diff options
author | Evan Cheng <evan.cheng@apple.com> | 2006-07-20 22:44:41 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2006-07-20 22:44:41 +0000 |
commit | e7bec0dbb50235ec60f78f1f7b3f6d2f6bb5cd91 (patch) | |
tree | 144d6e4c480b44f6b2bcb17dfc0a3d8e1a793bbe | |
parent | 514e258994b5a28935a144217680d23efaa16ba4 (diff) | |
download | external_llvm-e7bec0dbb50235ec60f78f1f7b3f6d2f6bb5cd91.zip external_llvm-e7bec0dbb50235ec60f78f1f7b3f6d2f6bb5cd91.tar.gz external_llvm-e7bec0dbb50235ec60f78f1f7b3f6d2f6bb5cd91.tar.bz2 |
If a shuffle is unary, i.e. one of the vector argument is not needed, turn the
operand into a undef and adjust mask accordingly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29232 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 6b86f4d..63f0f17 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2597,10 +2597,33 @@ SDOperand DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) { } } if (isIdentity) return N->getOperand(1); - - // If the LHS and the RHS are the same node, turn the RHS into an undef. - if (N->getOperand(0) == N->getOperand(1)) { - if (N->getOperand(0).getOpcode() == ISD::UNDEF) + + // Check if the shuffle is a unary shuffle, i.e. one of the vectors is not + // needed at all. + bool isUnary = true; + int VecNum = -1; + for (unsigned i = 0; i != NumElts; ++i) + if (ShufMask.getOperand(i).getOpcode() != ISD::UNDEF) { + unsigned Idx = cast<ConstantSDNode>(ShufMask.getOperand(i))->getValue(); + int V = (Idx < NumElts) ? 0 : 1; + if (VecNum == -1) + VecNum = V; + else if (VecNum != V) { + isUnary = false; + break; + } + } + + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + // Normalize unary shuffle so the RHS is undef. + if (isUnary && VecNum == 1) + std::swap(N0, N1); + + // If it is a unary or the LHS and the RHS are the same node, turn the RHS + // into an undef. + if (isUnary || N0 == N1) { + if (N0.getOpcode() == ISD::UNDEF) return DAG.getNode(ISD::UNDEF, N->getValueType(0)); // Check the SHUFFLE mask, mapping any inputs from the 2nd operand into the // first operand. @@ -2619,7 +2642,7 @@ SDOperand DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) { MappedOps); AddToWorkList(ShufMask.Val); return DAG.getNode(ISD::VECTOR_SHUFFLE, N->getValueType(0), - N->getOperand(0), + N0, DAG.getNode(ISD::UNDEF, N->getValueType(0)), ShufMask); } @@ -2653,8 +2676,31 @@ SDOperand DAGCombiner::visitVVECTOR_SHUFFLE(SDNode *N) { } if (isIdentity) return N->getOperand(1); - // If the LHS and the RHS are the same node, turn the RHS into an undef. - if (N->getOperand(0) == N->getOperand(1)) { + // Check if the shuffle is a unary shuffle, i.e. one of the vectors is not + // needed at all. + bool isUnary = true; + int VecNum = -1; + for (unsigned i = 0; i != NumElts; ++i) + if (ShufMask.getOperand(i).getOpcode() != ISD::UNDEF) { + unsigned Idx = cast<ConstantSDNode>(ShufMask.getOperand(i))->getValue(); + int V = (Idx < NumElts) ? 0 : 1; + if (VecNum == -1) + VecNum = V; + else if (VecNum != V) { + isUnary = false; + break; + } + } + + SDOperand N0 = N->getOperand(0); + SDOperand N1 = N->getOperand(1); + // Normalize unary shuffle so the RHS is undef. + if (isUnary && VecNum == 1) + std::swap(N0, N1); + + // If it is a unary or the LHS and the RHS are the same node, turn the RHS + // into an undef. + if (isUnary || N0 == N1) { // Check the SHUFFLE mask, mapping any inputs from the 2nd operand into the // first operand. std::vector<SDOperand> MappedOps; @@ -2680,12 +2726,12 @@ SDOperand DAGCombiner::visitVVECTOR_SHUFFLE(SDNode *N) { SDOperand UDVal = DAG.getNode(ISD::UNDEF, MappedOps[0].getValueType()); for (unsigned i = 0; i != NumElts; ++i) MappedOps[i] = UDVal; - MappedOps[NumElts ] = *(N->getOperand(0).Val->op_end()-2); - MappedOps[NumElts+1] = *(N->getOperand(0).Val->op_end()-1); + MappedOps[NumElts ] = *(N0.Val->op_end()-2); + MappedOps[NumElts+1] = *(N0.Val->op_end()-1); UDVal = DAG.getNode(ISD::VBUILD_VECTOR, MVT::Vector, MappedOps); return DAG.getNode(ISD::VVECTOR_SHUFFLE, MVT::Vector, - N->getOperand(0), UDVal, ShufMask, + N0, UDVal, ShufMask, MappedOps[NumElts], MappedOps[NumElts+1]); } |