What is PseudoVADD in RISC-V tablegen?

Hi, I’m quite confuse with the PseudoVADD record define in RISCVInstrInfoVPseudos.td and
RISCVInstrInfoVSDPatterns.td, how does it further transfer into the machine instruction like vadd.vv in LLVM backend? I searched all the strings in LLVM Project to find the place that will reference the PseudoVADD record, but it doesn’t show up in RISCVInstrInfoV.td.

By the way, I’m trying to figure out the procedure that VP intrinsic lower to machine instruction, I know that the SelctionDag will lower ISD::VP_ADD to the RISCVISD::ADD_VL SDNode, and the RISCVISD::ADD_VL SDNode will finally match the PseudoVADD instruction, but it’s a little bit confuse to going further. Can anybody help to explain such procedure? Thanks!

The pseudo instructions carry additional information that the MC layer instructions don’t have. This is due to vsetvli/vsetivli instructions effectively providing additional instruction encoding bits through the VL and VTYPE physical registers.

There are 7 PseudoVADDs, one for each possible LMUL. Four of them are needed because we need different register classes for register allocation to pick LMUL 1, 2, 4, or 8 registers. Fractional LMULs use the same register class as LMUL=1. Register classes foreach operand are statically bound to the MCInstrDesc that each MachineInstr references, so needed different MCInstrDescs.

There other extra operands on the pseudo instructions that contain the SEW(stored in as log2(SEW)) , the AVL, and the tail/mask policy. These operands along with the LMUL stored in the TSFlags of MCInstrDesc are used by the RISCVInsertVSETVLI pass to insert vsetvli/vsetivli instructions as necessary.

The pseudo instructions are converted to their MC layer equivalent by lowerRISCVVMachineInstrToMCInst in RISCVAsmPrinter.cpp (was formerly part of RISCVMCInstLowering.cpp if you’re not on trunk). This is the last pass that runs in the CodeGen pass pipleine. The SEW, AVL, and policy operands are dropped during this conversion. The mapping from the pseudo opcode to MC opcode is done using the tablegen-ed function RISCVVPseudosTable::getPseudoInfo.

Some documentation was just added here ⚙ D152937 [RISCV] Document overview of vector pseudos [nfc]

Hope this helps.