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