@@ -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
723724void 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