[llvm] [Global-ISel][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 07:47:50 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: AZero13 (AZero13)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/154129.diff


1 Files Affected:

- (modified) llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp (+20-12) 


``````````diff
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
index 2abe0dd0bbdc2..36b45b3b10bc7 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;
@@ -626,9 +633,8 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
     // x sgt c => s sge c + 1
     //
     // When c is not the largest possible signed integer.
-    if ((Size == 32 && static_cast<int32_t>(C) == INT32_MAX) ||
-        (Size == 64 && static_cast<int64_t>(C) == INT64_MAX))
-      return std::nullopt;
+    assert(C != (Size == 32 ? UINT32_MAX : UINT64_MAX) &&
+           "C should not be -1 here!");
     P = (P == CmpInst::ICMP_SLE) ? CmpInst::ICMP_SLT : CmpInst::ICMP_SGE;
     C += 1;
     break;
@@ -639,8 +645,10 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
     // x ule c => x ult c + 1
     // x ugt c => s uge c + 1
     //
-    assert(C != (Size == 32 ? UINT32_MAX : UINT64_MAX) &&
-           "C should not be -1 here!");
+    // When c is not the largest possible unsigned integer.
+    if ((Size == 32 && static_cast<uint32_t>(C) == UINT32_MAX) ||
+        (Size == 64 && C == UINT64_MAX))
+      return std::nullopt;
     P = (P == CmpInst::ICMP_ULE) ? CmpInst::ICMP_ULT : CmpInst::ICMP_UGE;
     C += 1;
     break;

``````````

</details>


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


More information about the llvm-commits mailing list