Commit 969f6a33 by Qining Lu

Add -reorder-basic-blocks option and fix nop insertion

1. Basic block reordering can be enabled with -reorder-basic-blocks option enabled. Blocks will be sorted according to the Reversed Post Traversal Order, but the next node to visit among all candidate children nodes is selected 'randomly'. Example: A / \ B C \ / D This CFG can generate two possible layouts: A-B-C-D or A-C-B-D 2. Fix nop insetion Add checks to avoiding insertions in empty basic blocks(dead blocks) and bundle locked instructions. BUG= R=jpp@chromium.org, jvoung@chromium.org, stichnot@chromium.org Review URL: https://codereview.chromium.org/1255303004.
parent c2648c2d
...@@ -371,6 +371,51 @@ void Cfg::reorderNodes() { ...@@ -371,6 +371,51 @@ void Cfg::reorderNodes() {
assert(Nodes.size() == OldSize); assert(Nodes.size() == OldSize);
} }
namespace {
void getRandomPostOrder(CfgNode *Node, llvm::BitVector &ToVisit,
Ice::NodeList &PostOrder,
Ice::RandomNumberGenerator *RNG) {
assert(ToVisit[Node->getIndex()]);
ToVisit[Node->getIndex()] = false;
NodeList Outs = Node->getOutEdges();
Ice::RandomShuffle(Outs.begin(), Outs.end(),
[RNG](int N) { return RNG->next(N); });
for (CfgNode *Next : Outs) {
if (ToVisit[Next->getIndex()])
getRandomPostOrder(Next, ToVisit, PostOrder, RNG);
}
PostOrder.push_back(Node);
}
} // end of anonymous namespace
void Cfg::shuffleNodes() {
if (!Ctx->getFlags().shouldReorderBasicBlocks())
return;
NodeList ReversedReachable;
NodeList Unreachable;
llvm::BitVector ToVisit(Nodes.size(), true);
// Traverse from entry node.
getRandomPostOrder(getEntryNode(), ToVisit, ReversedReachable,
&Ctx->getRNG());
// Collect the unreachable nodes.
for (CfgNode *Node : Nodes)
if (ToVisit[Node->getIndex()])
Unreachable.push_back(Node);
// Copy the layout list to the Nodes.
SizeT OldSize = Nodes.size();
(void)OldSize;
Nodes.clear();
for (CfgNode *Node : reverse_range(ReversedReachable))
Nodes.emplace_back(Node);
for (CfgNode *Node : Unreachable) {
Nodes.emplace_back(Node);
}
assert(Nodes.size() == OldSize);
dump("After basic block shuffling");
}
void Cfg::doArgLowering() { void Cfg::doArgLowering() {
TimerMarker T(TimerStack::TT_doArgLowering, this); TimerMarker T(TimerStack::TT_doArgLowering, this);
getTarget()->lowerArguments(); getTarget()->lowerArguments();
...@@ -383,6 +428,8 @@ void Cfg::doAddressOpt() { ...@@ -383,6 +428,8 @@ void Cfg::doAddressOpt() {
} }
void Cfg::doNopInsertion() { void Cfg::doNopInsertion() {
if (!Ctx->getFlags().shouldDoNopInsertion())
return;
TimerMarker T(TimerStack::TT_doNopInsertion, this); TimerMarker T(TimerStack::TT_doNopInsertion, this);
for (CfgNode *Node : Nodes) for (CfgNode *Node : Nodes)
Node->doNopInsertion(); Node->doNopInsertion();
......
...@@ -180,6 +180,7 @@ public: ...@@ -180,6 +180,7 @@ public:
void deletePhis(); void deletePhis();
void advancedPhiLowering(); void advancedPhiLowering();
void reorderNodes(); void reorderNodes();
void shuffleNodes();
void doAddressOpt(); void doAddressOpt();
void doArgLowering(); void doArgLowering();
void doNopInsertion(); void doNopInsertion();
......
...@@ -500,18 +500,22 @@ void CfgNode::doNopInsertion() { ...@@ -500,18 +500,22 @@ void CfgNode::doNopInsertion() {
TargetLowering *Target = Func->getTarget(); TargetLowering *Target = Func->getTarget();
LoweringContext &Context = Target->getContext(); LoweringContext &Context = Target->getContext();
Context.init(this); Context.init(this);
Context.setInsertPoint(Context.getCur());
// Do not insert nop in bundle locked instructions.
bool PauseNopInsertion = false;
while (!Context.atEnd()) { while (!Context.atEnd()) {
if (llvm::isa<InstBundleLock>(Context.getCur())) {
PauseNopInsertion = true;
} else if (llvm::isa<InstBundleUnlock>(Context.getCur())) {
PauseNopInsertion = false;
}
if (!PauseNopInsertion)
Target->doNopInsertion(); Target->doNopInsertion();
// 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.advanceNext();
Context.advanceCur(); Context.advanceCur();
}
// Insert before all instructions.
Context.setInsertPoint(getInsts().begin());
Context.advanceNext(); Context.advanceNext();
Context.advanceCur(); }
Target->doNopInsertion();
} }
// Drives the target lowering. Passes the current instruction and the // Drives the target lowering. Passes the current instruction and the
......
...@@ -284,6 +284,12 @@ cl::opt<uint32_t> RandomizeAndPoolImmediatesThreshold( ...@@ -284,6 +284,12 @@ cl::opt<uint32_t> RandomizeAndPoolImmediatesThreshold(
cl::desc("The threshold for immediates randomization and pooling"), cl::desc("The threshold for immediates randomization and pooling"),
cl::init(0xffff)); cl::init(0xffff));
// Command line option for turning on basic block shuffling.
cl::opt<bool> ReorderBasicBlocks(
"reorder-basic-blocks",
cl::desc("Shuffle the layout of basic blocks in each functions"),
cl::init(false));
// Command line option for turning on function layout reordering. // Command line option for turning on function layout reordering.
cl::opt<bool> ReorderFunctions( cl::opt<bool> ReorderFunctions(
"reorder-functions", "reorder-functions",
...@@ -341,6 +347,7 @@ void ClFlags::resetClFlags(ClFlags &OutFlags) { ...@@ -341,6 +347,7 @@ void ClFlags::resetClFlags(ClFlags &OutFlags) {
OutFlags.PhiEdgeSplit = false; OutFlags.PhiEdgeSplit = false;
OutFlags.RandomNopInsertion = false; OutFlags.RandomNopInsertion = false;
OutFlags.RandomRegAlloc = false; OutFlags.RandomRegAlloc = false;
OutFlags.ReorderBasicBlocks = false;
OutFlags.ReorderFunctions = false; OutFlags.ReorderFunctions = false;
OutFlags.ReorderGlobalVariables = false; OutFlags.ReorderGlobalVariables = false;
OutFlags.ReorderPooledConstants = false; OutFlags.ReorderPooledConstants = false;
...@@ -398,8 +405,17 @@ void ClFlags::getParsedClFlags(ClFlags &OutFlags) { ...@@ -398,8 +405,17 @@ void ClFlags::getParsedClFlags(ClFlags &OutFlags) {
OutFlags.setOptLevel(::OLevel); OutFlags.setOptLevel(::OLevel);
OutFlags.setPhiEdgeSplit(::EnablePhiEdgeSplit); OutFlags.setPhiEdgeSplit(::EnablePhiEdgeSplit);
OutFlags.setRandomSeed(::RandomSeed); OutFlags.setRandomSeed(::RandomSeed);
OutFlags.setRandomizeAndPoolImmediatesOption(
::RandomizeAndPoolImmediatesOption);
OutFlags.setRandomizeAndPoolImmediatesThreshold(
::RandomizeAndPoolImmediatesThreshold);
OutFlags.setReorderFunctionsWindowSize(::ReorderFunctionsWindowSize);
OutFlags.setShouldReorderBasicBlocks(::ReorderBasicBlocks);
OutFlags.setShouldDoNopInsertion(::ShouldDoNopInsertion); OutFlags.setShouldDoNopInsertion(::ShouldDoNopInsertion);
OutFlags.setShouldRandomizeRegAlloc(::RandomizeRegisterAllocation); OutFlags.setShouldRandomizeRegAlloc(::RandomizeRegisterAllocation);
OutFlags.setShouldReorderFunctions(::ReorderFunctions);
OutFlags.setShouldReorderGlobalVariables(::ReorderGlobalVariables);
OutFlags.setShouldReorderPooledConstants(::ReorderPooledConstants);
OutFlags.setSkipUnimplemented(::SkipUnimplemented); OutFlags.setSkipUnimplemented(::SkipUnimplemented);
OutFlags.setSubzeroTimingEnabled(::SubzeroTimingEnabled); OutFlags.setSubzeroTimingEnabled(::SubzeroTimingEnabled);
OutFlags.setTargetArch(::TargetArch); OutFlags.setTargetArch(::TargetArch);
...@@ -414,22 +430,6 @@ void ClFlags::getParsedClFlags(ClFlags &OutFlags) { ...@@ -414,22 +430,6 @@ void ClFlags::getParsedClFlags(ClFlags &OutFlags) {
OutFlags.setMaxNopsPerInstruction(::MaxNopsPerInstruction); OutFlags.setMaxNopsPerInstruction(::MaxNopsPerInstruction);
OutFlags.setNopProbabilityAsPercentage(::NopProbabilityAsPercentage); OutFlags.setNopProbabilityAsPercentage(::NopProbabilityAsPercentage);
OutFlags.setVerbose(VMask); OutFlags.setVerbose(VMask);
// Set for immediates randomization or pooling option.
OutFlags.setRandomizeAndPoolImmediatesOption(
::RandomizeAndPoolImmediatesOption);
OutFlags.setRandomizeAndPoolImmediatesThreshold(
::RandomizeAndPoolImmediatesThreshold);
// Set for function reordering options.
OutFlags.setShouldReorderFunctions(::ReorderFunctions);
OutFlags.setReorderFunctionsWindowSize(::ReorderFunctionsWindowSize);
// Set for global variable reordering option.
OutFlags.setShouldReorderGlobalVariables(::ReorderGlobalVariables);
// Set for pooled constant reordering option.
OutFlags.setShouldReorderPooledConstants(::ReorderPooledConstants);
} }
void ClFlags::getParsedClFlagsExtra(ClFlagsExtra &OutFlagsExtra) { void ClFlags::getParsedClFlagsExtra(ClFlagsExtra &OutFlagsExtra) {
......
...@@ -153,6 +153,11 @@ public: ...@@ -153,6 +153,11 @@ public:
return RandomizeAndPoolImmediatesThreshold; return RandomizeAndPoolImmediatesThreshold;
} }
bool shouldReorderBasicBlocks() const { return ReorderBasicBlocks; }
void setShouldReorderBasicBlocks(bool NewValue) {
ReorderBasicBlocks = NewValue;
}
void setShouldReorderFunctions(bool Option) { ReorderFunctions = Option; } void setShouldReorderFunctions(bool Option) { ReorderFunctions = Option; }
bool shouldReorderFunctions() const { return ReorderFunctions; } bool shouldReorderFunctions() const { return ReorderFunctions; }
...@@ -229,6 +234,7 @@ private: ...@@ -229,6 +234,7 @@ private:
bool PhiEdgeSplit; bool PhiEdgeSplit;
bool RandomNopInsertion; bool RandomNopInsertion;
bool RandomRegAlloc; bool RandomRegAlloc;
bool ReorderBasicBlocks;
bool ReorderFunctions; bool ReorderFunctions;
bool ReorderGlobalVariables; bool ReorderGlobalVariables;
bool ReorderPooledConstants; bool ReorderPooledConstants;
......
...@@ -400,6 +400,9 @@ template <class Machine> void TargetX86Base<Machine>::translateO2() { ...@@ -400,6 +400,9 @@ template <class Machine> void TargetX86Base<Machine>::translateO2() {
Func->contractEmptyNodes(); Func->contractEmptyNodes();
Func->reorderNodes(); Func->reorderNodes();
// Shuffle basic block order if -reorder-basic-blocks is enabled.
Func->shuffleNodes();
// Branch optimization. This needs to be done just before code emission. In // Branch optimization. This needs to be done just before code emission. In
// particular, no transformations that insert or reorder CfgNodes should be // particular, no transformations that insert or reorder CfgNodes should be
// done after branch optimization. We go ahead and do it before nop insertion // done after branch optimization. We go ahead and do it before nop insertion
...@@ -407,8 +410,7 @@ template <class Machine> void TargetX86Base<Machine>::translateO2() { ...@@ -407,8 +410,7 @@ template <class Machine> void TargetX86Base<Machine>::translateO2() {
Func->doBranchOpt(); Func->doBranchOpt();
Func->dump("After branch optimization"); Func->dump("After branch optimization");
// Nop insertion // Nop insertion if -nop-insertion is enabled.
if (Ctx->getFlags().shouldDoNopInsertion())
Func->doNopInsertion(); Func->doNopInsertion();
// Mark nodes that require sandbox alignment // Mark nodes that require sandbox alignment
...@@ -446,10 +448,11 @@ template <class Machine> void TargetX86Base<Machine>::translateOm1() { ...@@ -446,10 +448,11 @@ template <class Machine> void TargetX86Base<Machine>::translateOm1() {
return; return;
Func->dump("After stack frame mapping"); Func->dump("After stack frame mapping");
// Nop insertion // Shuffle basic block order if -reorder-basic-blocks is enabled.
if (Ctx->getFlags().shouldDoNopInsertion()) { Func->shuffleNodes();
// Nop insertion if -nop-insertion is enabled.
Func->doNopInsertion(); Func->doNopInsertion();
}
// Mark nodes that require sandbox alignment // Mark nodes that require sandbox alignment
if (Ctx->getFlags().getUseSandboxing()) if (Ctx->getFlags().getUseSandboxing())
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
; Use filetype=asm because this currently depends on the # variant ; Use filetype=asm because this currently depends on the # variant
; assembler comment. ; assembler comment.
; RUN: %p2i -i %s --filetype=asm -a -sz-seed=1 -nop-insertion \ ; RUN: %p2i -i %s --filetype=asm -a -sz-seed=1 -nop-insertion \
; RUN: -nop-insertion-percentage=50 -max-nops-per-instruction=1 \ ; RUN: -nop-insertion-percentage=50 -max-nops-per-instruction=1 \
; RUN: | FileCheck %s --check-prefix=PROB50 ; RUN: | FileCheck %s --check-prefix=PROB50
...@@ -13,88 +14,121 @@ ...@@ -13,88 +14,121 @@
; RUN: %p2i -i %s --filetype=asm -a -sz-seed=1 -nop-insertion \ ; RUN: %p2i -i %s --filetype=asm -a -sz-seed=1 -nop-insertion \
; RUN: -nop-insertion-percentage=50 -max-nops-per-instruction=2 \ ; RUN: -nop-insertion-percentage=50 -max-nops-per-instruction=2 \
; RUN: | FileCheck %s --check-prefix=MAXNOPS2 ; RUN: | FileCheck %s --check-prefix=MAXNOPS2
; RUN: %p2i -i %s --filetype=asm -a -sz-seed=1 -nop-insertion -sandbox\
; RUN: -nop-insertion-percentage=50 -max-nops-per-instruction=1 \
; RUN: | FileCheck %s --check-prefix=SANDBOX50
define <4 x i32> @mul_v4i32(<4 x i32> %a, <4 x i32> %b) { define <4 x i32> @mul_v4i32(<4 x i32> %a, <4 x i32> %b) {
entry: entry:
%res = mul <4 x i32> %a, %b %res = mul <4 x i32> %a, %b
ret <4 x i32> %res ret <4 x i32> %res
; PROB50-LABEL: mul_v4i32 ; PROB50-LABEL: mul_v4i32
; PROB50: nop # variant = 3
; PROB50: subl $60, %esp
; PROB50: nop # variant = 4 ; PROB50: nop # variant = 4
; PROB50: subl $60, %esp
; PROB50: movups %xmm0, 32(%esp) ; PROB50: movups %xmm0, 32(%esp)
; PROB50: movups %xmm1, 16(%esp)
; PROB50: nop # variant = 0 ; PROB50: nop # variant = 0
; PROB50: movups 32(%esp), %xmm0 ; PROB50: movups %xmm1, 16(%esp)
; PROB50: nop # variant = 4 ; PROB50: nop # variant = 4
; PROB50: movups 32(%esp), %xmm0
; PROB50: pshufd $49, 32(%esp), %xmm1 ; PROB50: pshufd $49, 32(%esp), %xmm1
; PROB50: pshufd $49, 16(%esp), %xmm2 ; PROB50: pshufd $49, 16(%esp), %xmm2
; PROB50: pmuludq 16(%esp), %xmm0 ; PROB50: pmuludq 16(%esp), %xmm0
; PROB50: pmuludq %xmm2, %xmm1
; PROB50: nop # variant = 0 ; PROB50: nop # variant = 0
; PROB50: pmuludq %xmm2, %xmm1
; PROB50: shufps $136, %xmm1, %xmm0 ; PROB50: shufps $136, %xmm1, %xmm0
; PROB50: pshufd $216, %xmm0, %xmm0
; PROB50: nop # variant = 2 ; PROB50: nop # variant = 2
; PROB50: pshufd $216, %xmm0, %xmm0
; PROB50: movups %xmm0, (%esp) ; PROB50: movups %xmm0, (%esp)
; PROB50: movups (%esp), %xmm0 ; PROB50: movups (%esp), %xmm0
; PROB50: addl $60, %esp
; PROB50: nop # variant = 0 ; PROB50: nop # variant = 0
; PROB50: addl $60, %esp
; PROB50: nop # variant = 3
; PROB50: ret ; PROB50: ret
; PROB90-LABEL: mul_v4i32 ; PROB90-LABEL: mul_v4i32
; PROB90: nop # variant = 3
; PROB90: subl $60, %esp
; PROB90: nop # variant = 4 ; PROB90: nop # variant = 4
; PROB90: movups %xmm0, 32(%esp) ; PROB90: subl $60, %esp
; PROB90: nop # variant = 3 ; PROB90: nop # variant = 3
; PROB90: movups %xmm1, 16(%esp) ; PROB90: movups %xmm0, 32(%esp)
; PROB90: nop # variant = 2 ; PROB90: nop # variant = 2
; PROB90: movups 32(%esp), %xmm0 ; PROB90: movups %xmm1, 16(%esp)
; PROB90: nop # variant = 3 ; PROB90: nop # variant = 3
; PROB90: pshufd $49, 32(%esp), %xmm1 ; PROB90: movups 32(%esp), %xmm0
; PROB90: nop # variant = 4 ; PROB90: nop # variant = 4
; PROB90: pshufd $49, 16(%esp), %xmm2 ; PROB90: pshufd $49, 32(%esp), %xmm1
; PROB90: nop # variant = 0 ; PROB90: nop # variant = 0
; PROB90: pmuludq 16(%esp), %xmm0 ; PROB90: pshufd $49, 16(%esp), %xmm2
; PROB90: nop # variant = 2 ; PROB90: nop # variant = 2
; PROB90: pmuludq %xmm2, %xmm1 ; PROB90: pmuludq 16(%esp), %xmm0
; PROB90: nop # variant = 3 ; PROB90: nop # variant = 3
; PROB90: shufps $136, %xmm1, %xmm0 ; PROB90: pmuludq %xmm2, %xmm1
; PROB90: nop # variant = 4 ; PROB90: nop # variant = 4
; PROB90: pshufd $216, %xmm0, %xmm0 ; PROB90: shufps $136, %xmm1, %xmm0
; PROB90: nop # variant = 2 ; PROB90: nop # variant = 2
; PROB90: movups %xmm0, (%esp) ; PROB90: pshufd $216, %xmm0, %xmm0
; PROB90: nop # variant = 4 ; PROB90: nop # variant = 4
; PROB90: movups (%esp), %xmm0 ; PROB90: movups %xmm0, (%esp)
; PROB90: nop # variant = 2 ; PROB90: nop # variant = 2
; PROB90: movups (%esp), %xmm0
; PROB90: nop # variant = 3
; PROB90: addl $60, %esp ; PROB90: addl $60, %esp
; PROB90: nop # variant = 3 ; PROB90: nop # variant = 3
; PROB90: ret ; PROB90: ret
; MAXNOPS2-LABEL: mul_v4i32 ; MAXNOPS2-LABEL: mul_v4i32
; MAXNOPS2: subl $60, %esp
; MAXNOPS2: nop # variant = 4 ; MAXNOPS2: nop # variant = 4
; MAXNOPS2: movups %xmm0, 32(%esp) ; MAXNOPS2: subl $60, %esp
; MAXNOPS2: nop # variant = 0 ; MAXNOPS2: nop # variant = 0
; MAXNOPS2: nop # variant = 4 ; MAXNOPS2: nop # variant = 4
; MAXNOPS2: movups %xmm0, 32(%esp)
; MAXNOPS2: movups %xmm1, 16(%esp) ; MAXNOPS2: movups %xmm1, 16(%esp)
; MAXNOPS2: movups 32(%esp), %xmm0
; MAXNOPS2: nop # variant = 0 ; MAXNOPS2: nop # variant = 0
; MAXNOPS2: pshufd $49, 32(%esp), %xmm1 ; MAXNOPS2: movups 32(%esp), %xmm0
; MAXNOPS2: nop # variant = 2 ; MAXNOPS2: nop # variant = 2
; MAXNOPS2: pshufd $49, 32(%esp), %xmm1
; MAXNOPS2: pshufd $49, 16(%esp), %xmm2 ; MAXNOPS2: pshufd $49, 16(%esp), %xmm2
; MAXNOPS2: pmuludq 16(%esp), %xmm0
; MAXNOPS2: nop # variant = 0 ; MAXNOPS2: nop # variant = 0
; MAXNOPS2: nop # variant = 3 ; MAXNOPS2: nop # variant = 3
; MAXNOPS2: pmuludq 16(%esp), %xmm0
; MAXNOPS2: pmuludq %xmm2, %xmm1 ; MAXNOPS2: pmuludq %xmm2, %xmm1
; MAXNOPS2: shufps $136, %xmm1, %xmm0 ; MAXNOPS2: shufps $136, %xmm1, %xmm0
; MAXNOPS2: pshufd $216, %xmm0, %xmm0
; MAXNOPS2: nop # variant = 3 ; MAXNOPS2: nop # variant = 3
; MAXNOPS2: movups %xmm0, (%esp) ; MAXNOPS2: pshufd $216, %xmm0, %xmm0
; MAXNOPS2: nop # variant = 0 ; MAXNOPS2: nop # variant = 0
; MAXNOPS2: movups (%esp), %xmm0 ; MAXNOPS2: movups %xmm0, (%esp)
; MAXNOPS2: nop # variant = 2 ; MAXNOPS2: nop # variant = 2
; MAXNOPS2: addl $60, %esp ; MAXNOPS2: movups (%esp), %xmm0
; MAXNOPS2: nop # variant = 4 ; MAXNOPS2: nop # variant = 4
; MAXNOPS2: addl $60, %esp
; MAXNOPS2: ret ; MAXNOPS2: ret
; SANDBOX50-LABEL: mul_v4i32
; SANDBOX50: nop # variant = 4
; SANDBOX50: subl $60, %esp
; SANDBOX50: movups %xmm0, 32(%esp)
; SANDBOX50: nop # variant = 0
; SANDBOX50: movups %xmm1, 16(%esp)
; SANDBOX50: nop # variant = 4
; SANDBOX50: movups 32(%esp), %xmm0
; SANDBOX50: pshufd $49, 32(%esp), %xmm1
; SANDBOX50: pshufd $49, 16(%esp), %xmm2
; SANDBOX50: pmuludq 16(%esp), %xmm0
; SANDBOX50: nop # variant = 0
; SANDBOX50: pmuludq %xmm2, %xmm1
; SANDBOX50: shufps $136, %xmm1, %xmm0
; SANDBOX50: nop # variant = 2
; SANDBOX50: pshufd $216, %xmm0, %xmm0
; 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
; SANDBOX50: jmp *%ecx
; SANDBOX50: .bundle_unlock
} }
; Trivial smoke test of basic block reordering. Different random seeds should
; generate different basic block layout.
; REQUIRES allow_dump
; RUN: %p2i -i %s --filetype=asm --args -O2 -sz-seed=1 \
; RUN: -reorder-basic-blocks -threads=0 \
; RUN: | FileCheck %s --check-prefix=SEED1
; RUN: %p2i -i %s --filetype=asm --args -O2 -sz-seed=2 \
; RUN: -reorder-basic-blocks -threads=0 \
; RUN: | FileCheck %s --check-prefix=SEED2
define void @basic_block_reordering(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
; SEED1-LABEL: basic_block_reordering:
; 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:
; SEED2-LABEL: basic_block_reordering:
; SEED2: .Lbasic_block_reordering$entry:
; SEED2: .Lbasic_block_reordering$BB2:
; SEED2: .Lbasic_block_reordering$BB1:
; SEED2: .Lbasic_block_reordering$BB4:
; SEED2: .Lbasic_block_reordering$BB3
}
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