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