@@ -65,7 +65,8 @@ class RISCVVectorPeephole : public MachineFunctionPass {
65
65
bool convertToVLMAX (MachineInstr &MI) const ;
66
66
bool convertToWholeRegister (MachineInstr &MI) const ;
67
67
bool convertToUnmasked (MachineInstr &MI) const ;
68
- bool convertVMergeToVMv (MachineInstr &MI) const ;
68
+ bool convertAllOnesVMergeToVMv (MachineInstr &MI) const ;
69
+ bool convertSameMaskVMergeToVMv (MachineInstr &MI) const ;
69
70
bool foldUndefPassthruVMV_V_V (MachineInstr &MI);
70
71
bool foldVMV_V_V (MachineInstr &MI);
71
72
@@ -342,17 +343,14 @@ bool RISCVVectorPeephole::convertToWholeRegister(MachineInstr &MI) const {
342
343
return true ;
343
344
}
344
345
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) {
348
347
#define CASE_VMERGE_TO_VMV (lmul ) \
349
348
case RISCV::PseudoVMERGE_VVM_##lmul: \
350
- NewOpc = RISCV::PseudoVMV_V_V_##lmul; \
349
+ return RISCV::PseudoVMV_V_V_##lmul; \
351
350
break ;
352
- unsigned NewOpc;
353
351
switch (MI.getOpcode ()) {
354
352
default :
355
- return false ;
353
+ return 0 ;
356
354
CASE_VMERGE_TO_VMV (MF8)
357
355
CASE_VMERGE_TO_VMV (MF4)
358
356
CASE_VMERGE_TO_VMV (MF2)
@@ -361,14 +359,68 @@ bool RISCVVectorPeephole::convertVMergeToVMv(MachineInstr &MI) const {
361
359
CASE_VMERGE_TO_VMV (M4)
362
360
CASE_VMERGE_TO_VMV (M8)
363
361
}
362
+ }
364
363
364
+ // / Convert a PseudoVMERGE_VVM with an all ones mask to a PseudoVMV_V_V.
365
+ // /
366
+ // / %x = PseudoVMERGE_VVM %passthru, %false, %true, %allones, sew, vl
367
+ // / ->
368
+ // / %x = PseudoVMV_V_V %passthru, %true, vl, sew, tu_mu
369
+ bool RISCVVectorPeephole::convertAllOnesVMergeToVMv (MachineInstr &MI) const {
370
+ unsigned NewOpc = getVMV_V_VOpcodeForVMERGE_VVM (MI);
371
+ if (!NewOpc)
372
+ return false ;
365
373
assert (MI.getOperand (4 ).isReg () && MI.getOperand (4 ).getReg () == RISCV::V0);
366
374
if (!isAllOnesMask (V0Defs.lookup (&MI)))
367
375
return false ;
368
376
369
377
MI.setDesc (TII->get (NewOpc));
370
- MI.removeOperand (2 ); // False operand
371
- MI.removeOperand (3 ); // Mask operand
378
+ MI.removeOperand (2 ); // False operand
379
+ MI.removeOperand (3 ); // Mask operand
380
+ MI.addOperand (
381
+ MachineOperand::CreateImm (RISCVII::TAIL_UNDISTURBED_MASK_UNDISTURBED));
382
+
383
+ // vmv.v.v doesn't have a mask operand, so we may be able to inflate the
384
+ // register class for the destination and passthru operands e.g. VRNoV0 -> VR
385
+ MRI->recomputeRegClass (MI.getOperand (0 ).getReg ());
386
+ if (MI.getOperand (1 ).getReg () != RISCV::NoRegister)
387
+ MRI->recomputeRegClass (MI.getOperand (1 ).getReg ());
388
+ return true ;
389
+ }
390
+
391
+ // / If a PseudoVMERGE_VVM's true operand is a masked pseudo and both have the
392
+ // / same mask, and the masked pseudo's passthru is the same as the false
393
+ // / operand, we can convert the PseudoVMERGE_VVM to a PseudoVMV_V_V.
394
+ // /
395
+ // / %true = PseudoVADD_VV_M1_MASK %false, %x, %y, %mask, vl1, sew, policy
396
+ // / %x = PseudoVMERGE_VVM %passthru, %false, %true, %mask, vl2, sew
397
+ // / ->
398
+ // / %true = PseudoVADD_VV_M1_MASK %false, %x, %y, %mask, vl1, sew, policy
399
+ // / %x = PseudoVMV_V_V %passthru, %true, vl2, sew, tu_mu
400
+ bool RISCVVectorPeephole::convertSameMaskVMergeToVMv (MachineInstr &MI) const {
401
+ unsigned NewOpc = getVMV_V_VOpcodeForVMERGE_VVM (MI);
402
+ if (!NewOpc)
403
+ return false ;
404
+ MachineInstr *True = MRI->getVRegDef (MI.getOperand (3 ).getReg ());
405
+ if (!True || !RISCV::getMaskedPseudoInfo (True->getOpcode ()) ||
406
+ !hasSameEEW (MI, *True))
407
+ return false ;
408
+
409
+ // True's passthru needs to be equivalent to False
410
+ Register TruePassthruReg = True->getOperand (1 ).getReg ();
411
+ Register FalseReg = MI.getOperand (2 ).getReg ();
412
+ if (TruePassthruReg != RISCV::NoRegister && TruePassthruReg != FalseReg)
413
+ return false ;
414
+
415
+ const MachineInstr *TrueV0Def = V0Defs.lookup (True);
416
+ const MachineInstr *MIV0Def = V0Defs.lookup (&MI);
417
+ assert (TrueV0Def->isCopy () && MIV0Def->isCopy ());
418
+ if (TrueV0Def->getOperand (1 ).getReg () != MIV0Def->getOperand (1 ).getReg ())
419
+ return false ;
420
+
421
+ MI.setDesc (TII->get (NewOpc));
422
+ MI.removeOperand (2 ); // False operand
423
+ MI.removeOperand (3 ); // Mask operand
372
424
MI.addOperand (
373
425
MachineOperand::CreateImm (RISCVII::TAIL_UNDISTURBED_MASK_UNDISTURBED));
374
426
@@ -622,7 +674,8 @@ bool RISCVVectorPeephole::runOnMachineFunction(MachineFunction &MF) {
622
674
Changed |= tryToReduceVL (MI);
623
675
Changed |= convertToUnmasked (MI);
624
676
Changed |= convertToWholeRegister (MI);
625
- Changed |= convertVMergeToVMv (MI);
677
+ Changed |= convertAllOnesVMergeToVMv (MI);
678
+ Changed |= convertSameMaskVMergeToVMv (MI);
626
679
if (foldUndefPassthruVMV_V_V (MI)) {
627
680
Changed |= true ;
628
681
continue ; // MI is erased
0 commit comments