diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:31:46 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:37:19 +0000 |
commit | e8d8bef961a50d4dc22501cde4fb9fb0be1b2532 (patch) | |
tree | 94f04805f47bb7c59ae29690d8952b6074fff602 /contrib/llvm-project/llvm/lib/Support/APFloat.cpp | |
parent | bb130ff39747b94592cb26d71b7cb097b9a4ea6b (diff) | |
parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/APFloat.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Support/APFloat.cpp | 108 |
1 files changed, 49 insertions, 59 deletions
diff --git a/contrib/llvm-project/llvm/lib/Support/APFloat.cpp b/contrib/llvm-project/llvm/lib/Support/APFloat.cpp index 362595d8f8b1..5dea98ee3993 100644 --- a/contrib/llvm-project/llvm/lib/Support/APFloat.cpp +++ b/contrib/llvm-project/llvm/lib/Support/APFloat.cpp @@ -755,6 +755,7 @@ void IEEEFloat::copySignificand(const IEEEFloat &rhs) { void IEEEFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill) { category = fcNaN; sign = Negative; + exponent = exponentNaN(); integerPart *significand = significandParts(); unsigned numParts = partCount(); @@ -841,7 +842,7 @@ bool IEEEFloat::isSignificandAllOnes() const { // Test if the significand excluding the integral bit is all ones. This allows // us to test for binade boundaries. const integerPart *Parts = significandParts(); - const unsigned PartCount = partCount(); + const unsigned PartCount = partCountForBits(semantics->precision); for (unsigned i = 0; i < PartCount - 1; i++) if (~Parts[i]) return false; @@ -849,8 +850,8 @@ bool IEEEFloat::isSignificandAllOnes() const { // Set the unused high bits to all ones when we compare. const unsigned NumHighBits = PartCount*integerPartWidth - semantics->precision + 1; - assert(NumHighBits <= integerPartWidth && "Can not have more high bits to " - "fill than integerPartWidth"); + assert(NumHighBits <= integerPartWidth && NumHighBits > 0 && + "Can not have more high bits to fill than integerPartWidth"); const integerPart HighBitFill = ~integerPart(0) << (integerPartWidth - NumHighBits); if (~(Parts[PartCount - 1] | HighBitFill)) @@ -863,15 +864,16 @@ bool IEEEFloat::isSignificandAllZeros() const { // Test if the significand excluding the integral bit is all zeros. This // allows us to test for binade boundaries. const integerPart *Parts = significandParts(); - const unsigned PartCount = partCount(); + const unsigned PartCount = partCountForBits(semantics->precision); for (unsigned i = 0; i < PartCount - 1; i++) if (Parts[i]) return false; + // Compute how many bits are used in the final word. const unsigned NumHighBits = PartCount*integerPartWidth - semantics->precision + 1; - assert(NumHighBits <= integerPartWidth && "Can not have more high bits to " + assert(NumHighBits < integerPartWidth && "Can not have more high bits to " "clear than integerPartWidth"); const integerPart HighBitMask = ~integerPart(0) >> NumHighBits; @@ -925,8 +927,7 @@ IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, integerPart value) { IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics) { initialize(&ourSemantics); - category = fcZero; - sign = false; + makeZero(false); } // Delegate to the previous constructor, because later copy constructor may @@ -2242,26 +2243,15 @@ IEEEFloat::opStatus IEEEFloat::convert(const fltSemantics &toSemantics, if (!X86SpecialNan && semantics == &semX87DoubleExtended) APInt::tcSetBit(significandParts(), semantics->precision - 1); - // If we are truncating NaN, it is possible that we shifted out all of the - // set bits in a signalling NaN payload. But NaN must remain NaN, so some - // bit in the significand must be set (otherwise it is Inf). - // This can only happen with sNaN. Set the 1st bit after the quiet bit, - // so that we still have an sNaN. - // FIXME: Set quiet and return opInvalidOp (on convert of any sNaN). - // But this requires fixing LLVM to parse 32-bit hex FP or ignoring - // conversions while parsing IR. - if (APInt::tcIsZero(significandParts(), newPartCount)) { - assert(shift < 0 && "Should not lose NaN payload on extend"); - assert(semantics->precision >= 3 && "Unexpectedly narrow significand"); - assert(*losesInfo && "Missing payload should have set lost info"); - APInt::tcSetBit(significandParts(), semantics->precision - 3); + // Convert of sNaN creates qNaN and raises an exception (invalid op). + // This also guarantees that a sNaN does not become Inf on a truncation + // that loses all payload bits. + if (isSignaling()) { + makeQuiet(); + fs = opInvalidOp; + } else { + fs = opOK; } - - // gcc forces the Quiet bit on, which means (float)(double)(float_sNan) - // does not give you back the same bits. This is dubious, and we - // don't currently do it. You're really supposed to get - // an invalid operation signal at runtime, but nobody does that. - fs = opOK; } else { *losesInfo = false; fs = opOK; @@ -3394,15 +3384,13 @@ void IEEEFloat::initFromF80LongDoubleAPInt(const APInt &api) { sign = static_cast<unsigned int>(i2>>15); if (myexponent == 0 && mysignificand == 0) { - // exponent, significand meaningless - category = fcZero; + makeZero(sign); } else if (myexponent==0x7fff && mysignificand==0x8000000000000000ULL) { - // exponent, significand meaningless - category = fcInfinity; + makeInf(sign); } else if ((myexponent == 0x7fff && mysignificand != 0x8000000000000000ULL) || (myexponent != 0x7fff && myexponent != 0 && myintegerbit == 0)) { - // exponent meaningless category = fcNaN; + exponent = exponentNaN(); significandParts()[0] = mysignificand; significandParts()[1] = 0; } else { @@ -3453,16 +3441,14 @@ void IEEEFloat::initFromQuadrupleAPInt(const APInt &api) { sign = static_cast<unsigned int>(i2>>63); if (myexponent==0 && (mysignificand==0 && mysignificand2==0)) { - // exponent, significand meaningless - category = fcZero; + makeZero(sign); } else if (myexponent==0x7fff && (mysignificand==0 && mysignificand2==0)) { - // exponent, significand meaningless - category = fcInfinity; + makeInf(sign); } else if (myexponent==0x7fff && (mysignificand!=0 || mysignificand2 !=0)) { - // exponent meaningless category = fcNaN; + exponent = exponentNaN(); significandParts()[0] = mysignificand; significandParts()[1] = mysignificand2; } else { @@ -3488,14 +3474,12 @@ void IEEEFloat::initFromDoubleAPInt(const APInt &api) { sign = static_cast<unsigned int>(i>>63); if (myexponent==0 && mysignificand==0) { - // exponent, significand meaningless - category = fcZero; + makeZero(sign); } else if (myexponent==0x7ff && mysignificand==0) { - // exponent, significand meaningless - category = fcInfinity; + makeInf(sign); } else if (myexponent==0x7ff && mysignificand!=0) { - // exponent meaningless category = fcNaN; + exponent = exponentNaN(); *significandParts() = mysignificand; } else { category = fcNormal; @@ -3519,14 +3503,12 @@ void IEEEFloat::initFromFloatAPInt(const APInt &api) { sign = i >> 31; if (myexponent==0 && mysignificand==0) { - // exponent, significand meaningless - category = fcZero; + makeZero(sign); } else if (myexponent==0xff && mysignificand==0) { - // exponent, significand meaningless - category = fcInfinity; + makeInf(sign); } else if (myexponent==0xff && mysignificand!=0) { - // sign, exponent, significand meaningless category = fcNaN; + exponent = exponentNaN(); *significandParts() = mysignificand; } else { category = fcNormal; @@ -3550,14 +3532,12 @@ void IEEEFloat::initFromBFloatAPInt(const APInt &api) { sign = i >> 15; if (myexponent == 0 && mysignificand == 0) { - // exponent, significand meaningless - category = fcZero; + makeZero(sign); } else if (myexponent == 0xff && mysignificand == 0) { - // exponent, significand meaningless - category = fcInfinity; + makeInf(sign); } else if (myexponent == 0xff && mysignificand != 0) { - // sign, exponent, significand meaningless category = fcNaN; + exponent = exponentNaN(); *significandParts() = mysignificand; } else { category = fcNormal; @@ -3581,14 +3561,12 @@ void IEEEFloat::initFromHalfAPInt(const APInt &api) { sign = i >> 15; if (myexponent==0 && mysignificand==0) { - // exponent, significand meaningless - category = fcZero; + makeZero(sign); } else if (myexponent==0x1f && mysignificand==0) { - // exponent, significand meaningless - category = fcInfinity; + makeInf(sign); } else if (myexponent==0x1f && mysignificand!=0) { - // sign, exponent, significand meaningless category = fcNaN; + exponent = exponentNaN(); *significandParts() = mysignificand; } else { category = fcNormal; @@ -4146,17 +4124,29 @@ IEEEFloat::opStatus IEEEFloat::next(bool nextDown) { return result; } +APFloatBase::ExponentType IEEEFloat::exponentNaN() const { + return semantics->maxExponent + 1; +} + +APFloatBase::ExponentType IEEEFloat::exponentInf() const { + return semantics->maxExponent + 1; +} + +APFloatBase::ExponentType IEEEFloat::exponentZero() const { + return semantics->minExponent - 1; +} + void IEEEFloat::makeInf(bool Negative) { category = fcInfinity; sign = Negative; - exponent = semantics->maxExponent + 1; + exponent = exponentInf(); APInt::tcSet(significandParts(), 0, partCount()); } void IEEEFloat::makeZero(bool Negative) { category = fcZero; sign = Negative; - exponent = semantics->minExponent-1; + exponent = exponentZero(); APInt::tcSet(significandParts(), 0, partCount()); } @@ -4884,6 +4874,6 @@ APFloat::opStatus APFloat::convertToInteger(APSInt &result, return status; } -} // End llvm namespace +} // namespace llvm #undef APFLOAT_DISPATCH_ON_SEMANTICS |