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