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