From 18da0c0a287707b2f80880c14d77e4f071aae88d Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Wed, 10 Nov 2021 16:11:18 -0800 Subject: [PATCH] [libc] clean up FPUtil long doubles Add quietNaNMask consts to FloatProperties and make LongDoubleBitsX86 clear the extra bits that aren't set when initializing with an 80 bit long double. Reviewed By: sivachandra, lntue Differential Revision: https://reviews.llvm.org/D113625 --- libc/src/__support/FPUtil/FloatProperties.h | 16 ++++++++++++++++ libc/src/__support/FPUtil/LongDoubleBitsX86.h | 6 +++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/libc/src/__support/FPUtil/FloatProperties.h b/libc/src/__support/FPUtil/FloatProperties.h index ff132ed5dfa5..d8d0fea977d2 100644 --- a/libc/src/__support/FPUtil/FloatProperties.h +++ b/libc/src/__support/FPUtil/FloatProperties.h @@ -80,6 +80,12 @@ template <> struct FloatProperties { FloatProperties::exponentMask; static constexpr uint32_t exponentBias = FloatProperties::exponentBias; + + // If a number x is a NAN, then it is a quiet NAN if: + // QuietNaNMask & bits(x) != 0 + // Else, it is a signalling NAN. + static constexpr BitsType quietNaNMask = + FloatProperties::quietNaNMask; }; #elif defined(SPECIAL_X86_LONG_DOUBLE) // Properties for numbers represented in 80 bits long double on non-Windows x86 @@ -99,6 +105,11 @@ template <> struct FloatProperties { static constexpr BitsType exponentMask = ((BitsType(1) << exponentWidth) - 1) << (mantissaWidth + 1); static constexpr uint32_t exponentBias = 16383; + + // If a number x is a NAN, then it is a quiet NAN if: + // QuietNaNMask & bits(x) != 0 + // Else, it is a signalling NAN. + static constexpr BitsType quietNaNMask = BitsType(1) << (mantissaWidth - 1); }; #else // Properties for numbers represented in 128 bits long double on non x86 @@ -117,6 +128,11 @@ template <> struct FloatProperties { << (exponentWidth + mantissaWidth); static constexpr BitsType exponentMask = ~(signMask | mantissaMask); static constexpr uint32_t exponentBias = 16383; + + // If a number x is a NAN, then it is a quiet NAN if: + // QuietNaNMask & bits(x) != 0 + // Else, it is a signalling NAN. + static constexpr BitsType quietNaNMask = BitsType(1) << (mantissaWidth - 1); }; #endif diff --git a/libc/src/__support/FPUtil/LongDoubleBitsX86.h b/libc/src/__support/FPUtil/LongDoubleBitsX86.h index 1c963b0ac610..77611ad281c6 100644 --- a/libc/src/__support/FPUtil/LongDoubleBitsX86.h +++ b/libc/src/__support/FPUtil/LongDoubleBitsX86.h @@ -89,7 +89,11 @@ template <> union FPBits { template ::Value, int> = 0> - explicit FPBits(XType x) : val(x) {} + explicit FPBits(XType x) : val(x) { + // bits starts uninitialized, and setting it to a long double only + // overwrites the first 80 bits. This clears those upper bits. + bits = bits & ((UIntType(1) << 80) - 1); + } template ::Value, int> = 0>