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