1b6f0625de2d4a733dab2b63f6c54f59c84cefee0Daniel Dunbar//===-- llvm-stress.cpp - Generate random LL files to stress-test LLVM ----===// 2fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem// 3fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem// The LLVM Compiler Infrastructure 4fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem// 5fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem// This file is distributed under the University of Illinois Open Source 6fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem// License. See LICENSE.TXT for details. 7fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem// 8fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem//===----------------------------------------------------------------------===// 9fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem// 10fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem// This program is a utility that generates random .ll files to stress-test 11fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem// different components in LLVM. 12fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem// 13fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem//===----------------------------------------------------------------------===// 140b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h" 157375f4f98148fc34f0c7fc765967501cdc65b24eMatt Arsenault#include "llvm/ADT/OwningPtr.h" 163251e81d793a293b78f4914be6093b405c24fc2aChandler Carruth#include "llvm/Analysis/CallGraphSCCPass.h" 17f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Analysis/Verifier.h" 18f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Assembly/PrintModulePass.h" 190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h" 200b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instruction.h" 210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 22f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/PassManager.h" 23fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Support/Debug.h" 24fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Support/ManagedStatic.h" 25f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Support/PassNameParser.h" 26fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Support/PluginLoader.h" 27fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Support/PrettyStackTrace.h" 28fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Support/ToolOutputFile.h" 29f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include <algorithm> 30fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include <set> 31f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include <sstream> 32fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include <vector> 33fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemusing namespace llvm; 34fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 35fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstatic cl::opt<unsigned> SeedCL("seed", 36fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem cl::desc("Seed used for randomness"), cl::init(0)); 37fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstatic cl::opt<unsigned> SizeCL("size", 38fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem cl::desc("The estimated size of the generated function (# of instrs)"), 39fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem cl::init(100)); 40fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstatic cl::opt<std::string> 41fdc309cc4e95778d7615f3829917c4fe42086e1eNadav RotemOutputFilename("o", cl::desc("Override output filename"), 42fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem cl::value_desc("filename")); 43fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 442cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkelstatic cl::opt<bool> GenHalfFloat("generate-half-float", 452cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel cl::desc("Generate half-length floating-point values"), cl::init(false)); 462cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkelstatic cl::opt<bool> GenX86FP80("generate-x86-fp80", 472cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel cl::desc("Generate 80-bit X86 floating-point values"), cl::init(false)); 482cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkelstatic cl::opt<bool> GenFP128("generate-fp128", 492cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel cl::desc("Generate 128-bit floating-point values"), cl::init(false)); 502cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkelstatic cl::opt<bool> GenPPCFP128("generate-ppc-fp128", 512cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel cl::desc("Generate 128-bit PPC floating-point values"), cl::init(false)); 522cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkelstatic cl::opt<bool> GenX86MMX("generate-x86-mmx", 532cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel cl::desc("Generate X86 MMX floating-point values"), cl::init(false)); 542cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel 55fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem/// A utility class to provide a pseudo-random number generator which is 56fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem/// the same across all platforms. This is somewhat close to the libc 57fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem/// implementation. Note: This is not a cryptographically secure pseudorandom 58fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem/// number generator. 59fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemclass Random { 60fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotempublic: 61fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// C'tor 62fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Random(unsigned _seed):Seed(_seed) {} 6383f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith 6483f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith /// Return a random integer, up to a 6583f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith /// maximum of 2**19 - 1. 6683f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith uint32_t Rand() { 6783f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith uint32_t Val = Seed + 0x000b07a1; 68fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Seed = (Val * 0x3c7c0ac1); 69fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Only lowest 19 bits are random-ish. 70fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return Seed & 0x7ffff; 71fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 72fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 7383f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith /// Return a random 32 bit integer. 7483f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith uint32_t Rand32() { 7583f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith uint32_t Val = Rand(); 7683f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith Val &= 0xffff; 7783f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith return Val | (Rand() << 16); 7883f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith } 7983f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith 8083f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith /// Return a random 64 bit integer. 8183f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith uint64_t Rand64() { 8283f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith uint64_t Val = Rand32(); 8383f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith return Val | (uint64_t(Rand32()) << 32); 8483f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith } 857060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem 867060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem /// Rand operator for STL algorithms. 877060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem ptrdiff_t operator()(ptrdiff_t y) { 887060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem return Rand64() % y; 897060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem } 907060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem 91fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemprivate: 92fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned Seed; 93fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 94fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 95fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem/// Generate an empty function with a default argument list. 96fdc309cc4e95778d7615f3829917c4fe42086e1eNadav RotemFunction *GenEmptyFunction(Module *M) { 97fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Type Definitions 98fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::vector<Type*> ArgsTy; 99fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Define a few arguments 100fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem LLVMContext &Context = M->getContext(); 101fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ArgsTy.push_back(PointerType::get(IntegerType::getInt8Ty(Context), 0)); 102fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ArgsTy.push_back(PointerType::get(IntegerType::getInt32Ty(Context), 0)); 103fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ArgsTy.push_back(PointerType::get(IntegerType::getInt64Ty(Context), 0)); 104fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ArgsTy.push_back(IntegerType::getInt32Ty(Context)); 105fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ArgsTy.push_back(IntegerType::getInt64Ty(Context)); 106fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ArgsTy.push_back(IntegerType::getInt8Ty(Context)); 107fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 108fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem FunctionType *FuncTy = FunctionType::get(Type::getVoidTy(Context), ArgsTy, 0); 109fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Pick a unique name to describe the input parameters 110fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::stringstream ss; 111fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ss<<"autogen_SD"<<SeedCL; 112fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Function *Func = Function::Create(FuncTy, GlobalValue::ExternalLinkage, 113fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ss.str(), M); 114fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 115fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Func->setCallingConv(CallingConv::C); 116fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return Func; 117fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem} 118fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 119fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem/// A base class, implementing utilities needed for 120fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem/// modifying and adding new random instructions. 121fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct Modifier { 122fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Used to store the randomly generated values. 123fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem typedef std::vector<Value*> PieceTable; 124fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 125fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotempublic: 126fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// C'tor 12708c833930726d5c33baac060a7aca7c1caf636b3Nadav Rotem Modifier(BasicBlock *Block, PieceTable *PT, Random *R): 128b6f0625de2d4a733dab2b63f6c54f59c84cefee0Daniel Dunbar BB(Block),PT(PT),Ran(R),Context(BB->getContext()) {} 12967076a91cf5572ae75680b48f507a066e7ea36d4Andrew Trick 13067076a91cf5572ae75680b48f507a066e7ea36d4Andrew Trick /// virtual D'tor to silence warnings. 13167076a91cf5572ae75680b48f507a066e7ea36d4Andrew Trick virtual ~Modifier() {} 13267076a91cf5572ae75680b48f507a066e7ea36d4Andrew Trick 133fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Add a new instruction. 134fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() = 0; 135fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Add N new instructions, 136fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void ActN(unsigned n) { 137fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (unsigned i=0; i<n; ++i) 138fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Act(); 139fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 140fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 141fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemprotected: 142fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Return a random value from the list of known values. 143fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *getRandomVal() { 144fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem assert(PT->size()); 145fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->at(Ran->Rand() % PT->size()); 146fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 147fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 148bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem Constant *getRandomConstant(Type *Tp) { 149bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem if (Tp->isIntegerTy()) { 150bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem if (Ran->Rand() & 1) 151bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem return ConstantInt::getAllOnesValue(Tp); 152bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem return ConstantInt::getNullValue(Tp); 153bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem } else if (Tp->isFloatingPointTy()) { 154bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem if (Ran->Rand() & 1) 155bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem return ConstantFP::getAllOnesValue(Tp); 156bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem return ConstantFP::getNullValue(Tp); 157bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem } 158bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem return UndefValue::get(Tp); 159bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem } 160bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem 161fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Return a random value with a known type. 162fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *getRandomValue(Type *Tp) { 163fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned index = Ran->Rand(); 164fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (unsigned i=0; i<PT->size(); ++i) { 165fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = PT->at((index + i) % PT->size()); 166fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (V->getType() == Tp) 167fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return V; 168fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 169fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 170fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // If the requested type was not found, generate a constant value. 171fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Tp->isIntegerTy()) { 172fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ran->Rand() & 1) 173fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return ConstantInt::getAllOnesValue(Tp); 174fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return ConstantInt::getNullValue(Tp); 175fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } else if (Tp->isFloatingPointTy()) { 176fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ran->Rand() & 1) 177fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return ConstantFP::getAllOnesValue(Tp); 178fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return ConstantFP::getNullValue(Tp); 179bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem } else if (Tp->isVectorTy()) { 180bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem VectorType *VTp = cast<VectorType>(Tp); 181bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem 182bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem std::vector<Constant*> TempValues; 183bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem TempValues.reserve(VTp->getNumElements()); 184bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem for (unsigned i = 0; i < VTp->getNumElements(); ++i) 185bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem TempValues.push_back(getRandomConstant(VTp->getScalarType())); 186bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem 187bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem ArrayRef<Constant*> VectorValue(TempValues); 188bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem return ConstantVector::get(VectorValue); 189fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 190fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 191fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return UndefValue::get(Tp); 192fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 193fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 194fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Return a random value of any pointer type. 195fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *getRandomPointerValue() { 196fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned index = Ran->Rand(); 197fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (unsigned i=0; i<PT->size(); ++i) { 198fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = PT->at((index + i) % PT->size()); 199fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (V->getType()->isPointerTy()) 200fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return V; 201fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 202fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return UndefValue::get(pickPointerType()); 203fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 204fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 205fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Return a random value of any vector type. 206fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *getRandomVectorValue() { 207fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned index = Ran->Rand(); 208fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (unsigned i=0; i<PT->size(); ++i) { 209fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = PT->at((index + i) % PT->size()); 210fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (V->getType()->isVectorTy()) 211fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return V; 212fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 213fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return UndefValue::get(pickVectorType()); 214fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 215fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 216fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Pick a random type. 217fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *pickType() { 218fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return (Ran->Rand() & 1 ? pickVectorType() : pickScalarType()); 219fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 220fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 221fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Pick a random pointer type. 222fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *pickPointerType() { 223fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *Ty = pickType(); 224fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PointerType::get(Ty, 0); 225fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 226fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 227fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Pick a random vector type. 228fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *pickVectorType(unsigned len = (unsigned)-1) { 229fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Pick a random vector width in the range 2**0 to 2**4. 230fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // by adding two randoms we are generating a normal-like distribution 231fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // around 2**3. 232fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned width = 1<<((Ran->Rand() % 3) + (Ran->Rand() % 3)); 233701de8fafc8db86a0a7df61b177720b1f681c60cDylan Noblesmith Type *Ty; 234701de8fafc8db86a0a7df61b177720b1f681c60cDylan Noblesmith 235701de8fafc8db86a0a7df61b177720b1f681c60cDylan Noblesmith // Vectors of x86mmx are illegal; keep trying till we get something else. 236701de8fafc8db86a0a7df61b177720b1f681c60cDylan Noblesmith do { 237701de8fafc8db86a0a7df61b177720b1f681c60cDylan Noblesmith Ty = pickScalarType(); 238701de8fafc8db86a0a7df61b177720b1f681c60cDylan Noblesmith } while (Ty->isX86_MMXTy()); 239701de8fafc8db86a0a7df61b177720b1f681c60cDylan Noblesmith 240fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (len != (unsigned)-1) 241fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem width = len; 242fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return VectorType::get(Ty, width); 243fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 244fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 245fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Pick a random scalar type. 246fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *pickScalarType() { 2472cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel Type *t = 0; 2482cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel do { 2492cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel switch (Ran->Rand() % 30) { 2502cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 0: t = Type::getInt1Ty(Context); break; 2512cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 1: t = Type::getInt8Ty(Context); break; 2522cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 2: t = Type::getInt16Ty(Context); break; 2532cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 3: case 4: 2542cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 5: t = Type::getFloatTy(Context); break; 2552cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 6: case 7: 2562cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 8: t = Type::getDoubleTy(Context); break; 2572cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 9: case 10: 2582cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 11: t = Type::getInt32Ty(Context); break; 2592cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 12: case 13: 2602cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 14: t = Type::getInt64Ty(Context); break; 2612cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 15: case 16: 2622cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 17: if (GenHalfFloat) t = Type::getHalfTy(Context); break; 2632cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 18: case 19: 2642cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 20: if (GenX86FP80) t = Type::getX86_FP80Ty(Context); break; 2652cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 21: case 22: 2662cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 23: if (GenFP128) t = Type::getFP128Ty(Context); break; 2672cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 24: case 25: 2682cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 26: if (GenPPCFP128) t = Type::getPPC_FP128Ty(Context); break; 2692cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 27: case 28: 2702cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 29: if (GenX86MMX) t = Type::getX86_MMXTy(Context); break; 2712cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel default: llvm_unreachable("Invalid scalar value"); 2722cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel } 2732cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel } while (t == 0); 2742cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel 2752cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel return t; 276fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 277fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 278fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Basic block to populate 279fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BasicBlock *BB; 280fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Value table 281fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PieceTable *PT; 282fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Random number generator 283fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Random *Ran; 284fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Context 285fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem LLVMContext &Context; 286fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 287fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 288fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct LoadModifier: public Modifier { 289b6f0625de2d4a733dab2b63f6c54f59c84cefee0Daniel Dunbar LoadModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 290fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 291fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Try to use predefined pointers. If non exist, use undef pointer value; 292fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Ptr = getRandomPointerValue(); 293fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = new LoadInst(Ptr, "L", BB->getTerminator()); 294fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PT->push_back(V); 295fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 296fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 297fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 298fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct StoreModifier: public Modifier { 299fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem StoreModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 300fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 301fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Try to use predefined pointers. If non exist, use undef pointer value; 302fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Ptr = getRandomPointerValue(); 303fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *Tp = Ptr->getType(); 304fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val = getRandomValue(Tp->getContainedType(0)); 3052e851a9abf781bc5feef9be98f794dcb1caab548Nadav Rotem Type *ValTy = Val->getType(); 306fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 307fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Do not store vectors of i1s because they are unsupported 308794c16ae856f827babb22f862f4e69118ad68b09Nadav Rotem // by the codegen. 309794c16ae856f827babb22f862f4e69118ad68b09Nadav Rotem if (ValTy->isVectorTy() && ValTy->getScalarSizeInBits() == 1) 310fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return; 311fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 312fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new StoreInst(Val, Ptr, BB->getTerminator()); 313fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 314fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 315fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 316fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct BinModifier: public Modifier { 317fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BinModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 318fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 319fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 320fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val0 = getRandomVal(); 321fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val1 = getRandomValue(Val0->getType()); 322fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 323fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Don't handle pointer types. 324fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Val0->getType()->isPointerTy() || 325fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Val1->getType()->isPointerTy()) 326fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return; 327fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 328fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Don't handle i1 types. 329fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Val0->getType()->getScalarSizeInBits() == 1) 330fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return; 331fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 332fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 333fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem bool isFloat = Val0->getType()->getScalarType()->isFloatingPointTy(); 334fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Instruction* Term = BB->getTerminator(); 335fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned R = Ran->Rand() % (isFloat ? 7 : 13); 336fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Instruction::BinaryOps Op; 337fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 338fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem switch (R) { 339fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem default: llvm_unreachable("Invalid BinOp"); 340fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 0:{Op = (isFloat?Instruction::FAdd : Instruction::Add); break; } 341fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 1:{Op = (isFloat?Instruction::FSub : Instruction::Sub); break; } 342fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 2:{Op = (isFloat?Instruction::FMul : Instruction::Mul); break; } 343fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 3:{Op = (isFloat?Instruction::FDiv : Instruction::SDiv); break; } 344fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 4:{Op = (isFloat?Instruction::FDiv : Instruction::UDiv); break; } 345fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 5:{Op = (isFloat?Instruction::FRem : Instruction::SRem); break; } 346fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 6:{Op = (isFloat?Instruction::FRem : Instruction::URem); break; } 347fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 7: {Op = Instruction::Shl; break; } 348fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 8: {Op = Instruction::LShr; break; } 349fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 9: {Op = Instruction::AShr; break; } 350fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 10:{Op = Instruction::And; break; } 351fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 11:{Op = Instruction::Or; break; } 352fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 12:{Op = Instruction::Xor; break; } 353fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 354fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 355fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PT->push_back(BinaryOperator::Create(Op, Val0, Val1, "B", Term)); 356fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 357fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 358fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 359fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem/// Generate constant values. 360fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct ConstModifier: public Modifier { 361fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ConstModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 362fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 363fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *Ty = pickType(); 364fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 365fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ty->isVectorTy()) { 366fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem switch (Ran->Rand() % 2) { 367fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 0: if (Ty->getScalarType()->isIntegerTy()) 368fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(ConstantVector::getAllOnesValue(Ty)); 369fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 1: if (Ty->getScalarType()->isIntegerTy()) 370fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(ConstantVector::getNullValue(Ty)); 371fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 372fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 373fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 374fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ty->isFloatingPointTy()) { 37583f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith // Generate 128 random bits, the size of the (currently) 37683f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith // largest floating-point types. 37783f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith uint64_t RandomBits[2]; 37883f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith for (unsigned i = 0; i < 2; ++i) 37983f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith RandomBits[i] = Ran->Rand64(); 38083f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith 38183f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith APInt RandomInt(Ty->getPrimitiveSizeInBits(), makeArrayRef(RandomBits)); 382f65dc6e347492407fc7792a621849ac2ecd6801cTim Northover APFloat RandomFloat(Ty->getFltSemantics(), RandomInt); 38383f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith 384fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ran->Rand() & 1) 385fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(ConstantFP::getNullValue(Ty)); 38683f17f25fc560db4f756010a1bbe1f8eb1d74b12Dylan Noblesmith return PT->push_back(ConstantFP::get(Ty->getContext(), RandomFloat)); 387fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 388fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 389fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ty->isIntegerTy()) { 390fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem switch (Ran->Rand() % 7) { 391fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 0: if (Ty->isIntegerTy()) 392fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(ConstantInt::get(Ty, 393fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem APInt::getAllOnesValue(Ty->getPrimitiveSizeInBits()))); 394fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 1: if (Ty->isIntegerTy()) 395fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(ConstantInt::get(Ty, 396fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem APInt::getNullValue(Ty->getPrimitiveSizeInBits()))); 397fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 2: case 3: case 4: case 5: 398fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 6: if (Ty->isIntegerTy()) 399fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PT->push_back(ConstantInt::get(Ty, Ran->Rand())); 400fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 401fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 402fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 403fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 404fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 405fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 406fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct AllocaModifier: public Modifier { 407fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem AllocaModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R){} 408fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 409fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 410fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *Tp = pickType(); 411fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PT->push_back(new AllocaInst(Tp, "A", BB->getFirstNonPHI())); 412fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 413fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 414fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 415fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct ExtractElementModifier: public Modifier { 416fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ExtractElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): 417fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifier(BB, PT, R) {} 418fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 419fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 420fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val0 = getRandomVectorValue(); 421fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = ExtractElementInst::Create(Val0, 422fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ConstantInt::get(Type::getInt32Ty(BB->getContext()), 4237d719a5237d8da0aed188a400b9792b64dae5fc0Nadav Rotem Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()), 424fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem "E", BB->getTerminator()); 425fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(V); 426fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 427fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 428fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 429fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct ShuffModifier: public Modifier { 430fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ShuffModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 431fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 432fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 433fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val0 = getRandomVectorValue(); 434fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val1 = getRandomValue(Val0->getType()); 435fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 436fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned Width = cast<VectorType>(Val0->getType())->getNumElements(); 437fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::vector<Constant*> Idxs; 438fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 439fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *I32 = Type::getInt32Ty(BB->getContext()); 440fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (unsigned i=0; i<Width; ++i) { 441fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Constant *CI = ConstantInt::get(I32, Ran->Rand() % (Width*2)); 442fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Pick some undef values. 443fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (!(Ran->Rand() % 5)) 444fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem CI = UndefValue::get(I32); 445fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Idxs.push_back(CI); 446fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 447fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 448fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Constant *Mask = ConstantVector::get(Idxs); 449fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 450fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = new ShuffleVectorInst(Val0, Val1, Mask, "Shuff", 451fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BB->getTerminator()); 452fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PT->push_back(V); 453fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 454fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 455fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 456fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct InsertElementModifier: public Modifier { 457fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem InsertElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): 458fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifier(BB, PT, R) {} 459fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 460fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 461fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val0 = getRandomVectorValue(); 462fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val1 = getRandomValue(Val0->getType()->getScalarType()); 463fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 464fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = InsertElementInst::Create(Val0, Val1, 465fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ConstantInt::get(Type::getInt32Ty(BB->getContext()), 466fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()), 467fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem "I", BB->getTerminator()); 468fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(V); 469fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 470fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 471fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 472fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 473fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct CastModifier: public Modifier { 474fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem CastModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 475fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 476fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 477fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = getRandomVal(); 478fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *VTy = V->getType(); 479fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *DestTy = pickScalarType(); 480fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 481fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Handle vector casts vectors. 482fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy->isVectorTy()) { 483fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem VectorType *VecTy = cast<VectorType>(VTy); 484fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem DestTy = pickVectorType(VecTy->getNumElements()); 485fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 486fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 4877d719a5237d8da0aed188a400b9792b64dae5fc0Nadav Rotem // no need to cast. 488fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy == DestTy) return; 489fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 490fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Pointers: 491fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy->isPointerTy()) { 492fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (!DestTy->isPointerTy()) 493fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem DestTy = PointerType::get(DestTy, 0); 494fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 495fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new BitCastInst(V, DestTy, "PC", BB->getTerminator())); 496fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 497fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 4987d719a5237d8da0aed188a400b9792b64dae5fc0Nadav Rotem unsigned VSize = VTy->getScalarType()->getPrimitiveSizeInBits(); 4997d719a5237d8da0aed188a400b9792b64dae5fc0Nadav Rotem unsigned DestSize = DestTy->getScalarType()->getPrimitiveSizeInBits(); 5007d719a5237d8da0aed188a400b9792b64dae5fc0Nadav Rotem 501fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Generate lots of bitcasts. 5027d719a5237d8da0aed188a400b9792b64dae5fc0Nadav Rotem if ((Ran->Rand() & 1) && VSize == DestSize) { 503fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 504fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new BitCastInst(V, DestTy, "BC", BB->getTerminator())); 505fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 506fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 507fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Both types are integers: 508fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy->getScalarType()->isIntegerTy() && 509fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem DestTy->getScalarType()->isIntegerTy()) { 5107d719a5237d8da0aed188a400b9792b64dae5fc0Nadav Rotem if (VSize > DestSize) { 511fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 512fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new TruncInst(V, DestTy, "Tr", BB->getTerminator())); 513fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } else { 5147d719a5237d8da0aed188a400b9792b64dae5fc0Nadav Rotem assert(VSize < DestSize && "Different int types with the same size?"); 515fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ran->Rand() & 1) 516fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 517fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new ZExtInst(V, DestTy, "ZE", BB->getTerminator())); 518fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(new SExtInst(V, DestTy, "Se", BB->getTerminator())); 519fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 520fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 521fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 522fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Fp to int. 523fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy->getScalarType()->isFloatingPointTy() && 524fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem DestTy->getScalarType()->isIntegerTy()) { 525fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ran->Rand() & 1) 526fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 527fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new FPToSIInst(V, DestTy, "FC", BB->getTerminator())); 528fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(new FPToUIInst(V, DestTy, "FC", BB->getTerminator())); 529fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 530fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 531fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Int to fp. 532fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy->getScalarType()->isIntegerTy() && 533fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem DestTy->getScalarType()->isFloatingPointTy()) { 534fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ran->Rand() & 1) 535fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 536fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new SIToFPInst(V, DestTy, "FC", BB->getTerminator())); 537fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(new UIToFPInst(V, DestTy, "FC", BB->getTerminator())); 538fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 539fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 540fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 541fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Both floats. 542fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy->getScalarType()->isFloatingPointTy() && 543fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem DestTy->getScalarType()->isFloatingPointTy()) { 5447d719a5237d8da0aed188a400b9792b64dae5fc0Nadav Rotem if (VSize > DestSize) { 545fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 546fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new FPTruncInst(V, DestTy, "Tr", BB->getTerminator())); 5477d719a5237d8da0aed188a400b9792b64dae5fc0Nadav Rotem } else if (VSize < DestSize) { 548fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 549fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new FPExtInst(V, DestTy, "ZE", BB->getTerminator())); 550fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 5517d719a5237d8da0aed188a400b9792b64dae5fc0Nadav Rotem // If VSize == DestSize, then the two types must be fp128 and ppc_fp128, 5527d719a5237d8da0aed188a400b9792b64dae5fc0Nadav Rotem // for which there is no defined conversion. So do nothing. 553fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 554fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 555fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 556fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 557fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 558fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct SelectModifier: public Modifier { 559fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem SelectModifier(BasicBlock *BB, PieceTable *PT, Random *R): 560fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifier(BB, PT, R) {} 561fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 562fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 563fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Try a bunch of different select configuration until a valid one is found. 564fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val0 = getRandomVal(); 565fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val1 = getRandomValue(Val0->getType()); 566fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 567fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *CondTy = Type::getInt1Ty(Context); 568fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 569fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // If the value type is a vector, and we allow vector select, then in 50% 570fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // of the cases generate a vector select. 571fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Val0->getType()->isVectorTy() && (Ran->Rand() % 1)) { 572fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned NumElem = cast<VectorType>(Val0->getType())->getNumElements(); 573fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem CondTy = VectorType::get(CondTy, NumElem); 574fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 575fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 576fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Cond = getRandomValue(CondTy); 577fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = SelectInst::Create(Cond, Val0, Val1, "Sl", BB->getTerminator()); 578fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(V); 579fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 580fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 581fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 582fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 583fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct CmpModifier: public Modifier { 584fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem CmpModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 585fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 586fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 587fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val0 = getRandomVal(); 588fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val1 = getRandomValue(Val0->getType()); 589fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 590fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Val0->getType()->isPointerTy()) return; 591fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem bool fp = Val0->getType()->getScalarType()->isFloatingPointTy(); 592fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 593fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem int op; 594fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (fp) { 595fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem op = Ran->Rand() % 596fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem (CmpInst::LAST_FCMP_PREDICATE - CmpInst::FIRST_FCMP_PREDICATE) + 597fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem CmpInst::FIRST_FCMP_PREDICATE; 598fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } else { 599fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem op = Ran->Rand() % 600fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem (CmpInst::LAST_ICMP_PREDICATE - CmpInst::FIRST_ICMP_PREDICATE) + 601fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem CmpInst::FIRST_ICMP_PREDICATE; 602fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 603fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 604fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = CmpInst::Create(fp ? Instruction::FCmp : Instruction::ICmp, 605fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem op, Val0, Val1, "Cmp", BB->getTerminator()); 606fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(V); 607fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 608fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 609fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 6107060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotemvoid FillFunction(Function *F, Random &R) { 611fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Create a legal entry block. 612fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BasicBlock *BB = BasicBlock::Create(F->getContext(), "BB", F); 613fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ReturnInst::Create(F->getContext(), BB); 614fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 615fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Create the value table. 616fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifier::PieceTable PT; 617fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 618fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Consider arguments as legal values. 619fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (Function::arg_iterator it = F->arg_begin(), e = F->arg_end(); 620fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem it != e; ++it) 621fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PT.push_back(it); 622fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 623fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // List of modifiers which add new random instructions. 624fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::vector<Modifier*> Modifiers; 6257375f4f98148fc34f0c7fc765967501cdc65b24eMatt Arsenault OwningPtr<Modifier> LM(new LoadModifier(BB, &PT, &R)); 6267375f4f98148fc34f0c7fc765967501cdc65b24eMatt Arsenault OwningPtr<Modifier> SM(new StoreModifier(BB, &PT, &R)); 6277375f4f98148fc34f0c7fc765967501cdc65b24eMatt Arsenault OwningPtr<Modifier> EE(new ExtractElementModifier(BB, &PT, &R)); 6287375f4f98148fc34f0c7fc765967501cdc65b24eMatt Arsenault OwningPtr<Modifier> SHM(new ShuffModifier(BB, &PT, &R)); 6297375f4f98148fc34f0c7fc765967501cdc65b24eMatt Arsenault OwningPtr<Modifier> IE(new InsertElementModifier(BB, &PT, &R)); 6307375f4f98148fc34f0c7fc765967501cdc65b24eMatt Arsenault OwningPtr<Modifier> BM(new BinModifier(BB, &PT, &R)); 6317375f4f98148fc34f0c7fc765967501cdc65b24eMatt Arsenault OwningPtr<Modifier> CM(new CastModifier(BB, &PT, &R)); 6327375f4f98148fc34f0c7fc765967501cdc65b24eMatt Arsenault OwningPtr<Modifier> SLM(new SelectModifier(BB, &PT, &R)); 6337375f4f98148fc34f0c7fc765967501cdc65b24eMatt Arsenault OwningPtr<Modifier> PM(new CmpModifier(BB, &PT, &R)); 634fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(LM.get()); 635fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(SM.get()); 636fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(EE.get()); 637fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(SHM.get()); 638fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(IE.get()); 639fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(BM.get()); 640fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(CM.get()); 641fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(SLM.get()); 642fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(PM.get()); 643fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 644fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Generate the random instructions 645fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem AllocaModifier AM(BB, &PT, &R); AM.ActN(5); // Throw in a few allocas 646fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ConstModifier COM(BB, &PT, &R); COM.ActN(40); // Throw in a few constants 647fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 648fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (unsigned i=0; i< SizeCL / Modifiers.size(); ++i) 649fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (std::vector<Modifier*>::iterator it = Modifiers.begin(), 650fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem e = Modifiers.end(); it != e; ++it) { 651fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem (*it)->Act(); 652fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 653fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 654fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem SM->ActN(5); // Throw in a few stores. 655fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem} 656fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 6577060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotemvoid IntroduceControlFlow(Function *F, Random &R) { 6587060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem std::vector<Instruction*> BoolInst; 659fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (BasicBlock::iterator it = F->begin()->begin(), 660fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem e = F->begin()->end(); it != e; ++it) { 661fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (it->getType() == IntegerType::getInt1Ty(F->getContext())) 6627060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem BoolInst.push_back(it); 663fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 664fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 6657060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem std::random_shuffle(BoolInst.begin(), BoolInst.end(), R); 6667060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem 6677060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem for (std::vector<Instruction*>::iterator it = BoolInst.begin(), 668fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem e = BoolInst.end(); it != e; ++it) { 669fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Instruction *Instr = *it; 670fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BasicBlock *Curr = Instr->getParent(); 671fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BasicBlock::iterator Loc= Instr; 672fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BasicBlock *Next = Curr->splitBasicBlock(Loc, "CF"); 673fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Instr->moveBefore(Curr->getTerminator()); 674fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Curr != &F->getEntryBlock()) { 675fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BranchInst::Create(Curr, Next, Instr, Curr->getTerminator()); 676fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Curr->getTerminator()->eraseFromParent(); 677fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 678fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 679fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem} 680fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 681fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemint main(int argc, char **argv) { 682fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Init LLVM, call llvm_shutdown() on exit, parse args, etc. 683fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem llvm::PrettyStackTraceProgram X(argc, argv); 684fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem cl::ParseCommandLineOptions(argc, argv, "llvm codegen stress-tester\n"); 685fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem llvm_shutdown_obj Y; 686fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 6877375f4f98148fc34f0c7fc765967501cdc65b24eMatt Arsenault OwningPtr<Module> M(new Module("/tmp/autogen.bc", getGlobalContext())); 688fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Function *F = GenEmptyFunction(M.get()); 6897060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem 6907060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem // Pick an initial seed value 6917060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem Random R(SeedCL); 6927060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem // Generate lots of random instructions inside a single basic block. 6937060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem FillFunction(F, R); 6947060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem // Break the basic block into many loops. 6957060221ae256ded2b7bbfec60a2c9bdc71426ff2Nadav Rotem IntroduceControlFlow(F, R); 696fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 697fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Figure out what stream we are supposed to write to... 698fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem OwningPtr<tool_output_file> Out; 699fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Default to standard output. 700fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (OutputFilename.empty()) 701fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem OutputFilename = "-"; 702fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 703fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::string ErrorInfo; 704fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, 705c1b49b56d4132efa2e06deb8f23508d0de4c8800Rafael Espindola sys::fs::F_Binary)); 706fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (!ErrorInfo.empty()) { 707fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem errs() << ErrorInfo << '\n'; 708fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return 1; 709fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 710fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 711fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PassManager Passes; 712fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Passes.add(createVerifierPass()); 713fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Passes.add(createPrintModulePass(&Out->os())); 714fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Passes.run(*M.get()); 715fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Out->keep(); 716fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 717fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return 0; 718fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem} 719