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/Pass.h"
38 #include "llvm/Support/Casting.h"
39 #include "llvm/Support/CommandLine.h"
40 #include "llvm/Support/ErrorHandling.h"
41 #include "llvm/Support/FileSystem.h"
42 #include "llvm/Support/InitLLVM.h"
43 #include "llvm/Support/ToolOutputFile.h"
44 #include "llvm/Support/WithColor.h"
45 #include "llvm/Support/raw_ostream.h"
46 #include <algorithm>
47 #include <cassert>
48 #include <cstddef>
49 #include <cstdint>
50 #include <memory>
51 #include <string>
52 #include <system_error>
53 #include <vector>
54 
55 namespace llvm {
56 
57 static cl::OptionCategory StressCategory("Stress Options");
58 
59 static cl::opt<unsigned> SeedCL("seed", cl::desc("Seed used for randomness"),
60                                 cl::init(0), cl::cat(StressCategory));
61 
62 static cl::opt<unsigned> SizeCL(
63     "size",
64     cl::desc("The estimated size of the generated function (# of instrs)"),
65     cl::init(100), cl::cat(StressCategory));
66 
67 static cl::opt<std::string> OutputFilename("o",
68                                            cl::desc("Override output filename"),
69                                            cl::value_desc("filename"),
70                                            cl::cat(StressCategory));
71 
72 static LLVMContext Context;
73 
74 namespace cl {
75 
76 template <> class parser<Type*> final : public basic_parser<Type*> {
77 public:
78   parser(Option &O) : basic_parser(O) {}
79 
80   // Parse options as IR types. Return true on error.
81   bool parse(Option &O, StringRef, StringRef Arg, Type *&Value) {
82     if      (Arg == "half")      Value = Type::getHalfTy(Context);
83     else if (Arg == "fp128")     Value = Type::getFP128Ty(Context);
84     else if (Arg == "x86_fp80")  Value = Type::getX86_FP80Ty(Context);
85     else if (Arg == "ppc_fp128") Value = Type::getPPC_FP128Ty(Context);
86     else if (Arg == "x86_mmx")   Value = Type::getX86_MMXTy(Context);
87     else if (Arg.startswith("i")) {
88       unsigned N = 0;
89       Arg.drop_front().getAsInteger(10, N);
90       if (N > 0)
91         Value = Type::getIntNTy(Context, N);
92     }
93 
94     if (!Value)
95       return O.error("Invalid IR scalar type: '" + Arg + "'!");
96     return false;
97   }
98 
99   StringRef getValueName() const override { return "IR scalar type"; }
100 };
101 
102 } // end namespace cl
103 
104 static cl::list<Type*> AdditionalScalarTypes("types", cl::CommaSeparated,
105   cl::desc("Additional IR scalar types "
106            "(always includes i1, i8, i16, i32, i64, float and double)"));
107 
108 namespace {
109 
110 /// A utility class to provide a pseudo-random number generator which is
111 /// the same across all platforms. This is somewhat close to the libc
112 /// implementation. Note: This is not a cryptographically secure pseudorandom
113 /// number generator.
114 class Random {
115 public:
116   /// C'tor
117   Random(unsigned _seed):Seed(_seed) {}
118 
119   /// Return a random integer, up to a
120   /// maximum of 2**19 - 1.
121   uint32_t Rand() {
122     uint32_t Val = Seed + 0x000b07a1;
123     Seed = (Val * 0x3c7c0ac1);
124     // Only lowest 19 bits are random-ish.
125     return Seed & 0x7ffff;
126   }
127 
128   /// Return a random 64 bit integer.
129   uint64_t Rand64() {
130     uint64_t Val = Rand() & 0xffff;
131     Val |= uint64_t(Rand() & 0xffff) << 16;
132     Val |= uint64_t(Rand() & 0xffff) << 32;
133     Val |= uint64_t(Rand() & 0xffff) << 48;
134     return Val;
135   }
136 
137   /// Rand operator for STL algorithms.
138   ptrdiff_t operator()(ptrdiff_t y) {
139     return  Rand64() % y;
140   }
141 
142   /// Make this like a C++11 random device
143   using result_type = uint32_t ;
144 
145   static constexpr result_type min() { return 0; }
146   static constexpr result_type max() { return 0x7ffff; }
147 
148   uint32_t operator()() {
149     uint32_t Val = Rand();
150     assert(Val <= max() && "Random value out of range");
151     return Val;
152   }
153 
154 private:
155   unsigned Seed;
156 };
157 
158 /// Generate an empty function with a default argument list.
159 Function *GenEmptyFunction(Module *M) {
160   // Define a few arguments
161   LLVMContext &Context = M->getContext();
162   Type* ArgsTy[] = {
163     Type::getInt8PtrTy(Context),
164     Type::getInt32PtrTy(Context),
165     Type::getInt64PtrTy(Context),
166     Type::getInt32Ty(Context),
167     Type::getInt64Ty(Context),
168     Type::getInt8Ty(Context)
169   };
170 
171   auto *FuncTy = FunctionType::get(Type::getVoidTy(Context), ArgsTy, false);
172   // Pick a unique name to describe the input parameters
173   Twine Name = "autogen_SD" + Twine{SeedCL};
174   auto *Func = Function::Create(FuncTy, GlobalValue::ExternalLinkage, Name, M);
175   Func->setCallingConv(CallingConv::C);
176   return Func;
177 }
178 
179 /// A base class, implementing utilities needed for
180 /// modifying and adding new random instructions.
181 struct Modifier {
182   /// Used to store the randomly generated values.
183   using PieceTable = std::vector<Value *>;
184 
185 public:
186   /// C'tor
187   Modifier(BasicBlock *Block, PieceTable *PT, Random *R)
188       : BB(Block), PT(PT), Ran(R), Context(BB->getContext()) {}
189 
190   /// virtual D'tor to silence warnings.
191   virtual ~Modifier() = default;
192 
193   /// Add a new instruction.
194   virtual void Act() = 0;
195 
196   /// Add N new instructions,
197   virtual void ActN(unsigned n) {
198     for (unsigned i=0; i<n; ++i)
199       Act();
200   }
201 
202 protected:
203   /// Return a random integer.
204   uint32_t getRandom() {
205     return Ran->Rand();
206   }
207 
208   /// Return a random value from the list of known values.
209   Value *getRandomVal() {
210     assert(PT->size());
211     return PT->at(getRandom() % PT->size());
212   }
213 
214   Constant *getRandomConstant(Type *Tp) {
215     if (Tp->isIntegerTy()) {
216       if (getRandom() & 1)
217         return ConstantInt::getAllOnesValue(Tp);
218       return ConstantInt::getNullValue(Tp);
219     } else if (Tp->isFloatingPointTy()) {
220       if (getRandom() & 1)
221         return ConstantFP::getAllOnesValue(Tp);
222       return ConstantFP::getNullValue(Tp);
223     }
224     return UndefValue::get(Tp);
225   }
226 
227   /// Return a random value with a known type.
228   Value *getRandomValue(Type *Tp) {
229     unsigned index = getRandom();
230     for (unsigned i=0; i<PT->size(); ++i) {
231       Value *V = PT->at((index + i) % PT->size());
232       if (V->getType() == Tp)
233         return V;
234     }
235 
236     // If the requested type was not found, generate a constant value.
237     if (Tp->isIntegerTy()) {
238       if (getRandom() & 1)
239         return ConstantInt::getAllOnesValue(Tp);
240       return ConstantInt::getNullValue(Tp);
241     } else if (Tp->isFloatingPointTy()) {
242       if (getRandom() & 1)
243         return ConstantFP::getAllOnesValue(Tp);
244       return ConstantFP::getNullValue(Tp);
245     } else if (Tp->isVectorTy()) {
246       auto *VTp = cast<FixedVectorType>(Tp);
247 
248       std::vector<Constant*> TempValues;
249       TempValues.reserve(VTp->getNumElements());
250       for (unsigned i = 0; i < VTp->getNumElements(); ++i)
251         TempValues.push_back(getRandomConstant(VTp->getScalarType()));
252 
253       ArrayRef<Constant*> VectorValue(TempValues);
254       return ConstantVector::get(VectorValue);
255     }
256 
257     return UndefValue::get(Tp);
258   }
259 
260   /// Return a random value of any pointer type.
261   Value *getRandomPointerValue() {
262     unsigned index = getRandom();
263     for (unsigned i=0; i<PT->size(); ++i) {
264       Value *V = PT->at((index + i) % PT->size());
265       if (V->getType()->isPointerTy())
266         return V;
267     }
268     return UndefValue::get(pickPointerType());
269   }
270 
271   /// Return a random value of any vector type.
272   Value *getRandomVectorValue() {
273     unsigned index = getRandom();
274     for (unsigned i=0; i<PT->size(); ++i) {
275       Value *V = PT->at((index + i) % PT->size());
276       if (V->getType()->isVectorTy())
277         return V;
278     }
279     return UndefValue::get(pickVectorType());
280   }
281 
282   /// Pick a random type.
283   Type *pickType() {
284     return (getRandom() & 1) ? pickVectorType() : pickScalarType();
285   }
286 
287   /// Pick a random pointer type.
288   Type *pickPointerType() {
289     Type *Ty = pickType();
290     return PointerType::get(Ty, 0);
291   }
292 
293   /// Pick a random vector type.
294   Type *pickVectorType(unsigned len = (unsigned)-1) {
295     // Pick a random vector width in the range 2**0 to 2**4.
296     // by adding two randoms we are generating a normal-like distribution
297     // around 2**3.
298     unsigned width = 1<<((getRandom() % 3) + (getRandom() % 3));
299     Type *Ty;
300 
301     // Vectors of x86mmx are illegal; keep trying till we get something else.
302     do {
303       Ty = pickScalarType();
304     } while (Ty->isX86_MMXTy());
305 
306     if (len != (unsigned)-1)
307       width = len;
308     return FixedVectorType::get(Ty, width);
309   }
310 
311   /// Pick a random scalar type.
312   Type *pickScalarType() {
313     static std::vector<Type*> ScalarTypes;
314     if (ScalarTypes.empty()) {
315       ScalarTypes.assign({
316         Type::getInt1Ty(Context),
317         Type::getInt8Ty(Context),
318         Type::getInt16Ty(Context),
319         Type::getInt32Ty(Context),
320         Type::getInt64Ty(Context),
321         Type::getFloatTy(Context),
322         Type::getDoubleTy(Context)
323       });
324       llvm::append_range(ScalarTypes, AdditionalScalarTypes);
325     }
326 
327     return ScalarTypes[getRandom() % ScalarTypes.size()];
328   }
329 
330   /// Basic block to populate
331   BasicBlock *BB;
332 
333   /// Value table
334   PieceTable *PT;
335 
336   /// Random number generator
337   Random *Ran;
338 
339   /// Context
340   LLVMContext &Context;
341 };
342 
343 struct LoadModifier: public Modifier {
344   LoadModifier(BasicBlock *BB, PieceTable *PT, Random *R)
345       : Modifier(BB, PT, R) {}
346 
347   void Act() override {
348     // Try to use predefined pointers. If non-exist, use undef pointer value;
349     Value *Ptr = getRandomPointerValue();
350     Value *V = new LoadInst(Ptr->getType()->getPointerElementType(), Ptr, "L",
351                             BB->getTerminator());
352     PT->push_back(V);
353   }
354 };
355 
356 struct StoreModifier: public Modifier {
357   StoreModifier(BasicBlock *BB, PieceTable *PT, Random *R)
358       : Modifier(BB, PT, R) {}
359 
360   void Act() override {
361     // Try to use predefined pointers. If non-exist, use undef pointer value;
362     Value *Ptr = getRandomPointerValue();
363     Value *Val = getRandomValue(Ptr->getType()->getPointerElementType());
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 {
376   BinModifier(BasicBlock *BB, PieceTable *PT, Random *R)
377       : Modifier(BB, PT, R) {}
378 
379   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 {
420   ConstModifier(BasicBlock *BB, PieceTable *PT, Random *R)
421       : Modifier(BB, PT, R) {}
422 
423   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::getAllOnes(Ty->getPrimitiveSizeInBits())));
456       case 1:
457         return PT->push_back(
458             ConstantInt::get(Ty, APInt::getZero(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 {
471   AllocaModifier(BasicBlock *BB, PieceTable *PT, Random *R)
472       : Modifier(BB, PT, R) {}
473 
474   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 {
483   ExtractElementModifier(BasicBlock *BB, PieceTable *PT, Random *R)
484       : Modifier(BB, PT, R) {}
485 
486   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 {
500   ShuffModifier(BasicBlock *BB, PieceTable *PT, Random *R)
501       : Modifier(BB, PT, R) {}
502 
503   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 {
528   InsertElementModifier(BasicBlock *BB, PieceTable *PT, Random *R)
529       : Modifier(BB, PT, R) {}
530 
531   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 {
547   CastModifier(BasicBlock *BB, PieceTable *PT, Random *R)
548       : Modifier(BB, PT, R) {}
549 
550   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 {
627   SelectModifier(BasicBlock *BB, PieceTable *PT, Random *R)
628       : Modifier(BB, PT, R) {}
629 
630   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 {
652   CmpModifier(BasicBlock *BB, PieceTable *PT, Random *R)
653       : Modifier(BB, PT, R) {}
654 
655   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 
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 
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 
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