X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FAPFloat.cpp;h=4b0a0e5d4819a662b2603ab06d4c8d4104340af1;hb=7fb69bc395ac445706bbc7220ecc6373247dcd9a;hp=ae4a101febab4ab02a828e2031f2b412969bfb79;hpb=b57770387ab262a0a23e77f094f599b6c955ba14;p=oota-llvm.git diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index ae4a101feba..4b0a0e5d481 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -35,8 +35,7 @@ using namespace llvm; /* Assumed in hexadecimal significand parsing, and conversion to hexadecimal strings. */ -#define COMPILE_TIME_ASSERT(cond) extern int CTAssert[(cond) ? 1 : -1] -COMPILE_TIME_ASSERT(integerPartWidth % 4 == 0); +static_assert(integerPartWidth % 4 == 0, "Part width must be divisible by 4!"); namespace llvm { @@ -212,15 +211,15 @@ skipLeadingZeroesAndAnyDot(StringRef::iterator begin, StringRef::iterator end, { StringRef::iterator p = begin; *dot = end; - while (*p == '0' && p != end) + while (p != end && *p == '0') p++; - if (*p == '.') { + if (p != end && *p == '.') { *dot = p++; assert(end - begin != 1 && "Significand has no digits"); - while (*p == '0' && p != end) + while (p != end && *p == '0') p++; } @@ -319,8 +318,8 @@ trailingHexadecimalFraction(StringRef::iterator p, StringRef::iterator end, else if (digitValue < 8 && digitValue > 0) return lfLessThanHalf; - /* Otherwise we need to find the first non-zero digit. */ - while (*p == '0') + // Otherwise we need to find the first non-zero digit. + while (p != end && (*p == '0' || *p == '.')) p++; assert(p != end && "Invalid trailing hexadecimal fraction!"); @@ -683,6 +682,20 @@ APFloat::operator=(const APFloat &rhs) return *this; } +APFloat & +APFloat::operator=(APFloat &&rhs) { + freeSignificand(); + + semantics = rhs.semantics; + significand = rhs.significand; + exponent = rhs.exponent; + category = rhs.category; + sign = rhs.sign; + + rhs.semantics = &Bogus; + return *this; +} + bool APFloat::isDenormal() const { return isFiniteNonZero() && (exponent == semantics->minExponent) && @@ -778,6 +791,7 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const { APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) { initialize(&ourSemantics); sign = 0; + category = fcNormal; zeroSignificand(); exponent = ourSemantics.precision - 1; significandParts()[0] = value; @@ -805,6 +819,10 @@ APFloat::APFloat(const APFloat &rhs) { assign(rhs); } +APFloat::APFloat(APFloat &&rhs) : semantics(&Bogus) { + *this = std::move(rhs); +} + APFloat::~APFloat() { freeSignificand(); @@ -845,7 +863,6 @@ APFloat::significandParts() void APFloat::zeroSignificand() { - category = fcNormal; APInt::tcSet(significandParts(), 0, partCount()); } @@ -909,7 +926,10 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) assert(semantics == rhs.semantics); precision = semantics->precision; - newPartsCount = partCountForBits(precision * 2); + + // Allocate space for twice as many bits as the original significand, plus one + // extra bit for the addition to overflow into. + newPartsCount = partCountForBits(precision * 2 + 1); if (newPartsCount > 4) fullSignificand = new integerPart[newPartsCount]; @@ -931,13 +951,14 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) // *this = a23 . a22 ... a0 * 2^e1 // rhs = b23 . b22 ... b0 * 2^e2 // the result of multiplication is: - // *this = c47 c46 . c45 ... c0 * 2^(e1+e2) - // Note that there are two significant bits at the left-hand side of the - // radix point. Move the radix point toward left by one bit, and adjust - // exponent accordingly. - exponent += 1; - - if (addend) { + // *this = c48 c47 c46 . c45 ... c0 * 2^(e1+e2) + // Note that there are three significant bits at the left-hand side of the + // radix point: two for the multiplication, and an overflow bit for the + // addition (that will always be zero at this point). Move the radix point + // toward left by two bits, and adjust exponent accordingly. + exponent += 2; + + if (addend && addend->isNonZero()) { // The intermediate result of the multiplication has "2 * precision" // signicant bit; adjust the addend to be consistent with mul result. // @@ -947,13 +968,13 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) opStatus status; unsigned int extendedPrecision; - /* Normalize our MSB. */ - extendedPrecision = 2 * precision; - if (omsb != extendedPrecision) { + // Normalize our MSB to one below the top bit to allow for overflow. + extendedPrecision = 2 * precision + 1; + if (omsb != extendedPrecision - 1) { assert(extendedPrecision > omsb); APInt::tcShiftLeft(fullSignificand, newPartsCount, - extendedPrecision - omsb); - exponent -= extendedPrecision - omsb; + (extendedPrecision - 1) - omsb); + exponent -= (extendedPrecision - 1) - omsb; } /* Create new semantics. */ @@ -970,6 +991,14 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored); assert(status == opOK); (void)status; + + // Shift the significand of the addend right by one bit. This guarantees + // that the high bit of the significand is zero (same as fullSignificand), + // so the addition will overflow (if it does overflow at all) into the top bit. + lost_fraction = extendedAddend.shiftSignificandRight(1); + assert(lost_fraction == lfExactlyZero && + "Lost precision while shifting addend for fused-multiply-add."); + lost_fraction = addOrSubtractSignificand(extendedAddend, false); /* Restore our state. */ @@ -985,7 +1014,7 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) // having "precision" significant-bits. First, move the radix point from // poision "2*precision - 1" to "precision - 1". The exponent need to be // adjusted by "2*precision - 1" - "precision - 1" = "precision". - exponent -= precision; + exponent -= precision + 1; // In case MSB resides at the left-hand side of radix point, shift the // mantissa right by some amount to make sure the MSB reside right before @@ -1219,10 +1248,10 @@ APFloat::roundAwayFromZero(roundingMode rounding_mode, return false; case rmTowardPositive: - return sign == false; + return !sign; case rmTowardNegative: - return sign == true; + return sign; } llvm_unreachable("Invalid rounding mode found"); } @@ -1340,7 +1369,7 @@ APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract) { switch (PackCategoriesIntoKey(category, rhs.category)) { default: - llvm_unreachable(0); + llvm_unreachable(nullptr); case PackCategoriesIntoKey(fcNaN, fcZero): case PackCategoriesIntoKey(fcNaN, fcNormal): @@ -1354,6 +1383,9 @@ APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract) case PackCategoriesIntoKey(fcZero, fcNaN): case PackCategoriesIntoKey(fcNormal, fcNaN): case PackCategoriesIntoKey(fcInfinity, fcNaN): + // We need to be sure to flip the sign here for subtraction because we + // don't have a separate negate operation so -NaN becomes 0 - NaN here. + sign = rhs.sign ^ subtract; category = fcNaN; copySignificand(rhs); return opOK; @@ -1398,7 +1430,7 @@ APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract) /* Determine if the operation on the absolute values is effectively an addition or subtraction. */ - subtract ^= (sign ^ rhs.sign) ? true : false; + subtract ^= static_cast(sign ^ rhs.sign); /* Are we bigger exponent-wise than the RHS? */ bits = exponent - rhs.exponent; @@ -1466,17 +1498,19 @@ APFloat::multiplySpecials(const APFloat &rhs) { switch (PackCategoriesIntoKey(category, rhs.category)) { default: - llvm_unreachable(0); + llvm_unreachable(nullptr); case PackCategoriesIntoKey(fcNaN, fcZero): case PackCategoriesIntoKey(fcNaN, fcNormal): case PackCategoriesIntoKey(fcNaN, fcInfinity): case PackCategoriesIntoKey(fcNaN, fcNaN): + sign = false; return opOK; case PackCategoriesIntoKey(fcZero, fcNaN): case PackCategoriesIntoKey(fcNormal, fcNaN): case PackCategoriesIntoKey(fcInfinity, fcNaN): + sign = false; category = fcNaN; copySignificand(rhs); return opOK; @@ -1508,25 +1542,24 @@ APFloat::divideSpecials(const APFloat &rhs) { switch (PackCategoriesIntoKey(category, rhs.category)) { default: - llvm_unreachable(0); + llvm_unreachable(nullptr); + case PackCategoriesIntoKey(fcZero, fcNaN): + case PackCategoriesIntoKey(fcNormal, fcNaN): + case PackCategoriesIntoKey(fcInfinity, fcNaN): + category = fcNaN; + copySignificand(rhs); case PackCategoriesIntoKey(fcNaN, fcZero): case PackCategoriesIntoKey(fcNaN, fcNormal): case PackCategoriesIntoKey(fcNaN, fcInfinity): case PackCategoriesIntoKey(fcNaN, fcNaN): + sign = false; case PackCategoriesIntoKey(fcInfinity, fcZero): case PackCategoriesIntoKey(fcInfinity, fcNormal): case PackCategoriesIntoKey(fcZero, fcInfinity): case PackCategoriesIntoKey(fcZero, fcNormal): return opOK; - case PackCategoriesIntoKey(fcZero, fcNaN): - case PackCategoriesIntoKey(fcNormal, fcNaN): - case PackCategoriesIntoKey(fcInfinity, fcNaN): - category = fcNaN; - copySignificand(rhs); - return opOK; - case PackCategoriesIntoKey(fcNormal, fcInfinity): category = fcZero; return opOK; @@ -1550,7 +1583,7 @@ APFloat::modSpecials(const APFloat &rhs) { switch (PackCategoriesIntoKey(category, rhs.category)) { default: - llvm_unreachable(0); + llvm_unreachable(nullptr); case PackCategoriesIntoKey(fcNaN, fcZero): case PackCategoriesIntoKey(fcNaN, fcNormal): @@ -1564,6 +1597,7 @@ APFloat::modSpecials(const APFloat &rhs) case PackCategoriesIntoKey(fcZero, fcNaN): case PackCategoriesIntoKey(fcNormal, fcNaN): case PackCategoriesIntoKey(fcInfinity, fcNaN): + sign = false; category = fcNaN; copySignificand(rhs); return opOK; @@ -1658,7 +1692,7 @@ APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode) fs = multiplySpecials(rhs); if (isFiniteNonZero()) { - lostFraction lost_fraction = multiplySignificand(rhs, 0); + lostFraction lost_fraction = multiplySignificand(rhs, nullptr); fs = normalize(rounding_mode, lost_fraction); if (lost_fraction != lfExactlyZero) fs = (opStatus) (fs | opInexact); @@ -1778,7 +1812,7 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand, extended-precision calculation. */ if (isFiniteNonZero() && multiplicand.isFiniteNonZero() && - addend.isFiniteNonZero()) { + addend.isFinite()) { lostFraction lost_fraction; lost_fraction = multiplySignificand(multiplicand, &addend); @@ -1789,7 +1823,7 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand, /* If two numbers add (exactly) to zero, IEEE 754 decrees it is a positive zero unless rounding to minus infinity, except that adding two like-signed zeroes gives that zero. */ - if (category == fcZero && sign != addend.sign) + if (category == fcZero && !(fs & opUnderflow) && sign != addend.sign) sign = (rounding_mode == rmTowardNegative); } else { fs = multiplySpecials(multiplicand); @@ -1861,7 +1895,7 @@ APFloat::compare(const APFloat &rhs) const switch (PackCategoriesIntoKey(category, rhs.category)) { default: - llvm_unreachable(0); + llvm_unreachable(nullptr); case PackCategoriesIntoKey(fcNaN, fcZero): case PackCategoriesIntoKey(fcNaN, fcNormal): @@ -1956,6 +1990,23 @@ APFloat::convert(const fltSemantics &toSemantics, X86SpecialNan = true; } + // If this is a truncation of a denormal number, and the target semantics + // has larger exponent range than the source semantics (this can happen + // when truncating from PowerPC double-double to double format), the + // right shift could lose result mantissa bits. Adjust exponent instead + // of performing excessive shift. + if (shift < 0 && isFiniteNonZero()) { + int exponentChange = significandMSB() + 1 - fromSemantics.precision; + if (exponent + exponentChange < toSemantics.minExponent) + exponentChange = toSemantics.minExponent - exponent; + if (exponentChange < shift) + exponentChange = shift; + if (exponentChange < 0) { + shift -= exponentChange; + exponent += exponentChange; + } + } + // If this is a truncation, perform the shift before we narrow the storage. if (shift < 0 && (isFiniteNonZero() || category==fcNaN)) lostFraction = shiftRight(significandParts(), oldPartCount, -shift); @@ -2283,56 +2334,46 @@ APFloat::opStatus APFloat::convertFromHexadecimalString(StringRef s, roundingMode rounding_mode) { lostFraction lost_fraction = lfExactlyZero; - integerPart *significand; - unsigned int bitPos, partsCount; - StringRef::iterator dot, firstSignificantDigit; + category = fcNormal; zeroSignificand(); exponent = 0; - category = fcNormal; - significand = significandParts(); - partsCount = partCount(); - bitPos = partsCount * integerPartWidth; + integerPart *significand = significandParts(); + unsigned partsCount = partCount(); + unsigned bitPos = partsCount * integerPartWidth; + bool computedTrailingFraction = false; - /* Skip leading zeroes and any (hexa)decimal point. */ + // Skip leading zeroes and any (hexa)decimal point. StringRef::iterator begin = s.begin(); StringRef::iterator end = s.end(); + StringRef::iterator dot; StringRef::iterator p = skipLeadingZeroesAndAnyDot(begin, end, &dot); - firstSignificantDigit = p; + StringRef::iterator firstSignificantDigit = p; - for (; p != end;) { + while (p != end) { integerPart hex_value; if (*p == '.') { assert(dot == end && "String contains multiple dots"); dot = p++; - if (p == end) { - break; - } + continue; } hex_value = hexDigitValue(*p); - if (hex_value == -1U) { + if (hex_value == -1U) break; - } p++; - if (p == end) { - break; - } else { - /* Store the number whilst 4-bit nibbles remain. */ - if (bitPos) { - bitPos -= 4; - hex_value <<= bitPos % integerPartWidth; - significand[bitPos / integerPartWidth] |= hex_value; - } else { - lost_fraction = trailingHexadecimalFraction(p, end, hex_value); - while (p != end && hexDigitValue(*p) != -1U) - p++; - break; - } + // Store the number while we have space. + if (bitPos) { + bitPos -= 4; + hex_value <<= bitPos % integerPartWidth; + significand[bitPos / integerPartWidth] |= hex_value; + } else if (!computedTrailingFraction) { + lost_fraction = trailingHexadecimalFraction(p, end, hex_value); + computedTrailingFraction = true; } } @@ -2411,7 +2452,7 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts, if (exp >= 0) { /* multiplySignificand leaves the precision-th bit set to 1. */ - calcLostFraction = decSig.multiplySignificand(pow5, NULL); + calcLostFraction = decSig.multiplySignificand(pow5, nullptr); powHUerr = powStatus != opOK; } else { calcLostFraction = decSig.divideSignificand(pow5); @@ -2488,7 +2529,7 @@ APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) // D->firstSigDigit equals str.end(), every digit must be a zero and there can // be at most one dot. On the other hand, if we have a zero with a non-zero // exponent, then we know that D.firstSigDigit will be non-numeric. - if (decDigitValue(*D.firstSigDigit) >= 10U || D.firstSigDigit == str.end()) { + if (D.firstSigDigit == str.end() || decDigitValue(*D.firstSigDigit) >= 10U) { category = fcZero; fs = opOK; @@ -2505,6 +2546,7 @@ APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) (D.normalizedExponent + 1) * 28738 <= 8651 * (semantics->minExponent - (int) semantics->precision)) { /* Underflow to zero and round. */ + category = fcNormal; zeroSignificand(); fs = normalize(rounding_mode, lfLessThanHalf); @@ -3302,7 +3344,7 @@ APFloat::initFromAPInt(const fltSemantics* Sem, const APInt& api) if (Sem == &PPCDoubleDouble) return initFromPPCDoubleDoubleAPInt(api); - llvm_unreachable(0); + llvm_unreachable(nullptr); } APFloat @@ -3346,7 +3388,9 @@ void APFloat::makeLargest(bool Negative) { // internal consistency. const unsigned NumUnusedHighBits = PartCount*integerPartWidth - semantics->precision; - significand[PartCount - 1] = ~integerPart(0) >> NumUnusedHighBits; + significand[PartCount - 1] = (NumUnusedHighBits < integerPartWidth) + ? (~integerPart(0) >> NumUnusedHighBits) + : 0; } /// Make this number the smallest magnitude denormal number in the given @@ -3391,6 +3435,7 @@ APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) { // exponent = 0..0 // significand = 10..0 + Val.category = fcNormal; Val.zeroSignificand(); Val.sign = Negative; Val.exponent = Sem.minExponent; @@ -3534,11 +3579,14 @@ void APFloat::toString(SmallVectorImpl &Str, // Set FormatPrecision if zero. We want to do this before we // truncate trailing zeros, as those are part of the precision. if (!FormatPrecision) { - // It's an interesting question whether to use the nominal - // precision or the active precision here for denormals. + // We use enough digits so the number can be round-tripped back to an + // APFloat. The formula comes from "How to Print Floating-Point Numbers + // Accurately" by Steele and White. + // FIXME: Using a formula based purely on the precision is conservative; + // we can print fewer digits depending on the actual value being printed. - // FormatPrecision = ceil(significandBits / lg_2(10)) - FormatPrecision = (semantics->precision * 59 + 195) / 196; + // FormatPrecision = 2 + floor(significandBits / lg_2(10)) + FormatPrecision = 2 + semantics->precision * 59 / 196; } // Ignore trailing binary zeros. @@ -3761,8 +3809,8 @@ APFloat::opStatus APFloat::next(bool nextDown) { // change the payload. if (isSignaling()) { result = opInvalidOp; - // For consistency, propogate the sign of the sNaN to the qNaN. - makeNaN(false, isNegative(), 0); + // For consistency, propagate the sign of the sNaN to the qNaN. + makeNaN(false, isNegative(), nullptr); } break; case fcZero: @@ -3801,7 +3849,7 @@ APFloat::opStatus APFloat::next(bool nextDown) { // Decrement the significand. // // We always do this since: - // 1. If we are dealing with a non binade decrement, by definition we + // 1. If we are dealing with a non-binade decrement, by definition we // just decrement the significand. // 2. If we are dealing with a normal -> normal binade decrement, since // we have an explicit integral bit the fact that all bits but the @@ -3869,3 +3917,20 @@ APFloat::makeZero(bool Negative) { exponent = semantics->minExponent-1; APInt::tcSet(significandParts(), 0, partCount()); } + +APFloat llvm::scalbn(APFloat X, int Exp) { + if (X.isInfinity() || X.isZero() || X.isNaN()) + return X; + + auto MaxExp = X.getSemantics().maxExponent; + auto MinExp = X.getSemantics().minExponent; + if (Exp > (MaxExp - X.exponent)) + // Overflow saturates to infinity. + return APFloat::getInf(X.getSemantics(), X.isNegative()); + if (Exp < (MinExp - X.exponent)) + // Underflow saturates to zero. + return APFloat::getZero(X.getSemantics(), X.isNegative()); + + X.exponent += Exp; + return X; +}