summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <dan433584@gmail.com>2015-12-16 19:06:41 +0000
committerDan Gohman <dan433584@gmail.com>2015-12-16 19:06:41 +0000
commitb3aa1ecab0b4ebfba8f2fce7dfaec94f231032b3 (patch)
tree2ce0187a1f606a02bf795d6ab2211cd012b00c58
parent7fda3c9ff30fd82e7e0cdf0d97288da3e1a20bf5 (diff)
downloadbcm5719-llvm-b3aa1ecab0b4ebfba8f2fce7dfaec94f231032b3.tar.gz
bcm5719-llvm-b3aa1ecab0b4ebfba8f2fce7dfaec94f231032b3.zip
[WebAssembly] Fix the CFG Stackifier to handle unoptimized branches
If a branch both branches to and falls through to the same block, treat it as an explicit branch. llvm-svn: 255803
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp16
-rw-r--r--llvm/test/CodeGen/WebAssembly/cfg-stackify.ll46
2 files changed, 60 insertions, 2 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
index 6412442176d..6ac53662359 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
@@ -251,6 +251,19 @@ static void SortBlocks(MachineFunction &MF, const MachineLoopInfo &MLI) {
#endif
}
+/// Test whether Pred has any terminators explicitly branching to MBB, as
+/// opposed to falling through. Note that it's possible (eg. in unoptimized
+/// code) for a branch instruction to both branch to a block and fallthrough
+/// to it, so we check the actual branch operands to see if there are any
+/// explicit mentions.
+static bool ExplicitlyBranchesTo(MachineBasicBlock *Pred, MachineBasicBlock *MBB) {
+ for (MachineInstr &MI : Pred->terminators())
+ for (MachineOperand &MO : MI.explicit_operands())
+ if (MO.isMBB() && MO.getMBB() == MBB)
+ return true;
+ return false;
+}
+
/// Insert a BLOCK marker for branches to MBB (if needed).
static void PlaceBlockMarker(MachineBasicBlock &MBB, MachineFunction &MF,
SmallVectorImpl<MachineBasicBlock *> &ScopeTops,
@@ -266,8 +279,7 @@ static void PlaceBlockMarker(MachineBasicBlock &MBB, MachineFunction &MF,
for (MachineBasicBlock *Pred : MBB.predecessors())
if (Pred->getNumber() < MBBNumber) {
Header = Header ? MDT.findNearestCommonDominator(Header, Pred) : Pred;
- if (!Pred->isLayoutSuccessor(&MBB) ||
- !(Pred->empty() || !Pred->back().isBarrier()))
+ if (ExplicitlyBranchesTo(Pred, &MBB))
IsBranchedTo = true;
}
if (!Header)
diff --git a/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll b/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll
index 7717f35fec0..a10fb614909 100644
--- a/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll
+++ b/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll
@@ -1054,3 +1054,49 @@ bb4:
bb7:
ret void
}
+
+; A block can be "branched to" from another even if it is also reachable via
+; fallthrough from the other. This would normally be optimized away, so use
+; optnone to disable optimizations to test this case.
+
+; CHECK-LABEL: test13:
+; CHECK-NEXT: .local i32{{$}}
+; CHECK: block BB22_2{{$}}
+; CHECK: br_if $pop4, BB22_2{{$}}
+; CHECK-NEXT: return{{$}}
+; CHECK-NEXT: BB22_2:
+; CHECK: block BB22_4{{$}}
+; CHECK-NEXT: br_if $0, BB22_4{{$}}
+; CHECK: BB22_4:
+; CHECK: block BB22_5{{$}}
+; CHECK: br_if $pop6, BB22_5{{$}}
+; CHECK-NEXT: BB22_5:
+; CHECK-NEXT: unreachable{{$}}
+; OPT-LABEL: test13:
+; OPT-NEXT: .local i32{{$}}
+; OPT: block BB22_2{{$}}
+; OPT: br_if $pop4, BB22_2{{$}}
+; OPT-NEXT: return{{$}}
+; OPT-NEXT: BB22_2:
+; OPT: block BB22_4{{$}}
+; OPT-NEXT: br_if $0, BB22_4{{$}}
+; OPT: BB22_4:
+; OPT: block BB22_5{{$}}
+; OPT: br_if $pop6, BB22_5{{$}}
+; OPT-NEXT: BB22_5:
+; OPT-NEXT: unreachable{{$}}
+define void @test13() noinline optnone {
+bb:
+ br i1 undef, label %bb5, label %bb2
+bb1:
+ unreachable
+bb2:
+ br i1 undef, label %bb3, label %bb4
+bb3:
+ br label %bb4
+bb4:
+ %tmp = phi i1 [ false, %bb2 ], [ false, %bb3 ]
+ br i1 %tmp, label %bb1, label %bb1
+bb5:
+ ret void
+}
OpenPOWER on IntegriCloud