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