llvm-stress.cpp revision 2cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513
1c367dfc2f458e30249544ea2c8b05c956b419162Nadav Rotem//===-- 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//===----------------------------------------------------------------------===// 14fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/LLVMContext.h" 15fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Module.h" 16fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/PassManager.h" 17fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Constants.h" 18fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Instruction.h" 19fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/CallGraphSCCPass.h" 20fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Assembly/PrintModulePass.h" 21fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Analysis/Verifier.h" 22fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Support/PassNameParser.h" 23fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Support/Debug.h" 24fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Support/ManagedStatic.h" 25fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Support/PluginLoader.h" 26fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Support/PrettyStackTrace.h" 27fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include "llvm/Support/ToolOutputFile.h" 28fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include <memory> 29fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include <sstream> 30fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include <set> 31fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include <vector> 32fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem#include <algorithm> 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) {} 63fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Return the next random value. 64fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned Rand() { 65fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned Val = Seed + 0x000b07a1; 66fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Seed = (Val * 0x3c7c0ac1); 67fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Only lowest 19 bits are random-ish. 68fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return Seed & 0x7ffff; 69fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 70fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 71fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemprivate: 72fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned Seed; 73fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 74fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 75fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem/// Generate an empty function with a default argument list. 76fdc309cc4e95778d7615f3829917c4fe42086e1eNadav RotemFunction *GenEmptyFunction(Module *M) { 77fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Type Definitions 78fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::vector<Type*> ArgsTy; 79fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Define a few arguments 80fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem LLVMContext &Context = M->getContext(); 81fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ArgsTy.push_back(PointerType::get(IntegerType::getInt8Ty(Context), 0)); 82fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ArgsTy.push_back(PointerType::get(IntegerType::getInt32Ty(Context), 0)); 83fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ArgsTy.push_back(PointerType::get(IntegerType::getInt64Ty(Context), 0)); 84fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ArgsTy.push_back(IntegerType::getInt32Ty(Context)); 85fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ArgsTy.push_back(IntegerType::getInt64Ty(Context)); 86fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ArgsTy.push_back(IntegerType::getInt8Ty(Context)); 87fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 88fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem FunctionType *FuncTy = FunctionType::get(Type::getVoidTy(Context), ArgsTy, 0); 89fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Pick a unique name to describe the input parameters 90fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::stringstream ss; 91fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ss<<"autogen_SD"<<SeedCL; 92fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Function *Func = Function::Create(FuncTy, GlobalValue::ExternalLinkage, 93fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ss.str(), M); 94fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 95fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Func->setCallingConv(CallingConv::C); 96fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return Func; 97fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem} 98fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 99fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem/// A base class, implementing utilities needed for 100fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem/// modifying and adding new random instructions. 101fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct Modifier { 102fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Used to store the randomly generated values. 103fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem typedef std::vector<Value*> PieceTable; 104fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 105fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotempublic: 106fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// C'tor 10708c833930726d5c33baac060a7aca7c1caf636b3Nadav Rotem Modifier(BasicBlock *Block, PieceTable *PT, Random *R): 10808c833930726d5c33baac060a7aca7c1caf636b3Nadav Rotem BB(Block),PT(PT),Ran(R),Context(BB->getContext()) {}; 109fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Add a new instruction. 110fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() = 0; 111fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Add N new instructions, 112fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void ActN(unsigned n) { 113fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (unsigned i=0; i<n; ++i) 114fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Act(); 115fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 116fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 117fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemprotected: 118fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Return a random value from the list of known values. 119fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *getRandomVal() { 120fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem assert(PT->size()); 121fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->at(Ran->Rand() % PT->size()); 122fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 123fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 124bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem Constant *getRandomConstant(Type *Tp) { 125bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem if (Tp->isIntegerTy()) { 126bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem if (Ran->Rand() & 1) 127bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem return ConstantInt::getAllOnesValue(Tp); 128bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem return ConstantInt::getNullValue(Tp); 129bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem } else if (Tp->isFloatingPointTy()) { 130bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem if (Ran->Rand() & 1) 131bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem return ConstantFP::getAllOnesValue(Tp); 132bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem return ConstantFP::getNullValue(Tp); 133bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem } 134bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem return UndefValue::get(Tp); 135bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem } 136bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem 137fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Return a random value with a known type. 138fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *getRandomValue(Type *Tp) { 139fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned index = Ran->Rand(); 140fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (unsigned i=0; i<PT->size(); ++i) { 141fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = PT->at((index + i) % PT->size()); 142fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (V->getType() == Tp) 143fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return V; 144fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 145fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 146fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // If the requested type was not found, generate a constant value. 147fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Tp->isIntegerTy()) { 148fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ran->Rand() & 1) 149fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return ConstantInt::getAllOnesValue(Tp); 150fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return ConstantInt::getNullValue(Tp); 151fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } else if (Tp->isFloatingPointTy()) { 152fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ran->Rand() & 1) 153fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return ConstantFP::getAllOnesValue(Tp); 154fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return ConstantFP::getNullValue(Tp); 155bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem } else if (Tp->isVectorTy()) { 156bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem VectorType *VTp = cast<VectorType>(Tp); 157bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem 158bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem std::vector<Constant*> TempValues; 159bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem TempValues.reserve(VTp->getNumElements()); 160bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem for (unsigned i = 0; i < VTp->getNumElements(); ++i) 161bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem TempValues.push_back(getRandomConstant(VTp->getScalarType())); 162bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem 163bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem ArrayRef<Constant*> VectorValue(TempValues); 164bfb7dfa756ffa48d2c968ffcade3295938495b6eNadav Rotem return ConstantVector::get(VectorValue); 165fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 166fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 167fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return UndefValue::get(Tp); 168fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 169fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 170fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Return a random value of any pointer type. 171fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *getRandomPointerValue() { 172fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned index = Ran->Rand(); 173fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (unsigned i=0; i<PT->size(); ++i) { 174fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = PT->at((index + i) % PT->size()); 175fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (V->getType()->isPointerTy()) 176fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return V; 177fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 178fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return UndefValue::get(pickPointerType()); 179fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 180fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 181fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Return a random value of any vector type. 182fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *getRandomVectorValue() { 183fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned index = Ran->Rand(); 184fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (unsigned i=0; i<PT->size(); ++i) { 185fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = PT->at((index + i) % PT->size()); 186fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (V->getType()->isVectorTy()) 187fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return V; 188fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 189fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return UndefValue::get(pickVectorType()); 190fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 191fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 192fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Pick a random type. 193fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *pickType() { 194fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return (Ran->Rand() & 1 ? pickVectorType() : pickScalarType()); 195fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 196fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 197fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Pick a random pointer type. 198fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *pickPointerType() { 199fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *Ty = pickType(); 200fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PointerType::get(Ty, 0); 201fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 202fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 203fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Pick a random vector type. 204fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *pickVectorType(unsigned len = (unsigned)-1) { 205fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *Ty = pickScalarType(); 206fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Pick a random vector width in the range 2**0 to 2**4. 207fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // by adding two randoms we are generating a normal-like distribution 208fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // around 2**3. 209fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned width = 1<<((Ran->Rand() % 3) + (Ran->Rand() % 3)); 210fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (len != (unsigned)-1) 211fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem width = len; 212fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return VectorType::get(Ty, width); 213fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 214fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 215fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Pick a random scalar type. 216fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *pickScalarType() { 2172cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel Type *t = 0; 2182cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel do { 2192cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel switch (Ran->Rand() % 30) { 2202cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 0: t = Type::getInt1Ty(Context); break; 2212cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 1: t = Type::getInt8Ty(Context); break; 2222cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 2: t = Type::getInt16Ty(Context); break; 2232cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 3: case 4: 2242cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 5: t = Type::getFloatTy(Context); break; 2252cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 6: case 7: 2262cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 8: t = Type::getDoubleTy(Context); break; 2272cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 9: case 10: 2282cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 11: t = Type::getInt32Ty(Context); break; 2292cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 12: case 13: 2302cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 14: t = Type::getInt64Ty(Context); break; 2312cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 15: case 16: 2322cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 17: if (GenHalfFloat) t = Type::getHalfTy(Context); break; 2332cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 18: case 19: 2342cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 20: if (GenX86FP80) t = Type::getX86_FP80Ty(Context); break; 2352cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 21: case 22: 2362cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 23: if (GenFP128) t = Type::getFP128Ty(Context); break; 2372cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 24: case 25: 2382cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 26: if (GenPPCFP128) t = Type::getPPC_FP128Ty(Context); break; 2392cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 27: case 28: 2402cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel case 29: if (GenX86MMX) t = Type::getX86_MMXTy(Context); break; 2412cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel default: llvm_unreachable("Invalid scalar value"); 2422cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel } 2432cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel } while (t == 0); 2442cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel 2452cff6179ab40fc92ec5b6302b9ab5f7b0ee1e513Hal Finkel return t; 246fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 247fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 248fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Basic block to populate 249fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BasicBlock *BB; 250fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Value table 251fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PieceTable *PT; 252fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Random number generator 253fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Random *Ran; 254fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem /// Context 255fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem LLVMContext &Context; 256fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 257fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 258fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct LoadModifier: public Modifier { 259fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem LoadModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}; 260fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 261fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Try to use predefined pointers. If non exist, use undef pointer value; 262fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Ptr = getRandomPointerValue(); 263fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = new LoadInst(Ptr, "L", BB->getTerminator()); 264fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PT->push_back(V); 265fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 266fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 267fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 268fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct StoreModifier: public Modifier { 269fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem StoreModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 270fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 271fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Try to use predefined pointers. If non exist, use undef pointer value; 272fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Ptr = getRandomPointerValue(); 273fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *Tp = Ptr->getType(); 274fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val = getRandomValue(Tp->getContainedType(0)); 2752e851a9abf781bc5feef9be98f794dcb1caab548Nadav Rotem Type *ValTy = Val->getType(); 276fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 277fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Do not store vectors of i1s because they are unsupported 278794c16ae856f827babb22f862f4e69118ad68b09Nadav Rotem // by the codegen. 279794c16ae856f827babb22f862f4e69118ad68b09Nadav Rotem if (ValTy->isVectorTy() && ValTy->getScalarSizeInBits() == 1) 280fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return; 281fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 282fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new StoreInst(Val, Ptr, BB->getTerminator()); 283fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 284fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 285fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 286fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct BinModifier: public Modifier { 287fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BinModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 288fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 289fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 290fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val0 = getRandomVal(); 291fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val1 = getRandomValue(Val0->getType()); 292fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 293fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Don't handle pointer types. 294fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Val0->getType()->isPointerTy() || 295fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Val1->getType()->isPointerTy()) 296fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return; 297fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 298fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Don't handle i1 types. 299fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Val0->getType()->getScalarSizeInBits() == 1) 300fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return; 301fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 302fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 303fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem bool isFloat = Val0->getType()->getScalarType()->isFloatingPointTy(); 304fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Instruction* Term = BB->getTerminator(); 305fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned R = Ran->Rand() % (isFloat ? 7 : 13); 306fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Instruction::BinaryOps Op; 307fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 308fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem switch (R) { 309fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem default: llvm_unreachable("Invalid BinOp"); 310fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 0:{Op = (isFloat?Instruction::FAdd : Instruction::Add); break; } 311fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 1:{Op = (isFloat?Instruction::FSub : Instruction::Sub); break; } 312fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 2:{Op = (isFloat?Instruction::FMul : Instruction::Mul); break; } 313fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 3:{Op = (isFloat?Instruction::FDiv : Instruction::SDiv); break; } 314fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 4:{Op = (isFloat?Instruction::FDiv : Instruction::UDiv); break; } 315fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 5:{Op = (isFloat?Instruction::FRem : Instruction::SRem); break; } 316fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 6:{Op = (isFloat?Instruction::FRem : Instruction::URem); break; } 317fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 7: {Op = Instruction::Shl; break; } 318fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 8: {Op = Instruction::LShr; break; } 319fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 9: {Op = Instruction::AShr; break; } 320fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 10:{Op = Instruction::And; break; } 321fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 11:{Op = Instruction::Or; break; } 322fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 12:{Op = Instruction::Xor; break; } 323fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 324fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 325fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PT->push_back(BinaryOperator::Create(Op, Val0, Val1, "B", Term)); 326fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 327fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 328fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 329fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem/// Generate constant values. 330fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct ConstModifier: public Modifier { 331fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ConstModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 332fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 333fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *Ty = pickType(); 334fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 335fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ty->isVectorTy()) { 336fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem switch (Ran->Rand() % 2) { 337fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 0: if (Ty->getScalarType()->isIntegerTy()) 338fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(ConstantVector::getAllOnesValue(Ty)); 339fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 1: if (Ty->getScalarType()->isIntegerTy()) 340fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(ConstantVector::getNullValue(Ty)); 341fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 342fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 343fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 344fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ty->isFloatingPointTy()) { 345fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ran->Rand() & 1) 346fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(ConstantFP::getNullValue(Ty)); 347fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(ConstantFP::get(Ty, 348fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem static_cast<double>(1)/Ran->Rand())); 349fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 350fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 351fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ty->isIntegerTy()) { 352fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem switch (Ran->Rand() % 7) { 353fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 0: if (Ty->isIntegerTy()) 354fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(ConstantInt::get(Ty, 355fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem APInt::getAllOnesValue(Ty->getPrimitiveSizeInBits()))); 356fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 1: if (Ty->isIntegerTy()) 357fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(ConstantInt::get(Ty, 358fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem APInt::getNullValue(Ty->getPrimitiveSizeInBits()))); 359fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 2: case 3: case 4: case 5: 360fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem case 6: if (Ty->isIntegerTy()) 361fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PT->push_back(ConstantInt::get(Ty, Ran->Rand())); 362fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 363fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 364fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 365fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 366fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 367fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 368fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct AllocaModifier: public Modifier { 369fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem AllocaModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R){} 370fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 371fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 372fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *Tp = pickType(); 373fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PT->push_back(new AllocaInst(Tp, "A", BB->getFirstNonPHI())); 374fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 375fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 376fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 377fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct ExtractElementModifier: public Modifier { 378fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ExtractElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): 379fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifier(BB, PT, R) {} 380fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 381fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 382fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val0 = getRandomVectorValue(); 383fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = ExtractElementInst::Create(Val0, 384fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ConstantInt::get(Type::getInt32Ty(BB->getContext()), 385fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()), 386fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem "E", BB->getTerminator()); 387fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(V); 388fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 389fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 390fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 391fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct ShuffModifier: public Modifier { 392fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ShuffModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 393fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 394fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 395fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val0 = getRandomVectorValue(); 396fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val1 = getRandomValue(Val0->getType()); 397fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 398fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned Width = cast<VectorType>(Val0->getType())->getNumElements(); 399fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::vector<Constant*> Idxs; 400fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 401fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *I32 = Type::getInt32Ty(BB->getContext()); 402fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (unsigned i=0; i<Width; ++i) { 403fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Constant *CI = ConstantInt::get(I32, Ran->Rand() % (Width*2)); 404fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Pick some undef values. 405fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (!(Ran->Rand() % 5)) 406fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem CI = UndefValue::get(I32); 407fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Idxs.push_back(CI); 408fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 409fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 410fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Constant *Mask = ConstantVector::get(Idxs); 411fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 412fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = new ShuffleVectorInst(Val0, Val1, Mask, "Shuff", 413fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BB->getTerminator()); 414fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PT->push_back(V); 415fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 416fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 417fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 418fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct InsertElementModifier: public Modifier { 419fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem InsertElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): 420fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifier(BB, PT, R) {} 421fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 422fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 423fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val0 = getRandomVectorValue(); 424fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val1 = getRandomValue(Val0->getType()->getScalarType()); 425fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 426fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = InsertElementInst::Create(Val0, Val1, 427fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ConstantInt::get(Type::getInt32Ty(BB->getContext()), 428fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()), 429fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem "I", BB->getTerminator()); 430fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(V); 431fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 432fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 433fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 434fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 435fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct CastModifier: public Modifier { 436fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem CastModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 437fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 438fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 439fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = getRandomVal(); 440fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *VTy = V->getType(); 441fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *DestTy = pickScalarType(); 442fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 443fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Handle vector casts vectors. 444fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy->isVectorTy()) { 445fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem VectorType *VecTy = cast<VectorType>(VTy); 446fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem DestTy = pickVectorType(VecTy->getNumElements()); 447fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 448fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 449fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // no need to casr. 450fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy == DestTy) return; 451fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 452fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Pointers: 453fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy->isPointerTy()) { 454fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (!DestTy->isPointerTy()) 455fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem DestTy = PointerType::get(DestTy, 0); 456fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 457fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new BitCastInst(V, DestTy, "PC", BB->getTerminator())); 458fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 459fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 460fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Generate lots of bitcasts. 461fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if ((Ran->Rand() & 1) && 462fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem VTy->getPrimitiveSizeInBits() == DestTy->getPrimitiveSizeInBits()) { 463fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 464fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new BitCastInst(V, DestTy, "BC", BB->getTerminator())); 465fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 466fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 467fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Both types are integers: 468fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy->getScalarType()->isIntegerTy() && 469fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem DestTy->getScalarType()->isIntegerTy()) { 470fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy->getScalarType()->getPrimitiveSizeInBits() > 471fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem DestTy->getScalarType()->getPrimitiveSizeInBits()) { 472fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 473fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new TruncInst(V, DestTy, "Tr", BB->getTerminator())); 474fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } else { 475fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ran->Rand() & 1) 476fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 477fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new ZExtInst(V, DestTy, "ZE", BB->getTerminator())); 478fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(new SExtInst(V, DestTy, "Se", BB->getTerminator())); 479fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 480fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 481fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 482fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Fp to int. 483fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy->getScalarType()->isFloatingPointTy() && 484fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem DestTy->getScalarType()->isIntegerTy()) { 485fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ran->Rand() & 1) 486fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 487fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new FPToSIInst(V, DestTy, "FC", BB->getTerminator())); 488fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(new FPToUIInst(V, DestTy, "FC", BB->getTerminator())); 489fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 490fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 491fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Int to fp. 492fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy->getScalarType()->isIntegerTy() && 493fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem DestTy->getScalarType()->isFloatingPointTy()) { 494fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Ran->Rand() & 1) 495fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 496fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new SIToFPInst(V, DestTy, "FC", BB->getTerminator())); 497fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(new UIToFPInst(V, DestTy, "FC", BB->getTerminator())); 498fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 499fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 500fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 501fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Both floats. 502fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy->getScalarType()->isFloatingPointTy() && 503fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem DestTy->getScalarType()->isFloatingPointTy()) { 504fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (VTy->getScalarType()->getPrimitiveSizeInBits() > 505fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem DestTy->getScalarType()->getPrimitiveSizeInBits()) { 506fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 507fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new FPTruncInst(V, DestTy, "Tr", BB->getTerminator())); 508fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } else { 509fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back( 510fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem new FPExtInst(V, DestTy, "ZE", BB->getTerminator())); 511fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 512fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 513fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 514fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 515fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 516fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 517fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct SelectModifier: public Modifier { 518fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem SelectModifier(BasicBlock *BB, PieceTable *PT, Random *R): 519fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifier(BB, PT, R) {} 520fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 521fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 522fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Try a bunch of different select configuration until a valid one is found. 523fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val0 = getRandomVal(); 524fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val1 = getRandomValue(Val0->getType()); 525fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 526fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Type *CondTy = Type::getInt1Ty(Context); 527fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 528fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // If the value type is a vector, and we allow vector select, then in 50% 529fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // of the cases generate a vector select. 530fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Val0->getType()->isVectorTy() && (Ran->Rand() % 1)) { 531fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem unsigned NumElem = cast<VectorType>(Val0->getType())->getNumElements(); 532fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem CondTy = VectorType::get(CondTy, NumElem); 533fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 534fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 535fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Cond = getRandomValue(CondTy); 536fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = SelectInst::Create(Cond, Val0, Val1, "Sl", BB->getTerminator()); 537fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(V); 538fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 539fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 540fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 541fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 542fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemstruct CmpModifier: public Modifier { 543fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem CmpModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} 544fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem virtual void Act() { 545fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 546fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val0 = getRandomVal(); 547fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *Val1 = getRandomValue(Val0->getType()); 548fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 549fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Val0->getType()->isPointerTy()) return; 550fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem bool fp = Val0->getType()->getScalarType()->isFloatingPointTy(); 551fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 552fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem int op; 553fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (fp) { 554fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem op = Ran->Rand() % 555fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem (CmpInst::LAST_FCMP_PREDICATE - CmpInst::FIRST_FCMP_PREDICATE) + 556fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem CmpInst::FIRST_FCMP_PREDICATE; 557fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } else { 558fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem op = Ran->Rand() % 559fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem (CmpInst::LAST_ICMP_PREDICATE - CmpInst::FIRST_ICMP_PREDICATE) + 560fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem CmpInst::FIRST_ICMP_PREDICATE; 561fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 562fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 563fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Value *V = CmpInst::Create(fp ? Instruction::FCmp : Instruction::ICmp, 564fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem op, Val0, Val1, "Cmp", BB->getTerminator()); 565fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return PT->push_back(V); 566fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 567fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem}; 568fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 569fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemvoid FillFunction(Function *F) { 570fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Create a legal entry block. 571fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BasicBlock *BB = BasicBlock::Create(F->getContext(), "BB", F); 572fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ReturnInst::Create(F->getContext(), BB); 573fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 574fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Create the value table. 575fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifier::PieceTable PT; 576fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Pick an initial seed value 577fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Random R(SeedCL); 578fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 579fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Consider arguments as legal values. 580fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (Function::arg_iterator it = F->arg_begin(), e = F->arg_end(); 581fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem it != e; ++it) 582fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PT.push_back(it); 583fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 584fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // List of modifiers which add new random instructions. 585fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::vector<Modifier*> Modifiers; 586fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::auto_ptr<Modifier> LM(new LoadModifier(BB, &PT, &R)); 587fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::auto_ptr<Modifier> SM(new StoreModifier(BB, &PT, &R)); 588fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::auto_ptr<Modifier> EE(new ExtractElementModifier(BB, &PT, &R)); 589fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::auto_ptr<Modifier> SHM(new ShuffModifier(BB, &PT, &R)); 590fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::auto_ptr<Modifier> IE(new InsertElementModifier(BB, &PT, &R)); 591fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::auto_ptr<Modifier> BM(new BinModifier(BB, &PT, &R)); 592fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::auto_ptr<Modifier> CM(new CastModifier(BB, &PT, &R)); 593fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::auto_ptr<Modifier> SLM(new SelectModifier(BB, &PT, &R)); 594fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::auto_ptr<Modifier> PM(new CmpModifier(BB, &PT, &R)); 595fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(LM.get()); 596fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(SM.get()); 597fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(EE.get()); 598fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(SHM.get()); 599fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(IE.get()); 600fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(BM.get()); 601fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(CM.get()); 602fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(SLM.get()); 603fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Modifiers.push_back(PM.get()); 604fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 605fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Generate the random instructions 606fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem AllocaModifier AM(BB, &PT, &R); AM.ActN(5); // Throw in a few allocas 607fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem ConstModifier COM(BB, &PT, &R); COM.ActN(40); // Throw in a few constants 608fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 609fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (unsigned i=0; i< SizeCL / Modifiers.size(); ++i) 610fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (std::vector<Modifier*>::iterator it = Modifiers.begin(), 611fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem e = Modifiers.end(); it != e; ++it) { 612fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem (*it)->Act(); 613fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 614fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 615fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem SM->ActN(5); // Throw in a few stores. 616fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem} 617fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 618fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemvoid IntroduceControlFlow(Function *F) { 619fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::set<Instruction*> BoolInst; 620fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (BasicBlock::iterator it = F->begin()->begin(), 621fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem e = F->begin()->end(); it != e; ++it) { 622fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (it->getType() == IntegerType::getInt1Ty(F->getContext())) 623fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BoolInst.insert(it); 624fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 625fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 626fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem for (std::set<Instruction*>::iterator it = BoolInst.begin(), 627fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem e = BoolInst.end(); it != e; ++it) { 628fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Instruction *Instr = *it; 629fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BasicBlock *Curr = Instr->getParent(); 630fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BasicBlock::iterator Loc= Instr; 631fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BasicBlock *Next = Curr->splitBasicBlock(Loc, "CF"); 632fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Instr->moveBefore(Curr->getTerminator()); 633fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (Curr != &F->getEntryBlock()) { 634fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem BranchInst::Create(Curr, Next, Instr, Curr->getTerminator()); 635fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Curr->getTerminator()->eraseFromParent(); 636fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 637fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 638fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem} 639fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 640fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotemint main(int argc, char **argv) { 641fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Init LLVM, call llvm_shutdown() on exit, parse args, etc. 642fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem llvm::PrettyStackTraceProgram X(argc, argv); 643fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem cl::ParseCommandLineOptions(argc, argv, "llvm codegen stress-tester\n"); 644fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem llvm_shutdown_obj Y; 645fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 646fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::auto_ptr<Module> M(new Module("/tmp/autogen.bc", getGlobalContext())); 647fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Function *F = GenEmptyFunction(M.get()); 648fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem FillFunction(F); 649fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem IntroduceControlFlow(F); 650fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 651fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Figure out what stream we are supposed to write to... 652fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem OwningPtr<tool_output_file> Out; 653fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem // Default to standard output. 654fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (OutputFilename.empty()) 655fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem OutputFilename = "-"; 656fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 657fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem std::string ErrorInfo; 658fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, 659fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem raw_fd_ostream::F_Binary)); 660fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem if (!ErrorInfo.empty()) { 661fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem errs() << ErrorInfo << '\n'; 662fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return 1; 663fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem } 664fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 665fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem PassManager Passes; 666fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Passes.add(createVerifierPass()); 667fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Passes.add(createPrintModulePass(&Out->os())); 668fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Passes.run(*M.get()); 669fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem Out->keep(); 670fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem 671fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem return 0; 672fdc309cc4e95778d7615f3829917c4fe42086e1eNadav Rotem} 673