diff options
author | Duncan Sands <baldrick@free.fr> | 2008-12-09 21:33:20 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2008-12-09 21:33:20 +0000 |
commit | 47d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7 (patch) | |
tree | 1377381b42e58700f2935db21eb26448fad758a9 /lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp | |
parent | 20d6f0982ad33818cfa141f80157ac13e36d5550 (diff) |
Fix PR3117: not all nodes being legalized. The
essential problem was that the DAG can contain
random unused nodes which were never analyzed.
When remapping a value of a node being processed,
such a node may become used and need to be analyzed;
however due to operands being transformed during
analysis the node may morph into a different one.
Users of the morphing node need to be updated, and
this wasn't happening. While there I added a bunch
of documentation and sanity checks, so I (or some
other poor soul) won't have to scratch their head
over this stuff so long trying to remember how it
was all supposed to work next time some obscure
problem pops up! The extra sanity checking exposed
a few places where invariants weren't being preserved,
so those are fixed too. Since some of the sanity
checking is expensive, I added a flag to turn it
on. It is also turned on when building with
ENABLE_EXPENSIVE_CHECKS=1.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60797 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp index 22e5b82516..21a69f578f 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp @@ -18,6 +18,7 @@ //===----------------------------------------------------------------------===// #include "LegalizeTypes.h" +#include "llvm/Target/TargetData.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -30,7 +31,8 @@ using namespace llvm; void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo, SDValue &Hi) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + MVT OutVT = N->getValueType(0); + MVT NOutVT = TLI.getTypeToTransformTo(OutVT); SDValue InOp = N->getOperand(0); MVT InVT = InOp.getValueType(); @@ -44,15 +46,15 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo, case SoftenFloat: // Convert the integer operand instead. SplitInteger(GetSoftenedFloat(InOp), Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Hi); return; case ExpandInteger: case ExpandFloat: // Convert the expanded pieces of the input. GetExpandedOp(InOp, Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Hi); return; case SplitVector: // Convert the split parts of the input if it was split in two. @@ -60,22 +62,46 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo, if (Lo.getValueType() == Hi.getValueType()) { if (TLI.isBigEndian()) std::swap(Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Hi); return; } break; case ScalarizeVector: // Convert the element instead. SplitInteger(BitConvertToInteger(GetScalarizedVector(InOp)), Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Hi); return; } - // Lower the bit-convert to a store/load from the stack, then expand the load. - SDValue Op = CreateStackStoreLoad(InOp, N->getValueType(0)); - ExpandRes_NormalLoad(Op.getNode(), Lo, Hi); + // Lower the bit-convert to a store/load from the stack. + assert(NOutVT.isByteSized() && "Expanded type not byte sized!"); + + // Create the stack frame object. Make sure it is aligned for both + // the source and expanded destination types. + unsigned Alignment = + TLI.getTargetData()->getPrefTypeAlignment(NOutVT.getTypeForMVT()); + SDValue StackPtr = DAG.CreateStackTemporary(InVT, Alignment); + + // Emit a store to the stack slot. + SDValue Store = DAG.getStore(DAG.getEntryNode(), InOp, StackPtr, NULL, 0); + + // Load the first half from the stack slot. + Lo = DAG.getLoad(NOutVT, Store, StackPtr, NULL, 0); + + // Increment the pointer to the other half. + unsigned IncrementSize = NOutVT.getSizeInBits() / 8; + StackPtr = DAG.getNode(ISD::ADD, StackPtr.getValueType(), StackPtr, + DAG.getIntPtrConstant(IncrementSize)); + + // Load the second half from the stack slot. + Hi = DAG.getLoad(NOutVT, Store, StackPtr, NULL, 0, false, + MinAlign(Alignment, IncrementSize)); + + // Handle endianness of the load. + if (TLI.isBigEndian()) + std::swap(Lo, Hi); } void DAGTypeLegalizer::ExpandRes_BUILD_PAIR(SDNode *N, SDValue &Lo, |