[llvm] [RISCV] Move vmerge same mask peephole to RISCVVectorPeephole (PR #106108)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 5 16:55:12 PDT 2024
================
@@ -361,14 +359,68 @@ bool RISCVVectorPeephole::convertVMergeToVMv(MachineInstr &MI) const {
CASE_VMERGE_TO_VMV(M4)
CASE_VMERGE_TO_VMV(M8)
}
+}
+/// Convert a PseudoVMERGE_VVM with an all ones mask to a PseudoVMV_V_V.
+///
+/// %x = PseudoVMERGE_VVM %passthru, %false, %true, %allones, sew, vl
+/// ->
+/// %x = PseudoVMV_V_V %passthru, %true, vl, sew, tu_mu
+bool RISCVVectorPeephole::convertAllOnesVMergeToVMv(MachineInstr &MI) const {
+ unsigned NewOpc = getVMV_V_VOpcodeForVMERGE_VVM(MI);
+ if (!NewOpc)
+ return false;
assert(MI.getOperand(4).isReg() && MI.getOperand(4).getReg() == RISCV::V0);
if (!isAllOnesMask(V0Defs.lookup(&MI)))
return false;
MI.setDesc(TII->get(NewOpc));
- MI.removeOperand(2); // False operand
- MI.removeOperand(3); // Mask operand
+ MI.removeOperand(2); // False operand
+ MI.removeOperand(3); // Mask operand
+ MI.addOperand(
+ MachineOperand::CreateImm(RISCVII::TAIL_UNDISTURBED_MASK_UNDISTURBED));
+
+ // vmv.v.v doesn't have a mask operand, so we may be able to inflate the
+ // register class for the destination and passthru operands e.g. VRNoV0 -> VR
+ MRI->recomputeRegClass(MI.getOperand(0).getReg());
+ if (MI.getOperand(1).getReg() != RISCV::NoRegister)
+ MRI->recomputeRegClass(MI.getOperand(1).getReg());
+ return true;
+}
+
+/// If a PseudoVMERGE_VVM's true operand is a masked pseudo and both have the
+/// same mask, and the masked pseudo's passthru is the same as the false
+/// operand, we can convert the PseudoVMERGE_VVM to a PseudoVMV_V_V.
+///
+/// %true = PseudoVADD_VV_M1_MASK %false, %x, %y, %mask, vl1, sew, policy
+/// %x = PseudoVMERGE_VVM %passthru, %false, %true, %mask, vl2, sew
+/// ->
+/// %true = PseudoVADD_VV_M1_MASK %false, %x, %y, %mask, vl1, sew, policy
+/// %x = PseudoVMV_V_V %passthru, %true, vl2, sew, tu_mu
+bool RISCVVectorPeephole::convertSameMaskVMergeToVMv(MachineInstr &MI) const {
+ unsigned NewOpc = getVMV_V_VOpcodeForVMERGE_VVM(MI);
+ if (!NewOpc)
+ return false;
+ MachineInstr *True = MRI->getVRegDef(MI.getOperand(3).getReg());
+ if (!True || !RISCV::getMaskedPseudoInfo(True->getOpcode()) ||
+ !hasSameEEW(MI, *True))
+ return false;
+
+ // True's passthru needs to be equivalent to False
+ Register TruePassthruReg = True->getOperand(1).getReg();
+ Register FalseReg = MI.getOperand(2).getReg();
+ if (TruePassthruReg != RISCV::NoRegister && TruePassthruReg != FalseReg)
+ return false;
+
+ const MachineInstr *TrueV0Def = V0Defs.lookup(True);
+ const MachineInstr *MIV0Def = V0Defs.lookup(&MI);
+ assert(TrueV0Def->isCopy() && MIV0Def->isCopy());
----------------
topperc wrote:
Yes. But the assert seemed better than a crash for an asserts build.
https://github.com/llvm/llvm-project/pull/106108
More information about the llvm-commits
mailing list