@@ -62,7 +62,7 @@ struct DemandedVL {
6262};
6363
6464class RISCVVLOptimizer : public MachineFunctionPass {
65- const MachineRegisterInfo *MRI;
65+ MachineRegisterInfo *MRI;
6666 const MachineDominatorTree *MDT;
6767 const TargetInstrInfo *TII;
6868
@@ -1392,6 +1392,41 @@ bool RISCVVLOptimizer::isCandidate(const MachineInstr &MI) const {
13921392 return true ;
13931393}
13941394
1395+ // / Given a vslidedown.vx like:
1396+ // /
1397+ // / %slideamt = ADDI %x, -1
1398+ // / %v = PseudoVSLIDEDOWN_VX %passthru, %src, %slideamt, avl=1
1399+ // /
1400+ // / %v will only read the first %slideamt + 1 lanes of %src, which = %x.
1401+ // / This is a common case when lowering extractelement.
1402+ // /
1403+ // / Note that if %x is 0, %slideamt will be all ones. In this case %src will be
1404+ // / completely slid down and none of its lanes will be read (since %slideamt is
1405+ // / greater than the largest VLMAX of 65536) so we can demand any minimum VL.
1406+ static std::optional<DemandedVL>
1407+ getMinimumVLForVSLIDEDOWN_VX (const MachineOperand &UserOp,
1408+ const MachineRegisterInfo *MRI) {
1409+ const MachineInstr &MI = *UserOp.getParent ();
1410+ if (RISCV::getRVVMCOpcode (MI.getOpcode ()) != RISCV::VSLIDEDOWN_VX)
1411+ return std::nullopt ;
1412+ // We're looking at what lanes are used from the src operand.
1413+ if (UserOp.getOperandNo () != 2 )
1414+ return std::nullopt ;
1415+ // For now, the AVL must be 1.
1416+ const MachineOperand &AVL = MI.getOperand (4 );
1417+ if (!AVL.isImm () || AVL.getImm () != 1 )
1418+ return std::nullopt ;
1419+ // The slide amount must be %x - 1.
1420+ const MachineOperand &SlideAmt = MI.getOperand (3 );
1421+ if (!SlideAmt.getReg ().isVirtual ())
1422+ return std::nullopt ;
1423+ MachineInstr *SlideAmtDef = MRI->getUniqueVRegDef (SlideAmt.getReg ());
1424+ if (SlideAmtDef->getOpcode () != RISCV::ADDI ||
1425+ SlideAmtDef->getOperand (2 ).getImm () != -AVL.getImm ())
1426+ return std::nullopt ;
1427+ return SlideAmtDef->getOperand (1 );
1428+ }
1429+
13951430DemandedVL
13961431RISCVVLOptimizer::getMinimumVLForUser (const MachineOperand &UserOp) const {
13971432 const MachineInstr &UserMI = *UserOp.getParent ();
@@ -1406,6 +1441,9 @@ RISCVVLOptimizer::getMinimumVLForUser(const MachineOperand &UserOp) const {
14061441 return DemandedVL::vlmax ();
14071442 }
14081443
1444+ if (auto VL = getMinimumVLForVSLIDEDOWN_VX (UserOp, MRI))
1445+ return *VL;
1446+
14091447 if (RISCVII::readsPastVL (
14101448 TII->get (RISCV::getRVVMCOpcode (UserMI.getOpcode ())).TSFlags )) {
14111449 LLVM_DEBUG (dbgs () << " Abort because used by unsafe instruction\n " );
@@ -1624,6 +1662,7 @@ bool RISCVVLOptimizer::tryReduceVL(MachineInstr &MI) const {
16241662
16251663 // All our checks passed. We can reduce VL.
16261664 VLOp.ChangeToRegister (CommonVL->getReg (), false );
1665+ MRI->constrainRegClass (CommonVL->getReg (), &RISCV::GPRNoX0RegClass);
16271666 return true ;
16281667}
16291668
0 commit comments