@@ -666,6 +666,7 @@ SDValue LoongArchTargetLowering::lowerVECREDUCE_ADD(SDValue Op,
666
666
667
667
unsigned NumEles = Val.getSimpleValueType ().getVectorNumElements ();
668
668
unsigned EleBits = Val.getSimpleValueType ().getScalarSizeInBits ();
669
+ unsigned ResBits = OpVT.getScalarSizeInBits ();
669
670
670
671
unsigned LegalVecSize = 128 ;
671
672
bool isLASX256Vector =
@@ -691,10 +692,11 @@ SDValue LoongArchTargetLowering::lowerVECREDUCE_ADD(SDValue Op,
691
692
692
693
if (isLASX256Vector) {
693
694
SDValue Tmp = DAG.getNode (LoongArchISD::XVPERMI, DL, MVT::v4i64, Val,
694
- DAG.getConstant (2 , DL, MVT:: i64 ));
695
+ DAG.getConstant (2 , DL, Subtarget. getGRLenVT () ));
695
696
Val = DAG.getNode (ISD::ADD, DL, MVT::v4i64, Tmp, Val);
696
697
}
697
698
699
+ Val = DAG.getBitcast (MVT::getVectorVT (OpVT, LegalVecSize / ResBits), Val);
698
700
return DAG.getNode (ISD::EXTRACT_VECTOR_ELT, DL, OpVT, Val,
699
701
DAG.getConstant (0 , DL, Subtarget.getGRLenVT ()));
700
702
}
@@ -727,15 +729,16 @@ SDValue LoongArchTargetLowering::lowerVECREDUCE(SDValue Op,
727
729
728
730
unsigned Opcode = ISD::getVecReduceBaseOpcode (Op.getOpcode ());
729
731
MVT VecTy = Val.getSimpleValueType ();
732
+ MVT GRLenVT = Subtarget.getGRLenVT ();
730
733
731
734
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 );
733
736
SDValue Tmp = DAG.getNode (LoongArchISD::VBSRL, DL, VecTy, Val, ShiftAmt);
734
737
Val = DAG.getNode (Opcode, DL, VecTy, Tmp, Val);
735
738
}
736
739
737
740
return DAG.getNode (ISD::EXTRACT_VECTOR_ELT, DL, OpVT, Val,
738
- DAG.getConstant (0 , DL, Subtarget. getGRLenVT () ));
741
+ DAG.getConstant (0 , DL, GRLenVT ));
739
742
}
740
743
741
744
SDValue LoongArchTargetLowering::lowerPREFETCH (SDValue Op,
@@ -1119,6 +1122,10 @@ SDValue LoongArchTargetLowering::lowerBITREVERSE(SDValue Op,
1119
1122
SDValue Src = Op->getOperand (0 );
1120
1123
SDLoc DL (Op);
1121
1124
1125
+ // LoongArchISD::BITREV_8B is not supported on LA32.
1126
+ if (!Subtarget.is64Bit () && (ResTy == MVT::v16i8 || ResTy == MVT::v32i8))
1127
+ return SDValue ();
1128
+
1122
1129
EVT NewVT = ResTy.is128BitVector () ? MVT::v2i64 : MVT::v4i64;
1123
1130
unsigned int OrigEltNum = ResTy.getVectorNumElements ();
1124
1131
unsigned int NewEltNum = NewVT.getVectorNumElements ();
@@ -1128,7 +1135,7 @@ SDValue LoongArchTargetLowering::lowerBITREVERSE(SDValue Op,
1128
1135
SmallVector<SDValue, 8 > Ops;
1129
1136
for (unsigned int i = 0 ; i < NewEltNum; i++) {
1130
1137
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 () ));
1132
1139
unsigned RevOp = (ResTy == MVT::v16i8 || ResTy == MVT::v32i8)
1133
1140
? (unsigned )LoongArchISD::BITREV_8B
1134
1141
: (unsigned )ISD::BITREVERSE;
@@ -1611,9 +1618,8 @@ lowerVECTOR_SHUFFLE_VREPLVEI(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
1611
1618
1612
1619
assert (SplatIndex < (int )Mask.size () && " Out of bounds mask index" );
1613
1620
if (fitsRegularPattern<int >(Mask.begin (), 1 , Mask.end (), SplatIndex, 0 )) {
1614
- APInt Imm (64 , SplatIndex);
1615
1621
return DAG.getNode (LoongArchISD::VREPLVEI, DL, VT, V1,
1616
- DAG.getConstant (Imm , DL, Subtarget.getGRLenVT ()));
1622
+ DAG.getConstant (SplatIndex , DL, Subtarget.getGRLenVT ()));
1617
1623
}
1618
1624
1619
1625
return SDValue ();
@@ -1671,7 +1677,7 @@ lowerVECTOR_SHUFFLE_VSHUF4I(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
1671
1677
}
1672
1678
1673
1679
// Calculate the immediate. Replace any remaining undefs with zero
1674
- APInt Imm ( 64 , 0 ) ;
1680
+ int Imm = 0 ;
1675
1681
for (int i = SubVecSize - 1 ; i >= 0 ; --i) {
1676
1682
int M = SubMask[i];
1677
1683
@@ -1946,11 +1952,12 @@ static SDValue lowerVECTOR_SHUFFLE_VPICKOD(const SDLoc &DL, ArrayRef<int> Mask,
1946
1952
// / adding it as an operand to the resulting VSHUF.
1947
1953
static SDValue lowerVECTOR_SHUFFLE_VSHUF (const SDLoc &DL, ArrayRef<int > Mask,
1948
1954
MVT VT, SDValue V1, SDValue V2,
1949
- SelectionDAG &DAG) {
1955
+ SelectionDAG &DAG,
1956
+ const LoongArchSubtarget &Subtarget) {
1950
1957
1951
1958
SmallVector<SDValue, 16 > Ops;
1952
1959
for (auto M : Mask)
1953
- Ops.push_back (DAG.getConstant (M, DL, MVT:: i64 ));
1960
+ Ops.push_back (DAG.getSignedConstant (M, DL, Subtarget. getGRLenVT () ));
1954
1961
1955
1962
EVT MaskVecTy = VT.changeVectorElementTypeToInteger ();
1956
1963
SDValue MaskVec = DAG.getBuildVector (MaskVecTy, DL, Ops);
@@ -2030,7 +2037,8 @@ static SDValue lower128BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
2030
2037
return Result;
2031
2038
if (SDValue NewShuffle = widenShuffleMask (DL, Mask, VT, V1, V2, DAG))
2032
2039
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)))
2034
2042
return Result;
2035
2043
return SDValue ();
2036
2044
}
@@ -2088,7 +2096,8 @@ lowerVECTOR_SHUFFLE_XVSHUF4I(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
2088
2096
// / Lower VECTOR_SHUFFLE into XVPERM (if possible).
2089
2097
static SDValue lowerVECTOR_SHUFFLE_XVPERM (const SDLoc &DL, ArrayRef<int > Mask,
2090
2098
MVT VT, SDValue V1, SDValue V2,
2091
- SelectionDAG &DAG) {
2099
+ SelectionDAG &DAG,
2100
+ const LoongArchSubtarget &Subtarget) {
2092
2101
// LoongArch LASX only have XVPERM_W.
2093
2102
if (Mask.size () != 8 || (VT != MVT::v8i32 && VT != MVT::v8f32))
2094
2103
return SDValue ();
@@ -2119,9 +2128,10 @@ static SDValue lowerVECTOR_SHUFFLE_XVPERM(const SDLoc &DL, ArrayRef<int> Mask,
2119
2128
return SDValue ();
2120
2129
2121
2130
SmallVector<SDValue, 8 > Masks;
2131
+ MVT GRLenVT = Subtarget.getGRLenVT ();
2122
2132
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 ));
2125
2135
SDValue MaskVec = DAG.getBuildVector (MVT::v8i32, DL, Masks);
2126
2136
2127
2137
return DAG.getNode (LoongArchISD::XVPERM, DL, VT, V1, MaskVec);
@@ -2533,7 +2543,8 @@ static SDValue lower256BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
2533
2543
if ((Result = lowerVECTOR_SHUFFLE_XVSHUF4I (DL, NewMask, VT, V1, V2, DAG,
2534
2544
Subtarget)))
2535
2545
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)))
2537
2548
return Result;
2538
2549
if ((Result = lowerVECTOR_SHUFFLEAsLanePermuteAndShuffle (DL, NewMask, VT,
2539
2550
V1, V2, DAG)))
@@ -3102,12 +3113,33 @@ LoongArchTargetLowering::lowerINSERT_VECTOR_ELT(SDValue Op,
3102
3113
return SDValue ();
3103
3114
3104
3115
SDValue SplatElt = DAG.getSplatBuildVector (VT, DL, Op1);
3105
- SDValue SplatIdx = DAG.getSplatBuildVector (IdxVTy, DL, Op2);
3106
-
3107
3116
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
+ }
3111
3143
3112
3144
// insert vec, elt, idx
3113
3145
// =>
@@ -5129,7 +5161,7 @@ performSETCC_BITCASTCombine(SDNode *N, SelectionDAG &DAG,
5129
5161
if (Opc == ISD::DELETED_NODE)
5130
5162
return SDValue ();
5131
5163
5132
- SDValue V = DAG.getNode (Opc, DL, MVT:: i64 , Src.getOperand (0 ));
5164
+ SDValue V = DAG.getNode (Opc, DL, Subtarget. getGRLenVT () , Src.getOperand (0 ));
5133
5165
EVT T = EVT::getIntegerVT (*DAG.getContext (), SrcVT.getVectorNumElements ());
5134
5166
V = DAG.getZExtOrTrunc (V, DL, T);
5135
5167
return DAG.getBitcast (VT, V);
@@ -5142,6 +5174,7 @@ static SDValue performBITCASTCombine(SDNode *N, SelectionDAG &DAG,
5142
5174
EVT VT = N->getValueType (0 );
5143
5175
SDValue Src = N->getOperand (0 );
5144
5176
EVT SrcVT = Src.getValueType ();
5177
+ MVT GRLenVT = Subtarget.getGRLenVT ();
5145
5178
5146
5179
if (!DCI.isBeforeLegalizeOps ())
5147
5180
return SDValue ();
@@ -5209,19 +5242,19 @@ static SDValue performBITCASTCombine(SDNode *N, SelectionDAG &DAG,
5209
5242
if (Src.getSimpleValueType () == MVT::v32i8) {
5210
5243
SDValue Lo, Hi;
5211
5244
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,
5215
5248
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);
5217
5250
} else if (UseLASX) {
5218
5251
return SDValue ();
5219
5252
}
5220
5253
}
5221
5254
5222
5255
if (!V) {
5223
5256
Opc = UseLASX ? LoongArchISD::XVMSKLTZ : LoongArchISD::VMSKLTZ;
5224
- V = DAG.getNode (Opc, DL, MVT:: i64 , Src);
5257
+ V = DAG.getNode (Opc, DL, GRLenVT , Src);
5225
5258
}
5226
5259
5227
5260
EVT T = EVT::getIntegerVT (*DAG.getContext (), SrcVT.getVectorNumElements ());
@@ -5878,6 +5911,22 @@ static SDValue lowerVectorBitRevImm(SDNode *Node, SelectionDAG &DAG) {
5878
5911
return DAG.getNode (ISD::XOR, DL, ResTy, Node->getOperand (1 ), BitImm);
5879
5912
}
5880
5913
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
+
5881
5930
static SDValue
5882
5931
performINTRINSIC_WO_CHAINCombine (SDNode *N, SelectionDAG &DAG,
5883
5932
TargetLowering::DAGCombinerInfo &DCI,
@@ -6367,6 +6416,68 @@ performINTRINSIC_WO_CHAINCombine(SDNode *N, SelectionDAG &DAG,
6367
6416
N->getOperand (1 ),
6368
6417
DAG.getNode (ISD::ANY_EXTEND, DL, Subtarget.getGRLenVT (),
6369
6418
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 ;
6370
6481
}
6371
6482
return SDValue ();
6372
6483
}
0 commit comments