[libc-commits] [libc] 79a2e2b - [libc][math] Fix `is_quiet_nan` function in FPBits (#76931)
via libc-commits
libc-commits at lists.llvm.org
Thu Jan 4 09:24:57 PST 2024
Author: Nishant Mittal
Date: 2024-01-04T12:24:54-05:00
New Revision: 79a2e2b9e8d0dffa602375c2386371666b412272
URL: https://github.com/llvm/llvm-project/commit/79a2e2b9e8d0dffa602375c2386371666b412272
DIFF: https://github.com/llvm/llvm-project/commit/79a2e2b9e8d0dffa602375c2386371666b412272.diff
LOG: [libc][math] Fix `is_quiet_nan` function in FPBits (#76931)
Added:
Modified:
libc/src/__support/FPUtil/FPBits.h
libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
libc/test/src/__support/FPUtil/fpbits_test.cpp
Removed:
################################################################################
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 63eeba85f15e5c..93e32ba7cc9415 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -162,9 +162,9 @@ struct FPRepBase : public internal::FPLayout<fp_type> {
? bit_at(SIG_LEN - 1) | bit_at(SIG_LEN - 2) // 0b1100...
: bit_at(SIG_LEN - 1); // 0b1000...
- // If a number x is a NAN, then it is a signalling NAN if:
- // SIGNALING_NAN_MASK & bits(x) != 0
- LIBC_INLINE_VAR static constexpr StorageType SIGNALING_NAN_MASK =
+ // Mask to generate a default signaling NAN. Any NAN that is not
+ // a quiet NAN is considered a signaling NAN.
+ LIBC_INLINE_VAR static constexpr StorageType DEFAULT_SIGNALING_NAN =
fp_type == FPType::X86_Binary80
? bit_at(SIG_LEN - 1) | bit_at(SIG_LEN - 3) // 0b1010...
: bit_at(SIG_LEN - 2); // 0b0100...
@@ -356,7 +356,7 @@ template <typename T> struct FPBits : public internal::FPRep<get_fp_type<T>()> {
}
LIBC_INLINE constexpr bool is_quiet_nan() const {
- return (bits & EXP_SIG_MASK) == (EXP_MASK | QUIET_NAN_MASK);
+ return (bits & EXP_SIG_MASK) >= (EXP_MASK | QUIET_NAN_MASK);
}
LIBC_INLINE constexpr bool is_inf_or_nan() const {
diff --git a/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h b/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
index 8abc0c87af0d20..c18abcee77ea50 100644
--- a/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
+++ b/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
@@ -114,6 +114,10 @@ struct FPBits<long double> : public internal::FPRep<FPType::X86_Binary80> {
(get_biased_exponent() != 0 && get_implicit_bit() == 0);
}
+ LIBC_INLINE constexpr bool is_quiet_nan() const {
+ return (bits & EXP_SIG_MASK) >= (EXP_MASK | QUIET_NAN_MASK);
+ }
+
// Methods below this are used by tests.
LIBC_INLINE static constexpr long double zero(bool sign = false) {
diff --git a/libc/test/src/__support/FPUtil/fpbits_test.cpp b/libc/test/src/__support/FPUtil/fpbits_test.cpp
index fa743855c48619..e2dbe248ef2131 100644
--- a/libc/test/src/__support/FPUtil/fpbits_test.cpp
+++ b/libc/test/src/__support/FPUtil/fpbits_test.cpp
@@ -69,6 +69,9 @@ TEST(LlvmLibcFPBitsTest, FloatType) {
EXPECT_EQ(negnum.uintval(), static_cast<uint32_t>(0xBF900000));
EXPECT_STREQ(LIBC_NAMESPACE::str(negnum).c_str(),
"0xBF900000 = (S: 1, E: 0x007F, M: 0x00100000)");
+
+ FloatBits quiet_nan = FloatBits(FloatBits::build_quiet_nan(1));
+ EXPECT_EQ(quiet_nan.is_quiet_nan(), true);
}
TEST(LlvmLibcFPBitsTest, DoubleType) {
@@ -129,6 +132,9 @@ TEST(LlvmLibcFPBitsTest, DoubleType) {
EXPECT_EQ(negnum.uintval(), static_cast<uint64_t>(0xBFF2000000000000));
EXPECT_STREQ(LIBC_NAMESPACE::str(negnum).c_str(),
"0xBFF2000000000000 = (S: 1, E: 0x03FF, M: 0x0002000000000000)");
+
+ DoubleBits quiet_nan = DoubleBits(DoubleBits::build_quiet_nan(1));
+ EXPECT_EQ(quiet_nan.is_quiet_nan(), true);
}
#ifdef LIBC_TARGET_ARCH_IS_X86
@@ -210,6 +216,9 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
LIBC_NAMESPACE::str(negnum).c_str(),
"0x000000000000BFFF9000000000000000 = "
"(S: 1, E: 0x3FFF, I: 1, M: 0x00000000000000001000000000000000)");
+
+ LongDoubleBits quiet_nan = LongDoubleBits(LongDoubleBits::build_quiet_nan(1));
+ EXPECT_EQ(quiet_nan.is_quiet_nan(), true);
}
#else
TEST(LlvmLibcFPBitsTest, LongDoubleType) {
@@ -284,6 +293,9 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) {
EXPECT_STREQ(LIBC_NAMESPACE::str(negnum).c_str(),
"0xBFFF2000000000000000000000000000 = "
"(S: 1, E: 0x3FFF, M: 0x00002000000000000000000000000000)");
+
+ LongDoubleBits quiet_nan = LongDoubleBits(LongDoubleBits::build_quiet_nan(1));
+ EXPECT_EQ(quiet_nan.is_quiet_nan(), true);
#endif
}
#endif
@@ -357,5 +369,8 @@ TEST(LlvmLibcFPBitsTest, Float128Type) {
EXPECT_STREQ(LIBC_NAMESPACE::str(negnum).c_str(),
"0xBFFF2000000000000000000000000000 = "
"(S: 1, E: 0x3FFF, M: 0x00002000000000000000000000000000)");
+
+ Float128Bits quiet_nan = Float128Bits(Float128Bits::build_quiet_nan(1));
+ EXPECT_EQ(quiet_nan.is_quiet_nan(), true);
}
#endif // LIBC_COMPILER_HAS_FLOAT128
More information about the libc-commits
mailing list