Skip to content

Commit 31c8f8e

Browse files
committed
[RISCV] Combine vmerge_vl allones -> vmv_v_v, vmv_v_v splat(x) -> vmv_v_x
Stacked on #170536 An upcoming patch aims to remove the last use of @llvm.experimental.vp.splat in RISCVCodegenPrepare by replacing it with a vp_merge of a regular splat. A vp_merge will get lowered to vmerge_vl, and if we combine vmerge_vl of a splat to vmv_v_x we can get the same behaviour as the vp.splat intrinsic. This adds the two combines needed. It was easier to do the combines on _vl nodes rather than on vp_merge itself, since the types are already legal for _vl nodes.
1 parent c69cdce commit 31c8f8e

File tree

3 files changed

+47
-21
lines changed

3 files changed

+47
-21
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21872,6 +21872,44 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
2187221872
return N->getOperand(0);
2187321873
break;
2187421874
}
21875+
case RISCVISD::VMERGE_VL: {
21876+
// vmerge_vl allones, x, y, passthru, vl -> vmv_v_v passthru, x, vl
21877+
SDValue Mask = N->getOperand(0);
21878+
SDValue True = N->getOperand(1);
21879+
SDValue Passthru = N->getOperand(3);
21880+
SDValue VL = N->getOperand(4);
21881+
21882+
// Fixed vectors are wrapped in scalable containers, unwrap them.
21883+
using namespace SDPatternMatch;
21884+
SDValue SubVec;
21885+
if (sd_match(Mask, m_InsertSubvector(m_Undef(), m_Value(SubVec), m_Zero())))
21886+
Mask = SubVec;
21887+
21888+
if (!isOneOrOneSplat(Mask))
21889+
break;
21890+
21891+
return DAG.getNode(RISCVISD::VMV_V_V_VL, SDLoc(N), N->getSimpleValueType(0),
21892+
Passthru, True, VL);
21893+
}
21894+
case RISCVISD::VMV_V_V_VL: {
21895+
// vmv_v_v passthru, splat(x), vl -> vmv_v_x passthru, x, vl
21896+
SDValue Passthru = N->getOperand(0);
21897+
SDValue Src = N->getOperand(1);
21898+
SDValue VL = N->getOperand(2);
21899+
21900+
// Fixed vectors are wrapped in scalable containers, unwrap them.
21901+
using namespace SDPatternMatch;
21902+
SDValue SubVec;
21903+
if (sd_match(Src, m_InsertSubvector(m_Undef(), m_Value(SubVec), m_Zero())))
21904+
Src = SubVec;
21905+
21906+
SDValue SplatVal = DAG.getSplatValue(Src);
21907+
if (!SplatVal)
21908+
break;
21909+
MVT VT = N->getSimpleValueType(0);
21910+
return lowerScalarSplat(Passthru, SplatVal, VL, VT, SDLoc(N), DAG,
21911+
Subtarget);
21912+
}
2187521913
case RISCVISD::VSLIDEDOWN_VL:
2187621914
case RISCVISD::VSLIDEUP_VL:
2187721915
if (N->getOperand(1)->isUndef())

llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vpmerge.ll

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,10 +1357,8 @@ define <32 x double> @vpmerge_vf_v32f64(double %a, <32 x double> %vb, <32 x i1>
13571357
define <4 x i32> @splat_v4i32(i32 %x, i32 zeroext %evl) {
13581358
; CHECK-LABEL: splat_v4i32:
13591359
; CHECK: # %bb.0:
1360-
; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
1361-
; CHECK-NEXT: vmset.m v0
13621360
; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma
1363-
; CHECK-NEXT: vmerge.vxm v8, v8, a0, v0
1361+
; CHECK-NEXT: vmv.v.x v8, a0
13641362
; CHECK-NEXT: ret
13651363
%head = insertelement <4 x i32> poison, i32 %x, i32 0
13661364
%splat = shufflevector <4 x i32> %head, <4 x i32> poison, <4 x i32> zeroinitializer
@@ -1371,10 +1369,8 @@ define <4 x i32> @splat_v4i32(i32 %x, i32 zeroext %evl) {
13711369
define <4 x float> @splat_v4f32(float %x, i32 zeroext %evl) {
13721370
; CHECK-LABEL: splat_v4f32:
13731371
; CHECK: # %bb.0:
1374-
; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
1375-
; CHECK-NEXT: vmset.m v0
13761372
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
1377-
; CHECK-NEXT: vfmerge.vfm v8, v8, fa0, v0
1373+
; CHECK-NEXT: vfmv.v.f v8, fa0
13781374
; CHECK-NEXT: ret
13791375
%head = insertelement <4 x float> poison, float %x, i32 0
13801376
%splat = shufflevector <4 x float> %head, <4 x float> poison, <4 x i32> zeroinitializer
@@ -1385,10 +1381,8 @@ define <4 x float> @splat_v4f32(float %x, i32 zeroext %evl) {
13851381
define <4 x i32> @splat_v4i32_const(i32 zeroext %evl) {
13861382
; CHECK-LABEL: splat_v4i32_const:
13871383
; CHECK: # %bb.0:
1388-
; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
1389-
; CHECK-NEXT: vmset.m v0
13901384
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
1391-
; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
1385+
; CHECK-NEXT: vmv.v.i v8, 1
13921386
; CHECK-NEXT: ret
13931387
%v = call <4 x i32> @llvm.vp.merge(<4 x i1> splat (i1 true), <4 x i32> splat (i32 1), <4 x i32> poison, i32 %evl)
13941388
ret <4 x i32> %v
@@ -1397,11 +1391,9 @@ define <4 x i32> @splat_v4i32_const(i32 zeroext %evl) {
13971391
define <4 x float> @splat_v4f32_const(i32 zeroext %evl) {
13981392
; CHECK-LABEL: splat_v4f32_const:
13991393
; CHECK: # %bb.0:
1400-
; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
1401-
; CHECK-NEXT: vmset.m v0
14021394
; CHECK-NEXT: lui a1, 270976
14031395
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
1404-
; CHECK-NEXT: vmerge.vxm v8, v8, a1, v0
1396+
; CHECK-NEXT: vmv.v.x v8, a1
14051397
; CHECK-NEXT: ret
14061398
%v = call <4 x float> @llvm.vp.merge(<4 x i1> splat (i1 true), <4 x float> splat (float 42.0), <4 x float> poison, i32 %evl)
14071399
ret <4 x float> %v

llvm/test/CodeGen/RISCV/rvv/vpmerge-sdnode.ll

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,8 +1668,7 @@ define <vscale x 2 x i32> @splat_nxv2i32(i32 %x, i32 zeroext %evl) {
16681668
; CHECK-LABEL: splat_nxv2i32:
16691669
; CHECK: # %bb.0:
16701670
; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma
1671-
; CHECK-NEXT: vmset.m v0
1672-
; CHECK-NEXT: vmerge.vxm v8, v8, a0, v0
1671+
; CHECK-NEXT: vmv.v.x v8, a0
16731672
; CHECK-NEXT: ret
16741673
%head = insertelement <vscale x 2 x i32> poison, i32 %x, i32 0
16751674
%splat = shufflevector <vscale x 2 x i32> %head, <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer
@@ -1681,8 +1680,7 @@ define <vscale x 2 x float> @splat_nxv2f32(float %x, i32 zeroext %evl) {
16811680
; CHECK-LABEL: splat_nxv2f32:
16821681
; CHECK: # %bb.0:
16831682
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
1684-
; CHECK-NEXT: vmset.m v0
1685-
; CHECK-NEXT: vfmerge.vfm v8, v8, fa0, v0
1683+
; CHECK-NEXT: vfmv.v.f v8, fa0
16861684
; CHECK-NEXT: ret
16871685
%head = insertelement <vscale x 2 x float> poison, float %x, i32 0
16881686
%splat = shufflevector <vscale x 2 x float> %head, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer
@@ -1694,8 +1692,7 @@ define <vscale x 2 x i32> @splat_nxv2i32_const(i32 zeroext %evl) {
16941692
; CHECK-LABEL: splat_nxv2i32_const:
16951693
; CHECK: # %bb.0:
16961694
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
1697-
; CHECK-NEXT: vmset.m v0
1698-
; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
1695+
; CHECK-NEXT: vmv.v.i v8, 1
16991696
; CHECK-NEXT: ret
17001697
%v = call <vscale x 2 x i32> @llvm.vp.merge(<vscale x 2 x i1> splat (i1 true), <vscale x 2 x i32> splat (i32 1), <vscale x 2 x i32> poison, i32 %evl)
17011698
ret <vscale x 2 x i32> %v
@@ -1704,10 +1701,9 @@ define <vscale x 2 x i32> @splat_nxv2i32_const(i32 zeroext %evl) {
17041701
define <vscale x 2 x float> @splat_nxv2f32_const(i32 zeroext %evl) {
17051702
; CHECK-LABEL: splat_nxv2f32_const:
17061703
; CHECK: # %bb.0:
1704+
; CHECK-NEXT: lui a1, 270976
17071705
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
1708-
; CHECK-NEXT: vmset.m v0
1709-
; CHECK-NEXT: lui a0, 270976
1710-
; CHECK-NEXT: vmerge.vxm v8, v8, a0, v0
1706+
; CHECK-NEXT: vmv.v.x v8, a1
17111707
; CHECK-NEXT: ret
17121708
%v = call <vscale x 2 x float> @llvm.vp.merge(<vscale x 2 x i1> splat (i1 true), <vscale x 2 x float> splat (float 42.0), <vscale x 2 x float> poison, i32 %evl)
17131709
ret <vscale x 2 x float> %v

0 commit comments

Comments
 (0)