[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