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