@@ -2319,6 +2319,25 @@ static SDValue lowerVECTOR_SHUFFLE_XVPICKOD(const SDLoc &DL, ArrayRef<int> Mask,
23192319 return DAG.getNode (LoongArchISD::VPICKOD, DL, VT, V2, V1);
23202320}
23212321
2322+ // Check if exactly one element of the Mask is replaced by 'Replaced', while
2323+ // all other elements are either 'Base + i' or undef (-1). On success, return
2324+ // the index of the replaced element. Otherwise, just return -1.
2325+ static int checkReplaceOne (ArrayRef<int > Mask, int Base, int Replaced) {
2326+ int MaskSize = Mask.size ();
2327+ int Idx = -1 ;
2328+ for (int i = 0 ; i < MaskSize; ++i) {
2329+ if (Mask[i] == Base + i || Mask[i] == -1 )
2330+ continue ;
2331+ if (Mask[i] != Replaced)
2332+ return -1 ;
2333+ if (Idx == -1 )
2334+ Idx = i;
2335+ else
2336+ return -1 ;
2337+ }
2338+ return Idx;
2339+ }
2340+
23222341// / Lower VECTOR_SHUFFLE into XVINSVE0 (if possible).
23232342static SDValue
23242343lowerVECTOR_SHUFFLE_XVINSVE0 (const SDLoc &DL, ArrayRef<int > Mask, MVT VT,
@@ -2329,49 +2348,21 @@ lowerVECTOR_SHUFFLE_XVINSVE0(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
23292348 VT != MVT::v4f64)
23302349 return SDValue ();
23312350
2351+ MVT GRLenVT = Subtarget.getGRLenVT ();
23322352 int MaskSize = Mask.size ();
23332353 assert (MaskSize == (int )VT.getVectorNumElements () && " Unexpected mask size" );
23342354
2335- // Check if exactly one element of the Mask is replaced by the lowest element
2336- // of the other vector, while all other elements are either its index or
2337- // undef (-1). On success, return the index of the replaced element and the
2338- // two result vectors. Otherwise, just return -1 and empty.
2339- auto DetectReplaced = [&](ArrayRef<int > Mask, SDValue V1,
2340- SDValue V2) -> std::tuple<SDValue, SDValue, int > {
2341- int Idx1 = -1 , Idx2 = -1 ;
2342- bool Found1 = true , Found2 = true ;
2343-
2344- for (int i = 0 ; i < MaskSize; ++i) {
2345- int Cur = Mask[i];
2346- // Case 1: the lowest element of V2 replaces one element in V1.
2347- bool Match1 = (Cur == i || Cur == -1 || (Cur == MaskSize && Idx1 == -1 ));
2348- // Case 2: the lowest element of V1 replaces one element in V2.
2349- bool Match2 =
2350- (Cur == MaskSize + i || Cur == -1 || (Cur == 0 && Idx2 == -1 ));
2351-
2352- // Record the index of the replaced element.
2353- if (Match1 && Cur == MaskSize && Idx1 == -1 )
2354- Idx1 = i;
2355- if (Match2 && Cur == 0 && Idx2 == -1 )
2356- Idx2 = i;
2357-
2358- Found1 &= Match1;
2359- Found2 &= Match2;
2360- if (!Found1 && !Found2)
2361- return {SDValue (), SDValue (), -1 };
2362- }
2363-
2364- if (Found1 && Idx1 != -1 )
2365- return {V1, V2, Idx1};
2366- if (Found2 && Idx2 != -1 )
2367- return {V2, V1, Idx2};
2368- return {SDValue (), SDValue (), -1 };
2369- };
2355+ // Case 1: the lowest element of V2 replaces one element in V1.
2356+ int Idx = checkReplaceOne (Mask, 0 , MaskSize);
2357+ if (Idx != -1 )
2358+ return DAG.getNode (LoongArchISD::XVINSVE0, DL, VT, V1, V2,
2359+ DAG.getConstant (Idx, DL, GRLenVT));
23702360
2371- auto [Src, Ins, Idx] = DetectReplaced (Mask, V1, V2);
2361+ // Case 2: the lowest element of V1 replaces one element in V2.
2362+ Idx = checkReplaceOne (Mask, MaskSize, 0 );
23722363 if (Idx != -1 )
2373- return DAG.getNode (LoongArchISD::XVINSVE0, DL, VT, Src, Ins ,
2374- DAG.getConstant (Idx, DL, Subtarget. getGRLenVT () ));
2364+ return DAG.getNode (LoongArchISD::XVINSVE0, DL, VT, V2, V1 ,
2365+ DAG.getConstant (Idx, DL, GRLenVT ));
23752366
23762367 return SDValue ();
23772368}
0 commit comments