Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libc] Fix is_subnormal for Intel Extended Precision #78592

Merged
merged 2 commits into from
Jan 19, 2024

Conversation

gchatelet
Copy link
Contributor

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

Also turn a set of `get_biased_exponent() == 0` into `is_subnormal()` which is clearer.
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 18, 2024

@llvm/pr-subscribers-libc

Author: Guillaume Chatelet (gchatelet)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/78592.diff

7 Files Affected:

  • (modified) libc/src/__support/FPUtil/FPBits.h (+1-2)
  • (modified) libc/src/__support/FPUtil/NormalFloat.h (+2-2)
  • (modified) libc/src/__support/FPUtil/generic/FMA.h (+3-3)
  • (modified) libc/src/__support/FPUtil/generic/sqrt.h (+1-1)
  • (modified) libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h (+1-1)
  • (modified) libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h (+1-1)
  • (modified) libc/utils/MPFRWrapper/MPFRUtils.cpp (+4-4)
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 3ee6289b749648..e6c0f91c878f75 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -559,8 +559,7 @@ struct FPRep<FPType::X86_Binary80> : public FPRepBase<FPType::X86_Binary80> {
   }
   LIBC_INLINE
   constexpr bool is_subnormal() const {
-    return exp_sig_bits() >
-           encode(BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO());
+    return exp_bits() == encode(BiasedExponent::BITS_ALL_ZEROES());
   }
   LIBC_INLINE constexpr bool is_normal() const {
     const auto exp = exp_bits();
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..6e3cc1d1834d79 100644
--- a/libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h
+++ b/libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h
@@ -39,7 +39,7 @@ LIBC_INLINE long double nextafter(long double from, long double to) {
 
   // Convert pseudo subnormal number to normal number.
   if (from_bits.get_implicit_bit() == 1 &&
-      from_bits.get_biased_exponent() == 0) {
+      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);

Copy link

github-actions bot commented Jan 18, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

libc/src/__support/FPUtil/FPBits.h Outdated Show resolved Hide resolved
@gchatelet gchatelet merged commit 14f0c06 into llvm:main Jan 19, 2024
4 checks passed
@gchatelet gchatelet deleted the fix_is_subnormal branch January 19, 2024 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants