Skip to content

Commit 2f4dfb6

Browse files
committed
[RISCV][GISel] Support select indexed vector load store intrinsics
1 parent 37cf1fc commit 2f4dfb6

File tree

9 files changed

+25367
-4
lines changed

9 files changed

+25367
-4
lines changed

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

Lines changed: 120 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ class RISCVInstructionSelector : public InstructionSelector {
9595
void addVectorLoadStoreOperands(MachineInstr &I,
9696
SmallVectorImpl<SrcOp> &SrcOps,
9797
unsigned &CurOp, bool IsMasked,
98-
bool IsStrided) const;
98+
bool IsStridedOrIndexed,
99+
LLT *IndexVT = nullptr) const;
99100
bool selectIntrinsicWithSideEffects(MachineInstr &I,
100101
MachineIRBuilder &MIB) const;
101102

@@ -722,15 +723,17 @@ static unsigned selectRegImmLoadStoreOp(unsigned GenericOpc, unsigned OpSize) {
722723

723724
void RISCVInstructionSelector::addVectorLoadStoreOperands(
724725
MachineInstr &I, SmallVectorImpl<SrcOp> &SrcOps, unsigned &CurOp,
725-
bool IsMasked, bool IsStrided) const {
726+
bool IsMasked, bool IsStridedOrIndexed, LLT *IndexVT) const {
726727
// Base Pointer
727728
auto PtrReg = I.getOperand(CurOp++).getReg();
728729
SrcOps.push_back(PtrReg);
729730

730-
// Stride
731-
if (IsStrided) {
731+
// Stride or Index
732+
if (IsStridedOrIndexed) {
732733
auto StrideReg = I.getOperand(CurOp++).getReg();
733734
SrcOps.push_back(StrideReg);
735+
if (IndexVT)
736+
*IndexVT = MRI->getType(StrideReg);
734737
}
735738

736739
// Mask
@@ -805,6 +808,69 @@ bool RISCVInstructionSelector::selectIntrinsicWithSideEffects(
805808
I.eraseFromParent();
806809
return constrainSelectedInstRegOperands(*PseudoMI, TII, TRI, RBI);
807810
}
811+
case Intrinsic::riscv_vloxei:
812+
case Intrinsic::riscv_vloxei_mask:
813+
case Intrinsic::riscv_vluxei:
814+
case Intrinsic::riscv_vluxei_mask: {
815+
bool IsMasked = IntrinID == Intrinsic::riscv_vloxei_mask ||
816+
IntrinID == Intrinsic::riscv_vluxei_mask;
817+
bool IsOrdered = IntrinID == Intrinsic::riscv_vloxei ||
818+
IntrinID == Intrinsic::riscv_vloxei_mask;
819+
LLT VT = MRI->getType(I.getOperand(0).getReg());
820+
unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
821+
822+
// Result vector
823+
const Register DstReg = I.getOperand(0).getReg();
824+
825+
// Sources
826+
bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
827+
unsigned CurOp = 2;
828+
SmallVector<SrcOp, 4> SrcOps; // Source registers.
829+
830+
// Passthru
831+
if (HasPassthruOperand) {
832+
auto PassthruReg = I.getOperand(CurOp++).getReg();
833+
SrcOps.push_back(PassthruReg);
834+
} else {
835+
SrcOps.push_back(Register(RISCV::NoRegister));
836+
}
837+
LLT IndexVT;
838+
addVectorLoadStoreOperands(I, SrcOps, CurOp, IsMasked, true, &IndexVT);
839+
840+
RISCVVType::VLMUL LMUL = RISCVTargetLowering::getLMUL(getMVTForLLT(VT));
841+
RISCVVType::VLMUL IndexLMUL =
842+
RISCVTargetLowering::getLMUL(getMVTForLLT(IndexVT));
843+
unsigned IndexLog2EEW = Log2_32(IndexVT.getScalarSizeInBits());
844+
if (IndexLog2EEW == 6 && !Subtarget->is64Bit()) {
845+
report_fatal_error("The V extension does not support EEW=64 for index "
846+
"values when XLEN=32");
847+
}
848+
const RISCV::VLX_VSXPseudo *P = RISCV::getVLXPseudo(
849+
IsMasked, IsOrdered, IndexLog2EEW, static_cast<unsigned>(LMUL),
850+
static_cast<unsigned>(IndexLMUL));
851+
852+
auto PseudoMI = MIB.buildInstr(P->Pseudo, {DstReg}, SrcOps);
853+
854+
// Select VL
855+
auto VLOpFn = renderVLOp(I.getOperand(CurOp++));
856+
for (auto &RenderFn : *VLOpFn)
857+
RenderFn(PseudoMI);
858+
859+
// SEW
860+
PseudoMI.addImm(Log2SEW);
861+
862+
// Policy
863+
uint64_t Policy = RISCVVType::MASK_AGNOSTIC;
864+
if (IsMasked)
865+
Policy = I.getOperand(CurOp++).getImm();
866+
PseudoMI.addImm(Policy);
867+
868+
// Memref
869+
PseudoMI.cloneMemRefs(I);
870+
871+
I.eraseFromParent();
872+
return constrainSelectedInstRegOperands(*PseudoMI, TII, TRI, RBI);
873+
}
808874
case Intrinsic::riscv_vsm:
809875
case Intrinsic::riscv_vse:
810876
case Intrinsic::riscv_vse_mask:
@@ -847,6 +913,56 @@ bool RISCVInstructionSelector::selectIntrinsicWithSideEffects(
847913
I.eraseFromParent();
848914
return constrainSelectedInstRegOperands(*PseudoMI, TII, TRI, RBI);
849915
}
916+
case Intrinsic::riscv_vsoxei:
917+
case Intrinsic::riscv_vsoxei_mask:
918+
case Intrinsic::riscv_vsuxei:
919+
case Intrinsic::riscv_vsuxei_mask: {
920+
bool IsMasked = IntrinID == Intrinsic::riscv_vsoxei_mask ||
921+
IntrinID == Intrinsic::riscv_vsuxei_mask;
922+
bool IsOrdered = IntrinID == Intrinsic::riscv_vsoxei ||
923+
IntrinID == Intrinsic::riscv_vsoxei_mask;
924+
LLT VT = MRI->getType(I.getOperand(1).getReg());
925+
unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
926+
927+
// Sources
928+
unsigned CurOp = 1;
929+
SmallVector<SrcOp, 4> SrcOps; // Source registers.
930+
931+
// Store value
932+
auto PassthruReg = I.getOperand(CurOp++).getReg();
933+
SrcOps.push_back(PassthruReg);
934+
935+
LLT IndexVT;
936+
addVectorLoadStoreOperands(I, SrcOps, CurOp, IsMasked, true, &IndexVT);
937+
938+
RISCVVType::VLMUL LMUL = RISCVTargetLowering::getLMUL(getMVTForLLT(VT));
939+
RISCVVType::VLMUL IndexLMUL =
940+
RISCVTargetLowering::getLMUL(getMVTForLLT(IndexVT));
941+
unsigned IndexLog2EEW = Log2_32(IndexVT.getScalarSizeInBits());
942+
if (IndexLog2EEW == 6 && !Subtarget->is64Bit()) {
943+
report_fatal_error("The V extension does not support EEW=64 for index "
944+
"values when XLEN=32");
945+
}
946+
const RISCV::VLX_VSXPseudo *P = RISCV::getVSXPseudo(
947+
IsMasked, IsOrdered, IndexLog2EEW, static_cast<unsigned>(LMUL),
948+
static_cast<unsigned>(IndexLMUL));
949+
950+
auto PseudoMI = MIB.buildInstr(P->Pseudo, {}, SrcOps);
951+
952+
// Select VL
953+
auto VLOpFn = renderVLOp(I.getOperand(CurOp++));
954+
for (auto &RenderFn : *VLOpFn)
955+
RenderFn(PseudoMI);
956+
957+
// SEW
958+
PseudoMI.addImm(Log2SEW);
959+
960+
// Memref
961+
PseudoMI.cloneMemRefs(I);
962+
963+
I.eraseFromParent();
964+
return constrainSelectedInstRegOperands(*PseudoMI, TII, TRI, RBI);
965+
}
850966
}
851967
}
852968

0 commit comments

Comments
 (0)