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