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