Commit aee5fa8d by Qining Lu

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.
parent cfa628b5
...@@ -43,6 +43,16 @@ Cfg::Cfg(GlobalContext *Ctx, uint32_t SequenceNumber) ...@@ -43,6 +43,16 @@ Cfg::Cfg(GlobalContext *Ctx, uint32_t SequenceNumber)
VMetadata(new VariablesMetadata(this)), VMetadata(new VariablesMetadata(this)),
TargetAssembler(TargetLowering::createAssembler( TargetAssembler(TargetLowering::createAssembler(
Ctx->getFlags().getTargetArch(), this)) { 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); } Cfg::~Cfg() { assert(ICE_TLS_GET_FIELD(CurrentCfg) == nullptr); }
...@@ -396,9 +406,11 @@ void Cfg::shuffleNodes() { ...@@ -396,9 +406,11 @@ void Cfg::shuffleNodes() {
NodeList ReversedReachable; NodeList ReversedReachable;
NodeList Unreachable; NodeList Unreachable;
llvm::BitVector ToVisit(Nodes.size(), true); 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. // Traverse from entry node.
getRandomPostOrder(getEntryNode(), ToVisit, ReversedReachable, getRandomPostOrder(getEntryNode(), ToVisit, ReversedReachable, &RNG);
&Ctx->getRNG());
// Collect the unreachable nodes. // Collect the unreachable nodes.
for (CfgNode *Node : Nodes) for (CfgNode *Node : Nodes)
if (ToVisit[Node->getIndex()]) if (ToVisit[Node->getIndex()])
...@@ -431,8 +443,10 @@ void Cfg::doNopInsertion() { ...@@ -431,8 +443,10 @@ void Cfg::doNopInsertion() {
if (!Ctx->getFlags().shouldDoNopInsertion()) if (!Ctx->getFlags().shouldDoNopInsertion())
return; return;
TimerMarker T(TimerStack::TT_doNopInsertion, this); TimerMarker T(TimerStack::TT_doNopInsertion, this);
RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(), RPE_NopInsertion,
SequenceNumber);
for (CfgNode *Node : Nodes) for (CfgNode *Node : Nodes)
Node->doNopInsertion(); Node->doNopInsertion(RNG);
} }
void Cfg::genCode() { void Cfg::genCode() {
......
...@@ -164,6 +164,7 @@ public: ...@@ -164,6 +164,7 @@ public:
bool hasComputedFrame() const; bool hasComputedFrame() const;
bool getFocusedTiming() const { return FocusedTiming; } bool getFocusedTiming() const { return FocusedTiming; }
void setFocusedTiming() { FocusedTiming = true; } void setFocusedTiming() { FocusedTiming = true; }
uint32_t getConstantBlindingCookie() const { return ConstantBlindingCookie; }
/// @} /// @}
/// Returns true if Var is a global variable that is used by the profiling /// Returns true if Var is a global variable that is used by the profiling
...@@ -247,7 +248,8 @@ private: ...@@ -247,7 +248,8 @@ private:
void emitJumpTables(); void emitJumpTables();
GlobalContext *Ctx; 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; VerboseMask VMask;
IceString FunctionName = ""; IceString FunctionName = "";
Type ReturnType = IceType_void; Type ReturnType = IceType_void;
......
...@@ -496,7 +496,7 @@ void CfgNode::doAddressOpt() { ...@@ -496,7 +496,7 @@ void CfgNode::doAddressOpt() {
} }
} }
void CfgNode::doNopInsertion() { void CfgNode::doNopInsertion(RandomNumberGenerator &RNG) {
TargetLowering *Target = Func->getTarget(); TargetLowering *Target = Func->getTarget();
LoweringContext &Context = Target->getContext(); LoweringContext &Context = Target->getContext();
Context.init(this); Context.init(this);
...@@ -510,7 +510,7 @@ void CfgNode::doNopInsertion() { ...@@ -510,7 +510,7 @@ void CfgNode::doNopInsertion() {
PauseNopInsertion = false; PauseNopInsertion = false;
} }
if (!PauseNopInsertion) if (!PauseNopInsertion)
Target->doNopInsertion(); Target->doNopInsertion(RNG);
// Ensure Cur=Next, so that the nops are inserted before the current // Ensure Cur=Next, so that the nops are inserted before the current
// instruction rather than after. // instruction rather than after.
Context.advanceCur(); Context.advanceCur();
......
...@@ -91,7 +91,7 @@ public: ...@@ -91,7 +91,7 @@ public:
void deletePhis(); void deletePhis();
void advancedPhiLowering(); void advancedPhiLowering();
void doAddressOpt(); void doAddressOpt();
void doNopInsertion(); void doNopInsertion(RandomNumberGenerator &RNG);
void genCode(); void genCode();
void livenessLightweight(); void livenessLightweight();
bool liveness(Liveness *Liveness); bool liveness(Liveness *Liveness);
......
...@@ -279,6 +279,18 @@ llvm::iterator_range<typename T::reverse_iterator> reverse_range(T &Container) { ...@@ -279,6 +279,18 @@ llvm::iterator_range<typename T::reverse_iterator> reverse_range(T &Container) {
/// Options for pooling and randomization of immediates. /// Options for pooling and randomization of immediates.
enum RandomizeAndPoolImmediatesEnum { RPI_None, RPI_Randomize, RPI_Pool }; 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 } // end of namespace Ice
#endif // SUBZERO_SRC_ICEDEFS_H #endif // SUBZERO_SRC_ICEDEFS_H
...@@ -512,11 +512,15 @@ template <typename ConstType> void ELFObjectWriter::writeConstantPool(Type Ty) { ...@@ -512,11 +512,15 @@ template <typename ConstType> void ELFObjectWriter::writeConstantPool(Type Ty) {
// If the -reorder-pooled-constant option is set to true, we should shuffle // If the -reorder-pooled-constant option is set to true, we should shuffle
// the constants before we emit them. // the constants before we emit them.
auto *CtxPtr = &Ctx; if (Ctx.getFlags().shouldReorderPooledConstants() && !Pool.empty()) {
if (Ctx.getFlags().shouldReorderPooledConstants()) // Use the constant's kind value as the salt for creating random number
RandomShuffle(Pool.begin(), Pool.end(), [CtxPtr](uint64_t N) { // generator.
return (uint32_t)CtxPtr->getRNG().next(N); 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. // Write the data.
for (Constant *C : Pool) { for (Constant *C : Pool) {
if (!C->getShouldBePooled()) if (!C->getShouldBePooled())
......
...@@ -222,8 +222,7 @@ void GlobalContext::CodeStats::dump(const IceString &Name, Ostream &Str) { ...@@ -222,8 +222,7 @@ void GlobalContext::CodeStats::dump(const IceString &Name, Ostream &Str) {
GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
ELFStreamer *ELFStr, const ClFlags &Flags) ELFStreamer *ELFStr, const ClFlags &Flags)
: ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump),
StrEmit(OsEmit), StrError(OsError), Flags(Flags), StrEmit(OsEmit), StrError(OsError), Flags(Flags), ObjectWriter(),
RNG(Flags.getRandomSeed()), ObjectWriter(),
OptQ(/*Sequential=*/Flags.isSequential(), OptQ(/*Sequential=*/Flags.isSequential(),
/*MaxSize=*/Flags.getNumTranslationThreads()), /*MaxSize=*/Flags.getNumTranslationThreads()),
// EmitQ is allowed unlimited size. // EmitQ is allowed unlimited size.
...@@ -273,14 +272,6 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, ...@@ -273,14 +272,6 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
ProfileBlockInfoVarDecl->setName("__Sz_block_profile_info"); ProfileBlockInfoVarDecl->setName("__Sz_block_profile_info");
ProfileBlockInfoVarDecl->setSuppressMangling(); ProfileBlockInfoVarDecl->setSuppressMangling();
ProfileBlockInfoVarDecl->setLinkage(llvm::GlobalValue::ExternalLinkage); 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() { void GlobalContext::translateFunctions() {
...@@ -403,9 +394,11 @@ void GlobalContext::lowerGlobals(const IceString &SectionSuffix) { ...@@ -403,9 +394,11 @@ void GlobalContext::lowerGlobals(const IceString &SectionSuffix) {
addBlockInfoPtrs(Globals, ProfileBlockInfoVarDecl); addBlockInfoPtrs(Globals, ProfileBlockInfoVarDecl);
// If we need to shuffle the layout of global variables, shuffle them now. // If we need to shuffle the layout of global variables, shuffle them now.
if (getFlags().shouldReorderGlobalVariables()) { 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(), 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); DataLowering->lowerGlobals(Globals, SectionSuffix);
for (VariableDeclaration *Var : Globals) { for (VariableDeclaration *Var : Globals) {
...@@ -446,6 +439,9 @@ void GlobalContext::emitItems() { ...@@ -446,6 +439,9 @@ void GlobalContext::emitItems() {
const uint32_t ShuffleWindowSize = const uint32_t ShuffleWindowSize =
std::max(1u, getFlags().getReorderFunctionsWindowSize()); std::max(1u, getFlags().getReorderFunctionsWindowSize());
bool Shuffle = Threaded && getFlags().shouldReorderFunctions(); bool Shuffle = Threaded && getFlags().shouldReorderFunctions();
// Create a random number generator for function reordering.
RandomNumberGenerator RNG(getFlags().getRandomSeed(), RPE_FunctionReordering);
while (!EmitQueueEmpty) { while (!EmitQueueEmpty) {
resizePending(Pending, DesiredSequenceNumber); resizePending(Pending, DesiredSequenceNumber);
// See if Pending contains DesiredSequenceNumber. // See if Pending contains DesiredSequenceNumber.
...@@ -497,7 +493,7 @@ void GlobalContext::emitItems() { ...@@ -497,7 +493,7 @@ void GlobalContext::emitItems() {
// Pending[ShuffleEndIndex]. // Pending[ShuffleEndIndex].
RandomShuffle(Pending.begin() + ShuffleStartIndex, RandomShuffle(Pending.begin() + ShuffleStartIndex,
Pending.begin() + ShuffleEndIndex, 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. // Emit the item from ShuffleStartIndex to ShuffleEndIndex.
...@@ -879,20 +875,25 @@ ConstantList GlobalContext::getConstantExternSyms() { ...@@ -879,20 +875,25 @@ ConstantList GlobalContext::getConstantExternSyms() {
JumpTableDataList GlobalContext::getJumpTables() { JumpTableDataList GlobalContext::getJumpTables() {
JumpTableDataList JumpTables(*getJumpTableList()); 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 (getFlags().shouldReorderPooledConstants()) {
// If reorder-pooled-constants option is set to true, we need to shuffle the // If reorder-pooled-constants option is set to true, we also shuffle the
// constant pool before emitting it. // 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(), RandomShuffle(JumpTables.begin(), JumpTables.end(),
[this](uint64_t N) { return (uint32_t)getRNG().next(N); }); [&RNG](uint64_t N) { return (uint32_t)RNG.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();
});
} }
return JumpTables; return JumpTables;
} }
......
...@@ -243,10 +243,6 @@ public: ...@@ -243,10 +243,6 @@ public:
const Intrinsics &getIntrinsicsInfo() const { return IntrinsicsInfo; } 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(); } ELFObjectWriter *getObjectWriter() const { return ObjectWriter.get(); }
/// Reset stats at the beginning of a function. /// Reset stats at the beginning of a function.
...@@ -440,10 +436,6 @@ public: ...@@ -440,10 +436,6 @@ public:
return Match.empty() || Match == SymbolName; return Match.empty() || Match == SymbolName;
} }
/// Return the randomization cookie for diversification.
/// Initialize the cookie if necessary
uint32_t getRandomizationCookie() const { return RandomizationCookie; }
private: private:
// Try to ensure mutexes are allocated on separate cache lines. // Try to ensure mutexes are allocated on separate cache lines.
...@@ -496,7 +488,6 @@ private: ...@@ -496,7 +488,6 @@ private:
Intrinsics IntrinsicsInfo; Intrinsics IntrinsicsInfo;
const ClFlags &Flags; const ClFlags &Flags;
RandomNumberGenerator RNG; // TODO(stichnot): Move into Cfg.
// TODO(jpp): move to EmitterContext. // TODO(jpp): move to EmitterContext.
std::unique_ptr<ELFObjectWriter> ObjectWriter; std::unique_ptr<ELFObjectWriter> ObjectWriter;
BoundedProducerConsumerQueue<Cfg> OptQ; BoundedProducerConsumerQueue<Cfg> OptQ;
...@@ -557,11 +548,6 @@ private: ...@@ -557,11 +548,6 @@ private:
typedef llvm::SmallVector<char, 32> ManglerVector; typedef llvm::SmallVector<char, 32> ManglerVector;
void incrementSubstitutions(ManglerVector &OldName) const; void incrementSubstitutions(ManglerVector &OldName) const;
// Randomization Cookie
// Managed by getRandomizationCookie()
GlobalLockType RandomizationCookieLock;
uint32_t RandomizationCookie = 0;
public: public:
static void TlsInit() { ICE_TLS_INIT_FIELD(TLS); } static void TlsInit() { ICE_TLS_INIT_FIELD(TLS); }
}; };
......
...@@ -31,6 +31,16 @@ constexpr unsigned MAX = 2147483647; ...@@ -31,6 +31,16 @@ constexpr unsigned MAX = 2147483647;
RandomNumberGenerator::RandomNumberGenerator(uint64_t Seed, llvm::StringRef) RandomNumberGenerator::RandomNumberGenerator(uint64_t Seed, llvm::StringRef)
: State(Seed) {} : 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) { uint64_t RandomNumberGenerator::next(uint64_t Max) {
// Lewis, Goodman, and Miller (1969) // Lewis, Goodman, and Miller (1969)
State = (16807 * State) % MAX; State = (16807 * State) % MAX;
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include "IceDefs.h"
#include <cstdint> #include <cstdint>
namespace Ice { namespace Ice {
...@@ -28,6 +30,22 @@ class RandomNumberGenerator { ...@@ -28,6 +30,22 @@ class RandomNumberGenerator {
public: public:
explicit RandomNumberGenerator(uint64_t Seed, llvm::StringRef Salt = ""); 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); uint64_t next(uint64_t Max);
private: private:
......
...@@ -250,11 +250,11 @@ void LinearScan::init(RegAllocKind Kind) { ...@@ -250,11 +250,11 @@ void LinearScan::init(RegAllocKind Kind) {
} }
auto CompareRanges = [](const Variable *L, const Variable *R) { auto CompareRanges = [](const Variable *L, const Variable *R) {
InstNumberT Lstart = L->getLiveRange().getStart(); InstNumberT Lstart = L->getLiveRange().getStart();
InstNumberT Rstart = R->getLiveRange().getStart(); InstNumberT Rstart = R->getLiveRange().getStart();
if (Lstart == Rstart) if (Lstart == Rstart)
return L->getIndex() < R->getIndex(); return L->getIndex() < R->getIndex();
return Lstart < Rstart; return Lstart < Rstart;
}; };
// Do a reverse sort so that erasing elements (from the end) is fast. // Do a reverse sort so that erasing elements (from the end) is fast.
std::sort(Unhandled.rbegin(), Unhandled.rend(), CompareRanges); std::sort(Unhandled.rbegin(), Unhandled.rend(), CompareRanges);
...@@ -776,8 +776,15 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull, ...@@ -776,8 +776,15 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull,
llvm::SmallVector<int32_t, REGS_SIZE> Permutation(NumRegisters); llvm::SmallVector<int32_t, REGS_SIZE> Permutation(NumRegisters);
if (Randomized) { 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( Func->getTarget()->makeRandomRegisterPermutation(
Permutation, PreDefinedRegisters | ~RegMaskFull); Permutation, PreDefinedRegisters | ~RegMaskFull, Salt);
} }
// Finish up by assigning RegNumTmp->RegNum (or a random permutation // Finish up by assigning RegNumTmp->RegNum (or a random permutation
......
...@@ -103,7 +103,7 @@ void TargetLowering::doAddressOpt() { ...@@ -103,7 +103,7 @@ void TargetLowering::doAddressOpt() {
Context.advanceNext(); Context.advanceNext();
} }
void TargetLowering::doNopInsertion() { void TargetLowering::doNopInsertion(RandomNumberGenerator &RNG) {
Inst *I = Context.getCur(); Inst *I = Context.getCur();
bool ShouldSkip = llvm::isa<InstFakeUse>(I) || llvm::isa<InstFakeDef>(I) || bool ShouldSkip = llvm::isa<InstFakeUse>(I) || llvm::isa<InstFakeDef>(I) ||
llvm::isa<InstFakeKill>(I) || I->isRedundantAssign() || llvm::isa<InstFakeKill>(I) || I->isRedundantAssign() ||
...@@ -111,7 +111,7 @@ void TargetLowering::doNopInsertion() { ...@@ -111,7 +111,7 @@ void TargetLowering::doNopInsertion() {
if (!ShouldSkip) { if (!ShouldSkip) {
int Probability = Ctx->getFlags().getNopProbabilityAsPercentage(); int Probability = Ctx->getFlags().getNopProbabilityAsPercentage();
for (int I = 0; I < Ctx->getFlags().getMaxNopsPerInstruction(); ++I) { for (int I = 0; I < Ctx->getFlags().getMaxNopsPerInstruction(); ++I) {
randomlyInsertNop(Probability / 100.0); randomlyInsertNop(Probability / 100.0, RNG);
} }
} }
} }
......
...@@ -153,7 +153,7 @@ public: ...@@ -153,7 +153,7 @@ public:
/// Tries to do address mode optimization on a single instruction. /// Tries to do address mode optimization on a single instruction.
void doAddressOpt(); void doAddressOpt();
/// Randomly insert NOPs. /// Randomly insert NOPs.
void doNopInsertion(); void doNopInsertion(RandomNumberGenerator &RNG);
/// Lowers a single non-Phi instruction. /// Lowers a single non-Phi instruction.
void lower(); void lower();
/// Inserts and lowers a single high-level instruction at a specific insertion /// Inserts and lowers a single high-level instruction at a specific insertion
...@@ -213,9 +213,10 @@ public: ...@@ -213,9 +213,10 @@ public:
virtual const llvm::SmallBitVector &getRegisterSetForType(Type Ty) const = 0; virtual const llvm::SmallBitVector &getRegisterSetForType(Type Ty) const = 0;
void regAlloc(RegAllocKind Kind); void regAlloc(RegAllocKind Kind);
virtual void makeRandomRegisterPermutation( virtual void
llvm::SmallVectorImpl<int32_t> &Permutation, makeRandomRegisterPermutation(llvm::SmallVectorImpl<int32_t> &Permutation,
const llvm::SmallBitVector &ExcludeRegisters) const = 0; const llvm::SmallBitVector &ExcludeRegisters,
uint64_t Salt) const = 0;
/// Save/restore any mutable state for the situation where code /// Save/restore any mutable state for the situation where code
/// emission needs multiple passes, such as sandboxing or relaxation. /// emission needs multiple passes, such as sandboxing or relaxation.
...@@ -279,7 +280,8 @@ protected: ...@@ -279,7 +280,8 @@ protected:
virtual void doAddressOptLoad() {} virtual void doAddressOptLoad() {}
virtual void doAddressOptStore() {} 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 /// This gives the target an opportunity to post-process the lowered
/// expansion before returning. /// expansion before returning.
virtual void postLower() {} virtual void postLower() {}
......
...@@ -2505,9 +2505,10 @@ void TargetARM32::doAddressOptLoad() { ...@@ -2505,9 +2505,10 @@ void TargetARM32::doAddressOptLoad() {
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetARM32::randomlyInsertNop(float Probability) { void TargetARM32::randomlyInsertNop(float Probability,
RandomNumberGeneratorWrapper RNG(Ctx->getRNG()); RandomNumberGenerator &RNG) {
if (RNG.getTrueWithProbability(Probability)) { RandomNumberGeneratorWrapper RNGW(RNG);
if (RNGW.getTrueWithProbability(Probability)) {
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
} }
} }
...@@ -2929,9 +2930,10 @@ void TargetARM32::postLower() { ...@@ -2929,9 +2930,10 @@ void TargetARM32::postLower() {
void TargetARM32::makeRandomRegisterPermutation( void TargetARM32::makeRandomRegisterPermutation(
llvm::SmallVectorImpl<int32_t> &Permutation, llvm::SmallVectorImpl<int32_t> &Permutation,
const llvm::SmallBitVector &ExcludeRegisters) const { const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const {
(void)Permutation; (void)Permutation;
(void)ExcludeRegisters; (void)ExcludeRegisters;
(void)Salt;
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
} }
......
...@@ -138,7 +138,8 @@ protected: ...@@ -138,7 +138,8 @@ protected:
void prelowerPhis() override; void prelowerPhis() override;
void doAddressOptLoad() override; void doAddressOptLoad() override;
void doAddressOptStore() override; void doAddressOptStore() override;
void randomlyInsertNop(float Probability) override; void randomlyInsertNop(float Probability,
RandomNumberGenerator &RNG) override;
enum OperandLegalization { enum OperandLegalization {
Legal_None = 0, Legal_None = 0,
...@@ -162,9 +163,10 @@ protected: ...@@ -162,9 +163,10 @@ protected:
/// Returns a vector in a register with the given constant entries. /// Returns a vector in a register with the given constant entries.
Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister);
void makeRandomRegisterPermutation( void
llvm::SmallVectorImpl<int32_t> &Permutation, makeRandomRegisterPermutation(llvm::SmallVectorImpl<int32_t> &Permutation,
const llvm::SmallBitVector &ExcludeRegisters) const override; const llvm::SmallBitVector &ExcludeRegisters,
uint64_t Salt) const override;
// If a divide-by-zero check is needed, inserts a: // If a divide-by-zero check is needed, inserts a:
// test; branch .LSKIP; trap; .LSKIP: <continuation>. // test; branch .LSKIP; trap; .LSKIP: <continuation>.
......
...@@ -607,9 +607,10 @@ void TargetMIPS32::doAddressOptLoad() { ...@@ -607,9 +607,10 @@ void TargetMIPS32::doAddressOptLoad() {
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::randomlyInsertNop(float Probability) { void TargetMIPS32::randomlyInsertNop(float Probability,
RandomNumberGeneratorWrapper RNG(Ctx->getRNG()); RandomNumberGenerator &RNG) {
if (RNG.getTrueWithProbability(Probability)) { RandomNumberGeneratorWrapper RNGW(RNG);
if (RNGW.getTrueWithProbability(Probability)) {
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
} }
} }
...@@ -666,9 +667,10 @@ void TargetMIPS32::postLower() { ...@@ -666,9 +667,10 @@ void TargetMIPS32::postLower() {
void TargetMIPS32::makeRandomRegisterPermutation( void TargetMIPS32::makeRandomRegisterPermutation(
llvm::SmallVectorImpl<int32_t> &Permutation, llvm::SmallVectorImpl<int32_t> &Permutation,
const llvm::SmallBitVector &ExcludeRegisters) const { const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const {
(void)Permutation; (void)Permutation;
(void)ExcludeRegisters; (void)ExcludeRegisters;
(void)Salt;
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
} }
......
...@@ -116,10 +116,12 @@ protected: ...@@ -116,10 +116,12 @@ protected:
void prelowerPhis() override; void prelowerPhis() override;
void doAddressOptLoad() override; void doAddressOptLoad() override;
void doAddressOptStore() override; void doAddressOptStore() override;
void randomlyInsertNop(float Probability) override; void randomlyInsertNop(float Probability,
void makeRandomRegisterPermutation( RandomNumberGenerator &RNG) override;
llvm::SmallVectorImpl<int32_t> &Permutation, void
const llvm::SmallBitVector &ExcludeRegisters) const override; makeRandomRegisterPermutation(llvm::SmallVectorImpl<int32_t> &Permutation,
const llvm::SmallBitVector &ExcludeRegisters,
uint64_t Salt) const override;
static Type stackSlotType(); static Type stackSlotType();
......
...@@ -731,10 +731,16 @@ void TargetDataX8632::emitConstantPool(GlobalContext *Ctx) { ...@@ -731,10 +731,16 @@ void TargetDataX8632::emitConstantPool(GlobalContext *Ctx) {
// If reorder-pooled-constants option is set to true, we need to shuffle the // If reorder-pooled-constants option is set to true, we need to shuffle the
// constant pool before emitting it. // constant pool before emitting it.
if (Ctx->getFlags().shouldReorderPooledConstants()) if (Ctx->getFlags().shouldReorderPooledConstants() && !Pool.empty()) {
RandomShuffle(Pool.begin(), Pool.end(), [Ctx](uint64_t N) { // Use the constant's kind value as the salt for creating random number
return (uint32_t)Ctx->getRNG().next(N); // 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) { for (Constant *C : Pool) {
if (!C->getShouldBePooled()) if (!C->getShouldBePooled())
......
...@@ -362,7 +362,8 @@ template <> struct MachineTraits<TargetX8632> { ...@@ -362,7 +362,8 @@ template <> struct MachineTraits<TargetX8632> {
static void static void
makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func, makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func,
llvm::SmallVectorImpl<int32_t> &Permutation, 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 // TODO(stichnot): Declaring Permutation this way loses type/size
// information. Fix this in conjunction with the caller-side TODO. // information. Fix this in conjunction with the caller-side TODO.
assert(Permutation.size() >= RegisterSet::Reg_NUM); assert(Permutation.size() >= RegisterSet::Reg_NUM);
...@@ -393,13 +394,16 @@ template <> struct MachineTraits<TargetX8632> { ...@@ -393,13 +394,16 @@ template <> struct MachineTraits<TargetX8632> {
REGX8632_TABLE REGX8632_TABLE
#undef X #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. // Shuffle the resulting equivalence classes.
for (auto I : EquivalenceClasses) { for (auto I : EquivalenceClasses) {
const RegisterList &List = I.second; const RegisterList &List = I.second;
RegisterList Shuffled(List); 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) { for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) {
Permutation[List[SI]] = Shuffled[SI]; Permutation[List[SI]] = Shuffled[SI];
++NumShuffled; ++NumShuffled;
......
...@@ -743,10 +743,15 @@ void TargetDataX8664::emitConstantPool(GlobalContext *Ctx) { ...@@ -743,10 +743,15 @@ void TargetDataX8664::emitConstantPool(GlobalContext *Ctx) {
// If reorder-pooled-constants option is set to true, we need to shuffle the // If reorder-pooled-constants option is set to true, we need to shuffle the
// constant pool before emitting it. // constant pool before emitting it.
if (Ctx->getFlags().shouldReorderPooledConstants()) if (Ctx->getFlags().shouldReorderPooledConstants()) {
RandomShuffle(Pool.begin(), Pool.end(), [Ctx](uint64_t N) { // Use the constant's kind value as the salt for creating random number
return (uint32_t)Ctx->getRNG().next(N); // 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) { for (Constant *C : Pool) {
if (!C->getShouldBePooled()) if (!C->getShouldBePooled())
......
...@@ -375,7 +375,8 @@ template <> struct MachineTraits<TargetX8664> { ...@@ -375,7 +375,8 @@ template <> struct MachineTraits<TargetX8664> {
static void static void
makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func, makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func,
llvm::SmallVectorImpl<int32_t> &Permutation, 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 // TODO(stichnot): Declaring Permutation this way loses type/size
// information. Fix this in conjunction with the caller-side TODO. // information. Fix this in conjunction with the caller-side TODO.
assert(Permutation.size() >= RegisterSet::Reg_NUM); assert(Permutation.size() >= RegisterSet::Reg_NUM);
...@@ -406,13 +407,16 @@ template <> struct MachineTraits<TargetX8664> { ...@@ -406,13 +407,16 @@ template <> struct MachineTraits<TargetX8664> {
REGX8664_TABLE REGX8664_TABLE
#undef X #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. // Shuffle the resulting equivalence classes.
for (auto I : EquivalenceClasses) { for (auto I : EquivalenceClasses) {
const RegisterList &List = I.second; const RegisterList &List = I.second;
RegisterList Shuffled(List); 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) { for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) {
Permutation[List[SI]] = Shuffled[SI]; Permutation[List[SI]] = Shuffled[SI];
++NumShuffled; ++NumShuffled;
......
...@@ -180,7 +180,8 @@ protected: ...@@ -180,7 +180,8 @@ protected:
void prelowerPhis() override; void prelowerPhis() override;
void doAddressOptLoad() override; void doAddressOptLoad() override;
void doAddressOptStore() override; void doAddressOptStore() override;
void randomlyInsertNop(float Probability) override; void randomlyInsertNop(float Probability,
RandomNumberGenerator &RNG) override;
/// Naive lowering of cmpxchg. /// Naive lowering of cmpxchg.
void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected, void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected,
...@@ -290,9 +291,10 @@ protected: ...@@ -290,9 +291,10 @@ protected:
typename Traits::X86OperandMem * typename Traits::X86OperandMem *
getMemoryOperandForStackSlot(Type Ty, Variable *Slot, uint32_t Offset = 0); getMemoryOperandForStackSlot(Type Ty, Variable *Slot, uint32_t Offset = 0);
void makeRandomRegisterPermutation( void
llvm::SmallVectorImpl<int32_t> &Permutation, makeRandomRegisterPermutation(llvm::SmallVectorImpl<int32_t> &Permutation,
const llvm::SmallBitVector &ExcludeRegisters) const override; const llvm::SmallBitVector &ExcludeRegisters,
uint64_t Salt) const override;
/// The following are helpers that insert lowered x86 instructions /// The following are helpers that insert lowered x86 instructions
/// with minimal syntactic overhead, so that the lowering code can /// with minimal syntactic overhead, so that the lowering code can
......
...@@ -4161,10 +4161,11 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptLoad() { ...@@ -4161,10 +4161,11 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptLoad() {
} }
template <class Machine> template <class Machine>
void TargetX86Base<Machine>::randomlyInsertNop(float Probability) { void TargetX86Base<Machine>::randomlyInsertNop(float Probability,
RandomNumberGeneratorWrapper RNG(Ctx->getRNG()); RandomNumberGenerator &RNG) {
if (RNG.getTrueWithProbability(Probability)) { RandomNumberGeneratorWrapper RNGW(RNG);
_nop(RNG(Traits::X86_NUM_NOP_VARIANTS)); if (RNGW.getTrueWithProbability(Probability)) {
_nop(RNGW(Traits::X86_NUM_NOP_VARIANTS));
} }
} }
...@@ -5119,9 +5120,9 @@ template <class Machine> void TargetX86Base<Machine>::postLower() { ...@@ -5119,9 +5120,9 @@ template <class Machine> void TargetX86Base<Machine>::postLower() {
template <class Machine> template <class Machine>
void TargetX86Base<Machine>::makeRandomRegisterPermutation( void TargetX86Base<Machine>::makeRandomRegisterPermutation(
llvm::SmallVectorImpl<int32_t> &Permutation, llvm::SmallVectorImpl<int32_t> &Permutation,
const llvm::SmallBitVector &ExcludeRegisters) const { const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const {
Traits::makeRandomRegisterPermutation(Ctx, Func, Permutation, Traits::makeRandomRegisterPermutation(Ctx, Func, Permutation,
ExcludeRegisters); ExcludeRegisters, Salt);
} }
template <class Machine> template <class Machine>
...@@ -5196,7 +5197,7 @@ Operand *TargetX86Base<Machine>::randomizeOrPoolImmediate(Constant *Immediate, ...@@ -5196,7 +5197,7 @@ Operand *TargetX86Base<Machine>::randomizeOrPoolImmediate(Constant *Immediate,
Variable *Reg = makeReg(IceType_i32, RegNum); Variable *Reg = makeReg(IceType_i32, RegNum);
ConstantInteger32 *Integer = llvm::cast<ConstantInteger32>(Immediate); ConstantInteger32 *Integer = llvm::cast<ConstantInteger32>(Immediate);
uint32_t Value = Integer->getValue(); uint32_t Value = Integer->getValue();
uint32_t Cookie = Ctx->getRandomizationCookie(); uint32_t Cookie = Func->getConstantBlindingCookie();
_mov(Reg, Ctx->getConstantInt(IceType_i32, Cookie + Value)); _mov(Reg, Ctx->getConstantInt(IceType_i32, Cookie + Value));
Constant *Offset = Ctx->getConstantInt(IceType_i32, 0 - Cookie); Constant *Offset = Ctx->getConstantInt(IceType_i32, 0 - Cookie);
_lea(Reg, Traits::X86OperandMem::create(Func, IceType_i32, Reg, Offset, _lea(Reg, Traits::X86OperandMem::create(Func, IceType_i32, Reg, Offset,
...@@ -5275,7 +5276,7 @@ TargetX86Base<Machine>::randomizeOrPoolImmediate( ...@@ -5275,7 +5276,7 @@ TargetX86Base<Machine>::randomizeOrPoolImmediate(
uint32_t Value = uint32_t Value =
llvm::dyn_cast<ConstantInteger32>(MemOperand->getOffset()) llvm::dyn_cast<ConstantInteger32>(MemOperand->getOffset())
->getValue(); ->getValue();
uint32_t Cookie = Ctx->getRandomizationCookie(); uint32_t Cookie = Func->getConstantBlindingCookie();
Constant *Mask1 = Ctx->getConstantInt( Constant *Mask1 = Ctx->getConstantInt(
MemOperand->getOffset()->getType(), Cookie + Value); MemOperand->getOffset()->getType(), Cookie + Value);
Constant *Mask2 = Constant *Mask2 =
......
...@@ -25,106 +25,112 @@ entry: ...@@ -25,106 +25,112 @@ entry:
ret <4 x i32> %res ret <4 x i32> %res
; PROB50-LABEL: mul_v4i32 ; PROB50-LABEL: mul_v4i32
; PROB50: nop # variant = 4 ; PROB50: nop # variant = 1
; PROB50: subl $60, %esp ; PROB50: subl $60, %esp
; PROB50: nop # variant = 3
; PROB50: movups %xmm0, 32(%esp) ; PROB50: movups %xmm0, 32(%esp)
; PROB50: nop # variant = 0
; PROB50: movups %xmm1, 16(%esp) ; PROB50: movups %xmm1, 16(%esp)
; PROB50: nop # variant = 4
; PROB50: movups 32(%esp), %xmm0 ; PROB50: movups 32(%esp), %xmm0
; PROB50: nop # variant = 1
; PROB50: pshufd $49, 32(%esp), %xmm1 ; PROB50: pshufd $49, 32(%esp), %xmm1
; PROB50: nop # variant = 4
; PROB50: pshufd $49, 16(%esp), %xmm2 ; PROB50: pshufd $49, 16(%esp), %xmm2
; PROB50: nop # variant = 1
; PROB50: pmuludq 16(%esp), %xmm0 ; PROB50: pmuludq 16(%esp), %xmm0
; PROB50: nop # variant = 0
; PROB50: pmuludq %xmm2, %xmm1 ; PROB50: pmuludq %xmm2, %xmm1
; PROB50: nop # variant = 0
; PROB50: shufps $136, %xmm1, %xmm0 ; PROB50: shufps $136, %xmm1, %xmm0
; PROB50: nop # variant = 2 ; PROB50: nop # variant = 3
; PROB50: pshufd $216, %xmm0, %xmm0 ; PROB50: pshufd $216, %xmm0, %xmm0
; PROB50: nop # variant = 1
; PROB50: movups %xmm0, (%esp) ; PROB50: movups %xmm0, (%esp)
; PROB50: movups (%esp), %xmm0 ; PROB50: movups (%esp), %xmm0
; PROB50: nop # variant = 0
; PROB50: addl $60, %esp ; PROB50: addl $60, %esp
; PROB50: nop # variant = 3
; PROB50: ret ; PROB50: ret
; PROB90-LABEL: mul_v4i32 ; PROB90-LABEL: mul_v4i32
; PROB90: nop # variant = 4 ; PROB90: nop # variant = 1
; PROB90: subl $60, %esp ; PROB90: subl $60, %esp
; PROB90: nop # variant = 3 ; PROB90: nop # variant = 3
; PROB90: movups %xmm0, 32(%esp) ; PROB90: movups %xmm0, 32(%esp)
; PROB90: nop # variant = 2 ; PROB90: nop # variant = 4
; PROB90: movups %xmm1, 16(%esp) ; PROB90: movups %xmm1, 16(%esp)
; PROB90: nop # variant = 3 ; PROB90: nop # variant = 1
; PROB90: movups 32(%esp), %xmm0 ; PROB90: movups 32(%esp), %xmm0
; PROB90: nop # variant = 4 ; PROB90: nop # variant = 4
; PROB90: pshufd $49, 32(%esp), %xmm1 ; PROB90: pshufd $49, 32(%esp), %xmm1
; PROB90: nop # variant = 0 ; PROB90: nop # variant = 1
; PROB90: pshufd $49, 16(%esp), %xmm2 ; PROB90: pshufd $49, 16(%esp), %xmm2
; PROB90: nop # variant = 2 ; PROB90: nop # variant = 4
; PROB90: pmuludq 16(%esp), %xmm0 ; PROB90: pmuludq 16(%esp), %xmm0
; PROB90: nop # variant = 3 ; PROB90: nop # variant = 2
; PROB90: pmuludq %xmm2, %xmm1 ; PROB90: pmuludq %xmm2, %xmm1
; PROB90: nop # variant = 4
; PROB90: shufps $136, %xmm1, %xmm0 ; PROB90: shufps $136, %xmm1, %xmm0
; PROB90: nop # variant = 2 ; PROB90: nop # variant = 1
; PROB90: pshufd $216, %xmm0, %xmm0 ; PROB90: pshufd $216, %xmm0, %xmm0
; PROB90: nop # variant = 4
; PROB90: movups %xmm0, (%esp) ; PROB90: movups %xmm0, (%esp)
; PROB90: nop # variant = 2 ; PROB90: nop # variant = 1
; PROB90: movups (%esp), %xmm0 ; PROB90: movups (%esp), %xmm0
; PROB90: nop # variant = 3 ; PROB90: nop # variant = 0
; PROB90: addl $60, %esp ; PROB90: addl $60, %esp
; PROB90: nop # variant = 3 ; PROB90: nop # variant = 0
; PROB90: ret ; PROB90: ret
; PROB90: nop # variant = 4
; MAXNOPS2-LABEL: mul_v4i32 ; MAXNOPS2-LABEL: mul_v4i32
; MAXNOPS2: nop # variant = 4 ; MAXNOPS2: nop # variant = 1
; MAXNOPS2: nop # variant = 3
; MAXNOPS2: subl $60, %esp ; MAXNOPS2: subl $60, %esp
; MAXNOPS2: nop # variant = 0
; MAXNOPS2: nop # variant = 4
; MAXNOPS2: movups %xmm0, 32(%esp) ; MAXNOPS2: movups %xmm0, 32(%esp)
; MAXNOPS2: nop # variant = 1
; MAXNOPS2: nop # variant = 4
; MAXNOPS2: movups %xmm1, 16(%esp) ; MAXNOPS2: movups %xmm1, 16(%esp)
; MAXNOPS2: nop # variant = 0 ; MAXNOPS2: nop # variant = 1
; MAXNOPS2: movups 32(%esp), %xmm0 ; 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 = 0
; MAXNOPS2: nop # variant = 3 ; 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 16(%esp), %xmm0
; MAXNOPS2: pmuludq %xmm2, %xmm1 ; MAXNOPS2: pmuludq %xmm2, %xmm1
; MAXNOPS2: nop # variant = 0
; MAXNOPS2: shufps $136, %xmm1, %xmm0 ; MAXNOPS2: shufps $136, %xmm1, %xmm0
; MAXNOPS2: nop # variant = 3
; MAXNOPS2: pshufd $216, %xmm0, %xmm0
; MAXNOPS2: nop # variant = 0 ; 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: movups %xmm0, (%esp)
; MAXNOPS2: nop # variant = 2 ; MAXNOPS2: nop # variant = 3
; MAXNOPS2: movups (%esp), %xmm0 ; MAXNOPS2: movups (%esp), %xmm0
; MAXNOPS2: nop # variant = 4
; MAXNOPS2: addl $60, %esp ; MAXNOPS2: addl $60, %esp
; MAXNOPS2: nop # variant = 3
; MAXNOPS2: ret ; MAXNOPS2: ret
; SANDBOX50-LABEL: mul_v4i32 ; SANDBOX50-LABEL: mul_v4i32
; SANDBOX50: nop # variant = 4 ; SANDBOX50: nop # variant = 1
; SANDBOX50: subl $60, %esp ; SANDBOX50: subl $60, %esp
; SANDBOX50: nop # variant = 3
; SANDBOX50: movups %xmm0, 32(%esp) ; SANDBOX50: movups %xmm0, 32(%esp)
; SANDBOX50: nop # variant = 0
; SANDBOX50: movups %xmm1, 16(%esp) ; SANDBOX50: movups %xmm1, 16(%esp)
; SANDBOX50: nop # variant = 4
; SANDBOX50: movups 32(%esp), %xmm0 ; SANDBOX50: movups 32(%esp), %xmm0
; SANDBOX50: nop # variant = 1
; SANDBOX50: pshufd $49, 32(%esp), %xmm1 ; SANDBOX50: pshufd $49, 32(%esp), %xmm1
; SANDBOX50: nop # variant = 4
; SANDBOX50: pshufd $49, 16(%esp), %xmm2 ; SANDBOX50: pshufd $49, 16(%esp), %xmm2
; SANDBOX50: nop # variant = 1
; SANDBOX50: pmuludq 16(%esp), %xmm0 ; SANDBOX50: pmuludq 16(%esp), %xmm0
; SANDBOX50: nop # variant = 0
; SANDBOX50: pmuludq %xmm2, %xmm1 ; SANDBOX50: pmuludq %xmm2, %xmm1
; SANDBOX50: nop # variant = 0
; SANDBOX50: shufps $136, %xmm1, %xmm0 ; SANDBOX50: shufps $136, %xmm1, %xmm0
; SANDBOX50: nop # variant = 2 ; SANDBOX50: nop # variant = 3
; SANDBOX50: pshufd $216, %xmm0, %xmm0 ; SANDBOX50: pshufd $216, %xmm0, %xmm0
; SANDBOX50: nop # variant = 1
; SANDBOX50: movups %xmm0, (%esp) ; SANDBOX50: movups %xmm0, (%esp)
; SANDBOX50: movups (%esp), %xmm0 ; SANDBOX50: movups (%esp), %xmm0
; SANDBOX50: nop # variant = 0
; SANDBOX50: addl $60, %esp ; SANDBOX50: addl $60, %esp
; SANDBOX50: nop # variant = 3
; SANDBOX50: pop %ecx ; SANDBOX50: pop %ecx
; SANDBOX50: .bundle_lock ; SANDBOX50: .bundle_lock
; SANDBOX50: andl $-32, %ecx ; SANDBOX50: andl $-32, %ecx
......
...@@ -25,12 +25,12 @@ entry: ...@@ -25,12 +25,12 @@ entry:
ret i32 %res ret i32 %res
; BLINDINGO2-LABEL: add_arg_plus_200000 ; BLINDINGO2-LABEL: add_arg_plus_200000
; BLINDINGO2: mov [[REG:e[a-z]*]],0x34ee7 ; BLINDINGO2: mov [[REG:e[a-z]*]],0x2c8df4
; BLINDINGO2-NEXT: lea [[REG]],{{[[]}}[[REG]]-0x41a7{{[]]}} ; BLINDINGO2-NEXT: lea [[REG]],{{[[]}}[[REG]]-0x2980b4{{[]]}}
; BLINDINGOM1-LABEL: add_arg_plus_200000 ; BLINDINGOM1-LABEL: add_arg_plus_200000
; BLINDINGOM1: mov [[REG:e[a-z]*]],0x34ee7 ; BLINDINGOM1: mov [[REG:e[a-z]*]],0x2c8df4
; BLINDINGOM1-NEXT: lea [[REG]],{{[[]}}[[REG]]-0x41a7{{[]]}} ; BLINDINGOM1-NEXT: lea [[REG]],{{[[]}}[[REG]]-0x2980b4{{[]]}}
; POOLING-LABEL: add_arg_plus_200000 ; 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]*}} ; POOLING: mov e{{[a-z]*}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32${{[0-9]*}}
...@@ -44,10 +44,10 @@ entry: ...@@ -44,10 +44,10 @@ entry:
%addr.load = load float, float* %addr.ptr, align 4 %addr.load = load float, float* %addr.ptr, align 4
ret float %addr.load ret float %addr.load
; BLINDINGO2-LABEL: load_arg_plus_200000 ; 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-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-LABEL: load_arg_plus_200000
; POOLING: mov e{{[a-z]*}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32${{[0-9]*}} ; POOLING: mov e{{[a-z]*}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32${{[0-9]*}}
...@@ -61,13 +61,13 @@ entry: ...@@ -61,13 +61,13 @@ entry:
; BLINDINGO2-LABEL: add_arg_plus_64bits ; BLINDINGO2-LABEL: add_arg_plus_64bits
; BLINDINGO2: sar [[RHI:e[a-z]*]],0x1f ; BLINDINGO2: sar [[RHI:e[a-z]*]],0x1f
; BLINDINGO2: mov [[RLO:e[a-z]*]],0xf46b45a7 ; BLINDINGO2: mov [[RLO:e[a-z]*]],0xf4a0f8f8
; BLINDINGO2-NEXT: lea [[RLO]],{{[[]}}[[RLO]]-0x41a7{{[]]}} ; BLINDINGO2-NEXT: lea [[RLO]],{{[[]}}[[RLO]]-0x35f4f8{{[]]}}
; BLINDINGOM1-LABEL: add_arg_plus_64bits ; BLINDINGOM1-LABEL: add_arg_plus_64bits
; BLINDINGOM1: sar [[RHI:e[a-z]*]],0x1f ; BLINDINGOM1: sar [[RHI:e[a-z]*]],0x1f
; BLINDINGOM1: mov [[RLO:e[a-z]*]],0xf46b45a7 ; BLINDINGOM1: mov [[RLO:e[a-z]*]],0xf4a0f8f8
; BLINDINGOM1-NEXT: lea [[RLO]],{{[[]}}[[RLO]]-0x41a7{{[]]}} ; BLINDINGOM1-NEXT: lea [[RLO]],{{[[]}}[[RLO]]-0x35f4f8{{[]]}}
; POOLING-LABEL: add_arg_plus_64bits ; 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]*}} ; POOLING: mov e{{[a-z]*}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32${{[0-9]*}}
...@@ -82,12 +82,12 @@ entry: ...@@ -82,12 +82,12 @@ entry:
ret i64 %arg.load ret i64 %arg.load
; BLINDINGO2-LABEL: load_arg_plus_64bits ; BLINDINGO2-LABEL: load_arg_plus_64bits
; BLINDINGO2: lea e{{[a-z]*}},{{[[]}}e{{[a-z]*}}+0x1a137{{[]]}} ; BLINDINGO2: lea e{{[a-z]*}},{{[[]}}e{{[a-z]*}}+0x3d8eac{{[]]}}
; BLINDINGO2: mov e{{[a-z]*}},DWORD PTR {{[[]}}e{{[a-z]*}}-0x41a7{{[]]}} ; BLINDINGO2: mov e{{[a-z]*}},DWORD PTR {{[[]}}e{{[a-z]*}}-0x3c2f1c{{[]]}}
; BLINDINGOM1-LABEL: load_arg_plus_64bits ; BLINDINGOM1-LABEL: load_arg_plus_64bits
; BLINDINGOM1: mov e{{[a-z]*}},0x1a137 ; BLINDINGOM1: mov e{{[a-z]*}},0x3d8eac
; BLINDINGOM1-NEXT: lea e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x41a7{{[]]}} ; BLINDINGOM1-NEXT: lea e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x3c2f1c{{[]]}}
; POOLING-LABEL: load_arg_plus_64bits ; 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]*}} ; POOLING: mov e{{[a-z]x}},DWORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i32${{[0-9]*}}
...@@ -101,12 +101,12 @@ entry: ...@@ -101,12 +101,12 @@ entry:
ret i32 %ret ret i32 %ret
; BLINDINGO2-LABEL: add_const_8bits ; BLINDINGO2-LABEL: add_const_8bits
; BLINDINGO2: mov e{{[a-z]*}},0x4222 ; BLINDINGO2: mov e{{[a-z]*}},0x1d0aa
; BLINDINGO2-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x41a7{{[]]}} ; BLINDINGO2-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x1d02f{{[]]}}
; BLINDINGOM1-LABEL: add_const_8bits ; BLINDINGOM1-LABEL: add_const_8bits
; BLINDINGOM1: mov e{{[a-z]*}},0x4222 ; BLINDINGOM1: mov e{{[a-z]*}},0x1d0aa
; BLINDINGOM1-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x41a7{{[]]}} ; BLINDINGOM1-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x1d02f{{[]]}}
; POOLING-LABEL: add_const_8bits ; POOLING-LABEL: add_const_8bits
; POOLING: mov {{[a-z]l}},BYTE PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i8${{[0-9]*}} ; POOLING: mov {{[a-z]l}},BYTE PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i8${{[0-9]*}}
...@@ -120,12 +120,12 @@ entry: ...@@ -120,12 +120,12 @@ entry:
ret i32 %ret ret i32 %ret
; BLINDINGO2-LABEL: add_const_16bits ; BLINDINGO2-LABEL: add_const_16bits
; BLINDINGO2: mov e{{[a-z]*}},0xc1a5 ; BLINDINGO2: mov e{{[a-z]*}},0x88a4d
; BLINDINGO2-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x41a7{{[]]}} ; BLINDINGO2-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x80a4f{{[]]}}
; BLINDINGOM1-LABEL: add_const_16bits ; BLINDINGOM1-LABEL: add_const_16bits
; BLINDINGOM1: mov e{{[a-z]*}},0xc1a5 ; BLINDINGOM1: mov e{{[a-z]*}},0x88a4d
; BLINDINGOM1-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x41a7{{[]]}} ; BLINDINGOM1-NEXT: e{{[a-z]*}},{{[[]}}e{{[a-z]*}}-0x80a4f{{[]]}}
; POOLING-LABEL: add_const_16bits ; POOLING-LABEL: add_const_16bits
; POOLING: mov {{[a-z]x}},WORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i16${{[0-9]*}} ; POOLING: mov {{[a-z]x}},WORD PTR ds:0x0 {{[0-9a-f]*}}: R_386_32 .L$i16${{[0-9]*}}
......
...@@ -26,11 +26,11 @@ entry: ...@@ -26,11 +26,11 @@ entry:
; OPTM1_1-NEXT: movups XMMWORD PTR [esp+0x20],xmm0 ; OPTM1_1-NEXT: movups XMMWORD PTR [esp+0x20],xmm0
; OPTM1_1-NEXT: movups XMMWORD PTR [esp+0x10],xmm1 ; OPTM1_1-NEXT: movups XMMWORD PTR [esp+0x10],xmm1
; OPTM1_1-NEXT: movups xmm0,XMMWORD PTR [esp+0x20] ; OPTM1_1-NEXT: movups xmm0,XMMWORD PTR [esp+0x20]
; OPTM1_1-NEXT: pshufd xmm1,XMMWORD PTR [esp+0x20],0x31 ; OPTM1_1-NEXT: pshufd xmm7,XMMWORD PTR [esp+0x20],0x31
; OPTM1_1-NEXT: pshufd xmm2,XMMWORD PTR [esp+0x10],0x31 ; OPTM1_1-NEXT: pshufd xmm3,XMMWORD PTR [esp+0x10],0x31
; OPTM1_1-NEXT: pmuludq xmm0,XMMWORD PTR [esp+0x10] ; OPTM1_1-NEXT: pmuludq xmm0,XMMWORD PTR [esp+0x10]
; OPTM1_1-NEXT: pmuludq xmm1,xmm2 ; OPTM1_1-NEXT: pmuludq xmm7,xmm3
; OPTM1_1-NEXT: shufps xmm0,xmm1,0x88 ; OPTM1_1-NEXT: shufps xmm0,xmm7,0x88
; OPTM1_1-NEXT: pshufd xmm0,xmm0,0xd8 ; OPTM1_1-NEXT: pshufd xmm0,xmm0,0xd8
; OPTM1_1-NEXT: movups XMMWORD PTR [esp],xmm0 ; OPTM1_1-NEXT: movups XMMWORD PTR [esp],xmm0
; OPTM1_1-NEXT: movups xmm0,XMMWORD PTR [esp] ; OPTM1_1-NEXT: movups xmm0,XMMWORD PTR [esp]
...@@ -38,14 +38,14 @@ entry: ...@@ -38,14 +38,14 @@ entry:
; OPTM1_1-NEXT: ret ; OPTM1_1-NEXT: ret
; CHECK_1-LABEL: mul_v4i32 ; 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 xmm0,xmm0,0x31
; CHECK_1-NEXT: pshufd xmm3,xmm1,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: pmuludq xmm0,xmm3
; CHECK_1-NEXT: shufps xmm5,xmm0,0x88 ; CHECK_1-NEXT: shufps xmm7,xmm0,0x88
; CHECK_1-NEXT: pshufd xmm5,xmm5,0xd8 ; CHECK_1-NEXT: pshufd xmm7,xmm7,0xd8
; CHECK_1-NEXT: movups xmm0,xmm5 ; CHECK_1-NEXT: movups xmm0,xmm7
; CHECK_1-NEXT: ret ; CHECK_1-NEXT: ret
; OPTM1_123-LABEL: mul_v4i32 ; OPTM1_123-LABEL: mul_v4i32
...@@ -53,11 +53,11 @@ entry: ...@@ -53,11 +53,11 @@ entry:
; OPTM1_123-NEXT: movups XMMWORD PTR [esp+0x20],xmm0 ; OPTM1_123-NEXT: movups XMMWORD PTR [esp+0x20],xmm0
; OPTM1_123-NEXT: movups XMMWORD PTR [esp+0x10],xmm1 ; OPTM1_123-NEXT: movups XMMWORD PTR [esp+0x10],xmm1
; OPTM1_123-NEXT: movups xmm0,XMMWORD PTR [esp+0x20] ; OPTM1_123-NEXT: movups xmm0,XMMWORD PTR [esp+0x20]
; OPTM1_123-NEXT: pshufd xmm1,XMMWORD PTR [esp+0x20],0x31 ; OPTM1_123-NEXT: pshufd xmm2,XMMWORD PTR [esp+0x20],0x31
; OPTM1_123-NEXT: pshufd xmm6,XMMWORD PTR [esp+0x10],0x31 ; OPTM1_123-NEXT: pshufd xmm1,XMMWORD PTR [esp+0x10],0x31
; OPTM1_123-NEXT: pmuludq xmm0,XMMWORD PTR [esp+0x10] ; OPTM1_123-NEXT: pmuludq xmm0,XMMWORD PTR [esp+0x10]
; OPTM1_123-NEXT: pmuludq xmm1,xmm6 ; OPTM1_123-NEXT: pmuludq xmm2,xmm1
; OPTM1_123-NEXT: shufps xmm0,xmm1,0x88 ; OPTM1_123-NEXT: shufps xmm0,xmm2,0x88
; OPTM1_123-NEXT: pshufd xmm0,xmm0,0xd8 ; OPTM1_123-NEXT: pshufd xmm0,xmm0,0xd8
; OPTM1_123-NEXT: movups XMMWORD PTR [esp],xmm0 ; OPTM1_123-NEXT: movups XMMWORD PTR [esp],xmm0
; OPTM1_123-NEXT: movups xmm0,XMMWORD PTR [esp] ; OPTM1_123-NEXT: movups xmm0,XMMWORD PTR [esp]
...@@ -65,14 +65,14 @@ entry: ...@@ -65,14 +65,14 @@ entry:
; OPTM1_123-NEXT: ret ; OPTM1_123-NEXT: ret
; CHECK_123-LABEL: mul_v4i32 ; 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 xmm0,xmm0,0x31
; CHECK_123-NEXT: pshufd xmm2,xmm1,0x31 ; CHECK_123-NEXT: pshufd xmm5,xmm1,0x31
; CHECK_123-NEXT: pmuludq xmm4,xmm1 ; CHECK_123-NEXT: pmuludq xmm3,xmm1
; CHECK_123-NEXT: pmuludq xmm0,xmm2 ; CHECK_123-NEXT: pmuludq xmm0,xmm5
; CHECK_123-NEXT: shufps xmm4,xmm0,0x88 ; CHECK_123-NEXT: shufps xmm3,xmm0,0x88
; CHECK_123-NEXT: pshufd xmm4,xmm4,0xd8 ; CHECK_123-NEXT: pshufd xmm3,xmm3,0xd8
; CHECK_123-NEXT: movups xmm0,xmm4 ; CHECK_123-NEXT: movups xmm0,xmm3
; CHECK_123-NEXT: ret ; CHECK_123-NEXT: ret
} }
......
...@@ -29,8 +29,8 @@ BB4: ...@@ -29,8 +29,8 @@ BB4:
; SEED1: .Lbasic_block_reordering$entry: ; SEED1: .Lbasic_block_reordering$entry:
; SEED1: .Lbasic_block_reordering$BB1: ; SEED1: .Lbasic_block_reordering$BB1:
; SEED1: .Lbasic_block_reordering$BB2: ; SEED1: .Lbasic_block_reordering$BB2:
; SEED1: .Lbasic_block_reordering$BB3:
; SEED1: .Lbasic_block_reordering$BB4: ; SEED1: .Lbasic_block_reordering$BB4:
; SEED1: .Lbasic_block_reordering$BB3:
; SEED2-LABEL: basic_block_reordering: ; SEED2-LABEL: basic_block_reordering:
; SEED2: .Lbasic_block_reordering$entry: ; SEED2: .Lbasic_block_reordering$entry:
......
...@@ -61,12 +61,12 @@ define void @func6() { ...@@ -61,12 +61,12 @@ define void @func6() {
ret void ret void
} }
; DEFAULTWINDOWSIZE-LABEL: func4
; DEFAULTWINDOWSIZE-LABEL: func1 ; DEFAULTWINDOWSIZE-LABEL: func1
; DEFAULTWINDOWSIZE-LABEL: func3 ; DEFAULTWINDOWSIZE-LABEL: func4
; DEFAULTWINDOWSIZE-LABEL: func6
; DEFAULTWINDOWSIZE-LABEL: func5 ; DEFAULTWINDOWSIZE-LABEL: func5
; DEFAULTWINDOWSIZE-LABEL: func2 ; DEFAULTWINDOWSIZE-LABEL: func2
; DEFAULTWINDOWSIZE-LABEL: func6
; DEFAULTWINDOWSIZE-LABEL: func3
; WINDOWSIZE1-LABEL: func1 ; WINDOWSIZE1-LABEL: func1
; WINDOWSIZE1-LABEL: func2 ; WINDOWSIZE1-LABEL: func2
...@@ -82,9 +82,9 @@ define void @func6() { ...@@ -82,9 +82,9 @@ define void @func6() {
; SEQUENTIAL-LABEL: func5 ; SEQUENTIAL-LABEL: func5
; SEQUENTIAL-LABEL: func6 ; SEQUENTIAL-LABEL: func6
; WINDOWSIZEMAX-LABEL: func4
; WINDOWSIZEMAX-LABEL: func1 ; WINDOWSIZEMAX-LABEL: func1
; WINDOWSIZEMAX-LABEL: func3 ; WINDOWSIZEMAX-LABEL: func4
; WINDOWSIZEMAX-LABEL: func6
; WINDOWSIZEMAX-LABEL: func5 ; WINDOWSIZEMAX-LABEL: func5
; WINDOWSIZEMAX-LABEL: func2 ; WINDOWSIZEMAX-LABEL: func2
; WINDOWSIZEMAX-LABEL: func6
; WINDOWSIZEMAX-LABEL: func3
...@@ -54,16 +54,11 @@ ...@@ -54,16 +54,11 @@
@ArrayUninitConstInt = internal constant [20 x i8] zeroinitializer, align 4 @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. ; Make sure the shuffled order is correct.
; CHECK-LABEL: ArrayInitPartial
; CHECK-LABEL: PrimitiveInit
; CHECK-LABEL: ArrayInit ; CHECK-LABEL: ArrayInit
; CHECK-LABEL: PrimitiveInit
; CHECK-LABEL: ArrayInitPartial
; CHECK-LABEL: PrimitiveUninit ; CHECK-LABEL: PrimitiveUninit
; CHECK-LABEL: ArrayUninit ; CHECK-LABEL: ArrayUninit
; CHECK-LABEL: PrimitiveInitStatic ; CHECK-LABEL: PrimitiveInitStatic
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
; RUN: %p2i --assemble --disassemble --filetype=obj --dis-flags=-s \ ; RUN: %p2i --assemble --disassemble --filetype=obj --dis-flags=-s \
; RUN: --target x8632 -i %s --args -sz-seed=1 -O2 -reorder-pooled-constants \ ; 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: %p2i --assemble --disassemble --filetype=obj --dis-flags=-s \
; RUN: --target x8632 -i %s --args -sz-seed=1 -Om1 -reorder-pooled-constants \ ; 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 @__init_array_start = internal constant [0 x i8] zeroinitializer, align 4
@__fini_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 @@ return: ; preds = %entry, %sw.bb65, %s ...@@ -533,38 +533,17 @@ return: ; preds = %entry, %sw.bb65, %s
} }
; Make sure the constants in pools are shuffled. ; 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 ; Check for float pool
; X86O2-LABEL: .rodata.cst4 ; X86-LABEL: .rodata.cst4
; X86O2: 00000040 0000c0ff 00000041 00000000 ; X86: 00000041 0000c0ff 0000803f 00008040
; X86O2: 0000003f 0000803f 00008040 0000c07f ; X86: 0000c07f 00000000 0000003f 0000803e
; X86O2: 0000803e ; X86: 00000040
; Check for double pool ; Check for double pool
; X86O2-LABEL: .rodata.cst8 ; X86-LABEL: .rodata.cst8
; X86O2: 55555555 5555d53f 00000000 0000f8ff ; X86: 00000000 0000f8ff 00000000 0000f87f
; X86O2: 00000000 0000f87f 00000000 0000e03f ; X86: 00000000 0000e03f 00000000 00000000
; X86O2: 00000000 0000d03f 00000000 00000000 ; X86: 55555555 5555d53f 00000000 0000d03f
; X86O2-LABEL: .text ; X86-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
; 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment