|
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 |
|
@@ -1671,6 +1672,36 @@ static SDValue lower256BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
|
1671 | 1672 |
|
1672 | 1673 | return SDValue();
|
1673 | 1674 | }
|
| 1675 | +// Widen element type to get a new mask value (if possible). |
| 1676 | +// For example: |
| 1677 | +// shufflevector <4 x i32> %a, <4 x i32> %b, |
| 1678 | +// <4 x i32> <i32 6, i32 7, i32 2, i32 3> |
| 1679 | +// is equivalent to: |
| 1680 | +// shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 1> |
| 1681 | +// can be lowered to: |
| 1682 | +// VPACKOD_D vr0, vr0, vr1 |
| 1683 | +static SDValue widenShuffleMask(const SDLoc &DL, ArrayRef<int> Mask, MVT VT, |
| 1684 | + SDValue V1, SDValue V2, SelectionDAG &DAG) { |
| 1685 | + unsigned EltBits = VT.getScalarSizeInBits(); |
| 1686 | + |
| 1687 | + if (EltBits > 32 || EltBits == 1) |
| 1688 | + return SDValue(); |
| 1689 | + |
| 1690 | + SmallVector<int, 8> NewMask; |
| 1691 | + if (widenShuffleMaskElts(Mask, NewMask)) { |
| 1692 | + MVT NewEltVT = VT.isFloatingPoint() ? MVT::getFloatingPointVT(EltBits * 2) |
| 1693 | + : MVT::getIntegerVT(EltBits * 2); |
| 1694 | + MVT NewVT = MVT::getVectorVT(NewEltVT, VT.getVectorNumElements() / 2); |
| 1695 | + if (DAG.getTargetLoweringInfo().isTypeLegal(NewVT)) { |
| 1696 | + SDValue NewV1 = DAG.getBitcast(NewVT, V1); |
| 1697 | + SDValue NewV2 = DAG.getBitcast(NewVT, V2); |
| 1698 | + return DAG.getBitcast( |
| 1699 | + VT, DAG.getVectorShuffle(NewVT, DL, NewV1, NewV2, NewMask)); |
| 1700 | + } |
| 1701 | + } |
| 1702 | + |
| 1703 | + return SDValue(); |
| 1704 | +} |
1674 | 1705 |
|
1675 | 1706 | SDValue LoongArchTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
|
1676 | 1707 | SelectionDAG &DAG) const {
|
@@ -1705,6 +1736,9 @@ SDValue LoongArchTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
|
1705 | 1736 | return DAG.getVectorShuffle(VT, DL, V1, V2, NewMask);
|
1706 | 1737 | }
|
1707 | 1738 |
|
| 1739 | + if (SDValue NewShuffle = widenShuffleMask(DL, OrigMask, VT, V1, V2, DAG)) |
| 1740 | + return NewShuffle; |
| 1741 | + |
1708 | 1742 | // Check for illegal shuffle mask element index values.
|
1709 | 1743 | int MaskUpperLimit = OrigMask.size() * (V2IsUndef ? 1 : 2);
|
1710 | 1744 | (void)MaskUpperLimit;
|
|
0 commit comments