@@ -68,6 +68,9 @@ class RISCVInstructionSelector : public InstructionSelector {
68
68
// Returns true if the instruction was modified.
69
69
void preISelLower (MachineInstr &MI, MachineIRBuilder &MIB);
70
70
71
+ // An early selection function that runs before the selectImpl() call.
72
+ bool earlySelect (MachineInstr &I);
73
+
71
74
bool replacePtrWithInt (MachineOperand &Op, MachineIRBuilder &MIB);
72
75
73
76
// Custom selection methods
@@ -530,7 +533,6 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
530
533
MachineFunction &MF = *MBB.getParent ();
531
534
MachineIRBuilder MIB (MI);
532
535
533
- bool OpcWasGSplatVector = MI.getOpcode () == TargetOpcode::G_SPLAT_VECTOR;
534
536
preISelLower (MI, MIB);
535
537
const unsigned Opc = MI.getOpcode ();
536
538
@@ -569,17 +571,8 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
569
571
return true ;
570
572
}
571
573
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 ;
583
576
584
577
if (selectImpl (MI, *CoverageInfo))
585
578
return true ;
@@ -813,8 +806,19 @@ void RISCVInstructionSelector::preISelLower(MachineInstr &MI,
813
806
replacePtrWithInt (MI.getOperand (1 ), MIB);
814
807
MI.setDesc (TII.get (TargetOpcode::G_AND));
815
808
MRI->setType (DstReg, sXLen );
816
- break ;
817
809
}
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 ;
818
822
case TargetOpcode::G_SPLAT_VECTOR: {
819
823
// Convert integer SPLAT_VECTOR to VMV_V_X_VL and floating-point
820
824
// SPLAT_VECTOR to VFMV_V_F_VL to reduce isel burden.
@@ -825,23 +829,27 @@ void RISCVInstructionSelector::preISelLower(MachineInstr &MI,
825
829
sXLen .getSizeInBits ()))
826
830
Scalar = MIB.buildAnyExt (sXLen , Scalar).getReg (0 );
827
831
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.
830
839
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 );
833
840
LLT VecTy = MRI->getType (MI.getOperand (0 ).getReg ());
834
841
auto Passthru = MIB.buildUndef (VecTy);
835
842
auto VLMax = MIB.buildConstant (sXLen , -1 );
836
843
MRI->setRegBank (Passthru.getReg (0 ), RBI.getRegBank (RISCV::VRBRegBankID));
837
844
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) ;
843
850
}
844
851
}
852
+ return false ;
845
853
}
846
854
847
855
void RISCVInstructionSelector::renderNegImm (MachineInstrBuilder &MIB,
0 commit comments