@@ -65,7 +65,8 @@ class RISCVVectorPeephole : public MachineFunctionPass {
6565 bool convertToVLMAX (MachineInstr &MI) const ;
6666 bool convertToWholeRegister (MachineInstr &MI) const ;
6767 bool convertToUnmasked (MachineInstr &MI) const ;
68- bool convertVMergeToVMv (MachineInstr &MI) const ;
68+ bool convertAllOnesVMergeToVMv (MachineInstr &MI) const ;
69+ bool convertSameMaskVMergeToVMv (MachineInstr &MI) const ;
6970 bool foldUndefPassthruVMV_V_V (MachineInstr &MI);
7071 bool foldVMV_V_V (MachineInstr &MI);
7172
@@ -342,17 +343,13 @@ bool RISCVVectorPeephole::convertToWholeRegister(MachineInstr &MI) const {
342343 return true ;
343344}
344345
345- // Transform (VMERGE_VVM_<LMUL> pt, false, true, allones, vl, sew) to
346- // (VMV_V_V_<LMUL> pt, true, vl, sew). It may decrease uses of VMSET.
347- bool RISCVVectorPeephole::convertVMergeToVMv (MachineInstr &MI) const {
346+ static unsigned getVMV_V_VOpcodeForVMERGE_VVM (const MachineInstr &MI) {
348347#define CASE_VMERGE_TO_VMV (lmul ) \
349348 case RISCV::PseudoVMERGE_VVM_##lmul: \
350- NewOpc = RISCV::PseudoVMV_V_V_##lmul; \
351- break ;
352- unsigned NewOpc;
349+ return RISCV::PseudoVMV_V_V_##lmul;
353350 switch (MI.getOpcode ()) {
354351 default :
355- return false ;
352+ return 0 ;
356353 CASE_VMERGE_TO_VMV (MF8)
357354 CASE_VMERGE_TO_VMV (MF4)
358355 CASE_VMERGE_TO_VMV (MF2)
@@ -361,14 +358,68 @@ bool RISCVVectorPeephole::convertVMergeToVMv(MachineInstr &MI) const {
361358 CASE_VMERGE_TO_VMV (M4)
362359 CASE_VMERGE_TO_VMV (M8)
363360 }
361+ }
364362
363+ // / Convert a PseudoVMERGE_VVM with an all ones mask to a PseudoVMV_V_V.
364+ // /
365+ // / %x = PseudoVMERGE_VVM %passthru, %false, %true, %allones, sew, vl
366+ // / ->
367+ // / %x = PseudoVMV_V_V %passthru, %true, vl, sew, tu_mu
368+ bool RISCVVectorPeephole::convertAllOnesVMergeToVMv (MachineInstr &MI) const {
369+ unsigned NewOpc = getVMV_V_VOpcodeForVMERGE_VVM (MI);
370+ if (!NewOpc)
371+ return false ;
365372 assert (MI.getOperand (4 ).isReg () && MI.getOperand (4 ).getReg () == RISCV::V0);
366373 if (!isAllOnesMask (V0Defs.lookup (&MI)))
367374 return false ;
368375
369376 MI.setDesc (TII->get (NewOpc));
370- MI.removeOperand (2 ); // False operand
371- MI.removeOperand (3 ); // Mask operand
377+ MI.removeOperand (2 ); // False operand
378+ MI.removeOperand (3 ); // Mask operand
379+ MI.addOperand (
380+ MachineOperand::CreateImm (RISCVII::TAIL_UNDISTURBED_MASK_UNDISTURBED));
381+
382+ // vmv.v.v doesn't have a mask operand, so we may be able to inflate the
383+ // register class for the destination and passthru operands e.g. VRNoV0 -> VR
384+ MRI->recomputeRegClass (MI.getOperand (0 ).getReg ());
385+ if (MI.getOperand (1 ).getReg () != RISCV::NoRegister)
386+ MRI->recomputeRegClass (MI.getOperand (1 ).getReg ());
387+ return true ;
388+ }
389+
390+ // / If a PseudoVMERGE_VVM's true operand is a masked pseudo and both have the
391+ // / same mask, and the masked pseudo's passthru is the same as the false
392+ // / operand, we can convert the PseudoVMERGE_VVM to a PseudoVMV_V_V.
393+ // /
394+ // / %true = PseudoVADD_VV_M1_MASK %false, %x, %y, %mask, vl1, sew, policy
395+ // / %x = PseudoVMERGE_VVM %passthru, %false, %true, %mask, vl2, sew
396+ // / ->
397+ // / %true = PseudoVADD_VV_M1_MASK %false, %x, %y, %mask, vl1, sew, policy
398+ // / %x = PseudoVMV_V_V %passthru, %true, vl2, sew, tu_mu
399+ bool RISCVVectorPeephole::convertSameMaskVMergeToVMv (MachineInstr &MI) const {
400+ unsigned NewOpc = getVMV_V_VOpcodeForVMERGE_VVM (MI);
401+ if (!NewOpc)
402+ return false ;
403+ MachineInstr *True = MRI->getVRegDef (MI.getOperand (3 ).getReg ());
404+ if (!True || !RISCV::getMaskedPseudoInfo (True->getOpcode ()) ||
405+ !hasSameEEW (MI, *True))
406+ return false ;
407+
408+ // True's passthru needs to be equivalent to False
409+ Register TruePassthruReg = True->getOperand (1 ).getReg ();
410+ Register FalseReg = MI.getOperand (2 ).getReg ();
411+ if (TruePassthruReg != RISCV::NoRegister && TruePassthruReg != FalseReg)
412+ return false ;
413+
414+ const MachineInstr *TrueV0Def = V0Defs.lookup (True);
415+ const MachineInstr *MIV0Def = V0Defs.lookup (&MI);
416+ assert (TrueV0Def && TrueV0Def->isCopy () && MIV0Def && MIV0Def->isCopy ());
417+ if (TrueV0Def->getOperand (1 ).getReg () != MIV0Def->getOperand (1 ).getReg ())
418+ return false ;
419+
420+ MI.setDesc (TII->get (NewOpc));
421+ MI.removeOperand (2 ); // False operand
422+ MI.removeOperand (3 ); // Mask operand
372423 MI.addOperand (
373424 MachineOperand::CreateImm (RISCVII::TAIL_UNDISTURBED_MASK_UNDISTURBED));
374425
@@ -623,7 +674,8 @@ bool RISCVVectorPeephole::runOnMachineFunction(MachineFunction &MF) {
623674 Changed |= tryToReduceVL (MI);
624675 Changed |= convertToUnmasked (MI);
625676 Changed |= convertToWholeRegister (MI);
626- Changed |= convertVMergeToVMv (MI);
677+ Changed |= convertAllOnesVMergeToVMv (MI);
678+ Changed |= convertSameMaskVMergeToVMv (MI);
627679 if (foldUndefPassthruVMV_V_V (MI)) {
628680 Changed |= true ;
629681 continue ; // MI is erased
0 commit comments