diff options
author | Evan Cheng <evan.cheng@apple.com> | 2008-02-18 23:04:32 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2008-02-18 23:04:32 +0000 |
commit | efec751a1b786724862ceff52748df94873a807e (patch) | |
tree | eaa70165cf0d18db2261a60816bef7d6663661bc /lib/CodeGen/SelectionDAG | |
parent | e0cfecf47d466b5776371526c27969e07177b839 (diff) |
- When DAG combiner is folding a bit convert into a BUILD_VECTOR, it should check if it's essentially a SCALAR_TO_VECTOR. Avoid turning (v8i16) <10, u, u, u> to <10, 0, u, u, u, u, u, u>. Instead, simply convert it to a SCALAR_TO_VECTOR of the proper type.
- X86 now normalize SCALAR_TO_VECTOR to (BIT_CONVERT (v4i32 SCALAR_TO_VECTOR)). Get rid of X86ISD::S2VEC.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47290 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG')
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 13 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 21 |
2 files changed, 29 insertions, 5 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 29a31e4e1d..026666c45f 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3450,14 +3450,16 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT::ValueType DstEltVT) { Ops.push_back(DAG.getConstant(NewBits, DstEltVT)); } - MVT::ValueType VT = MVT::getVectorType(DstEltVT, - Ops.size()); + MVT::ValueType VT = MVT::getVectorType(DstEltVT, Ops.size()); return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size()); } // Finally, this must be the case where we are shrinking elements: each input // turns into multiple outputs. + bool isS2V = ISD::isScalarToVector(BV); unsigned NumOutputsPerInput = SrcBitSize/DstBitSize; + MVT::ValueType VT = MVT::getVectorType(DstEltVT, + NumOutputsPerInput * BV->getNumOperands()); SmallVector<SDOperand, 8> Ops; for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) { if (BV->getOperand(i).getOpcode() == ISD::UNDEF) { @@ -3466,18 +3468,19 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT::ValueType DstEltVT) { continue; } uint64_t OpVal = cast<ConstantSDNode>(BV->getOperand(i))->getValue(); - for (unsigned j = 0; j != NumOutputsPerInput; ++j) { unsigned ThisVal = OpVal & ((1ULL << DstBitSize)-1); - OpVal >>= DstBitSize; Ops.push_back(DAG.getConstant(ThisVal, DstEltVT)); + if (isS2V && i == 0 && j == 0 && ThisVal == OpVal) + // Simply turn this into a SCALAR_TO_VECTOR of the new type. + return DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, Ops[0]); + OpVal >>= DstBitSize; } // For big endian targets, swap the order of the pieces of each element. if (TLI.isBigEndian()) std::reverse(Ops.end()-NumOutputsPerInput, Ops.end()); } - MVT::ValueType VT = MVT::getVectorType(DstEltVT, Ops.size()); return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size()); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index c12c98b4e3..f904fa16d5 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -176,6 +176,27 @@ bool ISD::isBuildVectorAllZeros(const SDNode *N) { return true; } +/// isScalarToVector - Return true if the specified node is a +/// ISD::SCALAR_TO_VECTOR node or a BUILD_VECTOR node where only the low +/// element is not an undef. +bool ISD::isScalarToVector(const SDNode *N) { + if (N->getOpcode() == ISD::SCALAR_TO_VECTOR) + return true; + + if (N->getOpcode() != ISD::BUILD_VECTOR) + return false; + if (N->getOperand(0).getOpcode() == ISD::UNDEF) + return false; + unsigned NumElems = N->getNumOperands(); + for (unsigned i = 1; i < NumElems; ++i) { + SDOperand V = N->getOperand(i); + if (V.getOpcode() != ISD::UNDEF) + return false; + } + return true; +} + + /// isDebugLabel - Return true if the specified node represents a debug /// label (i.e. ISD::LABEL or TargetInstrInfo::LABEL node and third operand /// is 0). |