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