summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/APFloat.cpp
diff options
context:
space:
mode:
authorPavel Labath <labath@google.com>2018-05-09 15:13:45 +0000
committerPavel Labath <labath@google.com>2018-05-09 15:13:45 +0000
commitb1bcafd70647b88e0679f03ce952cc2b14746b9d (patch)
tree36f74832738615f119b41e7c787e479f31952f3a /llvm/lib/Support/APFloat.cpp
parent8e7625eed7da9c4be06262f2235b5294ee6c2f5a (diff)
downloadbcm5719-llvm-b1bcafd70647b88e0679f03ce952cc2b14746b9d.tar.gz
bcm5719-llvm-b1bcafd70647b88e0679f03ce952cc2b14746b9d.zip
APFloat/x87: Fix string conversion for "unnormal" values (pr35860)
Summary: Unnormal values are a feature of some very old x87 processors. We handle them correctly for the most part -- the only exception was an unnormal value whose significand happened to be zero. In this case the APFloat was still initialized as normal number (category = fcNormal), but a subsequent toString operation would assert because the math would produce nonsensical values for the zero significand. During review, it was decided that the correct way to fix this is to treat all unnormal values as NaNs (as that is what any >=386 processor will do). The issue was discovered because LLDB would crash when trying to print some "long double" values. Reviewers: skatkov, scanon, gottesmm Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D41868 llvm-svn: 331884
Diffstat (limited to 'llvm/lib/Support/APFloat.cpp')
-rw-r--r--llvm/lib/Support/APFloat.cpp10
1 files changed, 6 insertions, 4 deletions
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index 6d32b03f12c..9035017a9c4 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -3032,27 +3032,29 @@ double IEEEFloat::convertToDouble() const {
/// does not support these bit patterns:
/// exponent = all 1's, integer bit 0, significand 0 ("pseudoinfinity")
/// exponent = all 1's, integer bit 0, significand nonzero ("pseudoNaN")
-/// exponent = 0, integer bit 1 ("pseudodenormal")
/// exponent!=0 nor all 1's, integer bit 0 ("unnormal")
-/// At the moment, the first two are treated as NaNs, the second two as Normal.
+/// exponent = 0, integer bit 1 ("pseudodenormal")
+/// At the moment, the first three are treated as NaNs, the last one as Normal.
void IEEEFloat::initFromF80LongDoubleAPInt(const APInt &api) {
assert(api.getBitWidth()==80);
uint64_t i1 = api.getRawData()[0];
uint64_t i2 = api.getRawData()[1];
uint64_t myexponent = (i2 & 0x7fff);
uint64_t mysignificand = i1;
+ uint8_t myintegerbit = mysignificand >> 63;
initialize(&semX87DoubleExtended);
assert(partCount()==2);
sign = static_cast<unsigned int>(i2>>15);
- if (myexponent==0 && mysignificand==0) {
+ if (myexponent == 0 && mysignificand == 0) {
// exponent, significand meaningless
category = fcZero;
} else if (myexponent==0x7fff && mysignificand==0x8000000000000000ULL) {
// exponent, significand meaningless
category = fcInfinity;
- } else if (myexponent==0x7fff && mysignificand!=0x8000000000000000ULL) {
+ } else if ((myexponent == 0x7fff && mysignificand != 0x8000000000000000ULL) ||
+ (myexponent != 0x7fff && myexponent != 0 && myintegerbit == 0)) {
// exponent meaningless
category = fcNaN;
significandParts()[0] = mysignificand;
OpenPOWER on IntegriCloud