-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[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
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-backend-risc-v Author: Ming Yan (NexMing) ChangesFold (vslideup_vl/vslidedown_vl undef, vec, 0, mask, vl, policy) Fold (vslideup_vl (insert_ele poison, first, 0), vec, 1, mask, vl, policy) Full diff: https://github.com/llvm/llvm-project/pull/144871.diff 4 Files Affected:
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) {
|
870f41b
to
99bc05d
Compare
99bc05d
to
1b16845
Compare
There was a problem hiding this 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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
vp.splice
to vslide1up
.
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).
1b16845
to
092dd0a
Compare
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).