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