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