xref: /llvm-project/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp (revision 8675cd3facc063673c47ed585bd4b7013119fe1f)
11c94388fSMichael Maitland //===-------------- RISCVVLOptimizer.cpp - VL Optimizer -------------------===//
21c94388fSMichael Maitland //
31c94388fSMichael Maitland // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41c94388fSMichael Maitland // See https://llvm.org/LICENSE.txt for license information.
51c94388fSMichael Maitland // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61c94388fSMichael Maitland //
71c94388fSMichael Maitland //===---------------------------------------------------------------------===//
81c94388fSMichael Maitland //
91c94388fSMichael Maitland // This pass reduces the VL where possible at the MI level, before VSETVLI
101c94388fSMichael Maitland // instructions are inserted.
111c94388fSMichael Maitland //
121c94388fSMichael Maitland // The purpose of this optimization is to make the VL argument, for instructions
131c94388fSMichael Maitland // that have a VL argument, as small as possible. This is implemented by
141c94388fSMichael Maitland // visiting each instruction in reverse order and checking that if it has a VL
151c94388fSMichael Maitland // argument, whether the VL can be reduced.
161c94388fSMichael Maitland //
171c94388fSMichael Maitland //===---------------------------------------------------------------------===//
181c94388fSMichael Maitland 
191c94388fSMichael Maitland #include "RISCV.h"
201c94388fSMichael Maitland #include "RISCVSubtarget.h"
21*8675cd3fSLuke Lau #include "llvm/ADT/PostOrderIterator.h"
221c94388fSMichael Maitland #include "llvm/CodeGen/MachineDominators.h"
231c94388fSMichael Maitland #include "llvm/CodeGen/MachineFunctionPass.h"
241c94388fSMichael Maitland #include "llvm/InitializePasses.h"
251c94388fSMichael Maitland 
261c94388fSMichael Maitland using namespace llvm;
271c94388fSMichael Maitland 
281c94388fSMichael Maitland #define DEBUG_TYPE "riscv-vl-optimizer"
291c94388fSMichael Maitland #define PASS_NAME "RISC-V VL Optimizer"
301c94388fSMichael Maitland 
311c94388fSMichael Maitland namespace {
321c94388fSMichael Maitland 
331c94388fSMichael Maitland class RISCVVLOptimizer : public MachineFunctionPass {
341c94388fSMichael Maitland   const MachineRegisterInfo *MRI;
351c94388fSMichael Maitland   const MachineDominatorTree *MDT;
361c94388fSMichael Maitland 
371c94388fSMichael Maitland public:
381c94388fSMichael Maitland   static char ID;
391c94388fSMichael Maitland 
401c94388fSMichael Maitland   RISCVVLOptimizer() : MachineFunctionPass(ID) {}
411c94388fSMichael Maitland 
421c94388fSMichael Maitland   bool runOnMachineFunction(MachineFunction &MF) override;
431c94388fSMichael Maitland 
441c94388fSMichael Maitland   void getAnalysisUsage(AnalysisUsage &AU) const override {
451c94388fSMichael Maitland     AU.setPreservesCFG();
461c94388fSMichael Maitland     AU.addRequired<MachineDominatorTreeWrapperPass>();
471c94388fSMichael Maitland     MachineFunctionPass::getAnalysisUsage(AU);
481c94388fSMichael Maitland   }
491c94388fSMichael Maitland 
501c94388fSMichael Maitland   StringRef getPassName() const override { return PASS_NAME; }
511c94388fSMichael Maitland 
521c94388fSMichael Maitland private:
53142787d3SMichael Maitland   std::optional<MachineOperand> getMinimumVLForUser(MachineOperand &UserOp);
54142787d3SMichael Maitland   /// Returns the largest common VL MachineOperand that may be used to optimize
55142787d3SMichael Maitland   /// MI. Returns std::nullopt if it failed to find a suitable VL.
56142787d3SMichael Maitland   std::optional<MachineOperand> checkUsers(MachineInstr &MI);
571c94388fSMichael Maitland   bool tryReduceVL(MachineInstr &MI);
581c94388fSMichael Maitland   bool isCandidate(const MachineInstr &MI) const;
59*8675cd3fSLuke Lau 
60*8675cd3fSLuke Lau   /// For a given instruction, records what elements of it are demanded by
61*8675cd3fSLuke Lau   /// downstream users.
62*8675cd3fSLuke Lau   DenseMap<const MachineInstr *, std::optional<MachineOperand>> DemandedVLs;
631c94388fSMichael Maitland };
641c94388fSMichael Maitland 
651c94388fSMichael Maitland } // end anonymous namespace
661c94388fSMichael Maitland 
671c94388fSMichael Maitland char RISCVVLOptimizer::ID = 0;
681c94388fSMichael Maitland INITIALIZE_PASS_BEGIN(RISCVVLOptimizer, DEBUG_TYPE, PASS_NAME, false, false)
691c94388fSMichael Maitland INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
701c94388fSMichael Maitland INITIALIZE_PASS_END(RISCVVLOptimizer, DEBUG_TYPE, PASS_NAME, false, false)
711c94388fSMichael Maitland 
721c94388fSMichael Maitland FunctionPass *llvm::createRISCVVLOptimizerPass() {
731c94388fSMichael Maitland   return new RISCVVLOptimizer();
741c94388fSMichael Maitland }
751c94388fSMichael Maitland 
761c94388fSMichael Maitland /// Return true if R is a physical or virtual vector register, false otherwise.
771c94388fSMichael Maitland static bool isVectorRegClass(Register R, const MachineRegisterInfo *MRI) {
781c94388fSMichael Maitland   if (R.isPhysical())
791c94388fSMichael Maitland     return RISCV::VRRegClass.contains(R);
801c94388fSMichael Maitland   const TargetRegisterClass *RC = MRI->getRegClass(R);
811c94388fSMichael Maitland   return RISCVRI::isVRegClass(RC->TSFlags);
821c94388fSMichael Maitland }
831c94388fSMichael Maitland 
841c94388fSMichael Maitland /// Represents the EMUL and EEW of a MachineOperand.
851c94388fSMichael Maitland struct OperandInfo {
861c94388fSMichael Maitland   // Represent as 1,2,4,8, ... and fractional indicator. This is because
871c94388fSMichael Maitland   // EMUL can take on values that don't map to RISCVII::VLMUL values exactly.
881c94388fSMichael Maitland   // For example, a mask operand can have an EMUL less than MF8.
891c94388fSMichael Maitland   std::optional<std::pair<unsigned, bool>> EMUL;
901c94388fSMichael Maitland 
911c94388fSMichael Maitland   unsigned Log2EEW;
921c94388fSMichael Maitland 
931c94388fSMichael Maitland   OperandInfo(RISCVII::VLMUL EMUL, unsigned Log2EEW)
940b4fca5bSPhilip Reames       : EMUL(RISCVVType::decodeVLMUL(EMUL)), Log2EEW(Log2EEW) {}
951c94388fSMichael Maitland 
961c94388fSMichael Maitland   OperandInfo(std::pair<unsigned, bool> EMUL, unsigned Log2EEW)
970b4fca5bSPhilip Reames       : EMUL(EMUL), Log2EEW(Log2EEW) {}
981c94388fSMichael Maitland 
990b4fca5bSPhilip Reames   OperandInfo(unsigned Log2EEW) : Log2EEW(Log2EEW) {}
100142787d3SMichael Maitland 
1010b4fca5bSPhilip Reames   OperandInfo() = delete;
1021c94388fSMichael Maitland 
1031c94388fSMichael Maitland   static bool EMULAndEEWAreEqual(const OperandInfo &A, const OperandInfo &B) {
1041c94388fSMichael Maitland     return A.Log2EEW == B.Log2EEW && A.EMUL->first == B.EMUL->first &&
1051c94388fSMichael Maitland            A.EMUL->second == B.EMUL->second;
1061c94388fSMichael Maitland   }
1071c94388fSMichael Maitland 
108142787d3SMichael Maitland   static bool EEWAreEqual(const OperandInfo &A, const OperandInfo &B) {
109142787d3SMichael Maitland     return A.Log2EEW == B.Log2EEW;
110142787d3SMichael Maitland   }
111142787d3SMichael Maitland 
1121c94388fSMichael Maitland   void print(raw_ostream &OS) const {
1130b4fca5bSPhilip Reames     if (EMUL) {
114f7468a25SCraig Topper       OS << "EMUL: m";
1151c94388fSMichael Maitland       if (EMUL->second)
116f7468a25SCraig Topper         OS << "f";
117f7468a25SCraig Topper       OS << EMUL->first;
1180b4fca5bSPhilip Reames     } else
1190b4fca5bSPhilip Reames       OS << "EMUL: unknown\n";
1201c94388fSMichael Maitland     OS << ", EEW: " << (1 << Log2EEW);
1211c94388fSMichael Maitland   }
1221c94388fSMichael Maitland };
1231c94388fSMichael Maitland 
1248b179162SJie Fu LLVM_ATTRIBUTE_UNUSED
1251c94388fSMichael Maitland static raw_ostream &operator<<(raw_ostream &OS, const OperandInfo &OI) {
1261c94388fSMichael Maitland   OI.print(OS);
1271c94388fSMichael Maitland   return OS;
1281c94388fSMichael Maitland }
1291c94388fSMichael Maitland 
1300b4fca5bSPhilip Reames LLVM_ATTRIBUTE_UNUSED
1310b4fca5bSPhilip Reames static raw_ostream &operator<<(raw_ostream &OS,
1320b4fca5bSPhilip Reames                                const std::optional<OperandInfo> &OI) {
1330b4fca5bSPhilip Reames   if (OI)
1340b4fca5bSPhilip Reames     OI->print(OS);
1350b4fca5bSPhilip Reames   else
1360b4fca5bSPhilip Reames     OS << "nullopt";
1370b4fca5bSPhilip Reames   return OS;
1380b4fca5bSPhilip Reames }
1390b4fca5bSPhilip Reames 
1401c94388fSMichael Maitland namespace llvm {
1411c94388fSMichael Maitland namespace RISCVVType {
1421c94388fSMichael Maitland /// Return EMUL = (EEW / SEW) * LMUL where EEW comes from Log2EEW and LMUL and
1431c94388fSMichael Maitland /// SEW are from the TSFlags of MI.
1441c94388fSMichael Maitland static std::pair<unsigned, bool>
1451c94388fSMichael Maitland getEMULEqualsEEWDivSEWTimesLMUL(unsigned Log2EEW, const MachineInstr &MI) {
1461c94388fSMichael Maitland   RISCVII::VLMUL MIVLMUL = RISCVII::getLMul(MI.getDesc().TSFlags);
1471c94388fSMichael Maitland   auto [MILMUL, MILMULIsFractional] = RISCVVType::decodeVLMUL(MIVLMUL);
1481c94388fSMichael Maitland   unsigned MILog2SEW =
1491c94388fSMichael Maitland       MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
150d99c9994SMichael Maitland 
151d99c9994SMichael Maitland   // Mask instructions will have 0 as the SEW operand. But the LMUL of these
152d99c9994SMichael Maitland   // instructions is calculated is as if the SEW operand was 3 (e8).
153d99c9994SMichael Maitland   if (MILog2SEW == 0)
154d99c9994SMichael Maitland     MILog2SEW = 3;
155d99c9994SMichael Maitland 
1561c94388fSMichael Maitland   unsigned MISEW = 1 << MILog2SEW;
1571c94388fSMichael Maitland 
1581c94388fSMichael Maitland   unsigned EEW = 1 << Log2EEW;
1591c94388fSMichael Maitland   // Calculate (EEW/SEW)*LMUL preserving fractions less than 1. Use GCD
1601c94388fSMichael Maitland   // to put fraction in simplest form.
1611c94388fSMichael Maitland   unsigned Num = EEW, Denom = MISEW;
1621c94388fSMichael Maitland   int GCD = MILMULIsFractional ? std::gcd(Num, Denom * MILMUL)
1631c94388fSMichael Maitland                                : std::gcd(Num * MILMUL, Denom);
1641c94388fSMichael Maitland   Num = MILMULIsFractional ? Num / GCD : Num * MILMUL / GCD;
1651c94388fSMichael Maitland   Denom = MILMULIsFractional ? Denom * MILMUL / GCD : Denom / GCD;
1661c94388fSMichael Maitland   return std::make_pair(Num > Denom ? Num : Denom, Denom > Num);
1671c94388fSMichael Maitland }
1681c94388fSMichael Maitland } // end namespace RISCVVType
1691c94388fSMichael Maitland } // end namespace llvm
1701c94388fSMichael Maitland 
171983a9577SPhilip Reames /// Dest has EEW=SEW. Source EEW=SEW/Factor (i.e. F2 => EEW/2).
172983a9577SPhilip Reames /// SEW comes from TSFlags of MI.
173983a9577SPhilip Reames static unsigned getIntegerExtensionOperandEEW(unsigned Factor,
1741c94388fSMichael Maitland                                               const MachineInstr &MI,
1751c94388fSMichael Maitland                                               const MachineOperand &MO) {
1761c94388fSMichael Maitland   unsigned MILog2SEW =
1771c94388fSMichael Maitland       MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
1781c94388fSMichael Maitland 
1791c94388fSMichael Maitland   if (MO.getOperandNo() == 0)
180983a9577SPhilip Reames     return MILog2SEW;
1811c94388fSMichael Maitland 
1821c94388fSMichael Maitland   unsigned MISEW = 1 << MILog2SEW;
1831c94388fSMichael Maitland   unsigned EEW = MISEW / Factor;
1841c94388fSMichael Maitland   unsigned Log2EEW = Log2_32(EEW);
1851c94388fSMichael Maitland 
186983a9577SPhilip Reames   return Log2EEW;
1871c94388fSMichael Maitland }
1881c94388fSMichael Maitland 
1891c94388fSMichael Maitland /// Check whether MO is a mask operand of MI.
1901c94388fSMichael Maitland static bool isMaskOperand(const MachineInstr &MI, const MachineOperand &MO,
1911c94388fSMichael Maitland                           const MachineRegisterInfo *MRI) {
1921c94388fSMichael Maitland 
1931c94388fSMichael Maitland   if (!MO.isReg() || !isVectorRegClass(MO.getReg(), MRI))
1941c94388fSMichael Maitland     return false;
1951c94388fSMichael Maitland 
1961c94388fSMichael Maitland   const MCInstrDesc &Desc = MI.getDesc();
1971c94388fSMichael Maitland   return Desc.operands()[MO.getOperandNo()].RegClass == RISCV::VMV0RegClassID;
1981c94388fSMichael Maitland }
1991c94388fSMichael Maitland 
200983a9577SPhilip Reames static std::optional<unsigned>
201983a9577SPhilip Reames getOperandLog2EEW(const MachineOperand &MO, const MachineRegisterInfo *MRI) {
202f8ad6e0cSLuke Lau   const MachineInstr &MI = *MO.getParent();
2031c94388fSMichael Maitland   const RISCVVPseudosTable::PseudoInfo *RVV =
2041c94388fSMichael Maitland       RISCVVPseudosTable::getPseudoInfo(MI.getOpcode());
2051c94388fSMichael Maitland   assert(RVV && "Could not find MI in PseudoTable");
2061c94388fSMichael Maitland 
207983a9577SPhilip Reames   // MI has a SEW associated with it. The RVV specification defines
208983a9577SPhilip Reames   // the EEW of each operand and definition in relation to MI.SEW.
2091c94388fSMichael Maitland   unsigned MILog2SEW =
2101c94388fSMichael Maitland       MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
2111c94388fSMichael Maitland 
2121c94388fSMichael Maitland   const bool HasPassthru = RISCVII::isFirstDefTiedToFirstUse(MI.getDesc());
213437e1a70SLuke Lau   const bool IsTied = RISCVII::isTiedPseudo(MI.getDesc().TSFlags);
2141c94388fSMichael Maitland 
2151c94388fSMichael Maitland   bool IsMODef = MO.getOperandNo() == 0;
2161c94388fSMichael Maitland 
217983a9577SPhilip Reames   // All mask operands have EEW=1
2181c94388fSMichael Maitland   if (isMaskOperand(MI, MO, MRI))
219983a9577SPhilip Reames     return 0;
2201c94388fSMichael Maitland 
2211c94388fSMichael Maitland   // switch against BaseInstr to reduce number of cases that need to be
2221c94388fSMichael Maitland   // considered.
2231c94388fSMichael Maitland   switch (RVV->BaseInstr) {
2241c94388fSMichael Maitland 
2251c94388fSMichael Maitland   // 6. Configuration-Setting Instructions
2261c94388fSMichael Maitland   // Configuration setting instructions do not read or write vector registers
2271c94388fSMichael Maitland   case RISCV::VSETIVLI:
2281c94388fSMichael Maitland   case RISCV::VSETVL:
2291c94388fSMichael Maitland   case RISCV::VSETVLI:
2301c94388fSMichael Maitland     llvm_unreachable("Configuration setting instructions do not read or write "
2311c94388fSMichael Maitland                      "vector registers");
2321c94388fSMichael Maitland 
233ad0fbb03SMichael Maitland   // Vector Loads and Stores
234ad0fbb03SMichael Maitland   // Vector Unit-Stride Instructions
235ad0fbb03SMichael Maitland   // Vector Strided Instructions
236983a9577SPhilip Reames   /// Dest EEW encoded in the instruction
237b253a80fSMichael Maitland   case RISCV::VLM_V:
238b253a80fSMichael Maitland   case RISCV::VSM_V:
239983a9577SPhilip Reames     return 0;
24036e4176fSMichael Maitland   case RISCV::VLE8_V:
241ad0fbb03SMichael Maitland   case RISCV::VSE8_V:
24236e4176fSMichael Maitland   case RISCV::VLSE8_V:
243ad0fbb03SMichael Maitland   case RISCV::VSSE8_V:
244983a9577SPhilip Reames     return 3;
24536e4176fSMichael Maitland   case RISCV::VLE16_V:
246ad0fbb03SMichael Maitland   case RISCV::VSE16_V:
24736e4176fSMichael Maitland   case RISCV::VLSE16_V:
248ad0fbb03SMichael Maitland   case RISCV::VSSE16_V:
249983a9577SPhilip Reames     return 4;
25036e4176fSMichael Maitland   case RISCV::VLE32_V:
251ad0fbb03SMichael Maitland   case RISCV::VSE32_V:
25236e4176fSMichael Maitland   case RISCV::VLSE32_V:
253ad0fbb03SMichael Maitland   case RISCV::VSSE32_V:
254983a9577SPhilip Reames     return 5;
25536e4176fSMichael Maitland   case RISCV::VLE64_V:
256ad0fbb03SMichael Maitland   case RISCV::VSE64_V:
25736e4176fSMichael Maitland   case RISCV::VLSE64_V:
258ad0fbb03SMichael Maitland   case RISCV::VSSE64_V:
259983a9577SPhilip Reames     return 6;
260ad0fbb03SMichael Maitland 
261a61eeaa7SMichael Maitland   // Vector Indexed Instructions
262a61eeaa7SMichael Maitland   // vs(o|u)xei<eew>.v
263983a9577SPhilip Reames   // Dest/Data (operand 0) EEW=SEW.  Source EEW=<eew>.
264a61eeaa7SMichael Maitland   case RISCV::VLUXEI8_V:
265a61eeaa7SMichael Maitland   case RISCV::VLOXEI8_V:
266a61eeaa7SMichael Maitland   case RISCV::VSUXEI8_V:
267a61eeaa7SMichael Maitland   case RISCV::VSOXEI8_V: {
268a61eeaa7SMichael Maitland     if (MO.getOperandNo() == 0)
269983a9577SPhilip Reames       return MILog2SEW;
270983a9577SPhilip Reames     return 3;
271a61eeaa7SMichael Maitland   }
272a61eeaa7SMichael Maitland   case RISCV::VLUXEI16_V:
273a61eeaa7SMichael Maitland   case RISCV::VLOXEI16_V:
274a61eeaa7SMichael Maitland   case RISCV::VSUXEI16_V:
275a61eeaa7SMichael Maitland   case RISCV::VSOXEI16_V: {
276a61eeaa7SMichael Maitland     if (MO.getOperandNo() == 0)
277983a9577SPhilip Reames       return MILog2SEW;
278983a9577SPhilip Reames     return 4;
279a61eeaa7SMichael Maitland   }
280a61eeaa7SMichael Maitland   case RISCV::VLUXEI32_V:
281a61eeaa7SMichael Maitland   case RISCV::VLOXEI32_V:
282a61eeaa7SMichael Maitland   case RISCV::VSUXEI32_V:
283a61eeaa7SMichael Maitland   case RISCV::VSOXEI32_V: {
284a61eeaa7SMichael Maitland     if (MO.getOperandNo() == 0)
285983a9577SPhilip Reames       return MILog2SEW;
286983a9577SPhilip Reames     return 5;
287a61eeaa7SMichael Maitland   }
288a61eeaa7SMichael Maitland   case RISCV::VLUXEI64_V:
289a61eeaa7SMichael Maitland   case RISCV::VLOXEI64_V:
290a61eeaa7SMichael Maitland   case RISCV::VSUXEI64_V:
291a61eeaa7SMichael Maitland   case RISCV::VSOXEI64_V: {
292a61eeaa7SMichael Maitland     if (MO.getOperandNo() == 0)
293983a9577SPhilip Reames       return MILog2SEW;
294983a9577SPhilip Reames     return 6;
295a61eeaa7SMichael Maitland   }
296a61eeaa7SMichael Maitland 
2972f09c722SMichael Maitland   // Vector Integer Arithmetic Instructions
2982f09c722SMichael Maitland   // Vector Single-Width Integer Add and Subtract
2991c94388fSMichael Maitland   case RISCV::VADD_VI:
3001c94388fSMichael Maitland   case RISCV::VADD_VV:
3011c94388fSMichael Maitland   case RISCV::VADD_VX:
3021c94388fSMichael Maitland   case RISCV::VSUB_VV:
3031c94388fSMichael Maitland   case RISCV::VSUB_VX:
3041c94388fSMichael Maitland   case RISCV::VRSUB_VI:
3051c94388fSMichael Maitland   case RISCV::VRSUB_VX:
3062f09c722SMichael Maitland   // Vector Bitwise Logical Instructions
3072f09c722SMichael Maitland   // Vector Single-Width Shift Instructions
308983a9577SPhilip Reames   // EEW=SEW.
3091c94388fSMichael Maitland   case RISCV::VAND_VI:
3101c94388fSMichael Maitland   case RISCV::VAND_VV:
3111c94388fSMichael Maitland   case RISCV::VAND_VX:
3121c94388fSMichael Maitland   case RISCV::VOR_VI:
3131c94388fSMichael Maitland   case RISCV::VOR_VV:
3141c94388fSMichael Maitland   case RISCV::VOR_VX:
3151c94388fSMichael Maitland   case RISCV::VXOR_VI:
3161c94388fSMichael Maitland   case RISCV::VXOR_VV:
3171c94388fSMichael Maitland   case RISCV::VXOR_VX:
3181c94388fSMichael Maitland   case RISCV::VSLL_VI:
3191c94388fSMichael Maitland   case RISCV::VSLL_VV:
3201c94388fSMichael Maitland   case RISCV::VSLL_VX:
3211c94388fSMichael Maitland   case RISCV::VSRL_VI:
3221c94388fSMichael Maitland   case RISCV::VSRL_VV:
3231c94388fSMichael Maitland   case RISCV::VSRL_VX:
3241c94388fSMichael Maitland   case RISCV::VSRA_VI:
3251c94388fSMichael Maitland   case RISCV::VSRA_VV:
3261c94388fSMichael Maitland   case RISCV::VSRA_VX:
3272f09c722SMichael Maitland   // Vector Integer Min/Max Instructions
328983a9577SPhilip Reames   // EEW=SEW.
3291c94388fSMichael Maitland   case RISCV::VMINU_VV:
3301c94388fSMichael Maitland   case RISCV::VMINU_VX:
3311c94388fSMichael Maitland   case RISCV::VMIN_VV:
3321c94388fSMichael Maitland   case RISCV::VMIN_VX:
3331c94388fSMichael Maitland   case RISCV::VMAXU_VV:
3341c94388fSMichael Maitland   case RISCV::VMAXU_VX:
3351c94388fSMichael Maitland   case RISCV::VMAX_VV:
3361c94388fSMichael Maitland   case RISCV::VMAX_VX:
3372f09c722SMichael Maitland   // Vector Single-Width Integer Multiply Instructions
338983a9577SPhilip Reames   // Source and Dest EEW=SEW.
3391c94388fSMichael Maitland   case RISCV::VMUL_VV:
3401c94388fSMichael Maitland   case RISCV::VMUL_VX:
3411c94388fSMichael Maitland   case RISCV::VMULH_VV:
3421c94388fSMichael Maitland   case RISCV::VMULH_VX:
3431c94388fSMichael Maitland   case RISCV::VMULHU_VV:
3441c94388fSMichael Maitland   case RISCV::VMULHU_VX:
3451c94388fSMichael Maitland   case RISCV::VMULHSU_VV:
3461c94388fSMichael Maitland   case RISCV::VMULHSU_VX:
3472f09c722SMichael Maitland   // Vector Integer Divide Instructions
348983a9577SPhilip Reames   // EEW=SEW.
3491c94388fSMichael Maitland   case RISCV::VDIVU_VV:
3501c94388fSMichael Maitland   case RISCV::VDIVU_VX:
3511c94388fSMichael Maitland   case RISCV::VDIV_VV:
3521c94388fSMichael Maitland   case RISCV::VDIV_VX:
3531c94388fSMichael Maitland   case RISCV::VREMU_VV:
3541c94388fSMichael Maitland   case RISCV::VREMU_VX:
3551c94388fSMichael Maitland   case RISCV::VREM_VV:
3561c94388fSMichael Maitland   case RISCV::VREM_VX:
3572f09c722SMichael Maitland   // Vector Single-Width Integer Multiply-Add Instructions
358983a9577SPhilip Reames   // EEW=SEW.
3591c94388fSMichael Maitland   case RISCV::VMACC_VV:
3601c94388fSMichael Maitland   case RISCV::VMACC_VX:
3611c94388fSMichael Maitland   case RISCV::VNMSAC_VV:
3621c94388fSMichael Maitland   case RISCV::VNMSAC_VX:
3631c94388fSMichael Maitland   case RISCV::VMADD_VV:
3641c94388fSMichael Maitland   case RISCV::VMADD_VX:
3651c94388fSMichael Maitland   case RISCV::VNMSUB_VV:
3661c94388fSMichael Maitland   case RISCV::VNMSUB_VX:
3672f09c722SMichael Maitland   // Vector Integer Merge Instructions
3687442be68SMichael Maitland   // Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
369983a9577SPhilip Reames   // EEW=SEW, except the mask operand has EEW=1. Mask operand is handled
370983a9577SPhilip Reames   // before this switch.
3711c94388fSMichael Maitland   case RISCV::VMERGE_VIM:
3721c94388fSMichael Maitland   case RISCV::VMERGE_VVM:
3731c94388fSMichael Maitland   case RISCV::VMERGE_VXM:
3747442be68SMichael Maitland   case RISCV::VADC_VIM:
3757442be68SMichael Maitland   case RISCV::VADC_VVM:
3767442be68SMichael Maitland   case RISCV::VADC_VXM:
3777442be68SMichael Maitland   case RISCV::VSBC_VVM:
3787442be68SMichael Maitland   case RISCV::VSBC_VXM:
3792f09c722SMichael Maitland   // Vector Integer Move Instructions
3802f09c722SMichael Maitland   // Vector Fixed-Point Arithmetic Instructions
3812f09c722SMichael Maitland   // Vector Single-Width Saturating Add and Subtract
3822f09c722SMichael Maitland   // Vector Single-Width Averaging Add and Subtract
383983a9577SPhilip Reames   // EEW=SEW.
3841c94388fSMichael Maitland   case RISCV::VMV_V_I:
3851c94388fSMichael Maitland   case RISCV::VMV_V_V:
3861c94388fSMichael Maitland   case RISCV::VMV_V_X:
3871c94388fSMichael Maitland   case RISCV::VSADDU_VI:
3881c94388fSMichael Maitland   case RISCV::VSADDU_VV:
3891c94388fSMichael Maitland   case RISCV::VSADDU_VX:
3901c94388fSMichael Maitland   case RISCV::VSADD_VI:
3911c94388fSMichael Maitland   case RISCV::VSADD_VV:
3921c94388fSMichael Maitland   case RISCV::VSADD_VX:
3931c94388fSMichael Maitland   case RISCV::VSSUBU_VV:
3941c94388fSMichael Maitland   case RISCV::VSSUBU_VX:
3951c94388fSMichael Maitland   case RISCV::VSSUB_VV:
3961c94388fSMichael Maitland   case RISCV::VSSUB_VX:
3971c94388fSMichael Maitland   case RISCV::VAADDU_VV:
3981c94388fSMichael Maitland   case RISCV::VAADDU_VX:
3991c94388fSMichael Maitland   case RISCV::VAADD_VV:
4001c94388fSMichael Maitland   case RISCV::VAADD_VX:
4011c94388fSMichael Maitland   case RISCV::VASUBU_VV:
4021c94388fSMichael Maitland   case RISCV::VASUBU_VX:
4031c94388fSMichael Maitland   case RISCV::VASUB_VV:
4041c94388fSMichael Maitland   case RISCV::VASUB_VX:
40550a457d9SMichael Maitland   // Vector Single-Width Fractional Multiply with Rounding and Saturation
406983a9577SPhilip Reames   // EEW=SEW. The instruction produces 2*SEW product internally but
40750a457d9SMichael Maitland   // saturates to fit into SEW bits.
40850a457d9SMichael Maitland   case RISCV::VSMUL_VV:
40950a457d9SMichael Maitland   case RISCV::VSMUL_VX:
4102f09c722SMichael Maitland   // Vector Single-Width Scaling Shift Instructions
411983a9577SPhilip Reames   // EEW=SEW.
4121c94388fSMichael Maitland   case RISCV::VSSRL_VI:
4131c94388fSMichael Maitland   case RISCV::VSSRL_VV:
4141c94388fSMichael Maitland   case RISCV::VSSRL_VX:
4151c94388fSMichael Maitland   case RISCV::VSSRA_VI:
4161c94388fSMichael Maitland   case RISCV::VSSRA_VV:
4171c94388fSMichael Maitland   case RISCV::VSSRA_VX:
4182f09c722SMichael Maitland   // Vector Permutation Instructions
4192f09c722SMichael Maitland   // Integer Scalar Move Instructions
4202f09c722SMichael Maitland   // Floating-Point Scalar Move Instructions
421983a9577SPhilip Reames   // EEW=SEW.
4221c94388fSMichael Maitland   case RISCV::VMV_X_S:
4231c94388fSMichael Maitland   case RISCV::VMV_S_X:
4241c94388fSMichael Maitland   case RISCV::VFMV_F_S:
4251c94388fSMichael Maitland   case RISCV::VFMV_S_F:
4262f09c722SMichael Maitland   // Vector Slide Instructions
427983a9577SPhilip Reames   // EEW=SEW.
4281c94388fSMichael Maitland   case RISCV::VSLIDEUP_VI:
4291c94388fSMichael Maitland   case RISCV::VSLIDEUP_VX:
4301c94388fSMichael Maitland   case RISCV::VSLIDEDOWN_VI:
4311c94388fSMichael Maitland   case RISCV::VSLIDEDOWN_VX:
4321c94388fSMichael Maitland   case RISCV::VSLIDE1UP_VX:
4331c94388fSMichael Maitland   case RISCV::VFSLIDE1UP_VF:
4341c94388fSMichael Maitland   case RISCV::VSLIDE1DOWN_VX:
4351c94388fSMichael Maitland   case RISCV::VFSLIDE1DOWN_VF:
4362f09c722SMichael Maitland   // Vector Register Gather Instructions
437983a9577SPhilip Reames   // EEW=SEW. For mask operand, EEW=1.
4381c94388fSMichael Maitland   case RISCV::VRGATHER_VI:
4391c94388fSMichael Maitland   case RISCV::VRGATHER_VV:
4401c94388fSMichael Maitland   case RISCV::VRGATHER_VX:
4412f09c722SMichael Maitland   // Vector Compress Instruction
442983a9577SPhilip Reames   // EEW=SEW.
4431c94388fSMichael Maitland   case RISCV::VCOMPRESS_VM:
444fb33268dSMichael Maitland   // Vector Element Index Instruction
445fb33268dSMichael Maitland   case RISCV::VID_V:
446b48e5f0fSMichael Maitland   // Vector Single-Width Floating-Point Add/Subtract Instructions
447b48e5f0fSMichael Maitland   case RISCV::VFADD_VF:
448b48e5f0fSMichael Maitland   case RISCV::VFADD_VV:
449b48e5f0fSMichael Maitland   case RISCV::VFSUB_VF:
450b48e5f0fSMichael Maitland   case RISCV::VFSUB_VV:
451b48e5f0fSMichael Maitland   case RISCV::VFRSUB_VF:
452b48e5f0fSMichael Maitland   // Vector Single-Width Floating-Point Multiply/Divide Instructions
453b48e5f0fSMichael Maitland   case RISCV::VFMUL_VF:
454b48e5f0fSMichael Maitland   case RISCV::VFMUL_VV:
455b48e5f0fSMichael Maitland   case RISCV::VFDIV_VF:
456b48e5f0fSMichael Maitland   case RISCV::VFDIV_VV:
457b48e5f0fSMichael Maitland   case RISCV::VFRDIV_VF:
458b48e5f0fSMichael Maitland   // Vector Floating-Point Square-Root Instruction
459b48e5f0fSMichael Maitland   case RISCV::VFSQRT_V:
460b48e5f0fSMichael Maitland   // Vector Floating-Point Reciprocal Square-Root Estimate Instruction
461b48e5f0fSMichael Maitland   case RISCV::VFRSQRT7_V:
462b48e5f0fSMichael Maitland   // Vector Floating-Point Reciprocal Estimate Instruction
463b48e5f0fSMichael Maitland   case RISCV::VFREC7_V:
464b48e5f0fSMichael Maitland   // Vector Floating-Point MIN/MAX Instructions
465b48e5f0fSMichael Maitland   case RISCV::VFMIN_VF:
466b48e5f0fSMichael Maitland   case RISCV::VFMIN_VV:
467b48e5f0fSMichael Maitland   case RISCV::VFMAX_VF:
468b48e5f0fSMichael Maitland   case RISCV::VFMAX_VV:
469b48e5f0fSMichael Maitland   // Vector Floating-Point Sign-Injection Instructions
470b48e5f0fSMichael Maitland   case RISCV::VFSGNJ_VF:
471b48e5f0fSMichael Maitland   case RISCV::VFSGNJ_VV:
472b48e5f0fSMichael Maitland   case RISCV::VFSGNJN_VV:
473b48e5f0fSMichael Maitland   case RISCV::VFSGNJN_VF:
474b48e5f0fSMichael Maitland   case RISCV::VFSGNJX_VF:
475b48e5f0fSMichael Maitland   case RISCV::VFSGNJX_VV:
476b48e5f0fSMichael Maitland   // Vector Floating-Point Classify Instruction
477b48e5f0fSMichael Maitland   case RISCV::VFCLASS_V:
478b48e5f0fSMichael Maitland   // Vector Floating-Point Move Instruction
479b48e5f0fSMichael Maitland   case RISCV::VFMV_V_F:
480b48e5f0fSMichael Maitland   // Single-Width Floating-Point/Integer Type-Convert Instructions
481b48e5f0fSMichael Maitland   case RISCV::VFCVT_XU_F_V:
482b48e5f0fSMichael Maitland   case RISCV::VFCVT_X_F_V:
483b48e5f0fSMichael Maitland   case RISCV::VFCVT_RTZ_XU_F_V:
484b48e5f0fSMichael Maitland   case RISCV::VFCVT_RTZ_X_F_V:
485b48e5f0fSMichael Maitland   case RISCV::VFCVT_F_XU_V:
486b48e5f0fSMichael Maitland   case RISCV::VFCVT_F_X_V:
487b48e5f0fSMichael Maitland   // Vector Floating-Point Merge Instruction
488b48e5f0fSMichael Maitland   case RISCV::VFMERGE_VFM:
489d5145715SMichael Maitland   // Vector count population in mask vcpop.m
490d5145715SMichael Maitland   // vfirst find-first-set mask bit
491d5145715SMichael Maitland   case RISCV::VCPOP_M:
492d5145715SMichael Maitland   case RISCV::VFIRST_M:
493983a9577SPhilip Reames     return MILog2SEW;
4941c94388fSMichael Maitland 
4952f09c722SMichael Maitland   // Vector Widening Integer Add/Subtract
496983a9577SPhilip Reames   // Def uses EEW=2*SEW . Operands use EEW=SEW.
4971c94388fSMichael Maitland   case RISCV::VWADDU_VV:
4981c94388fSMichael Maitland   case RISCV::VWADDU_VX:
4991c94388fSMichael Maitland   case RISCV::VWSUBU_VV:
5001c94388fSMichael Maitland   case RISCV::VWSUBU_VX:
5011c94388fSMichael Maitland   case RISCV::VWADD_VV:
5021c94388fSMichael Maitland   case RISCV::VWADD_VX:
5031c94388fSMichael Maitland   case RISCV::VWSUB_VV:
5041c94388fSMichael Maitland   case RISCV::VWSUB_VX:
5051c94388fSMichael Maitland   case RISCV::VWSLL_VI:
5062f09c722SMichael Maitland   // Vector Widening Integer Multiply Instructions
507983a9577SPhilip Reames   // Destination EEW=2*SEW. Source EEW=SEW.
5081c94388fSMichael Maitland   case RISCV::VWMUL_VV:
5091c94388fSMichael Maitland   case RISCV::VWMUL_VX:
5101c94388fSMichael Maitland   case RISCV::VWMULSU_VV:
5111c94388fSMichael Maitland   case RISCV::VWMULSU_VX:
5121c94388fSMichael Maitland   case RISCV::VWMULU_VV:
513131b7fe2SMichael Maitland   case RISCV::VWMULU_VX:
514131b7fe2SMichael Maitland   // Vector Widening Integer Multiply-Add Instructions
515983a9577SPhilip Reames   // Destination EEW=2*SEW. Source EEW=SEW.
516131b7fe2SMichael Maitland   // A SEW-bit*SEW-bit multiply of the sources forms a 2*SEW-bit value, which
517131b7fe2SMichael Maitland   // is then added to the 2*SEW-bit Dest. These instructions never have a
518131b7fe2SMichael Maitland   // passthru operand.
519131b7fe2SMichael Maitland   case RISCV::VWMACCU_VV:
520131b7fe2SMichael Maitland   case RISCV::VWMACCU_VX:
521131b7fe2SMichael Maitland   case RISCV::VWMACC_VV:
522131b7fe2SMichael Maitland   case RISCV::VWMACC_VX:
523131b7fe2SMichael Maitland   case RISCV::VWMACCSU_VV:
524131b7fe2SMichael Maitland   case RISCV::VWMACCSU_VX:
525b48e5f0fSMichael Maitland   case RISCV::VWMACCUS_VX:
526b48e5f0fSMichael Maitland   // Vector Widening Floating-Point Fused Multiply-Add Instructions
527b48e5f0fSMichael Maitland   case RISCV::VFWMACC_VF:
528b48e5f0fSMichael Maitland   case RISCV::VFWMACC_VV:
529b48e5f0fSMichael Maitland   case RISCV::VFWNMACC_VF:
530b48e5f0fSMichael Maitland   case RISCV::VFWNMACC_VV:
531b48e5f0fSMichael Maitland   case RISCV::VFWMSAC_VF:
532b48e5f0fSMichael Maitland   case RISCV::VFWMSAC_VV:
533b48e5f0fSMichael Maitland   case RISCV::VFWNMSAC_VF:
534b48e5f0fSMichael Maitland   case RISCV::VFWNMSAC_VV:
535b48e5f0fSMichael Maitland   // Vector Widening Floating-Point Add/Subtract Instructions
536983a9577SPhilip Reames   // Dest EEW=2*SEW. Source EEW=SEW.
537b48e5f0fSMichael Maitland   case RISCV::VFWADD_VV:
538b48e5f0fSMichael Maitland   case RISCV::VFWADD_VF:
539b48e5f0fSMichael Maitland   case RISCV::VFWSUB_VV:
540b48e5f0fSMichael Maitland   case RISCV::VFWSUB_VF:
541b48e5f0fSMichael Maitland   // Vector Widening Floating-Point Multiply
542b48e5f0fSMichael Maitland   case RISCV::VFWMUL_VF:
543b48e5f0fSMichael Maitland   case RISCV::VFWMUL_VV:
544b48e5f0fSMichael Maitland   // Widening Floating-Point/Integer Type-Convert Instructions
545b48e5f0fSMichael Maitland   case RISCV::VFWCVT_XU_F_V:
546b48e5f0fSMichael Maitland   case RISCV::VFWCVT_X_F_V:
547b48e5f0fSMichael Maitland   case RISCV::VFWCVT_RTZ_XU_F_V:
548b48e5f0fSMichael Maitland   case RISCV::VFWCVT_RTZ_X_F_V:
549b48e5f0fSMichael Maitland   case RISCV::VFWCVT_F_XU_V:
550b48e5f0fSMichael Maitland   case RISCV::VFWCVT_F_X_V:
55141e4018fSCraig Topper   case RISCV::VFWCVT_F_F_V:
552e44f03ddSMichael Maitland   case RISCV::VFWCVTBF16_F_F_V:
55341e4018fSCraig Topper     return IsMODef ? MILog2SEW + 1 : MILog2SEW;
5541c94388fSMichael Maitland 
555983a9577SPhilip Reames   // Def and Op1 uses EEW=2*SEW. Op2 uses EEW=SEW.
5561c94388fSMichael Maitland   case RISCV::VWADDU_WV:
5571c94388fSMichael Maitland   case RISCV::VWADDU_WX:
5581c94388fSMichael Maitland   case RISCV::VWSUBU_WV:
5591c94388fSMichael Maitland   case RISCV::VWSUBU_WX:
5601c94388fSMichael Maitland   case RISCV::VWADD_WV:
5611c94388fSMichael Maitland   case RISCV::VWADD_WX:
5621c94388fSMichael Maitland   case RISCV::VWSUB_WV:
563b48e5f0fSMichael Maitland   case RISCV::VWSUB_WX:
564b48e5f0fSMichael Maitland   // Vector Widening Floating-Point Add/Subtract Instructions
565b48e5f0fSMichael Maitland   case RISCV::VFWADD_WF:
566b48e5f0fSMichael Maitland   case RISCV::VFWADD_WV:
567b48e5f0fSMichael Maitland   case RISCV::VFWSUB_WF:
568b48e5f0fSMichael Maitland   case RISCV::VFWSUB_WV: {
569437e1a70SLuke Lau     bool IsOp1 = (HasPassthru && !IsTied) ? MO.getOperandNo() == 2
570437e1a70SLuke Lau                                           : MO.getOperandNo() == 1;
5711c94388fSMichael Maitland     bool TwoTimes = IsMODef || IsOp1;
57241e4018fSCraig Topper     return TwoTimes ? MILog2SEW + 1 : MILog2SEW;
5731c94388fSMichael Maitland   }
5741c94388fSMichael Maitland 
5752f09c722SMichael Maitland   // Vector Integer Extension
5761c94388fSMichael Maitland   case RISCV::VZEXT_VF2:
5771c94388fSMichael Maitland   case RISCV::VSEXT_VF2:
578983a9577SPhilip Reames     return getIntegerExtensionOperandEEW(2, MI, MO);
5791c94388fSMichael Maitland   case RISCV::VZEXT_VF4:
5801c94388fSMichael Maitland   case RISCV::VSEXT_VF4:
581983a9577SPhilip Reames     return getIntegerExtensionOperandEEW(4, MI, MO);
5821c94388fSMichael Maitland   case RISCV::VZEXT_VF8:
5831c94388fSMichael Maitland   case RISCV::VSEXT_VF8:
584983a9577SPhilip Reames     return getIntegerExtensionOperandEEW(8, MI, MO);
5851c94388fSMichael Maitland 
5862f09c722SMichael Maitland   // Vector Narrowing Integer Right Shift Instructions
587983a9577SPhilip Reames   // Destination EEW=SEW, Op 1 has EEW=2*SEW. Op2 has EEW=SEW
5881c94388fSMichael Maitland   case RISCV::VNSRL_WX:
5891c94388fSMichael Maitland   case RISCV::VNSRL_WI:
5901c94388fSMichael Maitland   case RISCV::VNSRL_WV:
5911c94388fSMichael Maitland   case RISCV::VNSRA_WI:
5921c94388fSMichael Maitland   case RISCV::VNSRA_WV:
5931c94388fSMichael Maitland   case RISCV::VNSRA_WX:
5942f09c722SMichael Maitland   // Vector Narrowing Fixed-Point Clip Instructions
595983a9577SPhilip Reames   // Destination and Op1 EEW=SEW. Op2 EEW=2*SEW.
5961c94388fSMichael Maitland   case RISCV::VNCLIPU_WI:
5971c94388fSMichael Maitland   case RISCV::VNCLIPU_WV:
5981c94388fSMichael Maitland   case RISCV::VNCLIPU_WX:
5991c94388fSMichael Maitland   case RISCV::VNCLIP_WI:
6001c94388fSMichael Maitland   case RISCV::VNCLIP_WV:
601b48e5f0fSMichael Maitland   case RISCV::VNCLIP_WX:
602b48e5f0fSMichael Maitland   // Narrowing Floating-Point/Integer Type-Convert Instructions
603b48e5f0fSMichael Maitland   case RISCV::VFNCVT_XU_F_W:
604b48e5f0fSMichael Maitland   case RISCV::VFNCVT_X_F_W:
605b48e5f0fSMichael Maitland   case RISCV::VFNCVT_RTZ_XU_F_W:
606b48e5f0fSMichael Maitland   case RISCV::VFNCVT_RTZ_X_F_W:
607b48e5f0fSMichael Maitland   case RISCV::VFNCVT_F_XU_W:
608b48e5f0fSMichael Maitland   case RISCV::VFNCVT_F_X_W:
609b48e5f0fSMichael Maitland   case RISCV::VFNCVT_F_F_W:
610e44f03ddSMichael Maitland   case RISCV::VFNCVT_ROD_F_F_W:
611e44f03ddSMichael Maitland   case RISCV::VFNCVTBF16_F_F_W: {
612437e1a70SLuke Lau     assert(!IsTied);
613db57fc4eSLuke Lau     bool IsOp1 = HasPassthru ? MO.getOperandNo() == 2 : MO.getOperandNo() == 1;
6141c94388fSMichael Maitland     bool TwoTimes = IsOp1;
61541e4018fSCraig Topper     return TwoTimes ? MILog2SEW + 1 : MILog2SEW;
6161c94388fSMichael Maitland   }
6171c94388fSMichael Maitland 
618d99c9994SMichael Maitland   // Vector Mask Instructions
619d99c9994SMichael Maitland   // Vector Mask-Register Logical Instructions
620d99c9994SMichael Maitland   // vmsbf.m set-before-first mask bit
621d99c9994SMichael Maitland   // vmsif.m set-including-first mask bit
622d99c9994SMichael Maitland   // vmsof.m set-only-first mask bit
623983a9577SPhilip Reames   // EEW=1
624d99c9994SMichael Maitland   // We handle the cases when operand is a v0 mask operand above the switch,
625d99c9994SMichael Maitland   // but these instructions may use non-v0 mask operands and need to be handled
626d99c9994SMichael Maitland   // specifically.
627d99c9994SMichael Maitland   case RISCV::VMAND_MM:
628d99c9994SMichael Maitland   case RISCV::VMNAND_MM:
629d99c9994SMichael Maitland   case RISCV::VMANDN_MM:
630d99c9994SMichael Maitland   case RISCV::VMXOR_MM:
631d99c9994SMichael Maitland   case RISCV::VMOR_MM:
632d99c9994SMichael Maitland   case RISCV::VMNOR_MM:
633d99c9994SMichael Maitland   case RISCV::VMORN_MM:
634d99c9994SMichael Maitland   case RISCV::VMXNOR_MM:
635d99c9994SMichael Maitland   case RISCV::VMSBF_M:
636d99c9994SMichael Maitland   case RISCV::VMSIF_M:
637d99c9994SMichael Maitland   case RISCV::VMSOF_M: {
638b16777afSCraig Topper     return MILog2SEW;
639d99c9994SMichael Maitland   }
640d99c9994SMichael Maitland 
641fb33268dSMichael Maitland   // Vector Iota Instruction
642983a9577SPhilip Reames   // EEW=SEW, except the mask operand has EEW=1. Mask operand is not handled
643983a9577SPhilip Reames   // before this switch.
644fb33268dSMichael Maitland   case RISCV::VIOTA_M: {
645fb33268dSMichael Maitland     if (IsMODef || MO.getOperandNo() == 1)
646983a9577SPhilip Reames       return MILog2SEW;
647983a9577SPhilip Reames     return 0;
648fb33268dSMichael Maitland   }
649fb33268dSMichael Maitland 
6507442be68SMichael Maitland   // Vector Integer Compare Instructions
651983a9577SPhilip Reames   // Dest EEW=1. Source EEW=SEW.
6527442be68SMichael Maitland   case RISCV::VMSEQ_VI:
6537442be68SMichael Maitland   case RISCV::VMSEQ_VV:
6547442be68SMichael Maitland   case RISCV::VMSEQ_VX:
6557442be68SMichael Maitland   case RISCV::VMSNE_VI:
6567442be68SMichael Maitland   case RISCV::VMSNE_VV:
6577442be68SMichael Maitland   case RISCV::VMSNE_VX:
6587442be68SMichael Maitland   case RISCV::VMSLTU_VV:
6597442be68SMichael Maitland   case RISCV::VMSLTU_VX:
6607442be68SMichael Maitland   case RISCV::VMSLT_VV:
6617442be68SMichael Maitland   case RISCV::VMSLT_VX:
6627442be68SMichael Maitland   case RISCV::VMSLEU_VV:
6637442be68SMichael Maitland   case RISCV::VMSLEU_VI:
6647442be68SMichael Maitland   case RISCV::VMSLEU_VX:
6657442be68SMichael Maitland   case RISCV::VMSLE_VV:
6667442be68SMichael Maitland   case RISCV::VMSLE_VI:
6677442be68SMichael Maitland   case RISCV::VMSLE_VX:
6687442be68SMichael Maitland   case RISCV::VMSGTU_VI:
6697442be68SMichael Maitland   case RISCV::VMSGTU_VX:
6707442be68SMichael Maitland   case RISCV::VMSGT_VI:
6717442be68SMichael Maitland   case RISCV::VMSGT_VX:
6727442be68SMichael Maitland   // Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
673983a9577SPhilip Reames   // Dest EEW=1. Source EEW=SEW. Mask source operand handled above this switch.
6747442be68SMichael Maitland   case RISCV::VMADC_VIM:
6757442be68SMichael Maitland   case RISCV::VMADC_VVM:
6767442be68SMichael Maitland   case RISCV::VMADC_VXM:
6777442be68SMichael Maitland   case RISCV::VMSBC_VVM:
6787442be68SMichael Maitland   case RISCV::VMSBC_VXM:
679983a9577SPhilip Reames   // Dest EEW=1. Source EEW=SEW.
6807442be68SMichael Maitland   case RISCV::VMADC_VV:
6817442be68SMichael Maitland   case RISCV::VMADC_VI:
6827442be68SMichael Maitland   case RISCV::VMADC_VX:
6837442be68SMichael Maitland   case RISCV::VMSBC_VV:
684b48e5f0fSMichael Maitland   case RISCV::VMSBC_VX:
685b48e5f0fSMichael Maitland   // 13.13. Vector Floating-Point Compare Instructions
686983a9577SPhilip Reames   // Dest EEW=1. Source EEW=SEW
687b48e5f0fSMichael Maitland   case RISCV::VMFEQ_VF:
688b48e5f0fSMichael Maitland   case RISCV::VMFEQ_VV:
689b48e5f0fSMichael Maitland   case RISCV::VMFNE_VF:
690b48e5f0fSMichael Maitland   case RISCV::VMFNE_VV:
691b48e5f0fSMichael Maitland   case RISCV::VMFLT_VF:
692b48e5f0fSMichael Maitland   case RISCV::VMFLT_VV:
693b48e5f0fSMichael Maitland   case RISCV::VMFLE_VF:
694b48e5f0fSMichael Maitland   case RISCV::VMFLE_VV:
695b48e5f0fSMichael Maitland   case RISCV::VMFGT_VF:
696b48e5f0fSMichael Maitland   case RISCV::VMFGE_VF: {
6977442be68SMichael Maitland     if (IsMODef)
698983a9577SPhilip Reames       return 0;
699983a9577SPhilip Reames     return MILog2SEW;
7007442be68SMichael Maitland   }
7017442be68SMichael Maitland 
702142787d3SMichael Maitland   // Vector Reduction Operations
703142787d3SMichael Maitland   // Vector Single-Width Integer Reduction Instructions
704142787d3SMichael Maitland   case RISCV::VREDAND_VS:
705142787d3SMichael Maitland   case RISCV::VREDMAX_VS:
706142787d3SMichael Maitland   case RISCV::VREDMAXU_VS:
707142787d3SMichael Maitland   case RISCV::VREDMIN_VS:
708142787d3SMichael Maitland   case RISCV::VREDMINU_VS:
709142787d3SMichael Maitland   case RISCV::VREDOR_VS:
710142787d3SMichael Maitland   case RISCV::VREDSUM_VS:
711550841f8SMichael Maitland   case RISCV::VREDXOR_VS:
712550841f8SMichael Maitland   // Vector Single-Width Floating-Point Reduction Instructions
713550841f8SMichael Maitland   case RISCV::VFREDMAX_VS:
714550841f8SMichael Maitland   case RISCV::VFREDMIN_VS:
715550841f8SMichael Maitland   case RISCV::VFREDOSUM_VS:
716550841f8SMichael Maitland   case RISCV::VFREDUSUM_VS: {
717983a9577SPhilip Reames     return MILog2SEW;
718142787d3SMichael Maitland   }
719142787d3SMichael Maitland 
720f77a7dd8SMichael Maitland   // Vector Widening Integer Reduction Instructions
721f77a7dd8SMichael Maitland   // The Dest and VS1 read only element 0 for the vector register. Return
722f77a7dd8SMichael Maitland   // 2*EEW for these. VS2 has EEW=SEW and EMUL=LMUL.
723f77a7dd8SMichael Maitland   case RISCV::VWREDSUM_VS:
724f77a7dd8SMichael Maitland   case RISCV::VWREDSUMU_VS:
725f77a7dd8SMichael Maitland   // Vector Widening Floating-Point Reduction Instructions
726f77a7dd8SMichael Maitland   case RISCV::VFWREDOSUM_VS:
727f77a7dd8SMichael Maitland   case RISCV::VFWREDUSUM_VS: {
728f77a7dd8SMichael Maitland     bool TwoTimes = IsMODef || MO.getOperandNo() == 3;
72941e4018fSCraig Topper     return TwoTimes ? MILog2SEW + 1 : MILog2SEW;
730f77a7dd8SMichael Maitland   }
731f77a7dd8SMichael Maitland 
7321c94388fSMichael Maitland   default:
7330b4fca5bSPhilip Reames     return std::nullopt;
7341c94388fSMichael Maitland   }
7351c94388fSMichael Maitland }
7361c94388fSMichael Maitland 
7370b4fca5bSPhilip Reames static std::optional<OperandInfo>
7380b4fca5bSPhilip Reames getOperandInfo(const MachineOperand &MO, const MachineRegisterInfo *MRI) {
739983a9577SPhilip Reames   const MachineInstr &MI = *MO.getParent();
740983a9577SPhilip Reames   const RISCVVPseudosTable::PseudoInfo *RVV =
741983a9577SPhilip Reames       RISCVVPseudosTable::getPseudoInfo(MI.getOpcode());
742983a9577SPhilip Reames   assert(RVV && "Could not find MI in PseudoTable");
743983a9577SPhilip Reames 
744983a9577SPhilip Reames   std::optional<unsigned> Log2EEW = getOperandLog2EEW(MO, MRI);
745983a9577SPhilip Reames   if (!Log2EEW)
7460b4fca5bSPhilip Reames     return std::nullopt;
747983a9577SPhilip Reames 
748983a9577SPhilip Reames   switch (RVV->BaseInstr) {
749983a9577SPhilip Reames   // Vector Reduction Operations
750983a9577SPhilip Reames   // Vector Single-Width Integer Reduction Instructions
751f77a7dd8SMichael Maitland   // Vector Widening Integer Reduction Instructions
752f77a7dd8SMichael Maitland   // Vector Widening Floating-Point Reduction Instructions
753983a9577SPhilip Reames   // The Dest and VS1 only read element 0 of the vector register. Return just
754983a9577SPhilip Reames   // the EEW for these.
755983a9577SPhilip Reames   case RISCV::VREDAND_VS:
756983a9577SPhilip Reames   case RISCV::VREDMAX_VS:
757983a9577SPhilip Reames   case RISCV::VREDMAXU_VS:
758983a9577SPhilip Reames   case RISCV::VREDMIN_VS:
759983a9577SPhilip Reames   case RISCV::VREDMINU_VS:
760983a9577SPhilip Reames   case RISCV::VREDOR_VS:
761983a9577SPhilip Reames   case RISCV::VREDSUM_VS:
762983a9577SPhilip Reames   case RISCV::VREDXOR_VS:
763f77a7dd8SMichael Maitland   case RISCV::VWREDSUM_VS:
764f77a7dd8SMichael Maitland   case RISCV::VWREDSUMU_VS:
765f77a7dd8SMichael Maitland   case RISCV::VFWREDOSUM_VS:
766f77a7dd8SMichael Maitland   case RISCV::VFWREDUSUM_VS:
767983a9577SPhilip Reames     if (MO.getOperandNo() != 2)
768983a9577SPhilip Reames       return OperandInfo(*Log2EEW);
769983a9577SPhilip Reames     break;
770983a9577SPhilip Reames   };
771983a9577SPhilip Reames 
772983a9577SPhilip Reames   // All others have EMUL=EEW/SEW*LMUL
773983a9577SPhilip Reames   return OperandInfo(RISCVVType::getEMULEqualsEEWDivSEWTimesLMUL(*Log2EEW, MI),
774983a9577SPhilip Reames                      *Log2EEW);
775983a9577SPhilip Reames }
776983a9577SPhilip Reames 
7771c94388fSMichael Maitland /// Return true if this optimization should consider MI for VL reduction. This
7781c94388fSMichael Maitland /// white-list approach simplifies this optimization for instructions that may
7791c94388fSMichael Maitland /// have more complex semantics with relation to how it uses VL.
7801c94388fSMichael Maitland static bool isSupportedInstr(const MachineInstr &MI) {
7811c94388fSMichael Maitland   const RISCVVPseudosTable::PseudoInfo *RVV =
7821c94388fSMichael Maitland       RISCVVPseudosTable::getPseudoInfo(MI.getOpcode());
7831c94388fSMichael Maitland 
7841c94388fSMichael Maitland   if (!RVV)
7851c94388fSMichael Maitland     return false;
7861c94388fSMichael Maitland 
7871c94388fSMichael Maitland   switch (RVV->BaseInstr) {
78836e4176fSMichael Maitland   // Vector Unit-Stride Instructions
78936e4176fSMichael Maitland   // Vector Strided Instructions
790b253a80fSMichael Maitland   case RISCV::VLM_V:
79136e4176fSMichael Maitland   case RISCV::VLE8_V:
79236e4176fSMichael Maitland   case RISCV::VLSE8_V:
79336e4176fSMichael Maitland   case RISCV::VLE16_V:
79436e4176fSMichael Maitland   case RISCV::VLSE16_V:
79536e4176fSMichael Maitland   case RISCV::VLE32_V:
79636e4176fSMichael Maitland   case RISCV::VLSE32_V:
79736e4176fSMichael Maitland   case RISCV::VLE64_V:
79836e4176fSMichael Maitland   case RISCV::VLSE64_V:
79936e4176fSMichael Maitland   // Vector Indexed Instructions
80036e4176fSMichael Maitland   case RISCV::VLUXEI8_V:
80136e4176fSMichael Maitland   case RISCV::VLOXEI8_V:
80236e4176fSMichael Maitland   case RISCV::VLUXEI16_V:
80336e4176fSMichael Maitland   case RISCV::VLOXEI16_V:
80436e4176fSMichael Maitland   case RISCV::VLUXEI32_V:
80536e4176fSMichael Maitland   case RISCV::VLOXEI32_V:
80636e4176fSMichael Maitland   case RISCV::VLUXEI64_V:
80736e4176fSMichael Maitland   case RISCV::VLOXEI64_V: {
80836e4176fSMichael Maitland     for (const MachineMemOperand *MMO : MI.memoperands())
80936e4176fSMichael Maitland       if (MMO->isVolatile())
81036e4176fSMichael Maitland         return false;
81136e4176fSMichael Maitland     return true;
81236e4176fSMichael Maitland   }
81336e4176fSMichael Maitland 
8142f09c722SMichael Maitland   // Vector Single-Width Integer Add and Subtract
8151c94388fSMichael Maitland   case RISCV::VADD_VI:
8161c94388fSMichael Maitland   case RISCV::VADD_VV:
8171c94388fSMichael Maitland   case RISCV::VADD_VX:
8181c94388fSMichael Maitland   case RISCV::VSUB_VV:
8191c94388fSMichael Maitland   case RISCV::VSUB_VX:
8201c94388fSMichael Maitland   case RISCV::VRSUB_VI:
8211c94388fSMichael Maitland   case RISCV::VRSUB_VX:
8229bb29c3dSMichael Maitland   // Vector Bitwise Logical Instructions
8239bb29c3dSMichael Maitland   // Vector Single-Width Shift Instructions
8249bb29c3dSMichael Maitland   case RISCV::VAND_VI:
8259bb29c3dSMichael Maitland   case RISCV::VAND_VV:
8269bb29c3dSMichael Maitland   case RISCV::VAND_VX:
8279bb29c3dSMichael Maitland   case RISCV::VOR_VI:
8289bb29c3dSMichael Maitland   case RISCV::VOR_VV:
8299bb29c3dSMichael Maitland   case RISCV::VOR_VX:
8309bb29c3dSMichael Maitland   case RISCV::VXOR_VI:
8319bb29c3dSMichael Maitland   case RISCV::VXOR_VV:
8329bb29c3dSMichael Maitland   case RISCV::VXOR_VX:
8339bb29c3dSMichael Maitland   case RISCV::VSLL_VI:
8349bb29c3dSMichael Maitland   case RISCV::VSLL_VV:
8359bb29c3dSMichael Maitland   case RISCV::VSLL_VX:
8369bb29c3dSMichael Maitland   case RISCV::VSRL_VI:
8379bb29c3dSMichael Maitland   case RISCV::VSRL_VV:
8389bb29c3dSMichael Maitland   case RISCV::VSRL_VX:
8399bb29c3dSMichael Maitland   case RISCV::VSRA_VI:
8409bb29c3dSMichael Maitland   case RISCV::VSRA_VV:
8419bb29c3dSMichael Maitland   case RISCV::VSRA_VX:
8422f09c722SMichael Maitland   // Vector Widening Integer Add/Subtract
8431c94388fSMichael Maitland   case RISCV::VWADDU_VV:
8441c94388fSMichael Maitland   case RISCV::VWADDU_VX:
8451c94388fSMichael Maitland   case RISCV::VWSUBU_VV:
8461c94388fSMichael Maitland   case RISCV::VWSUBU_VX:
8471c94388fSMichael Maitland   case RISCV::VWADD_VV:
8481c94388fSMichael Maitland   case RISCV::VWADD_VX:
8491c94388fSMichael Maitland   case RISCV::VWSUB_VV:
8501c94388fSMichael Maitland   case RISCV::VWSUB_VX:
8511c94388fSMichael Maitland   case RISCV::VWADDU_WV:
8521c94388fSMichael Maitland   case RISCV::VWADDU_WX:
8531c94388fSMichael Maitland   case RISCV::VWSUBU_WV:
8541c94388fSMichael Maitland   case RISCV::VWSUBU_WX:
8551c94388fSMichael Maitland   case RISCV::VWADD_WV:
8561c94388fSMichael Maitland   case RISCV::VWADD_WX:
8571c94388fSMichael Maitland   case RISCV::VWSUB_WV:
8581c94388fSMichael Maitland   case RISCV::VWSUB_WX:
8592f09c722SMichael Maitland   // Vector Integer Extension
8601c94388fSMichael Maitland   case RISCV::VZEXT_VF2:
8611c94388fSMichael Maitland   case RISCV::VSEXT_VF2:
8621c94388fSMichael Maitland   case RISCV::VZEXT_VF4:
8631c94388fSMichael Maitland   case RISCV::VSEXT_VF4:
8641c94388fSMichael Maitland   case RISCV::VZEXT_VF8:
8651c94388fSMichael Maitland   case RISCV::VSEXT_VF8:
8662f09c722SMichael Maitland   // Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
8672f09c722SMichael Maitland   // FIXME: Add support
8687442be68SMichael Maitland   case RISCV::VMADC_VV:
8697442be68SMichael Maitland   case RISCV::VMADC_VI:
8707442be68SMichael Maitland   case RISCV::VMADC_VX:
8717442be68SMichael Maitland   case RISCV::VMSBC_VV:
8727442be68SMichael Maitland   case RISCV::VMSBC_VX:
8732f09c722SMichael Maitland   // Vector Narrowing Integer Right Shift Instructions
874412ab602SMichael Maitland   case RISCV::VNSRL_WX:
8751c94388fSMichael Maitland   case RISCV::VNSRL_WI:
876412ab602SMichael Maitland   case RISCV::VNSRL_WV:
877412ab602SMichael Maitland   case RISCV::VNSRA_WI:
878412ab602SMichael Maitland   case RISCV::VNSRA_WV:
879412ab602SMichael Maitland   case RISCV::VNSRA_WX:
8802f09c722SMichael Maitland   // Vector Integer Compare Instructions
8817442be68SMichael Maitland   case RISCV::VMSEQ_VI:
8827442be68SMichael Maitland   case RISCV::VMSEQ_VV:
8837442be68SMichael Maitland   case RISCV::VMSEQ_VX:
8847442be68SMichael Maitland   case RISCV::VMSNE_VI:
8857442be68SMichael Maitland   case RISCV::VMSNE_VV:
8867442be68SMichael Maitland   case RISCV::VMSNE_VX:
8877442be68SMichael Maitland   case RISCV::VMSLTU_VV:
8887442be68SMichael Maitland   case RISCV::VMSLTU_VX:
8897442be68SMichael Maitland   case RISCV::VMSLT_VV:
8907442be68SMichael Maitland   case RISCV::VMSLT_VX:
8917442be68SMichael Maitland   case RISCV::VMSLEU_VV:
8927442be68SMichael Maitland   case RISCV::VMSLEU_VI:
8937442be68SMichael Maitland   case RISCV::VMSLEU_VX:
8947442be68SMichael Maitland   case RISCV::VMSLE_VV:
8957442be68SMichael Maitland   case RISCV::VMSLE_VI:
8967442be68SMichael Maitland   case RISCV::VMSLE_VX:
8977442be68SMichael Maitland   case RISCV::VMSGTU_VI:
8987442be68SMichael Maitland   case RISCV::VMSGTU_VX:
8997442be68SMichael Maitland   case RISCV::VMSGT_VI:
9007442be68SMichael Maitland   case RISCV::VMSGT_VX:
9012f09c722SMichael Maitland   // Vector Integer Min/Max Instructions
90282e89c02SMichael Maitland   case RISCV::VMINU_VV:
90382e89c02SMichael Maitland   case RISCV::VMINU_VX:
90482e89c02SMichael Maitland   case RISCV::VMIN_VV:
90582e89c02SMichael Maitland   case RISCV::VMIN_VX:
90682e89c02SMichael Maitland   case RISCV::VMAXU_VV:
90782e89c02SMichael Maitland   case RISCV::VMAXU_VX:
90882e89c02SMichael Maitland   case RISCV::VMAX_VV:
90982e89c02SMichael Maitland   case RISCV::VMAX_VX:
9102f09c722SMichael Maitland   // Vector Single-Width Integer Multiply Instructions
9111c94388fSMichael Maitland   case RISCV::VMUL_VV:
9121c94388fSMichael Maitland   case RISCV::VMUL_VX:
9131c94388fSMichael Maitland   case RISCV::VMULH_VV:
9141c94388fSMichael Maitland   case RISCV::VMULH_VX:
9151c94388fSMichael Maitland   case RISCV::VMULHU_VV:
9161c94388fSMichael Maitland   case RISCV::VMULHU_VX:
9171c94388fSMichael Maitland   case RISCV::VMULHSU_VV:
9181c94388fSMichael Maitland   case RISCV::VMULHSU_VX:
9192f09c722SMichael Maitland   // Vector Integer Divide Instructions
920c2c4db8dSMichael Maitland   case RISCV::VDIVU_VV:
921c2c4db8dSMichael Maitland   case RISCV::VDIVU_VX:
922c2c4db8dSMichael Maitland   case RISCV::VDIV_VV:
923c2c4db8dSMichael Maitland   case RISCV::VDIV_VX:
924c2c4db8dSMichael Maitland   case RISCV::VREMU_VV:
925c2c4db8dSMichael Maitland   case RISCV::VREMU_VX:
926c2c4db8dSMichael Maitland   case RISCV::VREM_VV:
927c2c4db8dSMichael Maitland   case RISCV::VREM_VX:
9282f09c722SMichael Maitland   // Vector Widening Integer Multiply Instructions
929658ff0b8SMichael Maitland   case RISCV::VWMUL_VV:
930658ff0b8SMichael Maitland   case RISCV::VWMUL_VX:
931658ff0b8SMichael Maitland   case RISCV::VWMULSU_VV:
932658ff0b8SMichael Maitland   case RISCV::VWMULSU_VX:
933658ff0b8SMichael Maitland   case RISCV::VWMULU_VV:
934658ff0b8SMichael Maitland   case RISCV::VWMULU_VX:
9352f09c722SMichael Maitland   // Vector Single-Width Integer Multiply-Add Instructions
9363a573dcdSMichael Maitland   case RISCV::VMACC_VV:
9373a573dcdSMichael Maitland   case RISCV::VMACC_VX:
9383a573dcdSMichael Maitland   case RISCV::VNMSAC_VV:
9393a573dcdSMichael Maitland   case RISCV::VNMSAC_VX:
9403a573dcdSMichael Maitland   case RISCV::VMADD_VV:
9413a573dcdSMichael Maitland   case RISCV::VMADD_VX:
9423a573dcdSMichael Maitland   case RISCV::VNMSUB_VV:
9433a573dcdSMichael Maitland   case RISCV::VNMSUB_VX:
944328c3a84SMichael Maitland   // Vector Integer Merge Instructions
945328c3a84SMichael Maitland   case RISCV::VMERGE_VIM:
946328c3a84SMichael Maitland   case RISCV::VMERGE_VVM:
947328c3a84SMichael Maitland   case RISCV::VMERGE_VXM:
948d0373dbeSMichael Maitland   // Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
949d0373dbeSMichael Maitland   case RISCV::VADC_VIM:
950d0373dbeSMichael Maitland   case RISCV::VADC_VVM:
951d0373dbeSMichael Maitland   case RISCV::VADC_VXM:
9522f09c722SMichael Maitland   // Vector Widening Integer Multiply-Add Instructions
953131b7fe2SMichael Maitland   case RISCV::VWMACCU_VV:
9541c94388fSMichael Maitland   case RISCV::VWMACCU_VX:
955131b7fe2SMichael Maitland   case RISCV::VWMACC_VV:
956131b7fe2SMichael Maitland   case RISCV::VWMACC_VX:
957131b7fe2SMichael Maitland   case RISCV::VWMACCSU_VV:
958131b7fe2SMichael Maitland   case RISCV::VWMACCSU_VX:
959131b7fe2SMichael Maitland   case RISCV::VWMACCUS_VX:
9602f09c722SMichael Maitland   // Vector Integer Merge Instructions
9612f09c722SMichael Maitland   // FIXME: Add support
9622f09c722SMichael Maitland   // Vector Integer Move Instructions
9632f09c722SMichael Maitland   // FIXME: Add support
9641c94388fSMichael Maitland   case RISCV::VMV_V_I:
9651c94388fSMichael Maitland   case RISCV::VMV_V_X:
9669bb29c3dSMichael Maitland   case RISCV::VMV_V_V:
96704e54cc1SMichael Maitland   // Vector Single-Width Averaging Add and Subtract
96804e54cc1SMichael Maitland   case RISCV::VAADDU_VV:
96904e54cc1SMichael Maitland   case RISCV::VAADDU_VX:
97004e54cc1SMichael Maitland   case RISCV::VAADD_VV:
97104e54cc1SMichael Maitland   case RISCV::VAADD_VX:
97204e54cc1SMichael Maitland   case RISCV::VASUBU_VV:
97304e54cc1SMichael Maitland   case RISCV::VASUBU_VX:
97404e54cc1SMichael Maitland   case RISCV::VASUB_VV:
97504e54cc1SMichael Maitland   case RISCV::VASUB_VX:
9761c94388fSMichael Maitland 
9771c94388fSMichael Maitland   // Vector Crypto
9781c94388fSMichael Maitland   case RISCV::VWSLL_VI:
979d99c9994SMichael Maitland 
980d99c9994SMichael Maitland   // Vector Mask Instructions
981d99c9994SMichael Maitland   // Vector Mask-Register Logical Instructions
982d99c9994SMichael Maitland   // vmsbf.m set-before-first mask bit
983d99c9994SMichael Maitland   // vmsif.m set-including-first mask bit
984d99c9994SMichael Maitland   // vmsof.m set-only-first mask bit
985fb33268dSMichael Maitland   // Vector Iota Instruction
986fb33268dSMichael Maitland   // Vector Element Index Instruction
987d99c9994SMichael Maitland   case RISCV::VMAND_MM:
988d99c9994SMichael Maitland   case RISCV::VMNAND_MM:
989d99c9994SMichael Maitland   case RISCV::VMANDN_MM:
990d99c9994SMichael Maitland   case RISCV::VMXOR_MM:
991d99c9994SMichael Maitland   case RISCV::VMOR_MM:
992d99c9994SMichael Maitland   case RISCV::VMNOR_MM:
993d99c9994SMichael Maitland   case RISCV::VMORN_MM:
994d99c9994SMichael Maitland   case RISCV::VMXNOR_MM:
995d99c9994SMichael Maitland   case RISCV::VMSBF_M:
996d99c9994SMichael Maitland   case RISCV::VMSIF_M:
997d99c9994SMichael Maitland   case RISCV::VMSOF_M:
998fb33268dSMichael Maitland   case RISCV::VIOTA_M:
999fb33268dSMichael Maitland   case RISCV::VID_V:
1000c036a9a2SMichael Maitland   // Vector Single-Width Floating-Point Add/Subtract Instructions
1001c036a9a2SMichael Maitland   case RISCV::VFADD_VF:
1002c036a9a2SMichael Maitland   case RISCV::VFADD_VV:
1003c036a9a2SMichael Maitland   case RISCV::VFSUB_VF:
1004c036a9a2SMichael Maitland   case RISCV::VFSUB_VV:
1005c036a9a2SMichael Maitland   case RISCV::VFRSUB_VF:
10068beb9d39SMichael Maitland   // Vector Widening Floating-Point Add/Subtract Instructions
10078beb9d39SMichael Maitland   case RISCV::VFWADD_VV:
10088beb9d39SMichael Maitland   case RISCV::VFWADD_VF:
10098beb9d39SMichael Maitland   case RISCV::VFWSUB_VV:
10108beb9d39SMichael Maitland   case RISCV::VFWSUB_VF:
10118beb9d39SMichael Maitland   case RISCV::VFWADD_WF:
10128beb9d39SMichael Maitland   case RISCV::VFWADD_WV:
10138beb9d39SMichael Maitland   case RISCV::VFWSUB_WF:
10148beb9d39SMichael Maitland   case RISCV::VFWSUB_WV:
1015a484fa1dSMichael Maitland   // Vector Single-Width Floating-Point Multiply/Divide Instructions
1016a484fa1dSMichael Maitland   case RISCV::VFMUL_VF:
1017a484fa1dSMichael Maitland   case RISCV::VFMUL_VV:
1018a484fa1dSMichael Maitland   case RISCV::VFDIV_VF:
1019a484fa1dSMichael Maitland   case RISCV::VFDIV_VV:
1020a484fa1dSMichael Maitland   case RISCV::VFRDIV_VF:
1021b419edeeSMichael Maitland   // Vector Widening Floating-Point Multiply
1022b419edeeSMichael Maitland   case RISCV::VFWMUL_VF:
1023b419edeeSMichael Maitland   case RISCV::VFWMUL_VV:
1024f402e06eSMichael Maitland   // Vector Floating-Point MIN/MAX Instructions
1025f402e06eSMichael Maitland   case RISCV::VFMIN_VF:
1026f402e06eSMichael Maitland   case RISCV::VFMIN_VV:
1027f402e06eSMichael Maitland   case RISCV::VFMAX_VF:
1028f402e06eSMichael Maitland   case RISCV::VFMAX_VV:
1029bf258dbdSMichael Maitland   // Vector Floating-Point Sign-Injection Instructions
1030bf258dbdSMichael Maitland   case RISCV::VFSGNJ_VF:
1031bf258dbdSMichael Maitland   case RISCV::VFSGNJ_VV:
1032bf258dbdSMichael Maitland   case RISCV::VFSGNJN_VV:
1033bf258dbdSMichael Maitland   case RISCV::VFSGNJN_VF:
1034bf258dbdSMichael Maitland   case RISCV::VFSGNJX_VF:
1035bf258dbdSMichael Maitland   case RISCV::VFSGNJX_VV:
10365f70fea7SMichael Maitland   // Vector Floating-Point Compare Instructions
10375f70fea7SMichael Maitland   case RISCV::VMFEQ_VF:
10385f70fea7SMichael Maitland   case RISCV::VMFEQ_VV:
10395f70fea7SMichael Maitland   case RISCV::VMFNE_VF:
10405f70fea7SMichael Maitland   case RISCV::VMFNE_VV:
10415f70fea7SMichael Maitland   case RISCV::VMFLT_VF:
10425f70fea7SMichael Maitland   case RISCV::VMFLT_VV:
10435f70fea7SMichael Maitland   case RISCV::VMFLE_VF:
10445f70fea7SMichael Maitland   case RISCV::VMFLE_VV:
10455f70fea7SMichael Maitland   case RISCV::VMFGT_VF:
10465f70fea7SMichael Maitland   case RISCV::VMFGE_VF:
1047e93181bfSMichael Maitland   // Single-Width Floating-Point/Integer Type-Convert Instructions
1048e93181bfSMichael Maitland   case RISCV::VFCVT_XU_F_V:
1049e93181bfSMichael Maitland   case RISCV::VFCVT_X_F_V:
1050e93181bfSMichael Maitland   case RISCV::VFCVT_RTZ_XU_F_V:
1051e93181bfSMichael Maitland   case RISCV::VFCVT_RTZ_X_F_V:
1052e93181bfSMichael Maitland   case RISCV::VFCVT_F_XU_V:
1053e93181bfSMichael Maitland   case RISCV::VFCVT_F_X_V:
1054e93181bfSMichael Maitland   // Widening Floating-Point/Integer Type-Convert Instructions
1055e93181bfSMichael Maitland   case RISCV::VFWCVT_XU_F_V:
1056e93181bfSMichael Maitland   case RISCV::VFWCVT_X_F_V:
1057e93181bfSMichael Maitland   case RISCV::VFWCVT_RTZ_XU_F_V:
1058e93181bfSMichael Maitland   case RISCV::VFWCVT_RTZ_X_F_V:
1059e93181bfSMichael Maitland   case RISCV::VFWCVT_F_XU_V:
1060e93181bfSMichael Maitland   case RISCV::VFWCVT_F_X_V:
1061e93181bfSMichael Maitland   case RISCV::VFWCVT_F_F_V:
1062e44f03ddSMichael Maitland   case RISCV::VFWCVTBF16_F_F_V:
1063e93181bfSMichael Maitland   // Narrowing Floating-Point/Integer Type-Convert Instructions
1064e93181bfSMichael Maitland   case RISCV::VFNCVT_XU_F_W:
1065e93181bfSMichael Maitland   case RISCV::VFNCVT_X_F_W:
1066e93181bfSMichael Maitland   case RISCV::VFNCVT_RTZ_XU_F_W:
1067e93181bfSMichael Maitland   case RISCV::VFNCVT_RTZ_X_F_W:
1068e93181bfSMichael Maitland   case RISCV::VFNCVT_F_XU_W:
1069e93181bfSMichael Maitland   case RISCV::VFNCVT_F_X_W:
1070e93181bfSMichael Maitland   case RISCV::VFNCVT_F_F_W:
1071e93181bfSMichael Maitland   case RISCV::VFNCVT_ROD_F_F_W:
1072e44f03ddSMichael Maitland   case RISCV::VFNCVTBF16_F_F_W:
10731c94388fSMichael Maitland     return true;
10741c94388fSMichael Maitland   }
10751c94388fSMichael Maitland 
10761c94388fSMichael Maitland   return false;
10771c94388fSMichael Maitland }
10781c94388fSMichael Maitland 
10791c94388fSMichael Maitland /// Return true if MO is a vector operand but is used as a scalar operand.
10801c94388fSMichael Maitland static bool isVectorOpUsedAsScalarOp(MachineOperand &MO) {
10811c94388fSMichael Maitland   MachineInstr *MI = MO.getParent();
10821c94388fSMichael Maitland   const RISCVVPseudosTable::PseudoInfo *RVV =
10831c94388fSMichael Maitland       RISCVVPseudosTable::getPseudoInfo(MI->getOpcode());
10841c94388fSMichael Maitland 
10851c94388fSMichael Maitland   if (!RVV)
10861c94388fSMichael Maitland     return false;
10871c94388fSMichael Maitland 
10881c94388fSMichael Maitland   switch (RVV->BaseInstr) {
10891c94388fSMichael Maitland   // Reductions only use vs1[0] of vs1
10901c94388fSMichael Maitland   case RISCV::VREDAND_VS:
10911c94388fSMichael Maitland   case RISCV::VREDMAX_VS:
10921c94388fSMichael Maitland   case RISCV::VREDMAXU_VS:
10931c94388fSMichael Maitland   case RISCV::VREDMIN_VS:
10941c94388fSMichael Maitland   case RISCV::VREDMINU_VS:
10951c94388fSMichael Maitland   case RISCV::VREDOR_VS:
10961c94388fSMichael Maitland   case RISCV::VREDSUM_VS:
10971c94388fSMichael Maitland   case RISCV::VREDXOR_VS:
10981c94388fSMichael Maitland   case RISCV::VWREDSUM_VS:
10991c94388fSMichael Maitland   case RISCV::VWREDSUMU_VS:
11001c94388fSMichael Maitland   case RISCV::VFREDMAX_VS:
11011c94388fSMichael Maitland   case RISCV::VFREDMIN_VS:
11021c94388fSMichael Maitland   case RISCV::VFREDOSUM_VS:
11031c94388fSMichael Maitland   case RISCV::VFREDUSUM_VS:
11041c94388fSMichael Maitland   case RISCV::VFWREDOSUM_VS:
1105043f066aSLuke Lau   case RISCV::VFWREDUSUM_VS:
1106043f066aSLuke Lau     return MO.getOperandNo() == 3;
11078b577043SMichael Maitland   case RISCV::VMV_X_S:
11088b577043SMichael Maitland   case RISCV::VFMV_F_S:
11098b577043SMichael Maitland     return MO.getOperandNo() == 1;
11101c94388fSMichael Maitland   default:
11111c94388fSMichael Maitland     return false;
11121c94388fSMichael Maitland   }
11131c94388fSMichael Maitland }
11141c94388fSMichael Maitland 
11151c94388fSMichael Maitland /// Return true if MI may read elements past VL.
11161c94388fSMichael Maitland static bool mayReadPastVL(const MachineInstr &MI) {
11171c94388fSMichael Maitland   const RISCVVPseudosTable::PseudoInfo *RVV =
11181c94388fSMichael Maitland       RISCVVPseudosTable::getPseudoInfo(MI.getOpcode());
11191c94388fSMichael Maitland   if (!RVV)
11201c94388fSMichael Maitland     return true;
11211c94388fSMichael Maitland 
11221c94388fSMichael Maitland   switch (RVV->BaseInstr) {
11231c94388fSMichael Maitland   // vslidedown instructions may read elements past VL. They are handled
11241c94388fSMichael Maitland   // according to current tail policy.
11251c94388fSMichael Maitland   case RISCV::VSLIDEDOWN_VI:
11261c94388fSMichael Maitland   case RISCV::VSLIDEDOWN_VX:
11271c94388fSMichael Maitland   case RISCV::VSLIDE1DOWN_VX:
11281c94388fSMichael Maitland   case RISCV::VFSLIDE1DOWN_VF:
11291c94388fSMichael Maitland 
11301c94388fSMichael Maitland   // vrgather instructions may read the source vector at any index < VLMAX,
11311c94388fSMichael Maitland   // regardless of VL.
11321c94388fSMichael Maitland   case RISCV::VRGATHER_VI:
11331c94388fSMichael Maitland   case RISCV::VRGATHER_VV:
11341c94388fSMichael Maitland   case RISCV::VRGATHER_VX:
11351c94388fSMichael Maitland   case RISCV::VRGATHEREI16_VV:
11361c94388fSMichael Maitland     return true;
11371c94388fSMichael Maitland 
11381c94388fSMichael Maitland   default:
11391c94388fSMichael Maitland     return false;
11401c94388fSMichael Maitland   }
11411c94388fSMichael Maitland }
11421c94388fSMichael Maitland 
11431c94388fSMichael Maitland bool RISCVVLOptimizer::isCandidate(const MachineInstr &MI) const {
11441c94388fSMichael Maitland   const MCInstrDesc &Desc = MI.getDesc();
11451c94388fSMichael Maitland   if (!RISCVII::hasVLOp(Desc.TSFlags) || !RISCVII::hasSEWOp(Desc.TSFlags))
11461c94388fSMichael Maitland     return false;
11471c94388fSMichael Maitland   if (MI.getNumDefs() != 1)
11481c94388fSMichael Maitland     return false;
11491c94388fSMichael Maitland 
1150e93181bfSMichael Maitland   if (MI.mayRaiseFPException()) {
1151e93181bfSMichael Maitland     LLVM_DEBUG(dbgs() << "Not a candidate because may raise FP exception\n");
1152e93181bfSMichael Maitland     return false;
1153e93181bfSMichael Maitland   }
1154e93181bfSMichael Maitland 
11551c94388fSMichael Maitland   // Some instructions that produce vectors have semantics that make it more
11561c94388fSMichael Maitland   // difficult to determine whether the VL can be reduced. For example, some
11571c94388fSMichael Maitland   // instructions, such as reductions, may write lanes past VL to a scalar
11581c94388fSMichael Maitland   // register. Other instructions, such as some loads or stores, may write
11591c94388fSMichael Maitland   // lower lanes using data from higher lanes. There may be other complex
11601c94388fSMichael Maitland   // semantics not mentioned here that make it hard to determine whether
11611c94388fSMichael Maitland   // the VL can be optimized. As a result, a white-list of supported
11622214e023SCraig Topper   // instructions is used. Over time, more instructions can be supported
11631c94388fSMichael Maitland   // upon careful examination of their semantics under the logic in this
11641c94388fSMichael Maitland   // optimization.
11651c94388fSMichael Maitland   // TODO: Use a better approach than a white-list, such as adding
11661c94388fSMichael Maitland   // properties to instructions using something like TSFlags.
11671c94388fSMichael Maitland   if (!isSupportedInstr(MI)) {
11681c94388fSMichael Maitland     LLVM_DEBUG(dbgs() << "Not a candidate due to unsupported instruction\n");
11691c94388fSMichael Maitland     return false;
11701c94388fSMichael Maitland   }
11711c94388fSMichael Maitland 
117227ccc99cSPhilip Reames   assert(MI.getOperand(0).isReg() &&
117327ccc99cSPhilip Reames          isVectorRegClass(MI.getOperand(0).getReg(), MRI) &&
117427ccc99cSPhilip Reames          "All supported instructions produce a vector register result");
117527ccc99cSPhilip Reames 
11761c94388fSMichael Maitland   LLVM_DEBUG(dbgs() << "Found a candidate for VL reduction: " << MI << "\n");
11771c94388fSMichael Maitland   return true;
11781c94388fSMichael Maitland }
11791c94388fSMichael Maitland 
1180142787d3SMichael Maitland std::optional<MachineOperand>
1181142787d3SMichael Maitland RISCVVLOptimizer::getMinimumVLForUser(MachineOperand &UserOp) {
1182142787d3SMichael Maitland   const MachineInstr &UserMI = *UserOp.getParent();
1183142787d3SMichael Maitland   const MCInstrDesc &Desc = UserMI.getDesc();
1184142787d3SMichael Maitland 
1185142787d3SMichael Maitland   if (!RISCVII::hasVLOp(Desc.TSFlags) || !RISCVII::hasSEWOp(Desc.TSFlags)) {
1186142787d3SMichael Maitland     LLVM_DEBUG(dbgs() << "    Abort due to lack of VL, assume that"
1187142787d3SMichael Maitland                          " use VLMAX\n");
1188142787d3SMichael Maitland     return std::nullopt;
1189142787d3SMichael Maitland   }
1190142787d3SMichael Maitland 
1191142787d3SMichael Maitland   // Instructions like reductions may use a vector register as a scalar
1192142787d3SMichael Maitland   // register. In this case, we should treat it as only reading the first lane.
1193142787d3SMichael Maitland   if (isVectorOpUsedAsScalarOp(UserOp)) {
1194142787d3SMichael Maitland     [[maybe_unused]] Register R = UserOp.getReg();
1195142787d3SMichael Maitland     [[maybe_unused]] const TargetRegisterClass *RC = MRI->getRegClass(R);
1196142787d3SMichael Maitland     assert(RISCV::VRRegClass.hasSubClassEq(RC) &&
1197142787d3SMichael Maitland            "Expect LMUL 1 register class for vector as scalar operands!");
1198142787d3SMichael Maitland     LLVM_DEBUG(dbgs() << "    Used this operand as a scalar operand\n");
1199142787d3SMichael Maitland 
1200142787d3SMichael Maitland     return MachineOperand::CreateImm(1);
1201142787d3SMichael Maitland   }
1202142787d3SMichael Maitland 
1203142787d3SMichael Maitland   unsigned VLOpNum = RISCVII::getVLOpNum(Desc);
1204142787d3SMichael Maitland   const MachineOperand &VLOp = UserMI.getOperand(VLOpNum);
1205142787d3SMichael Maitland   // Looking for an immediate or a register VL that isn't X0.
1206142787d3SMichael Maitland   assert((!VLOp.isReg() || VLOp.getReg() != RISCV::X0) &&
1207142787d3SMichael Maitland          "Did not expect X0 VL");
1208*8675cd3fSLuke Lau 
1209*8675cd3fSLuke Lau   // If we know the demanded VL of UserMI, then we can reduce the VL it
1210*8675cd3fSLuke Lau   // requires.
1211*8675cd3fSLuke Lau   if (auto DemandedVL = DemandedVLs[&UserMI]) {
1212*8675cd3fSLuke Lau     assert(isCandidate(UserMI));
1213*8675cd3fSLuke Lau     if (RISCV::isVLKnownLE(*DemandedVL, VLOp))
1214*8675cd3fSLuke Lau       return DemandedVL;
1215*8675cd3fSLuke Lau   }
1216*8675cd3fSLuke Lau 
1217142787d3SMichael Maitland   return VLOp;
1218142787d3SMichael Maitland }
1219142787d3SMichael Maitland 
1220142787d3SMichael Maitland std::optional<MachineOperand> RISCVVLOptimizer::checkUsers(MachineInstr &MI) {
1221142787d3SMichael Maitland   std::optional<MachineOperand> CommonVL;
12221c94388fSMichael Maitland   for (auto &UserOp : MRI->use_operands(MI.getOperand(0).getReg())) {
12231c94388fSMichael Maitland     const MachineInstr &UserMI = *UserOp.getParent();
12241c94388fSMichael Maitland     LLVM_DEBUG(dbgs() << "  Checking user: " << UserMI << "\n");
12251c94388fSMichael Maitland     if (mayReadPastVL(UserMI)) {
12261c94388fSMichael Maitland       LLVM_DEBUG(dbgs() << "    Abort because used by unsafe instruction\n");
1227142787d3SMichael Maitland       return std::nullopt;
12281c94388fSMichael Maitland     }
12291c94388fSMichael Maitland 
1230cb6f021aSLuke Lau     // If used as a passthru, elements past VL will be read.
12311c94388fSMichael Maitland     if (UserOp.isTied()) {
12321c94388fSMichael Maitland       LLVM_DEBUG(dbgs() << "    Abort because user used as tied operand\n");
1233142787d3SMichael Maitland       return std::nullopt;
12341c94388fSMichael Maitland     }
12351c94388fSMichael Maitland 
1236142787d3SMichael Maitland     auto VLOp = getMinimumVLForUser(UserOp);
1237142787d3SMichael Maitland     if (!VLOp)
1238142787d3SMichael Maitland       return std::nullopt;
12391c94388fSMichael Maitland 
124037100505SMichael Maitland     // Use the largest VL among all the users. If we cannot determine this
124137100505SMichael Maitland     // statically, then we cannot optimize the VL.
1242142787d3SMichael Maitland     if (!CommonVL || RISCV::isVLKnownLE(*CommonVL, *VLOp)) {
1243142787d3SMichael Maitland       CommonVL = *VLOp;
1244ae68d532SMichael Maitland       LLVM_DEBUG(dbgs() << "    User VL is: " << VLOp << "\n");
1245142787d3SMichael Maitland     } else if (!RISCV::isVLKnownLE(*VLOp, *CommonVL)) {
124637100505SMichael Maitland       LLVM_DEBUG(dbgs() << "    Abort because cannot determine a common VL\n");
1247142787d3SMichael Maitland       return std::nullopt;
12481c94388fSMichael Maitland     }
12491c94388fSMichael Maitland 
1250142787d3SMichael Maitland     if (!RISCVII::hasSEWOp(UserMI.getDesc().TSFlags)) {
1251142787d3SMichael Maitland       LLVM_DEBUG(dbgs() << "    Abort due to lack of SEW operand\n");
1252142787d3SMichael Maitland       return std::nullopt;
1253142787d3SMichael Maitland     }
1254142787d3SMichael Maitland 
12550b4fca5bSPhilip Reames     std::optional<OperandInfo> ConsumerInfo = getOperandInfo(UserOp, MRI);
12560b4fca5bSPhilip Reames     std::optional<OperandInfo> ProducerInfo =
12570b4fca5bSPhilip Reames         getOperandInfo(MI.getOperand(0), MRI);
12580b4fca5bSPhilip Reames     if (!ConsumerInfo || !ProducerInfo) {
1259142787d3SMichael Maitland       LLVM_DEBUG(dbgs() << "    Abort due to unknown operand information.\n");
12601c94388fSMichael Maitland       LLVM_DEBUG(dbgs() << "      ConsumerInfo is: " << ConsumerInfo << "\n");
12611c94388fSMichael Maitland       LLVM_DEBUG(dbgs() << "      ProducerInfo is: " << ProducerInfo << "\n");
1262142787d3SMichael Maitland       return std::nullopt;
1263142787d3SMichael Maitland     }
1264142787d3SMichael Maitland 
1265142787d3SMichael Maitland     // If the operand is used as a scalar operand, then the EEW must be
1266142787d3SMichael Maitland     // compatible. Otherwise, the EMUL *and* EEW must be compatible.
1267142787d3SMichael Maitland     bool IsVectorOpUsedAsScalarOp = isVectorOpUsedAsScalarOp(UserOp);
1268142787d3SMichael Maitland     if ((IsVectorOpUsedAsScalarOp &&
12690b4fca5bSPhilip Reames          !OperandInfo::EEWAreEqual(*ConsumerInfo, *ProducerInfo)) ||
1270142787d3SMichael Maitland         (!IsVectorOpUsedAsScalarOp &&
12710b4fca5bSPhilip Reames          !OperandInfo::EMULAndEEWAreEqual(*ConsumerInfo, *ProducerInfo))) {
1272142787d3SMichael Maitland       LLVM_DEBUG(
1273142787d3SMichael Maitland           dbgs()
1274142787d3SMichael Maitland           << "    Abort due to incompatible information for EMUL or EEW.\n");
1275142787d3SMichael Maitland       LLVM_DEBUG(dbgs() << "      ConsumerInfo is: " << ConsumerInfo << "\n");
1276142787d3SMichael Maitland       LLVM_DEBUG(dbgs() << "      ProducerInfo is: " << ProducerInfo << "\n");
1277142787d3SMichael Maitland       return std::nullopt;
12781c94388fSMichael Maitland     }
12791c94388fSMichael Maitland   }
1280142787d3SMichael Maitland 
1281142787d3SMichael Maitland   return CommonVL;
12821c94388fSMichael Maitland }
12831c94388fSMichael Maitland 
128458959325SPhilip Reames bool RISCVVLOptimizer::tryReduceVL(MachineInstr &MI) {
12851c94388fSMichael Maitland   LLVM_DEBUG(dbgs() << "Trying to reduce VL for " << MI << "\n");
12861c94388fSMichael Maitland 
1287ff271d04SLuke Lau   unsigned VLOpNum = RISCVII::getVLOpNum(MI.getDesc());
1288ff271d04SLuke Lau   MachineOperand &VLOp = MI.getOperand(VLOpNum);
1289ff271d04SLuke Lau 
1290ff271d04SLuke Lau   // If the VL is 1, then there is no need to reduce it. This is an
1291ff271d04SLuke Lau   // optimization, not needed to preserve correctness.
1292ff271d04SLuke Lau   if (VLOp.isImm() && VLOp.getImm() == 1) {
1293ff271d04SLuke Lau     LLVM_DEBUG(dbgs() << "  Abort due to VL == 1, no point in reducing.\n");
1294ff271d04SLuke Lau     return false;
1295ff271d04SLuke Lau   }
1296ff271d04SLuke Lau 
1297*8675cd3fSLuke Lau   auto CommonVL = DemandedVLs[&MI];
1298142787d3SMichael Maitland   if (!CommonVL)
129958959325SPhilip Reames     return false;
13001c94388fSMichael Maitland 
1301ae68d532SMichael Maitland   assert((CommonVL->isImm() || CommonVL->getReg().isVirtual()) &&
1302ae68d532SMichael Maitland          "Expected VL to be an Imm or virtual Reg");
1303ae68d532SMichael Maitland 
1304ae68d532SMichael Maitland   if (!RISCV::isVLKnownLE(*CommonVL, VLOp)) {
1305ae68d532SMichael Maitland     LLVM_DEBUG(dbgs() << "    Abort due to CommonVL not <= VLOp.\n");
130658959325SPhilip Reames     return false;
13071c94388fSMichael Maitland   }
13081c94388fSMichael Maitland 
13091687aa2aSMichael Maitland   if (CommonVL->isIdenticalTo(VLOp)) {
13101687aa2aSMichael Maitland     LLVM_DEBUG(
13111687aa2aSMichael Maitland         dbgs() << "    Abort due to CommonVL == VLOp, no point in reducing.\n");
13121687aa2aSMichael Maitland     return false;
13131687aa2aSMichael Maitland   }
13141687aa2aSMichael Maitland 
1315ae68d532SMichael Maitland   if (CommonVL->isImm()) {
1316ae68d532SMichael Maitland     LLVM_DEBUG(dbgs() << "  Reduce VL from " << VLOp << " to "
1317ae68d532SMichael Maitland                       << CommonVL->getImm() << " for " << MI << "\n");
1318ae68d532SMichael Maitland     VLOp.ChangeToImmediate(CommonVL->getImm());
131958959325SPhilip Reames     return true;
132058959325SPhilip Reames   }
1321ae68d532SMichael Maitland   const MachineInstr *VLMI = MRI->getVRegDef(CommonVL->getReg());
13221c94388fSMichael Maitland   if (!MDT->dominates(VLMI, &MI))
132358959325SPhilip Reames     return false;
1324ae68d532SMichael Maitland   LLVM_DEBUG(
1325ae68d532SMichael Maitland       dbgs() << "  Reduce VL from " << VLOp << " to "
1326ae68d532SMichael Maitland              << printReg(CommonVL->getReg(), MRI->getTargetRegisterInfo())
1327ae68d532SMichael Maitland              << " for " << MI << "\n");
13281c94388fSMichael Maitland 
13291c94388fSMichael Maitland   // All our checks passed. We can reduce VL.
1330ae68d532SMichael Maitland   VLOp.ChangeToRegister(CommonVL->getReg(), false);
133158959325SPhilip Reames   return true;
13321c94388fSMichael Maitland }
13331c94388fSMichael Maitland 
13341c94388fSMichael Maitland bool RISCVVLOptimizer::runOnMachineFunction(MachineFunction &MF) {
13351c94388fSMichael Maitland   if (skipFunction(MF.getFunction()))
13361c94388fSMichael Maitland     return false;
13371c94388fSMichael Maitland 
13381c94388fSMichael Maitland   MRI = &MF.getRegInfo();
13391c94388fSMichael Maitland   MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
13401c94388fSMichael Maitland 
13411c94388fSMichael Maitland   const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
13421c94388fSMichael Maitland   if (!ST.hasVInstructions())
13431c94388fSMichael Maitland     return false;
13441c94388fSMichael Maitland 
1345*8675cd3fSLuke Lau   // For each instruction that defines a vector, compute what VL its
1346*8675cd3fSLuke Lau   // downstream users demand.
1347*8675cd3fSLuke Lau   for (MachineBasicBlock *MBB : post_order(&MF)) {
1348*8675cd3fSLuke Lau     assert(MDT->isReachableFromEntry(MBB));
1349*8675cd3fSLuke Lau     for (MachineInstr &MI : reverse(*MBB)) {
1350*8675cd3fSLuke Lau       if (!isCandidate(MI))
135158959325SPhilip Reames         continue;
1352*8675cd3fSLuke Lau       DemandedVLs.insert({&MI, checkUsers(MI)});
135358959325SPhilip Reames     }
1354*8675cd3fSLuke Lau   }
135558959325SPhilip Reames 
1356*8675cd3fSLuke Lau   // Then go through and see if we can reduce the VL of any instructions to
1357*8675cd3fSLuke Lau   // only what's demanded.
13581c94388fSMichael Maitland   bool MadeChange = false;
13591c94388fSMichael Maitland   for (MachineBasicBlock &MBB : MF) {
136058959325SPhilip Reames     // Avoid unreachable blocks as they have degenerate dominance
136158959325SPhilip Reames     if (!MDT->isReachableFromEntry(&MBB))
136258959325SPhilip Reames       continue;
136358959325SPhilip Reames 
1364c8d3ccfaSLuke Lau     for (auto &MI : reverse(MBB)) {
13651c94388fSMichael Maitland       if (!isCandidate(MI))
13661c94388fSMichael Maitland         continue;
136758959325SPhilip Reames       if (!tryReduceVL(MI))
136858959325SPhilip Reames         continue;
136958959325SPhilip Reames       MadeChange = true;
13701c94388fSMichael Maitland     }
13711c94388fSMichael Maitland   }
13721c94388fSMichael Maitland 
13731c94388fSMichael Maitland   return MadeChange;
13741c94388fSMichael Maitland }
1375