[llvm] [RISCV] Move vmv.v.v peephole from SelectionDAG to RISCVVectorPeephole (PR #100367)
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 29 08:37:06 PDT 2024
================
@@ -297,6 +298,143 @@ bool RISCVVectorPeephole::convertToUnmasked(MachineInstr &MI) const {
return true;
}
+/// Given two VL operands, returns the one known to be the smallest or nullptr
+/// if unknown.
+static const MachineOperand *getKnownMinVL(const MachineOperand *LHS,
+ const MachineOperand *RHS) {
+ if (LHS->isReg() && RHS->isReg() && LHS->getReg().isVirtual() &&
+ LHS->getReg() == RHS->getReg())
+ return LHS;
+ if (LHS->isImm() && LHS->getImm() == RISCV::VLMaxSentinel)
+ return RHS;
+ if (RHS->isImm() && RHS->getImm() == RISCV::VLMaxSentinel)
+ return LHS;
+ if (!LHS->isImm() || !RHS->isImm())
+ return nullptr;
+ return LHS->getImm() <= RHS->getImm() ? LHS : RHS;
+}
+
+/// Check if it's safe to move From down to To, checking that no physical
+/// registers are clobbered.
+static bool isSafeToMove(const MachineInstr &From, const MachineInstr &To) {
+ assert(From.getParent() == To.getParent() && !From.hasImplicitDef());
+ SmallVector<Register> PhysUses;
+ for (const MachineOperand &MO : From.all_uses())
+ if (MO.getReg().isPhysical())
+ PhysUses.push_back(MO.getReg());
+ bool SawStore = false;
+ for (auto II = From.getIterator(); II != To.getIterator(); II++) {
+ for (Register PhysReg : PhysUses)
+ if (II->definesRegister(PhysReg, nullptr))
+ return false;
+ if (II->mayStore()) {
+ SawStore = true;
+ break;
+ }
+ }
+ return From.isSafeToMove(nullptr, SawStore);
+}
+
+static const RISCV::RISCVMaskedPseudoInfo *
+lookupMaskedPseudoInfo(const MachineInstr &MI) {
+ const RISCV::RISCVMaskedPseudoInfo *Info =
+ RISCV::lookupMaskedIntrinsicByUnmasked(MI.getOpcode());
+ if (!Info)
+ Info = RISCV::getMaskedPseudoInfo(MI.getOpcode());
+ return Info;
+}
+
+/// If a PseudoVMV_V_V is the only user of it's input, fold its passthru and VL
+/// into it.
+///
+/// %x = PseudoVADD_V_V_M1 %passthru, %a, %b, %vl, sew, policy
+/// %y = PseudoVMV_V_V_M1 %passthru, %x, %vl, sew, policy
+///
+/// ->
+///
+/// %y = PseudoVADD_V_V_M1 %passthru, %a, %b, %vl, sew, policy
+bool RISCVVectorPeephole::foldVMV_V_V(MachineInstr &MI) {
+ if (RISCV::getRVVMCOpcode(MI.getOpcode()) != RISCV::VMV_V_V)
+ return false;
+
+ MachineOperand &Passthru = MI.getOperand(1);
+ MachineInstr *Src = MRI->getVRegDef(MI.getOperand(2).getReg());
+
+ if (!MRI->hasOneUse(MI.getOperand(2).getReg()))
+ return false;
+
+ if (!Src || Src->hasUnmodeledSideEffects() ||
+ Src->getParent() != MI.getParent())
+ return false;
+
+ // Src needs to be a pseudo that's opted into this transform.
+ const RISCV::RISCVMaskedPseudoInfo *Info = lookupMaskedPseudoInfo(*Src);
----------------
preames wrote:
Okay, there's a very non-obvious thing happening here. You're looking up the masked version, but only to check if it has the ActiveElementsAffectResult, and you're assuming that the unmasked variant has the flag exactly when the masked variant does. I believe this does hold. Would you mind extracting a helper function which returns ActiveElementsAffectResult (not Info), and includes comments to that effect? This code confused me.
https://github.com/llvm/llvm-project/pull/100367
More information about the llvm-commits
mailing list