@@ -1701,6 +1701,43 @@ 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+ if (!ShuffleVectorInst::isReverseMask (Mask, Mask.size ()))
1723+ return SDValue ();
1724+
1725+ int WidenNumElts = VT.getVectorNumElements () / 4 ;
1726+ SmallVector<int , 16 > WidenMask (WidenNumElts, -1 );
1727+ for (int i = 0 ; i < WidenNumElts; ++i)
1728+ WidenMask[i] = WidenNumElts - 1 - i;
1729+
1730+ MVT WidenVT = MVT::getVectorVT (
1731+ VT.getVectorElementType () == MVT::i8 ? MVT::i32 : MVT::i64 , WidenNumElts);
1732+ SDValue NewV1 = DAG.getBitcast (WidenVT, V1);
1733+ SDValue WidenRev = DAG.getVectorShuffle (WidenVT, DL, NewV1,
1734+ DAG.getUNDEF (WidenVT), WidenMask);
1735+
1736+ return DAG.getNode (LoongArchISD::VSHUF4I, DL, VT,
1737+ DAG.getBitcast (VT, WidenRev),
1738+ DAG.getConstant (27 , DL, Subtarget.getGRLenVT ()));
1739+ }
1740+
17041741// / Lower VECTOR_SHUFFLE into VPACKEV (if possible).
17051742// /
17061743// / VPACKEV interleaves the even elements from each vector.
@@ -2004,6 +2041,9 @@ static SDValue lower128BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
20042041 if ((Result =
20052042 lowerVECTOR_SHUFFLE_VSHUF4I (DL, Mask, VT, V1, V2, DAG, Subtarget)))
20062043 return Result;
2044+ if ((Result =
2045+ lowerVECTOR_SHUFFLE_IsReverse (DL, Mask, VT, V1, DAG, Subtarget)))
2046+ return Result;
20072047
20082048 // TODO: This comment may be enabled in the future to better match the
20092049 // pattern for instruction selection.
@@ -2622,6 +2662,9 @@ static SDValue lower256BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
26222662 return Result;
26232663 if ((Result = lowerVECTOR_SHUFFLE_XVPERM (DL, Mask, VT, V1, DAG, Subtarget)))
26242664 return Result;
2665+ if ((Result =
2666+ lowerVECTOR_SHUFFLE_IsReverse (DL, Mask, VT, V1, DAG, Subtarget)))
2667+ return Result;
26252668
26262669 // TODO: This comment may be enabled in the future to better match the
26272670 // pattern for instruction selection.
0 commit comments