@@ -582,9 +582,9 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
582
582
SplatActions.clampScalar (1 , sXLen , sXLen );
583
583
584
584
getActionDefinitionsBuilder (G_INSERT_SUBVECTOR)
585
- .customIf (all (typeIsLegalBoolVec (0 , BoolVecTys, ST),
585
+ .legalIf (all (typeIsLegalBoolVec (0 , BoolVecTys, ST),
586
586
typeIsLegalBoolVec (1 , BoolVecTys, ST)))
587
- .customIf (all (typeIsLegalIntOrFPVec (0 , IntOrFPVecTys, ST),
587
+ .legalIf (all (typeIsLegalIntOrFPVec (0 , IntOrFPVecTys, ST),
588
588
typeIsLegalIntOrFPVec (1 , IntOrFPVecTys, ST)));
589
589
590
590
getLegacyLegalizerInfo ().computeTables ();
@@ -921,152 +921,6 @@ bool RISCVLegalizerInfo::legalizeSplatVector(MachineInstr &MI,
921
921
return true ;
922
922
}
923
923
924
- static LLT getLMUL1Ty (LLT VecTy) {
925
- assert (VecTy.getElementType ().getSizeInBits () <= 64 &&
926
- " Unexpected vector LLT" );
927
- return LLT::scalable_vector (RISCV::RVVBitsPerBlock /
928
- VecTy.getElementType ().getSizeInBits (),
929
- VecTy.getElementType ());
930
- }
931
-
932
- bool RISCVLegalizerInfo::legalizeInsertSubvector (MachineInstr &MI,
933
- MachineIRBuilder &MIB) const {
934
- GInsertSubvector &IS = cast<GInsertSubvector>(MI);
935
-
936
- MachineRegisterInfo &MRI = *MIB.getMRI ();
937
-
938
- Register Dst = IS.getReg (0 );
939
- Register Src1 = IS.getBigVec ();
940
- Register Src2 = IS.getSubVec ();
941
- uint64_t Idx = IS.getIndexImm ();
942
-
943
- LLT BigTy = MRI.getType (Src1);
944
- LLT LitTy = MRI.getType (Src2);
945
- Register BigVec = Src1;
946
- Register LitVec = Src2;
947
-
948
- // We don't have the ability to slide mask vectors up indexed by their i1
949
- // elements; the smallest we can do is i8. Often we are able to bitcast to
950
- // equivalent i8 vectors. Otherwise, we can must zeroextend to equivalent i8
951
- // vectors and truncate down after the insert.
952
- if (LitTy.getElementType () == LLT::scalar (1 ) &&
953
- (Idx != 0 ||
954
- MRI.getVRegDef (BigVec)->getOpcode () != TargetOpcode::G_IMPLICIT_DEF)) {
955
- auto BigTyMinElts = BigTy.getElementCount ().getKnownMinValue ();
956
- auto LitTyMinElts = LitTy.getElementCount ().getKnownMinValue ();
957
- if (BigTyMinElts >= 8 && LitTyMinElts >= 8 ) {
958
- assert (Idx % 8 == 0 && " Invalid index" );
959
- assert (BigTyMinElts % 8 == 0 && LitTyMinElts % 8 == 0 &&
960
- " Unexpected mask vector lowering" );
961
- Idx /= 8 ;
962
- BigTy = LLT::vector (BigTy.getElementCount ().divideCoefficientBy (8 ), 8 );
963
- LitTy = LLT::vector (LitTy.getElementCount ().divideCoefficientBy (8 ), 8 );
964
- BigVec = MIB.buildBitcast (BigTy, BigVec).getReg (0 );
965
- LitVec = MIB.buildBitcast (LitTy, LitVec).getReg (0 );
966
- } else {
967
- // We can't slide this mask vector up indexed by its i1 elements.
968
- // This poses a problem when we wish to insert a scalable vector which
969
- // can't be re-expressed as a larger type. Just choose the slow path and
970
- // extend to a larger type, then truncate back down.
971
- LLT ExtBigTy = BigTy.changeElementType (LLT::scalar (8 ));
972
- LLT ExtLitTy = LitTy.changeElementType (LLT::scalar (8 ));
973
- auto BigZExt = MIB.buildZExt (ExtBigTy, BigVec);
974
- auto LitZExt = MIB.buildZExt (ExtLitTy, LitVec);
975
- auto Insert = MIB.buildInsertSubvector (ExtBigTy, BigZExt, LitZExt, Idx);
976
- auto SplatZero = MIB.buildSplatVector (
977
- ExtBigTy, MIB.buildConstant (ExtBigTy.getElementType (), 0 ));
978
- MIB.buildICmp (CmpInst::Predicate::ICMP_NE, Dst, Insert, SplatZero);
979
- MI.eraseFromParent ();
980
- return true ;
981
- }
982
- }
983
-
984
- const RISCVRegisterInfo *TRI = STI.getRegisterInfo ();
985
- MVT LitTyMVT = getMVTForLLT (LitTy);
986
- unsigned SubRegIdx, RemIdx;
987
- std::tie (SubRegIdx, RemIdx) =
988
- RISCVTargetLowering::decomposeSubvectorInsertExtractToSubRegs (
989
- getMVTForLLT (BigTy), LitTyMVT, Idx, TRI);
990
-
991
- RISCVII::VLMUL SubVecLMUL = RISCVTargetLowering::getLMUL (getMVTForLLT (LitTy));
992
- bool IsSubVecPartReg = !RISCVVType::decodeVLMUL (SubVecLMUL).second ;
993
-
994
- // If the Idx has been completely eliminated and this subvector's size is a
995
- // vector register or a multiple thereof, or the surrounding elements are
996
- // undef, then this is a subvector insert which naturally aligns to a vector
997
- // register. These can easily be handled using subregister manipulation.
998
- if (RemIdx == 0 && (!IsSubVecPartReg || MRI.getVRegDef (Src1)->getOpcode () ==
999
- TargetOpcode::G_IMPLICIT_DEF))
1000
- return true ;
1001
-
1002
- // If the subvector is smaller than a vector register, then the insertion
1003
- // must preserve the undisturbed elements of the register. We do this by
1004
- // lowering to an EXTRACT_SUBVECTOR grabbing the nearest LMUL=1 vector type
1005
- // (which resolves to a subregister copy), performing a VSLIDEUP to place the
1006
- // subvector within the vector register, and an INSERT_SUBVECTOR of that
1007
- // LMUL=1 type back into the larger vector (resolving to another subregister
1008
- // operation). See below for how our VSLIDEUP works. We go via a LMUL=1 type
1009
- // to avoid allocating a large register group to hold our subvector.
1010
-
1011
- // VSLIDEUP works by leaving elements 0<i<OFFSET undisturbed, elements
1012
- // OFFSET<=i<VL set to the "subvector" and vl<=i<VLMAX set to the tail policy
1013
- // (in our case undisturbed). This means we can set up a subvector insertion
1014
- // where OFFSET is the insertion offset, and the VL is the OFFSET plus the
1015
- // size of the subvector.
1016
- const LLT XLenTy (STI.getXLenVT ());
1017
- LLT InterLitTy = BigTy;
1018
- Register AlignedExtract = Src1;
1019
- unsigned AlignedIdx = Idx - RemIdx;
1020
- if (TypeSize::isKnownGT (BigTy.getSizeInBits (),
1021
- getLMUL1Ty (BigTy).getSizeInBits ())) {
1022
- InterLitTy = getLMUL1Ty (BigTy);
1023
- // Extract a subvector equal to the nearest full vector register type. This
1024
- // should resolve to a G_EXTRACT on a subreg.
1025
- AlignedExtract =
1026
- MIB.buildExtractSubvector (InterLitTy, BigVec, AlignedIdx).getReg (0 );
1027
- }
1028
-
1029
- auto Insert = MIB.buildInsertSubvector (InterLitTy, MIB.buildUndef (InterLitTy),
1030
- LitVec, 0 );
1031
-
1032
- auto [Mask, _] = buildDefaultVLOps (BigTy, MIB, MRI);
1033
- auto VL = MIB.buildVScale (XLenTy, LitTy.getElementCount ().getKnownMinValue ());
1034
-
1035
- // Use tail agnostic policy if we're inserting over InterLitTy's tail.
1036
- ElementCount EndIndex =
1037
- ElementCount::getScalable (RemIdx) + LitTy.getElementCount ();
1038
- uint64_t Policy = RISCVII::TAIL_UNDISTURBED_MASK_UNDISTURBED;
1039
- if (EndIndex == InterLitTy.getElementCount ())
1040
- Policy = RISCVII::TAIL_AGNOSTIC;
1041
-
1042
- // If we're inserting into the lowest elements, use a tail undisturbed
1043
- // vmv.v.v.
1044
- MachineInstrBuilder Inserted;
1045
- if (RemIdx == 0 ) {
1046
- Inserted = MIB.buildInstr (RISCV::G_VMV_V_V_VL, {InterLitTy},
1047
- {AlignedExtract, Insert, VL});
1048
- } else {
1049
- auto SlideupAmt = MIB.buildVScale (XLenTy, RemIdx);
1050
- // Construct the vector length corresponding to RemIdx + length(LitTy).
1051
- VL = MIB.buildAdd (XLenTy, SlideupAmt, VL);
1052
- Inserted =
1053
- MIB.buildInstr (RISCV::G_VSLIDEUP_VL, {InterLitTy},
1054
- {AlignedExtract, LitVec, SlideupAmt, Mask, VL, Policy});
1055
- }
1056
-
1057
- // If required, insert this subvector back into the correct vector register.
1058
- // This should resolve to an INSERT_SUBREG instruction.
1059
- if (TypeSize::isKnownGT (BigTy.getSizeInBits (), InterLitTy.getSizeInBits ()))
1060
- Inserted = MIB.buildInsertSubvector (BigTy, BigVec, LitVec, AlignedIdx);
1061
-
1062
- // We might have bitcast from a mask type: cast back to the original type if
1063
- // required.
1064
- MIB.buildBitcast (Dst, Inserted);
1065
-
1066
- MI.eraseFromParent ();
1067
- return true ;
1068
- }
1069
-
1070
924
bool RISCVLegalizerInfo::legalizeCustom (
1071
925
LegalizerHelper &Helper, MachineInstr &MI,
1072
926
LostDebugLocObserver &LocObserver) const {
@@ -1137,8 +991,6 @@ bool RISCVLegalizerInfo::legalizeCustom(
1137
991
return legalizeExt (MI, MIRBuilder);
1138
992
case TargetOpcode::G_SPLAT_VECTOR:
1139
993
return legalizeSplatVector (MI, MIRBuilder);
1140
- case TargetOpcode::G_INSERT_SUBVECTOR:
1141
- return legalizeInsertSubvector (MI, MIRBuilder);
1142
994
case TargetOpcode::G_LOAD:
1143
995
case TargetOpcode::G_STORE:
1144
996
return legalizeLoadStore (MI, Helper, MIRBuilder);
0 commit comments