[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:21:12 PDT 2025
https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/154129
>From fcda4adc19d7225e533b4b5a3ca977ebcaa5c8ff 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
---
.../GISel/AArch64PostLegalizerLowering.cpp | 21 ++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
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