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