@@ -2319,25 +2319,6 @@ 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-
23412322// / Lower VECTOR_SHUFFLE into XVINSVE0 (if possible).
23422323static SDValue
23432324lowerVECTOR_SHUFFLE_XVINSVE0 (const SDLoc &DL, ArrayRef<int > Mask, MVT VT,
@@ -2348,21 +2329,49 @@ lowerVECTOR_SHUFFLE_XVINSVE0(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
23482329 VT != MVT::v4f64)
23492330 return SDValue ();
23502331
2351- MVT GRLenVT = Subtarget.getGRLenVT ();
23522332 int MaskSize = Mask.size ();
23532333 assert (MaskSize == (int )VT.getVectorNumElements () && " Unexpected mask size" );
23542334
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));
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+ };
23602370
2361- // Case 2: the lowest element of V1 replaces one element in V2.
2362- Idx = checkReplaceOne (Mask, MaskSize, 0 );
2371+ auto [Src, Ins, Idx] = DetectReplaced (Mask, V1, V2);
23632372 if (Idx != -1 )
2364- return DAG.getNode (LoongArchISD::XVINSVE0, DL, VT, V2, V1 ,
2365- DAG.getConstant (Idx, DL, GRLenVT ));
2373+ return DAG.getNode (LoongArchISD::XVINSVE0, DL, VT, Src, Ins ,
2374+ DAG.getConstant (Idx, DL, Subtarget. getGRLenVT () ));
23662375
23672376 return SDValue ();
23682377}
0 commit comments