Skip to content

Commit 6584e47

Browse files
authored
[RISCV] Combine vmerge_vl allones -> vmv_v_v, vmv_v_v splat(x) -> vmv_v_x (#170539)
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 cb8ce28 commit 6584e47

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
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: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,3 +1353,48 @@ define <32 x double> @vpmerge_vf_v32f64(double %a, <32 x double> %vb, <32 x i1>
13531353
%v = call <32 x double> @llvm.vp.merge.v32f64(<32 x i1> %m, <32 x double> %va, <32 x double> %vb, i32 %evl)
13541354
ret <32 x double> %v
13551355
}
1356+
1357+
define <4 x i32> @splat_v4i32(i32 %x, i32 zeroext %evl) {
1358+
; CHECK-LABEL: splat_v4i32:
1359+
; CHECK: # %bb.0:
1360+
; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma
1361+
; CHECK-NEXT: vmv.v.x v8, a0
1362+
; CHECK-NEXT: ret
1363+
%head = insertelement <4 x i32> poison, i32 %x, i32 0
1364+
%splat = shufflevector <4 x i32> %head, <4 x i32> poison, <4 x i32> zeroinitializer
1365+
%v = call <4 x i32> @llvm.vp.merge(<4 x i1> splat (i1 true), <4 x i32> %splat, <4 x i32> poison, i32 %evl)
1366+
ret <4 x i32> %v
1367+
}
1368+
1369+
define <4 x float> @splat_v4f32(float %x, i32 zeroext %evl) {
1370+
; CHECK-LABEL: splat_v4f32:
1371+
; CHECK: # %bb.0:
1372+
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
1373+
; CHECK-NEXT: vfmv.v.f v8, fa0
1374+
; CHECK-NEXT: ret
1375+
%head = insertelement <4 x float> poison, float %x, i32 0
1376+
%splat = shufflevector <4 x float> %head, <4 x float> poison, <4 x i32> zeroinitializer
1377+
%v = call <4 x float> @llvm.vp.merge(<4 x i1> splat (i1 true), <4 x float> %splat, <4 x float> poison, i32 %evl)
1378+
ret <4 x float> %v
1379+
}
1380+
1381+
define <4 x i32> @splat_v4i32_const(i32 zeroext %evl) {
1382+
; CHECK-LABEL: splat_v4i32_const:
1383+
; CHECK: # %bb.0:
1384+
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
1385+
; CHECK-NEXT: vmv.v.i v8, 1
1386+
; CHECK-NEXT: ret
1387+
%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)
1388+
ret <4 x i32> %v
1389+
}
1390+
1391+
define <4 x float> @splat_v4f32_const(i32 zeroext %evl) {
1392+
; CHECK-LABEL: splat_v4f32_const:
1393+
; CHECK: # %bb.0:
1394+
; CHECK-NEXT: lui a1, 270976
1395+
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
1396+
; CHECK-NEXT: vmv.v.x v8, a1
1397+
; CHECK-NEXT: ret
1398+
%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)
1399+
ret <4 x float> %v
1400+
}

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,3 +1663,48 @@ define <vscale x 8 x double> @vpmerge_vf_nxv8f64(double %a, <vscale x 8 x double
16631663
%v = call <vscale x 8 x double> @llvm.vp.merge.nxv8f64(<vscale x 8 x i1> %m, <vscale x 8 x double> %va, <vscale x 8 x double> %vb, i32 %evl)
16641664
ret <vscale x 8 x double> %v
16651665
}
1666+
1667+
define <vscale x 2 x i32> @splat_nxv2i32(i32 %x, i32 zeroext %evl) {
1668+
; CHECK-LABEL: splat_nxv2i32:
1669+
; CHECK: # %bb.0:
1670+
; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma
1671+
; CHECK-NEXT: vmv.v.x v8, a0
1672+
; CHECK-NEXT: ret
1673+
%head = insertelement <vscale x 2 x i32> poison, i32 %x, i32 0
1674+
%splat = shufflevector <vscale x 2 x i32> %head, <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer
1675+
%v = call <vscale x 2 x i32> @llvm.vp.merge(<vscale x 2 x i1> splat (i1 true), <vscale x 2 x i32> %splat, <vscale x 2 x i32> poison, i32 %evl)
1676+
ret <vscale x 2 x i32> %v
1677+
}
1678+
1679+
define <vscale x 2 x float> @splat_nxv2f32(float %x, i32 zeroext %evl) {
1680+
; CHECK-LABEL: splat_nxv2f32:
1681+
; CHECK: # %bb.0:
1682+
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
1683+
; CHECK-NEXT: vfmv.v.f v8, fa0
1684+
; CHECK-NEXT: ret
1685+
%head = insertelement <vscale x 2 x float> poison, float %x, i32 0
1686+
%splat = shufflevector <vscale x 2 x float> %head, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer
1687+
%v = call <vscale x 2 x float> @llvm.vp.merge(<vscale x 2 x i1> splat (i1 true), <vscale x 2 x float> %splat, <vscale x 2 x float> poison, i32 %evl)
1688+
ret <vscale x 2 x float> %v
1689+
}
1690+
1691+
define <vscale x 2 x i32> @splat_nxv2i32_const(i32 zeroext %evl) {
1692+
; CHECK-LABEL: splat_nxv2i32_const:
1693+
; CHECK: # %bb.0:
1694+
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
1695+
; CHECK-NEXT: vmv.v.i v8, 1
1696+
; CHECK-NEXT: ret
1697+
%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)
1698+
ret <vscale x 2 x i32> %v
1699+
}
1700+
1701+
define <vscale x 2 x float> @splat_nxv2f32_const(i32 zeroext %evl) {
1702+
; CHECK-LABEL: splat_nxv2f32_const:
1703+
; CHECK: # %bb.0:
1704+
; CHECK-NEXT: lui a1, 270976
1705+
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
1706+
; CHECK-NEXT: vmv.v.x v8, a1
1707+
; CHECK-NEXT: ret
1708+
%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)
1709+
ret <vscale x 2 x float> %v
1710+
}

0 commit comments

Comments
 (0)