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