[llvm] [clang] [clang-tools-extra] [mlir] [libc] [libc][math] Fix `is_quiet_nan` function in FPBits (PR #76931)

Nishant Mittal via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 4 08:00:21 PST 2024


https://github.com/nishantwrp updated https://github.com/llvm/llvm-project/pull/76931

>From f6244d1599c604f0fc865762e3d5e133228de9a7 Mon Sep 17 00:00:00 2001
From: Nishant Mittal <nishantwrp at google.com>
Date: Thu, 4 Jan 2024 09:52:32 +0000
Subject: [PATCH] [libc][math] Fix  function in FPBits

---
 libc/src/__support/FPUtil/FPBits.h                |  8 ++++----
 libc/src/__support/FPUtil/x86_64/LongDoubleBits.h |  4 ++++
 libc/test/src/__support/FPUtil/fpbits_test.cpp    | 15 +++++++++++++++
 3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 8304b76d3d8ad0..59e0f34fec3f87 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -167,9 +167,9 @@ struct FPBaseMasksAndShifts : 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 =
       UP::ENCODING == internal::FPEncoding::X86_ExtendedPrecision
           ? bit_at(SIG_LEN - 1) | bit_at(SIG_LEN - 3) // 0b1010...
           : bit_at(SIG_LEN - 2);                      // 0b0100...
@@ -376,7 +376,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 4dc5d25e269820..2f0323c7b0d823 100644
--- a/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
+++ b/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
@@ -115,6 +115,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() { return 0.0l; }
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 cfe-commits mailing list