@@ -2319,6 +2319,54 @@ 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+
2341+ // / Lower VECTOR_SHUFFLE into XVINSVE0 (if possible).
2342+ static SDValue
2343+ lowerVECTOR_SHUFFLE_XVINSVE0 (const SDLoc &DL, ArrayRef<int > Mask, MVT VT,
2344+ SDValue V1, SDValue V2, SelectionDAG &DAG,
2345+ const LoongArchSubtarget &Subtarget) {
2346+ // LoongArch LASX only supports xvinsve0.{w/d}.
2347+ if (VT != MVT::v8i32 && VT != MVT::v8f32 && VT != MVT::v4i64 &&
2348+ VT != MVT::v4f64)
2349+ return SDValue ();
2350+
2351+ MVT GRLenVT = Subtarget.getGRLenVT ();
2352+ int MaskSize = Mask.size ();
2353+ assert (MaskSize == (int )VT.getVectorNumElements () && " Unexpected mask size" );
2354+
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));
2360+
2361+ // Case 2: the lowest element of V1 replaces one element in V2.
2362+ Idx = checkReplaceOne (Mask, MaskSize, 0 );
2363+ if (Idx != -1 )
2364+ return DAG.getNode (LoongArchISD::XVINSVE0, DL, VT, V2, V1,
2365+ DAG.getConstant (Idx, DL, GRLenVT));
2366+
2367+ return SDValue ();
2368+ }
2369+
23222370// / Lower VECTOR_SHUFFLE into XVSHUF (if possible).
23232371static SDValue lowerVECTOR_SHUFFLE_XVSHUF (const SDLoc &DL, ArrayRef<int > Mask,
23242372 MVT VT, SDValue V1, SDValue V2,
@@ -2595,6 +2643,9 @@ static SDValue lower256BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
25952643 if ((Result = lowerVECTOR_SHUFFLEAsShift (DL, Mask, VT, V1, V2, DAG, Subtarget,
25962644 Zeroable)))
25972645 return Result;
2646+ if ((Result =
2647+ lowerVECTOR_SHUFFLE_XVINSVE0 (DL, Mask, VT, V1, V2, DAG, Subtarget)))
2648+ return Result;
25982649 if ((Result = lowerVECTOR_SHUFFLEAsByteRotate (DL, Mask, VT, V1, V2, DAG,
25992650 Subtarget)))
26002651 return Result;
@@ -7453,6 +7504,7 @@ const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const {
74537504 NODE_NAME_CASE (XVPERM)
74547505 NODE_NAME_CASE (XVREPLVE0)
74557506 NODE_NAME_CASE (XVREPLVE0Q)
7507+ NODE_NAME_CASE (XVINSVE0)
74567508 NODE_NAME_CASE (VPICK_SEXT_ELT)
74577509 NODE_NAME_CASE (VPICK_ZEXT_ELT)
74587510 NODE_NAME_CASE (VREPLVE)
0 commit comments