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][NFC] Rename MANTISSA_WIDTH in FRACTION_LEN #75489

Merged
merged 10 commits into from
Dec 15, 2023

Conversation

gchatelet
Copy link
Contributor

@gchatelet gchatelet commented Dec 14, 2023

This one might be a bit controversial since the terminology has been introduced from the start but I think FRACTION_LEN is a better name here. AFAICT it really is "the number of bits after the decimal dot when the number is in normal form."

MANTISSA_WIDTH is less precise as it's unclear whether we take the leading bit into account.
This patch also renames most of the properties to use the _LEN suffix and fixes useless casts or variables.

@gchatelet gchatelet requested a review from lntue December 14, 2023 16:00
@llvmbot llvmbot added the libc label Dec 14, 2023
@gchatelet gchatelet changed the title [libc][NFC] Rename MANTISSA_WIDTH in FRACTION_BITS [libc][NFC] Rename MANTISSA_WIDTH in FRACTION_BITS Dec 14, 2023
@llvmbot
Copy link
Member

llvmbot commented Dec 14, 2023

@llvm/pr-subscribers-libc

Author: Guillaume Chatelet (gchatelet)

Changes

This one might be a bit controversial since the terminology has been introduced from the start but I think FRACTION_BITS is a better name here. AFAICT it really is "the number of bits after the decimal dot when the number is in normal form."

Mantissa width is less precise as it's unclear whether we take into account the hidden bit for IEEE754 formats.


Patch is 73.77 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/75489.diff

46 Files Affected:

  • (modified) libc/src/__support/FPUtil/FPBits.h (+12-12)
  • (modified) libc/src/__support/FPUtil/FloatProperties.h (+6-8)
  • (modified) libc/src/__support/FPUtil/Hypot.h (+4-4)
  • (modified) libc/src/__support/FPUtil/ManipulationFunctions.h (+1-1)
  • (modified) libc/src/__support/FPUtil/NearestIntegerOperations.h (+8-8)
  • (modified) libc/src/__support/FPUtil/NormalFloat.h (+5-5)
  • (modified) libc/src/__support/FPUtil/dyadic_float.h (+5-5)
  • (modified) libc/src/__support/FPUtil/fpbits_str.h (+1-2)
  • (modified) libc/src/__support/FPUtil/generic/FMA.h (+4-4)
  • (modified) libc/src/__support/FPUtil/generic/FMod.h (+1-1)
  • (modified) libc/src/__support/FPUtil/generic/sqrt.h (+3-3)
  • (modified) libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h (+3-3)
  • (modified) libc/src/__support/FPUtil/x86_64/LongDoubleBits.h (+14-14)
  • (modified) libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h (+8-9)
  • (modified) libc/src/__support/float_to_string.h (+10-8)
  • (modified) libc/src/__support/str_to_float.h (+16-16)
  • (modified) libc/src/math/generic/asinf.cpp (+1-1)
  • (modified) libc/src/math/generic/erff.cpp (+1-1)
  • (modified) libc/src/math/generic/exp.cpp (+2-2)
  • (modified) libc/src/math/generic/exp10.cpp (+2-2)
  • (modified) libc/src/math/generic/exp2.cpp (+2-2)
  • (modified) libc/src/math/generic/exp2f_impl.h (+1-1)
  • (modified) libc/src/math/generic/explogxf.h (+8-8)
  • (modified) libc/src/math/generic/expm1.cpp (+2-2)
  • (modified) libc/src/math/generic/hypotf.cpp (+1-1)
  • (modified) libc/src/math/generic/log1p.cpp (+8-9)
  • (modified) libc/src/math/generic/log1pf.cpp (+1-1)
  • (modified) libc/src/math/generic/powf.cpp (+9-11)
  • (modified) libc/src/math/generic/range_reduction.h (+1-1)
  • (modified) libc/src/math/generic/sincosf.cpp (+1-1)
  • (modified) libc/src/math/generic/tanhf.cpp (+1-1)
  • (modified) libc/src/stdio/printf_core/float_dec_converter.h (+18-18)
  • (modified) libc/src/stdio/printf_core/float_hex_converter.h (+7-7)
  • (modified) libc/test/src/math/FrexpTest.h (+1-1)
  • (modified) libc/test/src/math/LdExpTest.h (+5-5)
  • (modified) libc/test/src/math/LogbTest.h (+1-1)
  • (modified) libc/test/src/math/NextAfterTest.h (+2-4)
  • (modified) libc/test/src/math/RoundToIntegerTest.h (+1-1)
  • (modified) libc/test/src/math/SqrtTest.h (+1-1)
  • (modified) libc/test/src/math/smoke/FrexpTest.h (+1-1)
  • (modified) libc/test/src/math/smoke/LdExpTest.h (+5-5)
  • (modified) libc/test/src/math/smoke/LogbTest.h (+1-1)
  • (modified) libc/test/src/math/smoke/NextAfterTest.h (+2-4)
  • (modified) libc/test/src/math/smoke/NextTowardTest.h (+2-4)
  • (modified) libc/test/src/math/smoke/SqrtTest.h (+1-1)
  • (modified) libc/utils/MPFRWrapper/MPFRUtils.cpp (+3-3)
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index d1e26de22ef13..bbc006dc10eaa 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -37,8 +37,8 @@ template <typename T> struct FPBits : private FloatProperties<T> {
   using FloatProperties<T>::EXPONENT_MASK;
   using FloatProperties<T>::EXPONENT_BIAS;
   using FloatProperties<T>::EXPONENT_WIDTH;
-  using FloatProperties<T>::MANTISSA_MASK;
-  using FloatProperties<T>::MANTISSA_WIDTH;
+  using FloatProperties<T>::FRACTION_MASK;
+  using FloatProperties<T>::FRACTION_BITS;
   using FloatProperties<T>::QUIET_NAN_MASK;
   using FloatProperties<T>::SIGN_MASK;
 
@@ -48,32 +48,32 @@ template <typename T> struct FPBits : private FloatProperties<T> {
   UIntType bits;
 
   LIBC_INLINE constexpr void set_mantissa(UIntType mantVal) {
-    mantVal &= MANTISSA_MASK;
-    bits &= ~MANTISSA_MASK;
+    mantVal &= FRACTION_MASK;
+    bits &= ~FRACTION_MASK;
     bits |= mantVal;
   }
 
   LIBC_INLINE constexpr UIntType get_mantissa() const {
-    return bits & MANTISSA_MASK;
+    return bits & FRACTION_MASK;
   }
 
   LIBC_INLINE constexpr void set_biased_exponent(UIntType expVal) {
-    expVal = (expVal << MANTISSA_WIDTH) & EXPONENT_MASK;
+    expVal = (expVal << FRACTION_BITS) & EXPONENT_MASK;
     bits &= ~EXPONENT_MASK;
     bits |= expVal;
   }
 
   LIBC_INLINE constexpr uint16_t get_biased_exponent() const {
-    return uint16_t((bits & EXPONENT_MASK) >> MANTISSA_WIDTH);
+    return uint16_t((bits & EXPONENT_MASK) >> FRACTION_BITS);
   }
 
   // The function return mantissa with the implicit bit set iff the current
   // value is a valid normal number.
   LIBC_INLINE constexpr UIntType get_explicit_mantissa() {
     return ((get_biased_exponent() > 0 && !is_inf_or_nan())
-                ? (MANTISSA_MASK + 1)
+                ? (FRACTION_MASK + 1)
                 : 0) |
-           (MANTISSA_MASK & bits);
+           (FRACTION_MASK & bits);
   }
 
   LIBC_INLINE constexpr void set_sign(bool signVal) {
@@ -92,10 +92,10 @@ template <typename T> struct FPBits : private FloatProperties<T> {
   static constexpr int MAX_EXPONENT = (1 << EXPONENT_WIDTH) - 1;
 
   static constexpr UIntType MIN_SUBNORMAL = UIntType(1);
-  static constexpr UIntType MAX_SUBNORMAL = (UIntType(1) << MANTISSA_WIDTH) - 1;
-  static constexpr UIntType MIN_NORMAL = (UIntType(1) << MANTISSA_WIDTH);
+  static constexpr UIntType MAX_SUBNORMAL = FRACTION_MASK;
+  static constexpr UIntType MIN_NORMAL = (UIntType(1) << FRACTION_BITS);
   static constexpr UIntType MAX_NORMAL =
-      ((UIntType(MAX_EXPONENT) - 1) << MANTISSA_WIDTH) | MAX_SUBNORMAL;
+      ((UIntType(MAX_EXPONENT) - 1) << FRACTION_BITS) | MAX_SUBNORMAL;
 
   // We don't want accidental type promotions/conversions, so we require exact
   // type match.
diff --git a/libc/src/__support/FPUtil/FloatProperties.h b/libc/src/__support/FPUtil/FloatProperties.h
index 3f7dbdc5af342..9e301fc1cbbeb 100644
--- a/libc/src/__support/FPUtil/FloatProperties.h
+++ b/libc/src/__support/FPUtil/FloatProperties.h
@@ -152,18 +152,16 @@ struct FPProperties : public internal::FPBaseProperties<fp_type> {
           ? bit_at(SIG_BITS - 1) | bit_at(SIG_BITS - 3) // 0b1010...
           : bit_at(SIG_BITS - 2);                       // 0b0100...
 
-  // The number of bits after the decimal dot when the number if in normal form.
+public:
+  LIBC_INLINE_VAR static constexpr uint32_t BIT_WIDTH = TOTAL_BITS;
+  // The number of bits after the decimal dot when the number is in normal form.
   LIBC_INLINE_VAR static constexpr int FRACTION_BITS =
       UP::ENCODING == internal::FPEncoding::X86_ExtendedPrecision ? SIG_BITS - 1
                                                                   : SIG_BITS;
-
-public:
-  LIBC_INLINE_VAR static constexpr uint32_t BIT_WIDTH = TOTAL_BITS;
-  LIBC_INLINE_VAR static constexpr uint32_t MANTISSA_WIDTH = FRACTION_BITS;
   LIBC_INLINE_VAR static constexpr uint32_t MANTISSA_PRECISION =
-      MANTISSA_WIDTH + 1;
-  LIBC_INLINE_VAR static constexpr UIntType MANTISSA_MASK =
-      mask_trailing_ones<UIntType, MANTISSA_WIDTH>();
+      FRACTION_BITS + 1;
+  LIBC_INLINE_VAR static constexpr UIntType FRACTION_MASK =
+      mask_trailing_ones<UIntType, FRACTION_BITS>();
   LIBC_INLINE_VAR static constexpr uint32_t EXPONENT_WIDTH = EXP_BITS;
   LIBC_INLINE_VAR static constexpr int32_t EXPONENT_BIAS = EXP_BIAS;
   LIBC_INLINE_VAR static constexpr UIntType EXPONENT_MASK = EXP_MASK;
diff --git a/libc/src/__support/FPUtil/Hypot.h b/libc/src/__support/FPUtil/Hypot.h
index ad6b72db0524f..4d6b786b1b620 100644
--- a/libc/src/__support/FPUtil/Hypot.h
+++ b/libc/src/__support/FPUtil/Hypot.h
@@ -124,7 +124,7 @@ LIBC_INLINE T hypot(T x, T y) {
   uint16_t y_exp = y_bits.get_biased_exponent();
   uint16_t exp_diff = (x_exp > y_exp) ? (x_exp - y_exp) : (y_exp - x_exp);
 
-  if ((exp_diff >= FPBits_t::MANTISSA_WIDTH + 2) || (x == 0) || (y == 0)) {
+  if ((exp_diff >= FPBits_t::FRACTION_BITS + 2) || (x == 0) || (y == 0)) {
     return abs(x) + abs(y);
   }
 
@@ -148,7 +148,7 @@ LIBC_INLINE T hypot(T x, T y) {
   out_exp = a_exp;
 
   // Add an extra bit to simplify the final rounding bit computation.
-  constexpr UIntType ONE = UIntType(1) << (FPBits_t::MANTISSA_WIDTH + 1);
+  constexpr UIntType ONE = UIntType(1) << (FPBits_t::FRACTION_BITS + 1);
 
   a_mant <<= 1;
   b_mant <<= 1;
@@ -158,7 +158,7 @@ LIBC_INLINE T hypot(T x, T y) {
   if (a_exp != 0) {
     leading_one = ONE;
     a_mant |= ONE;
-    y_mant_width = FPBits_t::MANTISSA_WIDTH + 1;
+    y_mant_width = FPBits_t::FRACTION_BITS + 1;
   } else {
     leading_one = internal::find_leading_one(a_mant, y_mant_width);
     a_exp = 1;
@@ -258,7 +258,7 @@ LIBC_INLINE T hypot(T x, T y) {
     }
   }
 
-  y_new |= static_cast<UIntType>(out_exp) << FPBits_t::MANTISSA_WIDTH;
+  y_new |= static_cast<UIntType>(out_exp) << FPBits_t::FRACTION_BITS;
   return cpp::bit_cast<T>(y_new);
 }
 
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index 51b58ba29bab8..2f22fa2d5baa3 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -130,7 +130,7 @@ LIBC_INLINE T ldexp(T x, int exp) {
   // early. Because the result of the ldexp operation can be a subnormal number,
   // we need to accommodate the (mantissaWidht + 1) worth of shift in
   // calculating the limit.
-  int exp_limit = FPBits<T>::MAX_EXPONENT + FPBits<T>::MANTISSA_WIDTH + 1;
+  int exp_limit = FPBits<T>::MAX_EXPONENT + FPBits<T>::FRACTION_BITS + 1;
   if (exp > exp_limit)
     return bits.get_sign() ? T(FPBits<T>::neg_inf()) : T(FPBits<T>::inf());
 
diff --git a/libc/src/__support/FPUtil/NearestIntegerOperations.h b/libc/src/__support/FPUtil/NearestIntegerOperations.h
index b0ae8d0040ea1..37bdaca7c2515 100644
--- a/libc/src/__support/FPUtil/NearestIntegerOperations.h
+++ b/libc/src/__support/FPUtil/NearestIntegerOperations.h
@@ -36,7 +36,7 @@ LIBC_INLINE T trunc(T x) {
 
   // If the exponent is greater than the most negative mantissa
   // exponent, then x is already an integer.
-  if (exponent >= static_cast<int>(FPBits<T>::MANTISSA_WIDTH))
+  if (exponent >= static_cast<int>(FPBits<T>::FRACTION_BITS))
     return x;
 
   // If the exponent is such that abs(x) is less than 1, then return 0.
@@ -47,7 +47,7 @@ LIBC_INLINE T trunc(T x) {
       return T(0.0);
   }
 
-  int trim_size = FPBits<T>::MANTISSA_WIDTH - exponent;
+  int trim_size = FPBits<T>::FRACTION_BITS - exponent;
   bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size);
   return T(bits);
 }
@@ -65,7 +65,7 @@ LIBC_INLINE T ceil(T x) {
 
   // If the exponent is greater than the most negative mantissa
   // exponent, then x is already an integer.
-  if (exponent >= static_cast<int>(FPBits<T>::MANTISSA_WIDTH))
+  if (exponent >= static_cast<int>(FPBits<T>::FRACTION_BITS))
     return x;
 
   if (exponent <= -1) {
@@ -75,7 +75,7 @@ LIBC_INLINE T ceil(T x) {
       return T(1.0);
   }
 
-  uint32_t trim_size = FPBits<T>::MANTISSA_WIDTH - exponent;
+  uint32_t trim_size = FPBits<T>::FRACTION_BITS - exponent;
   bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size);
   T trunc_value = T(bits);
 
@@ -114,7 +114,7 @@ LIBC_INLINE T round(T x) {
 
   // If the exponent is greater than the most negative mantissa
   // exponent, then x is already an integer.
-  if (exponent >= static_cast<int>(FPBits<T>::MANTISSA_WIDTH))
+  if (exponent >= static_cast<int>(FPBits<T>::FRACTION_BITS))
     return x;
 
   if (exponent == -1) {
@@ -133,7 +133,7 @@ LIBC_INLINE T round(T x) {
       return T(0.0);
   }
 
-  uint32_t trim_size = FPBits<T>::MANTISSA_WIDTH - exponent;
+  uint32_t trim_size = FPBits<T>::FRACTION_BITS - exponent;
   bool half_bit_set =
       bool(bits.get_mantissa() & (UIntType(1) << (trim_size - 1)));
   bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size);
@@ -167,7 +167,7 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) {
 
   // If the exponent is greater than the most negative mantissa
   // exponent, then x is already an integer.
-  if (exponent >= static_cast<int>(FPBits<T>::MANTISSA_WIDTH))
+  if (exponent >= static_cast<int>(FPBits<T>::FRACTION_BITS))
     return x;
 
   if (exponent <= -1) {
@@ -188,7 +188,7 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) {
     }
   }
 
-  uint32_t trim_size = FPBits<T>::MANTISSA_WIDTH - exponent;
+  uint32_t trim_size = FPBits<T>::FRACTION_BITS - exponent;
   FPBits<T> new_bits = bits;
   new_bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size);
   T trunc_value = T(new_bits);
diff --git a/libc/src/__support/FPUtil/NormalFloat.h b/libc/src/__support/FPUtil/NormalFloat.h
index 397a3bb41673b..32ce0e2ab1299 100644
--- a/libc/src/__support/FPUtil/NormalFloat.h
+++ b/libc/src/__support/FPUtil/NormalFloat.h
@@ -32,7 +32,7 @@ template <typename T> struct NormalFloat {
       "NormalFloat template parameter has to be a floating point type.");
 
   using UIntType = typename FPBits<T>::UIntType;
-  static constexpr UIntType ONE = (UIntType(1) << FPBits<T>::MANTISSA_WIDTH);
+  static constexpr UIntType ONE = (UIntType(1) << FPBits<T>::FRACTION_BITS);
 
   // Unbiased exponent value.
   int32_t exponent;
@@ -40,7 +40,7 @@ template <typename T> struct NormalFloat {
   UIntType mantissa;
   // We want |UIntType| to have atleast one bit more than the actual mantissa
   // bit width to accommodate the implicit 1 value.
-  static_assert(sizeof(UIntType) * 8 >= FPBits<T>::MANTISSA_WIDTH + 1,
+  static_assert(sizeof(UIntType) * 8 >= FPBits<T>::FRACTION_BITS + 1,
                 "Bad type for mantissa in NormalFloat.");
 
   bool sign;
@@ -105,7 +105,7 @@ template <typename T> struct NormalFloat {
       unsigned shift = SUBNORMAL_EXPONENT - exponent;
       // Since exponent > subnormalExponent, shift is strictly greater than
       // zero.
-      if (shift <= FPBits<T>::MANTISSA_WIDTH + 1) {
+      if (shift <= FPBits<T>::FRACTION_BITS + 1) {
         // Generate a subnormal number. Might lead to loss of precision.
         // We round to nearest and round halfway cases to even.
         const UIntType shift_out_mask = (UIntType(1) << shift) - 1;
@@ -163,7 +163,7 @@ template <typename T> struct NormalFloat {
 
   LIBC_INLINE unsigned evaluate_normalization_shift(UIntType m) {
     unsigned shift = 0;
-    for (; (ONE & m) == 0 && (shift < FPBits<T>::MANTISSA_WIDTH);
+    for (; (ONE & m) == 0 && (shift < FPBits<T>::FRACTION_BITS);
          m <<= 1, ++shift)
       ;
     return shift;
@@ -222,7 +222,7 @@ template <> LIBC_INLINE NormalFloat<long double>::operator long double() const {
   constexpr int SUBNORMAL_EXPONENT = -LDBits::EXPONENT_BIAS + 1;
   if (exponent < SUBNORMAL_EXPONENT) {
     unsigned shift = SUBNORMAL_EXPONENT - exponent;
-    if (shift <= LDBits::MANTISSA_WIDTH + 1) {
+    if (shift <= LDBits::FRACTION_BITS + 1) {
       // Generate a subnormal number. Might lead to loss of precision.
       // We round to nearest and round halfway cases to even.
       const UIntType shift_out_mask = (UIntType(1) << shift) - 1;
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 5f0d8f49ccf64..da926e78003c0 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -42,10 +42,10 @@ template <size_t Bits> struct DyadicFloat {
 
   template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
   DyadicFloat(T x) {
-    static_assert(FloatProperties<T>::MANTISSA_WIDTH < Bits);
+    static_assert(FloatProperties<T>::FRACTION_BITS < Bits);
     FPBits<T> x_bits(x);
     sign = x_bits.get_sign();
-    exponent = x_bits.get_exponent() - FloatProperties<T>::MANTISSA_WIDTH;
+    exponent = x_bits.get_exponent() - FloatProperties<T>::FRACTION_BITS;
     mantissa = MantissaType(x_bits.get_explicit_mantissa());
     normalize();
   }
@@ -86,7 +86,7 @@ template <size_t Bits> struct DyadicFloat {
   // TODO(lntue): Test or add specialization for x86 long double.
   template <typename T, typename = cpp::enable_if_t<
                             cpp::is_floating_point_v<T> &&
-                                (FloatProperties<T>::MANTISSA_WIDTH < Bits),
+                                (FloatProperties<T>::FRACTION_BITS < Bits),
                             void>>
   explicit operator T() const {
     // TODO(lntue): Do we need to treat signed zeros properly?
@@ -116,7 +116,7 @@ template <size_t Bits> struct DyadicFloat {
 
     T d_hi = FPBits<T>::create_value(sign, exp_hi,
                                      static_cast<output_bits_t>(m_hi) &
-                                         FloatProperties<T>::MANTISSA_MASK)
+                                         FloatProperties<T>::FRACTION_MASK)
                  .get_val();
 
     const MantissaType round_mask = MantissaType(1) << (shift - 1);
@@ -157,7 +157,7 @@ template <size_t Bits> struct DyadicFloat {
     if (LIBC_UNLIKELY(denorm)) {
       // Output is denormal, simply clear the exponent field.
       output_bits_t clear_exp = output_bits_t(exp_hi)
-                                << FloatProperties<T>::MANTISSA_WIDTH;
+                                << FloatProperties<T>::FRACTION_BITS;
       output_bits_t r_bits = FPBits<T>(r).uintval() - clear_exp;
       return FPBits<T>(r_bits).get_val();
     }
diff --git a/libc/src/__support/FPUtil/fpbits_str.h b/libc/src/__support/FPUtil/fpbits_str.h
index 5d0bb6cf1ac4d..f23988cc3a680 100644
--- a/libc/src/__support/FPUtil/fpbits_str.h
+++ b/libc/src/__support/FPUtil/fpbits_str.h
@@ -56,8 +56,7 @@ template <typename T> LIBC_INLINE cpp::string str(fputil::FPBits<T> x) {
   const details::ZeroPaddedHexFmt<uint16_t> exponent(x.get_biased_exponent());
   s += exponent.view();
 
-  if constexpr (cpp::is_same_v<T, long double> &&
-                fputil::FloatProperties<long double>::MANTISSA_WIDTH == 63) {
+  if constexpr (fputil::get_fp_type<T>() == fputil::FPType::X86_Binary80) {
     s += ", I: ";
     s += sign_char(x.get_implicit_bit());
   }
diff --git a/libc/src/__support/FPUtil/generic/FMA.h b/libc/src/__support/FPUtil/generic/FMA.h
index 3c4d943a7c71f..7aed3168ace5a 100644
--- a/libc/src/__support/FPUtil/generic/FMA.h
+++ b/libc/src/__support/FPUtil/generic/FMA.h
@@ -159,10 +159,10 @@ template <> LIBC_INLINE double fma<double>(double x, double y, double z) {
 
   UInt128 prod_mant = x_mant * y_mant << 10;
   int prod_lsb_exp =
-      x_exp + y_exp - (FPBits::EXPONENT_BIAS + 2 * FPBits::MANTISSA_WIDTH + 10);
+      x_exp + y_exp - (FPBits::EXPONENT_BIAS + 2 * FPBits::FRACTION_BITS + 10);
 
   z_mant <<= 64;
-  int z_lsb_exp = z_exp - (FPBits::MANTISSA_WIDTH + 64);
+  int z_lsb_exp = z_exp - (FPBits::FRACTION_BITS + 64);
   bool round_bit = false;
   bool sticky_bits = false;
   bool z_shifted = false;
@@ -268,8 +268,8 @@ template <> LIBC_INLINE double fma<double>(double x, double y, double z) {
   }
 
   // Remove hidden bit and append the exponent field and sign bit.
-  result = (result & FloatProp::MANTISSA_MASK) |
-           (static_cast<uint64_t>(r_exp) << FloatProp::MANTISSA_WIDTH);
+  result = (result & FloatProp::FRACTION_MASK) |
+           (static_cast<uint64_t>(r_exp) << FloatProp::FRACTION_BITS);
   if (prod_sign) {
     result |= FloatProp::SIGN_MASK;
   }
diff --git a/libc/src/__support/FPUtil/generic/FMod.h b/libc/src/__support/FPUtil/generic/FMod.h
index f30586f9d7f34..7f2e9c41ca194 100644
--- a/libc/src/__support/FPUtil/generic/FMod.h
+++ b/libc/src/__support/FPUtil/generic/FMod.h
@@ -236,7 +236,7 @@ class FMod {
     int e_y = sy.get_biased_exponent();
 
     // Most common case where |y| is "very normal" and |x/y| < 2^EXPONENT_WIDTH
-    if (LIBC_LIKELY(e_y > int(FPB::MANTISSA_WIDTH) &&
+    if (LIBC_LIKELY(e_y > int(FPB::FRACTION_BITS) &&
                     e_x - e_y <= int(FPB::EXPONENT_WIDTH))) {
       UIntType m_x = sx.get_explicit_mantissa();
       UIntType m_y = sy.get_explicit_mantissa();
diff --git a/libc/src/__support/FPUtil/generic/sqrt.h b/libc/src/__support/FPUtil/generic/sqrt.h
index cd5ec58bcdbd5..bafea6595506f 100644
--- a/libc/src/__support/FPUtil/generic/sqrt.h
+++ b/libc/src/__support/FPUtil/generic/sqrt.h
@@ -37,7 +37,7 @@ template <typename T>
 LIBC_INLINE void normalize(int &exponent,
                            typename FPBits<T>::UIntType &mantissa) {
   const int shift = cpp::countl_zero(mantissa) -
-                    (8 * sizeof(mantissa) - 1 - FPBits<T>::MANTISSA_WIDTH);
+                    (8 * sizeof(mantissa) - 1 - FPBits<T>::FRACTION_BITS);
   exponent -= shift;
   mantissa <<= shift;
 }
@@ -72,7 +72,7 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> sqrt(T x) {
   } else {
     // IEEE floating points formats.
     using UIntType = typename FPBits<T>::UIntType;
-    constexpr UIntType ONE = UIntType(1) << FPBits<T>::MANTISSA_WIDTH;
+    constexpr UIntType ONE = UIntType(1) << FPBits<T>::FRACTION_BITS;
 
     FPBits<T> bits(x);
 
@@ -148,7 +148,7 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> sqrt(T x) {
       x_exp = ((x_exp >> 1) + FPBits<T>::EXPONENT_BIAS);
 
       y = (y - ONE) |
-          (static_cast<UIntType>(x_exp) << FPBits<T>::MANTISSA_WIDTH);
+          (static_cast<UIntType>(x_exp) << FPBits<T>::FRACTION_BITS);
 
       switch (quick_get_round()) {
       case FE_TONEAREST:
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 46ca796aeb4b6..c1309f3657354 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
@@ -23,7 +23,7 @@ namespace x86 {
 LIBC_INLINE void normalize(int &exponent, UInt128 &mantissa) {
   const unsigned int shift = static_cast<unsigned int>(
       cpp::countl_zero(static_cast<uint64_t>(mantissa)) -
-      (8 * sizeof(uint64_t) - 1 - FPBits<long double>::MANTISSA_WIDTH));
+      (8 * sizeof(uint64_t) - 1 - FPBits<long double>::FRACTION_BITS));
   exponent -= shift;
   mantissa <<= shift;
 }
@@ -38,7 +38,7 @@ LIBC_INLINE long double sqrt(long double x);
 LIBC_INLINE long double sqrt(long double x) {
   using LDBits = FPBits<long double>;
   using UIntType = typename LDBits::UIntType;
-  constexpr UIntType ONE = UIntType(1) << int(LDBits::MANTISSA_WIDTH);
+  constexpr UIntType ONE = UIntType(1) << int(LDBits::FRACTION_BITS);
 
   FPBits<long double> bits(x);
 
@@ -111,7 +111,7 @@ LIBC_INLINE long double sqrt(long double x) {
 
     // Append the exponent field.
     x_exp = ((x_exp >> 1) + LDBits::EXPONENT_BIAS);
-    y |= (static_cast<UIntType>(x_exp) << (LDBits::MANTISSA_WIDTH + 1));
+    y |= (static_cast<UIntType>(x_exp) << (LDBits::FRACTION_BITS + 1));
 
     switch (quick_get_round()) {
     case FE_TONEAREST:
diff --git a/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h b/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
index a31667528be2b..e64c9dad04739 100644
--- a/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
+++ b/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
@@ -33,37 +33,37 @@ template <> struct FPBits<long double> : private FloatProperties<long double> {
   using FloatProperties<long double>::EXPONENT_MASK;
   using FloatProperties<long double>::EXPONENT_BIAS;
   using FloatProperties<long double>::EXPONENT_WIDTH;
-  using FloatProperties<long double>::MANTISSA_MASK;...
[truncated]

@gchatelet
Copy link
Contributor Author

gchatelet commented Dec 14, 2023

I've also substituted a bunch of (UIntType(1) << FPBits::MANTISSA_WIDTH) - 1 with MANTISSA_MASK (or now FRACTION_MASK).

@@ -56,8 +56,7 @@ template <typename T> LIBC_INLINE cpp::string str(fputil::FPBits<T> x) {
const details::ZeroPaddedHexFmt<uint16_t> exponent(x.get_biased_exponent());
s += exponent.view();

if constexpr (cpp::is_same_v<T, long double> &&
fputil::FloatProperties<long double>::MANTISSA_WIDTH == 63) {
if constexpr (fputil::get_fp_type<T>() == fputil::FPType::X86_Binary80) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is now easier to test for the underlying representation of float, double and long double.

using FloatProperties<long double>::MANTISSA_MASK;
using FloatProperties<long double>::MANTISSA_WIDTH;
using FloatProperties<long double>::FRACTION_MASK;
using FloatProperties<long double>::FRACTION_BITS;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My only concern with this terminology is the inconsistency of : BIT_WIDTH, EXPONENT_WIDTH vs FRACTION_BITS

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm willing to change them to:

  • EXPONENT_WIDTH => EXP_BITS - or EXPONENT_BITS if you prefer
  • BIT_WIDTH => TOTAL_BITS - or any other suggestions, I initially thought about FP_BITS but @michaelrj-google rightfully suggested that it would conflict with the FPBits class.

I can do the modification as part of this patch or in another one if you prefer, let me know.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking that using LENGTH instead of WIDTH would make it clearer: BIT_LENGTH or TOTAL_LENGTH, EXPONENT_LENGTH, FRACTION_LENGTH. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it.
How about _LEN to make them shorter? I'm fine with _LENGTH also.

Copy link
Contributor Author

@gchatelet gchatelet Dec 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm but then it doesn't quite work with UINTTYPE_BITS -> UINTTYPE_LENGTH as it's unclear whether we count bits or bytes. _BITS kind of makes it clear what we count.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_LEN SGTM.
One way of resolving the UINTTYPE_BITS that I was thinking is to change UIntType to StorageType and then STORAGE_LEN would make sense. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll give it a try so we can evaluate whether it looks OK or not.

This one might be a bit controversial since the terminology has been introduced from the start but I think `FRACTION_BITS` is a better name here. AFAICT it really is "the number of bits after the decimal dot when the number is in normal form."

Mantissa width is less precise as it's unclear whether we take into account the hidden bit for IEEE754 formats.
@gchatelet gchatelet force-pushed the rename_mantissa_width_in_fraction_bits branch from 64e98e3 to 74b6deb Compare December 15, 2023 09:32
for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
using StorageType = typename FPBits::StorageType;
constexpr StorageType COUNT = 100'000;
constexpr StorageType STEP = StorageType(-1) / COUNT;
Copy link
Contributor Author

@gchatelet gchatelet Dec 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lntue we will need to get rid of these because they don't work with BigInt.
The most general fix seems to be using cpp::numeric_limts<StorageType>::max();, to be done in a follow up patch.

@gchatelet
Copy link
Contributor Author

@lntue

I've made the changes for all of the properties at once.

I've also fixed various things like "unnecessary casts" as individual commits above. You may want to check them but they should all be NFC.

I still kind of like the _BITS suffix better but I'm not opposed to _LEN so it's up to you.
Let me know what you think!

@gchatelet gchatelet requested a review from lntue December 15, 2023 12:46
@gchatelet gchatelet changed the title [libc][NFC] Rename MANTISSA_WIDTH in FRACTION_BITS [libc][NFC] Rename MANTISSA_WIDTH in FRACTION_LEN Dec 15, 2023
Copy link
Contributor

@lntue lntue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for cleaning up all of these!

@gchatelet gchatelet merged commit 3546f4d into llvm:main Dec 15, 2023
3 checks passed
@gchatelet gchatelet deleted the rename_mantissa_width_in_fraction_bits branch December 15, 2023 12:57
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