Use separate random number generator for each randomization pass
This removes random number generator from GlobalContext class and decouples different randomization passes
1. Add a new constructor for random number generator which merge three arguments to into one seed for the underlying implementation of random number generator.
RandomNumberGenerator(uint64_t Seed, RandomizationPassesEnum RandomizationPassID, uint64_t Salt=0)
param Seed: Should be the global random number seed passed through command line.
param RandomizationPassID: Should be the ID for different randomization passes.
param Salt: Should be an additional integer salt, default to be 0.
2. Move the creation of random number generators to the call sites of randomization passes. Each randomization pass create its own random number generator with specific salt value.
Function reordering: Salt = 0 (default)
Basic Block reordering: Salt = Function Sequence Number
Global Variable reordering: Salt = 0 (default)
Pooled Constants reordering: Salt = Constants' Kind value (return of getKind())
*Jump Tables: Salt = 0
Nop Insertion: Salt = Function Sequence Number
Register Alloc Randomization: Salt = (Function Sequence Number << 1) ^ (Kind == RAK_Phi ? 0u : 1u)
Constants Blinding: Salt = Function Sequence Number
*Jump tables are treated as pooled constants, but without Kind value as salt.
BUG=
R=stichnot@chromium.org
Review URL: https://codereview.chromium.org/1300993002.
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp
index 218ecd9..cc6d07c 100644
--- a/src/IceCfg.cpp
+++ b/src/IceCfg.cpp
@@ -43,6 +43,16 @@
VMetadata(new VariablesMetadata(this)),
TargetAssembler(TargetLowering::createAssembler(
Ctx->getFlags().getTargetArch(), this)) {
+ assert(!Ctx->isIRGenerationDisabled() &&
+ "Attempt to build cfg when IR generation disabled");
+ if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Randomize) {
+ // If -randomize-pool-immediates=randomize, create a random number generator
+ // to generate a cookie for constant blinding.
+ RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(),
+ RPE_ConstantBlinding, SequenceNumber);
+ ConstantBlindingCookie =
+ (uint32_t)RNG.next((uint64_t)std::numeric_limits<uint32_t>::max + 1);
+ }
}
Cfg::~Cfg() { assert(ICE_TLS_GET_FIELD(CurrentCfg) == nullptr); }
@@ -396,9 +406,11 @@
NodeList ReversedReachable;
NodeList Unreachable;
llvm::BitVector ToVisit(Nodes.size(), true);
+ // Create Random number generator for function reordering
+ RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(),
+ RPE_BasicBlockReordering, SequenceNumber);
// Traverse from entry node.
- getRandomPostOrder(getEntryNode(), ToVisit, ReversedReachable,
- &Ctx->getRNG());
+ getRandomPostOrder(getEntryNode(), ToVisit, ReversedReachable, &RNG);
// Collect the unreachable nodes.
for (CfgNode *Node : Nodes)
if (ToVisit[Node->getIndex()])
@@ -431,8 +443,10 @@
if (!Ctx->getFlags().shouldDoNopInsertion())
return;
TimerMarker T(TimerStack::TT_doNopInsertion, this);
+ RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(), RPE_NopInsertion,
+ SequenceNumber);
for (CfgNode *Node : Nodes)
- Node->doNopInsertion();
+ Node->doNopInsertion(RNG);
}
void Cfg::genCode() {
diff --git a/src/IceCfg.h b/src/IceCfg.h
index b5ded6a..e6c5a4a 100644
--- a/src/IceCfg.h
+++ b/src/IceCfg.h
@@ -164,6 +164,7 @@
bool hasComputedFrame() const;
bool getFocusedTiming() const { return FocusedTiming; }
void setFocusedTiming() { FocusedTiming = true; }
+ uint32_t getConstantBlindingCookie() const { return ConstantBlindingCookie; }
/// @}
/// Returns true if Var is a global variable that is used by the profiling
@@ -247,7 +248,8 @@
void emitJumpTables();
GlobalContext *Ctx;
- uint32_t SequenceNumber; /// output order for emission
+ uint32_t SequenceNumber; /// output order for emission
+ uint32_t ConstantBlindingCookie = 0; /// cookie for constant blinding
VerboseMask VMask;
IceString FunctionName = "";
Type ReturnType = IceType_void;
diff --git a/src/IceCfgNode.cpp b/src/IceCfgNode.cpp
index 76dc097..6926722 100644
--- a/src/IceCfgNode.cpp
+++ b/src/IceCfgNode.cpp
@@ -496,7 +496,7 @@
}
}
-void CfgNode::doNopInsertion() {
+void CfgNode::doNopInsertion(RandomNumberGenerator &RNG) {
TargetLowering *Target = Func->getTarget();
LoweringContext &Context = Target->getContext();
Context.init(this);
@@ -510,7 +510,7 @@
PauseNopInsertion = false;
}
if (!PauseNopInsertion)
- Target->doNopInsertion();
+ Target->doNopInsertion(RNG);
// Ensure Cur=Next, so that the nops are inserted before the current
// instruction rather than after.
Context.advanceCur();
diff --git a/src/IceCfgNode.h b/src/IceCfgNode.h
index e909690..963638d 100644
--- a/src/IceCfgNode.h
+++ b/src/IceCfgNode.h
@@ -91,7 +91,7 @@
void deletePhis();
void advancedPhiLowering();
void doAddressOpt();
- void doNopInsertion();
+ void doNopInsertion(RandomNumberGenerator &RNG);
void genCode();
void livenessLightweight();
bool liveness(Liveness *Liveness);
diff --git a/src/IceDefs.h b/src/IceDefs.h
index 2565aee..7ea34be 100644
--- a/src/IceDefs.h
+++ b/src/IceDefs.h
@@ -279,6 +279,18 @@
/// Options for pooling and randomization of immediates.
enum RandomizeAndPoolImmediatesEnum { RPI_None, RPI_Randomize, RPI_Pool };
+/// Salts for Random number generator for different randomization passes.
+enum RandomizationPassesEnum {
+ RPE_BasicBlockReordering,
+ RPE_ConstantBlinding,
+ RPE_FunctionReordering,
+ RPE_GlobalVariableReordering,
+ RPE_NopInsertion,
+ RPE_PooledConstantReordering,
+ RPE_RegAllocRandomization,
+ RPE_num
+};
+
} // end of namespace Ice
#endif // SUBZERO_SRC_ICEDEFS_H
diff --git a/src/IceELFObjectWriter.cpp b/src/IceELFObjectWriter.cpp
index f32a2b6..25c2bf3 100644
--- a/src/IceELFObjectWriter.cpp
+++ b/src/IceELFObjectWriter.cpp
@@ -512,11 +512,15 @@
// If the -reorder-pooled-constant option is set to true, we should shuffle
// the constants before we emit them.
- auto *CtxPtr = &Ctx;
- if (Ctx.getFlags().shouldReorderPooledConstants())
- RandomShuffle(Pool.begin(), Pool.end(), [CtxPtr](uint64_t N) {
- return (uint32_t)CtxPtr->getRNG().next(N);
- });
+ if (Ctx.getFlags().shouldReorderPooledConstants() && !Pool.empty()) {
+ // Use the constant's kind value as the salt for creating random number
+ // generator.
+ Operand::OperandKind K = (*Pool.begin())->getKind();
+ RandomNumberGenerator RNG(Ctx.getFlags().getRandomSeed(),
+ RPE_PooledConstantReordering, K);
+ RandomShuffle(Pool.begin(), Pool.end(),
+ [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); });
+ }
// Write the data.
for (Constant *C : Pool) {
if (!C->getShouldBePooled())
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp
index ffa6c15..3d15765 100644
--- a/src/IceGlobalContext.cpp
+++ b/src/IceGlobalContext.cpp
@@ -222,8 +222,7 @@
GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
ELFStreamer *ELFStr, const ClFlags &Flags)
: ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump),
- StrEmit(OsEmit), StrError(OsError), Flags(Flags),
- RNG(Flags.getRandomSeed()), ObjectWriter(),
+ StrEmit(OsEmit), StrError(OsError), Flags(Flags), ObjectWriter(),
OptQ(/*Sequential=*/Flags.isSequential(),
/*MaxSize=*/Flags.getNumTranslationThreads()),
// EmitQ is allowed unlimited size.
@@ -273,14 +272,6 @@
ProfileBlockInfoVarDecl->setName("__Sz_block_profile_info");
ProfileBlockInfoVarDecl->setSuppressMangling();
ProfileBlockInfoVarDecl->setLinkage(llvm::GlobalValue::ExternalLinkage);
-
- // Initialize the randomization cookie for constant blinding only if constant
- // blinding or pooling is turned on.
- // TODO(stichnot): Using RNG for constant blinding will affect the random
- // number to be used in nop-insertion and randomize-regalloc.
- if (Flags.getRandomizeAndPoolImmediatesOption() != RPI_None)
- RandomizationCookie =
- (uint32_t)RNG.next((uint64_t)std::numeric_limits<uint32_t>::max + 1);
}
void GlobalContext::translateFunctions() {
@@ -403,9 +394,11 @@
addBlockInfoPtrs(Globals, ProfileBlockInfoVarDecl);
// If we need to shuffle the layout of global variables, shuffle them now.
if (getFlags().shouldReorderGlobalVariables()) {
- auto *RNGPtr = &RNG;
+ // Create a random number generator for global variable reordering.
+ RandomNumberGenerator RNG(getFlags().getRandomSeed(),
+ RPE_GlobalVariableReordering);
RandomShuffle(Globals.begin(), Globals.end(),
- [RNGPtr](int N) { return (uint32_t)RNGPtr->next(N); });
+ [&RNG](int N) { return (uint32_t)RNG.next(N); });
}
DataLowering->lowerGlobals(Globals, SectionSuffix);
for (VariableDeclaration *Var : Globals) {
@@ -446,6 +439,9 @@
const uint32_t ShuffleWindowSize =
std::max(1u, getFlags().getReorderFunctionsWindowSize());
bool Shuffle = Threaded && getFlags().shouldReorderFunctions();
+ // Create a random number generator for function reordering.
+ RandomNumberGenerator RNG(getFlags().getRandomSeed(), RPE_FunctionReordering);
+
while (!EmitQueueEmpty) {
resizePending(Pending, DesiredSequenceNumber);
// See if Pending contains DesiredSequenceNumber.
@@ -497,7 +493,7 @@
// Pending[ShuffleEndIndex].
RandomShuffle(Pending.begin() + ShuffleStartIndex,
Pending.begin() + ShuffleEndIndex,
- [this](uint64_t N) { return (uint32_t)RNG.next(N); });
+ [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); });
}
// Emit the item from ShuffleStartIndex to ShuffleEndIndex.
@@ -879,20 +875,25 @@
JumpTableDataList GlobalContext::getJumpTables() {
JumpTableDataList JumpTables(*getJumpTableList());
+ // Make order deterministic by sorting into functions and then ID of the
+ // jump table within that function.
+ std::sort(JumpTables.begin(), JumpTables.end(),
+ [](const JumpTableData &A, const JumpTableData &B) {
+ if (A.getFunctionName() != B.getFunctionName())
+ return A.getFunctionName() < B.getFunctionName();
+ return A.getId() < B.getId();
+ });
+
if (getFlags().shouldReorderPooledConstants()) {
- // If reorder-pooled-constants option is set to true, we need to shuffle the
- // constant pool before emitting it.
+ // If reorder-pooled-constants option is set to true, we also shuffle the
+ // jump tables before emitting them.
+
+ // Create a random number generator for jump tables reordering, considering
+ // jump tables as pooled constants.
+ RandomNumberGenerator RNG(getFlags().getRandomSeed(),
+ RPE_PooledConstantReordering);
RandomShuffle(JumpTables.begin(), JumpTables.end(),
- [this](uint64_t N) { return (uint32_t)getRNG().next(N); });
- } else {
- // Make order deterministic by sorting into functions and then ID of the
- // jump table within that function.
- std::sort(JumpTables.begin(), JumpTables.end(),
- [](const JumpTableData &A, const JumpTableData &B) {
- if (A.getFunctionName() != B.getFunctionName())
- return A.getFunctionName() < B.getFunctionName();
- return A.getId() < B.getId();
- });
+ [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); });
}
return JumpTables;
}
diff --git a/src/IceGlobalContext.h b/src/IceGlobalContext.h
index 7f27024..e07e577 100644
--- a/src/IceGlobalContext.h
+++ b/src/IceGlobalContext.h
@@ -243,10 +243,6 @@
const Intrinsics &getIntrinsicsInfo() const { return IntrinsicsInfo; }
- // TODO(wala,stichnot): Make the RNG play nicely with multithreaded
- // translation.
- RandomNumberGenerator &getRNG() { return RNG; }
-
ELFObjectWriter *getObjectWriter() const { return ObjectWriter.get(); }
/// Reset stats at the beginning of a function.
@@ -440,10 +436,6 @@
return Match.empty() || Match == SymbolName;
}
- /// Return the randomization cookie for diversification.
- /// Initialize the cookie if necessary
- uint32_t getRandomizationCookie() const { return RandomizationCookie; }
-
private:
// Try to ensure mutexes are allocated on separate cache lines.
@@ -496,7 +488,6 @@
Intrinsics IntrinsicsInfo;
const ClFlags &Flags;
- RandomNumberGenerator RNG; // TODO(stichnot): Move into Cfg.
// TODO(jpp): move to EmitterContext.
std::unique_ptr<ELFObjectWriter> ObjectWriter;
BoundedProducerConsumerQueue<Cfg> OptQ;
@@ -557,11 +548,6 @@
typedef llvm::SmallVector<char, 32> ManglerVector;
void incrementSubstitutions(ManglerVector &OldName) const;
- // Randomization Cookie
- // Managed by getRandomizationCookie()
- GlobalLockType RandomizationCookieLock;
- uint32_t RandomizationCookie = 0;
-
public:
static void TlsInit() { ICE_TLS_INIT_FIELD(TLS); }
};
diff --git a/src/IceRNG.cpp b/src/IceRNG.cpp
index a6b9adf..28efb8f 100644
--- a/src/IceRNG.cpp
+++ b/src/IceRNG.cpp
@@ -31,6 +31,16 @@
RandomNumberGenerator::RandomNumberGenerator(uint64_t Seed, llvm::StringRef)
: State(Seed) {}
+RandomNumberGenerator::RandomNumberGenerator(
+ uint64_t Seed, RandomizationPassesEnum RandomizationPassID, uint64_t Salt) {
+ constexpr unsigned NumBitsGlobalSeed = CHAR_BIT * sizeof(State);
+ constexpr unsigned NumBitsPassID = 4;
+ constexpr unsigned NumBitsSalt = 12;
+ static_assert(RPE_num < (1 << NumBitsPassID), "NumBitsPassID too small");
+ State = Seed ^ ((uint64_t)RandomizationPassID
+ << (NumBitsGlobalSeed - NumBitsPassID)) ^
+ (Salt << (NumBitsGlobalSeed - NumBitsPassID - NumBitsSalt));
+}
uint64_t RandomNumberGenerator::next(uint64_t Max) {
// Lewis, Goodman, and Miller (1969)
State = (16807 * State) % MAX;
diff --git a/src/IceRNG.h b/src/IceRNG.h
index 5ddd97f..4eeefa6 100644
--- a/src/IceRNG.h
+++ b/src/IceRNG.h
@@ -17,6 +17,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
+#include "IceDefs.h"
+
#include <cstdint>
namespace Ice {
@@ -28,6 +30,22 @@
public:
explicit RandomNumberGenerator(uint64_t Seed, llvm::StringRef Salt = "");
+ /// Create a random number generator with: global seed, randomization pass ID
+ /// and a salt uint64_t integer.
+ /// @param Seed should be a global seed.
+ /// @param RandomizationPassID should be one of RandomizationPassesEnum.
+ /// @param Salt should be an additional integer input for generating unique
+ /// RNG.
+ /// The global seed is 64 bits; since it is likely to originate from the
+ /// system time, the lower bits are more "valuable" than the upper bits. As
+ /// such, we merge the randomization pass ID and the salt into the global seed
+ /// by xor'ing them into high bit ranges. We expect the pass ID to fit within
+ /// 4 bits, so it gets shifted by 60 to merge into the upper 4 bits. We expect
+ /// the salt (usually the function sequence number) to fit within 12 bits, so
+ /// it gets shifted by 48 before merging.
+ explicit RandomNumberGenerator(uint64_t Seed,
+ RandomizationPassesEnum RandomizationPassID,
+ uint64_t Salt = 0);
uint64_t next(uint64_t Max);
private:
diff --git a/src/IceRegAlloc.cpp b/src/IceRegAlloc.cpp
index 0d9afba..bc0643e 100644
--- a/src/IceRegAlloc.cpp
+++ b/src/IceRegAlloc.cpp
@@ -250,11 +250,11 @@
}
auto CompareRanges = [](const Variable *L, const Variable *R) {
- InstNumberT Lstart = L->getLiveRange().getStart();
- InstNumberT Rstart = R->getLiveRange().getStart();
- if (Lstart == Rstart)
- return L->getIndex() < R->getIndex();
- return Lstart < Rstart;
+ InstNumberT Lstart = L->getLiveRange().getStart();
+ InstNumberT Rstart = R->getLiveRange().getStart();
+ if (Lstart == Rstart)
+ return L->getIndex() < R->getIndex();
+ return Lstart < Rstart;
};
// Do a reverse sort so that erasing elements (from the end) is fast.
std::sort(Unhandled.rbegin(), Unhandled.rend(), CompareRanges);
@@ -776,8 +776,15 @@
llvm::SmallVector<int32_t, REGS_SIZE> Permutation(NumRegisters);
if (Randomized) {
+ // Create a random number generator for regalloc randomization. Merge
+ // function's sequence and Kind value as the Salt. Because regAlloc()
+ // is called twice under O2, the second time with RAK_Phi, we check
+ // Kind == RAK_Phi to determine the lowest-order bit to make sure the
+ // Salt is different.
+ uint64_t Salt =
+ (Func->getSequenceNumber() << 1) ^ (Kind == RAK_Phi ? 0u : 1u);
Func->getTarget()->makeRandomRegisterPermutation(
- Permutation, PreDefinedRegisters | ~RegMaskFull);
+ Permutation, PreDefinedRegisters | ~RegMaskFull, Salt);
}
// Finish up by assigning RegNumTmp->RegNum (or a random permutation
diff --git a/src/IceTargetLowering.cpp b/src/IceTargetLowering.cpp
index 3e93b76..5ef6d09 100644
--- a/src/IceTargetLowering.cpp
+++ b/src/IceTargetLowering.cpp
@@ -103,7 +103,7 @@
Context.advanceNext();
}
-void TargetLowering::doNopInsertion() {
+void TargetLowering::doNopInsertion(RandomNumberGenerator &RNG) {
Inst *I = Context.getCur();
bool ShouldSkip = llvm::isa<InstFakeUse>(I) || llvm::isa<InstFakeDef>(I) ||
llvm::isa<InstFakeKill>(I) || I->isRedundantAssign() ||
@@ -111,7 +111,7 @@
if (!ShouldSkip) {
int Probability = Ctx->getFlags().getNopProbabilityAsPercentage();
for (int I = 0; I < Ctx->getFlags().getMaxNopsPerInstruction(); ++I) {
- randomlyInsertNop(Probability / 100.0);
+ randomlyInsertNop(Probability / 100.0, RNG);
}
}
}
diff --git a/src/IceTargetLowering.h b/src/IceTargetLowering.h
index a5e6064..a1c5aad 100644
--- a/src/IceTargetLowering.h
+++ b/src/IceTargetLowering.h
@@ -153,7 +153,7 @@
/// Tries to do address mode optimization on a single instruction.
void doAddressOpt();
/// Randomly insert NOPs.
- void doNopInsertion();
+ void doNopInsertion(RandomNumberGenerator &RNG);
/// Lowers a single non-Phi instruction.
void lower();
/// Inserts and lowers a single high-level instruction at a specific insertion
@@ -213,9 +213,10 @@
virtual const llvm::SmallBitVector &getRegisterSetForType(Type Ty) const = 0;
void regAlloc(RegAllocKind Kind);
- virtual void makeRandomRegisterPermutation(
- llvm::SmallVectorImpl<int32_t> &Permutation,
- const llvm::SmallBitVector &ExcludeRegisters) const = 0;
+ virtual void
+ makeRandomRegisterPermutation(llvm::SmallVectorImpl<int32_t> &Permutation,
+ const llvm::SmallBitVector &ExcludeRegisters,
+ uint64_t Salt) const = 0;
/// Save/restore any mutable state for the situation where code
/// emission needs multiple passes, such as sandboxing or relaxation.
@@ -279,7 +280,8 @@
virtual void doAddressOptLoad() {}
virtual void doAddressOptStore() {}
- virtual void randomlyInsertNop(float Probability) = 0;
+ virtual void randomlyInsertNop(float Probability,
+ RandomNumberGenerator &RNG) = 0;
/// This gives the target an opportunity to post-process the lowered
/// expansion before returning.
virtual void postLower() {}
diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp
index 14fa072..c3d05a2 100644
--- a/src/IceTargetLoweringARM32.cpp
+++ b/src/IceTargetLoweringARM32.cpp
@@ -2505,9 +2505,10 @@
UnimplementedError(Func->getContext()->getFlags());
}
-void TargetARM32::randomlyInsertNop(float Probability) {
- RandomNumberGeneratorWrapper RNG(Ctx->getRNG());
- if (RNG.getTrueWithProbability(Probability)) {
+void TargetARM32::randomlyInsertNop(float Probability,
+ RandomNumberGenerator &RNG) {
+ RandomNumberGeneratorWrapper RNGW(RNG);
+ if (RNGW.getTrueWithProbability(Probability)) {
UnimplementedError(Func->getContext()->getFlags());
}
}
@@ -2929,9 +2930,10 @@
void TargetARM32::makeRandomRegisterPermutation(
llvm::SmallVectorImpl<int32_t> &Permutation,
- const llvm::SmallBitVector &ExcludeRegisters) const {
+ const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const {
(void)Permutation;
(void)ExcludeRegisters;
+ (void)Salt;
UnimplementedError(Func->getContext()->getFlags());
}
diff --git a/src/IceTargetLoweringARM32.h b/src/IceTargetLoweringARM32.h
index 637c9a2..0597510 100644
--- a/src/IceTargetLoweringARM32.h
+++ b/src/IceTargetLoweringARM32.h
@@ -138,7 +138,8 @@
void prelowerPhis() override;
void doAddressOptLoad() override;
void doAddressOptStore() override;
- void randomlyInsertNop(float Probability) override;
+ void randomlyInsertNop(float Probability,
+ RandomNumberGenerator &RNG) override;
enum OperandLegalization {
Legal_None = 0,
@@ -162,9 +163,10 @@
/// Returns a vector in a register with the given constant entries.
Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister);
- void makeRandomRegisterPermutation(
- llvm::SmallVectorImpl<int32_t> &Permutation,
- const llvm::SmallBitVector &ExcludeRegisters) const override;
+ void
+ makeRandomRegisterPermutation(llvm::SmallVectorImpl<int32_t> &Permutation,
+ const llvm::SmallBitVector &ExcludeRegisters,
+ uint64_t Salt) const override;
// If a divide-by-zero check is needed, inserts a:
// test; branch .LSKIP; trap; .LSKIP: <continuation>.
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp
index a59f486..8f434b5 100644
--- a/src/IceTargetLoweringMIPS32.cpp
+++ b/src/IceTargetLoweringMIPS32.cpp
@@ -607,9 +607,10 @@
UnimplementedError(Func->getContext()->getFlags());
}
-void TargetMIPS32::randomlyInsertNop(float Probability) {
- RandomNumberGeneratorWrapper RNG(Ctx->getRNG());
- if (RNG.getTrueWithProbability(Probability)) {
+void TargetMIPS32::randomlyInsertNop(float Probability,
+ RandomNumberGenerator &RNG) {
+ RandomNumberGeneratorWrapper RNGW(RNG);
+ if (RNGW.getTrueWithProbability(Probability)) {
UnimplementedError(Func->getContext()->getFlags());
}
}
@@ -666,9 +667,10 @@
void TargetMIPS32::makeRandomRegisterPermutation(
llvm::SmallVectorImpl<int32_t> &Permutation,
- const llvm::SmallBitVector &ExcludeRegisters) const {
+ const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const {
(void)Permutation;
(void)ExcludeRegisters;
+ (void)Salt;
UnimplementedError(Func->getContext()->getFlags());
}
diff --git a/src/IceTargetLoweringMIPS32.h b/src/IceTargetLoweringMIPS32.h
index 76a5239..4fe1995 100644
--- a/src/IceTargetLoweringMIPS32.h
+++ b/src/IceTargetLoweringMIPS32.h
@@ -116,10 +116,12 @@
void prelowerPhis() override;
void doAddressOptLoad() override;
void doAddressOptStore() override;
- void randomlyInsertNop(float Probability) override;
- void makeRandomRegisterPermutation(
- llvm::SmallVectorImpl<int32_t> &Permutation,
- const llvm::SmallBitVector &ExcludeRegisters) const override;
+ void randomlyInsertNop(float Probability,
+ RandomNumberGenerator &RNG) override;
+ void
+ makeRandomRegisterPermutation(llvm::SmallVectorImpl<int32_t> &Permutation,
+ const llvm::SmallBitVector &ExcludeRegisters,
+ uint64_t Salt) const override;
static Type stackSlotType();
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index 466564d..e9f9989 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -731,10 +731,16 @@
// If reorder-pooled-constants option is set to true, we need to shuffle the
// constant pool before emitting it.
- if (Ctx->getFlags().shouldReorderPooledConstants())
- RandomShuffle(Pool.begin(), Pool.end(), [Ctx](uint64_t N) {
- return (uint32_t)Ctx->getRNG().next(N);
- });
+ if (Ctx->getFlags().shouldReorderPooledConstants() && !Pool.empty()) {
+ // Use the constant's kind value as the salt for creating random number
+ // generator.
+ Operand::OperandKind K = (*Pool.begin())->getKind();
+
+ RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(),
+ RPE_PooledConstantReordering, K);
+ RandomShuffle(Pool.begin(), Pool.end(),
+ [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); });
+ }
for (Constant *C : Pool) {
if (!C->getShouldBePooled())
diff --git a/src/IceTargetLoweringX8632Traits.h b/src/IceTargetLoweringX8632Traits.h
index 1d47d3a..3bfd404 100644
--- a/src/IceTargetLoweringX8632Traits.h
+++ b/src/IceTargetLoweringX8632Traits.h
@@ -362,7 +362,8 @@
static void
makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func,
llvm::SmallVectorImpl<int32_t> &Permutation,
- const llvm::SmallBitVector &ExcludeRegisters) {
+ const llvm::SmallBitVector &ExcludeRegisters,
+ uint64_t Salt) {
// TODO(stichnot): Declaring Permutation this way loses type/size
// information. Fix this in conjunction with the caller-side TODO.
assert(Permutation.size() >= RegisterSet::Reg_NUM);
@@ -393,13 +394,16 @@
REGX8632_TABLE
#undef X
- RandomNumberGeneratorWrapper RNG(Ctx->getRNG());
+ // Create a random number generator for regalloc randomization.
+ RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(),
+ RPE_RegAllocRandomization, Salt);
+ RandomNumberGeneratorWrapper RNGW(RNG);
// Shuffle the resulting equivalence classes.
for (auto I : EquivalenceClasses) {
const RegisterList &List = I.second;
RegisterList Shuffled(List);
- RandomShuffle(Shuffled.begin(), Shuffled.end(), RNG);
+ RandomShuffle(Shuffled.begin(), Shuffled.end(), RNGW);
for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) {
Permutation[List[SI]] = Shuffled[SI];
++NumShuffled;
diff --git a/src/IceTargetLoweringX8664.cpp b/src/IceTargetLoweringX8664.cpp
index 41d24cc..76fffa0 100644
--- a/src/IceTargetLoweringX8664.cpp
+++ b/src/IceTargetLoweringX8664.cpp
@@ -743,10 +743,15 @@
// If reorder-pooled-constants option is set to true, we need to shuffle the
// constant pool before emitting it.
- if (Ctx->getFlags().shouldReorderPooledConstants())
- RandomShuffle(Pool.begin(), Pool.end(), [Ctx](uint64_t N) {
- return (uint32_t)Ctx->getRNG().next(N);
- });
+ if (Ctx->getFlags().shouldReorderPooledConstants()) {
+ // Use the constant's kind value as the salt for creating random number
+ // generator.
+ Operand::OperandKind K = (*Pool.begin())->getKind();
+ RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(),
+ RPE_PooledConstantReordering, K);
+ RandomShuffle(Pool.begin(), Pool.end(),
+ [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); });
+ }
for (Constant *C : Pool) {
if (!C->getShouldBePooled())
diff --git a/src/IceTargetLoweringX8664Traits.h b/src/IceTargetLoweringX8664Traits.h
index 7cb85e0..a84dbc4 100644
--- a/src/IceTargetLoweringX8664Traits.h
+++ b/src/IceTargetLoweringX8664Traits.h
@@ -375,7 +375,8 @@
static void
makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func,
llvm::SmallVectorImpl<int32_t> &Permutation,
- const llvm::SmallBitVector &ExcludeRegisters) {
+ const llvm::SmallBitVector &ExcludeRegisters,
+ uint64_t Salt) {
// TODO(stichnot): Declaring Permutation this way loses type/size
// information. Fix this in conjunction with the caller-side TODO.
assert(Permutation.size() >= RegisterSet::Reg_NUM);
@@ -406,13 +407,16 @@
REGX8664_TABLE
#undef X
- RandomNumberGeneratorWrapper RNG(Ctx->getRNG());
+ // Create a random number generator for regalloc randomization.
+ RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(),
+ RPE_RegAllocRandomization, Salt);
+ RandomNumberGeneratorWrapper RNGW(RNG);
// Shuffle the resulting equivalence classes.
for (auto I : EquivalenceClasses) {
const RegisterList &List = I.second;
RegisterList Shuffled(List);
- RandomShuffle(Shuffled.begin(), Shuffled.end(), RNG);
+ RandomShuffle(Shuffled.begin(), Shuffled.end(), RNGW);
for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) {
Permutation[List[SI]] = Shuffled[SI];
++NumShuffled;
diff --git a/src/IceTargetLoweringX86Base.h b/src/IceTargetLoweringX86Base.h
index 31bc35b..8c0f298 100644
--- a/src/IceTargetLoweringX86Base.h
+++ b/src/IceTargetLoweringX86Base.h
@@ -180,7 +180,8 @@
void prelowerPhis() override;
void doAddressOptLoad() override;
void doAddressOptStore() override;
- void randomlyInsertNop(float Probability) override;
+ void randomlyInsertNop(float Probability,
+ RandomNumberGenerator &RNG) override;
/// Naive lowering of cmpxchg.
void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected,
@@ -290,9 +291,10 @@
typename Traits::X86OperandMem *
getMemoryOperandForStackSlot(Type Ty, Variable *Slot, uint32_t Offset = 0);
- void makeRandomRegisterPermutation(
- llvm::SmallVectorImpl<int32_t> &Permutation,
- const llvm::SmallBitVector &ExcludeRegisters) const override;
+ void
+ makeRandomRegisterPermutation(llvm::SmallVectorImpl<int32_t> &Permutation,
+ const llvm::SmallBitVector &ExcludeRegisters,
+ uint64_t Salt) const override;
/// The following are helpers that insert lowered x86 instructions
/// with minimal syntactic overhead, so that the lowering code can
diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h
index 5e46c98..a0b5b6c 100644
--- a/src/IceTargetLoweringX86BaseImpl.h
+++ b/src/IceTargetLoweringX86BaseImpl.h
@@ -4161,10 +4161,11 @@
}
template <class Machine>
-void TargetX86Base<Machine>::randomlyInsertNop(float Probability) {
- RandomNumberGeneratorWrapper RNG(Ctx->getRNG());
- if (RNG.getTrueWithProbability(Probability)) {
- _nop(RNG(Traits::X86_NUM_NOP_VARIANTS));
+void TargetX86Base<Machine>::randomlyInsertNop(float Probability,
+ RandomNumberGenerator &RNG) {
+ RandomNumberGeneratorWrapper RNGW(RNG);
+ if (RNGW.getTrueWithProbability(Probability)) {
+ _nop(RNGW(Traits::X86_NUM_NOP_VARIANTS));
}
}
@@ -5119,9 +5120,9 @@
template <class Machine>
void TargetX86Base<Machine>::makeRandomRegisterPermutation(
llvm::SmallVectorImpl<int32_t> &Permutation,
- const llvm::SmallBitVector &ExcludeRegisters) const {
+ const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const {
Traits::makeRandomRegisterPermutation(Ctx, Func, Permutation,
- ExcludeRegisters);
+ ExcludeRegisters, Salt);
}
template <class Machine>
@@ -5196,7 +5197,7 @@
Variable *Reg = makeReg(IceType_i32, RegNum);
ConstantInteger32 *Integer = llvm::cast<ConstantInteger32>(Immediate);
uint32_t Value = Integer->getValue();
- uint32_t Cookie = Ctx->getRandomizationCookie();
+ uint32_t Cookie = Func->getConstantBlindingCookie();
_mov(Reg, Ctx->getConstantInt(IceType_i32, Cookie + Value));
Constant *Offset = Ctx->getConstantInt(IceType_i32, 0 - Cookie);
_lea(Reg, Traits::X86OperandMem::create(Func, IceType_i32, Reg, Offset,
@@ -5275,7 +5276,7 @@
uint32_t Value =
llvm::dyn_cast<ConstantInteger32>(MemOperand->getOffset())
->getValue();
- uint32_t Cookie = Ctx->getRandomizationCookie();
+ uint32_t Cookie = Func->getConstantBlindingCookie();
Constant *Mask1 = Ctx->getConstantInt(
MemOperand->getOffset()->getType(), Cookie + Value);
Constant *Mask2 =
diff --git a/tests_lit/llvm2ice_tests/nop-insertion.ll b/tests_lit/llvm2ice_tests/nop-insertion.ll
index 160d933..785ef48 100644
--- a/tests_lit/llvm2ice_tests/nop-insertion.ll
+++ b/tests_lit/llvm2ice_tests/nop-insertion.ll
@@ -25,106 +25,112 @@
ret <4 x i32> %res
; PROB50-LABEL: mul_v4i32
-; PROB50: nop # variant = 4
+; PROB50: nop # variant = 1
; PROB50: subl $60, %esp
+; PROB50: nop # variant = 3
; PROB50: movups %xmm0, 32(%esp)
-; PROB50: nop # variant = 0
; PROB50: movups %xmm1, 16(%esp)
-; PROB50: nop # variant = 4
; PROB50: movups 32(%esp), %xmm0
+; PROB50: nop # variant = 1
; PROB50: pshufd $49, 32(%esp), %xmm1
+; PROB50: nop # variant = 4
; PROB50: pshufd $49, 16(%esp), %xmm2
+; PROB50: nop # variant = 1
; PROB50: pmuludq 16(%esp), %xmm0
-; PROB50: nop # variant = 0
; PROB50: pmuludq %xmm2, %xmm1
+; PROB50: nop # variant = 0
; PROB50: shufps $136, %xmm1, %xmm0
-; PROB50: nop # variant = 2
+; PROB50: nop # variant = 3
; PROB50: pshufd $216, %xmm0, %xmm0
+; PROB50: nop # variant = 1
; PROB50: movups %xmm0, (%esp)
; PROB50: movups (%esp), %xmm0
-; PROB50: nop # variant = 0
; PROB50: addl $60, %esp
-; PROB50: nop # variant = 3
; PROB50: ret
; PROB90-LABEL: mul_v4i32
-; PROB90: nop # variant = 4
+; PROB90: nop # variant = 1
; PROB90: subl $60, %esp
; PROB90: nop # variant = 3
; PROB90: movups %xmm0, 32(%esp)
-; PROB90: nop # variant = 2
+; PROB90: nop # variant = 4
; PROB90: movups %xmm1, 16(%esp)
-; PROB90: nop # variant = 3
+; PROB90: nop # variant = 1
; PROB90: movups 32(%esp), %xmm0
; PROB90: nop # variant = 4
; PROB90: pshufd $49, 32(%esp), %xmm1
-; PROB90: nop # variant = 0
+; PROB90: nop # variant = 1
; PROB90: pshufd $49, 16(%esp), %xmm2
-; PROB90: nop # variant = 2
+; PROB90: nop # variant = 4
; PROB90: pmuludq 16(%esp), %xmm0
-; PROB90: nop # variant = 3
+; PROB90: nop # variant = 2
; PROB90: pmuludq %xmm2, %xmm1
-; PROB90: nop # variant = 4
; PROB90: shufps $136, %xmm1, %xmm0
-; PROB90: nop # variant = 2
+; PROB90: nop # variant = 1
; PROB90: pshufd $216, %xmm0, %xmm0
-; PROB90: nop # variant = 4
; PROB90: movups %xmm0, (%esp)
-; PROB90: nop # variant = 2
+; PROB90: nop # variant = 1
; PROB90: movups (%esp), %xmm0
-; PROB90: nop # variant = 3
+; PROB90: nop # variant = 0
; PROB90: addl $60, %esp
-; PROB90: nop # variant = 3
+; PROB90: nop # variant = 0
; PROB90: ret
+; PROB90: nop # variant = 4
; MAXNOPS2-LABEL: mul_v4i32
-; MAXNOPS2: nop # variant = 4
+; MAXNOPS2: nop # variant = 1
+; MAXNOPS2: nop # variant = 3
; MAXNOPS2: subl $60, %esp
-; MAXNOPS2: nop # variant = 0
-; MAXNOPS2: nop # variant = 4
; MAXNOPS2: movups %xmm0, 32(%esp)
+; MAXNOPS2: nop # variant = 1
+; MAXNOPS2: nop # variant = 4
; MAXNOPS2: movups %xmm1, 16(%esp)
-; MAXNOPS2: nop # variant = 0
+; MAXNOPS2: nop # variant = 1
; MAXNOPS2: movups 32(%esp), %xmm0
-; MAXNOPS2: nop # variant = 2
-; MAXNOPS2: pshufd $49, 32(%esp), %xmm1
-; MAXNOPS2: pshufd $49, 16(%esp), %xmm2
; MAXNOPS2: nop # variant = 0
; MAXNOPS2: nop # variant = 3
+; MAXNOPS2: pshufd $49, 32(%esp), %xmm1
+; MAXNOPS2: nop # variant = 1
+; MAXNOPS2: pshufd $49, 16(%esp), %xmm2
; MAXNOPS2: pmuludq 16(%esp), %xmm0
; MAXNOPS2: pmuludq %xmm2, %xmm1
-; MAXNOPS2: shufps $136, %xmm1, %xmm0
-; MAXNOPS2: nop # variant = 3
-; MAXNOPS2: pshufd $216, %xmm0, %xmm0
; MAXNOPS2: nop # variant = 0
+; MAXNOPS2: shufps $136, %xmm1, %xmm0
+; MAXNOPS2: nop # variant = 0
+; MAXNOPS2: nop # variant = 0
+; MAXNOPS2: pshufd $216, %xmm0, %xmm0
+; MAXNOPS2: nop # variant = 1
+; MAXNOPS2: nop # variant = 3
; MAXNOPS2: movups %xmm0, (%esp)
-; MAXNOPS2: nop # variant = 2
+; MAXNOPS2: nop # variant = 3
; MAXNOPS2: movups (%esp), %xmm0
-; MAXNOPS2: nop # variant = 4
; MAXNOPS2: addl $60, %esp
+; MAXNOPS2: nop # variant = 3
; MAXNOPS2: ret
+
; SANDBOX50-LABEL: mul_v4i32
-; SANDBOX50: nop # variant = 4
+; SANDBOX50: nop # variant = 1
; SANDBOX50: subl $60, %esp
+; SANDBOX50: nop # variant = 3
; SANDBOX50: movups %xmm0, 32(%esp)
-; SANDBOX50: nop # variant = 0
; SANDBOX50: movups %xmm1, 16(%esp)
-; SANDBOX50: nop # variant = 4
; SANDBOX50: movups 32(%esp), %xmm0
+; SANDBOX50: nop # variant = 1
; SANDBOX50: pshufd $49, 32(%esp), %xmm1
+; SANDBOX50: nop # variant = 4
; SANDBOX50: pshufd $49, 16(%esp), %xmm2
+; SANDBOX50: nop # variant = 1
; SANDBOX50: pmuludq 16(%esp), %xmm0
-; SANDBOX50: nop # variant = 0
; SANDBOX50: pmuludq %xmm2, %xmm1
+; SANDBOX50: nop # variant = 0
; SANDBOX50: shufps $136, %xmm1, %xmm0
-; SANDBOX50: nop # variant = 2
+; SANDBOX50: nop # variant = 3
; SANDBOX50: pshufd $216, %xmm0, %xmm0
+; SANDBOX50: nop # variant = 1
; SANDBOX50: movups %xmm0, (%esp)
; SANDBOX50: movups (%esp), %xmm0
-; SANDBOX50: nop # variant = 0
; SANDBOX50: addl $60, %esp
-; SANDBOX50: nop # variant = 3
; SANDBOX50: pop %ecx
; SANDBOX50: .bundle_lock
; SANDBOX50: andl $-32, %ecx
diff --git a/tests_lit/llvm2ice_tests/randomize-pool-immediate-basic.ll b/tests_lit/llvm2ice_tests/randomize-pool-immediate-basic.ll
index 5c88631..a334091 100644
--- a/tests_lit/llvm2ice_tests/randomize-pool-immediate-basic.ll
+++ b/tests_lit/llvm2ice_tests/randomize-pool-immediate-basic.ll
@@ -25,12 +25,12 @@
ret i32 %res
; BLINDINGO2-LABEL: add_arg_plus_200000
-; BLINDINGO2: mov [[REG:e[a-z]*]],0x34ee7
-; BLINDINGO2-NEXT: lea [[REG]],{{[[]}}[[REG]]-0x41a7{{[]]}}
+; BLINDINGO2: mov [[REG:e[a-z]*]],0x2c8df4
+; BLINDINGO2-NEXT: lea [[REG]],{{[[]}}[[REG]]-0x2980b4{{[]]}}
; BLINDINGOM1-LABEL: add_arg_plus_200000
-; BLINDINGOM1: mov [[REG:e[a-z]*]],0x34ee7
-; BLINDINGOM1-NEXT: lea [[REG]],{{[[]}}[[REG]]-0x41a7{{[]]}}
+; BLINDINGOM1: mov [[REG:e[a-z]*]],0x2c8df4
+; BLINDINGOM1-NEXT: lea [[REG]],{{[[]}}[[REG]]-0x2980b4{{[]]}}
; POOLING-LABEL: add_arg_plus_200000
; POOLING: mov e{{[a-z]*}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32${{[0-9]*}}
@@ -44,10 +44,10 @@
%addr.load = load float, float* %addr.ptr, align 4
ret float %addr.load
; BLINDINGO2-LABEL: load_arg_plus_200000
-; BLINDINGO2: lea [[REG:e[a-z]*]],{{[[]}}{{e[a-z]*}}+0x34ee7{{[]]}}
+; BLINDINGO2: lea [[REG:e[a-z]*]],{{[[]}}{{e[a-z]*}}+0x32c814{{[]]}}
; BLINDINGOM1-LABEL: load_arg_plus_200000
-; BLINDINGOM1: lea [[REG:e[a-z]*]],{{[[]}}{{e[a-z]*}}-0x41a7{{[]]}}
+; BLINDINGOM1: lea [[REG:e[a-z]*]],{{[[]}}{{e[a-z]*}}-0x2fbad4{{[]]}}
; POOLING-LABEL: load_arg_plus_200000
; POOLING: mov e{{[a-z]*}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32${{[0-9]*}}
@@ -61,13 +61,13 @@
; BLINDINGO2-LABEL: add_arg_plus_64bits
; BLINDINGO2: sar [[RHI:e[a-z]*]],0x1f
-; BLINDINGO2: mov [[RLO:e[a-z]*]],0xf46b45a7
-; BLINDINGO2-NEXT: lea [[RLO]],{{[[]}}[[RLO]]-0x41a7{{[]]}}
+; BLINDINGO2: mov [[RLO:e[a-z]*]],0xf4a0f8f8
+; BLINDINGO2-NEXT: lea [[RLO]],{{[[]}}[[RLO]]-0x35f4f8{{[]]}}
; BLINDINGOM1-LABEL: add_arg_plus_64bits
; BLINDINGOM1: sar [[RHI:e[a-z]*]],0x1f
-; BLINDINGOM1: mov [[RLO:e[a-z]*]],0xf46b45a7
-; BLINDINGOM1-NEXT: lea [[RLO]],{{[[]}}[[RLO]]-0x41a7{{[]]}}
+; BLINDINGOM1: mov [[RLO:e[a-z]*]],0xf4a0f8f8
+; BLINDINGOM1-NEXT: lea [[RLO]],{{[[]}}[[RLO]]-0x35f4f8{{[]]}}
; POOLING-LABEL: add_arg_plus_64bits
; POOLING: mov e{{[a-z]*}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32${{[0-9]*}}
@@ -82,12 +82,12 @@
ret i64 %arg.load
; BLINDINGO2-LABEL: load_arg_plus_64bits
-; BLINDINGO2: lea e{{[a-z]*}},{{[[]}}e{{[a-z]*}}+0x1a137{{[]]}}
-; BLINDINGO2: mov e{{[a-z]*}},DWORD PTR {{[[]}}e{{[a-z]*}}-0x41a7{{[]]}}
+; BLINDINGO2: lea e{{[a-z]*}},{{[[]}}e{{[a-z]*}}+0x3d8eac{{[]]}}
+; BLINDINGO2: mov e{{[a-z]*}},DWORD PTR {{[[]}}e{{[a-z]*}}-0x3c2f1c{{[]]}}
; BLINDINGOM1-LABEL: load_arg_plus_64bits
-; BLINDINGOM1: mov e{{[a-z]*}},0x1a137
-; BLINDINGOM1-NEXT: lea e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x41a7{{[]]}}
+; BLINDINGOM1: mov e{{[a-z]*}},0x3d8eac
+; BLINDINGOM1-NEXT: lea e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x3c2f1c{{[]]}}
; POOLING-LABEL: load_arg_plus_64bits
; POOLING: mov e{{[a-z]x}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32${{[0-9]*}}
@@ -101,12 +101,12 @@
ret i32 %ret
; BLINDINGO2-LABEL: add_const_8bits
-; BLINDINGO2: mov e{{[a-z]*}},0x4222
-; BLINDINGO2-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x41a7{{[]]}}
+; BLINDINGO2: mov e{{[a-z]*}},0x1d0aa
+; BLINDINGO2-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x1d02f{{[]]}}
; BLINDINGOM1-LABEL: add_const_8bits
-; BLINDINGOM1: mov e{{[a-z]*}},0x4222
-; BLINDINGOM1-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x41a7{{[]]}}
+; BLINDINGOM1: mov e{{[a-z]*}},0x1d0aa
+; BLINDINGOM1-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x1d02f{{[]]}}
; POOLING-LABEL: add_const_8bits
; POOLING: mov {{[a-z]l}},BYTE PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i8${{[0-9]*}}
@@ -120,12 +120,12 @@
ret i32 %ret
; BLINDINGO2-LABEL: add_const_16bits
-; BLINDINGO2: mov e{{[a-z]*}},0xc1a5
-; BLINDINGO2-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x41a7{{[]]}}
+; BLINDINGO2: mov e{{[a-z]*}},0x88a4d
+; BLINDINGO2-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x80a4f{{[]]}}
; BLINDINGOM1-LABEL: add_const_16bits
-; BLINDINGOM1: mov e{{[a-z]*}},0xc1a5
-; BLINDINGOM1-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x41a7{{[]]}}
+; BLINDINGOM1: mov e{{[a-z]*}},0x88a4d
+; BLINDINGOM1-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x80a4f{{[]]}}
; POOLING-LABEL: add_const_16bits
; POOLING: mov {{[a-z]x}},WORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i16${{[0-9]*}}
diff --git a/tests_lit/llvm2ice_tests/randomize-regalloc.ll b/tests_lit/llvm2ice_tests/randomize-regalloc.ll
index 696fce5..5bdd70d 100644
--- a/tests_lit/llvm2ice_tests/randomize-regalloc.ll
+++ b/tests_lit/llvm2ice_tests/randomize-regalloc.ll
@@ -26,11 +26,11 @@
; OPTM1_1-NEXT: movups XMMWORD PTR [esp+0x20],xmm0
; OPTM1_1-NEXT: movups XMMWORD PTR [esp+0x10],xmm1
; OPTM1_1-NEXT: movups xmm0,XMMWORD PTR [esp+0x20]
-; OPTM1_1-NEXT: pshufd xmm1,XMMWORD PTR [esp+0x20],0x31
-; OPTM1_1-NEXT: pshufd xmm2,XMMWORD PTR [esp+0x10],0x31
+; OPTM1_1-NEXT: pshufd xmm7,XMMWORD PTR [esp+0x20],0x31
+; OPTM1_1-NEXT: pshufd xmm3,XMMWORD PTR [esp+0x10],0x31
; OPTM1_1-NEXT: pmuludq xmm0,XMMWORD PTR [esp+0x10]
-; OPTM1_1-NEXT: pmuludq xmm1,xmm2
-; OPTM1_1-NEXT: shufps xmm0,xmm1,0x88
+; OPTM1_1-NEXT: pmuludq xmm7,xmm3
+; OPTM1_1-NEXT: shufps xmm0,xmm7,0x88
; OPTM1_1-NEXT: pshufd xmm0,xmm0,0xd8
; OPTM1_1-NEXT: movups XMMWORD PTR [esp],xmm0
; OPTM1_1-NEXT: movups xmm0,XMMWORD PTR [esp]
@@ -38,14 +38,14 @@
; OPTM1_1-NEXT: ret
; CHECK_1-LABEL: mul_v4i32
-; CHECK_1: movups xmm5,xmm0
+; CHECK_1: movups xmm7,xmm0
; CHECK_1-NEXT: pshufd xmm0,xmm0,0x31
; CHECK_1-NEXT: pshufd xmm3,xmm1,0x31
-; CHECK_1-NEXT: pmuludq xmm5,xmm1
+; CHECK_1-NEXT: pmuludq xmm7,xmm1
; CHECK_1-NEXT: pmuludq xmm0,xmm3
-; CHECK_1-NEXT: shufps xmm5,xmm0,0x88
-; CHECK_1-NEXT: pshufd xmm5,xmm5,0xd8
-; CHECK_1-NEXT: movups xmm0,xmm5
+; CHECK_1-NEXT: shufps xmm7,xmm0,0x88
+; CHECK_1-NEXT: pshufd xmm7,xmm7,0xd8
+; CHECK_1-NEXT: movups xmm0,xmm7
; CHECK_1-NEXT: ret
; OPTM1_123-LABEL: mul_v4i32
@@ -53,11 +53,11 @@
; OPTM1_123-NEXT: movups XMMWORD PTR [esp+0x20],xmm0
; OPTM1_123-NEXT: movups XMMWORD PTR [esp+0x10],xmm1
; OPTM1_123-NEXT: movups xmm0,XMMWORD PTR [esp+0x20]
-; OPTM1_123-NEXT: pshufd xmm1,XMMWORD PTR [esp+0x20],0x31
-; OPTM1_123-NEXT: pshufd xmm6,XMMWORD PTR [esp+0x10],0x31
+; OPTM1_123-NEXT: pshufd xmm2,XMMWORD PTR [esp+0x20],0x31
+; OPTM1_123-NEXT: pshufd xmm1,XMMWORD PTR [esp+0x10],0x31
; OPTM1_123-NEXT: pmuludq xmm0,XMMWORD PTR [esp+0x10]
-; OPTM1_123-NEXT: pmuludq xmm1,xmm6
-; OPTM1_123-NEXT: shufps xmm0,xmm1,0x88
+; OPTM1_123-NEXT: pmuludq xmm2,xmm1
+; OPTM1_123-NEXT: shufps xmm0,xmm2,0x88
; OPTM1_123-NEXT: pshufd xmm0,xmm0,0xd8
; OPTM1_123-NEXT: movups XMMWORD PTR [esp],xmm0
; OPTM1_123-NEXT: movups xmm0,XMMWORD PTR [esp]
@@ -65,14 +65,14 @@
; OPTM1_123-NEXT: ret
; CHECK_123-LABEL: mul_v4i32
-; CHECK_123: movups xmm4,xmm0
+; CHECK_123: movups xmm3,xmm0
; CHECK_123-NEXT: pshufd xmm0,xmm0,0x31
-; CHECK_123-NEXT: pshufd xmm2,xmm1,0x31
-; CHECK_123-NEXT: pmuludq xmm4,xmm1
-; CHECK_123-NEXT: pmuludq xmm0,xmm2
-; CHECK_123-NEXT: shufps xmm4,xmm0,0x88
-; CHECK_123-NEXT: pshufd xmm4,xmm4,0xd8
-; CHECK_123-NEXT: movups xmm0,xmm4
+; CHECK_123-NEXT: pshufd xmm5,xmm1,0x31
+; CHECK_123-NEXT: pmuludq xmm3,xmm1
+; CHECK_123-NEXT: pmuludq xmm0,xmm5
+; CHECK_123-NEXT: shufps xmm3,xmm0,0x88
+; CHECK_123-NEXT: pshufd xmm3,xmm3,0xd8
+; CHECK_123-NEXT: movups xmm0,xmm3
; CHECK_123-NEXT: ret
}
diff --git a/tests_lit/llvm2ice_tests/reorder-basic-blocks.ll b/tests_lit/llvm2ice_tests/reorder-basic-blocks.ll
index d390ff3..bd49021 100644
--- a/tests_lit/llvm2ice_tests/reorder-basic-blocks.ll
+++ b/tests_lit/llvm2ice_tests/reorder-basic-blocks.ll
@@ -29,8 +29,8 @@
; SEED1: .Lbasic_block_reordering$entry:
; SEED1: .Lbasic_block_reordering$BB1:
; SEED1: .Lbasic_block_reordering$BB2:
-; SEED1: .Lbasic_block_reordering$BB3:
; SEED1: .Lbasic_block_reordering$BB4:
+; SEED1: .Lbasic_block_reordering$BB3:
; SEED2-LABEL: basic_block_reordering:
; SEED2: .Lbasic_block_reordering$entry:
diff --git a/tests_lit/llvm2ice_tests/reorder-functions.ll b/tests_lit/llvm2ice_tests/reorder-functions.ll
index 02af79a..3cbce9c 100644
--- a/tests_lit/llvm2ice_tests/reorder-functions.ll
+++ b/tests_lit/llvm2ice_tests/reorder-functions.ll
@@ -61,12 +61,12 @@
ret void
}
-; DEFAULTWINDOWSIZE-LABEL: func4
; DEFAULTWINDOWSIZE-LABEL: func1
-; DEFAULTWINDOWSIZE-LABEL: func3
-; DEFAULTWINDOWSIZE-LABEL: func6
+; DEFAULTWINDOWSIZE-LABEL: func4
; DEFAULTWINDOWSIZE-LABEL: func5
; DEFAULTWINDOWSIZE-LABEL: func2
+; DEFAULTWINDOWSIZE-LABEL: func6
+; DEFAULTWINDOWSIZE-LABEL: func3
; WINDOWSIZE1-LABEL: func1
; WINDOWSIZE1-LABEL: func2
@@ -82,9 +82,9 @@
; SEQUENTIAL-LABEL: func5
; SEQUENTIAL-LABEL: func6
-; WINDOWSIZEMAX-LABEL: func4
; WINDOWSIZEMAX-LABEL: func1
-; WINDOWSIZEMAX-LABEL: func3
-; WINDOWSIZEMAX-LABEL: func6
+; WINDOWSIZEMAX-LABEL: func4
; WINDOWSIZEMAX-LABEL: func5
; WINDOWSIZEMAX-LABEL: func2
+; WINDOWSIZEMAX-LABEL: func6
+; WINDOWSIZEMAX-LABEL: func3
diff --git a/tests_lit/llvm2ice_tests/reorder-global-variables.ll b/tests_lit/llvm2ice_tests/reorder-global-variables.ll
index b2a77cc..e392502 100644
--- a/tests_lit/llvm2ice_tests/reorder-global-variables.ll
+++ b/tests_lit/llvm2ice_tests/reorder-global-variables.ll
@@ -54,16 +54,11 @@
@ArrayUninitConstInt = internal constant [20 x i8] zeroinitializer, align 4
-;@__init_array_start = internal constant [0 x i8] zeroinitializer, align 4
-;@__fini_array_start = internal constant [0 x i8] zeroinitializer, align 4
-;@__tls_template_start = internal constant [0 x i8] zeroinitializer, align 8
-;@__tls_template_alignment = internal constant [4 x i8] c"\01\00\00\00", align 4
-
; Make sure the shuffled order is correct.
-; CHECK-LABEL: ArrayInitPartial
-; CHECK-LABEL: PrimitiveInit
; CHECK-LABEL: ArrayInit
+; CHECK-LABEL: PrimitiveInit
+; CHECK-LABEL: ArrayInitPartial
; CHECK-LABEL: PrimitiveUninit
; CHECK-LABEL: ArrayUninit
; CHECK-LABEL: PrimitiveInitStatic
diff --git a/tests_lit/llvm2ice_tests/reorder-pooled-constants.ll b/tests_lit/llvm2ice_tests/reorder-pooled-constants.ll
index 688caac..ce53ea1 100644
--- a/tests_lit/llvm2ice_tests/reorder-pooled-constants.ll
+++ b/tests_lit/llvm2ice_tests/reorder-pooled-constants.ll
@@ -3,11 +3,11 @@
; RUN: %p2i --assemble --disassemble --filetype=obj --dis-flags=-s \
; RUN: --target x8632 -i %s --args -sz-seed=1 -O2 -reorder-pooled-constants \
-; RUN: | FileCheck %s --check-prefix=X86O2
+; RUN: | FileCheck %s --check-prefix=X86
; RUN: %p2i --assemble --disassemble --filetype=obj --dis-flags=-s \
; RUN: --target x8632 -i %s --args -sz-seed=1 -Om1 -reorder-pooled-constants \
-; RUN: | FileCheck %s --check-prefix=X86OM1
+; RUN: | FileCheck %s --check-prefix=X86
@__init_array_start = internal constant [0 x i8] zeroinitializer, align 4
@__fini_array_start = internal constant [0 x i8] zeroinitializer, align 4
@@ -533,38 +533,17 @@
}
; Make sure the constants in pools are shuffled.
-; TODO(qining, stichnot): Unify the checkers for Om1 and O2 optimization levels.
-; Om1 and O2 result into different sizes of i32 constant pools.
-; Because the shuffling routine of constant pools is applied to integer
-; constant pools first, the random number used for shuffling float and double
-; constant pools will be different for Om1 and O2, so is the order of the pooled
-; float and double constants. The source of this difference may includes: stack
-; frame size, strength reduction, etc.
; Check for float pool
-; X86O2-LABEL: .rodata.cst4
-; X86O2: 00000040 0000c0ff 00000041 00000000
-; X86O2: 0000003f 0000803f 00008040 0000c07f
-; X86O2: 0000803e
+; X86-LABEL: .rodata.cst4
+; X86: 00000041 0000c0ff 0000803f 00008040
+; X86: 0000c07f 00000000 0000003f 0000803e
+; X86: 00000040
; Check for double pool
-; X86O2-LABEL: .rodata.cst8
-; X86O2: 55555555 5555d53f 00000000 0000f8ff
-; X86O2: 00000000 0000f87f 00000000 0000e03f
-; X86O2: 00000000 0000d03f 00000000 00000000
+; X86-LABEL: .rodata.cst8
+; X86: 00000000 0000f8ff 00000000 0000f87f
+; X86: 00000000 0000e03f 00000000 00000000
+; X86: 55555555 5555d53f 00000000 0000d03f
-; X86O2-LABEL: .text
-
-; Check for float pool
-; X86OM1-LABEL: .rodata.cst4
-; X86OM1: 0000803f 0000003f 00000040 0000c0ff
-; X86OM1: 00000000 00008040 0000c07f 0000803e
-; X86OM1: 00000041
-
-; Check for double pool
-; X86OM1-LABEL: .rodata.cst8
-; X86OM1: 00000000 0000e03f 00000000 0000f87f
-; X86OM1: 00000000 0000f8ff 00000000 0000d03f
-; X86OM1: 00000000 00000000 55555555 5555d53f
-
-; X86OM1-LABEL: .text
+; X86-LABEL: .text
diff --git a/tests_lit/llvm2ice_tests/rng.ll b/tests_lit/llvm2ice_tests/rng.ll
new file mode 100644
index 0000000..f7c40b3
--- /dev/null
+++ b/tests_lit/llvm2ice_tests/rng.ll
@@ -0,0 +1,258 @@
+; This is a smoke test of random number generator.
+; The random number generators for different randomization passes should be
+; decoupled. The random number used in one randomization pass should not be
+; influenced by the existence of other randomization passes.
+
+; REQUIRES: allow_dump, target_X8632
+
+; Command for checking constant blinding (Need to turn off nop-insertion)
+; RUN: %p2i --target x8632 -i %s --filetype=obj --disassemble --args -O2 \
+; RUN: -sz-seed=1 -randomize-pool-immediates=randomize \
+; RUN: -randomize-pool-threshold=0x1 \
+; RUN: -reorder-global-variables \
+; RUN: -reorder-basic-blocks \
+; RUN: -reorder-functions \
+; RUN: -randomize-regalloc \
+; RUN: -nop-insertion=0 \
+; RUN: -reorder-pooled-constants \
+; RUN: | FileCheck %s --check-prefix=BLINDINGO2
+
+; Command for checking global variable reordering
+; RUN: %p2i --target x8632 -i %s \
+; RUN: --filetype=obj --disassemble --dis-flags=-rD \
+; RUN: --args -O2 -sz-seed=1 \
+; RUN: -randomize-pool-immediates=randomize \
+; RUN: -randomize-pool-threshold=0x1 \
+; RUN: -reorder-global-variables \
+; RUN: -reorder-basic-blocks \
+; RUN: -reorder-functions \
+; RUN: -randomize-regalloc \
+; RUN: -nop-insertion \
+; RUN: -reorder-pooled-constants \
+; RUN: | FileCheck %s --check-prefix=GLOBALVARS
+
+; Command for checking basic block reordering
+; RUN: %p2i --target x8632 -i %s --filetype=asm --args -O2 -sz-seed=1\
+; RUN: -randomize-pool-immediates=randomize \
+; RUN: -randomize-pool-threshold=0x1 \
+; RUN: -reorder-global-variables \
+; RUN: -reorder-basic-blocks \
+; RUN: -reorder-functions \
+; RUN: -randomize-regalloc \
+; RUN: -nop-insertion \
+; RUN: -reorder-pooled-constants \
+; RUN: | FileCheck %s --check-prefix=BBREORDERING
+
+; Command for checking function reordering
+; RUN: %p2i --target x8632 -i %s --filetype=obj --disassemble --args -O2 \
+; RUN: -sz-seed=1 -randomize-pool-immediates=randomize \
+; RUN: -randomize-pool-threshold=0x1 \
+; RUN: -reorder-global-variables \
+; RUN: -reorder-basic-blocks \
+; RUN: -reorder-functions \
+; RUN: -randomize-regalloc \
+; RUN: -nop-insertion \
+; RUN: -reorder-pooled-constants \
+; RUN: | FileCheck %s --check-prefix=FUNCREORDERING
+
+; Command for checking regalloc randomization
+; RUN: %p2i --target x8632 -i %s --filetype=obj --disassemble --args -O2 \
+; RUN: -sz-seed=1 -randomize-pool-immediates=randomize \
+; RUN: -randomize-pool-threshold=0x1 \
+; RUN: -reorder-global-variables \
+; RUN: -reorder-basic-blocks \
+; RUN: -reorder-functions \
+; RUN: -randomize-regalloc \
+; RUN: -nop-insertion \
+; RUN: -reorder-pooled-constants \
+; RUN: | FileCheck %s --check-prefix=REGALLOC
+
+; Command for checking nop insertion (Need to turn off randomize-regalloc)
+; RUN: %p2i --target x8632 -i %s --filetype=asm --args \
+; RUN: -sz-seed=1 -randomize-pool-immediates=randomize \
+; RUN: -reorder-global-variables \
+; RUN: -reorder-basic-blocks \
+; RUN: -reorder-functions \
+; RUN: -randomize-regalloc=0 \
+; RUN: -nop-insertion -nop-insertion-percentage=50\
+; RUN: -reorder-pooled-constants \
+; RUN: | FileCheck %s --check-prefix=NOPINSERTION
+
+; Command for checking pooled constants reordering
+; RUN: %p2i --target x8632 -i %s --filetype=obj --disassemble --dis-flags=-s \
+; RUN: --args -O2 -sz-seed=1 \
+; RUN: -randomize-pool-immediates=randomize \
+; RUN: -randomize-pool-threshold=0x1 \
+; RUN: -reorder-global-variables \
+; RUN: -reorder-basic-blocks \
+; RUN: -reorder-functions \
+; RUN: -randomize-regalloc \
+; RUN: -nop-insertion \
+; RUN: -reorder-pooled-constants \
+; RUN: | FileCheck %s --check-prefix=POOLEDCONSTANTS
+
+
+; Global variables copied from reorder-global-variables.ll
+@PrimitiveInit = internal global [4 x i8] c"\1B\00\00\00", align 4
+@PrimitiveInitConst = internal constant [4 x i8] c"\0D\00\00\00", align 4
+@ArrayInit = internal global [20 x i8] c"\0A\00\00\00\14\00\00\00\1E\00\00\00(\00\00\002\00\00\00", align 4
+@ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4
+@PrimitiveInitStatic = internal global [4 x i8] zeroinitializer, align 4
+@PrimitiveUninit = internal global [4 x i8] zeroinitializer, align 4
+@ArrayUninit = internal global [20 x i8] zeroinitializer, align 4
+@ArrayUninitConstDouble = internal constant [200 x i8] zeroinitializer, align 8
+@ArrayUninitConstInt = internal constant [20 x i8] zeroinitializer, align 4
+
+
+define <4 x i32> @func1(<4 x i32> %a, <4 x i32> %b) {
+entry:
+ %res = mul <4 x i32> %a, %b
+ ret <4 x i32> %res
+
+; NOPINSERTION-LABEL: func1
+; NOPINSERTION: nop # variant = 1
+; NOPINSERTION: subl $60, %esp
+; NOPINSERTION: nop # variant = 3
+; NOPINSERTION: movups %xmm0, 32(%esp)
+; NOPINSERTION: movups %xmm1, 16(%esp)
+; NOPINSERTION: movups 32(%esp), %xmm0
+; NOPINSERTION: nop # variant = 1
+; NOPINSERTION: pshufd $49, 32(%esp), %xmm1
+; NOPINSERTION: nop # variant = 4
+; NOPINSERTION: pshufd $49, 16(%esp), %xmm2
+; NOPINSERTION: nop # variant = 1
+; NOPINSERTION: pmuludq 16(%esp), %xmm0
+; NOPINSERTION: pmuludq %xmm2, %xmm1
+; NOPINSERTION: nop # variant = 0
+; NOPINSERTION: shufps $136, %xmm1, %xmm0
+; NOPINSERTION: nop # variant = 3
+; NOPINSERTION: pshufd $216, %xmm0, %xmm0
+; NOPINSERTION: nop # variant = 1
+; NOPINSERTION: movups %xmm0, (%esp)
+; NOPINSERTION: movups (%esp), %xmm0
+; NOPINSERTION: addl $60, %esp
+; NOPINSERTION: ret
+}
+
+
+
+define float @func2(float* %arg) {
+entry:
+ %arg.int = ptrtoint float* %arg to i32
+ %addr.int = add i32 %arg.int, 200000
+ %addr.ptr = inttoptr i32 %addr.int to float*
+ %addr.load = load float, float* %addr.ptr, align 4
+ ret float %addr.load
+
+; BLINDINGO2-LABEL: func2
+; BLINDINGO2: lea [[REG:e[a-z]*]],{{[[]}}{{e[a-z]*}}+0x32c814{{[]]}}
+}
+
+define float @func3(i32 %arg, float %input) {
+entry:
+ switch i32 %arg, label %return [
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb1
+ i32 2, label %sw.bb2
+ i32 3, label %sw.bb3
+ i32 4, label %sw.bb4
+ ]
+
+sw.bb:
+ %rbb = fadd float %input, 1.000000e+00
+ br label %return
+
+sw.bb1:
+ %rbb1 = fadd float %input, 2.000000e+00
+ br label %return
+
+sw.bb2:
+ %rbb2 = fadd float %input, 4.000000e+00
+ br label %return
+
+sw.bb3:
+ %rbb3 = fadd float %input, 5.000000e-01
+ br label %return
+
+sw.bb4:
+ %rbb4 = fadd float %input, 2.500000e-01
+ br label %return
+
+return:
+ %retval.0 = phi float [ %rbb, %sw.bb ], [ %rbb1, %sw.bb1 ], [ %rbb2, %sw.bb2 ], [ %rbb3, %sw.bb3 ], [ %rbb4, %sw.bb4], [ 0.000000e+00, %entry ]
+ ret float %retval.0
+}
+
+define <4 x i32> @func4(<4 x i32> %a, <4 x i32> %b) {
+entry:
+ %res = mul <4 x i32> %a, %b
+ ret <4 x i32> %res
+
+; REGALLOC-LABEL: func4
+; REGALLOC: movups xmm3,xmm0
+; REGALLOC-NEXT: pshufd xmm0,xmm0,0x31
+; REGALLOC-NEXT: pshufd xmm5,xmm1,0x31
+; REGALLOC-NEXT: pmuludq xmm3,xmm1
+; REGALLOC-NEXT: pmuludq xmm0,xmm5
+; REGALLOC-NEXT: shufps xmm3,xmm0,0x88
+; REGALLOC-NEXT: pshufd xmm3,xmm3,0xd8
+; REGALLOC-NEXT: movups xmm0,xmm3
+; REGALLOC-NEXT: ret
+}
+
+define void @func5(i32 %foo, i32 %bar) {
+entry:
+ %r1 = icmp eq i32 %foo, %bar
+ br i1 %r1, label %BB1, label %BB2
+BB1:
+ %r2 = icmp sgt i32 %foo, %bar
+ br i1 %r2, label %BB3, label %BB4
+BB2:
+ %r3 = icmp slt i32 %foo, %bar
+ br i1 %r3, label %BB3, label %BB4
+BB3:
+ ret void
+BB4:
+ ret void
+
+; BBREORDERING-LABEL: func5:
+; BBREORDERING: .Lfunc5$entry:
+; BBREORDERING: .Lfunc5$BB1:
+; BBREORDERING: .Lfunc5$BB2:
+; BBREORDERING: .Lfunc5$BB4:
+; BBREORDERING: .Lfunc5$BB3
+}
+
+define i32 @func6(i32 %arg) {
+entry:
+ %res = add i32 200000, %arg
+ ret i32 %res
+
+; BLINDINGO2-LABEL: func6
+; BLINDINGO2: mov [[REG:e[a-z]*]],0xb178f
+; BLINDINGO2-NEXT: lea [[REG]],{{[[]}}[[REG]]-0x80a4f{{[]]}}
+}
+
+; Check for function reordering
+; FUNCREORDERING-LABEL: func1
+; FUNCREORDERING-LABEL: func4
+; FUNCREORDERING-LABEL: func5
+; FUNCREORDERING-LABEL: func2
+; FUNCREORDERING-LABEL: func6
+; FUNCREORDERING-LABEL: func3
+
+; Check for global variable reordering
+; GLOBALVARS-LABEL: ArrayInit
+; GLOBALVARS-LABEL: PrimitiveInit
+; GLOBALVARS-LABEL: ArrayInitPartial
+; GLOBALVARS-LABEL: PrimitiveUninit
+; GLOBALVARS-LABEL: ArrayUninit
+; GLOBALVARS-LABEL: PrimitiveInitStatic
+; GLOBALVARS-LABEL: ArrayUninitConstDouble
+; GLOBALVARS-LABEL: ArrayUninitConstInt
+; GLOBALVARS-LABEL: PrimitiveInitConst
+
+; Check for pooled constant reordering
+; POOLEDCONSTANTS-LABEL: .rodata.cst4
+; POOLEDCONSTANTS: 0000803e 0000803f 00000000 0000003f
+; POOLEDCONSTANTS: 00008040 00000040