[llvm] [GlobalISel][AArch64] Allow negative integers to be considered as legal cmp immediates (PR #154129)

via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 18 08:22:02 PDT 2025


https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/154129

>From 779eb5b2e6024de1ae86f10e462d09b8c4c03078 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Mon, 18 Aug 2025 10:32:11 -0400
Subject: [PATCH] [Global-ISel][AArch64] Allow negative integers to be
 considered as legal cmp immediates

Also replace checks with assertions now.
---
 .../Target/AArch64/AArch64ISelLowering.cpp    | 13 ++++++------
 .../GISel/AArch64PostLegalizerLowering.cpp    | 21 ++++++++++++-------
 2 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 63a85faf344c4..c27bf82157393 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -4035,13 +4035,12 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
         break;
       case ISD::SETULE:
       case ISD::SETUGT: {
-        if (!C.isAllOnes()) {
-          APInt CPlusOne = C + 1;
-          if (isLegalCmpImmed(CPlusOne) ||
-              (NumImmForC > numberOfInstrToLoadImm(CPlusOne))) {
-            CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE;
-            RHS = DAG.getConstant(CPlusOne, DL, VT);
-          }
+        assert(!C.isAllOnes() && "C should not be -1 here");
+        APInt CPlusOne = C + 1;
+        if (isLegalCmpImmed(CPlusOne) ||
+            (NumImmForC > numberOfInstrToLoadImm(CPlusOne))) {
+          CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE;
+          RHS = DAG.getConstant(CPlusOne, DL, VT);
         }
         break;
       }
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
index 6025f1c9f5f4e..97d17ef498fcb 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
@@ -561,6 +561,12 @@ void applyVAshrLshrImm(MachineInstr &MI, MachineRegisterInfo &MRI,
   MI.eraseFromParent();
 }
 
+bool isLegalCmpImmed(APInt C) {
+  // Works for negative immediates too, as it can be written as an ADDS
+  // instruction with a negated immediate.
+  return isLegalArithImmed(C.abs().getZExtValue());
+}
+
 /// Determine if it is possible to modify the \p RHS and predicate \p P of a
 /// G_ICMP instruction such that the right-hand side is an arithmetic immediate.
 ///
@@ -582,11 +588,14 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
   auto ValAndVReg = getIConstantVRegValWithLookThrough(RHS, MRI);
   if (!ValAndVReg)
     return std::nullopt;
-  uint64_t OriginalC = ValAndVReg->Value.getZExtValue();
-  uint64_t C = OriginalC;
-  if (isLegalArithImmed(C))
+
+  APInt CInt = ValAndVReg->Value;
+  if (isLegalCmpImmed(CInt))
     return std::nullopt;
 
+  uint64_t OriginalC = CInt.getZExtValue();
+  uint64_t C = OriginalC;
+
   // We have a non-arithmetic immediate. Check if adjusting the immediate and
   // adjusting the predicate will result in a legal arithmetic immediate.
   switch (P) {
@@ -599,10 +608,8 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
     // x slt c => x sle c - 1
     // x sge c => x sgt c - 1
     //
-    // When c is not the smallest possible negative number.
-    if ((Size == 64 && static_cast<int64_t>(C) == INT64_MIN) ||
-        (Size == 32 && static_cast<int32_t>(C) == INT32_MIN))
-      return std::nullopt;
+    assert(C != (Size == 32 ? UINT32_MAX : UINT64_MAX) &&
+           "C should not be -1 here!");
     P = (P == CmpInst::ICMP_SLT) ? CmpInst::ICMP_SLE : CmpInst::ICMP_SGT;
     C -= 1;
     break;



More information about the llvm-commits mailing list