[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