[llvm] [AArch64] Snap 32 and -32 to 31 and -31 if possible for ccmp and ccmn (PR #144166)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 13 15:27:44 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: AZero13 (AZero13)
<details>
<summary>Changes</summary>
This lets us encode the immediate in the instruction.
---
Full diff: https://github.com/llvm/llvm-project/pull/144166.diff
2 Files Affected:
- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+49)
- (modified) llvm/test/CodeGen/AArch64/cmp-chains.ll (+44)
``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 7519ac5260a64..f4935d0acbac0 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -3716,6 +3716,55 @@ static SDValue emitConjunctionRec(SelectionDAG &DAG, SDValue Val,
// Produce a normal comparison if we are first in the chain
if (!CCOp)
return emitComparison(LHS, RHS, CC, DL, DAG);
+
+ if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.getNode())) {
+ EVT VT = RHS.getValueType();
+ APInt C = RHSC->getAPIntValue();
+ // shouldBeAdjustedToZero is a special case to better fold with
+ // emitComparison().
+ if (C.getZExtValue() == 32 && (CC == ISD::SETLT || CC == ISD::SETGE ||
+ CC == ISD::SETULT || CC == ISD::SETUGE)) {
+ switch (CC) {
+ case ISD::SETLT:
+ CC = ISD::SETLE;
+ break;
+ case ISD::SETGE:
+ CC = ISD::SETGT;
+ break;
+ case ISD::SETULT:
+ CC = ISD::SETULE;
+ break;
+ case ISD::SETUGE:
+ CC = ISD::SETUGT;
+ break;
+ default:
+ llvm_unreachable("Should not happen");
+ }
+ RHS = DAG.getConstant(31, DL, VT);
+ OutCC = changeIntCCToAArch64CC(CC);
+ } else if (C.getSExtValue() == -32 &&
+ (CC == ISD::SETLE || CC == ISD::SETGT || CC == ISD::SETULE ||
+ CC == ISD::SETUGT)) {
+ switch (CC) {
+ case ISD::SETLE:
+ CC = ISD::SETLT;
+ break;
+ case ISD::SETGT:
+ CC = ISD::SETGE;
+ break;
+ case ISD::SETULE:
+ CC = ISD::SETULT;
+ break;
+ case ISD::SETUGT:
+ CC = ISD::SETUGE;
+ break;
+ default:
+ llvm_unreachable("Should not happen");
+ }
+ RHS = DAG.getConstant((C + 1).getZExtValue(), DL, VT); // -31
+ OutCC = changeIntCCToAArch64CC(CC);
+ }
+ }
// Otherwise produce a ccmp.
return emitConditionalComparison(LHS, RHS, CC, CCOp, Predicate, OutCC, DL,
DAG);
diff --git a/llvm/test/CodeGen/AArch64/cmp-chains.ll b/llvm/test/CodeGen/AArch64/cmp-chains.ll
index 4b816df75a730..81c3f51a2b422 100644
--- a/llvm/test/CodeGen/AArch64/cmp-chains.ll
+++ b/llvm/test/CodeGen/AArch64/cmp-chains.ll
@@ -501,3 +501,47 @@ entry:
%land.ext = zext i1 %0 to i32
ret i32 %land.ext
}
+
+define i32 @compare_with_neg_32(i32 %a, i32 %b, i32 %c) {
+; SDISEL-LABEL: compare_with_neg_32:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmp w0, w2
+; SDISEL-NEXT: ccmn w1, #31, #8, lt
+; SDISEL-NEXT: csel w0, w1, w0, ge
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: compare_with_neg_32:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov w8, #-32 // =0xffffffe0
+; GISEL-NEXT: cmp w0, w2
+; GISEL-NEXT: ccmp w1, w8, #4, lt
+; GISEL-NEXT: csel w0, w1, w0, gt
+; GISEL-NEXT: ret
+ %cmp = icmp sgt i32 %b, -32
+ %cmp1 = icmp slt i32 %a, %c
+ %or.cond = and i1 %cmp, %cmp1
+ %cond = select i1 %or.cond, i32 %b, i32 %a
+ ret i32 %cond
+}
+
+define i32 @compare_with_32(i32 %a, i32 %b, i32 %c) {
+; SDISEL-LABEL: compare_with_32:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmp w0, w2
+; SDISEL-NEXT: ccmp w1, #31, #4, lt
+; SDISEL-NEXT: csel w0, w1, w0, gt
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: compare_with_32:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov w8, #32 // =0x20
+; GISEL-NEXT: cmp w0, w2
+; GISEL-NEXT: ccmp w1, w8, #8, lt
+; GISEL-NEXT: csel w0, w1, w0, ge
+; GISEL-NEXT: ret
+ %cmp = icmp sge i32 %b, 32
+ %cmp1 = icmp slt i32 %a, %c
+ %or.cond = and i1 %cmp, %cmp1
+ %cond = select i1 %or.cond, i32 %b, i32 %a
+ ret i32 %cond
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/144166
More information about the llvm-commits
mailing list