Skip to content

Commit eae7344

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 79af7bd commit eae7344

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
@@ -621,6 +621,23 @@ static OperandInfo getOperandInfo(const MachineOperand &MO,
621621
return OperandInfo(MIVLMul, MILog2SEW);
622622
}
623623

624+
// Vector Reduction Operations
625+
// Vector Single-Width Integer Reduction Instructions
626+
// The Dest and VS1 only read element 0 of the vector register. Return unknown
627+
// for these. VS2 has EEW=SEW and EMUL=LMUL.
628+
case RISCV::VREDAND_VS:
629+
case RISCV::VREDMAX_VS:
630+
case RISCV::VREDMAXU_VS:
631+
case RISCV::VREDMIN_VS:
632+
case RISCV::VREDMINU_VS:
633+
case RISCV::VREDOR_VS:
634+
case RISCV::VREDSUM_VS:
635+
case RISCV::VREDXOR_VS: {
636+
if (MO.getOperandNo() == 2)
637+
return OperandInfo(MIVLMul, MILog2SEW);
638+
return {};
639+
}
640+
624641
default:
625642
return {};
626643
}
@@ -943,11 +960,28 @@ bool RISCVVLOptimizer::checkUsers(const MachineOperand *&CommonVL,
943960

944961
// Instructions like reductions may use a vector register as a scalar
945962
// register. In this case, we should treat it like a scalar register which
946-
// does not impact the decision on whether to optimize VL.
947-
// TODO: Treat it like a scalar register instead of bailing out.
963+
// does not impact the decision on whether to optimize VL. But if there is
964+
// another user of MI and it has VL=0, we need to be sure not to reduce the
965+
// VL of MI to zero when the VLOp of UserOp is may be non-zero.
948966
if (isVectorOpUsedAsScalarOp(UserOp)) {
949-
CanReduceVL = false;
950-
break;
967+
[[maybe_unused]] Register R = UserOp.getReg();
968+
[[maybe_unused]] const TargetRegisterClass *RC = MRI->getRegClass(R);
969+
assert(RISCV::VRRegClass.hasSubClassEq(RC) &&
970+
"Expect LMUL 1 register class for vector as scalar operands!");
971+
LLVM_DEBUG(dbgs() << " Used this operand as a scalar operand\n");
972+
const MCInstrDesc &Desc = UserMI.getDesc();
973+
unsigned VLOpNum = RISCVII::getVLOpNum(Desc);
974+
const MachineOperand &VLOp = UserMI.getOperand(VLOpNum);
975+
if ((VLOp.isReg() && VLOp.getReg() != RISCV::X0) ||
976+
(VLOp.isImm() && VLOp.getImm() != 0)) {
977+
if (!CommonVL) {
978+
CommonVL = &VLOp;
979+
continue;
980+
} else if (!CommonVL->isIdenticalTo(VLOp)) {
981+
CanReduceVL = false;
982+
break;
983+
}
984+
}
951985
}
952986

953987
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
@@ -1064,3 +1064,22 @@ body: |
10641064
%x:vr = PseudoVMAND_MM_B1 $noreg, $noreg, -1, 0
10651065
%y:vr = PseudoVIOTA_M_MF2 $noreg, %x, 1, 3 /* e8 */, 0
10661066
...
1067+
name: vred_vs2
1068+
body: |
1069+
bb.0:
1070+
; CHECK-LABEL: name: vred_vs2
1071+
; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */
1072+
; CHECK-NEXT: %y:vr = PseudoVREDAND_VS_M1_E8 $noreg, %x, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */
1073+
%x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 0
1074+
%y:vr = PseudoVREDAND_VS_M1_E8 $noreg, %x, $noreg, 1, 3 /* e8 */, 0
1075+
...
1076+
---
1077+
name: vred_vs1
1078+
body: |
1079+
bb.0:
1080+
; CHECK-LABEL: name: vred_vs1
1081+
; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */
1082+
; CHECK-NEXT: %y:vr = PseudoVREDAND_VS_M1_E8 $noreg, $noreg, %x, 1, 3 /* e8 */, 0 /* tu, mu */
1083+
%x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 0
1084+
%y:vr = PseudoVREDAND_VS_M1_E8 $noreg, $noreg, %x, 1, 3 /* e8 */, 0
1085+
...

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)