[llvm-branch-commits] [llvm] [DAG] Expand vp.*rem and vp.cttz.elts with non-vp nodes. (PR #217864)

Luke Lau via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Aug 21 09:03:07 PDT 2026


https://github.com/lukel97 updated https://github.com/llvm/llvm-project/pull/217864

>From c4429f1fba6244592fd2d8624d85baa4443ec8cc Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Thu, 20 Aug 2026 17:25:16 +0800
Subject: [PATCH] [DAG] Expand vp.*rem and vp.cttz.elts with non-vp nodes.

Trivial VP SDNodes will be removed in an upcoming patch. The division is still predicated so we avoid UB.
---
 .../SelectionDAG/LegalizeVectorOps.cpp        | 10 +++---
 .../CodeGen/SelectionDAG/TargetLowering.cpp   |  8 ++---
 llvm/test/CodeGen/VE/Vector/vp_srem.ll        | 36 ++++++++++++-------
 llvm/test/CodeGen/VE/Vector/vp_urem.ll        | 36 ++++++++++++-------
 4 files changed, 56 insertions(+), 34 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
index 44fc8c0d41172..f85e6e58b88c8 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
@@ -1831,14 +1831,14 @@ SDValue VectorLegalizer::ExpandVP_MERGE(SDNode *Node) {
 }
 
 SDValue VectorLegalizer::ExpandVP_REM(SDNode *Node) {
-  // Implement VP_SREM/UREM in terms of VP_SDIV/VP_UDIV, VP_MUL, VP_SUB.
+  // Implement VP_SREM/UREM in terms of VP_SDIV/VP_UDIV, MUL, SUB.
   EVT VT = Node->getValueType(0);
 
   unsigned DivOpc = Node->getOpcode() == ISD::VP_SREM ? ISD::VP_SDIV : ISD::VP_UDIV;
 
   if (!TLI.isOperationLegalOrCustom(DivOpc, VT) ||
-      !TLI.isOperationLegalOrCustom(ISD::VP_MUL, VT) ||
-      !TLI.isOperationLegalOrCustom(ISD::VP_SUB, VT))
+      !TLI.isOperationLegalOrCustom(ISD::MUL, VT) ||
+      !TLI.isOperationLegalOrCustom(ISD::SUB, VT))
     return SDValue();
 
   SDLoc DL(Node);
@@ -1850,8 +1850,8 @@ SDValue VectorLegalizer::ExpandVP_REM(SDNode *Node) {
 
   // X % Y -> X-X/Y*Y
   SDValue Div = DAG.getNode(DivOpc, DL, VT, Dividend, Divisor, Mask, EVL);
-  SDValue Mul = DAG.getNode(ISD::VP_MUL, DL, VT, Divisor, Div, Mask, EVL);
-  return DAG.getNode(ISD::VP_SUB, DL, VT, Dividend, Mul, Mask, EVL);
+  SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, Divisor, Div);
+  return DAG.getNode(ISD::SUB, DL, VT, Dividend, Mul);
 }
 
 SDValue VectorLegalizer::ExpandVP_FNEG(SDNode *Node) {
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index cca7cdad0e2c8..54faa7f252602 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -11185,7 +11185,7 @@ SDValue TargetLowering::expandVPCTTZElements(SDNode *N,
   // %cond = to_bool_vec %source
   // %splat = splat /*val=*/VL
   // %tz = step_vector
-  // %v = vp.select %cond, /*true=*/tz, /*false=*/%splat
+  // %v = select %cond, /*true=*/tz, /*false=*/%splat
   // %r = vp.reduce.umin %v
   SDLoc DL(N);
   SDValue Source = N->getOperand(0);
@@ -11201,15 +11201,13 @@ SDValue TargetLowering::expandVPCTTZElements(SDNode *N,
     SDValue AllZero = DAG.getConstant(0, DL, SrcVT);
     SrcVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1,
                              SrcVT.getVectorElementCount());
-    Source = DAG.getNode(ISD::VP_SETCC, DL, SrcVT, Source, AllZero,
-                         DAG.getCondCode(ISD::SETNE), Mask, EVL);
+    Source = DAG.getSetCC(DL, SrcVT, Source, AllZero, ISD::SETNE);
   }
 
   SDValue ExtEVL = DAG.getZExtOrTrunc(EVL, DL, ResVT);
   SDValue Splat = DAG.getSplat(ResVecVT, DL, ExtEVL);
   SDValue StepVec = DAG.getStepVector(DL, ResVecVT);
-  SDValue Select =
-      DAG.getNode(ISD::VP_SELECT, DL, ResVecVT, Source, StepVec, Splat, EVL);
+  SDValue Select = DAG.getSelect(DL, ResVecVT, Source, StepVec, Splat);
   return DAG.getNode(ISD::VP_REDUCE_UMIN, DL, ResVT, ExtEVL, Select, Mask, EVL);
 }
 
diff --git a/llvm/test/CodeGen/VE/Vector/vp_srem.ll b/llvm/test/CodeGen/VE/Vector/vp_srem.ll
index 4895b9cb699ae..2d2208c8b8378 100644
--- a/llvm/test/CodeGen/VE/Vector/vp_srem.ll
+++ b/llvm/test/CodeGen/VE/Vector/vp_srem.ll
@@ -9,8 +9,10 @@ define fastcc <256 x i32> @test_vp_srem_v256i32_vv(<256 x i32> %i0, <256 x i32>
 ; CHECK-NEXT:    and %s0, %s0, (32)0
 ; CHECK-NEXT:    lvl %s0
 ; CHECK-NEXT:    vdivs.w.sx %v2, %v0, %v1, %vm1
-; CHECK-NEXT:    vmuls.w.sx %v1, %v1, %v2, %vm1
-; CHECK-NEXT:    vsubs.w.sx %v0, %v0, %v1, %vm1
+; CHECK-NEXT:    lea %s0, 256
+; CHECK-NEXT:    lvl %s0
+; CHECK-NEXT:    vmuls.w.sx %v1, %v1, %v2
+; CHECK-NEXT:    vsubs.w.sx %v0, %v0, %v1
 ; CHECK-NEXT:    b.l.t (, %s10)
   %r0 = call <256 x i32> @llvm.vp.srem.v256i32(<256 x i32> %i0, <256 x i32> %i1, <256 x i1> %m, i32 %n)
   ret <256 x i32> %r0
@@ -23,8 +25,10 @@ define fastcc <256 x i32> @test_vp_srem_v256i32_rv(i32 %s0, <256 x i32> %i1, <25
 ; CHECK-NEXT:    and %s0, %s0, (32)0
 ; CHECK-NEXT:    lvl %s1
 ; CHECK-NEXT:    vdivs.w.sx %v1, %s0, %v0, %vm1
-; CHECK-NEXT:    vmuls.w.sx %v0, %v0, %v1, %vm1
-; CHECK-NEXT:    vsubs.w.sx %v0, %s0, %v0, %vm1
+; CHECK-NEXT:    lea %s1, 256
+; CHECK-NEXT:    lvl %s1
+; CHECK-NEXT:    vmuls.w.sx %v0, %v0, %v1
+; CHECK-NEXT:    vsubs.w.sx %v0, %s0, %v0
 ; CHECK-NEXT:    b.l.t (, %s10)
   %xins = insertelement <256 x i32> undef, i32 %s0, i32 0
   %i0 = shufflevector <256 x i32> %xins, <256 x i32> undef, <256 x i32> zeroinitializer
@@ -39,8 +43,10 @@ define fastcc <256 x i32> @test_vp_srem_v256i32_vr(<256 x i32> %i0, i32 %s1, <25
 ; CHECK-NEXT:    and %s0, %s0, (32)0
 ; CHECK-NEXT:    lvl %s1
 ; CHECK-NEXT:    vdivs.w.sx %v1, %v0, %s0, %vm1
-; CHECK-NEXT:    vmuls.w.sx %v1, %s0, %v1, %vm1
-; CHECK-NEXT:    vsubs.w.sx %v0, %v0, %v1, %vm1
+; CHECK-NEXT:    lea %s1, 256
+; CHECK-NEXT:    lvl %s1
+; CHECK-NEXT:    vmuls.w.sx %v1, %s0, %v1
+; CHECK-NEXT:    vsubs.w.sx %v0, %v0, %v1
 ; CHECK-NEXT:    b.l.t (, %s10)
   %yins = insertelement <256 x i32> undef, i32 %s1, i32 0
   %i1 = shufflevector <256 x i32> %yins, <256 x i32> undef, <256 x i32> zeroinitializer
@@ -57,8 +63,10 @@ define fastcc <256 x i64> @test_vp_int_v256i64_vv(<256 x i64> %i0, <256 x i64> %
 ; CHECK-NEXT:    and %s0, %s0, (32)0
 ; CHECK-NEXT:    lvl %s0
 ; CHECK-NEXT:    vdivs.l %v2, %v0, %v1, %vm1
-; CHECK-NEXT:    vmuls.l %v1, %v1, %v2, %vm1
-; CHECK-NEXT:    vsubs.l %v0, %v0, %v1, %vm1
+; CHECK-NEXT:    lea %s0, 256
+; CHECK-NEXT:    lvl %s0
+; CHECK-NEXT:    vmuls.l %v1, %v1, %v2
+; CHECK-NEXT:    vsubs.l %v0, %v0, %v1
 ; CHECK-NEXT:    b.l.t (, %s10)
   %r0 = call <256 x i64> @llvm.vp.srem.v256i64(<256 x i64> %i0, <256 x i64> %i1, <256 x i1> %m, i32 %n)
   ret <256 x i64> %r0
@@ -70,8 +78,10 @@ define fastcc <256 x i64> @test_vp_srem_v256i64_rv(i64 %s0, <256 x i64> %i1, <25
 ; CHECK-NEXT:    and %s1, %s1, (32)0
 ; CHECK-NEXT:    lvl %s1
 ; CHECK-NEXT:    vdivs.l %v1, %s0, %v0, %vm1
-; CHECK-NEXT:    vmuls.l %v0, %v0, %v1, %vm1
-; CHECK-NEXT:    vsubs.l %v0, %s0, %v0, %vm1
+; CHECK-NEXT:    lea %s1, 256
+; CHECK-NEXT:    lvl %s1
+; CHECK-NEXT:    vmuls.l %v0, %v0, %v1
+; CHECK-NEXT:    vsubs.l %v0, %s0, %v0
 ; CHECK-NEXT:    b.l.t (, %s10)
   %xins = insertelement <256 x i64> undef, i64 %s0, i32 0
   %i0 = shufflevector <256 x i64> %xins, <256 x i64> undef, <256 x i32> zeroinitializer
@@ -85,8 +95,10 @@ define fastcc <256 x i64> @test_vp_srem_v256i64_vr(<256 x i64> %i0, i64 %s1, <25
 ; CHECK-NEXT:    and %s1, %s1, (32)0
 ; CHECK-NEXT:    lvl %s1
 ; CHECK-NEXT:    vdivs.l %v1, %v0, %s0, %vm1
-; CHECK-NEXT:    vmuls.l %v1, %s0, %v1, %vm1
-; CHECK-NEXT:    vsubs.l %v0, %v0, %v1, %vm1
+; CHECK-NEXT:    lea %s1, 256
+; CHECK-NEXT:    lvl %s1
+; CHECK-NEXT:    vmuls.l %v1, %s0, %v1
+; CHECK-NEXT:    vsubs.l %v0, %v0, %v1
 ; CHECK-NEXT:    b.l.t (, %s10)
   %yins = insertelement <256 x i64> undef, i64 %s1, i32 0
   %i1 = shufflevector <256 x i64> %yins, <256 x i64> undef, <256 x i32> zeroinitializer
diff --git a/llvm/test/CodeGen/VE/Vector/vp_urem.ll b/llvm/test/CodeGen/VE/Vector/vp_urem.ll
index fc19f53abdfaa..3d61c62ecd4b7 100644
--- a/llvm/test/CodeGen/VE/Vector/vp_urem.ll
+++ b/llvm/test/CodeGen/VE/Vector/vp_urem.ll
@@ -9,8 +9,10 @@ define fastcc <256 x i32> @test_vp_urem_v256i32_vv(<256 x i32> %i0, <256 x i32>
 ; CHECK-NEXT:    and %s0, %s0, (32)0
 ; CHECK-NEXT:    lvl %s0
 ; CHECK-NEXT:    vdivu.w %v2, %v0, %v1, %vm1
-; CHECK-NEXT:    vmuls.w.sx %v1, %v1, %v2, %vm1
-; CHECK-NEXT:    vsubs.w.sx %v0, %v0, %v1, %vm1
+; CHECK-NEXT:    lea %s0, 256
+; CHECK-NEXT:    lvl %s0
+; CHECK-NEXT:    vmuls.w.sx %v1, %v1, %v2
+; CHECK-NEXT:    vsubs.w.sx %v0, %v0, %v1
 ; CHECK-NEXT:    b.l.t (, %s10)
   %r0 = call <256 x i32> @llvm.vp.urem.v256i32(<256 x i32> %i0, <256 x i32> %i1, <256 x i1> %m, i32 %n)
   ret <256 x i32> %r0
@@ -23,8 +25,10 @@ define fastcc <256 x i32> @test_vp_urem_v256i32_rv(i32 %s0, <256 x i32> %i1, <25
 ; CHECK-NEXT:    and %s0, %s0, (32)0
 ; CHECK-NEXT:    lvl %s1
 ; CHECK-NEXT:    vdivu.w %v1, %s0, %v0, %vm1
-; CHECK-NEXT:    vmuls.w.sx %v0, %v0, %v1, %vm1
-; CHECK-NEXT:    vsubs.w.sx %v0, %s0, %v0, %vm1
+; CHECK-NEXT:    lea %s1, 256
+; CHECK-NEXT:    lvl %s1
+; CHECK-NEXT:    vmuls.w.sx %v0, %v0, %v1
+; CHECK-NEXT:    vsubs.w.sx %v0, %s0, %v0
 ; CHECK-NEXT:    b.l.t (, %s10)
   %xins = insertelement <256 x i32> undef, i32 %s0, i32 0
   %i0 = shufflevector <256 x i32> %xins, <256 x i32> undef, <256 x i32> zeroinitializer
@@ -39,8 +43,10 @@ define fastcc <256 x i32> @test_vp_urem_v256i32_vr(<256 x i32> %i0, i32 %s1, <25
 ; CHECK-NEXT:    and %s0, %s0, (32)0
 ; CHECK-NEXT:    lvl %s1
 ; CHECK-NEXT:    vdivu.w %v1, %v0, %s0, %vm1
-; CHECK-NEXT:    vmuls.w.sx %v1, %s0, %v1, %vm1
-; CHECK-NEXT:    vsubs.w.sx %v0, %v0, %v1, %vm1
+; CHECK-NEXT:    lea %s1, 256
+; CHECK-NEXT:    lvl %s1
+; CHECK-NEXT:    vmuls.w.sx %v1, %s0, %v1
+; CHECK-NEXT:    vsubs.w.sx %v0, %v0, %v1
 ; CHECK-NEXT:    b.l.t (, %s10)
   %yins = insertelement <256 x i32> undef, i32 %s1, i32 0
   %i1 = shufflevector <256 x i32> %yins, <256 x i32> undef, <256 x i32> zeroinitializer
@@ -57,8 +63,10 @@ define fastcc <256 x i64> @test_vp_int_v256i64_vv(<256 x i64> %i0, <256 x i64> %
 ; CHECK-NEXT:    and %s0, %s0, (32)0
 ; CHECK-NEXT:    lvl %s0
 ; CHECK-NEXT:    vdivu.l %v2, %v0, %v1, %vm1
-; CHECK-NEXT:    vmuls.l %v1, %v1, %v2, %vm1
-; CHECK-NEXT:    vsubs.l %v0, %v0, %v1, %vm1
+; CHECK-NEXT:    lea %s0, 256
+; CHECK-NEXT:    lvl %s0
+; CHECK-NEXT:    vmuls.l %v1, %v1, %v2
+; CHECK-NEXT:    vsubs.l %v0, %v0, %v1
 ; CHECK-NEXT:    b.l.t (, %s10)
   %r0 = call <256 x i64> @llvm.vp.urem.v256i64(<256 x i64> %i0, <256 x i64> %i1, <256 x i1> %m, i32 %n)
   ret <256 x i64> %r0
@@ -70,8 +78,10 @@ define fastcc <256 x i64> @test_vp_urem_v256i64_rv(i64 %s0, <256 x i64> %i1, <25
 ; CHECK-NEXT:    and %s1, %s1, (32)0
 ; CHECK-NEXT:    lvl %s1
 ; CHECK-NEXT:    vdivu.l %v1, %s0, %v0, %vm1
-; CHECK-NEXT:    vmuls.l %v0, %v0, %v1, %vm1
-; CHECK-NEXT:    vsubs.l %v0, %s0, %v0, %vm1
+; CHECK-NEXT:    lea %s1, 256
+; CHECK-NEXT:    lvl %s1
+; CHECK-NEXT:    vmuls.l %v0, %v0, %v1
+; CHECK-NEXT:    vsubs.l %v0, %s0, %v0
 ; CHECK-NEXT:    b.l.t (, %s10)
   %xins = insertelement <256 x i64> undef, i64 %s0, i32 0
   %i0 = shufflevector <256 x i64> %xins, <256 x i64> undef, <256 x i32> zeroinitializer
@@ -85,8 +95,10 @@ define fastcc <256 x i64> @test_vp_urem_v256i64_vr(<256 x i64> %i0, i64 %s1, <25
 ; CHECK-NEXT:    and %s1, %s1, (32)0
 ; CHECK-NEXT:    lvl %s1
 ; CHECK-NEXT:    vdivu.l %v1, %v0, %s0, %vm1
-; CHECK-NEXT:    vmuls.l %v1, %s0, %v1, %vm1
-; CHECK-NEXT:    vsubs.l %v0, %v0, %v1, %vm1
+; CHECK-NEXT:    lea %s1, 256
+; CHECK-NEXT:    lvl %s1
+; CHECK-NEXT:    vmuls.l %v1, %s0, %v1
+; CHECK-NEXT:    vsubs.l %v0, %v0, %v1
 ; CHECK-NEXT:    b.l.t (, %s10)
   %yins = insertelement <256 x i64> undef, i64 %s1, i32 0
   %i1 = shufflevector <256 x i64> %yins, <256 x i64> undef, <256 x i32> zeroinitializer



More information about the llvm-branch-commits mailing list