llvm-stress.cpp 22 KB

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