@@ -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+
717801bool 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