|
21 | 21 | #include "X86TargetMachine.h"
|
22 | 22 | #include "llvm/ADT/SmallBitVector.h"
|
23 | 23 | #include "llvm/ADT/SmallSet.h"
|
| 24 | +#include "llvm/ADT/SmallVector.h" |
24 | 25 | #include "llvm/ADT/Statistic.h"
|
25 | 26 | #include "llvm/ADT/StringExtras.h"
|
26 | 27 | #include "llvm/ADT/StringSwitch.h"
|
|
37 | 38 | #include "llvm/CodeGen/MachineModuleInfo.h"
|
38 | 39 | #include "llvm/CodeGen/MachineRegisterInfo.h"
|
39 | 40 | #include "llvm/CodeGen/SDPatternMatch.h"
|
| 41 | +#include "llvm/CodeGen/SelectionDAGNodes.h" |
40 | 42 | #include "llvm/CodeGen/TargetLowering.h"
|
41 | 43 | #include "llvm/CodeGen/WinEHFuncInfo.h"
|
42 | 44 | #include "llvm/IR/CallingConv.h"
|
@@ -8748,23 +8750,33 @@ static SDValue lowerBuildVectorToBitOp(BuildVectorSDNode *Op, const SDLoc &DL,
|
8748 | 8750 | static SDValue lowerBuildVectorAsBlend(BuildVectorSDNode *BVOp, SDLoc const &DL,
|
8749 | 8751 | X86Subtarget const &Subtarget,
|
8750 | 8752 | SelectionDAG &DAG) {
|
8751 |
| - if (!Subtarget.hasAVX()) |
8752 |
| - return {}; |
8753 |
| - |
8754 |
| - auto VT = BVOp->getSimpleValueType(0u); |
8755 |
| - |
8756 |
| - if (VT == MVT::v4f64 && BVOp->getNumOperands() == 4u) { |
8757 |
| - SDValue Op0 = BVOp->getOperand(0u); |
8758 |
| - SDValue Op1 = BVOp->getOperand(1u); |
8759 |
| - SDValue Op2 = BVOp->getOperand(2u); |
8760 |
| - SDValue Op3 = BVOp->getOperand(3u); |
8761 |
| - |
8762 |
| - // Match X,Y,Y,X inputs. |
8763 |
| - if (Op0 == Op3 && Op1 == Op2 && Op0 != Op1) { |
8764 |
| - auto NewOp0 = DAG.getSplatBuildVector(VT, DL, Op0); |
8765 |
| - auto NewOp1 = DAG.getSplatBuildVector(VT, DL, Op1); |
8766 |
| - return DAG.getVectorShuffle(VT, DL, NewOp0, NewOp1, {0, 5, 6, 3}); |
8767 |
| - } |
| 8753 | + MVT VT = BVOp->getSimpleValueType(0u); |
| 8754 | + auto const NumElems = VT.getVectorNumElements(); |
| 8755 | + |
| 8756 | + if (Subtarget.hasAVX() && VT == MVT::v4f64) { |
| 8757 | + // Collect unique operands. |
| 8758 | + auto UniqueOps = SmallSet<SDValue, 16u>(); |
| 8759 | + for (auto &Op : BVOp->ops()) { |
| 8760 | + if (isIntOrFPConstant(Op) || Op.get()->isUndef()) |
| 8761 | + return {}; |
| 8762 | + UniqueOps.insert(Op); |
| 8763 | + } |
| 8764 | + // Candidate BUILD_VECTOR must have 2 unique operands. |
| 8765 | + if (UniqueOps.size() != 2u) |
| 8766 | + return {}; |
| 8767 | + // Create shuffle mask. |
| 8768 | + auto Op0 = BVOp->getOperand(0u); |
| 8769 | + auto Mask = std::vector<int>(); |
| 8770 | + Mask.reserve(NumElems); |
| 8771 | + for (auto I = 0u; I < NumElems; ++I) { |
| 8772 | + auto &Op = BVOp->getOperand(I); |
| 8773 | + Mask.push_back(Op == Op0 ? I : I + NumElems); |
| 8774 | + } |
| 8775 | + // Create shuffle of splats. |
| 8776 | + UniqueOps.erase(Op0); |
| 8777 | + auto NewOp0 = DAG.getSplatBuildVector(VT, DL, Op0); |
| 8778 | + auto NewOp1 = DAG.getSplatBuildVector(VT, DL, *UniqueOps.begin()); |
| 8779 | + return DAG.getVectorShuffle(VT, DL, NewOp0, NewOp1, Mask); |
8768 | 8780 | }
|
8769 | 8781 |
|
8770 | 8782 | return {};
|
|
0 commit comments