@@ -666,6 +666,7 @@ SDValue LoongArchTargetLowering::lowerVECREDUCE_ADD(SDValue Op,
666666
667667 unsigned NumEles = Val.getSimpleValueType ().getVectorNumElements ();
668668 unsigned EleBits = Val.getSimpleValueType ().getScalarSizeInBits ();
669+ unsigned ResBits = OpVT.getScalarSizeInBits ();
669670
670671 unsigned LegalVecSize = 128 ;
671672 bool isLASX256Vector =
@@ -691,10 +692,11 @@ SDValue LoongArchTargetLowering::lowerVECREDUCE_ADD(SDValue Op,
691692
692693 if (isLASX256Vector) {
693694 SDValue Tmp = DAG.getNode (LoongArchISD::XVPERMI, DL, MVT::v4i64, Val,
694- DAG.getConstant (2 , DL, MVT:: i64 ));
695+ DAG.getConstant (2 , DL, Subtarget. getGRLenVT () ));
695696 Val = DAG.getNode (ISD::ADD, DL, MVT::v4i64, Tmp, Val);
696697 }
697698
699+ Val = DAG.getBitcast (MVT::getVectorVT (OpVT, LegalVecSize / ResBits), Val);
698700 return DAG.getNode (ISD::EXTRACT_VECTOR_ELT, DL, OpVT, Val,
699701 DAG.getConstant (0 , DL, Subtarget.getGRLenVT ()));
700702}
@@ -727,15 +729,16 @@ SDValue LoongArchTargetLowering::lowerVECREDUCE(SDValue Op,
727729
728730 unsigned Opcode = ISD::getVecReduceBaseOpcode (Op.getOpcode ());
729731 MVT VecTy = Val.getSimpleValueType ();
732+ MVT GRLenVT = Subtarget.getGRLenVT ();
730733
731734 for (int i = NumEles; i > 1 ; i /= 2 ) {
732- SDValue ShiftAmt = DAG.getConstant (i * EleBits / 16 , DL, MVT:: i64 );
735+ SDValue ShiftAmt = DAG.getConstant (i * EleBits / 16 , DL, GRLenVT );
733736 SDValue Tmp = DAG.getNode (LoongArchISD::VBSRL, DL, VecTy, Val, ShiftAmt);
734737 Val = DAG.getNode (Opcode, DL, VecTy, Tmp, Val);
735738 }
736739
737740 return DAG.getNode (ISD::EXTRACT_VECTOR_ELT, DL, OpVT, Val,
738- DAG.getConstant (0 , DL, Subtarget. getGRLenVT () ));
741+ DAG.getConstant (0 , DL, GRLenVT ));
739742}
740743
741744SDValue LoongArchTargetLowering::lowerPREFETCH (SDValue Op,
@@ -1119,6 +1122,10 @@ SDValue LoongArchTargetLowering::lowerBITREVERSE(SDValue Op,
11191122 SDValue Src = Op->getOperand (0 );
11201123 SDLoc DL (Op);
11211124
1125+ // LoongArchISD::BITREV_8B is not supported on LA32.
1126+ if (!Subtarget.is64Bit () && (ResTy == MVT::v16i8 || ResTy == MVT::v32i8))
1127+ return SDValue ();
1128+
11221129 EVT NewVT = ResTy.is128BitVector () ? MVT::v2i64 : MVT::v4i64;
11231130 unsigned int OrigEltNum = ResTy.getVectorNumElements ();
11241131 unsigned int NewEltNum = NewVT.getVectorNumElements ();
@@ -1128,7 +1135,7 @@ SDValue LoongArchTargetLowering::lowerBITREVERSE(SDValue Op,
11281135 SmallVector<SDValue, 8 > Ops;
11291136 for (unsigned int i = 0 ; i < NewEltNum; i++) {
11301137 SDValue Op = DAG.getNode (ISD::EXTRACT_VECTOR_ELT, DL, MVT::i64 , NewSrc,
1131- DAG.getConstant (i, DL, MVT:: i64 ));
1138+ DAG.getConstant (i, DL, Subtarget. getGRLenVT () ));
11321139 unsigned RevOp = (ResTy == MVT::v16i8 || ResTy == MVT::v32i8)
11331140 ? (unsigned )LoongArchISD::BITREV_8B
11341141 : (unsigned )ISD::BITREVERSE;
@@ -1611,9 +1618,8 @@ lowerVECTOR_SHUFFLE_VREPLVEI(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
16111618
16121619 assert (SplatIndex < (int )Mask.size () && " Out of bounds mask index" );
16131620 if (fitsRegularPattern<int >(Mask.begin (), 1 , Mask.end (), SplatIndex, 0 )) {
1614- APInt Imm (64 , SplatIndex);
16151621 return DAG.getNode (LoongArchISD::VREPLVEI, DL, VT, V1,
1616- DAG.getConstant (Imm , DL, Subtarget.getGRLenVT ()));
1622+ DAG.getConstant (SplatIndex , DL, Subtarget.getGRLenVT ()));
16171623 }
16181624
16191625 return SDValue ();
@@ -1671,7 +1677,7 @@ lowerVECTOR_SHUFFLE_VSHUF4I(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
16711677 }
16721678
16731679 // Calculate the immediate. Replace any remaining undefs with zero
1674- APInt Imm ( 64 , 0 ) ;
1680+ int Imm = 0 ;
16751681 for (int i = SubVecSize - 1 ; i >= 0 ; --i) {
16761682 int M = SubMask[i];
16771683
@@ -1946,11 +1952,12 @@ static SDValue lowerVECTOR_SHUFFLE_VPICKOD(const SDLoc &DL, ArrayRef<int> Mask,
19461952// / adding it as an operand to the resulting VSHUF.
19471953static SDValue lowerVECTOR_SHUFFLE_VSHUF (const SDLoc &DL, ArrayRef<int > Mask,
19481954 MVT VT, SDValue V1, SDValue V2,
1949- SelectionDAG &DAG) {
1955+ SelectionDAG &DAG,
1956+ const LoongArchSubtarget &Subtarget) {
19501957
19511958 SmallVector<SDValue, 16 > Ops;
19521959 for (auto M : Mask)
1953- Ops.push_back (DAG.getConstant (M, DL, MVT:: i64 ));
1960+ Ops.push_back (DAG.getSignedConstant (M, DL, Subtarget. getGRLenVT () ));
19541961
19551962 EVT MaskVecTy = VT.changeVectorElementTypeToInteger ();
19561963 SDValue MaskVec = DAG.getBuildVector (MaskVecTy, DL, Ops);
@@ -2030,7 +2037,8 @@ static SDValue lower128BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
20302037 return Result;
20312038 if (SDValue NewShuffle = widenShuffleMask (DL, Mask, VT, V1, V2, DAG))
20322039 return NewShuffle;
2033- if ((Result = lowerVECTOR_SHUFFLE_VSHUF (DL, Mask, VT, V1, V2, DAG)))
2040+ if ((Result =
2041+ lowerVECTOR_SHUFFLE_VSHUF (DL, Mask, VT, V1, V2, DAG, Subtarget)))
20342042 return Result;
20352043 return SDValue ();
20362044}
@@ -2088,7 +2096,8 @@ lowerVECTOR_SHUFFLE_XVSHUF4I(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
20882096// / Lower VECTOR_SHUFFLE into XVPERM (if possible).
20892097static SDValue lowerVECTOR_SHUFFLE_XVPERM (const SDLoc &DL, ArrayRef<int > Mask,
20902098 MVT VT, SDValue V1, SDValue V2,
2091- SelectionDAG &DAG) {
2099+ SelectionDAG &DAG,
2100+ const LoongArchSubtarget &Subtarget) {
20922101 // LoongArch LASX only have XVPERM_W.
20932102 if (Mask.size () != 8 || (VT != MVT::v8i32 && VT != MVT::v8f32))
20942103 return SDValue ();
@@ -2119,9 +2128,10 @@ static SDValue lowerVECTOR_SHUFFLE_XVPERM(const SDLoc &DL, ArrayRef<int> Mask,
21192128 return SDValue ();
21202129
21212130 SmallVector<SDValue, 8 > Masks;
2131+ MVT GRLenVT = Subtarget.getGRLenVT ();
21222132 for (unsigned i = 0 ; i < NumElts; ++i)
2123- Masks.push_back (Mask[i] == -1 ? DAG.getUNDEF (MVT:: i64 )
2124- : DAG.getConstant (Mask[i], DL, MVT:: i64 ));
2133+ Masks.push_back (Mask[i] == -1 ? DAG.getUNDEF (GRLenVT )
2134+ : DAG.getConstant (Mask[i], DL, GRLenVT ));
21252135 SDValue MaskVec = DAG.getBuildVector (MVT::v8i32, DL, Masks);
21262136
21272137 return DAG.getNode (LoongArchISD::XVPERM, DL, VT, V1, MaskVec);
@@ -2533,7 +2543,8 @@ static SDValue lower256BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
25332543 if ((Result = lowerVECTOR_SHUFFLE_XVSHUF4I (DL, NewMask, VT, V1, V2, DAG,
25342544 Subtarget)))
25352545 return Result;
2536- if ((Result = lowerVECTOR_SHUFFLE_XVPERM (DL, NewMask, VT, V1, V2, DAG)))
2546+ if ((Result = lowerVECTOR_SHUFFLE_XVPERM (DL, NewMask, VT, V1, V2, DAG,
2547+ Subtarget)))
25372548 return Result;
25382549 if ((Result = lowerVECTOR_SHUFFLEAsLanePermuteAndShuffle (DL, NewMask, VT,
25392550 V1, V2, DAG)))
@@ -3102,12 +3113,33 @@ LoongArchTargetLowering::lowerINSERT_VECTOR_ELT(SDValue Op,
31023113 return SDValue ();
31033114
31043115 SDValue SplatElt = DAG.getSplatBuildVector (VT, DL, Op1);
3105- SDValue SplatIdx = DAG.getSplatBuildVector (IdxVTy, DL, Op2);
3106-
31073116 SmallVector<SDValue, 32 > RawIndices;
3108- for (unsigned i = 0 ; i < NumElts; ++i)
3109- RawIndices.push_back (DAG.getConstant (i, DL, Subtarget.getGRLenVT ()));
3110- SDValue Indices = DAG.getBuildVector (IdxVTy, DL, RawIndices);
3117+ SDValue SplatIdx;
3118+ SDValue Indices;
3119+
3120+ if (!Subtarget.is64Bit () && IdxTy == MVT::i64 ) {
3121+ MVT PairVTy = MVT::getVectorVT (MVT::i32 , NumElts * 2 );
3122+ for (unsigned i = 0 ; i < NumElts; ++i) {
3123+ RawIndices.push_back (Op2);
3124+ RawIndices.push_back (DAG.getConstant (0 , DL, MVT::i32 ));
3125+ }
3126+ SplatIdx = DAG.getBuildVector (PairVTy, DL, RawIndices);
3127+ SplatIdx = DAG.getBitcast (IdxVTy, SplatIdx);
3128+
3129+ RawIndices.clear ();
3130+ for (unsigned i = 0 ; i < NumElts; ++i) {
3131+ RawIndices.push_back (DAG.getConstant (i, DL, MVT::i32 ));
3132+ RawIndices.push_back (DAG.getConstant (0 , DL, MVT::i32 ));
3133+ }
3134+ Indices = DAG.getBuildVector (PairVTy, DL, RawIndices);
3135+ Indices = DAG.getBitcast (IdxVTy, Indices);
3136+ } else {
3137+ SplatIdx = DAG.getSplatBuildVector (IdxVTy, DL, Op2);
3138+
3139+ for (unsigned i = 0 ; i < NumElts; ++i)
3140+ RawIndices.push_back (DAG.getConstant (i, DL, Subtarget.getGRLenVT ()));
3141+ Indices = DAG.getBuildVector (IdxVTy, DL, RawIndices);
3142+ }
31113143
31123144 // insert vec, elt, idx
31133145 // =>
@@ -5129,7 +5161,7 @@ performSETCC_BITCASTCombine(SDNode *N, SelectionDAG &DAG,
51295161 if (Opc == ISD::DELETED_NODE)
51305162 return SDValue ();
51315163
5132- SDValue V = DAG.getNode (Opc, DL, MVT:: i64 , Src.getOperand (0 ));
5164+ SDValue V = DAG.getNode (Opc, DL, Subtarget. getGRLenVT () , Src.getOperand (0 ));
51335165 EVT T = EVT::getIntegerVT (*DAG.getContext (), SrcVT.getVectorNumElements ());
51345166 V = DAG.getZExtOrTrunc (V, DL, T);
51355167 return DAG.getBitcast (VT, V);
@@ -5142,6 +5174,7 @@ static SDValue performBITCASTCombine(SDNode *N, SelectionDAG &DAG,
51425174 EVT VT = N->getValueType (0 );
51435175 SDValue Src = N->getOperand (0 );
51445176 EVT SrcVT = Src.getValueType ();
5177+ MVT GRLenVT = Subtarget.getGRLenVT ();
51455178
51465179 if (!DCI.isBeforeLegalizeOps ())
51475180 return SDValue ();
@@ -5209,19 +5242,19 @@ static SDValue performBITCASTCombine(SDNode *N, SelectionDAG &DAG,
52095242 if (Src.getSimpleValueType () == MVT::v32i8) {
52105243 SDValue Lo, Hi;
52115244 std::tie (Lo, Hi) = DAG.SplitVector (Src, DL);
5212- Lo = DAG.getNode (LoongArchISD::VMSKLTZ, DL, MVT:: i64 , Lo);
5213- Hi = DAG.getNode (LoongArchISD::VMSKLTZ, DL, MVT:: i64 , Hi);
5214- Hi = DAG.getNode (ISD::SHL, DL, MVT:: i64 , Hi,
5245+ Lo = DAG.getNode (LoongArchISD::VMSKLTZ, DL, GRLenVT , Lo);
5246+ Hi = DAG.getNode (LoongArchISD::VMSKLTZ, DL, GRLenVT , Hi);
5247+ Hi = DAG.getNode (ISD::SHL, DL, GRLenVT , Hi,
52155248 DAG.getConstant (16 , DL, MVT::i8 ));
5216- V = DAG.getNode (ISD::OR, DL, MVT:: i64 , Lo, Hi);
5249+ V = DAG.getNode (ISD::OR, DL, GRLenVT , Lo, Hi);
52175250 } else if (UseLASX) {
52185251 return SDValue ();
52195252 }
52205253 }
52215254
52225255 if (!V) {
52235256 Opc = UseLASX ? LoongArchISD::XVMSKLTZ : LoongArchISD::VMSKLTZ;
5224- V = DAG.getNode (Opc, DL, MVT:: i64 , Src);
5257+ V = DAG.getNode (Opc, DL, GRLenVT , Src);
52255258 }
52265259
52275260 EVT T = EVT::getIntegerVT (*DAG.getContext (), SrcVT.getVectorNumElements ());
@@ -5878,6 +5911,22 @@ static SDValue lowerVectorBitRevImm(SDNode *Node, SelectionDAG &DAG) {
58785911 return DAG.getNode (ISD::XOR, DL, ResTy, Node->getOperand (1 ), BitImm);
58795912}
58805913
5914+ template <unsigned W>
5915+ static SDValue lowerVectorPickVE2GR (SDNode *N, SelectionDAG &DAG,
5916+ unsigned ResOp) {
5917+ unsigned Imm = N->getConstantOperandVal (2 );
5918+ if (!isUInt<W>(Imm)) {
5919+ const StringRef ErrorMsg = " argument out of range" ;
5920+ DAG.getContext ()->emitError (N->getOperationName (0 ) + " : " + ErrorMsg + " ." );
5921+ return DAG.getUNDEF (N->getValueType (0 ));
5922+ }
5923+ SDLoc DL (N);
5924+ SDValue Vec = N->getOperand (1 );
5925+ SDValue Idx = DAG.getConstant (Imm, DL, MVT::i32 );
5926+ SDValue EltVT = DAG.getValueType (Vec.getValueType ().getVectorElementType ());
5927+ return DAG.getNode (ResOp, DL, N->getValueType (0 ), Vec, Idx, EltVT);
5928+ }
5929+
58815930static SDValue
58825931performINTRINSIC_WO_CHAINCombine (SDNode *N, SelectionDAG &DAG,
58835932 TargetLowering::DAGCombinerInfo &DCI,
@@ -6367,6 +6416,68 @@ performINTRINSIC_WO_CHAINCombine(SDNode *N, SelectionDAG &DAG,
63676416 N->getOperand (1 ),
63686417 DAG.getNode (ISD::ANY_EXTEND, DL, Subtarget.getGRLenVT (),
63696418 N->getOperand (2 )));
6419+ case Intrinsic::loongarch_lsx_vpickve2gr_b:
6420+ if (!Subtarget.is64Bit ())
6421+ return lowerVectorPickVE2GR<4 >(N, DAG, LoongArchISD::VPICK_SEXT_ELT);
6422+ break ;
6423+ case Intrinsic::loongarch_lsx_vpickve2gr_h:
6424+ case Intrinsic::loongarch_lasx_xvpickve2gr_w:
6425+ if (!Subtarget.is64Bit ())
6426+ return lowerVectorPickVE2GR<3 >(N, DAG, LoongArchISD::VPICK_SEXT_ELT);
6427+ break ;
6428+ case Intrinsic::loongarch_lsx_vpickve2gr_w:
6429+ if (!Subtarget.is64Bit ())
6430+ return lowerVectorPickVE2GR<2 >(N, DAG, LoongArchISD::VPICK_SEXT_ELT);
6431+ break ;
6432+ case Intrinsic::loongarch_lsx_vpickve2gr_bu:
6433+ if (!Subtarget.is64Bit ())
6434+ return lowerVectorPickVE2GR<4 >(N, DAG, LoongArchISD::VPICK_ZEXT_ELT);
6435+ break ;
6436+ case Intrinsic::loongarch_lsx_vpickve2gr_hu:
6437+ case Intrinsic::loongarch_lasx_xvpickve2gr_wu:
6438+ if (!Subtarget.is64Bit ())
6439+ return lowerVectorPickVE2GR<3 >(N, DAG, LoongArchISD::VPICK_ZEXT_ELT);
6440+ break ;
6441+ case Intrinsic::loongarch_lsx_vpickve2gr_wu:
6442+ if (!Subtarget.is64Bit ())
6443+ return lowerVectorPickVE2GR<2 >(N, DAG, LoongArchISD::VPICK_ZEXT_ELT);
6444+ break ;
6445+ case Intrinsic::loongarch_lsx_bz_b:
6446+ case Intrinsic::loongarch_lsx_bz_h:
6447+ case Intrinsic::loongarch_lsx_bz_w:
6448+ case Intrinsic::loongarch_lsx_bz_d:
6449+ case Intrinsic::loongarch_lasx_xbz_b:
6450+ case Intrinsic::loongarch_lasx_xbz_h:
6451+ case Intrinsic::loongarch_lasx_xbz_w:
6452+ case Intrinsic::loongarch_lasx_xbz_d:
6453+ if (!Subtarget.is64Bit ())
6454+ return DAG.getNode (LoongArchISD::VALL_ZERO, DL, N->getValueType (0 ),
6455+ N->getOperand (1 ));
6456+ break ;
6457+ case Intrinsic::loongarch_lsx_bz_v:
6458+ case Intrinsic::loongarch_lasx_xbz_v:
6459+ if (!Subtarget.is64Bit ())
6460+ return DAG.getNode (LoongArchISD::VANY_ZERO, DL, N->getValueType (0 ),
6461+ N->getOperand (1 ));
6462+ break ;
6463+ case Intrinsic::loongarch_lsx_bnz_b:
6464+ case Intrinsic::loongarch_lsx_bnz_h:
6465+ case Intrinsic::loongarch_lsx_bnz_w:
6466+ case Intrinsic::loongarch_lsx_bnz_d:
6467+ case Intrinsic::loongarch_lasx_xbnz_b:
6468+ case Intrinsic::loongarch_lasx_xbnz_h:
6469+ case Intrinsic::loongarch_lasx_xbnz_w:
6470+ case Intrinsic::loongarch_lasx_xbnz_d:
6471+ if (!Subtarget.is64Bit ())
6472+ return DAG.getNode (LoongArchISD::VALL_NONZERO, DL, N->getValueType (0 ),
6473+ N->getOperand (1 ));
6474+ break ;
6475+ case Intrinsic::loongarch_lsx_bnz_v:
6476+ case Intrinsic::loongarch_lasx_xbnz_v:
6477+ if (!Subtarget.is64Bit ())
6478+ return DAG.getNode (LoongArchISD::VANY_NONZERO, DL, N->getValueType (0 ),
6479+ N->getOperand (1 ));
6480+ break ;
63706481 }
63716482 return SDValue ();
63726483}
0 commit comments