1//===-- llvm-stress.cpp - Generate random LL files to stress-test LLVM ----===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This program is a utility that generates random .ll files to stress-test 11// different components in LLVM. 12// 13//===----------------------------------------------------------------------===// 14#include "llvm/IR/LLVMContext.h" 15#include "llvm/ADT/OwningPtr.h" 16#include "llvm/Analysis/CallGraphSCCPass.h" 17#include "llvm/Analysis/Verifier.h" 18#include "llvm/Assembly/PrintModulePass.h" 19#include "llvm/IR/Constants.h" 20#include "llvm/IR/Instruction.h" 21#include "llvm/IR/Module.h" 22#include "llvm/PassManager.h" 23#include "llvm/Support/Debug.h" 24#include "llvm/Support/ManagedStatic.h" 25#include "llvm/Support/PassNameParser.h" 26#include "llvm/Support/PluginLoader.h" 27#include "llvm/Support/PrettyStackTrace.h" 28#include "llvm/Support/ToolOutputFile.h" 29#include <algorithm> 30#include <set> 31#include <sstream> 32#include <vector> 33using namespace llvm; 34 35static cl::opt<unsigned> SeedCL("seed", 36 cl::desc("Seed used for randomness"), cl::init(0)); 37static cl::opt<unsigned> SizeCL("size", 38 cl::desc("The estimated size of the generated function (# of instrs)"), 39 cl::init(100)); 40static cl::opt<std::string> 41OutputFilename("o", cl::desc("Override output filename"), 42 cl::value_desc("filename")); 43 44static cl::opt<bool> GenHalfFloat("generate-half-float", 45 cl::desc("Generate half-length floating-point values"), cl::init(false)); 46static cl::opt<bool> GenX86FP80("generate-x86-fp80", 47 cl::desc("Generate 80-bit X86 floating-point values"), cl::init(false)); 48static cl::opt<bool> GenFP128("generate-fp128", 49 cl::desc("Generate 128-bit floating-point values"), cl::init(false)); 50static cl::opt<bool> GenPPCFP128("generate-ppc-fp128", 51 cl::desc("Generate 128-bit PPC floating-point values"), cl::init(false)); 52static cl::opt<bool> GenX86MMX("generate-x86-mmx", 53 cl::desc("Generate X86 MMX floating-point values"), cl::init(false)); 54 55namespace { 56/// A utility class to provide a pseudo-random number generator which is 57/// the same across all platforms. This is somewhat close to the libc 58/// implementation. Note: This is not a cryptographically secure pseudorandom 59/// number generator. 60class Random { 61public: 62 /// C'tor 63 Random(unsigned _seed):Seed(_seed) {} 64 65 /// Return a random integer, up to a 66 /// maximum of 2**19 - 1. 67 uint32_t Rand() { 68 uint32_t Val = Seed + 0x000b07a1; 69 Seed = (Val * 0x3c7c0ac1); 70 // Only lowest 19 bits are random-ish. 71 return Seed & 0x7ffff; 72 } 73 74 /// Return a random 32 bit integer. 75 uint32_t Rand32() { 76 uint32_t Val = Rand(); 77 Val &= 0xffff; 78 return Val | (Rand() << 16); 79 } 80 81 /// Return a random 64 bit integer. 82 uint64_t Rand64() { 83 uint64_t Val = Rand32(); 84 return Val | (uint64_t(Rand32()) << 32); 85 } 86 87 /// Rand operator for STL algorithms. 88 ptrdiff_t operator()(ptrdiff_t y) { 89 return Rand64() % y; 90 } 91 92private: 93 unsigned Seed; 94}; 95 96/// Generate an empty function with a default argument list. 97Function *GenEmptyFunction(Module *M) { 98 // Type Definitions 99 std::vector<Type*> ArgsTy; 100 // Define a few arguments 101 LLVMContext &Context = M->getContext(); 102 ArgsTy.push_back(PointerType::get(IntegerType::getInt8Ty(Context), 0)); 103 ArgsTy.push_back(PointerType::get(IntegerType::getInt32Ty(Context), 0)); 104 ArgsTy.push_back(PointerType::get(IntegerType::getInt64Ty(Context), 0)); 105 ArgsTy.push_back(IntegerType::getInt32Ty(Context)); 106 ArgsTy.push_back(IntegerType::getInt64Ty(Context)); 107 ArgsTy.push_back(IntegerType::getInt8Ty(Context)); 108 109 FunctionType *FuncTy = FunctionType::get(Type::getVoidTy(Context), ArgsTy, 0); 110 // Pick a unique name to describe the input parameters 111 std::stringstream ss; 112 ss<<"autogen_SD"<<SeedCL; 113 Function *Func = Function::Create(FuncTy, GlobalValue::ExternalLinkage, 114 ss.str(), M); 115 116 Func->setCallingConv(CallingConv::C); 117 return Func; 118} 119 120/// A base class, implementing utilities needed for 121/// modifying and adding new random instructions. 122struct Modifier { 123 /// Used to store the randomly generated values. 124 typedef std::vector<Value*> PieceTable; 125 126public: 127 /// C'tor 128 Modifier(BasicBlock *Block, PieceTable *PT, Random *R): 129 BB(Block),PT(PT),Ran(R),Context(BB->getContext()) {} 130 131 /// virtual D'tor to silence warnings. 132 virtual ~Modifier() {} 133 134 /// Add a new instruction. 135 virtual void Act() = 0; 136 /// Add N new instructions, 137 virtual void ActN(unsigned n) { 138 for (unsigned i=0; i<n; ++i) 139 Act(); 140 } 141 142protected: 143 /// Return a random value from the list of known values. 144 Value *getRandomVal() { 145 assert(PT->size()); 146 return PT->at(Ran->Rand() % PT->size()); 147 } 148 149 Constant *getRandomConstant(Type *Tp) { 150 if (Tp->isIntegerTy()) { 151 if (Ran->Rand() & 1) 152 return ConstantInt::getAllOnesValue(Tp); 153 return ConstantInt::getNullValue(Tp); 154 } else if (Tp->isFloatingPointTy()) { 155 if (Ran->Rand() & 1) 156 return ConstantFP::getAllOnesValue(Tp); 157 return ConstantFP::getNullValue(Tp); 158 } 159 return UndefValue::get(Tp); 160 } 161 162 /// Return a random value with a known type. 163 Value *getRandomValue(Type *Tp) { 164 unsigned index = Ran->Rand(); 165 for (unsigned i=0; i<PT->size(); ++i) { 166 Value *V = PT->at((index + i) % PT->size()); 167 if (V->getType() == Tp) 168 return V; 169 } 170 171 // If the requested type was not found, generate a constant value. 172 if (Tp->isIntegerTy()) { 173 if (Ran->Rand() & 1) 174 return ConstantInt::getAllOnesValue(Tp); 175 return ConstantInt::getNullValue(Tp); 176 } else if (Tp->isFloatingPointTy()) { 177 if (Ran->Rand() & 1) 178 return ConstantFP::getAllOnesValue(Tp); 179 return ConstantFP::getNullValue(Tp); 180 } else if (Tp->isVectorTy()) { 181 VectorType *VTp = cast<VectorType>(Tp); 182 183 std::vector<Constant*> TempValues; 184 TempValues.reserve(VTp->getNumElements()); 185 for (unsigned i = 0; i < VTp->getNumElements(); ++i) 186 TempValues.push_back(getRandomConstant(VTp->getScalarType())); 187 188 ArrayRef<Constant*> VectorValue(TempValues); 189 return ConstantVector::get(VectorValue); 190 } 191 192 return UndefValue::get(Tp); 193 } 194 195 /// Return a random value of any pointer type. 196 Value *getRandomPointerValue() { 197 unsigned index = Ran->Rand(); 198 for (unsigned i=0; i<PT->size(); ++i) { 199 Value *V = PT->at((index + i) % PT->size()); 200 if (V->getType()->isPointerTy()) 201 return V; 202 } 203 return UndefValue::get(pickPointerType()); 204 } 205 206 /// Return a random value of any vector type. 207 Value *getRandomVectorValue() { 208 unsigned index = Ran->Rand(); 209 for (unsigned i=0; i<PT->size(); ++i) { 210 Value *V = PT->at((index + i) % PT->size()); 211 if (V->getType()->isVectorTy()) 212 return V; 213 } 214 return UndefValue::get(pickVectorType()); 215 } 216 217 /// Pick a random type. 218 Type *pickType() { 219 return (Ran->Rand() & 1 ? pickVectorType() : pickScalarType()); 220 } 221 222 /// Pick a random pointer type. 223 Type *pickPointerType() { 224 Type *Ty = pickType(); 225 return PointerType::get(Ty, 0); 226 } 227 228 /// Pick a random vector type. 229 Type *pickVectorType(unsigned len = (unsigned)-1) { 230 // Pick a random vector width in the range 2**0 to 2**4. 231 // by adding two randoms we are generating a normal-like distribution 232 // around 2**3. 233 unsigned width = 1<<((Ran->Rand() % 3) + (Ran->Rand() % 3)); 234 Type *Ty; 235 236 // Vectors of x86mmx are illegal; keep trying till we get something else. 237 do { 238 Ty = pickScalarType(); 239 } while (Ty->isX86_MMXTy()); 240 241 if (len != (unsigned)-1) 242 width = len; 243 return VectorType::get(Ty, width); 244 } 245 246 /// Pick a random scalar type. 247 Type *pickScalarType() { 248 Type *t = 0; 249 do { 250 switch (Ran->Rand() % 30) { 251 case 0: t = Type::getInt1Ty(Context); break; 252 case 1: t = Type::getInt8Ty(Context); break; 253 case 2: t = Type::getInt16Ty(Context); break; 254 case 3: case 4: 255 case 5: t = Type::getFloatTy(Context); break; 256 case 6: case 7: 257 case 8: t = Type::getDoubleTy(Context); break; 258 case 9: case 10: 259 case 11: t = Type::getInt32Ty(Context); break; 260 case 12: case 13: 261 case 14: t = Type::getInt64Ty(Context); break; 262 case 15: case 16: 263 case 17: if (GenHalfFloat) t = Type::getHalfTy(Context); break; 264 case 18: case 19: 265 case 20: if (GenX86FP80) t = Type::getX86_FP80Ty(Context); break; 266 case 21: case 22: 267 case 23: if (GenFP128) t = Type::getFP128Ty(Context); break; 268 case 24: case 25: 269 case 26: if (GenPPCFP128) t = Type::getPPC_FP128Ty(Context); break; 270 case 27: case 28: 271 case 29: if (GenX86MMX) t = Type::getX86_MMXTy(Context); break; 272 default: llvm_unreachable("Invalid scalar value"); 273 } 274 } while (t == 0); 275 276 return t; 277 } 278 279 /// Basic block to populate 280 BasicBlock *BB; 281 /// Value table 282 PieceTable *PT; 283 /// Random number generator 284 Random *Ran; 285 /// Context 286 LLVMContext &Context; 287}; 288 289struct LoadModifier: public Modifier { 290 LoadModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 291 virtual void Act() { 292 // Try to use predefined pointers. If non exist, use undef pointer value; 293 Value *Ptr = getRandomPointerValue(); 294 Value *V = new LoadInst(Ptr, "L", BB->getTerminator()); 295 PT->push_back(V); 296 } 297}; 298 299struct StoreModifier: public Modifier { 300 StoreModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 301 virtual void Act() { 302 // Try to use predefined pointers. If non exist, use undef pointer value; 303 Value *Ptr = getRandomPointerValue(); 304 Type *Tp = Ptr->getType(); 305 Value *Val = getRandomValue(Tp->getContainedType(0)); 306 Type *ValTy = Val->getType(); 307 308 // Do not store vectors of i1s because they are unsupported 309 // by the codegen. 310 if (ValTy->isVectorTy() && ValTy->getScalarSizeInBits() == 1) 311 return; 312 313 new StoreInst(Val, Ptr, BB->getTerminator()); 314 } 315}; 316 317struct BinModifier: public Modifier { 318 BinModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 319 320 virtual void Act() { 321 Value *Val0 = getRandomVal(); 322 Value *Val1 = getRandomValue(Val0->getType()); 323 324 // Don't handle pointer types. 325 if (Val0->getType()->isPointerTy() || 326 Val1->getType()->isPointerTy()) 327 return; 328 329 // Don't handle i1 types. 330 if (Val0->getType()->getScalarSizeInBits() == 1) 331 return; 332 333 334 bool isFloat = Val0->getType()->getScalarType()->isFloatingPointTy(); 335 Instruction* Term = BB->getTerminator(); 336 unsigned R = Ran->Rand() % (isFloat ? 7 : 13); 337 Instruction::BinaryOps Op; 338 339 switch (R) { 340 default: llvm_unreachable("Invalid BinOp"); 341 case 0:{Op = (isFloat?Instruction::FAdd : Instruction::Add); break; } 342 case 1:{Op = (isFloat?Instruction::FSub : Instruction::Sub); break; } 343 case 2:{Op = (isFloat?Instruction::FMul : Instruction::Mul); break; } 344 case 3:{Op = (isFloat?Instruction::FDiv : Instruction::SDiv); break; } 345 case 4:{Op = (isFloat?Instruction::FDiv : Instruction::UDiv); break; } 346 case 5:{Op = (isFloat?Instruction::FRem : Instruction::SRem); break; } 347 case 6:{Op = (isFloat?Instruction::FRem : Instruction::URem); break; } 348 case 7: {Op = Instruction::Shl; break; } 349 case 8: {Op = Instruction::LShr; break; } 350 case 9: {Op = Instruction::AShr; break; } 351 case 10:{Op = Instruction::And; break; } 352 case 11:{Op = Instruction::Or; break; } 353 case 12:{Op = Instruction::Xor; break; } 354 } 355 356 PT->push_back(BinaryOperator::Create(Op, Val0, Val1, "B", Term)); 357 } 358}; 359 360/// Generate constant values. 361struct ConstModifier: public Modifier { 362 ConstModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 363 virtual void Act() { 364 Type *Ty = pickType(); 365 366 if (Ty->isVectorTy()) { 367 switch (Ran->Rand() % 2) { 368 case 0: if (Ty->getScalarType()->isIntegerTy()) 369 return PT->push_back(ConstantVector::getAllOnesValue(Ty)); 370 case 1: if (Ty->getScalarType()->isIntegerTy()) 371 return PT->push_back(ConstantVector::getNullValue(Ty)); 372 } 373 } 374 375 if (Ty->isFloatingPointTy()) { 376 // Generate 128 random bits, the size of the (currently) 377 // largest floating-point types. 378 uint64_t RandomBits[2]; 379 for (unsigned i = 0; i < 2; ++i) 380 RandomBits[i] = Ran->Rand64(); 381 382 APInt RandomInt(Ty->getPrimitiveSizeInBits(), makeArrayRef(RandomBits)); 383 APFloat RandomFloat(Ty->getFltSemantics(), RandomInt); 384 385 if (Ran->Rand() & 1) 386 return PT->push_back(ConstantFP::getNullValue(Ty)); 387 return PT->push_back(ConstantFP::get(Ty->getContext(), RandomFloat)); 388 } 389 390 if (Ty->isIntegerTy()) { 391 switch (Ran->Rand() % 7) { 392 case 0: if (Ty->isIntegerTy()) 393 return PT->push_back(ConstantInt::get(Ty, 394 APInt::getAllOnesValue(Ty->getPrimitiveSizeInBits()))); 395 case 1: if (Ty->isIntegerTy()) 396 return PT->push_back(ConstantInt::get(Ty, 397 APInt::getNullValue(Ty->getPrimitiveSizeInBits()))); 398 case 2: case 3: case 4: case 5: 399 case 6: if (Ty->isIntegerTy()) 400 PT->push_back(ConstantInt::get(Ty, Ran->Rand())); 401 } 402 } 403 404 } 405}; 406 407struct AllocaModifier: public Modifier { 408 AllocaModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R){} 409 410 virtual void Act() { 411 Type *Tp = pickType(); 412 PT->push_back(new AllocaInst(Tp, "A", BB->getFirstNonPHI())); 413 } 414}; 415 416struct ExtractElementModifier: public Modifier { 417 ExtractElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): 418 Modifier(BB, PT, R) {} 419 420 virtual void Act() { 421 Value *Val0 = getRandomVectorValue(); 422 Value *V = ExtractElementInst::Create(Val0, 423 ConstantInt::get(Type::getInt32Ty(BB->getContext()), 424 Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()), 425 "E", BB->getTerminator()); 426 return PT->push_back(V); 427 } 428}; 429 430struct ShuffModifier: public Modifier { 431 ShuffModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 432 virtual void Act() { 433 434 Value *Val0 = getRandomVectorValue(); 435 Value *Val1 = getRandomValue(Val0->getType()); 436 437 unsigned Width = cast<VectorType>(Val0->getType())->getNumElements(); 438 std::vector<Constant*> Idxs; 439 440 Type *I32 = Type::getInt32Ty(BB->getContext()); 441 for (unsigned i=0; i<Width; ++i) { 442 Constant *CI = ConstantInt::get(I32, Ran->Rand() % (Width*2)); 443 // Pick some undef values. 444 if (!(Ran->Rand() % 5)) 445 CI = UndefValue::get(I32); 446 Idxs.push_back(CI); 447 } 448 449 Constant *Mask = ConstantVector::get(Idxs); 450 451 Value *V = new ShuffleVectorInst(Val0, Val1, Mask, "Shuff", 452 BB->getTerminator()); 453 PT->push_back(V); 454 } 455}; 456 457struct InsertElementModifier: public Modifier { 458 InsertElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): 459 Modifier(BB, PT, R) {} 460 461 virtual void Act() { 462 Value *Val0 = getRandomVectorValue(); 463 Value *Val1 = getRandomValue(Val0->getType()->getScalarType()); 464 465 Value *V = InsertElementInst::Create(Val0, Val1, 466 ConstantInt::get(Type::getInt32Ty(BB->getContext()), 467 Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()), 468 "I", BB->getTerminator()); 469 return PT->push_back(V); 470 } 471 472}; 473 474struct CastModifier: public Modifier { 475 CastModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 476 virtual void Act() { 477 478 Value *V = getRandomVal(); 479 Type *VTy = V->getType(); 480 Type *DestTy = pickScalarType(); 481 482 // Handle vector casts vectors. 483 if (VTy->isVectorTy()) { 484 VectorType *VecTy = cast<VectorType>(VTy); 485 DestTy = pickVectorType(VecTy->getNumElements()); 486 } 487 488 // no need to cast. 489 if (VTy == DestTy) return; 490 491 // Pointers: 492 if (VTy->isPointerTy()) { 493 if (!DestTy->isPointerTy()) 494 DestTy = PointerType::get(DestTy, 0); 495 return PT->push_back( 496 new BitCastInst(V, DestTy, "PC", BB->getTerminator())); 497 } 498 499 unsigned VSize = VTy->getScalarType()->getPrimitiveSizeInBits(); 500 unsigned DestSize = DestTy->getScalarType()->getPrimitiveSizeInBits(); 501 502 // Generate lots of bitcasts. 503 if ((Ran->Rand() & 1) && VSize == DestSize) { 504 return PT->push_back( 505 new BitCastInst(V, DestTy, "BC", BB->getTerminator())); 506 } 507 508 // Both types are integers: 509 if (VTy->getScalarType()->isIntegerTy() && 510 DestTy->getScalarType()->isIntegerTy()) { 511 if (VSize > DestSize) { 512 return PT->push_back( 513 new TruncInst(V, DestTy, "Tr", BB->getTerminator())); 514 } else { 515 assert(VSize < DestSize && "Different int types with the same size?"); 516 if (Ran->Rand() & 1) 517 return PT->push_back( 518 new ZExtInst(V, DestTy, "ZE", BB->getTerminator())); 519 return PT->push_back(new SExtInst(V, DestTy, "Se", BB->getTerminator())); 520 } 521 } 522 523 // Fp to int. 524 if (VTy->getScalarType()->isFloatingPointTy() && 525 DestTy->getScalarType()->isIntegerTy()) { 526 if (Ran->Rand() & 1) 527 return PT->push_back( 528 new FPToSIInst(V, DestTy, "FC", BB->getTerminator())); 529 return PT->push_back(new FPToUIInst(V, DestTy, "FC", BB->getTerminator())); 530 } 531 532 // Int to fp. 533 if (VTy->getScalarType()->isIntegerTy() && 534 DestTy->getScalarType()->isFloatingPointTy()) { 535 if (Ran->Rand() & 1) 536 return PT->push_back( 537 new SIToFPInst(V, DestTy, "FC", BB->getTerminator())); 538 return PT->push_back(new UIToFPInst(V, DestTy, "FC", BB->getTerminator())); 539 540 } 541 542 // Both floats. 543 if (VTy->getScalarType()->isFloatingPointTy() && 544 DestTy->getScalarType()->isFloatingPointTy()) { 545 if (VSize > DestSize) { 546 return PT->push_back( 547 new FPTruncInst(V, DestTy, "Tr", BB->getTerminator())); 548 } else if (VSize < DestSize) { 549 return PT->push_back( 550 new FPExtInst(V, DestTy, "ZE", BB->getTerminator())); 551 } 552 // If VSize == DestSize, then the two types must be fp128 and ppc_fp128, 553 // for which there is no defined conversion. So do nothing. 554 } 555 } 556 557}; 558 559struct SelectModifier: public Modifier { 560 SelectModifier(BasicBlock *BB, PieceTable *PT, Random *R): 561 Modifier(BB, PT, R) {} 562 563 virtual void Act() { 564 // Try a bunch of different select configuration until a valid one is found. 565 Value *Val0 = getRandomVal(); 566 Value *Val1 = getRandomValue(Val0->getType()); 567 568 Type *CondTy = Type::getInt1Ty(Context); 569 570 // If the value type is a vector, and we allow vector select, then in 50% 571 // of the cases generate a vector select. 572 if (Val0->getType()->isVectorTy() && (Ran->Rand() % 1)) { 573 unsigned NumElem = cast<VectorType>(Val0->getType())->getNumElements(); 574 CondTy = VectorType::get(CondTy, NumElem); 575 } 576 577 Value *Cond = getRandomValue(CondTy); 578 Value *V = SelectInst::Create(Cond, Val0, Val1, "Sl", BB->getTerminator()); 579 return PT->push_back(V); 580 } 581}; 582 583 584struct CmpModifier: public Modifier { 585 CmpModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 586 virtual void Act() { 587 588 Value *Val0 = getRandomVal(); 589 Value *Val1 = getRandomValue(Val0->getType()); 590 591 if (Val0->getType()->isPointerTy()) return; 592 bool fp = Val0->getType()->getScalarType()->isFloatingPointTy(); 593 594 int op; 595 if (fp) { 596 op = Ran->Rand() % 597 (CmpInst::LAST_FCMP_PREDICATE - CmpInst::FIRST_FCMP_PREDICATE) + 598 CmpInst::FIRST_FCMP_PREDICATE; 599 } else { 600 op = Ran->Rand() % 601 (CmpInst::LAST_ICMP_PREDICATE - CmpInst::FIRST_ICMP_PREDICATE) + 602 CmpInst::FIRST_ICMP_PREDICATE; 603 } 604 605 Value *V = CmpInst::Create(fp ? Instruction::FCmp : Instruction::ICmp, 606 op, Val0, Val1, "Cmp", BB->getTerminator()); 607 return PT->push_back(V); 608 } 609}; 610 611} // end anonymous namespace 612 613static void FillFunction(Function *F, Random &R) { 614 // Create a legal entry block. 615 BasicBlock *BB = BasicBlock::Create(F->getContext(), "BB", F); 616 ReturnInst::Create(F->getContext(), BB); 617 618 // Create the value table. 619 Modifier::PieceTable PT; 620 621 // Consider arguments as legal values. 622 for (Function::arg_iterator it = F->arg_begin(), e = F->arg_end(); 623 it != e; ++it) 624 PT.push_back(it); 625 626 // List of modifiers which add new random instructions. 627 std::vector<Modifier*> Modifiers; 628 OwningPtr<Modifier> LM(new LoadModifier(BB, &PT, &R)); 629 OwningPtr<Modifier> SM(new StoreModifier(BB, &PT, &R)); 630 OwningPtr<Modifier> EE(new ExtractElementModifier(BB, &PT, &R)); 631 OwningPtr<Modifier> SHM(new ShuffModifier(BB, &PT, &R)); 632 OwningPtr<Modifier> IE(new InsertElementModifier(BB, &PT, &R)); 633 OwningPtr<Modifier> BM(new BinModifier(BB, &PT, &R)); 634 OwningPtr<Modifier> CM(new CastModifier(BB, &PT, &R)); 635 OwningPtr<Modifier> SLM(new SelectModifier(BB, &PT, &R)); 636 OwningPtr<Modifier> PM(new CmpModifier(BB, &PT, &R)); 637 Modifiers.push_back(LM.get()); 638 Modifiers.push_back(SM.get()); 639 Modifiers.push_back(EE.get()); 640 Modifiers.push_back(SHM.get()); 641 Modifiers.push_back(IE.get()); 642 Modifiers.push_back(BM.get()); 643 Modifiers.push_back(CM.get()); 644 Modifiers.push_back(SLM.get()); 645 Modifiers.push_back(PM.get()); 646 647 // Generate the random instructions 648 AllocaModifier AM(BB, &PT, &R); AM.ActN(5); // Throw in a few allocas 649 ConstModifier COM(BB, &PT, &R); COM.ActN(40); // Throw in a few constants 650 651 for (unsigned i=0; i< SizeCL / Modifiers.size(); ++i) 652 for (std::vector<Modifier*>::iterator it = Modifiers.begin(), 653 e = Modifiers.end(); it != e; ++it) { 654 (*it)->Act(); 655 } 656 657 SM->ActN(5); // Throw in a few stores. 658} 659 660static void IntroduceControlFlow(Function *F, Random &R) { 661 std::vector<Instruction*> BoolInst; 662 for (BasicBlock::iterator it = F->begin()->begin(), 663 e = F->begin()->end(); it != e; ++it) { 664 if (it->getType() == IntegerType::getInt1Ty(F->getContext())) 665 BoolInst.push_back(it); 666 } 667 668 std::random_shuffle(BoolInst.begin(), BoolInst.end(), R); 669 670 for (std::vector<Instruction*>::iterator it = BoolInst.begin(), 671 e = BoolInst.end(); it != e; ++it) { 672 Instruction *Instr = *it; 673 BasicBlock *Curr = Instr->getParent(); 674 BasicBlock::iterator Loc= Instr; 675 BasicBlock *Next = Curr->splitBasicBlock(Loc, "CF"); 676 Instr->moveBefore(Curr->getTerminator()); 677 if (Curr != &F->getEntryBlock()) { 678 BranchInst::Create(Curr, Next, Instr, Curr->getTerminator()); 679 Curr->getTerminator()->eraseFromParent(); 680 } 681 } 682} 683 684int main(int argc, char **argv) { 685 // Init LLVM, call llvm_shutdown() on exit, parse args, etc. 686 llvm::PrettyStackTraceProgram X(argc, argv); 687 cl::ParseCommandLineOptions(argc, argv, "llvm codegen stress-tester\n"); 688 llvm_shutdown_obj Y; 689 690 OwningPtr<Module> M(new Module("/tmp/autogen.bc", getGlobalContext())); 691 Function *F = GenEmptyFunction(M.get()); 692 693 // Pick an initial seed value 694 Random R(SeedCL); 695 // Generate lots of random instructions inside a single basic block. 696 FillFunction(F, R); 697 // Break the basic block into many loops. 698 IntroduceControlFlow(F, R); 699 700 // Figure out what stream we are supposed to write to... 701 OwningPtr<tool_output_file> Out; 702 // Default to standard output. 703 if (OutputFilename.empty()) 704 OutputFilename = "-"; 705 706 std::string ErrorInfo; 707 Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, 708 sys::fs::F_Binary)); 709 if (!ErrorInfo.empty()) { 710 errs() << ErrorInfo << '\n'; 711 return 1; 712 } 713 714 PassManager Passes; 715 Passes.add(createVerifierPass()); 716 Passes.add(createPrintModulePass(&Out->os())); 717 Passes.run(*M.get()); 718 Out->keep(); 719 720 return 0; 721} 722