[llvm] [NFC][AArch64] ConditionOptimizer Improve cmp adjustment semantics (PR #185426)

Hussam Alhassan via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 9 08:23:07 PDT 2026


https://github.com/hussam-alhassan updated https://github.com/llvm/llvm-project/pull/185426

>From b765f5cae9ffb4e52d6c34aed6d0a076eb0d4bbd Mon Sep 17 00:00:00 2001
From: Hussam Alhassan <hsm.link at proton.me>
Date: Sun, 1 Mar 2026 21:16:59 +0000
Subject: [PATCH] [NFC][AArch64] ConditionOptimizer Improve cmp adjustment
 semantics

Improve the readability and semantics of AArch64ConditionOptimizer cmp handling:
- Change the 'CmpInfo' tuple to a struct
- Rename adjustCmp() to getAdjustedCmpInfo()
---
 .../AArch64/AArch64ConditionOptimizer.cpp     | 69 +++++++++----------
 1 file changed, 32 insertions(+), 37 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ConditionOptimizer.cpp b/llvm/lib/Target/AArch64/AArch64ConditionOptimizer.cpp
index ef86f1b431418..6aa602cb2f6f3 100644
--- a/llvm/lib/Target/AArch64/AArch64ConditionOptimizer.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ConditionOptimizer.cpp
@@ -89,7 +89,6 @@
 #include "llvm/Support/raw_ostream.h"
 #include <cassert>
 #include <cstdlib>
-#include <tuple>
 
 using namespace llvm;
 
@@ -99,6 +98,13 @@ STATISTIC(NumConditionsAdjusted, "Number of conditions adjusted");
 
 namespace {
 
+/// Bundles the parameters needed to adjust a comparison instruction.
+struct CmpInfo {
+  int Imm;
+  unsigned Opc;
+  AArch64CC::CondCode CC;
+};
+
 class AArch64ConditionOptimizer : public MachineFunctionPass {
   const TargetInstrInfo *TII;
   const TargetRegisterInfo *TRI;
@@ -106,10 +112,6 @@ class AArch64ConditionOptimizer : public MachineFunctionPass {
   const MachineRegisterInfo *MRI;
 
 public:
-  // Stores immediate, compare instruction opcode and branch condition (in this
-  // order) of adjusted comparison.
-  using CmpInfo = std::tuple<int, unsigned, AArch64CC::CondCode>;
-
   static char ID;
 
   AArch64ConditionOptimizer() : MachineFunctionPass(ID) {}
@@ -120,7 +122,7 @@ class AArch64ConditionOptimizer : public MachineFunctionPass {
   bool nzcvLivesOut(MachineBasicBlock *MBB);
   MachineInstr *getBccTerminator(MachineBasicBlock *MBB);
   MachineInstr *findAdjustableCmp(MachineInstr *CondMI);
-  CmpInfo adjustCmp(MachineInstr *CmpMI, AArch64CC::CondCode Cmp);
+  CmpInfo getAdjustedCmpInfo(MachineInstr *CmpMI, AArch64CC::CondCode Cmp);
   void modifyCmp(MachineInstr *CmpMI, const CmpInfo &Info);
   bool adjustTo(MachineInstr *CmpMI, AArch64CC::CondCode Cmp, MachineInstr *To,
                 int ToImm);
@@ -312,11 +314,10 @@ static AArch64CC::CondCode getAdjustedCmp(AArch64CC::CondCode Cmp) {
   }
 }
 
-// Transforms GT -> GE, GE -> GT, LT -> LE, LE -> LT by updating comparison
-// operator and condition code.
-AArch64ConditionOptimizer::CmpInfo
-AArch64ConditionOptimizer::adjustCmp(MachineInstr *CmpMI,
-                                     AArch64CC::CondCode Cmp) {
+// Returns the adjusted immediate, opcode, and condition code for switching
+// between inclusive/exclusive forms (GT <-> GE, LT <-> LE).
+CmpInfo AArch64ConditionOptimizer::getAdjustedCmpInfo(MachineInstr *CmpMI,
+                                                      AArch64CC::CondCode Cmp) {
   unsigned Opc = CmpMI->getOpcode();
 
   bool IsSigned = Cmp == AArch64CC::GT || Cmp == AArch64CC::GE ||
@@ -338,7 +339,7 @@ AArch64ConditionOptimizer::adjustCmp(MachineInstr *CmpMI,
   // Bail out on cmn 0 (ADDS with immediate 0). It is a valid instruction but
   // doesn't set flags in a way we can safely transform, so skip optimization.
   if (OldImm == 0 && Negative)
-    return CmpInfo(OldImm, Opc, Cmp);
+    return {OldImm, Opc, Cmp};
 
   if ((OldImm == 1 && Negative && Correction == -1) ||
       (OldImm == 0 && Correction == -1)) {
@@ -346,28 +347,23 @@ AArch64ConditionOptimizer::adjustCmp(MachineInstr *CmpMI,
     // unsigned wrap (e.g., 0 wrapping to 0xFFFFFFFF), so return the old cmp.
     // Note: For signed comparisons, opcode changes (cmn 1 ↔ cmp 0) are valid.
     if (!IsSigned)
-      return CmpInfo(OldImm, Opc, Cmp);
+      return {OldImm, Opc, Cmp};
     Opc = getComplementOpc(Opc);
   }
 
-  return CmpInfo(NewImm, Opc, getAdjustedCmp(Cmp));
+  return {NewImm, Opc, getAdjustedCmp(Cmp)};
 }
 
-// Applies changes to comparison instruction suggested by adjustCmp().
+// Applies changes to comparison instruction suggested by getAdjustedCmpInfo().
 void AArch64ConditionOptimizer::modifyCmp(MachineInstr *CmpMI,
-    const CmpInfo &Info) {
-  int Imm;
-  unsigned Opc;
-  AArch64CC::CondCode Cmp;
-  std::tie(Imm, Opc, Cmp) = Info;
-
+                                          const CmpInfo &Info) {
   MachineBasicBlock *const MBB = CmpMI->getParent();
 
   // Change immediate in comparison instruction (ADDS or SUBS).
-  BuildMI(*MBB, CmpMI, CmpMI->getDebugLoc(), TII->get(Opc))
+  BuildMI(*MBB, CmpMI, CmpMI->getDebugLoc(), TII->get(Info.Opc))
       .add(CmpMI->getOperand(0))
       .add(CmpMI->getOperand(1))
-      .addImm(Imm)
+      .addImm(Info.Imm)
       .add(CmpMI->getOperand(3));
   CmpMI->eraseFromParent();
 
@@ -377,7 +373,7 @@ void AArch64ConditionOptimizer::modifyCmp(MachineInstr *CmpMI,
 
   // Change condition in branch instruction.
   BuildMI(*MBB, BrMI, BrMI.getDebugLoc(), TII->get(AArch64::Bcc))
-      .addImm(Cmp)
+      .addImm(Info.CC)
       .add(BrMI.getOperand(1));
   BrMI.eraseFromParent();
 
@@ -403,8 +399,8 @@ static bool parseCond(ArrayRef<MachineOperand> Cond, AArch64CC::CondCode &CC) {
 bool AArch64ConditionOptimizer::adjustTo(MachineInstr *CmpMI,
   AArch64CC::CondCode Cmp, MachineInstr *To, int ToImm)
 {
-  CmpInfo Info = adjustCmp(CmpMI, Cmp);
-  if (std::get<0>(Info) == ToImm && std::get<1>(Info) == To->getOpcode()) {
+  CmpInfo Info = getAdjustedCmpInfo(CmpMI, Cmp);
+  if (Info.Imm == ToImm && Info.Opc == To->getOpcode()) {
     modifyCmp(CmpMI, Info);
     return true;
   }
@@ -527,17 +523,16 @@ bool AArch64ConditionOptimizer::optimizeIntraBlock(MachineBasicBlock &MBB) {
     AArch64CC::CondCode CondToAdjust = adjustFirst ? FirstCond : SecondCond;
     int TargetImm = adjustFirst ? SecondImm : FirstImm;
 
-    CmpInfo AdjustedInfo = adjustCmp(CmpToAdjust, CondToAdjust);
+    CmpInfo Adj = getAdjustedCmpInfo(CmpToAdjust, CondToAdjust);
 
-    if (std::get<0>(AdjustedInfo) == TargetImm &&
-        std::get<1>(AdjustedInfo) ==
-            (adjustFirst ? SecondCmpMI : FirstCmpMI)->getOpcode()) {
+    if (Adj.Imm == TargetImm &&
+        Adj.Opc == (adjustFirst ? SecondCmpMI : FirstCmpMI)->getOpcode()) {
       LLVM_DEBUG(dbgs() << "Successfully optimizing intra-block CSINC pair\n");
 
       // Modify the selected CMP and CSINC
-      CmpToAdjust->getOperand(2).setImm(std::get<0>(AdjustedInfo));
-      CmpToAdjust->setDesc(TII->get(std::get<1>(AdjustedInfo)));
-      CSINCToAdjust->getOperand(3).setImm(std::get<2>(AdjustedInfo));
+      CmpToAdjust->getOperand(2).setImm(Adj.Imm);
+      CmpToAdjust->setDesc(TII->get(Adj.Opc));
+      CSINCToAdjust->getOperand(3).setImm(Adj.CC);
 
       return true;
     }
@@ -629,10 +624,10 @@ bool AArch64ConditionOptimizer::optimizeCrossBlock(MachineBasicBlock &HBB) {
     // 1) (a >= {NewImm} && ...) || (a <= {NewImm} && ...)
     // 2) (a <= {NewImm} && ...) || (a >= {NewImm} && ...)
 
-    CmpInfo HeadCmpInfo = adjustCmp(HeadCmpMI, HeadCmp);
-    CmpInfo TrueCmpInfo = adjustCmp(TrueCmpMI, TrueCmp);
-    if (std::get<0>(HeadCmpInfo) == std::get<0>(TrueCmpInfo) &&
-        std::get<1>(HeadCmpInfo) == std::get<1>(TrueCmpInfo)) {
+    CmpInfo HeadCmpInfo = getAdjustedCmpInfo(HeadCmpMI, HeadCmp);
+    CmpInfo TrueCmpInfo = getAdjustedCmpInfo(TrueCmpMI, TrueCmp);
+    if (HeadCmpInfo.Imm == TrueCmpInfo.Imm &&
+        HeadCmpInfo.Opc == TrueCmpInfo.Opc) {
       modifyCmp(HeadCmpMI, HeadCmpInfo);
       modifyCmp(TrueCmpMI, TrueCmpInfo);
       return true;



More information about the llvm-commits mailing list