summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2016-08-23 01:30:30 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2016-08-23 01:30:30 +0000
commit567631bdd407a556afb0ed8b0dc57f963f7e366e (patch)
tree4ba51ff2f9e6f052d27aae6b4bccd2d56ea9fae1
parent3721837d8941e39ee3fa28e8e8a4d66629517131 (diff)
downloadbcm5719-llvm-567631bdd407a556afb0ed8b0dc57f963f7e366e.tar.gz
bcm5719-llvm-567631bdd407a556afb0ed8b0dc57f963f7e366e.zip
BranchRelaxation: Fix handling of blocks with multiple conditional
branches Looping over all terminators exposed AArch64 tests hitting an assert from analyzeBranch failing. I believe these cases were miscompiled before. e.g. fcmp s0, s1 b.ne LBB0_1 b.vc LBB0_2 b LBB0_2 LBB0_1: ; Large block LBB0_2: ; ... Both of the individual conditional branches need to be expanded, since neither can reach the final block. Split the original block into ones which analyzeBranch will be able to understand. llvm-svn: 279499
-rw-r--r--llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp42
-rw-r--r--llvm/test/CodeGen/AArch64/branch-relax-bcc.ll18
2 files changed, 48 insertions, 12 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp b/llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp
index 9d2577eed95..92130a1107c 100644
--- a/llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp
+++ b/llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp
@@ -25,7 +25,7 @@ using namespace llvm;
#define DEBUG_TYPE "aarch64-branch-relax"
STATISTIC(NumSplit, "Number of basic blocks split");
-STATISTIC(NumRelaxed, "Number of conditional branches relaxed");
+STATISTIC(NumConditionalRelaxed, "Number of conditional branches relaxed");
namespace llvm {
void initializeAArch64BranchRelaxationPass(PassRegistry &);
@@ -477,13 +477,43 @@ bool AArch64BranchRelaxation::relaxBranchInstructions() {
if (J == MBB.end())
continue;
- MachineInstr &MI = *J;
- if (MI.isConditionalBranch() && !isBlockInRange(MI, *getDestBlock(MI))) {
- fixupConditionalBranch(MI);
- ++NumRelaxed;
- Changed = true;
+ MachineBasicBlock::iterator Next;
+ for (MachineBasicBlock::iterator J = MBB.getFirstTerminator();
+ J != MBB.end(); J = Next) {
+ Next = std::next(J);
+ MachineInstr &MI = *J;
+
+ if (MI.isConditionalBranch()) {
+ MachineBasicBlock *DestBB = getDestBlock(MI);
+ if (!isBlockInRange(MI, *DestBB)) {
+ if (Next != MBB.end() && Next->isConditionalBranch()) {
+ // If there are multiple conditional branches, this isn't an
+ // analyzable block. Split later terminators into a new block so
+ // each one will be analyzable.
+
+ MachineBasicBlock *NewBB = splitBlockBeforeInstr(*Next);
+ NewBB->transferSuccessors(&MBB);
+ MBB.addSuccessor(NewBB);
+ MBB.addSuccessor(DestBB);
+
+ // Cleanup potential unconditional branch to successor block.
+ NewBB->updateTerminator();
+ MBB.updateTerminator();
+ } else {
+ fixupConditionalBranch(MI);
+ ++NumConditionalRelaxed;
+ }
+
+ Changed = true;
+
+ // This may have modified all of the terminators, so start over.
+ Next = MBB.getFirstTerminator();
+ }
+
+ }
}
}
+
return Changed;
}
diff --git a/llvm/test/CodeGen/AArch64/branch-relax-bcc.ll b/llvm/test/CodeGen/AArch64/branch-relax-bcc.ll
index d73236c9381..636acf0a8b8 100644
--- a/llvm/test/CodeGen/AArch64/branch-relax-bcc.ll
+++ b/llvm/test/CodeGen/AArch64/branch-relax-bcc.ll
@@ -1,16 +1,22 @@
; RUN: llc -mtriple=aarch64-apple-darwin -aarch64-bcc-offset-bits=3 < %s | FileCheck %s
; CHECK-LABEL: invert_bcc:
-; CHECK: fcmp s0, s1
-; CHECK-NEXT: b.ne [[BB1:LBB[0-9]+_[0-9]+]]
-; CHECK-NEXT: b.vs [[BB2:LBB[0-9]+_[0-9]+]]
-; CHECK-NEXT: b [[BB2]]
+; CHECK: fcmp s0, s1
+; CHECK-NEXT: b.eq [[JUMP_BB1:LBB[0-9]+_[0-9]+]]
+; CHECK-NEXT: b [[JUMP_BB2:LBB[0-9]+_[0-9]+]]
-; CHECK: [[BB1]]:
+; CHECK-NEXT: [[JUMP_BB1]]:
+; CHECK-NEXT: b [[BB1:LBB[0-9]+_[0-9]+]]
+
+; CHECK-NEXT: [[JUMP_BB2]]:
+; CHECK-NEXT: b.vc [[BB2:LBB[0-9]+_[0-9]+]]
+; CHECK-NEXT: b [[BB1]]
+
+; CHECK: [[BB2]]: ; %bb2
; CHECK: mov w{{[0-9]+}}, #9
; CHECK: ret
-; CHECK: [[BB2]]:
+; CHECK: [[BB1]]: ; %bb1
; CHECK: mov w{{[0-9]+}}, #42
; CHECK: ret
OpenPOWER on IntegriCloud