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