[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