[llvm] [LLVM][CodeGen][SVE] Add isel for zext(setcc(x,0,ne)) -> umin(x,1). (PR #209452)
Paul Walker via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 14 04:50:48 PDT 2026
https://github.com/paulwalker-arm created https://github.com/llvm/llvm-project/pull/209452
None
>From da1306a593dc1e584e8befe59faa4c498339c295 Mon Sep 17 00:00:00 2001
From: Paul Walker <paul.walker at arm.com>
Date: Fri, 10 Jul 2026 17:17:52 +0100
Subject: [PATCH 1/2] Add tests.
---
llvm/test/CodeGen/AArch64/sve-cmp-folds.ll | 48 ++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/llvm/test/CodeGen/AArch64/sve-cmp-folds.ll b/llvm/test/CodeGen/AArch64/sve-cmp-folds.ll
index 103e31baa6d41..0e4011acc1314 100644
--- a/llvm/test/CodeGen/AArch64/sve-cmp-folds.ll
+++ b/llvm/test/CodeGen/AArch64/sve-cmp-folds.ll
@@ -89,6 +89,54 @@ define <vscale x 2 x i64> @icmp_cnot_nxv2i64(<vscale x 2 x i64> %a) {
ret <vscale x 2 x i64> %zext
}
+define <vscale x 16 x i8> @icmp_clamp_i1_nxv16i8(<vscale x 16 x i8> %a) {
+; CHECK-LABEL: icmp_clamp_i1_nxv16i8:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ptrue p0.b
+; CHECK-NEXT: cmpne p1.b, p0/z, z0.b, #0
+; CHECK-NEXT: mov z0.b, p1/z, #1 // =0x1
+; CHECK-NEXT: ret
+ %mask = icmp ne <vscale x 16 x i8> %a, zeroinitializer
+ %zext = zext <vscale x 16 x i1> %mask to <vscale x 16 x i8>
+ ret <vscale x 16 x i8> %zext
+}
+
+define <vscale x 8 x i16> @icmp_clamp_i1_nxv8i16(<vscale x 8 x i16> %a) {
+; CHECK-LABEL: icmp_clamp_i1_nxv8i16:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ptrue p0.h
+; CHECK-NEXT: cmpne p1.h, p0/z, z0.h, #0
+; CHECK-NEXT: mov z0.h, p1/z, #1 // =0x1
+; CHECK-NEXT: ret
+ %mask = icmp ne <vscale x 8 x i16> %a, zeroinitializer
+ %zext = zext <vscale x 8 x i1> %mask to <vscale x 8 x i16>
+ ret <vscale x 8 x i16> %zext
+}
+
+define <vscale x 4 x i32> @icmp_clamp_i1_nxv4i32(<vscale x 4 x i32> %a) {
+; CHECK-LABEL: icmp_clamp_i1_nxv4i32:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ptrue p0.s
+; CHECK-NEXT: cmpne p1.s, p0/z, z0.s, #0
+; CHECK-NEXT: mov z0.s, p1/z, #1 // =0x1
+; CHECK-NEXT: ret
+ %mask = icmp ne <vscale x 4 x i32> %a, zeroinitializer
+ %zext = zext <vscale x 4 x i1> %mask to <vscale x 4 x i32>
+ ret <vscale x 4 x i32> %zext
+}
+
+define <vscale x 2 x i64> @icmp_clamp_i1_nxv2i64(<vscale x 2 x i64> %a) {
+; CHECK-LABEL: icmp_clamp_i1_nxv2i64:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ptrue p0.d
+; CHECK-NEXT: cmpne p1.d, p0/z, z0.d, #0
+; CHECK-NEXT: mov z0.d, p1/z, #1 // =0x1
+; CHECK-NEXT: ret
+ %mask = icmp ne <vscale x 2 x i64> %a, zeroinitializer
+ %zext = zext <vscale x 2 x i1> %mask to <vscale x 2 x i64>
+ ret <vscale x 2 x i64> %zext
+}
+
define i1 @foo_first(<vscale x 4 x float> %a, <vscale x 4 x float> %b) {
; CHECK-LABEL: foo_first:
; CHECK: // %bb.0:
>From 2ad94c23054af4e9ee23c10c5f04d2991d6b508f Mon Sep 17 00:00:00 2001
From: Paul Walker <paul.walker at arm.com>
Date: Fri, 10 Jul 2026 17:32:37 +0100
Subject: [PATCH 2/2] [LLVM][CodeGen][SVE] Add isel for zext(setcc(x,0,ne)) ->
umin(x,1).
---
llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td | 10 ++++++++++
llvm/test/CodeGen/AArch64/sve-cmp-folds.ll | 16 ++++------------
2 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 26b0a38f6bae0..9b5c6f9cef125 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -789,6 +789,16 @@ let Predicates = [HasSVE_or_SME] in {
defm UMAX_ZI : sve_int_arith_imm1_unsigned<0b01, "umax", AArch64umax_p>;
defm UMIN_ZI : sve_int_arith_imm1_unsigned<0b11, "umin", AArch64umin_p>;
+ // zext(cmpne(x, splat(0))) -> umin(x, 1)
+ def : Pat<(nxv16i8 (zext (AArch64setcc_z (SVEAllActive), nxv16i8:$LHS, (SVEDup0), SETNE))),
+ (UMIN_ZI_B $LHS, 1)>;
+ def : Pat<(nxv8i16 (zext (AArch64setcc_z (SVEAllActive), nxv8i16:$LHS, (SVEDup0), SETNE))),
+ (UMIN_ZI_H $LHS, 1)>;
+ def : Pat<(nxv4i32 (zext (AArch64setcc_z (SVEAllActive), nxv4i32:$LHS, (SVEDup0), SETNE))),
+ (UMIN_ZI_S $LHS, 1)>;
+ def : Pat<(nxv2i64 (zext (AArch64setcc_z (SVEAllActive), nxv2i64:$LHS, (SVEDup0), SETNE))),
+ (UMIN_ZI_D $LHS, 1)>;
+
defm MUL_ZI : sve_int_arith_imm2<"mul", AArch64mul_p>;
defm MUL_ZPmZ : sve_int_bin_pred_arit_2<0b000, "mul", "MUL_ZPZZ", AArch64mul_m1, DestructiveBinaryComm>;
defm SMULH_ZPmZ : sve_int_bin_pred_arit_2<0b010, "smulh", "SMULH_ZPZZ", int_aarch64_sve_smulh, DestructiveBinaryComm>;
diff --git a/llvm/test/CodeGen/AArch64/sve-cmp-folds.ll b/llvm/test/CodeGen/AArch64/sve-cmp-folds.ll
index 0e4011acc1314..88b3b3ad2102b 100644
--- a/llvm/test/CodeGen/AArch64/sve-cmp-folds.ll
+++ b/llvm/test/CodeGen/AArch64/sve-cmp-folds.ll
@@ -92,9 +92,7 @@ define <vscale x 2 x i64> @icmp_cnot_nxv2i64(<vscale x 2 x i64> %a) {
define <vscale x 16 x i8> @icmp_clamp_i1_nxv16i8(<vscale x 16 x i8> %a) {
; CHECK-LABEL: icmp_clamp_i1_nxv16i8:
; CHECK: // %bb.0:
-; CHECK-NEXT: ptrue p0.b
-; CHECK-NEXT: cmpne p1.b, p0/z, z0.b, #0
-; CHECK-NEXT: mov z0.b, p1/z, #1 // =0x1
+; CHECK-NEXT: umin z0.b, z0.b, #1
; CHECK-NEXT: ret
%mask = icmp ne <vscale x 16 x i8> %a, zeroinitializer
%zext = zext <vscale x 16 x i1> %mask to <vscale x 16 x i8>
@@ -104,9 +102,7 @@ define <vscale x 16 x i8> @icmp_clamp_i1_nxv16i8(<vscale x 16 x i8> %a) {
define <vscale x 8 x i16> @icmp_clamp_i1_nxv8i16(<vscale x 8 x i16> %a) {
; CHECK-LABEL: icmp_clamp_i1_nxv8i16:
; CHECK: // %bb.0:
-; CHECK-NEXT: ptrue p0.h
-; CHECK-NEXT: cmpne p1.h, p0/z, z0.h, #0
-; CHECK-NEXT: mov z0.h, p1/z, #1 // =0x1
+; CHECK-NEXT: umin z0.h, z0.h, #1
; CHECK-NEXT: ret
%mask = icmp ne <vscale x 8 x i16> %a, zeroinitializer
%zext = zext <vscale x 8 x i1> %mask to <vscale x 8 x i16>
@@ -116,9 +112,7 @@ define <vscale x 8 x i16> @icmp_clamp_i1_nxv8i16(<vscale x 8 x i16> %a) {
define <vscale x 4 x i32> @icmp_clamp_i1_nxv4i32(<vscale x 4 x i32> %a) {
; CHECK-LABEL: icmp_clamp_i1_nxv4i32:
; CHECK: // %bb.0:
-; CHECK-NEXT: ptrue p0.s
-; CHECK-NEXT: cmpne p1.s, p0/z, z0.s, #0
-; CHECK-NEXT: mov z0.s, p1/z, #1 // =0x1
+; CHECK-NEXT: umin z0.s, z0.s, #1
; CHECK-NEXT: ret
%mask = icmp ne <vscale x 4 x i32> %a, zeroinitializer
%zext = zext <vscale x 4 x i1> %mask to <vscale x 4 x i32>
@@ -128,9 +122,7 @@ define <vscale x 4 x i32> @icmp_clamp_i1_nxv4i32(<vscale x 4 x i32> %a) {
define <vscale x 2 x i64> @icmp_clamp_i1_nxv2i64(<vscale x 2 x i64> %a) {
; CHECK-LABEL: icmp_clamp_i1_nxv2i64:
; CHECK: // %bb.0:
-; CHECK-NEXT: ptrue p0.d
-; CHECK-NEXT: cmpne p1.d, p0/z, z0.d, #0
-; CHECK-NEXT: mov z0.d, p1/z, #1 // =0x1
+; CHECK-NEXT: umin z0.d, z0.d, #1
; CHECK-NEXT: ret
%mask = icmp ne <vscale x 2 x i64> %a, zeroinitializer
%zext = zext <vscale x 2 x i1> %mask to <vscale x 2 x i64>
More information about the llvm-commits
mailing list