Index: tools/llvm-stress/llvm-stress.cpp =================================================================== --- tools/llvm-stress/llvm-stress.cpp +++ tools/llvm-stress/llvm-stress.cpp @@ -78,52 +78,6 @@ "(always includes i1, i8, i16, i32, i64, float and double)")); namespace { -/// A utility class to provide a pseudo-random number generator which is -/// the same across all platforms. This is somewhat close to the libc -/// implementation. Note: This is not a cryptographically secure pseudorandom -/// number generator. -class Random { -public: - /// C'tor - Random(unsigned _seed):Seed(_seed) {} - - /// Return a random integer, up to a - /// maximum of 2**19 - 1. - uint32_t Rand() { - uint32_t Val = Seed + 0x000b07a1; - Seed = (Val * 0x3c7c0ac1); - // Only lowest 19 bits are random-ish. - return Seed & 0x7ffff; - } - - /// Return a random 32 bit integer. - uint32_t Rand32() { - uint32_t Val = Rand(); - Val &= 0xffff; - return Val | (Rand() << 16); - } - - /// Return a random 64 bit integer. - uint64_t Rand64() { - uint64_t Val = Rand32(); - return Val | (uint64_t(Rand32()) << 32); - } - - /// Rand operator for STL algorithms. - ptrdiff_t operator()(ptrdiff_t y) { - return Rand64() % y; - } - - /// Make this like a C++11 random device - typedef uint32_t result_type; - uint32_t operator()() { return Rand32(); } - static constexpr result_type min() { return 0; } - static constexpr result_type max() { return 0x7ffff; } - -private: - unsigned Seed; -}; - /// Generate an empty function with a default argument list. Function *GenEmptyFunction(Module *M) { // Define a few arguments @@ -153,7 +107,7 @@ public: /// C'tor - Modifier(BasicBlock *Block, PieceTable *PT, Random *R): + Modifier(BasicBlock *Block, PieceTable *PT, std::mt19937_64 *R): BB(Block),PT(PT),Ran(R),Context(BB->getContext()) {} /// virtual D'tor to silence warnings. @@ -171,16 +125,16 @@ /// Return a random value from the list of known values. Value *getRandomVal() { assert(PT->size()); - return PT->at(Ran->Rand() % PT->size()); + return PT->at((*Ran)() % PT->size()); } Constant *getRandomConstant(Type *Tp) { if (Tp->isIntegerTy()) { - if (Ran->Rand() & 1) + if ((*Ran)() & 1) return ConstantInt::getAllOnesValue(Tp); return ConstantInt::getNullValue(Tp); } else if (Tp->isFloatingPointTy()) { - if (Ran->Rand() & 1) + if ((*Ran)() & 1) return ConstantFP::getAllOnesValue(Tp); return ConstantFP::getNullValue(Tp); } @@ -189,7 +143,7 @@ /// Return a random value with a known type. Value *getRandomValue(Type *Tp) { - unsigned index = Ran->Rand(); + unsigned index = (*Ran)(); for (unsigned i=0; isize(); ++i) { Value *V = PT->at((index + i) % PT->size()); if (V->getType() == Tp) @@ -198,11 +152,11 @@ // If the requested type was not found, generate a constant value. if (Tp->isIntegerTy()) { - if (Ran->Rand() & 1) + if ((*Ran)() & 1) return ConstantInt::getAllOnesValue(Tp); return ConstantInt::getNullValue(Tp); } else if (Tp->isFloatingPointTy()) { - if (Ran->Rand() & 1) + if ((*Ran)() & 1) return ConstantFP::getAllOnesValue(Tp); return ConstantFP::getNullValue(Tp); } else if (Tp->isVectorTy()) { @@ -222,7 +176,7 @@ /// Return a random value of any pointer type. Value *getRandomPointerValue() { - unsigned index = Ran->Rand(); + unsigned index = (*Ran)(); for (unsigned i=0; isize(); ++i) { Value *V = PT->at((index + i) % PT->size()); if (V->getType()->isPointerTy()) @@ -233,7 +187,7 @@ /// Return a random value of any vector type. Value *getRandomVectorValue() { - unsigned index = Ran->Rand(); + unsigned index = (*Ran)(); for (unsigned i=0; isize(); ++i) { Value *V = PT->at((index + i) % PT->size()); if (V->getType()->isVectorTy()) @@ -244,7 +198,7 @@ /// Pick a random type. Type *pickType() { - return (Ran->Rand() & 1 ? pickVectorType() : pickScalarType()); + return ((*Ran)() & 1 ? pickVectorType() : pickScalarType()); } /// Pick a random pointer type. @@ -258,7 +212,7 @@ // Pick a random vector width in the range 2**0 to 2**4. // by adding two randoms we are generating a normal-like distribution // around 2**3. - unsigned width = 1<<((Ran->Rand() % 3) + (Ran->Rand() % 3)); + unsigned width = 1<<(((*Ran)() % 3) + ((*Ran)() % 3)); Type *Ty; // Vectors of x86mmx are illegal; keep trying till we get something else. @@ -288,7 +242,7 @@ AdditionalScalarTypes.begin(), AdditionalScalarTypes.end()); } - return ScalarTypes[Ran->Rand() % ScalarTypes.size()]; + return ScalarTypes[(*Ran)() % ScalarTypes.size()]; } /// Basic block to populate @@ -296,13 +250,15 @@ /// Value table PieceTable *PT; /// Random number generator - Random *Ran; + std::mt19937_64 *Ran; /// Context LLVMContext &Context; }; struct LoadModifier: public Modifier { - LoadModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + LoadModifier(BasicBlock *BB, PieceTable *PT, std::mt19937_64 *R): + Modifier(BB, PT, R) {} + void Act() override { // Try to use predefined pointers. If non-exist, use undef pointer value; Value *Ptr = getRandomPointerValue(); @@ -312,7 +268,9 @@ }; struct StoreModifier: public Modifier { - StoreModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + StoreModifier(BasicBlock *BB, PieceTable *PT, std::mt19937_64 *R): + Modifier(BB, PT, R) {} + void Act() override { // Try to use predefined pointers. If non-exist, use undef pointer value; Value *Ptr = getRandomPointerValue(); @@ -330,7 +288,8 @@ }; struct BinModifier: public Modifier { - BinModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + BinModifier(BasicBlock *BB, PieceTable *PT, std::mt19937_64 *R): + Modifier(BB, PT, R) {} void Act() override { Value *Val0 = getRandomVal(); @@ -348,7 +307,7 @@ bool isFloat = Val0->getType()->getScalarType()->isFloatingPointTy(); Instruction* Term = BB->getTerminator(); - unsigned R = Ran->Rand() % (isFloat ? 7 : 13); + unsigned R = (*Ran)() % (isFloat ? 7 : 13); Instruction::BinaryOps Op; switch (R) { @@ -374,12 +333,14 @@ /// Generate constant values. struct ConstModifier: public Modifier { - ConstModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + ConstModifier(BasicBlock *BB, PieceTable *PT, std::mt19937_64 *R): + Modifier(BB, PT, R) {} + void Act() override { Type *Ty = pickType(); if (Ty->isVectorTy()) { - switch (Ran->Rand() % 2) { + switch ((*Ran)() % 2) { case 0: if (Ty->getScalarType()->isIntegerTy()) return PT->push_back(ConstantVector::getAllOnesValue(Ty)); break; @@ -393,18 +354,18 @@ // largest floating-point types. uint64_t RandomBits[2]; for (unsigned i = 0; i < 2; ++i) - RandomBits[i] = Ran->Rand64(); + RandomBits[i] = (*Ran)(); APInt RandomInt(Ty->getPrimitiveSizeInBits(), makeArrayRef(RandomBits)); APFloat RandomFloat(Ty->getFltSemantics(), RandomInt); - if (Ran->Rand() & 1) + if ((*Ran)() & 1) return PT->push_back(ConstantFP::getNullValue(Ty)); return PT->push_back(ConstantFP::get(Ty->getContext(), RandomFloat)); } if (Ty->isIntegerTy()) { - switch (Ran->Rand() % 7) { + switch ((*Ran)() % 7) { case 0: return PT->push_back(ConstantInt::get( Ty, APInt::getAllOnesValue(Ty->getPrimitiveSizeInBits()))); @@ -413,7 +374,7 @@ Ty, APInt::getNullValue(Ty->getPrimitiveSizeInBits()))); case 2: case 3: case 4: case 5: case 6: - PT->push_back(ConstantInt::get(Ty, Ran->Rand())); + PT->push_back(ConstantInt::get(Ty, (*Ran)())); } } @@ -421,7 +382,8 @@ }; struct AllocaModifier: public Modifier { - AllocaModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R){} + AllocaModifier(BasicBlock *BB, PieceTable *PT, std::mt19937_64 *R): + Modifier(BB, PT, R){} void Act() override { Type *Tp = pickType(); @@ -432,23 +394,24 @@ }; struct ExtractElementModifier: public Modifier { - ExtractElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): + ExtractElementModifier(BasicBlock *BB, PieceTable *PT, std::mt19937_64 *R): Modifier(BB, PT, R) {} void Act() override { Value *Val0 = getRandomVectorValue(); Value *V = ExtractElementInst::Create(Val0, ConstantInt::get(Type::getInt32Ty(BB->getContext()), - Ran->Rand() % cast(Val0->getType())->getNumElements()), + (*Ran)() % cast(Val0->getType())->getNumElements()), "E", BB->getTerminator()); return PT->push_back(V); } }; struct ShuffModifier: public Modifier { - ShuffModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - void Act() override { + ShuffModifier(BasicBlock *BB, PieceTable *PT, std::mt19937_64 *R): + Modifier(BB, PT, R) {} + void Act() override { Value *Val0 = getRandomVectorValue(); Value *Val1 = getRandomValue(Val0->getType()); @@ -457,9 +420,9 @@ Type *I32 = Type::getInt32Ty(BB->getContext()); for (unsigned i=0; iRand() % (Width*2)); + Constant *CI = ConstantInt::get(I32, (*Ran)() % (Width*2)); // Pick some undef values. - if (!(Ran->Rand() % 5)) + if (!((*Ran)() % 5)) CI = UndefValue::get(I32); Idxs.push_back(CI); } @@ -473,7 +436,7 @@ }; struct InsertElementModifier: public Modifier { - InsertElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): + InsertElementModifier(BasicBlock *BB, PieceTable *PT, std::mt19937_64 *R): Modifier(BB, PT, R) {} void Act() override { @@ -482,7 +445,7 @@ Value *V = InsertElementInst::Create(Val0, Val1, ConstantInt::get(Type::getInt32Ty(BB->getContext()), - Ran->Rand() % cast(Val0->getType())->getNumElements()), + (*Ran)() % cast(Val0->getType())->getNumElements()), "I", BB->getTerminator()); return PT->push_back(V); } @@ -490,9 +453,10 @@ }; struct CastModifier: public Modifier { - CastModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - void Act() override { + CastModifier(BasicBlock *BB, PieceTable *PT, std::mt19937_64 *R): + Modifier(BB, PT, R) {} + void Act() override { Value *V = getRandomVal(); Type *VTy = V->getType(); Type *DestTy = pickScalarType(); @@ -518,7 +482,7 @@ unsigned DestSize = DestTy->getScalarType()->getPrimitiveSizeInBits(); // Generate lots of bitcasts. - if ((Ran->Rand() & 1) && VSize == DestSize) { + if (((*Ran)() & 1) && VSize == DestSize) { return PT->push_back( new BitCastInst(V, DestTy, "BC", BB->getTerminator())); } @@ -531,7 +495,7 @@ new TruncInst(V, DestTy, "Tr", BB->getTerminator())); } else { assert(VSize < DestSize && "Different int types with the same size?"); - if (Ran->Rand() & 1) + if ((*Ran)() & 1) return PT->push_back( new ZExtInst(V, DestTy, "ZE", BB->getTerminator())); return PT->push_back(new SExtInst(V, DestTy, "Se", BB->getTerminator())); @@ -541,7 +505,7 @@ // Fp to int. if (VTy->getScalarType()->isFloatingPointTy() && DestTy->getScalarType()->isIntegerTy()) { - if (Ran->Rand() & 1) + if ((*Ran)() & 1) return PT->push_back( new FPToSIInst(V, DestTy, "FC", BB->getTerminator())); return PT->push_back(new FPToUIInst(V, DestTy, "FC", BB->getTerminator())); @@ -550,7 +514,7 @@ // Int to fp. if (VTy->getScalarType()->isIntegerTy() && DestTy->getScalarType()->isFloatingPointTy()) { - if (Ran->Rand() & 1) + if ((*Ran)() & 1) return PT->push_back( new SIToFPInst(V, DestTy, "FC", BB->getTerminator())); return PT->push_back(new UIToFPInst(V, DestTy, "FC", BB->getTerminator())); @@ -575,7 +539,7 @@ }; struct SelectModifier: public Modifier { - SelectModifier(BasicBlock *BB, PieceTable *PT, Random *R): + SelectModifier(BasicBlock *BB, PieceTable *PT, std::mt19937_64 *R): Modifier(BB, PT, R) {} void Act() override { @@ -587,7 +551,7 @@ // If the value type is a vector, and we allow vector select, then in 50% // of the cases generate a vector select. - if (Val0->getType()->isVectorTy() && (Ran->Rand() % 1)) { + if (Val0->getType()->isVectorTy() && ((*Ran)() % 1)) { unsigned NumElem = cast(Val0->getType())->getNumElements(); CondTy = VectorType::get(CondTy, NumElem); } @@ -600,9 +564,10 @@ struct CmpModifier: public Modifier { - CmpModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - void Act() override { + CmpModifier(BasicBlock *BB, PieceTable *PT, std::mt19937_64 *R): + Modifier(BB, PT, R) {} + void Act() override { Value *Val0 = getRandomVal(); Value *Val1 = getRandomValue(Val0->getType()); @@ -611,11 +576,11 @@ int op; if (fp) { - op = Ran->Rand() % + op = (*Ran)() % (CmpInst::LAST_FCMP_PREDICATE - CmpInst::FIRST_FCMP_PREDICATE) + CmpInst::FIRST_FCMP_PREDICATE; } else { - op = Ran->Rand() % + op = (*Ran)() % (CmpInst::LAST_ICMP_PREDICATE - CmpInst::FIRST_ICMP_PREDICATE) + CmpInst::FIRST_ICMP_PREDICATE; } @@ -629,7 +594,7 @@ } // end anonymous namespace -static void FillFunction(Function *F, Random &R) { +static void FillFunction(Function *F, std::mt19937_64 &R) { // Create a legal entry block. BasicBlock *BB = BasicBlock::Create(F->getContext(), "BB", F); ReturnInst::Create(F->getContext(), BB); @@ -665,7 +630,7 @@ SM->ActN(5); // Throw in a few stores. } -static void IntroduceControlFlow(Function *F, Random &R) { +static void IntroduceControlFlow(Function *F, std::mt19937_64 &R) { std::vector BoolInst; for (auto &Instr : F->front()) { if (Instr.getType() == IntegerType::getInt1Ty(F->getContext())) @@ -700,7 +665,7 @@ Function *F = GenEmptyFunction(M.get()); // Pick an initial seed value - Random R(SeedCL); + std::mt19937_64 R(SeedCL); // Generate lots of random instructions inside a single basic block. FillFunction(F, R); // Break the basic block into many loops.