diff options
| author | Jatin Bhateja <jatin.bhateja@gmail.com> | 2017-08-19 15:58:36 +0000 |
|---|---|---|
| committer | Jatin Bhateja <jatin.bhateja@gmail.com> | 2017-08-19 15:58:36 +0000 |
| commit | 313f97dd84b5d1b997d3763e530e4bf7523c76be (patch) | |
| tree | 722226a1f546b220437289893ea7f1a771ebdb41 /llvm/lib/CodeGen | |
| parent | a29d6aecedfefde83daaf5858c13f0f4ce7f2aaa (diff) | |
| download | bcm5719-llvm-313f97dd84b5d1b997d3763e530e4bf7523c76be.tar.gz bcm5719-llvm-313f97dd84b5d1b997d3763e530e4bf7523c76be.zip | |
Extension of shuffle vector pattern detection, updating post rebase.
llvm-svn: 311242
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 6a5e85f3d7f..dd8bc9fd119 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -14190,10 +14190,15 @@ SDValue DAGCombiner::createBuildVecShuffle(const SDLoc &DL, SDNode *N, EVT InVT1 = VecIn1.getValueType(); EVT InVT2 = VecIn2.getNode() ? VecIn2.getValueType() : InVT1; - unsigned Vec2Offset = InVT1.getVectorNumElements(); + unsigned Vec2Offset = 0; unsigned NumElems = VT.getVectorNumElements(); unsigned ShuffleNumElems = NumElems; + if (!(VecIn2 && (VecIn1.getOpcode() == ISD::EXTRACT_SUBVECTOR) && + (VecIn2.getOpcode() == ISD::EXTRACT_SUBVECTOR) && + (VecIn1.getOperand(0) == VecIn2.getOperand(0)))) + Vec2Offset = InVT1.getVectorNumElements(); + // We can't generate a shuffle node with mismatched input and output types. // Try to make the types match the type of the output. if (InVT1 != VT || InVT2 != VT) { @@ -14340,7 +14345,6 @@ SDValue DAGCombiner::reduceBuildVecToShuffle(SDNode *N) { if (Op.getOpcode() != ISD::EXTRACT_VECTOR_ELT || !isa<ConstantSDNode>(Op.getOperand(1))) return SDValue(); - SDValue ExtractedFromVec = Op.getOperand(0); // All inputs must have the same element type as the output. @@ -14363,6 +14367,46 @@ SDValue DAGCombiner::reduceBuildVecToShuffle(SDNode *N) { if (VecIn.size() < 2) return SDValue(); + // If all the Operands of BUILD_VECTOR extract from same + // vector, then split the vector efficiently based on the maximum + // vector access index and adjust the VectorMask and + // VecIn accordingly. + if (VecIn.size() == 2) { + unsigned MaxIndex = 0; + unsigned NearestPow2 = 0; + SDValue Vec = VecIn.back(); + EVT InVT = Vec.getValueType(); + MVT IdxTy = TLI.getVectorIdxTy(DAG.getDataLayout()); + SmallVector<unsigned, 8> IndexVec(NumElems, 0); + + for (unsigned i = 0; i < NumElems; i++) { + if (VectorMask[i] <= 0) + continue; + unsigned Index = N->getOperand(i).getConstantOperandVal(1); + IndexVec[i] = Index; + MaxIndex = std::max(MaxIndex,Index); + } + + NearestPow2 = PowerOf2Ceil(MaxIndex); + if (NearestPow2 && ((NumElems * 2) < NearestPow2)) { + unsigned SplitSize = NearestPow2 / 2; + if (SplitSize > 1) { + EVT SplitVT = EVT::getVectorVT(*DAG.getContext(), + InVT.getVectorElementType(), SplitSize); + SDValue VecIn2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SplitVT, Vec, + DAG.getConstant(SplitSize, DL, IdxTy)); + SDValue VecIn1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SplitVT, Vec, + DAG.getConstant(0, DL, IdxTy)); + VecIn.pop_back(); + VecIn.push_back(VecIn1); + VecIn.push_back(VecIn2); + + for (unsigned i = 0; i < NumElems; i++) + VectorMask[i] = (IndexVec[i] < SplitSize) ? 1 : 2; + } + } + } + // TODO: We want to sort the vectors by descending length, so that adjacent // pairs have similar length, and the longer vector is always first in the // pair. @@ -14451,7 +14495,6 @@ SDValue DAGCombiner::reduceBuildVecToShuffle(SDNode *N) { DAG.getVectorShuffle(VT, DL, Shuffles[Left], Shuffles[Right], Mask); } } - return Shuffles[0]; } |

