[llvm] [DAGCombiner] Fold vector subtraction if above threshold to `umin` (PR #148834)
Piotr Fusik via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 15 06:06:40 PDT 2025
https://github.com/pfusik updated https://github.com/llvm/llvm-project/pull/148834
>From a4a2e41807053acfd5f300ff033a7116b4706059 Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Tue, 15 Jul 2025 14:02:09 +0200
Subject: [PATCH 1/4] [RISCV][test] Add tests for vector subtraction if above
threshold
---
llvm/test/CodeGen/RISCV/rvv/vminu-sdnode.ll | 108 ++++++++++++++++++++
1 file changed, 108 insertions(+)
diff --git a/llvm/test/CodeGen/RISCV/rvv/vminu-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vminu-sdnode.ll
index e3b2d6c1efe1f..b8307c2f40318 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vminu-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vminu-sdnode.ll
@@ -893,3 +893,111 @@ define <vscale x 8 x i32> @vmin_vi_mask_nxv8i32(<vscale x 8 x i32> %va, <vscale
%vc = select <vscale x 8 x i1> %cmp, <vscale x 8 x i32> %va, <vscale x 8 x i32> %vs
ret <vscale x 8 x i32> %vc
}
+
+define <vscale x 2 x i8> @vsub_if_uge_nxv2i8(<vscale x 2 x i8> %va, <vscale x 2 x i8> %vb) {
+; CHECK-LABEL: vsub_if_uge_nxv2i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e8, mf4, ta, ma
+; CHECK-NEXT: vmsltu.vv v0, v8, v9
+; CHECK-NEXT: vsub.vv v9, v8, v9
+; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
+; CHECK-NEXT: ret
+ %cmp = icmp ult <vscale x 2 x i8> %va, %vb
+ %select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i8> zeroinitializer, <vscale x 2 x i8> %vb
+ %sub = sub nuw <vscale x 2 x i8> %va, %select
+ ret <vscale x 2 x i8> %sub
+}
+
+define <vscale x 2 x i8> @vsub_if_uge_swapped_nxv2i8(<vscale x 2 x i8> %va, <vscale x 2 x i8> %vb) {
+; CHECK-LABEL: vsub_if_uge_swapped_nxv2i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e8, mf4, ta, mu
+; CHECK-NEXT: vmsleu.vv v0, v9, v8
+; CHECK-NEXT: vsub.vv v8, v8, v9, v0.t
+; CHECK-NEXT: ret
+ %cmp = icmp uge <vscale x 2 x i8> %va, %vb
+ %select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i8> %vb, <vscale x 2 x i8> zeroinitializer
+ %sub = sub nuw <vscale x 2 x i8> %va, %select
+ ret <vscale x 2 x i8> %sub
+}
+
+define <vscale x 2 x i16> @vsub_if_uge_nxv2i16(<vscale x 2 x i16> %va, <vscale x 2 x i16> %vb) {
+; CHECK-LABEL: vsub_if_uge_nxv2i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e16, mf2, ta, ma
+; CHECK-NEXT: vmsltu.vv v0, v8, v9
+; CHECK-NEXT: vsub.vv v9, v8, v9
+; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
+; CHECK-NEXT: ret
+ %cmp = icmp ult <vscale x 2 x i16> %va, %vb
+ %select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i16> zeroinitializer, <vscale x 2 x i16> %vb
+ %sub = sub nuw <vscale x 2 x i16> %va, %select
+ ret <vscale x 2 x i16> %sub
+}
+
+define <vscale x 2 x i16> @vsub_if_uge_swapped_nxv2i16(<vscale x 2 x i16> %va, <vscale x 2 x i16> %vb) {
+; CHECK-LABEL: vsub_if_uge_swapped_nxv2i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e16, mf2, ta, mu
+; CHECK-NEXT: vmsleu.vv v0, v9, v8
+; CHECK-NEXT: vsub.vv v8, v8, v9, v0.t
+; CHECK-NEXT: ret
+ %cmp = icmp uge <vscale x 2 x i16> %va, %vb
+ %select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i16> %vb, <vscale x 2 x i16> zeroinitializer
+ %sub = sub nuw <vscale x 2 x i16> %va, %select
+ ret <vscale x 2 x i16> %sub
+}
+
+define <vscale x 2 x i32> @vsub_if_uge_nxv2i32(<vscale x 2 x i32> %va, <vscale x 2 x i32> %vb) {
+; CHECK-LABEL: vsub_if_uge_nxv2i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, ma
+; CHECK-NEXT: vmsltu.vv v0, v8, v9
+; CHECK-NEXT: vsub.vv v9, v8, v9
+; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
+; CHECK-NEXT: ret
+ %cmp = icmp ult <vscale x 2 x i32> %va, %vb
+ %select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i32> zeroinitializer, <vscale x 2 x i32> %vb
+ %sub = sub nuw <vscale x 2 x i32> %va, %select
+ ret <vscale x 2 x i32> %sub
+}
+
+define <vscale x 2 x i32> @vsub_if_uge_swapped_nxv2i32(<vscale x 2 x i32> %va, <vscale x 2 x i32> %vb) {
+; CHECK-LABEL: vsub_if_uge_swapped_nxv2i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, mu
+; CHECK-NEXT: vmsleu.vv v0, v9, v8
+; CHECK-NEXT: vsub.vv v8, v8, v9, v0.t
+; CHECK-NEXT: ret
+ %cmp = icmp uge <vscale x 2 x i32> %va, %vb
+ %select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i32> %vb, <vscale x 2 x i32> zeroinitializer
+ %sub = sub nuw <vscale x 2 x i32> %va, %select
+ ret <vscale x 2 x i32> %sub
+}
+
+define <vscale x 2 x i64> @vsub_if_uge_nxv2i64(<vscale x 2 x i64> %va, <vscale x 2 x i64> %vb) {
+; CHECK-LABEL: vsub_if_uge_nxv2i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e64, m2, ta, ma
+; CHECK-NEXT: vmsltu.vv v0, v8, v10
+; CHECK-NEXT: vsub.vv v10, v8, v10
+; CHECK-NEXT: vmerge.vvm v8, v10, v8, v0
+; CHECK-NEXT: ret
+ %cmp = icmp ult <vscale x 2 x i64> %va, %vb
+ %select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i64> zeroinitializer, <vscale x 2 x i64> %vb
+ %sub = sub nuw <vscale x 2 x i64> %va, %select
+ ret <vscale x 2 x i64> %sub
+}
+
+define <vscale x 2 x i64> @vsub_if_uge_swapped_nxv2i64(<vscale x 2 x i64> %va, <vscale x 2 x i64> %vb) {
+; CHECK-LABEL: vsub_if_uge_swapped_nxv2i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e64, m2, ta, mu
+; CHECK-NEXT: vmsleu.vv v0, v10, v8
+; CHECK-NEXT: vsub.vv v8, v8, v10, v0.t
+; CHECK-NEXT: ret
+ %cmp = icmp uge <vscale x 2 x i64> %va, %vb
+ %select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i64> %vb, <vscale x 2 x i64> zeroinitializer
+ %sub = sub nuw <vscale x 2 x i64> %va, %select
+ ret <vscale x 2 x i64> %sub
+}
>From aade972714d0cfc595dae5d7fa2d91c1cd9f3552 Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Tue, 15 Jul 2025 14:02:21 +0200
Subject: [PATCH 2/4] [DAGCombiner] Fold vector subtraction if above threshold
to `umin`
This extends #134235 to vectors.
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 34 ++++++++++--------
llvm/test/CodeGen/RISCV/rvv/vminu-sdnode.ll | 36 +++++++++----------
2 files changed, 36 insertions(+), 34 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 23812d795f5fa..27e9b3ccc47e3 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -4093,6 +4093,26 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
return N0;
}
+ // (sub x, ([v]select (ult x, y), 0, y)) -> (umin x, (sub x, y))
+ // (sub x, ([v]select (uge x, y), y, 0)) -> (umin x, (sub x, y))
+ if (N1.hasOneUse() && hasUMin(VT)) {
+ SDValue Y;
+ if (sd_match(N1, m_Select(m_SetCC(m_Specific(N0), m_Value(Y),
+ m_SpecificCondCode(ISD::SETULT)),
+ m_Zero(), m_Deferred(Y))) ||
+ sd_match(N1, m_Select(m_SetCC(m_Specific(N0), m_Value(Y),
+ m_SpecificCondCode(ISD::SETUGE)),
+ m_Deferred(Y), m_Zero())) ||
+ sd_match(N1, m_VSelect(m_SetCC(m_Specific(N0), m_Value(Y),
+ m_SpecificCondCode(ISD::SETULT)),
+ m_Zero(), m_Deferred(Y))) ||
+ sd_match(N1, m_VSelect(m_SetCC(m_Specific(N0), m_Value(Y),
+ m_SpecificCondCode(ISD::SETUGE)),
+ m_Deferred(Y), m_Zero())))
+ return DAG.getNode(ISD::UMIN, DL, VT, N0,
+ DAG.getNode(ISD::SUB, DL, VT, N0, Y));
+ }
+
if (SDValue NewSel = foldBinOpIntoSelect(N))
return NewSel;
@@ -4442,20 +4462,6 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
sd_match(N1, m_UMaxLike(m_Specific(A), m_Specific(B))))
return DAG.getNegative(DAG.getNode(ISD::ABDU, DL, VT, A, B), DL, VT);
- // (sub x, (select (ult x, y), 0, y)) -> (umin x, (sub x, y))
- // (sub x, (select (uge x, y), y, 0)) -> (umin x, (sub x, y))
- if (hasUMin(VT)) {
- SDValue Y;
- if (sd_match(N1, m_OneUse(m_Select(m_SetCC(m_Specific(N0), m_Value(Y),
- m_SpecificCondCode(ISD::SETULT)),
- m_Zero(), m_Deferred(Y)))) ||
- sd_match(N1, m_OneUse(m_Select(m_SetCC(m_Specific(N0), m_Value(Y),
- m_SpecificCondCode(ISD::SETUGE)),
- m_Deferred(Y), m_Zero()))))
- return DAG.getNode(ISD::UMIN, DL, VT, N0,
- DAG.getNode(ISD::SUB, DL, VT, N0, Y));
- }
-
return SDValue();
}
diff --git a/llvm/test/CodeGen/RISCV/rvv/vminu-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vminu-sdnode.ll
index b8307c2f40318..98bfa8d359e21 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vminu-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vminu-sdnode.ll
@@ -898,9 +898,8 @@ define <vscale x 2 x i8> @vsub_if_uge_nxv2i8(<vscale x 2 x i8> %va, <vscale x 2
; CHECK-LABEL: vsub_if_uge_nxv2i8:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetvli a0, zero, e8, mf4, ta, ma
-; CHECK-NEXT: vmsltu.vv v0, v8, v9
; CHECK-NEXT: vsub.vv v9, v8, v9
-; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
+; CHECK-NEXT: vminu.vv v8, v8, v9
; CHECK-NEXT: ret
%cmp = icmp ult <vscale x 2 x i8> %va, %vb
%select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i8> zeroinitializer, <vscale x 2 x i8> %vb
@@ -911,9 +910,9 @@ define <vscale x 2 x i8> @vsub_if_uge_nxv2i8(<vscale x 2 x i8> %va, <vscale x 2
define <vscale x 2 x i8> @vsub_if_uge_swapped_nxv2i8(<vscale x 2 x i8> %va, <vscale x 2 x i8> %vb) {
; CHECK-LABEL: vsub_if_uge_swapped_nxv2i8:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetvli a0, zero, e8, mf4, ta, mu
-; CHECK-NEXT: vmsleu.vv v0, v9, v8
-; CHECK-NEXT: vsub.vv v8, v8, v9, v0.t
+; CHECK-NEXT: vsetvli a0, zero, e8, mf4, ta, ma
+; CHECK-NEXT: vsub.vv v9, v8, v9
+; CHECK-NEXT: vminu.vv v8, v8, v9
; CHECK-NEXT: ret
%cmp = icmp uge <vscale x 2 x i8> %va, %vb
%select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i8> %vb, <vscale x 2 x i8> zeroinitializer
@@ -925,9 +924,8 @@ define <vscale x 2 x i16> @vsub_if_uge_nxv2i16(<vscale x 2 x i16> %va, <vscale x
; CHECK-LABEL: vsub_if_uge_nxv2i16:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetvli a0, zero, e16, mf2, ta, ma
-; CHECK-NEXT: vmsltu.vv v0, v8, v9
; CHECK-NEXT: vsub.vv v9, v8, v9
-; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
+; CHECK-NEXT: vminu.vv v8, v8, v9
; CHECK-NEXT: ret
%cmp = icmp ult <vscale x 2 x i16> %va, %vb
%select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i16> zeroinitializer, <vscale x 2 x i16> %vb
@@ -938,9 +936,9 @@ define <vscale x 2 x i16> @vsub_if_uge_nxv2i16(<vscale x 2 x i16> %va, <vscale x
define <vscale x 2 x i16> @vsub_if_uge_swapped_nxv2i16(<vscale x 2 x i16> %va, <vscale x 2 x i16> %vb) {
; CHECK-LABEL: vsub_if_uge_swapped_nxv2i16:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetvli a0, zero, e16, mf2, ta, mu
-; CHECK-NEXT: vmsleu.vv v0, v9, v8
-; CHECK-NEXT: vsub.vv v8, v8, v9, v0.t
+; CHECK-NEXT: vsetvli a0, zero, e16, mf2, ta, ma
+; CHECK-NEXT: vsub.vv v9, v8, v9
+; CHECK-NEXT: vminu.vv v8, v8, v9
; CHECK-NEXT: ret
%cmp = icmp uge <vscale x 2 x i16> %va, %vb
%select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i16> %vb, <vscale x 2 x i16> zeroinitializer
@@ -952,9 +950,8 @@ define <vscale x 2 x i32> @vsub_if_uge_nxv2i32(<vscale x 2 x i32> %va, <vscale x
; CHECK-LABEL: vsub_if_uge_nxv2i32:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, ma
-; CHECK-NEXT: vmsltu.vv v0, v8, v9
; CHECK-NEXT: vsub.vv v9, v8, v9
-; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
+; CHECK-NEXT: vminu.vv v8, v8, v9
; CHECK-NEXT: ret
%cmp = icmp ult <vscale x 2 x i32> %va, %vb
%select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i32> zeroinitializer, <vscale x 2 x i32> %vb
@@ -965,9 +962,9 @@ define <vscale x 2 x i32> @vsub_if_uge_nxv2i32(<vscale x 2 x i32> %va, <vscale x
define <vscale x 2 x i32> @vsub_if_uge_swapped_nxv2i32(<vscale x 2 x i32> %va, <vscale x 2 x i32> %vb) {
; CHECK-LABEL: vsub_if_uge_swapped_nxv2i32:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, mu
-; CHECK-NEXT: vmsleu.vv v0, v9, v8
-; CHECK-NEXT: vsub.vv v8, v8, v9, v0.t
+; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, ma
+; CHECK-NEXT: vsub.vv v9, v8, v9
+; CHECK-NEXT: vminu.vv v8, v8, v9
; CHECK-NEXT: ret
%cmp = icmp uge <vscale x 2 x i32> %va, %vb
%select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i32> %vb, <vscale x 2 x i32> zeroinitializer
@@ -979,9 +976,8 @@ define <vscale x 2 x i64> @vsub_if_uge_nxv2i64(<vscale x 2 x i64> %va, <vscale x
; CHECK-LABEL: vsub_if_uge_nxv2i64:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetvli a0, zero, e64, m2, ta, ma
-; CHECK-NEXT: vmsltu.vv v0, v8, v10
; CHECK-NEXT: vsub.vv v10, v8, v10
-; CHECK-NEXT: vmerge.vvm v8, v10, v8, v0
+; CHECK-NEXT: vminu.vv v8, v8, v10
; CHECK-NEXT: ret
%cmp = icmp ult <vscale x 2 x i64> %va, %vb
%select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i64> zeroinitializer, <vscale x 2 x i64> %vb
@@ -992,9 +988,9 @@ define <vscale x 2 x i64> @vsub_if_uge_nxv2i64(<vscale x 2 x i64> %va, <vscale x
define <vscale x 2 x i64> @vsub_if_uge_swapped_nxv2i64(<vscale x 2 x i64> %va, <vscale x 2 x i64> %vb) {
; CHECK-LABEL: vsub_if_uge_swapped_nxv2i64:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetvli a0, zero, e64, m2, ta, mu
-; CHECK-NEXT: vmsleu.vv v0, v10, v8
-; CHECK-NEXT: vsub.vv v8, v8, v10, v0.t
+; CHECK-NEXT: vsetvli a0, zero, e64, m2, ta, ma
+; CHECK-NEXT: vsub.vv v10, v8, v10
+; CHECK-NEXT: vminu.vv v8, v8, v10
; CHECK-NEXT: ret
%cmp = icmp uge <vscale x 2 x i64> %va, %vb
%select = select <vscale x 2 x i1> %cmp, <vscale x 2 x i64> %vb, <vscale x 2 x i64> zeroinitializer
>From 83a360154d624452d9e9a2ec6293c357f1935b1a Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Tue, 15 Jul 2025 15:02:38 +0200
Subject: [PATCH 3/4] [RISCV][test] Add tests for fixed vector subtraction if
above threshold
---
.../CodeGen/RISCV/rvv/fixed-vectors-int.ll | 108 ++++++++++++++++++
1 file changed, 108 insertions(+)
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll
index 0c30cbe4a42ef..00f4e95397b59 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll
@@ -5707,3 +5707,111 @@ define void @msub_vv_v2i64_2(ptr %x, <2 x i64> %y) {
store <2 x i64> %c, ptr %x
ret void
}
+
+define <8 x i8> @vsub_if_uge_v8i8(<8 x i8> %va, <8 x i8> %vb) {
+; CHECK-LABEL: vsub_if_uge_v8i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-NEXT: vmsltu.vv v0, v8, v9
+; CHECK-NEXT: vsub.vv v9, v8, v9
+; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
+; CHECK-NEXT: ret
+ %cmp = icmp ult <8 x i8> %va, %vb
+ %select = select <8 x i1> %cmp, <8 x i8> zeroinitializer, <8 x i8> %vb
+ %sub = sub nuw <8 x i8> %va, %select
+ ret <8 x i8> %sub
+}
+
+define <8 x i8> @vsub_if_uge_swapped_v8i8(<8 x i8> %va, <8 x i8> %vb) {
+; CHECK-LABEL: vsub_if_uge_swapped_v8i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, mu
+; CHECK-NEXT: vmsleu.vv v0, v9, v8
+; CHECK-NEXT: vsub.vv v8, v8, v9, v0.t
+; CHECK-NEXT: ret
+ %cmp = icmp uge <8 x i8> %va, %vb
+ %select = select <8 x i1> %cmp, <8 x i8> %vb, <8 x i8> zeroinitializer
+ %sub = sub nuw <8 x i8> %va, %select
+ ret <8 x i8> %sub
+}
+
+define <8 x i16> @vsub_if_uge_v8i16(<8 x i16> %va, <8 x i16> %vb) {
+; CHECK-LABEL: vsub_if_uge_v8i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma
+; CHECK-NEXT: vmsltu.vv v0, v8, v9
+; CHECK-NEXT: vsub.vv v9, v8, v9
+; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
+; CHECK-NEXT: ret
+ %cmp = icmp ult <8 x i16> %va, %vb
+ %select = select <8 x i1> %cmp, <8 x i16> zeroinitializer, <8 x i16> %vb
+ %sub = sub nuw <8 x i16> %va, %select
+ ret <8 x i16> %sub
+}
+
+define <8 x i16> @vsub_if_uge_swapped_v8i16(<8 x i16> %va, <8 x i16> %vb) {
+; CHECK-LABEL: vsub_if_uge_swapped_v8i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, mu
+; CHECK-NEXT: vmsleu.vv v0, v9, v8
+; CHECK-NEXT: vsub.vv v8, v8, v9, v0.t
+; CHECK-NEXT: ret
+ %cmp = icmp uge <8 x i16> %va, %vb
+ %select = select <8 x i1> %cmp, <8 x i16> %vb, <8 x i16> zeroinitializer
+ %sub = sub nuw <8 x i16> %va, %select
+ ret <8 x i16> %sub
+}
+
+define <4 x i32> @vsub_if_uge_v4i32(<4 x i32> %va, <4 x i32> %vb) {
+; CHECK-LABEL: vsub_if_uge_v4i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; CHECK-NEXT: vmsltu.vv v0, v8, v9
+; CHECK-NEXT: vsub.vv v9, v8, v9
+; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
+; CHECK-NEXT: ret
+ %cmp = icmp ult <4 x i32> %va, %vb
+ %select = select <4 x i1> %cmp, <4 x i32> zeroinitializer, <4 x i32> %vb
+ %sub = sub nuw <4 x i32> %va, %select
+ ret <4 x i32> %sub
+}
+
+define <4 x i32> @vsub_if_uge_swapped_v4i32(<4 x i32> %va, <4 x i32> %vb) {
+; CHECK-LABEL: vsub_if_uge_swapped_v4i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu
+; CHECK-NEXT: vmsleu.vv v0, v9, v8
+; CHECK-NEXT: vsub.vv v8, v8, v9, v0.t
+; CHECK-NEXT: ret
+ %cmp = icmp uge <4 x i32> %va, %vb
+ %select = select <4 x i1> %cmp, <4 x i32> %vb, <4 x i32> zeroinitializer
+ %sub = sub nuw <4 x i32> %va, %select
+ ret <4 x i32> %sub
+}
+
+define <2 x i64> @vsub_if_uge_v2i64(<2 x i64> %va, <2 x i64> %vb) {
+; CHECK-LABEL: vsub_if_uge_v2i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma
+; CHECK-NEXT: vmsltu.vv v0, v8, v9
+; CHECK-NEXT: vsub.vv v9, v8, v9
+; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
+; CHECK-NEXT: ret
+ %cmp = icmp ult <2 x i64> %va, %vb
+ %select = select <2 x i1> %cmp, <2 x i64> zeroinitializer, <2 x i64> %vb
+ %sub = sub nuw <2 x i64> %va, %select
+ ret <2 x i64> %sub
+}
+
+define <2 x i64> @vsub_if_uge_swapped_v2i64(<2 x i64> %va, <2 x i64> %vb) {
+; CHECK-LABEL: vsub_if_uge_swapped_v2i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, mu
+; CHECK-NEXT: vmsleu.vv v0, v9, v8
+; CHECK-NEXT: vsub.vv v8, v8, v9, v0.t
+; CHECK-NEXT: ret
+ %cmp = icmp uge <2 x i64> %va, %vb
+ %select = select <2 x i1> %cmp, <2 x i64> %vb, <2 x i64> zeroinitializer
+ %sub = sub nuw <2 x i64> %va, %select
+ ret <2 x i64> %sub
+}
>From 10d2ac704dd3e67d36a97a3adc6861a010f37929 Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Tue, 15 Jul 2025 15:04:33 +0200
Subject: [PATCH 4/4] [DAGCombiner] Include custom `umin`
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 2 +-
.../CodeGen/RISCV/rvv/fixed-vectors-int.ll | 36 +++++++++----------
2 files changed, 17 insertions(+), 21 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 27e9b3ccc47e3..120ac25d6ecaf 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -859,7 +859,7 @@ namespace {
auto LK = TLI.getTypeConversion(*DAG.getContext(), VT);
return (LK.first == TargetLoweringBase::TypeLegal ||
LK.first == TargetLoweringBase::TypePromoteInteger) &&
- TLI.isOperationLegal(ISD::UMIN, LK.second);
+ TLI.isOperationLegalOrCustom(ISD::UMIN, LK.second);
}
public:
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll
index 00f4e95397b59..66ddcbc995281 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll
@@ -5712,9 +5712,8 @@ define <8 x i8> @vsub_if_uge_v8i8(<8 x i8> %va, <8 x i8> %vb) {
; CHECK-LABEL: vsub_if_uge_v8i8:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmsltu.vv v0, v8, v9
; CHECK-NEXT: vsub.vv v9, v8, v9
-; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
+; CHECK-NEXT: vminu.vv v8, v8, v9
; CHECK-NEXT: ret
%cmp = icmp ult <8 x i8> %va, %vb
%select = select <8 x i1> %cmp, <8 x i8> zeroinitializer, <8 x i8> %vb
@@ -5725,9 +5724,9 @@ define <8 x i8> @vsub_if_uge_v8i8(<8 x i8> %va, <8 x i8> %vb) {
define <8 x i8> @vsub_if_uge_swapped_v8i8(<8 x i8> %va, <8 x i8> %vb) {
; CHECK-LABEL: vsub_if_uge_swapped_v8i8:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, mu
-; CHECK-NEXT: vmsleu.vv v0, v9, v8
-; CHECK-NEXT: vsub.vv v8, v8, v9, v0.t
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-NEXT: vsub.vv v9, v8, v9
+; CHECK-NEXT: vminu.vv v8, v8, v9
; CHECK-NEXT: ret
%cmp = icmp uge <8 x i8> %va, %vb
%select = select <8 x i1> %cmp, <8 x i8> %vb, <8 x i8> zeroinitializer
@@ -5739,9 +5738,8 @@ define <8 x i16> @vsub_if_uge_v8i16(<8 x i16> %va, <8 x i16> %vb) {
; CHECK-LABEL: vsub_if_uge_v8i16:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma
-; CHECK-NEXT: vmsltu.vv v0, v8, v9
; CHECK-NEXT: vsub.vv v9, v8, v9
-; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
+; CHECK-NEXT: vminu.vv v8, v8, v9
; CHECK-NEXT: ret
%cmp = icmp ult <8 x i16> %va, %vb
%select = select <8 x i1> %cmp, <8 x i16> zeroinitializer, <8 x i16> %vb
@@ -5752,9 +5750,9 @@ define <8 x i16> @vsub_if_uge_v8i16(<8 x i16> %va, <8 x i16> %vb) {
define <8 x i16> @vsub_if_uge_swapped_v8i16(<8 x i16> %va, <8 x i16> %vb) {
; CHECK-LABEL: vsub_if_uge_swapped_v8i16:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, mu
-; CHECK-NEXT: vmsleu.vv v0, v9, v8
-; CHECK-NEXT: vsub.vv v8, v8, v9, v0.t
+; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma
+; CHECK-NEXT: vsub.vv v9, v8, v9
+; CHECK-NEXT: vminu.vv v8, v8, v9
; CHECK-NEXT: ret
%cmp = icmp uge <8 x i16> %va, %vb
%select = select <8 x i1> %cmp, <8 x i16> %vb, <8 x i16> zeroinitializer
@@ -5766,9 +5764,8 @@ define <4 x i32> @vsub_if_uge_v4i32(<4 x i32> %va, <4 x i32> %vb) {
; CHECK-LABEL: vsub_if_uge_v4i32:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
-; CHECK-NEXT: vmsltu.vv v0, v8, v9
; CHECK-NEXT: vsub.vv v9, v8, v9
-; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
+; CHECK-NEXT: vminu.vv v8, v8, v9
; CHECK-NEXT: ret
%cmp = icmp ult <4 x i32> %va, %vb
%select = select <4 x i1> %cmp, <4 x i32> zeroinitializer, <4 x i32> %vb
@@ -5779,9 +5776,9 @@ define <4 x i32> @vsub_if_uge_v4i32(<4 x i32> %va, <4 x i32> %vb) {
define <4 x i32> @vsub_if_uge_swapped_v4i32(<4 x i32> %va, <4 x i32> %vb) {
; CHECK-LABEL: vsub_if_uge_swapped_v4i32:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu
-; CHECK-NEXT: vmsleu.vv v0, v9, v8
-; CHECK-NEXT: vsub.vv v8, v8, v9, v0.t
+; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; CHECK-NEXT: vsub.vv v9, v8, v9
+; CHECK-NEXT: vminu.vv v8, v8, v9
; CHECK-NEXT: ret
%cmp = icmp uge <4 x i32> %va, %vb
%select = select <4 x i1> %cmp, <4 x i32> %vb, <4 x i32> zeroinitializer
@@ -5793,9 +5790,8 @@ define <2 x i64> @vsub_if_uge_v2i64(<2 x i64> %va, <2 x i64> %vb) {
; CHECK-LABEL: vsub_if_uge_v2i64:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma
-; CHECK-NEXT: vmsltu.vv v0, v8, v9
; CHECK-NEXT: vsub.vv v9, v8, v9
-; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
+; CHECK-NEXT: vminu.vv v8, v8, v9
; CHECK-NEXT: ret
%cmp = icmp ult <2 x i64> %va, %vb
%select = select <2 x i1> %cmp, <2 x i64> zeroinitializer, <2 x i64> %vb
@@ -5806,9 +5802,9 @@ define <2 x i64> @vsub_if_uge_v2i64(<2 x i64> %va, <2 x i64> %vb) {
define <2 x i64> @vsub_if_uge_swapped_v2i64(<2 x i64> %va, <2 x i64> %vb) {
; CHECK-LABEL: vsub_if_uge_swapped_v2i64:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, mu
-; CHECK-NEXT: vmsleu.vv v0, v9, v8
-; CHECK-NEXT: vsub.vv v8, v8, v9, v0.t
+; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma
+; CHECK-NEXT: vsub.vv v9, v8, v9
+; CHECK-NEXT: vminu.vv v8, v8, v9
; CHECK-NEXT: ret
%cmp = icmp uge <2 x i64> %va, %vb
%select = select <2 x i1> %cmp, <2 x i64> %vb, <2 x i64> zeroinitializer
More information about the llvm-commits
mailing list