diff options
| author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2015-05-01 08:20:04 +0000 |
|---|---|---|
| committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2015-05-01 08:20:04 +0000 |
| commit | 9fb06bca670840f1efacf26c81df79aa16cbf720 (patch) | |
| tree | 5eb67076d54d44634aac8829e73cad05a1f0d08f /llvm/lib/CodeGen | |
| parent | aa798340c3e43ba9f2e4f23324b50e4719fb497c (diff) | |
| download | bcm5719-llvm-9fb06bca670840f1efacf26c81df79aa16cbf720.tar.gz bcm5719-llvm-9fb06bca670840f1efacf26c81df79aa16cbf720.zip | |
[SelectionDAG] Unary vector constant folding integer legality fixes
This patch fixes issues with vector constant folding not correctly handling scalar input operands if they require implicit truncation - this was tested with llvm-stress as recommended by Patrik H Hagglund.
The patch ensures that integer input scalars from a build vector are correctly truncated before folding, and that constant integer scalar results are promoted to a legal type before inclusion in the new folded build vector.
I have added another crash test case and also a test for UINT_TO_FP / SINT_TO_FP using an non-truncated scalar input, which was failing before this patch.
Differential Revision: http://reviews.llvm.org/D9282
llvm-svn: 236308
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index d289406e6e9..9d403a6948c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2858,23 +2858,43 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, // FIXME: Entirely reasonable to perform folding of other unary // operations here as the need arises. break; - case ISD::TRUNCATE: - // Constant build vector truncation can be done with the original scalar - // operands but with a new build vector with the truncated value type. - return getNode(ISD::BUILD_VECTOR, DL, VT, BV->ops()); case ISD::FNEG: case ISD::FABS: case ISD::FCEIL: case ISD::FTRUNC: case ISD::FFLOOR: case ISD::FP_EXTEND: + case ISD::TRUNCATE: case ISD::UINT_TO_FP: case ISD::SINT_TO_FP: { + EVT SVT = VT.getScalarType(); + EVT InVT = BV->getValueType(0); + EVT InSVT = InVT.getScalarType(); + + // Find legal integer scalar type for constant promotion. + EVT LegalSVT = SVT; + if (SVT.isInteger()) { + LegalSVT = TLI->getTypeToTransformTo(*getContext(), SVT); + assert(LegalSVT.bitsGE(SVT) && "Unexpected legal scalar type size"); + } + // Let the above scalar folding handle the folding of each element. SmallVector<SDValue, 8> Ops; for (int i = 0, e = VT.getVectorNumElements(); i != e; ++i) { SDValue OpN = BV->getOperand(i); - OpN = getNode(Opcode, DL, VT.getVectorElementType(), OpN); + EVT OpVT = OpN.getValueType(); + + // Build vector (integer) scalar operands may need implicit + // truncation - do this before constant folding. + if (OpVT.isInteger() && OpVT.bitsGT(InSVT)) + OpN = getNode(ISD::TRUNCATE, DL, InSVT, OpN); + + OpN = getNode(Opcode, DL, SVT, OpN); + + // Legalize the (integer) scalar constant if necessary. + if (LegalSVT != SVT) + OpN = getNode(ISD::ANY_EXTEND, DL, LegalSVT, OpN); + if (OpN.getOpcode() != ISD::UNDEF && OpN.getOpcode() != ISD::Constant && OpN.getOpcode() != ISD::ConstantFP) |

