[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