Skip to content

Commit 776db58

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 fb33268 commit 776db58

File tree

3 files changed

+69
-4
lines changed

3 files changed

+69
-4
lines changed

llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp

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

582+
// Vector Reduction Operations
583+
// Vector Single-Width Integer Reduction Instructions
584+
// The Dest and VS1 only read element 0 of the vector register. Return unknown
585+
// for these. VS2 has EEW=SEW and EMUL=LMUL.
586+
case RISCV::VREDAND_VS:
587+
case RISCV::VREDMAX_VS:
588+
case RISCV::VREDMAXU_VS:
589+
case RISCV::VREDMIN_VS:
590+
case RISCV::VREDMINU_VS:
591+
case RISCV::VREDOR_VS:
592+
case RISCV::VREDSUM_VS:
593+
case RISCV::VREDXOR_VS: {
594+
if (MO.getOperandNo() == 2)
595+
return OperandInfo(MIVLMul, MILog2SEW);
596+
return {};
597+
}
598+
582599
default:
583600
return {};
584601
}
@@ -901,11 +918,28 @@ bool RISCVVLOptimizer::checkUsers(const MachineOperand *&CommonVL,
901918

902919
// Instructions like reductions may use a vector register as a scalar
903920
// register. In this case, we should treat it like a scalar register which
904-
// does not impact the decision on whether to optimize VL.
905-
// TODO: Treat it like a scalar register instead of bailing out.
921+
// does not impact the decision on whether to optimize VL. But if there is
922+
// another user of MI and it has VL=0, we need to be sure not to reduce the
923+
// VL of MI to zero when the VLOp of UserOp is may be non-zero.
906924
if (isVectorOpUsedAsScalarOp(UserOp)) {
907-
CanReduceVL = false;
908-
break;
925+
[[maybe_unused]] Register R = UserOp.getReg();
926+
[[maybe_unused]] const TargetRegisterClass *RC = MRI->getRegClass(R);
927+
assert(RISCV::VRRegClass.hasSubClassEq(RC) &&
928+
"Expect LMUL 1 register class for vector as scalar operands!");
929+
LLVM_DEBUG(dbgs() << " Used this operand as a scalar operand\n");
930+
const MCInstrDesc &Desc = UserMI.getDesc();
931+
unsigned VLOpNum = RISCVII::getVLOpNum(Desc);
932+
const MachineOperand &VLOp = UserMI.getOperand(VLOpNum);
933+
if ((VLOp.isReg() && VLOp.getReg() != RISCV::X0) ||
934+
(VLOp.isImm() && VLOp.getImm() != 0)) {
935+
if (!CommonVL) {
936+
CommonVL = &VLOp;
937+
continue;
938+
} else if (!CommonVL->isIdenticalTo(VLOp)) {
939+
CanReduceVL = false;
940+
break;
941+
}
942+
}
909943
}
910944

911945
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
@@ -962,3 +962,22 @@ body: |
962962
%x:vr = PseudoVMAND_MM_B1 $noreg, $noreg, -1, 0
963963
%y:vr = PseudoVIOTA_M_MF2 $noreg, %x, 1, 3 /* e8 */, 0
964964
...
965+
name: vred_vs2
966+
body: |
967+
bb.0:
968+
; CHECK-LABEL: name: vred_vs2
969+
; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */
970+
; CHECK-NEXT: %y:vr = PseudoVREDAND_VS_M1_E8 $noreg, %x, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */
971+
%x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 0
972+
%y:vr = PseudoVREDAND_VS_M1_E8 $noreg, %x, $noreg, 1, 3 /* e8 */, 0
973+
...
974+
---
975+
name: vred_vs1
976+
body: |
977+
bb.0:
978+
; CHECK-LABEL: name: vred_vs1
979+
; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */
980+
; CHECK-NEXT: %y:vr = PseudoVREDAND_VS_M1_E8 $noreg, $noreg, %x, 1, 3 /* e8 */, 0 /* tu, mu */
981+
%x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 0
982+
%y:vr = PseudoVREDAND_VS_M1_E8 $noreg, $noreg, %x, 1, 3 /* e8 */, 0
983+
...

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,15 @@ body: |
3333
%y:vr = PseudoVREDSUM_VS_M1_E64 $noreg, %x, $noreg, -1, 6 /* e64 */, 0 /* tu, mu */
3434
%z:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, %vl, 5 /* e32 */, 0 /* tu, mu */
3535
...
36+
---
37+
name: vred_other_user_is_vl0
38+
body: |
39+
bb.0:
40+
; CHECK-LABEL: name: vred_other_user_is_vl0
41+
; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 0 /* tu, mu */
42+
; CHECK-NEXT: %y:vr = PseudoVREDSUM_VS_M1_E8 $noreg, $noreg, %x, 1, 3 /* e8 */, 0 /* tu, mu */
43+
; CHECK-NEXT: %z:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 0, 3 /* e8 */, 0 /* tu, mu */
44+
%x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 0
45+
%y:vr = PseudoVREDSUM_VS_M1_E8 $noreg, $noreg, %x, 1, 3 /* e8 */, 0
46+
%z:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 0, 3 /* e8 */, 0
47+
...

0 commit comments

Comments
 (0)