Skip to content

Commit d10079e

Browse files
authored
[RISCV] Reduce the VL of both operands in VMERGE_VVM (#144759)
The `tryToReduceVL` function in RISCVVectorPeephole currently only reduces the VL of the instruction that defines the true operand in VMERGE_VVM. We should be able to reduce VL of both operands. This patch generalizes this function to support multiple operands from a single instruction.
1 parent ac37a0d commit d10079e

File tree

3 files changed

+43
-38
lines changed

3 files changed

+43
-38
lines changed

llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ bool RISCVVectorPeephole::tryToReduceVL(MachineInstr &MI) const {
112112
//
113113
// TODO: We can handle a bunch more instructions here, and probably
114114
// recurse backwards through operands too.
115-
unsigned SrcIdx = 0;
115+
SmallVector<unsigned, 2> SrcIndices = {0};
116116
switch (RISCV::getRVVMCOpcode(MI.getOpcode())) {
117117
default:
118118
return false;
@@ -122,10 +122,10 @@ bool RISCVVectorPeephole::tryToReduceVL(MachineInstr &MI) const {
122122
case RISCV::VSE64_V:
123123
break;
124124
case RISCV::VMV_V_V:
125-
SrcIdx = 2;
125+
SrcIndices[0] = 2;
126126
break;
127127
case RISCV::VMERGE_VVM:
128-
SrcIdx = 3; // TODO: We can also handle the false operand.
128+
SrcIndices.assign({2, 3});
129129
break;
130130
case RISCV::VREDSUM_VS:
131131
case RISCV::VREDMAXU_VS:
@@ -143,50 +143,56 @@ bool RISCVVectorPeephole::tryToReduceVL(MachineInstr &MI) const {
143143
case RISCV::VFREDMIN_VS:
144144
case RISCV::VFWREDUSUM_VS:
145145
case RISCV::VFWREDOSUM_VS:
146-
SrcIdx = 2;
146+
SrcIndices[0] = 2;
147147
break;
148148
}
149149

150150
MachineOperand &VL = MI.getOperand(RISCVII::getVLOpNum(MI.getDesc()));
151151
if (VL.isImm() && VL.getImm() == RISCV::VLMaxSentinel)
152152
return false;
153153

154-
Register SrcReg = MI.getOperand(SrcIdx).getReg();
155-
// Note: one *use*, not one *user*.
156-
if (!MRI->hasOneUse(SrcReg))
157-
return false;
158-
159-
MachineInstr *Src = MRI->getVRegDef(SrcReg);
160-
if (!Src || Src->hasUnmodeledSideEffects() ||
161-
Src->getParent() != MI.getParent() || Src->getNumDefs() != 1 ||
162-
!RISCVII::hasVLOp(Src->getDesc().TSFlags) ||
163-
!RISCVII::hasSEWOp(Src->getDesc().TSFlags))
164-
return false;
165-
166-
// Src's dest needs to have the same EEW as MI's input.
167-
if (!hasSameEEW(MI, *Src))
168-
return false;
169-
170-
bool ElementsDependOnVL = RISCVII::elementsDependOnVL(
171-
TII->get(RISCV::getRVVMCOpcode(Src->getOpcode())).TSFlags);
172-
if (ElementsDependOnVL || Src->mayRaiseFPException())
173-
return false;
154+
bool Changed = false;
155+
for (unsigned SrcIdx : SrcIndices) {
156+
Register SrcReg = MI.getOperand(SrcIdx).getReg();
157+
// Note: one *use*, not one *user*.
158+
if (!MRI->hasOneUse(SrcReg))
159+
continue;
160+
161+
MachineInstr *Src = MRI->getVRegDef(SrcReg);
162+
if (!Src || Src->hasUnmodeledSideEffects() ||
163+
Src->getParent() != MI.getParent() || Src->getNumDefs() != 1 ||
164+
!RISCVII::hasVLOp(Src->getDesc().TSFlags) ||
165+
!RISCVII::hasSEWOp(Src->getDesc().TSFlags))
166+
continue;
167+
168+
// Src's dest needs to have the same EEW as MI's input.
169+
if (!hasSameEEW(MI, *Src))
170+
continue;
171+
172+
bool ElementsDependOnVL = RISCVII::elementsDependOnVL(
173+
TII->get(RISCV::getRVVMCOpcode(Src->getOpcode())).TSFlags);
174+
if (ElementsDependOnVL || Src->mayRaiseFPException())
175+
continue;
176+
177+
MachineOperand &SrcVL =
178+
Src->getOperand(RISCVII::getVLOpNum(Src->getDesc()));
179+
if (VL.isIdenticalTo(SrcVL) || !RISCV::isVLKnownLE(VL, SrcVL))
180+
continue;
174181

175-
MachineOperand &SrcVL = Src->getOperand(RISCVII::getVLOpNum(Src->getDesc()));
176-
if (VL.isIdenticalTo(SrcVL) || !RISCV::isVLKnownLE(VL, SrcVL))
177-
return false;
182+
if (!ensureDominates(VL, *Src))
183+
continue;
178184

179-
if (!ensureDominates(VL, *Src))
180-
return false;
185+
if (VL.isImm())
186+
SrcVL.ChangeToImmediate(VL.getImm());
187+
else if (VL.isReg())
188+
SrcVL.ChangeToRegister(VL.getReg(), false);
181189

182-
if (VL.isImm())
183-
SrcVL.ChangeToImmediate(VL.getImm());
184-
else if (VL.isReg())
185-
SrcVL.ChangeToRegister(VL.getReg(), false);
190+
Changed = true;
191+
}
186192

187193
// TODO: For instructions with a passthru, we could clear the passthru
188194
// and tail policy since we've just proven the tail is not demanded.
189-
return true;
195+
return Changed;
190196
}
191197

192198
/// Check if an operand is an immediate or a materialized ADDI $x0, imm.

llvm/test/CodeGen/RISCV/rvv/masked-load-int.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,8 @@ define <vscale x 1 x i8> @masked_load_passthru_nxv1i8(ptr %a, <vscale x 1 x i1>
3434
; ZVE32: # %bb.0:
3535
; ZVE32-NEXT: csrr a1, vlenb
3636
; ZVE32-NEXT: srli a1, a1, 3
37-
; ZVE32-NEXT: vsetvli a2, zero, e8, mf4, ta, ma
38-
; ZVE32-NEXT: vmv.v.i v8, 0
3937
; ZVE32-NEXT: vsetvli zero, a1, e8, mf4, ta, mu
38+
; ZVE32-NEXT: vmv.v.i v8, 0
4039
; ZVE32-NEXT: vle8.v v8, (a0), v0.t
4140
; ZVE32-NEXT: ret
4241
%load = call <vscale x 1 x i8> @llvm.masked.load.nxv1i8(ptr %a, i32 1, <vscale x 1 x i1> %mask, <vscale x 1 x i8> zeroinitializer)

llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3063,9 +3063,9 @@ define <vscale x 4 x i32> @vmv_v_x(<vscale x 4 x i32> %a, i32 %x, iXLen %vl) {
30633063
define <vscale x 1 x i8> @vmv_v_v(<vscale x 1 x i8> %a, <vscale x 1 x i8> %b, <vscale x 1 x i8> %c, <vscale x 1 x i1> %m, iXLen %vl) {
30643064
; NOVLOPT-LABEL: vmv_v_v:
30653065
; NOVLOPT: # %bb.0:
3066-
; NOVLOPT-NEXT: vsetvli a1, zero, e8, mf8, tu, ma
3066+
; NOVLOPT-NEXT: vsetvli zero, a0, e8, mf8, tu, ma
30673067
; NOVLOPT-NEXT: vmv.v.v v8, v9
3068-
; NOVLOPT-NEXT: vsetvli zero, a0, e8, mf8, ta, ma
3068+
; NOVLOPT-NEXT: vsetvli zero, zero, e8, mf8, ta, ma
30693069
; NOVLOPT-NEXT: vmerge.vvm v8, v8, v10, v0
30703070
; NOVLOPT-NEXT: ret
30713071
;

0 commit comments

Comments
 (0)