diff options
author | Tim Northover <tnorthover@apple.com> | 2014-06-15 09:27:20 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2014-06-15 09:27:20 +0000 |
commit | 40ed1d89b19856777b2072ab8a0ae89d54b2e440 (patch) | |
tree | cbcee58ce76a9972c569a0e763a4aea1af98a4c9 /lib/CodeGen/SelectionDAG | |
parent | 8bfc50e4a976476425e8f2ba7e71d7d14b48b474 (diff) | |
download | llvm-40ed1d89b19856777b2072ab8a0ae89d54b2e440.tar.gz llvm-40ed1d89b19856777b2072ab8a0ae89d54b2e440.tar.bz2 llvm-40ed1d89b19856777b2072ab8a0ae89d54b2e440.tar.xz |
LegalizeDAG: make sure cast is unsigned before using FP_TO_UINT.
It's valid to use FP_TO_SINT when asking for a smaller type (e.g. all
"unsigned int16" values fit into a "signed int32"), but the reverse
isn't true.
Unfortunately, I'm not actually aware of any architecture with
asymmetric FP_TO_SINT and FP_TO_UINT handling and the logic happens to
work in the symmetric case, so I can't actually write a test for this.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210986 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index c76a52abe6..48eb86c49c 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -2650,12 +2650,15 @@ SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDValue LegalOp, NewOutTy = (MVT::SimpleValueType)(NewOutTy.getSimpleVT().SimpleTy+1); assert(NewOutTy.isInteger() && "Ran out of possibilities!"); + // A larger signed type can hold all unsigned values of the requested type, + // so using FP_TO_SINT is valid if (TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NewOutTy)) { OpToUse = ISD::FP_TO_SINT; break; } - if (TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NewOutTy)) { + // However, if the value may be < 0.0, we *must* use some FP_TO_SINT. + if (!isSigned && TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NewOutTy)) { OpToUse = ISD::FP_TO_UINT; break; } |