Skip to content

[RISCV] Try to optimize vp.splice to vslide1up. #144871

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

NexMing
Copy link
Contributor

@NexMing NexMing commented Jun 19, 2025

Fold (vp.splice (insert_elt poison, scalar, 0), vec, 0, mask, 1, vl)
to (vslide1up vec, scalar, mask, vl).

Fold (vp.splice (splat_vector scalar), vec, 0, mask, 1, vl)
to (vslide1up vec, scalar, mask, vl).

@llvmbot
Copy link
Member

llvmbot commented Jun 19, 2025

@llvm/pr-subscribers-backend-risc-v

Author: Ming Yan (NexMing)

Changes

Fold (vslideup_vl/vslidedown_vl undef, vec, 0, mask, vl, policy)
-> (vec)

Fold (vslideup_vl (insert_ele poison, first, 0), vec, 1, mask, vl, policy)
-> (vslide1up_vl/vfslide1up_vl undef, vec, first, mask, vl)


Full diff: https://github.com/llvm/llvm-project/pull/144871.diff

4 Files Affected:

  • (modified) llvm/include/llvm/CodeGen/SDPatternMatch.h (+2)
  • (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+33)
  • (modified) llvm/test/CodeGen/RISCV/rvv/vp-splice.ll (+24)
  • (modified) llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp (+5)
diff --git a/llvm/include/llvm/CodeGen/SDPatternMatch.h b/llvm/include/llvm/CodeGen/SDPatternMatch.h
index d413227c4d961..9eb6dd45f912f 100644
--- a/llvm/include/llvm/CodeGen/SDPatternMatch.h
+++ b/llvm/include/llvm/CodeGen/SDPatternMatch.h
@@ -142,6 +142,8 @@ inline Opcode_match m_Opc(unsigned Opcode) { return Opcode_match(Opcode); }
 
 inline Opcode_match m_Undef() { return Opcode_match(ISD::UNDEF); }
 
+inline Opcode_match m_Poison() { return Opcode_match(ISD::POISON); }
+
 template <unsigned NumUses, typename Pattern> struct NUses_match {
   Pattern P;
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index b8ef221742a26..c17af90c57c93 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -17601,6 +17601,36 @@ static SDValue performFP_TO_INT_SATCombine(SDNode *N,
   return DAG.getSelectCC(DL, Src, Src, ZeroInt, FpToInt, ISD::CondCode::SETUO);
 }
 
+static SDValue performVSLIDEUPOrDOWNCombine(SDNode *N, SelectionDAG &DAG) {
+  assert((N->getOpcode() == RISCVISD::VSLIDEUP_VL ||
+          N->getOpcode() == RISCVISD::VSLIDEDOWN_VL) &&
+         "Unexpected opcode");
+
+  using namespace SDPatternMatch;
+
+  SDLoc DL(N);
+  SDValue Vec;
+  // (vslideup_vl/vslidedown_vl undef, vec, 0, mask, vl, policy) -> (vec)
+  if (sd_match(N, m_Node(N->getOpcode(), m_Undef(), m_Value(Vec), m_Zero(),
+                         m_Value(), m_Value(), m_Value())))
+    return Vec;
+
+  SDValue FirstEle, Mask, VL;
+  //    (vslideup_vl (insert_ele poison first, 0), vec, 1, mask, vl, policy)
+  // -> (vslide1up_vl/vfslide1up_vl undef, vec, first, mask, vl)
+  if (sd_match(N, m_Node(RISCVISD::VSLIDEUP_VL,
+                         m_InsertElt(m_Poison(), m_Value(FirstEle), m_Zero()),
+                         m_Value(Vec), m_One(), m_Value(Mask), m_Value(VL),
+                         m_Value()))) {
+    EVT VT = Vec.getValueType();
+    return DAG.getNode(VT.isFloatingPoint() ? RISCVISD::VFSLIDE1UP_VL
+                                            : RISCVISD::VSLIDE1UP_VL,
+                       DL, VT, DAG.getUNDEF(VT), Vec, FirstEle, Mask, VL);
+  }
+
+  return SDValue();
+}
+
 // Combine (bitreverse (bswap X)) to the BREV8 GREVI encoding if the type is
 // smaller than XLenVT.
 static SDValue performBITREVERSECombine(SDNode *N, SelectionDAG &DAG,
@@ -19881,6 +19911,9 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
 
     return SDValue();
   }
+  case RISCVISD::VSLIDEUP_VL:
+  case RISCVISD::VSLIDEDOWN_VL:
+    return performVSLIDEUPOrDOWNCombine(N, DAG);
   case ISD::BITREVERSE:
     return performBITREVERSECombine(N, DAG, Subtarget);
   case ISD::FP_TO_SINT:
diff --git a/llvm/test/CodeGen/RISCV/rvv/vp-splice.ll b/llvm/test/CodeGen/RISCV/rvv/vp-splice.ll
index a4f91c3e7c99e..f0ff6d622cef5 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vp-splice.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vp-splice.ll
@@ -286,3 +286,27 @@ define <vscale x 2 x float> @test_vp_splice_nxv2f32_masked(<vscale x 2 x float>
   %v = call <vscale x 2 x float> @llvm.experimental.vp.splice.nxv2f32(<vscale x 2 x float> %va, <vscale x 2 x float> %vb, i32 5, <vscale x 2 x i1> %mask, i32 %evla, i32 %evlb)
   ret <vscale x 2 x float> %v
 }
+
+define <vscale x 2 x i32> @test_vp_splice_nxv2i32_with_firstelt(i32 %first, <vscale x 2 x i32> %vb, <vscale x 2 x i1> %mask, i32 zeroext %evl) {
+; CHECK-LABEL: test_vp_splice_nxv2i32_with_firstelt:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vsetvli zero, a1, e32, m1, ta, ma
+; CHECK-NEXT:    vslide1up.vx v9, v8, a0, v0.t
+; CHECK-NEXT:    vmv.v.v v8, v9
+; CHECK-NEXT:    ret
+  %va = insertelement <vscale x 2 x i32> poison, i32 %first, i32 0
+  %v = call <vscale x 2 x i32> @llvm.experimental.vp.splice.nxv2i32(<vscale x 2 x i32> %va, <vscale x 2 x i32> %vb, i32 0, <vscale x 2 x i1> %mask, i32 1, i32 %evl)
+  ret <vscale x 2 x i32> %v
+}
+
+define <vscale x 2 x float> @test_vp_splice_nxv2f32_with_firstelt(float %first, <vscale x 2 x float> %vb, <vscale x 2 x i1> %mask, i32 zeroext %evl) {
+; CHECK-LABEL: test_vp_splice_nxv2f32_with_firstelt:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vsetvli zero, a0, e32, m1, ta, ma
+; CHECK-NEXT:    vfslide1up.vf v9, v8, fa0, v0.t
+; CHECK-NEXT:    vmv.v.v v8, v9
+; CHECK-NEXT:    ret
+  %va = insertelement <vscale x 2 x float> poison, float %first, i32 0
+  %v = call <vscale x 2 x float> @llvm.experimental.vp.splice.nxv2f32(<vscale x 2 x float> %va, <vscale x 2 x float> %vb, i32 0, <vscale x 2 x i1> %mask, i32 1, i32 %evl)
+  ret <vscale x 2 x float> %v
+}
diff --git a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
index 2162588aadfdb..2b1fa75a1475a 100644
--- a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
+++ b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
@@ -493,6 +493,11 @@ TEST_F(SelectionDAGPatternMatchTest, matchConstants) {
   SDValue UndefVInt32VT = DAG->getUNDEF(VInt32VT);
   EXPECT_TRUE(sd_match(UndefInt32VT, m_Undef()));
   EXPECT_TRUE(sd_match(UndefVInt32VT, m_Undef()));
+
+  SDValue PoisonInt32VT = DAG->getPOISON(Int32VT);
+  SDValue PoisonVInt32VT = DAG->getPOISON(VInt32VT);
+  EXPECT_TRUE(sd_match(PoisonInt32VT, m_Poison()));
+  EXPECT_TRUE(sd_match(PoisonVInt32VT, m_Poison()));
 }
 
 TEST_F(SelectionDAGPatternMatchTest, patternCombinators) {

@NexMing NexMing force-pushed the combine-vp-splice branch 2 times, most recently from 870f41b to 99bc05d Compare June 20, 2025 03:09
@NexMing NexMing requested a review from wangpc-pp June 20, 2025 03:10
@NexMing NexMing force-pushed the combine-vp-splice branch from 99bc05d to 1b16845 Compare June 20, 2025 11:09
@NexMing NexMing requested a review from wangpc-pp June 20, 2025 11:11
Copy link
Contributor

@wangpc-pp wangpc-pp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not opposed to this PR, but I want to know others' opinions since we don't have the same issue with current vectorizer in upstream.

sd_match(Op1, m_InsertElt(m_Poison(), m_Value(FirstEle), m_Zero())) &&
sd_match(Offset, m_Zero()) && sd_match(EVL1, m_One())) {
SDValue Result = DAG.getNode(
ContainerVT.isFloatingPoint() ? RISCVISD::VFSLIDE1UP_VL
Copy link
Collaborator

@topperc topperc Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this handle bf16 or f16 without Zvfh correctly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it depends on how the operation action for ISD::EXPERIMENTAL_VP_SPLICE is set.

@NexMing NexMing changed the title [RISCV] Combine (vp.splice (insert_elt poison, scalar, 0), vec, 0, mask, 1, vl) to vslide1up. [RISCV] Try to optimize vp.splice to vslide1up. Jun 23, 2025
Fold (vp.splice (insert_elt poison, scalar, 0), vec, 0, mask, 1, vl)
to (vslide1up vec, scalar, mask. vl).

Fold (vp.splice (splat_vector scalar), vec, 0, mask, 1, vl)
to (vslide1up vec, scalar, mask. vl).
@NexMing NexMing force-pushed the combine-vp-splice branch from 1b16845 to 092dd0a Compare June 23, 2025 02:47
@NexMing NexMing requested review from mshockwave and topperc June 23, 2025 02:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants