Skip to content

Commit 279a81e

Browse files
authored
[RISCV][GISel] Support select vector load intrinsics (#160720)
Include unit-stride, strided and mask vector load intrinsics.
1 parent 3cb8a52 commit 279a81e

File tree

4 files changed

+3522
-0
lines changed

4 files changed

+3522
-0
lines changed

llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ class RISCVInstructionSelector : public InstructionSelector {
9292
void emitFence(AtomicOrdering FenceOrdering, SyncScope::ID FenceSSID,
9393
MachineIRBuilder &MIB) const;
9494
bool selectUnmergeValues(MachineInstr &MI, MachineIRBuilder &MIB) const;
95+
bool selectIntrinsicWithSideEffects(MachineInstr &I,
96+
MachineIRBuilder &MIB) const;
9597

9698
ComplexRendererFns selectShiftMask(MachineOperand &Root,
9799
unsigned ShiftWidth) const;
@@ -714,6 +716,88 @@ static unsigned selectRegImmLoadStoreOp(unsigned GenericOpc, unsigned OpSize) {
714716
return GenericOpc;
715717
}
716718

719+
bool RISCVInstructionSelector::selectIntrinsicWithSideEffects(
720+
MachineInstr &I, MachineIRBuilder &MIB) const {
721+
// Find the intrinsic ID.
722+
unsigned IntrinID = cast<GIntrinsic>(I).getIntrinsicID();
723+
// Select the instruction.
724+
switch (IntrinID) {
725+
default:
726+
return false;
727+
case Intrinsic::riscv_vlm:
728+
case Intrinsic::riscv_vle:
729+
case Intrinsic::riscv_vle_mask:
730+
case Intrinsic::riscv_vlse:
731+
case Intrinsic::riscv_vlse_mask: {
732+
bool IsMasked = IntrinID == Intrinsic::riscv_vle_mask ||
733+
IntrinID == Intrinsic::riscv_vlse_mask;
734+
bool IsStrided = IntrinID == Intrinsic::riscv_vlse ||
735+
IntrinID == Intrinsic::riscv_vlse_mask;
736+
LLT VT = MRI->getType(I.getOperand(0).getReg());
737+
unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
738+
739+
// Result vector
740+
const Register DstReg = I.getOperand(0).getReg();
741+
742+
// Sources
743+
bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
744+
unsigned CurOp = 2;
745+
SmallVector<SrcOp, 4> SrcOps; // Source registers.
746+
747+
// Passthru
748+
if (HasPassthruOperand) {
749+
auto PassthruReg = I.getOperand(CurOp++).getReg();
750+
SrcOps.push_back(PassthruReg);
751+
} else {
752+
SrcOps.push_back(Register(RISCV::NoRegister));
753+
}
754+
755+
// Base Pointer
756+
auto PtrReg = I.getOperand(CurOp++).getReg();
757+
SrcOps.push_back(PtrReg);
758+
759+
// Stride
760+
if (IsStrided) {
761+
auto StrideReg = I.getOperand(CurOp++).getReg();
762+
SrcOps.push_back(StrideReg);
763+
}
764+
765+
// Mask
766+
if (IsMasked) {
767+
auto MaskReg = I.getOperand(CurOp++).getReg();
768+
SrcOps.push_back(MaskReg);
769+
}
770+
771+
RISCVVType::VLMUL LMUL = RISCVTargetLowering::getLMUL(getMVTForLLT(VT));
772+
const RISCV::VLEPseudo *P =
773+
RISCV::getVLEPseudo(IsMasked, IsStrided, /*FF*/ false, Log2SEW,
774+
static_cast<unsigned>(LMUL));
775+
776+
auto PseudoMI = MIB.buildInstr(P->Pseudo, {DstReg}, SrcOps);
777+
778+
// Select VL
779+
auto VLOpFn = renderVLOp(I.getOperand(CurOp++));
780+
for (auto &RenderFn : *VLOpFn)
781+
RenderFn(PseudoMI);
782+
783+
// SEW
784+
PseudoMI.addImm(Log2SEW);
785+
786+
// Policy
787+
uint64_t Policy = RISCVVType::MASK_AGNOSTIC;
788+
if (IsMasked)
789+
Policy = I.getOperand(CurOp++).getImm();
790+
PseudoMI.addImm(Policy);
791+
792+
// Memref
793+
PseudoMI.cloneMemRefs(I);
794+
795+
I.eraseFromParent();
796+
return constrainSelectedInstRegOperands(*PseudoMI, TII, TRI, RBI);
797+
}
798+
}
799+
}
800+
717801
bool RISCVInstructionSelector::select(MachineInstr &MI) {
718802
MachineIRBuilder MIB(MI);
719803

@@ -984,6 +1068,8 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
9841068

9851069
return constrainSelectedInstRegOperands(*NewInst, TII, TRI, RBI);
9861070
}
1071+
case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
1072+
return selectIntrinsicWithSideEffects(MI, MIB);
9871073
default:
9881074
return false;
9891075
}

0 commit comments

Comments
 (0)