@@ -1701,6 +1701,46 @@ lowerVECTOR_SHUFFLE_VSHUF4I(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
17011701 DAG.getConstant (Imm, DL, GRLenVT));
17021702}
17031703
1704+ // / Lower VECTOR_SHUFFLE whose result is the reversed source vector.
1705+ // /
1706+ // / It is possible to do optimization for VECTOR_SHUFFLE performing vector
1707+ // / reverse whose mask likes:
1708+ // / <7, 6, 5, 4, 3, 2, 1, 0>
1709+ // /
1710+ // / When undef's appear in the mask they are treated as if they were whatever
1711+ // / value is necessary in order to fit the above forms.
1712+ static SDValue
1713+ lowerVECTOR_SHUFFLE_IsReverse (const SDLoc &DL, ArrayRef<int > Mask, MVT VT,
1714+ SDValue V1, SelectionDAG &DAG,
1715+ const LoongArchSubtarget &Subtarget) {
1716+ // Only vectors with i8/i16 elements which cannot match other patterns
1717+ // directly needs to do this.
1718+ if (VT != MVT::v16i8 && VT != MVT::v8i16 && VT != MVT::v32i8 &&
1719+ VT != MVT::v16i16)
1720+ return SDValue ();
1721+
1722+ int MaskSize = Mask.size ();
1723+ for (int i = 0 ; i < MaskSize; ++i) {
1724+ if (Mask[i] != -1 && Mask[i] != MaskSize - 1 - i)
1725+ return SDValue ();
1726+ }
1727+
1728+ int WidenNumElts = VT.getVectorNumElements () / 4 ;
1729+ SmallVector<int , 16 > WidenMask (WidenNumElts, -1 );
1730+ for (int i = 0 ; i < WidenNumElts; ++i)
1731+ WidenMask[i] = WidenNumElts - 1 - i;
1732+
1733+ MVT WidenVT = MVT::getVectorVT (
1734+ VT.getVectorElementType () == MVT::i8 ? MVT::i32 : MVT::i64 , WidenNumElts);
1735+ SDValue NewV1 = DAG.getBitcast (WidenVT, V1);
1736+ SDValue WidenRev = DAG.getVectorShuffle (WidenVT, DL, NewV1,
1737+ DAG.getUNDEF (WidenVT), WidenMask);
1738+
1739+ return DAG.getNode (LoongArchISD::VSHUF4I, DL, VT,
1740+ DAG.getBitcast (VT, WidenRev),
1741+ DAG.getConstant (27 , DL, Subtarget.getGRLenVT ()));
1742+ }
1743+
17041744// / Lower VECTOR_SHUFFLE into VPACKEV (if possible).
17051745// /
17061746// / VPACKEV interleaves the even elements from each vector.
@@ -2004,6 +2044,9 @@ static SDValue lower128BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
20042044 if ((Result =
20052045 lowerVECTOR_SHUFFLE_VSHUF4I (DL, Mask, VT, V1, V2, DAG, Subtarget)))
20062046 return Result;
2047+ if ((Result =
2048+ lowerVECTOR_SHUFFLE_IsReverse (DL, Mask, VT, V1, DAG, Subtarget)))
2049+ return Result;
20072050
20082051 // TODO: This comment may be enabled in the future to better match the
20092052 // pattern for instruction selection.
@@ -2619,6 +2662,9 @@ static SDValue lower256BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
26192662 return Result;
26202663 if ((Result = lowerVECTOR_SHUFFLE_XVPERM (DL, Mask, VT, V1, DAG, Subtarget)))
26212664 return Result;
2665+ if ((Result =
2666+ lowerVECTOR_SHUFFLE_IsReverse (DL, Mask, VT, V1, DAG, Subtarget)))
2667+ return Result;
26222668
26232669 // TODO: This comment may be enabled in the future to better match the
26242670 // pattern for instruction selection.
0 commit comments