[llvm] Enable early elimination of fall-through B in ARM analyzeBranch (PR #152603)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 7 15:08:19 PDT 2025
https://github.com/AZero13 created https://github.com/llvm/llvm-project/pull/152603
This patch enables the ARM backend’s analyzeBranch() to fold away an unconditional branch targeting its layout-successor, mirroring the existing AArch64 behavior. When AllowModify is true and a lone B instruction jumps to the very next block in layout, the branch is removed and the block simply falls through.
>From f3d07a23bedd0148042a83f17f37058af7b1f202 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Thu, 7 Aug 2025 16:03:29 -0400
Subject: [PATCH] Enable early elimination of fall-through B in ARM
analyzeBranch
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch enables the ARM backend’s analyzeBranch() to fold away an unconditional branch targeting its layout-successor, mirroring the existing AArch64 behavior. When AllowModify is true and a lone B instruction jumps to the very next block in layout, the branch is removed and the block simply falls through.
---
llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | 17 +++++++++++++++++
.../ARM/ifcvt-diamond-unanalyzable-common.mir | 1 -
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 9e4dbecc16a87..2dd93ae55acde 100644
--- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -215,7 +215,24 @@ bool ARMBaseInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
// to clean up any instructions at the tail of the basic block.
CantAnalyze = true;
} else if (isUncondBranchOpcode(I->getOpcode())) {
+ // Record the fall-through target.
TBB = I->getOperand(0).getMBB();
+ if (AllowModify && !isPredicated(*I) && TBB &&
+ MBB.isLayoutSuccessor(TBB)) {
+ // Remove the fall-through unconditional branch and continue the
+ // backward scan from the previous instruction. The normal scanning
+ // logic will classify whatever remains (including fall-through
+ // conditional branches) consistently with the rest of this function.
+ auto After = I;
+ if (After == MBB.instr_begin()) {
+ I->eraseFromParent();
+ return false; // Empty of terminators: falls through.
+ }
+ auto Prev = std::prev(After);
+ I->eraseFromParent();
+ I = Prev;
+ continue;
+ }
} else if (isCondBranchOpcode(I->getOpcode())) {
// Bail out if we encounter multiple conditional branches.
if (!Cond.empty())
diff --git a/llvm/test/CodeGen/ARM/ifcvt-diamond-unanalyzable-common.mir b/llvm/test/CodeGen/ARM/ifcvt-diamond-unanalyzable-common.mir
index ab788f7011a12..2994a69e72a54 100644
--- a/llvm/test/CodeGen/ARM/ifcvt-diamond-unanalyzable-common.mir
+++ b/llvm/test/CodeGen/ARM/ifcvt-diamond-unanalyzable-common.mir
@@ -33,7 +33,6 @@ body: |
; CHECK-NEXT: t2CMPri $sp, 34, 14 /* CC::al */, $noreg, implicit-def $cpsr
; CHECK-NEXT: t2Bcc %bb.2, 1 /* CC::ne */, $cpsr
; CHECK-NEXT: t2Bcc %bb.2, 2 /* CC::hs */, killed $cpsr
- ; CHECK-NEXT: t2B %bb.1, 14 /* CC::al */, $noreg
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */
More information about the llvm-commits
mailing list