Skip to content

Commit 3b0709e

Browse files
[RISCV][VLOPT] Add support for checkUsers when UserMI is an reduction
Reductions are weird because for some operands, they are vector registers but only read the first lane. For these operands, we do not need to check to make sure the EEW and EMUL ratios match. However, we need to make sure that when the reduction instruction has a non-zero VL operand, we don't try and set the CommonVL=0. Since this is an edge case, we decide just not to optimize anything when this occurs.
1 parent 8b57704 commit 3b0709e

File tree

3 files changed

+70
-6
lines changed

3 files changed

+70
-6
lines changed

llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,23 @@ static OperandInfo getOperandInfo(const MachineOperand &MO,
716716
return OperandInfo(MIVLMul, MILog2SEW);
717717
}
718718

719+
// Vector Reduction Operations
720+
// Vector Single-Width Integer Reduction Instructions
721+
// The Dest and VS1 only read element 0 of the vector register. Return unknown
722+
// for these. VS2 has EEW=SEW and EMUL=LMUL.
723+
case RISCV::VREDAND_VS:
724+
case RISCV::VREDMAX_VS:
725+
case RISCV::VREDMAXU_VS:
726+
case RISCV::VREDMIN_VS:
727+
case RISCV::VREDMINU_VS:
728+
case RISCV::VREDOR_VS:
729+
case RISCV::VREDSUM_VS:
730+
case RISCV::VREDXOR_VS: {
731+
if (MO.getOperandNo() == 2)
732+
return OperandInfo(MIVLMul, MILog2SEW);
733+
return {};
734+
}
735+
719736
default:
720737
return {};
721738
}
@@ -1041,11 +1058,28 @@ bool RISCVVLOptimizer::checkUsers(const MachineOperand *&CommonVL,
10411058

10421059
// Instructions like reductions may use a vector register as a scalar
10431060
// register. In this case, we should treat it like a scalar register which
1044-
// does not impact the decision on whether to optimize VL.
1045-
// TODO: Treat it like a scalar register instead of bailing out.
1061+
// does not impact the decision on whether to optimize VL. But if there is
1062+
// another user of MI and it has VL=0, we need to be sure not to reduce the
1063+
// VL of MI to zero when the VLOp of UserOp is may be non-zero.
10461064
if (isVectorOpUsedAsScalarOp(UserOp)) {
1047-
CanReduceVL = false;
1048-
break;
1065+
[[maybe_unused]] Register R = UserOp.getReg();
1066+
[[maybe_unused]] const TargetRegisterClass *RC = MRI->getRegClass(R);
1067+
assert(RISCV::VRRegClass.hasSubClassEq(RC) &&
1068+
"Expect LMUL 1 register class for vector as scalar operands!");
1069+
LLVM_DEBUG(dbgs() << " Used this operand as a scalar operand\n");
1070+
const MCInstrDesc &Desc = UserMI.getDesc();
1071+
unsigned VLOpNum = RISCVII::getVLOpNum(Desc);
1072+
const MachineOperand &VLOp = UserMI.getOperand(VLOpNum);
1073+
if ((VLOp.isReg() && VLOp.getReg() != RISCV::X0) ||
1074+
(VLOp.isImm() && VLOp.getImm() != 0)) {
1075+
if (!CommonVL) {
1076+
CommonVL = &VLOp;
1077+
continue;
1078+
} else if (!CommonVL->isIdenticalTo(VLOp)) {
1079+
CanReduceVL = false;
1080+
break;
1081+
}
1082+
}
10491083
}
10501084

10511085
if (mayReadPastVL(UserMI)) {

llvm/test/CodeGen/RISCV/rvv/vl-opt-op-info.mir

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,3 +1094,22 @@ body: |
10941094
%x:vr = PseudoVMAND_MM_B1 $noreg, $noreg, -1, 0
10951095
%y:vr = PseudoVIOTA_M_MF2 $noreg, %x, 1, 3 /* e8 */, 0
10961096
...
1097+
name: vred_vs2
1098+
body: |
1099+
bb.0:
1100+
; CHECK-LABEL: name: vred_vs2
1101+
; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */
1102+
; CHECK-NEXT: %y:vr = PseudoVREDAND_VS_M1_E8 $noreg, %x, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */
1103+
%x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 0
1104+
%y:vr = PseudoVREDAND_VS_M1_E8 $noreg, %x, $noreg, 1, 3 /* e8 */, 0
1105+
...
1106+
---
1107+
name: vred_vs1
1108+
body: |
1109+
bb.0:
1110+
; CHECK-LABEL: name: vred_vs1
1111+
; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */
1112+
; CHECK-NEXT: %y:vr = PseudoVREDAND_VS_M1_E8 $noreg, $noreg, %x, 1, 3 /* e8 */, 0 /* tu, mu */
1113+
%x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 0
1114+
%y:vr = PseudoVREDAND_VS_M1_E8 $noreg, $noreg, %x, 1, 3 /* e8 */, 0
1115+
...

llvm/test/CodeGen/RISCV/rvv/vl-opt.mir

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ name: use_largest_common_vl_imm_imm
3838
body: |
3939
bb.0:
4040
; CHECK-LABEL: name: use_largest_common_vl_imm_imm
41-
; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, 2, 3 /* e8 */, 0 /* tu, mu */
41+
; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 0 /* tu, mu */
4242
; CHECK-NEXT: %y:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */
4343
; CHECK-NEXT: %z:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 2, 3 /* e8 */, 0 /* tu, mu */
4444
%x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 0
@@ -110,4 +110,15 @@ body: |
110110
%y:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 1, 3 /* e8 */, 0
111111
%z:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, -1, 3 /* e8 */, 0
112112
...
113-
113+
---
114+
name: vred_other_user_is_vl0
115+
body: |
116+
bb.0:
117+
; CHECK-LABEL: name: vred_other_user_is_vl0
118+
; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 0 /* tu, mu */
119+
; CHECK-NEXT: %y:vr = PseudoVREDSUM_VS_M1_E8 $noreg, $noreg, %x, 1, 3 /* e8 */, 0 /* tu, mu */
120+
; CHECK-NEXT: %z:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 0, 3 /* e8 */, 0 /* tu, mu */
121+
%x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 0
122+
%y:vr = PseudoVREDSUM_VS_M1_E8 $noreg, $noreg, %x, 1, 3 /* e8 */, 0
123+
%z:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 0, 3 /* e8 */, 0
124+
...

0 commit comments

Comments
 (0)