[llvm-commits] [llvm] r97382 - /llvm/trunk/lib/Support/APFloat.cpp
John McCall
rjmccall at apple.com
Sun Feb 28 04:49:50 PST 2010
Author: rjmccall
Date: Sun Feb 28 06:49:50 2010
New Revision: 97382
URL: http://llvm.org/viewvc/llvm-project?rev=97382&view=rev
Log:
Properly clear all the extra bits in a significand when making a NaN from an
APInt. Be certain to set the integer bit in an x87 extended-precision
significand so that we don't accidentally make a pseudo-NaN.
Modified:
llvm/trunk/lib/Support/APFloat.cpp
Modified: llvm/trunk/lib/Support/APFloat.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=97382&r1=97381&r2=97382&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APFloat.cpp (original)
+++ llvm/trunk/lib/Support/APFloat.cpp Sun Feb 28 06:49:50 2010
@@ -631,25 +631,45 @@
category = fcNaN;
sign = Negative;
+ integerPart *significand = significandParts();
+ unsigned numParts = partCount();
+
// Set the significand bits to the fill.
- if (!fill || fill->getNumWords() < partCount())
- APInt::tcSet(significandParts(), 0, partCount());
- if (fill)
- APInt::tcAssign(significandParts(), fill->getRawData(), partCount());
+ if (!fill || fill->getNumWords() < numParts)
+ APInt::tcSet(significand, 0, numParts);
+ if (fill) {
+ APInt::tcAssign(significand, fill->getRawData(), partCount());
+
+ // Zero out the excess bits of the significand.
+ unsigned bitsToPreserve = semantics->precision - 1;
+ unsigned part = bitsToPreserve / 64;
+ bitsToPreserve %= 64;
+ significand[part] &= ((1ULL << bitsToPreserve) - 1);
+ for (part++; part != numParts; ++part)
+ significand[part] = 0;
+ }
+
+ unsigned QNaNBit = semantics->precision - 2;
if (SNaN) {
// We always have to clear the QNaN bit to make it an SNaN.
- APInt::tcClearBit(significandParts(), semantics->precision - 2);
+ APInt::tcClearBit(significand, QNaNBit);
// If there are no bits set in the payload, we have to set
// *something* to make it a NaN instead of an infinity;
// conventionally, this is the next bit down from the QNaN bit.
- if (APInt::tcIsZero(significandParts(), partCount()))
- APInt::tcSetBit(significandParts(), semantics->precision - 3);
+ if (APInt::tcIsZero(significand, numParts))
+ APInt::tcSetBit(significand, QNaNBit - 1);
} else {
// We always have to set the QNaN bit to make it a QNaN.
- APInt::tcSetBit(significandParts(), semantics->precision - 2);
+ APInt::tcSetBit(significand, QNaNBit);
}
+
+ // For x87 extended precision, we want to make a NaN, not a
+ // pseudo-NaN. Maybe we should expose the ability to make
+ // pseudo-NaNs?
+ if (semantics == &APFloat::x87DoubleExtended)
+ APInt::tcSetBit(significand, QNaNBit + 1);
}
APFloat APFloat::makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative,
More information about the llvm-commits
mailing list