diff options
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp | 42 | ||||
| -rw-r--r-- | llvm/test/CodeGen/AArch64/branch-relax-bcc.ll | 18 |
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 |

