[llvm] [AArch64] Use umin for x != 0 when +cssc is enabled (PR #169159)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 26 04:59:52 PST 2025
https://github.com/clingfei updated https://github.com/llvm/llvm-project/pull/169159
>From 51d75337f6dd3a008529ca306e56d6921eef0abe Mon Sep 17 00:00:00 2001
From: clingfei <1599101385 at qq.com>
Date: Sat, 22 Nov 2025 18:36:17 +0800
Subject: [PATCH 1/6] Use umin for x != 0 when +cssc is enabled
---
.../Target/AArch64/AArch64ISelLowering.cpp | 10 ++-
.../test/CodeGen/AArch64/aarch64-isel-umin.ll | 82 +++++++++++++++++++
llvm/test/CodeGen/AArch64/arm64-popcnt.ll | 4 +-
3 files changed, 92 insertions(+), 4 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/aarch64-isel-umin.ll
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index ac3745ea5c274..fdea0d2dfd268 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -26375,7 +26375,8 @@ performVecReduceBitwiseCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
static SDValue performSETCCCombine(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI,
- SelectionDAG &DAG) {
+ SelectionDAG &DAG,
+ const AArch64Subtarget *Subtarget) {
assert(N->getOpcode() == ISD::SETCC && "Unexpected opcode!");
SDValue LHS = N->getOperand(0);
SDValue RHS = N->getOperand(1);
@@ -26417,6 +26418,11 @@ static SDValue performSETCCCombine(SDNode *N,
return DAG.getNode(ISD::SETCC, DL, VT, TST, RHS, N->getOperand(2));
}
}
+ if (Subtarget->hasCSSC() && Cond == ISD::SETNE && isNullConstant(RHS)) {
+ SDValue One = DAG.getConstant(1, DL, LHS.getValueType());
+ auto UMin = DAG.getNode(ISD::UMIN, DL, LHS.getValueType(), LHS, One);
+ return DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, UMin);
+ }
// setcc (iN (bitcast (vNi1 X))), 0, (eq|ne)
// ==> setcc (iN (zext (i1 (vecreduce_or (vNi1 X))))), 0, (eq|ne)
@@ -28180,7 +28186,7 @@ SDValue AArch64TargetLowering::PerformDAGCombine(SDNode *N,
case ISD::VSELECT:
return performVSelectCombine(N, DCI.DAG);
case ISD::SETCC:
- return performSETCCCombine(N, DCI, DAG);
+ return performSETCCCombine(N, DCI, DAG, Subtarget);
case ISD::LOAD:
return performLOADCombine(N, DCI, DAG, Subtarget);
case ISD::STORE:
diff --git a/llvm/test/CodeGen/AArch64/aarch64-isel-umin.ll b/llvm/test/CodeGen/AArch64/aarch64-isel-umin.ll
new file mode 100644
index 0000000000000..87b827aaaa3db
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/aarch64-isel-umin.ll
@@ -0,0 +1,82 @@
+; RUN: llc -mtriple=aarch64-- -o - < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD
+; RUN: llc -mtriple=aarch64-- -mattr=+cssc -o - < %s | FileCheck %s --check-prefixes=CHECK,CHECK-CSSC
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-unknown-linux-gnu"
+
+; auto icmpi64(long x0) { return x0 != 0; }
+define i1 @icmpi64(i64 noundef %0) {
+; CHECK-SD-LABEL: icmpi64:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: cmp x0, #0
+; CHECK-SD-NEXT: cset w0, ne
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: icmpi64:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: umin x0, x0, #1
+; CHECK-CSSC-NEXT: // kill: def $w0 killed $w0 killed $x0
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %2 = icmp ne i64 %0, 0
+ ret i1 %2
+}
+
+; auto icmpi32(int x0) { return x0 != 0; }
+define i1 @icmpi32(i32 noundef %0) {
+; CHECK-SD-LABEL: icmpi32:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: cmp w0, #0
+; CHECK-SD-NEXT: cset w0, ne
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: icmpi32:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: umin w0, w0, #1
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %2 = icmp ne i32 %0, 0
+ ret i1 %2
+}
+
+; auto icmpi16(short x0) { return x0 != 0; }
+define i1 @icmpi16(i16 noundef %0) {
+; CHECK-SD-LABEL: icmpi16:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: tst w0, #0xffff
+; CHECK-SD-NEXT: cset w0, ne
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: icmpi16:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: and w8, w0, #0xffff
+; CHECK-CSSC-NEXT: umin w0, w8, #1
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %2 = icmp ne i16 %0, 0
+ ret i1 %2
+}
+
+; auto icmpi8(char x0) { return x0 != 0; }
+define i1 @icmpi8(i8 noundef %0) {
+; CHECK-SD-LABEL: icmpi8:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: tst w0, #0xff
+; CHECK-SD-NEXT: cset w0, ne
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: icmpi8:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: and w8, w0, #0xff
+; CHECK-CSSC-NEXT: umin w0, w8, #1
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %2 = icmp ne i8 %0, 0
+ ret i1 %2
+}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK: {{.*}}
\ No newline at end of file
diff --git a/llvm/test/CodeGen/AArch64/arm64-popcnt.ll b/llvm/test/CodeGen/AArch64/arm64-popcnt.ll
index d06e42f5405ef..3d6cc814d157d 100644
--- a/llvm/test/CodeGen/AArch64/arm64-popcnt.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-popcnt.ll
@@ -414,8 +414,8 @@ define i1 @ctpop32_ne_one_nonzero(i32 %x) {
; CHECK-CSSC-LABEL: ctpop32_ne_one_nonzero:
; CHECK-CSSC: // %bb.0: // %entry
; CHECK-CSSC-NEXT: sub w8, w0, #1
-; CHECK-CSSC-NEXT: tst w0, w8
-; CHECK-CSSC-NEXT: cset w0, ne
+; CHECK-CSSC-NEXT: and w8, w0, w8
+; CHECK-CSSC-NEXT: umin w0, w8, #1
; CHECK-CSSC-NEXT: ret
;
; CHECK-BE-LABEL: ctpop32_ne_one_nonzero:
>From 6ae4bc20abd6f43d9ef943f2718217744266a62e Mon Sep 17 00:00:00 2001
From: clingfei <1599101385 at qq.com>
Date: Sat, 22 Nov 2025 22:44:18 +0800
Subject: [PATCH 2/6] use the SETCC's VT as new DAG node's type, and add more
tests
---
.../Target/AArch64/AArch64ISelLowering.cpp | 2 +-
.../test/CodeGen/AArch64/aarch64-isel-umin.ll | 241 +++++++++++++++++-
2 files changed, 238 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index fdea0d2dfd268..5c84142152b68 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -26421,7 +26421,7 @@ static SDValue performSETCCCombine(SDNode *N,
if (Subtarget->hasCSSC() && Cond == ISD::SETNE && isNullConstant(RHS)) {
SDValue One = DAG.getConstant(1, DL, LHS.getValueType());
auto UMin = DAG.getNode(ISD::UMIN, DL, LHS.getValueType(), LHS, One);
- return DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, UMin);
+ return DAG.getNode(ISD::TRUNCATE, DL, VT, UMin);
}
// setcc (iN (bitcast (vNi1 X))), 0, (eq|ne)
diff --git a/llvm/test/CodeGen/AArch64/aarch64-isel-umin.ll b/llvm/test/CodeGen/AArch64/aarch64-isel-umin.ll
index 87b827aaaa3db..ec60387223f3d 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-isel-umin.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-isel-umin.ll
@@ -1,5 +1,5 @@
-; RUN: llc -mtriple=aarch64-- -o - < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD
-; RUN: llc -mtriple=aarch64-- -mattr=+cssc -o - < %s | FileCheck %s --check-prefixes=CHECK,CHECK-CSSC
+; RUN: llc -mtriple=aarch64-- -o - < %s | FileCheck %s --check-prefix=CHECK-SD
+; RUN: llc -mtriple=aarch64-- -mattr=+cssc -o - < %s | FileCheck %s --check-prefix=CHECK-CSSC
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-unknown-linux-gnu"
@@ -78,5 +78,238 @@ entry:
%2 = icmp ne i8 %0, 0
ret i1 %2
}
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK: {{.*}}
\ No newline at end of file
+
+; unsigned long icmpi64i8(char x0) { return x0 != 0; }
+define i64 @icmpi64i8(i8 noundef %0) {
+; CHECK-SD-LABEL: icmpi64i8:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: tst w0, #0xff
+; CHECK-SD-NEXT: cset w0, ne
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: icmpi64i8:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: and w8, w0, #0xff
+; CHECK-CSSC-NEXT: umin w0, w8, #1
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %1 = icmp ne i8 %0, 0
+ %2 = zext i1 %1 to i64
+ ret i64 %2
+}
+
+; unsigned long setcc_i8_i64(char x0) { return x0 != 0; }
+define i8 @setcc_i8_i64(i64 %x) {
+; CHECK-SD-LABEL: setcc_i8_i64:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: cmp x0, #0
+; CHECK-SD-NEXT: cset w0, ne
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: setcc_i8_i64:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: umin x0, x0, #1
+; CHECK-CSSC-NEXT: // kill: def $w0 killed $w0 killed $x0
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %cmp = icmp ne i64 %x, 0
+ %conv = zext i1 %cmp to i8
+ ret i8 %conv
+}
+
+; short setcc_i16_i32(int x0) { return x0 != 0; }
+define i16 @setcc_i16_i32(i32 %x) {
+; CHECK-SD-LABEL: setcc_i16_i32:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: cmp w0, #0
+; CHECK-SD-NEXT: cset w0, ne
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: setcc_i16_i32:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: umin w0, w0, #1
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %cmp = icmp ne i32 %x, 0
+ %conv = zext i1 %cmp to i16
+ ret i16 %conv
+}
+
+; int setcc_i32_i64(unsigned long x0) { return x0 != 0; }
+define i32 @setcc_i32_i64(i64 %x) {
+; CHECK-SD-LABEL: setcc_i32_i64:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: cmp x0, #0
+; CHECK-SD-NEXT: cset w0, ne
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: setcc_i32_i64:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: umin x0, x0, #1
+; CHECK-CSSC-NEXT: // kill: def $w0 killed $w0 killed $x0
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %cmp = icmp ne i64 %x, 0
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+}
+
+; unsigned long setcc_i64_i64(unsigned long x0) { return x0 != 0; }
+define i64 @setcc_i64_i64(i64 %x) {
+; CHECK-SD-LABEL: setcc_i64_i64:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: cmp x0, #0
+; CHECK-SD-NEXT: cset w0, ne
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: setcc_i64_i64:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: umin x0, x0, #1
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %cmp = icmp ne i64 %x, 0
+ %conv = zext i1 %cmp to i64
+ ret i64 %conv
+}
+
+define <2 x i1> @setcc_v2i1_v2i64(<2 x i64> %x) {
+; CHECK-SD-LABEL: setcc_v2i1_v2i64:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: cmtst v0.2d, v0.2d, v0.2d
+; CHECK-SD-NEXT: xtn v0.2s, v0.2d
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: setcc_v2i1_v2i64:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: cmtst v0.2d, v0.2d, v0.2d
+; CHECK-CSSC-NEXT: xtn v0.2s, v0.2d
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %cmp = icmp ne <2 x i64> %x, zeroinitializer
+ ret <2 x i1> %cmp
+}
+
+define <4 x i1> @setcc_v4i1_v4i32(<4 x i32> %x) {
+; CHECK-SD-LABEL: setcc_v4i1_v4i32:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: cmtst v0.4s, v0.4s, v0.4s
+; CHECK-SD-NEXT: xtn v0.4h, v0.4s
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: setcc_v4i1_v4i32:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: cmtst v0.4s, v0.4s, v0.4s
+; CHECK-CSSC-NEXT: xtn v0.4h, v0.4s
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %cmp = icmp ne <4 x i32> %x, zeroinitializer
+ ret <4 x i1> %cmp
+}
+
+define <8 x i1> @setcc_v8i1_v8i16(<8 x i16> %x) {
+; CHECK-SD-LABEL: setcc_v8i1_v8i16:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: cmtst v0.8h, v0.8h, v0.8h
+; CHECK-SD-NEXT: xtn v0.8b, v0.8h
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: setcc_v8i1_v8i16:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: cmtst v0.8h, v0.8h, v0.8h
+; CHECK-CSSC-NEXT: xtn v0.8b, v0.8h
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %cmp = icmp ne <8 x i16> %x, zeroinitializer
+ ret <8 x i1> %cmp
+}
+
+define <16 x i1> @setcc_v16i1_v16i8(<16 x i8> %x) {
+; CHECK-SD-LABEL: setcc_v16i1_v16i8:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: cmtst v0.16b, v0.16b, v0.16b
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: setcc_v16i1_v16i8:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: cmtst v0.16b, v0.16b, v0.16b
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %cmp = icmp ne <16 x i8> %x, zeroinitializer
+ ret <16 x i1> %cmp
+}
+
+define <2 x i8> @setcc_v2i8_v2i64(<2 x i64> %x) {
+; CHECK-SD-LABEL: setcc_v2i8_v2i64:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: cmtst v0.2d, v0.2d, v0.2d
+; CHECK-SD-NEXT: movi v1.2s, #1
+; CHECK-SD-NEXT: xtn v0.2s, v0.2d
+; CHECK-SD-NEXT: and v0.8b, v0.8b, v1.8b
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: setcc_v2i8_v2i64:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: cmtst v0.2d, v0.2d, v0.2d
+; CHECK-CSSC-NEXT: movi v1.2s, #1
+; CHECK-CSSC-NEXT: xtn v0.2s, v0.2d
+; CHECK-CSSC-NEXT: and v0.8b, v0.8b, v1.8b
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %cmp = icmp ne <2 x i64> %x, zeroinitializer
+ %conv = zext <2 x i1> %cmp to <2 x i8>
+ ret <2 x i8> %conv
+}
+
+define <4 x i16> @setcc_v4i16_v4i32(<4 x i32> %x) {
+; CHECK-SD-LABEL: setcc_v4i16_v4i32:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: cmtst v0.4s, v0.4s, v0.4s
+; CHECK-SD-NEXT: movi v1.4h, #1
+; CHECK-SD-NEXT: xtn v0.4h, v0.4s
+; CHECK-SD-NEXT: and v0.8b, v0.8b, v1.8b
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: setcc_v4i16_v4i32:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: cmtst v0.4s, v0.4s, v0.4s
+; CHECK-CSSC-NEXT: movi v1.4h, #1
+; CHECK-CSSC-NEXT: xtn v0.4h, v0.4s
+; CHECK-CSSC-NEXT: and v0.8b, v0.8b, v1.8b
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %cmp = icmp ne <4 x i32> %x, zeroinitializer
+ %conv = zext <4 x i1> %cmp to <4 x i16>
+ ret <4 x i16> %conv
+}
+
+define <4 x i32> @setcc_v4i32_v4i32(<4 x i32> %x) {
+; CHECK-SD-LABEL: setcc_v4i32_v4i32:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: movi v1.4s, #1
+; CHECK-SD-NEXT: cmeq v0.4s, v0.4s, #0
+; CHECK-SD-NEXT: bic v0.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: setcc_v4i32_v4i32:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: movi v1.4s, #1
+; CHECK-CSSC-NEXT: cmeq v0.4s, v0.4s, #0
+; CHECK-CSSC-NEXT: bic v0.16b, v1.16b, v0.16b
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %cmp = icmp ne <4 x i32> %x, zeroinitializer
+ %conv = zext <4 x i1> %cmp to <4 x i32>
+ ret <4 x i32> %conv
+}
>From ad2311da9ffa91a26cb75471929e4cd27eb93205 Mon Sep 17 00:00:00 2001
From: clingfei <1599101385 at qq.com>
Date: Sat, 22 Nov 2025 23:59:00 +0800
Subject: [PATCH 3/6] check whether SETCC is vectortype
---
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 5c84142152b68..814f71d3fdec7 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -26418,7 +26418,7 @@ static SDValue performSETCCCombine(SDNode *N,
return DAG.getNode(ISD::SETCC, DL, VT, TST, RHS, N->getOperand(2));
}
}
- if (Subtarget->hasCSSC() && Cond == ISD::SETNE && isNullConstant(RHS)) {
+ if (Subtarget->hasCSSC() && Cond == ISD::SETNE && isNullConstant(RHS) && !VT.isVector()) {
SDValue One = DAG.getConstant(1, DL, LHS.getValueType());
auto UMin = DAG.getNode(ISD::UMIN, DL, LHS.getValueType(), LHS, One);
return DAG.getNode(ISD::TRUNCATE, DL, VT, UMin);
>From 9cb018f450ccf22b2a15475b7e1b8243761df1ba Mon Sep 17 00:00:00 2001
From: clingfei <1599101385 at qq.com>
Date: Sat, 22 Nov 2025 23:59:57 +0800
Subject: [PATCH 4/6] check whether SETCC is vectortype
---
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 814f71d3fdec7..abf08af179670 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -26418,7 +26418,8 @@ static SDValue performSETCCCombine(SDNode *N,
return DAG.getNode(ISD::SETCC, DL, VT, TST, RHS, N->getOperand(2));
}
}
- if (Subtarget->hasCSSC() && Cond == ISD::SETNE && isNullConstant(RHS) && !VT.isVector()) {
+ if (Subtarget->hasCSSC() && Cond == ISD::SETNE && isNullConstant(RHS) &&
+ !VT.isVector()) {
SDValue One = DAG.getConstant(1, DL, LHS.getValueType());
auto UMin = DAG.getNode(ISD::UMIN, DL, LHS.getValueType(), LHS, One);
return DAG.getNode(ISD::TRUNCATE, DL, VT, UMin);
>From f98d247dea1efa998de8a3c03b025399200a8387 Mon Sep 17 00:00:00 2001
From: clingfei <1599101385 at qq.com>
Date: Tue, 25 Nov 2025 19:02:14 +0800
Subject: [PATCH 5/6] perform SETCCCombine after LegalizeTypes
---
.../Target/AArch64/AArch64ISelLowering.cpp | 2 +-
.../test/CodeGen/AArch64/aarch64-isel-umin.ll | 21 +++++++++++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index abf08af179670..36a1494bb423f 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -26419,7 +26419,7 @@ static SDValue performSETCCCombine(SDNode *N,
}
}
if (Subtarget->hasCSSC() && Cond == ISD::SETNE && isNullConstant(RHS) &&
- !VT.isVector()) {
+ !VT.isVector() && DCI.getDAGCombineLevel() >= AfterLegalizeTypes) {
SDValue One = DAG.getConstant(1, DL, LHS.getValueType());
auto UMin = DAG.getNode(ISD::UMIN, DL, LHS.getValueType(), LHS, One);
return DAG.getNode(ISD::TRUNCATE, DL, VT, UMin);
diff --git a/llvm/test/CodeGen/AArch64/aarch64-isel-umin.ll b/llvm/test/CodeGen/AArch64/aarch64-isel-umin.ll
index ec60387223f3d..261f2cdad50e0 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-isel-umin.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-isel-umin.ll
@@ -313,3 +313,24 @@ entry:
%conv = zext <4 x i1> %cmp to <4 x i32>
ret <4 x i32> %conv
}
+
+; auto icmpi128(int128 x0) { return x0 != 0; }
+define i1 @icmpi128(i128 noundef %0) {
+; CHECK-SD-LABEL: icmpi128:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: orr x8, x0, x1
+; CHECK-SD-NEXT: cmp x8, #0
+; CHECK-SD-NEXT: cset w0, ne
+; CHECK-SD-NEXT: ret
+;
+; CHECK-CSSC-LABEL: icmpi128:
+; CHECK-CSSC: // %bb.0: // %entry
+; CHECK-CSSC-NEXT: orr x8, x0, x1
+; CHECK-CSSC-NEXT: umin x0, x8, #1
+; CHECK-CSSC-NEXT: // kill: def $w0 killed $w0 killed $x0
+; CHECK-CSSC-NEXT: ret
+;
+entry:
+ %2 = icmp ne i128 %0, 0
+ ret i1 %2
+}
>From 060a2ed4fc7d439088fcd24b62c7b585b0d09d88 Mon Sep 17 00:00:00 2001
From: clingfei <1599101385 at qq.com>
Date: Wed, 26 Nov 2025 20:59:27 +0800
Subject: [PATCH 6/6] Move the code into LowerSETCC
---
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 101791cc40542..2a83e36c1e552 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -11735,7 +11735,12 @@ SDValue AArch64TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
}
if (LHS.getValueType().isInteger()) {
-
+ if (Subtarget->hasCSSC() && CC == ISD::SETNE && isNullConstant(RHS)) {
+ SDValue One = DAG.getConstant(1, DL, LHS.getValueType());
+ auto UMin = DAG.getNode(ISD::UMIN, DL, LHS.getValueType(), LHS, One);
+ SDValue Res = DAG.getNode(ISD::TRUNCATE, DL, VT, UMin);
+ return IsStrict ? DAG.getMergeValues({Res, Chain}, DL) : Res;
+ }
simplifySetCCIntoEq(CC, LHS, RHS, DAG, DL);
SDValue CCVal;
More information about the llvm-commits
mailing list