[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
Thu Jan 2 18:51:07 PST 2025
================
@@ -963,46 +1031,58 @@ bool RISCVVLOptimizer::checkUsers(const MachineOperand *&CommonVL,
break;
}
- const MCInstrDesc &Desc = UserMI.getDesc();
- if (!RISCVII::hasVLOp(Desc.TSFlags) || !RISCVII::hasSEWOp(Desc.TSFlags)) {
- LLVM_DEBUG(dbgs() << " Abort due to lack of VL or SEW, assume that"
- " use VLMAX\n");
+ auto VLOp = getVLForUser(UserOp);
+ if (!VLOp) {
CanReduceVL = false;
break;
}
- unsigned VLOpNum = RISCVII::getVLOpNum(Desc);
- const MachineOperand &VLOp = UserMI.getOperand(VLOpNum);
-
- // Looking for an immediate or a register VL that isn't X0.
- assert((!VLOp.isReg() || VLOp.getReg() != RISCV::X0) &&
- "Did not expect X0 VL");
-
// Use the largest VL among all the users. If we cannot determine this
// statically, then we cannot optimize the VL.
- if (!CommonVL || RISCV::isVLKnownLE(*CommonVL, VLOp)) {
- CommonVL = &VLOp;
+ if (!CommonVL || RISCV::isVLKnownLE(*CommonVL, *VLOp)) {
+ CommonVL.emplace(*VLOp);
LLVM_DEBUG(dbgs() << " User VL is: " << VLOp << "\n");
- } else if (!RISCV::isVLKnownLE(VLOp, *CommonVL)) {
+ } else if (!RISCV::isVLKnownLE(*VLOp, *CommonVL)) {
LLVM_DEBUG(dbgs() << " Abort because cannot determine a common VL\n");
CanReduceVL = false;
break;
}
- // The SEW and LMUL of destination and source registers need to match.
+ if (!RISCVII::hasSEWOp(UserMI.getDesc().TSFlags)) {
+ LLVM_DEBUG(dbgs() << " Abort due to lack of SEW operand\n");
+ CanReduceVL = false;
+ break;
+ }
+
OperandInfo ConsumerInfo = getOperandInfo(UserOp, MRI);
OperandInfo ProducerInfo = getOperandInfo(MI.getOperand(0), MRI);
- if (ConsumerInfo.isUnknown() || ProducerInfo.isUnknown() ||
- !OperandInfo::EMULAndEEWAreEqual(ConsumerInfo, ProducerInfo)) {
- LLVM_DEBUG(dbgs() << " Abort due to incompatible or unknown "
- "information for EMUL or EEW.\n");
+ if (ConsumerInfo.isUnknown() || ProducerInfo.isUnknown()) {
+ LLVM_DEBUG(dbgs() << " Abort due to unknown operand information.\n");
+ LLVM_DEBUG(dbgs() << " ConsumerInfo is: " << ConsumerInfo << "\n");
+ LLVM_DEBUG(dbgs() << " ProducerInfo is: " << ProducerInfo << "\n");
+ CanReduceVL = false;
+ break;
+ }
+
+ // If the operand is used as a scalar operand, then the EEW must be
+ // compatible. Otherwise, the EMUL *and* EEW must be compatible.
+ if ((isVectorOpUsedAsScalarOp(UserOp) &&
+ !OperandInfo::EEWAreEqual(ConsumerInfo, ProducerInfo)) ||
+ (!isVectorOpUsedAsScalarOp(UserOp) &&
+ !OperandInfo::EMULAndEEWAreEqual(ConsumerInfo, ProducerInfo))) {
+ LLVM_DEBUG(
+ dbgs()
+ << " Abort due to incompatible information for EMUL or EEW.\n");
LLVM_DEBUG(dbgs() << " ConsumerInfo is: " << ConsumerInfo << "\n");
LLVM_DEBUG(dbgs() << " ProducerInfo is: " << ProducerInfo << "\n");
CanReduceVL = false;
break;
}
}
- return CanReduceVL;
+
+ return CanReduceVL && CommonVL
+ ? std::make_optional<const MachineOperand>(*CommonVL)
+ : std::nullopt;
----------------
lukel97 wrote:
Nit, would it be simpler if we just returned std::nullopt where we have `CanReduceVL = false; break` and then returned CommonVL directly here
https://github.com/llvm/llvm-project/pull/120345
More information about the llvm-commits
mailing list