[llvm] [AArch64] Prefer comparison with 0 with checking sign flag only (PR #153511)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 14 08:44:40 PDT 2025
https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/153511
>From ef68bd733028b8531fda919a978d323ee0acbf7f Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Wed, 13 Aug 2025 20:21:40 -0400
Subject: [PATCH] [AArch64] Prefer comparison with 0 with checking sign flag
only
The peephole optimizer prefers this.
---
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 17 ++++++++++++-----
.../AArch64/check-sign-bit-before-extension.ll | 12 ++++++------
.../test/CodeGen/AArch64/select-constant-xor.ll | 4 ++--
llvm/test/CodeGen/AArch64/signbit-shift.ll | 8 ++++----
llvm/test/CodeGen/AArch64/signbit-test.ll | 4 ++--
.../CodeGen/AArch64/typepromotion-signed.ll | 8 ++++----
6 files changed, 30 insertions(+), 23 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 2072e48914ae6..7606e06ba21d5 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -3960,16 +3960,23 @@ static unsigned getCmpOperandFoldingProfit(SDValue Op) {
// works.
static bool shouldBeAdjustedToZero(SDValue LHS, APInt C, ISD::CondCode &CC) {
// Only works for ANDS and AND.
- if (LHS.getOpcode() != ISD::AND && LHS.getOpcode() != AArch64ISD::ANDS)
+
+ // TODO: Is this too restrictive? This is just to prevent CSE with other
+ // comparisons.
+ if (LHS.getOpcode() != ISD::AND && LHS.getOpcode() != AArch64ISD::ANDS &&
+ !LHS.hasOneUse())
return false;
- if (C.isOne() && (CC == ISD::SETLT || CC == ISD::SETGE)) {
- CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
+ if (C.isAllOnes() && (CC == ISD::SETLE || CC == ISD::SETGT)) {
+ CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
return true;
}
- if (C.isAllOnes() && (CC == ISD::SETLE || CC == ISD::SETGT)) {
- CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
+ if (LHS.getOpcode() != ISD::AND && LHS.getOpcode() != AArch64ISD::ANDS)
+ return false;
+
+ if (C.isOne() && (CC == ISD::SETLT || CC == ISD::SETGE)) {
+ CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
return true;
}
diff --git a/llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll b/llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll
index 0960c4c2a3342..04675c68afd52 100644
--- a/llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll
+++ b/llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll
@@ -14,8 +14,8 @@ define i32 @f_i8_sign_extend_inreg(i8 %in, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: f_i8_sign_extend_inreg:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: sxtb w8, w0
-; CHECK-NEXT: cmn w8, #1
-; CHECK-NEXT: csel w8, w1, w2, gt
+; CHECK-NEXT: cmp w8, #0
+; CHECK-NEXT: csel w8, w1, w2, pl
; CHECK-NEXT: add w0, w8, w0, uxtb
; CHECK-NEXT: ret
entry:
@@ -36,8 +36,8 @@ define i32 @f_i16_sign_extend_inreg(i16 %in, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: f_i16_sign_extend_inreg:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: sxth w8, w0
-; CHECK-NEXT: cmn w8, #1
-; CHECK-NEXT: csel w8, w1, w2, gt
+; CHECK-NEXT: cmp w8, #0
+; CHECK-NEXT: csel w8, w1, w2, pl
; CHECK-NEXT: add w0, w8, w0, uxth
; CHECK-NEXT: ret
entry:
@@ -145,8 +145,8 @@ define i64 @f_i32_sign_extend_i64(i32 %in, i64 %a, i64 %b) nounwind {
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
; CHECK-NEXT: sxtw x8, w0
-; CHECK-NEXT: cmn x8, #1
-; CHECK-NEXT: csel x8, x1, x2, gt
+; CHECK-NEXT: cmp x8, #0
+; CHECK-NEXT: csel x8, x1, x2, pl
; CHECK-NEXT: add x0, x8, w0, uxtw
; CHECK-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/AArch64/select-constant-xor.ll b/llvm/test/CodeGen/AArch64/select-constant-xor.ll
index 97ad579a39f78..95a3a035e3456 100644
--- a/llvm/test/CodeGen/AArch64/select-constant-xor.ll
+++ b/llvm/test/CodeGen/AArch64/select-constant-xor.ll
@@ -168,8 +168,8 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
; CHECK-SD-LABEL: icmpasrne:
; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn w0, #1
-; CHECK-SD-NEXT: csel w0, w1, w2, gt
+; CHECK-SD-NEXT: cmp w0, #0
+; CHECK-SD-NEXT: csel w0, w1, w2, pl
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: icmpasrne:
diff --git a/llvm/test/CodeGen/AArch64/signbit-shift.ll b/llvm/test/CodeGen/AArch64/signbit-shift.ll
index ce8a96386d04c..0f64e7f485a5e 100644
--- a/llvm/test/CodeGen/AArch64/signbit-shift.ll
+++ b/llvm/test/CodeGen/AArch64/signbit-shift.ll
@@ -43,8 +43,8 @@ define i32 @sel_ifpos_tval_bigger(i32 %x) {
; CHECK-LABEL: sel_ifpos_tval_bigger:
; CHECK: // %bb.0:
; CHECK-NEXT: mov w8, #41 // =0x29
-; CHECK-NEXT: cmn w0, #1
-; CHECK-NEXT: cinc w0, w8, gt
+; CHECK-NEXT: cmp w0, #0
+; CHECK-NEXT: cinc w0, w8, pl
; CHECK-NEXT: ret
%c = icmp sgt i32 %x, -1
%r = select i1 %c, i32 42, i32 41
@@ -91,8 +91,8 @@ define i32 @sel_ifpos_fval_bigger(i32 %x) {
; CHECK-LABEL: sel_ifpos_fval_bigger:
; CHECK: // %bb.0:
; CHECK-NEXT: mov w8, #41 // =0x29
-; CHECK-NEXT: cmn w0, #1
-; CHECK-NEXT: cinc w0, w8, le
+; CHECK-NEXT: cmp w0, #0
+; CHECK-NEXT: cinc w0, w8, mi
; CHECK-NEXT: ret
%c = icmp sgt i32 %x, -1
%r = select i1 %c, i32 41, i32 42
diff --git a/llvm/test/CodeGen/AArch64/signbit-test.ll b/llvm/test/CodeGen/AArch64/signbit-test.ll
index c74a934ee09d8..bda2b299e6ea5 100644
--- a/llvm/test/CodeGen/AArch64/signbit-test.ll
+++ b/llvm/test/CodeGen/AArch64/signbit-test.ll
@@ -5,8 +5,8 @@ define i64 @test_clear_mask_i64_i32(i64 %x) nounwind {
; CHECK-LABEL: test_clear_mask_i64_i32:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov w8, #42 // =0x2a
-; CHECK-NEXT: cmn w0, #1
-; CHECK-NEXT: csel x0, x8, x0, gt
+; CHECK-NEXT: cmp w0, #0
+; CHECK-NEXT: csel x0, x8, x0, pl
; CHECK-NEXT: ret
entry:
%a = and i64 %x, 2147483648
diff --git a/llvm/test/CodeGen/AArch64/typepromotion-signed.ll b/llvm/test/CodeGen/AArch64/typepromotion-signed.ll
index 0feac24062647..ded6a1de2677d 100644
--- a/llvm/test/CodeGen/AArch64/typepromotion-signed.ll
+++ b/llvm/test/CodeGen/AArch64/typepromotion-signed.ll
@@ -60,9 +60,9 @@ define i32 @test_signext_b(ptr nocapture readonly %ptr, i8 signext %arg) {
; CHECK-NEXT: mov w8, #20894 // =0x519e
; CHECK-NEXT: add w9, w9, w1
; CHECK-NEXT: sxtb w9, w9
-; CHECK-NEXT: cmn w9, #1
+; CHECK-NEXT: cmp w9, #0
; CHECK-NEXT: mov w9, #42 // =0x2a
-; CHECK-NEXT: csel w0, w9, w8, gt
+; CHECK-NEXT: csel w0, w9, w8, pl
; CHECK-NEXT: ret
entry:
%0 = load i8, ptr %ptr, align 1
@@ -100,9 +100,9 @@ define i32 @test_signext_h(ptr nocapture readonly %ptr, i16 signext %arg) {
; CHECK-NEXT: mov w8, #20894 // =0x519e
; CHECK-NEXT: add w9, w9, w1
; CHECK-NEXT: sxth w9, w9
-; CHECK-NEXT: cmn w9, #1
+; CHECK-NEXT: cmp w9, #0
; CHECK-NEXT: mov w9, #42 // =0x2a
-; CHECK-NEXT: csel w0, w9, w8, gt
+; CHECK-NEXT: csel w0, w9, w8, pl
; CHECK-NEXT: ret
entry:
%0 = load i16, ptr %ptr, align 1
More information about the llvm-commits
mailing list