aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2006-07-20 22:44:41 +0000
committerEvan Cheng <evan.cheng@apple.com>2006-07-20 22:44:41 +0000
commite7bec0dbb50235ec60f78f1f7b3f6d2f6bb5cd91 (patch)
tree144d6e4c480b44f6b2bcb17dfc0a3d8e1a793bbe
parent514e258994b5a28935a144217680d23efaa16ba4 (diff)
downloadexternal_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.cpp66
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]);
}