[llvm] [RISCV][VLOPT] Add support for checkUsers when UserMI is a Single-Width Integer Reduction (PR #120345)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 5 09:54:45 PST 2025
================
@@ -1028,79 +1055,113 @@ bool RISCVVLOptimizer::isCandidate(const MachineInstr &MI) const {
return true;
}
-bool RISCVVLOptimizer::checkUsers(const MachineOperand *&CommonVL,
- MachineInstr &MI) {
+std::optional<MachineOperand>
+RISCVVLOptimizer::getVLForUser(MachineOperand &UserOp) {
+ const MachineInstr &UserMI = *UserOp.getParent();
+ const MCInstrDesc &Desc = UserMI.getDesc();
+
+ if (!RISCVII::hasVLOp(Desc.TSFlags) || !RISCVII::hasSEWOp(Desc.TSFlags)) {
+ LLVM_DEBUG(dbgs() << " Abort due to lack of VL, assume that"
+ " use VLMAX\n");
+ return std::nullopt;
+ }
+
+ // Instructions like reductions may use a vector register as a scalar
+ // register. In this case, we should treat it like a scalar register which
+ // does not impact the decision on whether to optimize VL. But if there is
+ // another user of MI and it may have VL=0, we need to be sure not to reduce
+ // the VL of MI to zero when the VLOp of UserOp may be non-zero. The most
+ // we can reduce it to is one.
+ if (isVectorOpUsedAsScalarOp(UserOp)) {
+ [[maybe_unused]] Register R = UserOp.getReg();
+ [[maybe_unused]] const TargetRegisterClass *RC = MRI->getRegClass(R);
+ assert(RISCV::VRRegClass.hasSubClassEq(RC) &&
+ "Expect LMUL 1 register class for vector as scalar operands!");
+ LLVM_DEBUG(dbgs() << " Used this operand as a scalar operand\n");
+
+ unsigned VLOpNum = RISCVII::getVLOpNum(Desc);
+ const MachineOperand &VLOp = UserMI.getOperand(VLOpNum);
+ if (VLOp.isReg() || (VLOp.isImm() && VLOp.getImm() != 0))
+ return MachineOperand::CreateImm(1);
----------------
lukel97 wrote:
> When scanning the users of %v, we will decide that the correct VL for %v is 0 (or a register which might be zero)
IIUC though the only time the VL would be reduced to a register that might be zero is if the VREDSUM also uses the same register for its VL, which would also have to be zero?
Since I thought the `RISCV::isVLKnownLE(*CommonVL, *VLOp)` check guarantees that we will never reduce the VL below anything we return in `getMinimumVLForUser`.
> We may be able to reduce it further to 1.
Agreed, I think we can return either 1 or VLOp. I just think that we don't need to check the value of VLOp here for correctness.
https://github.com/llvm/llvm-project/pull/120345
More information about the llvm-commits
mailing list