[libc-commits] [libc] 14f0c06 - [libc] Fix is_subnormal for Intel Extended Precision (#78592)

via libc-commits libc-commits at lists.llvm.org
Fri Jan 19 00:36:07 PST 2024


Author: Guillaume Chatelet
Date: 2024-01-19T09:36:03+01:00
New Revision: 14f0c06f48aca3e6f015944c88097b404005645e

URL: https://github.com/llvm/llvm-project/commit/14f0c06f48aca3e6f015944c88097b404005645e
DIFF: https://github.com/llvm/llvm-project/commit/14f0c06f48aca3e6f015944c88097b404005645e.diff

LOG: [libc] Fix is_subnormal for Intel Extended Precision (#78592)

Also turn a set of `get_biased_exponent() == 0` into `is_subnormal()`
which is clearer.

Added: 
    

Modified: 
    libc/src/__support/FPUtil/FPBits.h
    libc/src/__support/FPUtil/NormalFloat.h
    libc/src/__support/FPUtil/generic/FMA.h
    libc/src/__support/FPUtil/generic/sqrt.h
    libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h
    libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h
    libc/utils/MPFRWrapper/MPFRUtils.cpp

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 3ee6289b749648..be700285de8285 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -386,8 +386,11 @@ struct FPRepBase : public internal::FPLayout<fp_type> {
     bits = (value & FP_MASK);
   }
 
-  LIBC_INLINE constexpr bool is_zero() const {
-    return (bits & EXP_SIG_MASK) == 0;
+  LIBC_INLINE constexpr bool is_zero() const { return exp_sig_bits() == 0; }
+
+  LIBC_INLINE
+  constexpr bool is_subnormal() const {
+    return exp_bits() == encode(BiasedExponent::BITS_ALL_ZEROES());
   }
 
   LIBC_INLINE constexpr bool is_neg() const { return sign().is_neg(); }
@@ -435,19 +438,11 @@ template <FPType fp_type> struct FPRep : public FPRepBase<fp_type> {
     return exp_sig_bits() ==
            encode(BiasedExponent::BITS_ALL_ONES(), Significand::ZERO());
   }
-  LIBC_INLINE constexpr bool is_zero() const {
-    return exp_sig_bits() ==
-           encode(BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO());
-  }
   LIBC_INLINE constexpr bool is_finite() const {
     return exp_bits() != encode(BiasedExponent::BITS_ALL_ONES());
   }
-  LIBC_INLINE
-  constexpr bool is_subnormal() const {
-    return exp_bits() == encode(BiasedExponent::BITS_ALL_ZEROES());
-  }
   LIBC_INLINE constexpr bool is_normal() const {
-    return is_finite() && !is_subnormal();
+    return is_finite() && !UP::is_subnormal();
   }
 
   LIBC_INLINE static constexpr StorageType zero(Sign sign = Sign::POS) {
@@ -488,7 +483,7 @@ template <FPType fp_type> struct FPRep : public FPRepBase<fp_type> {
   // The function return mantissa with the implicit bit set iff the current
   // value is a valid normal number.
   LIBC_INLINE constexpr StorageType get_explicit_mantissa() {
-    if (is_subnormal())
+    if (UP::is_subnormal())
       return sig_bits();
     return (StorageType(1) << UP::SIG_LEN) | sig_bits();
   }
@@ -550,18 +545,9 @@ struct FPRep<FPType::X86_Binary80> : public FPRepBase<FPType::X86_Binary80> {
     return exp_sig_bits() ==
            encode(BiasedExponent::BITS_ALL_ONES(), Significand::MSB());
   }
-  LIBC_INLINE constexpr bool is_zero() const {
-    return exp_sig_bits() ==
-           encode(BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO());
-  }
   LIBC_INLINE constexpr bool is_finite() const {
     return !is_inf() && !is_nan();
   }
-  LIBC_INLINE
-  constexpr bool is_subnormal() const {
-    return exp_sig_bits() >
-           encode(BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO());
-  }
   LIBC_INLINE constexpr bool is_normal() const {
     const auto exp = exp_bits();
     if (exp == encode(BiasedExponent::BITS_ALL_ZEROES()) ||

diff  --git a/libc/src/__support/FPUtil/NormalFloat.h b/libc/src/__support/FPUtil/NormalFloat.h
index 8b1612e1b47c61..e7abc53ce6129c 100644
--- a/libc/src/__support/FPUtil/NormalFloat.h
+++ b/libc/src/__support/FPUtil/NormalFloat.h
@@ -153,7 +153,7 @@ template <typename T> struct NormalFloat {
     }
 
     // Normalize subnormal numbers.
-    if (bits.get_biased_exponent() == 0) {
+    if (bits.is_subnormal()) {
       unsigned shift = evaluate_normalization_shift(bits.get_mantissa());
       mantissa = StorageType(bits.get_mantissa()) << shift;
       exponent = 1 - FPBits<T>::EXP_BIAS - shift;
@@ -186,7 +186,7 @@ NormalFloat<long double>::init_from_bits(FPBits<long double> bits) {
     return;
   }
 
-  if (bits.get_biased_exponent() == 0) {
+  if (bits.is_subnormal()) {
     if (bits.get_implicit_bit() == 0) {
       // Since we ignore zero value, the mantissa in this case is non-zero.
       int normalization_shift =

diff  --git a/libc/src/__support/FPUtil/generic/FMA.h b/libc/src/__support/FPUtil/generic/FMA.h
index 9c67c645d5243d..6285cac1983d1e 100644
--- a/libc/src/__support/FPUtil/generic/FMA.h
+++ b/libc/src/__support/FPUtil/generic/FMA.h
@@ -104,15 +104,15 @@ template <> LIBC_INLINE double fma<double>(double x, double y, double z) {
   int z_exp = 0;
 
   // Normalize denormal inputs.
-  if (LIBC_UNLIKELY(FPBits(x).get_biased_exponent() == 0)) {
+  if (LIBC_UNLIKELY(FPBits(x).is_subnormal())) {
     x_exp -= 52;
     x *= 0x1.0p+52;
   }
-  if (LIBC_UNLIKELY(FPBits(y).get_biased_exponent() == 0)) {
+  if (LIBC_UNLIKELY(FPBits(y).is_subnormal())) {
     y_exp -= 52;
     y *= 0x1.0p+52;
   }
-  if (LIBC_UNLIKELY(FPBits(z).get_biased_exponent() == 0)) {
+  if (LIBC_UNLIKELY(FPBits(z).is_subnormal())) {
     z_exp -= 52;
     z *= 0x1.0p+52;
   }

diff  --git a/libc/src/__support/FPUtil/generic/sqrt.h b/libc/src/__support/FPUtil/generic/sqrt.h
index f273b678edf527..21ae9d081d3f12 100644
--- a/libc/src/__support/FPUtil/generic/sqrt.h
+++ b/libc/src/__support/FPUtil/generic/sqrt.h
@@ -97,7 +97,7 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> sqrt(T x) {
       StorageType x_mant = bits.get_mantissa();
 
       // Step 1a: Normalize denormal input and append hidden bit to the mantissa
-      if (bits.get_biased_exponent() == 0) {
+      if (bits.is_subnormal()) {
         ++x_exp; // let x_exp be the correct exponent of ONE bit.
         internal::normalize<T>(x_exp, x_mant);
       } else {

diff  --git a/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h b/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h
index 4fe9b49ff41cf0..4f8d136938f56e 100644
--- a/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h
+++ b/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h
@@ -65,7 +65,7 @@ LIBC_INLINE long double sqrt(long double x) {
     // Step 1a: Normalize denormal input
     if (bits.get_implicit_bit()) {
       x_mant |= ONE;
-    } else if (bits.get_biased_exponent() == 0) {
+    } else if (bits.is_subnormal()) {
       normalize(x_exp, x_mant);
     }
 

diff  --git a/libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h b/libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h
index 5f15bac5df77f8..512f5de4e7931a 100644
--- a/libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h
+++ b/libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h
@@ -38,8 +38,7 @@ LIBC_INLINE long double nextafter(long double from, long double to) {
     return to;
 
   // Convert pseudo subnormal number to normal number.
-  if (from_bits.get_implicit_bit() == 1 &&
-      from_bits.get_biased_exponent() == 0) {
+  if (from_bits.get_implicit_bit() == 1 && from_bits.is_subnormal()) {
     from_bits.set_biased_exponent(1);
   }
 

diff  --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp
index fca83c4cdc52f1..b6ca525db6cf74 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.cpp
+++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp
@@ -457,9 +457,9 @@ class MPFRNumber {
     int thisExponent = FPBits<T>(thisAsT).get_exponent();
     int inputExponent = FPBits<T>(input).get_exponent();
     // Adjust the exponents for denormal numbers.
-    if (FPBits<T>(thisAsT).get_biased_exponent() == 0)
+    if (FPBits<T>(thisAsT).is_subnormal())
       ++thisExponent;
-    if (FPBits<T>(input).get_biased_exponent() == 0)
+    if (FPBits<T>(input).is_subnormal())
       ++inputExponent;
 
     if (thisAsT * input < 0 || thisExponent == inputExponent) {
@@ -481,9 +481,9 @@ class MPFRNumber {
     int minExponent = FPBits<T>(min).get_exponent();
     int maxExponent = FPBits<T>(max).get_exponent();
     // Adjust the exponents for denormal numbers.
-    if (FPBits<T>(min).get_biased_exponent() == 0)
+    if (FPBits<T>(min).is_subnormal())
       ++minExponent;
-    if (FPBits<T>(max).get_biased_exponent() == 0)
+    if (FPBits<T>(max).is_subnormal())
       ++maxExponent;
 
     MPFRNumber minMPFR(min);


        


More information about the libc-commits mailing list