Skip to content

Commit 7866fc2

Browse files
authored
[RISCV] Rewrite vrgather.vx undef, (vmv.s.x), 0, v0 as vmv.v.x (#136010)
This extends the DAG combine introduced in 336b290 to handle the case where the prior value is defined by a vmv.s.x instead of a vmv.v.x. If the vrgather splats the single source element, and has no passthru we can replace it with a vmv.v.x - which will in turn usually get folded into a vmerge if a select follows.
1 parent 386cc00 commit 7866fc2

File tree

3 files changed

+40
-26
lines changed

3 files changed

+40
-26
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19710,20 +19710,46 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
1971019710
return V;
1971119711
break;
1971219712
case RISCVISD::VRGATHER_VX_VL: {
19713-
// Drop a redundant vrgather_vx.
1971419713
// Note this assumes that out of bounds indices produce poison
1971519714
// and can thus be replaced without having to prove them inbounds..
19715+
EVT VT = N->getValueType(0);
1971619716
SDValue Src = N->getOperand(0);
19717+
SDValue Idx = N->getOperand(1);
1971719718
SDValue Passthru = N->getOperand(2);
1971819719
SDValue VL = N->getOperand(4);
19720+
19721+
// Warning: Unlike most cases we strip an insert_subvector, this one
19722+
// does not require the first operand to be undef.
19723+
if (Src.getOpcode() == ISD::INSERT_SUBVECTOR &&
19724+
isNullConstant(Src.getOperand(2)))
19725+
Src = Src.getOperand(1);
19726+
1971919727
switch (Src.getOpcode()) {
1972019728
default:
1972119729
break;
1972219730
case RISCVISD::VMV_V_X_VL:
1972319731
case RISCVISD::VFMV_V_F_VL:
19724-
if (Passthru.isUndef() && VL == Src.getOperand(2))
19732+
// Drop a redundant vrgather_vx.
19733+
// TODO: Remove the type restriction if we find a motivating
19734+
// test case?
19735+
if (Passthru.isUndef() && VL == Src.getOperand(2) &&
19736+
Src.getValueType() == VT)
1972519737
return Src;
1972619738
break;
19739+
case RISCVISD::VMV_S_X_VL:
19740+
case RISCVISD::VFMV_S_F_VL:
19741+
// If this use only demands lane zero from the source vmv.s.x, and
19742+
// doesn't have a passthru, then this vrgather.vi/vx is equivalent to
19743+
// a vmv.v.x. Note that there can be other uses of the original
19744+
// vmv.s.x and thus we can't eliminate it. (vfmv.s.f is analogous)
19745+
if (isNullConstant(Idx) && Passthru.isUndef() &&
19746+
VL == Src.getOperand(2)) {
19747+
unsigned Opc =
19748+
VT.isFloatingPoint() ? RISCVISD::VFMV_V_F_VL : RISCVISD::VMV_V_X_VL;
19749+
return DAG.getNode(Opc, DL, VT, DAG.getUNDEF(VT), Src.getOperand(1),
19750+
VL);
19751+
}
19752+
break;
1972719753
}
1972819754
break;
1972919755
}

llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-fp.ll

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,11 @@ define <8 x float> @vmerge_vxm(<8 x float> %v, float %s) {
9696
; CHECK-LABEL: vmerge_vxm:
9797
; CHECK: # %bb.0:
9898
; CHECK-NEXT: li a0, 25
99-
; CHECK-NEXT: vsetivli zero, 8, e32, m1, tu, ma
100-
; CHECK-NEXT: vfmv.s.f v8, fa0
99+
; CHECK-NEXT: vsetivli zero, 1, e32, m4, tu, ma
101100
; CHECK-NEXT: vmv.s.x v0, a0
102-
; CHECK-NEXT: vmv2r.v v10, v8
103-
; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, mu
104-
; CHECK-NEXT: vrgather.vi v10, v8, 0, v0.t
105-
; CHECK-NEXT: vmv.v.v v8, v10
101+
; CHECK-NEXT: vfmv.s.f v8, fa0
102+
; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
103+
; CHECK-NEXT: vfmerge.vfm v8, v8, fa0, v0
106104
; CHECK-NEXT: ret
107105
%ins = insertelement <8 x float> %v, float %s, i32 0
108106
%shuf = shufflevector <8 x float> %ins, <8 x float> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 0, i32 0, i32 5, i32 6, i32 7>
@@ -112,15 +110,10 @@ define <8 x float> @vmerge_vxm(<8 x float> %v, float %s) {
112110
define <8 x float> @vmerge_vxm2(<8 x float> %v, float %s) {
113111
; CHECK-LABEL: vmerge_vxm2:
114112
; CHECK: # %bb.0:
115-
; CHECK-NEXT: vsetivli zero, 1, e32, m4, tu, ma
116-
; CHECK-NEXT: vmv1r.v v12, v8
117-
; CHECK-NEXT: vmv2r.v v10, v8
118113
; CHECK-NEXT: li a0, 25
119-
; CHECK-NEXT: vfmv.s.f v12, fa0
114+
; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
120115
; CHECK-NEXT: vmv.s.x v0, a0
121-
; CHECK-NEXT: vmv1r.v v10, v12
122-
; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, mu
123-
; CHECK-NEXT: vrgather.vi v8, v10, 0, v0.t
116+
; CHECK-NEXT: vfmerge.vfm v8, v8, fa0, v0
124117
; CHECK-NEXT: ret
125118
%ins = insertelement <8 x float> %v, float %s, i32 0
126119
%shuf = shufflevector <8 x float> %v, <8 x float> %ins, <8 x i32> <i32 8, i32 1, i32 2, i32 8, i32 8, i32 5, i32 6, i32 7>

llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-int.ll

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,13 +1448,11 @@ define <8 x i8> @vmerge_vxm(<8 x i8> %v, i8 %s) {
14481448
; CHECK-LABEL: vmerge_vxm:
14491449
; CHECK: # %bb.0:
14501450
; CHECK-NEXT: li a1, 25
1451-
; CHECK-NEXT: vsetivli zero, 8, e8, m1, tu, ma
1452-
; CHECK-NEXT: vmv.s.x v8, a0
1451+
; CHECK-NEXT: vsetivli zero, 1, e8, m1, tu, ma
14531452
; CHECK-NEXT: vmv.s.x v0, a1
1454-
; CHECK-NEXT: vmv1r.v v9, v8
1455-
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, mu
1456-
; CHECK-NEXT: vrgather.vi v9, v8, 0, v0.t
1457-
; CHECK-NEXT: vmv1r.v v8, v9
1453+
; CHECK-NEXT: vmv.s.x v8, a0
1454+
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
1455+
; CHECK-NEXT: vmerge.vxm v8, v8, a0, v0
14581456
; CHECK-NEXT: ret
14591457
%ins = insertelement <8 x i8> %v, i8 %s, i32 0
14601458
%shuf = shufflevector <8 x i8> %ins, <8 x i8> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 0, i32 0, i32 5, i32 6, i32 7>
@@ -1465,12 +1463,9 @@ define <8 x i8> @vmerge_vxm2(<8 x i8> %v, i8 %s) {
14651463
; CHECK-LABEL: vmerge_vxm2:
14661464
; CHECK: # %bb.0:
14671465
; CHECK-NEXT: li a1, 25
1468-
; CHECK-NEXT: vsetivli zero, 1, e8, m1, tu, ma
1466+
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
14691467
; CHECK-NEXT: vmv.s.x v0, a1
1470-
; CHECK-NEXT: vmv1r.v v9, v8
1471-
; CHECK-NEXT: vmv.s.x v9, a0
1472-
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, mu
1473-
; CHECK-NEXT: vrgather.vi v8, v9, 0, v0.t
1468+
; CHECK-NEXT: vmerge.vxm v8, v8, a0, v0
14741469
; CHECK-NEXT: ret
14751470
%ins = insertelement <8 x i8> %v, i8 %s, i32 0
14761471
%shuf = shufflevector <8 x i8> %v, <8 x i8> %ins, <8 x i32> <i32 8, i32 1, i32 2, i32 8, i32 8, i32 5, i32 6, i32 7>

0 commit comments

Comments
 (0)