[MBB] add a missing corner case in UpdateTerminator()

After the block placement, if a block ends with a conditional branch, but the
next block is not its successor. The conditional branch should be changed to
unconditional branch.  This patch fixes PR28307, PR28297, PR28402.

Differential Revision: http://reviews.llvm.org/D21811

llvm-svn: 274470
This commit is contained in:
Haicheng Wu 2016-07-03 19:14:17 +00:00
parent 68ea80649b
commit b71b2f622a
2 changed files with 77 additions and 10 deletions

View File

@ -470,17 +470,27 @@ void MachineBasicBlock::updateTerminator() {
FallthroughBB = *SI;
}
if (!FallthroughBB && canFallThrough()) {
// We fallthrough to the same basic block as the conditional jump targets.
// Remove the conditional jump, leaving unconditional fallthrough.
// FIXME: This does not seem like a reasonable pattern to support, but it
// has been seen in the wild coming out of degenerate ARM test cases.
TII->RemoveBranch(*this);
if (!FallthroughBB) {
if (canFallThrough()) {
// We fallthrough to the same basic block as the conditional jump targets.
// Remove the conditional jump, leaving unconditional fallthrough.
// FIXME: This does not seem like a reasonable pattern to support, but it
// has been seen in the wild coming out of degenerate ARM test cases.
TII->RemoveBranch(*this);
// Finally update the unconditional successor to be reached via a branch if
// it would not be reached by fallthrough.
if (!isLayoutSuccessor(TBB))
TII->InsertBranch(*this, TBB, nullptr, Cond, DL);
return;
}
// Finally update the unconditional successor to be reached via a branch if
// it would not be reached by fallthrough.
if (!isLayoutSuccessor(TBB))
TII->InsertBranch(*this, TBB, nullptr, Cond, DL);
// We enter here iff exactly one successor is TBB which cannot fallthrough
// and the rest successors if any are EHPads. In this case, we need to
// change the conditional branch into unconditional branch.
TII->RemoveBranch(*this);
Cond.clear();
TII->InsertBranch(*this, TBB, nullptr, Cond, DL);
return;
}

View File

@ -0,0 +1,57 @@
# RUN: llc -march=x86-64 -verify-machineinstrs -run-pass block-placement -o /dev/null %s 2>&1 | FileCheck %s
# Check the conditional jump in bb.1 is changed to unconditional after block placement swaps bb.2 and bb.3.
--- |
@a = external global i16
@b = external global i32
; Function Attrs: nounwind
define void @f2() {
br i1 undef, label %bb1, label %bb3
bb1:
br i1 undef, label %bb2, label %bb2
bb2:
br label %bb4
bb3:
br label %bb2
bb4:
ret void
}
...
---
# CHECK-LABEL: name: f2
# CHECK: bb.1:
# CHECK: JMP_1 %bb.2
# CHECK: bb.3:
# CHECK: bb.2:
name: f2
body: |
bb.0 (%ir-block.0):
successors: %bb.1(50), %bb.3(50)
JNE_1 %bb.1, implicit %eflags
JMP_1 %bb.3
bb.1:
successors: %bb.2(100)
JNE_1 %bb.2, implicit %eflags
bb.2:
successors: %bb.4(100)
JMP_1 %bb.4
bb.3:
successors: %bb.2(100)
JMP_1 %bb.2
bb.4:
RETQ
...