|
31 | 31 | #include "llvm/Support/ErrorHandling.h" |
32 | 32 | #include "llvm/Support/KnownBits.h" |
33 | 33 | #include "llvm/Support/MathExtras.h" |
| 34 | +#include <llvm/Analysis/VectorUtils.h> |
34 | 35 |
|
35 | 36 | using namespace llvm; |
36 | 37 |
|
@@ -1808,6 +1809,36 @@ static SDValue lower256BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT, |
1808 | 1809 |
|
1809 | 1810 | return SDValue(); |
1810 | 1811 | } |
| 1812 | +// Widen element type to get a new mask value (if possible). |
| 1813 | +// For example: |
| 1814 | +// shufflevector <4 x i32> %a, <4 x i32> %b, |
| 1815 | +// <4 x i32> <i32 6, i32 7, i32 2, i32 3> |
| 1816 | +// is equivalent to: |
| 1817 | +// shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 1> |
| 1818 | +// can be lowered to: |
| 1819 | +// VPACKOD_D vr0, vr0, vr1 |
| 1820 | +static SDValue widenShuffleMask(const SDLoc &DL, ArrayRef<int> Mask, MVT VT, |
| 1821 | + SDValue V1, SDValue V2, SelectionDAG &DAG) { |
| 1822 | + unsigned EltBits = VT.getScalarSizeInBits(); |
| 1823 | + |
| 1824 | + if (EltBits > 32 || EltBits == 1) |
| 1825 | + return SDValue(); |
| 1826 | + |
| 1827 | + SmallVector<int, 8> NewMask; |
| 1828 | + if (widenShuffleMaskElts(Mask, NewMask)) { |
| 1829 | + MVT NewEltVT = VT.isFloatingPoint() ? MVT::getFloatingPointVT(EltBits * 2) |
| 1830 | + : MVT::getIntegerVT(EltBits * 2); |
| 1831 | + MVT NewVT = MVT::getVectorVT(NewEltVT, VT.getVectorNumElements() / 2); |
| 1832 | + if (DAG.getTargetLoweringInfo().isTypeLegal(NewVT)) { |
| 1833 | + SDValue NewV1 = DAG.getBitcast(NewVT, V1); |
| 1834 | + SDValue NewV2 = DAG.getBitcast(NewVT, V2); |
| 1835 | + return DAG.getBitcast( |
| 1836 | + VT, DAG.getVectorShuffle(NewVT, DL, NewV1, NewV2, NewMask)); |
| 1837 | + } |
| 1838 | + } |
| 1839 | + |
| 1840 | + return SDValue(); |
| 1841 | +} |
1811 | 1842 |
|
1812 | 1843 | SDValue LoongArchTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op, |
1813 | 1844 | SelectionDAG &DAG) const { |
@@ -1842,6 +1873,9 @@ SDValue LoongArchTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op, |
1842 | 1873 | return DAG.getVectorShuffle(VT, DL, V1, V2, NewMask); |
1843 | 1874 | } |
1844 | 1875 |
|
| 1876 | + if (SDValue NewShuffle = widenShuffleMask(DL, OrigMask, VT, V1, V2, DAG)) |
| 1877 | + return NewShuffle; |
| 1878 | + |
1845 | 1879 | // Check for illegal shuffle mask element index values. |
1846 | 1880 | int MaskUpperLimit = OrigMask.size() * (V2IsUndef ? 1 : 2); |
1847 | 1881 | (void)MaskUpperLimit; |
|
0 commit comments