@@ -68,6 +68,9 @@ class RISCVInstructionSelector : public InstructionSelector {
6868 // Returns true if the instruction was modified.
6969 void preISelLower (MachineInstr &MI, MachineIRBuilder &MIB);
7070
71+ // An early selection function that runs before the selectImpl() call.
72+ bool earlySelect (MachineInstr &I);
73+
7174 bool replacePtrWithInt (MachineOperand &Op, MachineIRBuilder &MIB);
7275
7376 // Custom selection methods
@@ -530,7 +533,6 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
530533 MachineFunction &MF = *MBB.getParent ();
531534 MachineIRBuilder MIB (MI);
532535
533- bool OpcWasGSplatVector = MI.getOpcode () == TargetOpcode::G_SPLAT_VECTOR;
534536 preISelLower (MI, MIB);
535537 const unsigned Opc = MI.getOpcode ();
536538
@@ -569,17 +571,8 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
569571 return true ;
570572 }
571573
572- // FIXME: We create a IMPLICIT_DEF and a G_CONSTANT in preISelLower when
573- // we encounter a G_SPLAT_VECTOR. We cannot select the G_CONSTANT until after
574- // the MI is lowered, since renderVLOp needs to see the G_CONSTANT. It would
575- // be nice if the InstructionSelector selected these instructions without
576- // needing to call select on them explicitly.
577- if (OpcWasGSplatVector) {
578- MachineInstr *Passthru = MRI->getVRegDef (MI.getOperand (1 ).getReg ());
579- MachineInstr *VL = MRI->getVRegDef (MI.getOperand (3 ).getReg ());
580- if (selectImpl (MI, *CoverageInfo))
581- return select (*Passthru) && select (*VL);
582- }
574+ if (earlySelect (MI))
575+ return true ;
583576
584577 if (selectImpl (MI, *CoverageInfo))
585578 return true ;
@@ -813,8 +806,19 @@ void RISCVInstructionSelector::preISelLower(MachineInstr &MI,
813806 replacePtrWithInt (MI.getOperand (1 ), MIB);
814807 MI.setDesc (TII.get (TargetOpcode::G_AND));
815808 MRI->setType (DstReg, sXLen );
816- break ;
817809 }
810+ }
811+ }
812+
813+ bool RISCVInstructionSelector::earlySelect (MachineInstr &MI) {
814+ assert (MI.getParent () && " Instruction should be in a basic block!" );
815+ assert (MI.getParent ()->getParent () && " Instruction should be in a function!" );
816+
817+ MachineIRBuilder MIB (MI);
818+
819+ switch (MI.getOpcode ()) {
820+ default :
821+ break ;
818822 case TargetOpcode::G_SPLAT_VECTOR: {
819823 // Convert integer SPLAT_VECTOR to VMV_V_X_VL and floating-point
820824 // SPLAT_VECTOR to VFMV_V_F_VL to reduce isel burden.
@@ -825,23 +829,27 @@ void RISCVInstructionSelector::preISelLower(MachineInstr &MI,
825829 sXLen .getSizeInBits ()))
826830 Scalar = MIB.buildAnyExt (sXLen , Scalar).getReg (0 );
827831
828- // Convert MI in place, since select function is trying to select this
829- // instruction.
832+ // We create a IMPLICIT_DEF and a G_CONSTANT when we encounter a
833+ // G_SPLAT_VECTOR. We cannot select the G_CONSTANT until after the MI is
834+ // lowered, since renderVLOp needs to see the G_CONSTANT.
835+ // FIXME: It would be nice if the InstructionSelector selected these
836+ // instructions without needing to call select on them explicitly,
837+ // which would allow us to lower G_SPLAT_VECTOR in preISelLower and
838+ // rely on select to do the selection instead of early selecting here.
830839 unsigned Opc = IsGPRSplat ? RISCV::G_VMV_V_X_VL : RISCV::G_VFMV_V_F_VL;
831- MI.setDesc (TII.get (Opc));
832- MI.removeOperand (1 );
833840 LLT VecTy = MRI->getType (MI.getOperand (0 ).getReg ());
834841 auto Passthru = MIB.buildUndef (VecTy);
835842 auto VLMax = MIB.buildConstant (sXLen , -1 );
836843 MRI->setRegBank (Passthru.getReg (0 ), RBI.getRegBank (RISCV::VRBRegBankID));
837844 MRI->setRegBank (VLMax.getReg (0 ), RBI.getRegBank (RISCV::GPRBRegBankID));
838- MachineInstrBuilder (*MI. getMF (), &MI)
839- . addUse ( Passthru. getReg ( 0 ))
840- . addUse (Scalar)
841- . addUse (VLMax. getReg ( 0 ));
842- break ;
845+ auto Splat = MIB. buildInstr (Opc, {MI. getOperand ( 0 ). getReg ()},
846+ { Passthru, Scalar, VLMax});
847+ MI. eraseFromParent ();
848+ if ( selectImpl (*Splat, *CoverageInfo))
849+ return select (*Passthru) && select (*VLMax) ;
843850 }
844851 }
852+ return false ;
845853}
846854
847855void RISCVInstructionSelector::renderNegImm (MachineInstrBuilder &MIB,
0 commit comments