[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Evan Cheng
evan.cheng at apple.com
Fri Jul 21 01:26:18 PDT 2006
Changes in directory llvm/lib/CodeGen/SelectionDAG:
DAGCombiner.cpp updated: 1.177 -> 1.178
---
Log message:
If a shuffle is a splat, check if the argument is a build_vector with all elements being the same. If so, return the argument.
---
Diffs of the changes: (+90 -8)
DAGCombiner.cpp | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 90 insertions(+), 8 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.177 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.178
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.177 Thu Jul 20 17:44:41 2006
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Jul 21 03:25:53 2006
@@ -2601,16 +2601,23 @@
// Check if the shuffle is a unary shuffle, i.e. one of the vectors is not
// needed at all.
bool isUnary = true;
+ bool isSplat = true;
int VecNum = -1;
+ unsigned BaseIdx;
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)
+ if (VecNum == -1) {
VecNum = V;
- else if (VecNum != V) {
- isUnary = false;
- break;
+ BaseIdx = Idx;
+ } else {
+ if (BaseIdx != Idx)
+ isSplat = false;
+ if (VecNum != V) {
+ isUnary = false;
+ break;
+ }
}
}
@@ -2620,6 +2627,40 @@
if (isUnary && VecNum == 1)
std::swap(N0, N1);
+ // If it is a splat, check if the argument vector is a build_vector with
+ // all scalar elements the same.
+ if (isSplat) {
+ SDNode *V = N0.Val;
+ if (V->getOpcode() == ISD::BIT_CONVERT)
+ V = V->getOperand(0).Val;
+ if (V->getOpcode() == ISD::BUILD_VECTOR) {
+ unsigned NumElems = V->getNumOperands()-2;
+ if (NumElems > BaseIdx) {
+ SDOperand Base;
+ bool AllSame = true;
+ for (unsigned i = 0; i != NumElems; ++i) {
+ if (V->getOperand(i).getOpcode() != ISD::UNDEF) {
+ Base = V->getOperand(i);
+ break;
+ }
+ }
+ // Splat of <u, u, u, u>, return <u, u, u, u>
+ if (!Base.Val)
+ return N0;
+ for (unsigned i = 0; i != NumElems; ++i) {
+ if (V->getOperand(i).getOpcode() != ISD::UNDEF &&
+ V->getOperand(i) != Base) {
+ AllSame = false;
+ break;
+ }
+ }
+ // Splat of <x, x, x, x>, return <x, x, x, x>
+ if (AllSame)
+ return N0;
+ }
+ }
+ }
+
// 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) {
@@ -2679,16 +2720,23 @@
// Check if the shuffle is a unary shuffle, i.e. one of the vectors is not
// needed at all.
bool isUnary = true;
+ bool isSplat = true;
int VecNum = -1;
+ unsigned BaseIdx;
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)
+ if (VecNum == -1) {
VecNum = V;
- else if (VecNum != V) {
- isUnary = false;
- break;
+ BaseIdx = Idx;
+ } else {
+ if (BaseIdx != Idx)
+ isSplat = false;
+ if (VecNum != V) {
+ isUnary = false;
+ break;
+ }
}
}
@@ -2698,6 +2746,40 @@
if (isUnary && VecNum == 1)
std::swap(N0, N1);
+ // If it is a splat, check if the argument vector is a build_vector with
+ // all scalar elements the same.
+ if (isSplat) {
+ SDNode *V = N0.Val;
+ if (V->getOpcode() == ISD::VBIT_CONVERT)
+ V = V->getOperand(0).Val;
+ if (V->getOpcode() == ISD::VBUILD_VECTOR) {
+ unsigned NumElems = V->getNumOperands()-2;
+ if (NumElems > BaseIdx) {
+ SDOperand Base;
+ bool AllSame = true;
+ for (unsigned i = 0; i != NumElems; ++i) {
+ if (V->getOperand(i).getOpcode() != ISD::UNDEF) {
+ Base = V->getOperand(i);
+ break;
+ }
+ }
+ // Splat of <u, u, u, u>, return <u, u, u, u>
+ if (!Base.Val)
+ return N0;
+ for (unsigned i = 0; i != NumElems; ++i) {
+ if (V->getOperand(i).getOpcode() != ISD::UNDEF &&
+ V->getOperand(i) != Base) {
+ AllSame = false;
+ break;
+ }
+ }
+ // Splat of <x, x, x, x>, return <x, x, x, x>
+ if (AllSame)
+ return N0;
+ }
+ }
+ }
+
// 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) {
More information about the llvm-commits
mailing list