[llvm] [RISCV][GISel] Support select vector load intrinsics (PR #160720)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 29 11:30:27 PDT 2025


================
@@ -675,6 +681,109 @@ static void getOperandsForBranch(Register CondReg, RISCVCC::CondCode &CC,
   CC = getRISCVCCFromICmp(Pred);
 }
 
+bool RISCVInstructionSelector::selectIntrinsicWithSideEffects(
+    MachineInstr &I, MachineIRBuilder &MIB) const {
+  // Find the intrinsic ID.
+  unsigned IntrinID = cast<GIntrinsic>(I).getIntrinsicID();
+  // Select the instruction.
+  switch (IntrinID) {
+  default:
+    return false;
+  case Intrinsic::riscv_vlm:
+  case Intrinsic::riscv_vle:
+  case Intrinsic::riscv_vle_mask:
+  case Intrinsic::riscv_vlse:
+  case Intrinsic::riscv_vlse_mask: {
+    bool IsMasked = IntrinID == Intrinsic::riscv_vle_mask ||
+                    IntrinID == Intrinsic::riscv_vlse_mask;
+    bool IsStrided = IntrinID == Intrinsic::riscv_vlse ||
+                     IntrinID == Intrinsic::riscv_vlse_mask;
+    LLT VT = MRI->getType(I.getOperand(0).getReg());
+    unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
+
+    // Result vector
+    const Register DstReg = I.getOperand(0).getReg();
+    const TargetRegisterClass *DstRC = getRegClassForTypeOnBank(
+        MRI->getType(DstReg), *RBI.getRegBank(DstReg, *MRI, TRI));
+    if (IsMasked)
+      DstRC = TRI.getNoV0RegClass(DstRC);
+    RBI.constrainGenericRegister(DstReg, *DstRC, *MRI);
+
+    // Sources
+    bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
+    unsigned CurOp = 2;
+    SmallVector<SrcOp, 4> SrcOps; // Source registers.
+
+    // Passthru
+    if (HasPassthruOperand) {
+      auto PassthruReg = I.getOperand(CurOp++).getReg();
+      SrcOps.push_back(PassthruReg);
+      RBI.constrainGenericRegister(PassthruReg, *DstRC, *MRI);
+    } else {
+      auto UndefReg = MRI->createVirtualRegister(DstRC);
+      MIB.buildInstr(TargetOpcode::IMPLICIT_DEF).addDef(UndefReg);
+      SrcOps.push_back(UndefReg);
+    }
+
+    // Base Pointer
+    auto PtrReg = I.getOperand(CurOp++).getReg();
+    SrcOps.push_back(PtrReg);
+
+    // Stride
+    if (IsStrided) {
+      auto StrideReg = I.getOperand(CurOp++).getReg();
+      SrcOps.push_back(StrideReg);
+    }
+
+    // Mask
+    if (IsMasked) {
+      auto MaskReg = I.getOperand(CurOp++).getReg();
+      RBI.constrainGenericRegister(MaskReg, RISCV::VMV0RegClass, *MRI);
+      SrcOps.push_back(MaskReg);
+    }
+
+    RISCVVType::VLMUL LMUL = RISCVTargetLowering::getLMUL(getMVTForLLT(VT));
+    const RISCV::VLEPseudo *P =
+        RISCV::getVLEPseudo(IsMasked, IsStrided, /*FF*/ false, Log2SEW,
+                            static_cast<unsigned>(LMUL));
+
+    auto PseudoMI = MIB.buildInstr(P->Pseudo, {DstReg}, SrcOps);
+
+    // Select VL
+    auto VLOpFn = renderVLOp(I.getOperand(CurOp++));
+    for (auto &RenderFn : *VLOpFn)
+      RenderFn(PseudoMI);
+    if (auto VLReg = PseudoMI.getReg(PseudoMI.getInstr()->getNumOperands() - 1))
+      RBI.constrainGenericRegister(VLReg, RISCV::GPRNoX0RegClass, *MRI);
----------------
topperc wrote:

I think this would also be handled by calling `constrainSelectedInstRegOperands` at the end.

https://github.com/llvm/llvm-project/pull/160720


More information about the llvm-commits mailing list