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

Revert "[libc][NFC] Refactor FPBits and remove LongDoubleBits specialization (#78192)" #78329

Merged
merged 1 commit into from
Jan 16, 2024

Conversation

nickdesaulniers
Copy link
Member

This reverts commit fdbf255.

Causes build breakage on 32b arm (see reports:
#78192).

These are reproducible for the 32b arm baremetal target on x86 hosts as well.

…ization (llvm#78192)"

This reverts commit fdbf255.

Causes build breakage on 32b arm (see reports:
llvm#78192).

These are reproducible for the 32b arm baremetal target on x86 hosts as well.
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 16, 2024

@llvm/pr-subscribers-libc

Author: Nick Desaulniers (nickdesaulniers)

Changes

This reverts commit fdbf255.

Causes build breakage on 32b arm (see reports:
#78192).

These are reproducible for the 32b arm baremetal target on x86 hosts as well.


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

8 Files Affected:

  • (modified) libc/src/__support/FPUtil/FPBits.h (+91-352)
  • (modified) libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h (+1-1)
  • (added) libc/src/__support/FPUtil/x86_64/LongDoubleBits.h (+179)
  • (modified) libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h (+4-4)
  • (modified) libc/test/src/__support/FPUtil/fpbits_test.cpp (-213)
  • (modified) libc/test/utils/FPUtil/x86_long_double_test.cpp (+6-6)
  • (modified) utils/bazel/llvm-project-overlay/libc/BUILD.bazel (+1)
  • (removed) utils/bazel/llvm-project-overlay/libc/test/src/__support/FPUtil/BUILD.bazel (-42)
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index d6a9f60f71208c..93e32ba7cc9415 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -31,40 +31,6 @@ enum class FPType {
   X86_Binary80,
 };
 
-// The classes hierarchy is as follows:
-//
-//             ┌───────────────────┐
-//             │ FPLayout<FPType>  │
-//             └─────────▲─────────┘
-//                       │
-//             ┌─────────┴─────────┐
-//             │ FPRepBase<FPType> │
-//             └─────────▲─────────┘
-//                       │
-//          ┌────────────┴─────────────┐
-//          │                          │
-// ┌────────┴──────┐     ┌─────────────┴──────────────┐
-// │ FPRep<FPType> │     │ FPRep<FPType::X86_Binary80 │
-// └────────▲──────┘     └─────────────▲──────────────┘
-//          │                          │
-//          └────────────┬─────────────┘
-//                       │
-//                 ┌─────┴─────┐
-//                 │ FPBits<T> │
-//                 └───────────┘
-//
-// - 'FPLayout' defines only a few constants, namely the 'StorageType' and the
-// length of the sign, the exponent and significand parts.
-// - 'FPRepBase' builds more constants on top of those from 'FPLayout' like
-// exponent bias, shifts and masks. It also defines tools to assemble or test
-// these parts.
-// - 'FPRep' defines functions to interact with the floating point
-// representation. The default implementation is the one for 'IEEE754', a
-// specialization is provided for X86 Extended Precision that has a different
-// encoding.
-// - 'FPBits' is templated on the platform floating point types. Contrary to
-// 'FPRep' that is platform agnostic 'FPBits' is architecture dependent.
-
 namespace internal {
 
 // Defines the layout (sign, exponent, significand) of a floating point type in
@@ -166,94 +132,11 @@ struct FPRepBase : public internal::FPLayout<fp_type> {
   static_assert((SIG_MASK & EXP_MASK & SIGN_MASK) == 0, "masks disjoint");
   static_assert((SIG_MASK | EXP_MASK | SIGN_MASK) == FP_MASK, "masks cover");
 
-protected:
+private:
   LIBC_INLINE static constexpr StorageType bit_at(int position) {
     return StorageType(1) << position;
   }
 
-  // An opaque type to store a floating point exponent.
-  // We define special values but it is valid to create arbitrary values as long
-  // as they are in the range [MIN, MAX].
-  enum class Exponent : int32_t {
-    MIN = 1 - EXP_BIAS,
-    ZERO = 0,
-    MAX = EXP_BIAS,
-  };
-
-  // An opaque type to store a floating point biased exponent.
-  // We define special values but it is valid to create arbitrary values as long
-  // as they are in the range [BITS_ALL_ZEROES, BITS_ALL_ONES].
-  // Values greater than BITS_ALL_ONES are truncated.
-  enum class BiasedExponent : uint32_t {
-    // The exponent value for denormal numbers.
-    BITS_ALL_ZEROES = 0,
-    // The exponent value for infinity.
-    BITS_ALL_ONES = 2 * EXP_BIAS + 1,
-  };
-
-  LIBC_INLINE static constexpr BiasedExponent biased(Exponent value) {
-    return static_cast<BiasedExponent>(static_cast<int32_t>(value) + EXP_BIAS);
-  }
-
-  // An opaque type to store a floating point significand.
-  // We define special values but it is valid to create arbitrary values as long
-  // as they are in the range [BITS_ALL_ZEROES, BITS_ALL_ONES].
-  // Note that the semantics of the Significand are implementation dependent.
-  // Values greater than BITS_ALL_ONES are truncated.
-  enum class Significand : StorageType {
-    ZERO = 0,
-    LSB = 1,
-    MSB = bit_at(SIG_LEN - 1),
-    // Aliases
-    BITS_ALL_ZEROES = ZERO,
-    BITS_ALL_ONES = SIG_MASK,
-  };
-
-  template <typename T>
-  LIBC_INLINE static constexpr auto storage_cast(T value) {
-    return static_cast<StorageType>(value);
-  }
-
-  LIBC_INLINE friend constexpr Significand operator|(const Significand a,
-                                                     const Significand b) {
-    return Significand{storage_cast(storage_cast(a) | storage_cast(b))};
-  }
-  LIBC_INLINE friend constexpr Significand operator^(const Significand a,
-                                                     const Significand b) {
-    return Significand{storage_cast(storage_cast(a) ^ storage_cast(b))};
-  }
-  LIBC_INLINE friend constexpr Significand operator>>(const Significand a,
-                                                      int shift) {
-    return Significand{storage_cast(storage_cast(a) >> shift)};
-  }
-
-  LIBC_INLINE static constexpr StorageType encode(BiasedExponent exp) {
-    return (storage_cast(exp) << SIG_LEN) & EXP_MASK;
-  }
-
-  LIBC_INLINE static constexpr StorageType encode(Significand value) {
-    return storage_cast(value) & SIG_MASK;
-  }
-
-  LIBC_INLINE static constexpr StorageType encode(BiasedExponent exp,
-                                                  Significand sig) {
-    return encode(exp) | encode(sig);
-  }
-
-  LIBC_INLINE static constexpr StorageType encode(bool sign, BiasedExponent exp,
-                                                  Significand sig) {
-    if (sign)
-      return SIGN_MASK | encode(exp, sig);
-    return encode(exp, sig);
-  }
-
-  LIBC_INLINE constexpr StorageType exp_bits() const { return bits & EXP_MASK; }
-  LIBC_INLINE constexpr StorageType sig_bits() const { return bits & SIG_MASK; }
-  LIBC_INLINE constexpr StorageType exp_sig_bits() const {
-    return bits & EXP_SIG_MASK;
-  }
-
-private:
   // Merge bits from 'a' and 'b' values according to 'mask'.
   // Use 'a' bits when corresponding 'mask' bits are zeroes and 'b' bits when
   // corresponding bits are ones.
@@ -272,6 +155,20 @@ struct FPRepBase : public internal::FPLayout<fp_type> {
   LIBC_INLINE_VAR static constexpr StorageType FRACTION_MASK =
       mask_trailing_ones<StorageType, FRACTION_LEN>();
 
+  // If a number x is a NAN, then it is a quiet NAN if:
+  //   QUIET_NAN_MASK & bits(x) != 0
+  LIBC_INLINE_VAR static constexpr StorageType QUIET_NAN_MASK =
+      fp_type == FPType::X86_Binary80
+          ? bit_at(SIG_LEN - 1) | bit_at(SIG_LEN - 2) // 0b1100...
+          : bit_at(SIG_LEN - 1);                      // 0b1000...
+
+  // 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...
+
   // The floating point number representation as an unsigned integer.
   StorageType bits = 0;
 
@@ -323,9 +220,6 @@ struct FPRepBase : public internal::FPLayout<fp_type> {
   }
 
   LIBC_INLINE constexpr StorageType uintval() const { return bits & FP_MASK; }
-  LIBC_INLINE constexpr void set_uintval(StorageType value) {
-    bits = (value & FP_MASK);
-  }
 
   LIBC_INLINE constexpr bool is_zero() const {
     return (bits & EXP_SIG_MASK) == 0;
@@ -347,213 +241,6 @@ template <FPType fp_type> struct FPRep : public FPRepBase<fp_type> {
   using UP::FRACTION_LEN;
   using UP::FRACTION_MASK;
   using UP::MANTISSA_PRECISION;
-
-protected:
-  using typename UP::BiasedExponent;
-  using typename UP::Exponent;
-  using typename UP::Significand;
-  using UP::biased;
-  using UP::encode;
-  using UP::exp_bits;
-  using UP::exp_sig_bits;
-  using UP::sig_bits;
-
-public:
-  LIBC_INLINE constexpr bool is_nan() const {
-    return exp_sig_bits() >
-           encode(BiasedExponent::BITS_ALL_ONES, Significand::ZERO);
-  }
-  LIBC_INLINE constexpr bool is_quiet_nan() const {
-    return exp_sig_bits() >=
-           encode(BiasedExponent::BITS_ALL_ONES, Significand::MSB);
-  }
-  LIBC_INLINE constexpr bool is_signaling_nan() const {
-    return is_nan() && !is_quiet_nan();
-  }
-  LIBC_INLINE constexpr bool is_inf() const {
-    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();
-  }
-
-  LIBC_INLINE static constexpr StorageType zero(bool sign = false) {
-    return encode(sign, BiasedExponent::BITS_ALL_ZEROES, Significand::ZERO);
-  }
-  LIBC_INLINE static constexpr StorageType one(bool sign = false) {
-    return encode(sign, biased(Exponent::ZERO), Significand::ZERO);
-  }
-  LIBC_INLINE static constexpr StorageType min_subnormal(bool sign = false) {
-    return encode(sign, BiasedExponent::BITS_ALL_ZEROES, Significand::LSB);
-  }
-  LIBC_INLINE static constexpr StorageType max_subnormal(bool sign = false) {
-    return encode(sign, BiasedExponent::BITS_ALL_ZEROES,
-                  Significand::BITS_ALL_ONES);
-  }
-  LIBC_INLINE static constexpr StorageType min_normal(bool sign = false) {
-    return encode(sign, biased(Exponent::MIN), Significand::ZERO);
-  }
-  LIBC_INLINE static constexpr StorageType max_normal(bool sign = false) {
-    return encode(sign, biased(Exponent::MAX), Significand::BITS_ALL_ONES);
-  }
-  LIBC_INLINE static constexpr StorageType inf(bool sign = false) {
-    return encode(sign, BiasedExponent::BITS_ALL_ONES, Significand::ZERO);
-  }
-  LIBC_INLINE static constexpr StorageType build_nan(bool sign = false,
-                                                     StorageType v = 0) {
-    return encode(sign, BiasedExponent::BITS_ALL_ONES,
-                  (v ? Significand{v} : (Significand::MSB >> 1)));
-  }
-  LIBC_INLINE static constexpr StorageType build_quiet_nan(bool sign = false,
-                                                           StorageType v = 0) {
-    return encode(sign, BiasedExponent::BITS_ALL_ONES,
-                  Significand::MSB | Significand{v});
-  }
-
-  // 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())
-      return sig_bits();
-    return (StorageType(1) << UP::SIG_LEN) | sig_bits();
-  }
-};
-
-// Specialization for the X86 Extended Precision type.
-template <>
-struct FPRep<FPType::X86_Binary80> : public FPRepBase<FPType::X86_Binary80> {
-  using UP = FPRepBase<FPType::X86_Binary80>;
-  using typename UP::StorageType;
-  using UP::FRACTION_LEN;
-  using UP::FRACTION_MASK;
-  using UP::MANTISSA_PRECISION;
-
-protected:
-  using typename UP::BiasedExponent;
-  using typename UP::Significand;
-  using UP::encode;
-
-public:
-  // The x86 80 bit float represents the leading digit of the mantissa
-  // explicitly. This is the mask for that bit.
-  static constexpr StorageType EXPLICIT_BIT_MASK = StorageType(1)
-                                                   << FRACTION_LEN;
-  // The X80 significand is made of an explicit bit and the fractional part.
-  static_assert((EXPLICIT_BIT_MASK & FRACTION_MASK) == 0,
-                "the explicit bit and the fractional part should not overlap");
-  static_assert((EXPLICIT_BIT_MASK | FRACTION_MASK) == SIG_MASK,
-                "the explicit bit and the fractional part should cover the "
-                "whole significand");
-
-  LIBC_INLINE constexpr bool is_nan() const {
-    // Most encoding forms from the table found in
-    // https://en.wikipedia.org/wiki/Extended_precision#x86_extended_precision_format
-    // are interpreted as NaN.
-    // More precisely :
-    // - Pseudo-Infinity
-    // - Pseudo Not a Number
-    // - Signalling Not a Number
-    // - Floating-point Indefinite
-    // - Quiet Not a Number
-    // - Unnormal
-    // This can be reduced to the following logic:
-    if (exp_bits() == encode(BiasedExponent::BITS_ALL_ONES))
-      return !is_inf();
-    if (exp_bits() != encode(BiasedExponent::BITS_ALL_ZEROES))
-      return (sig_bits() & encode(Significand::MSB)) == 0;
-    return false;
-  }
-  LIBC_INLINE constexpr bool is_quiet_nan() const {
-    return exp_sig_bits() >= encode(BiasedExponent::BITS_ALL_ONES,
-                                    Significand::MSB | (Significand::MSB >> 1));
-  }
-  LIBC_INLINE constexpr bool is_signaling_nan() const {
-    return is_nan() && !is_quiet_nan();
-  }
-  LIBC_INLINE constexpr bool is_inf() const {
-    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) ||
-        exp == encode(BiasedExponent::BITS_ALL_ONES))
-      return false;
-    return get_implicit_bit();
-  }
-
-  LIBC_INLINE static constexpr StorageType zero(bool sign = false) {
-    return encode(sign, BiasedExponent::BITS_ALL_ZEROES, Significand::ZERO);
-  }
-  LIBC_INLINE static constexpr StorageType one(bool sign = false) {
-    return encode(sign, biased(Exponent::ZERO), Significand::MSB);
-  }
-  LIBC_INLINE static constexpr StorageType min_subnormal(bool sign = false) {
-    return encode(sign, BiasedExponent::BITS_ALL_ZEROES, Significand::LSB);
-  }
-  LIBC_INLINE static constexpr StorageType max_subnormal(bool sign = false) {
-    return encode(sign, BiasedExponent::BITS_ALL_ZEROES,
-                  Significand::BITS_ALL_ONES ^ Significand::MSB);
-  }
-  LIBC_INLINE static constexpr StorageType min_normal(bool sign = false) {
-    return encode(sign, biased(Exponent::MIN), Significand::MSB);
-  }
-  LIBC_INLINE static constexpr StorageType max_normal(bool sign = false) {
-    return encode(sign, biased(Exponent::MAX), Significand::BITS_ALL_ONES);
-  }
-  LIBC_INLINE static constexpr StorageType inf(bool sign = false) {
-    return encode(sign, BiasedExponent::BITS_ALL_ONES, Significand::MSB);
-  }
-  LIBC_INLINE static constexpr StorageType build_nan(bool sign = false,
-                                                     StorageType v = 0) {
-    return encode(sign, BiasedExponent::BITS_ALL_ONES,
-                  Significand::MSB |
-                      (v ? Significand{v} : (Significand::MSB >> 2)));
-  }
-  LIBC_INLINE static constexpr StorageType build_quiet_nan(bool sign = false,
-                                                           StorageType v = 0) {
-    return encode(sign, BiasedExponent::BITS_ALL_ONES,
-                  Significand::MSB | (Significand::MSB >> 1) | Significand{v});
-  }
-
-  LIBC_INLINE constexpr StorageType get_explicit_mantissa() const {
-    return sig_bits();
-  }
-
-  // The following functions are specific to FPRep<FPType::X86_Binary80>.
-  // TODO: Remove if possible.
-  LIBC_INLINE constexpr bool get_implicit_bit() const {
-    return bits & EXPLICIT_BIT_MASK;
-  }
-
-  LIBC_INLINE constexpr void set_implicit_bit(bool implicitVal) {
-    if (get_implicit_bit() != implicitVal)
-      bits ^= EXPLICIT_BIT_MASK;
-  }
 };
 
 } // namespace internal
@@ -589,29 +276,47 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
     static_assert(cpp::always_false<UnqualT>, "Unsupported type");
 }
 
-// A generic class to represent floating point formats.
+// A generic class to represent single precision, double precision, and quad
+// precision IEEE 754 floating point formats.
 // On most platforms, the 'float' type corresponds to single precision floating
 // point numbers, the 'double' type corresponds to double precision floating
 // point numers, and the 'long double' type corresponds to the quad precision
 // floating numbers. On x86 platforms however, the 'long double' type maps to
-// an x87 floating point format.
+// an x87 floating point format. This format is an IEEE 754 extension format.
+// It is handled as an explicit specialization of this class.
 template <typename T> struct FPBits : public internal::FPRep<get_fp_type<T>()> {
   static_assert(cpp::is_floating_point_v<T>,
                 "FPBits instantiated with invalid type.");
   using UP = internal::FPRep<get_fp_type<T>()>;
-  using Rep = UP;
-  using StorageType = typename UP::StorageType;
 
+private:
+  using UP::EXP_SIG_MASK;
+  using UP::QUIET_NAN_MASK;
+  using UP::SIG_LEN;
+  using UP::SIG_MASK;
+
+public:
+  using StorageType = typename UP::StorageType;
   using UP::bits;
+  using UP::EXP_BIAS;
   using UP::EXP_LEN;
+  using UP::EXP_MASK;
+  using UP::EXP_MASK_SHIFT;
+  using UP::FRACTION_LEN;
+  using UP::FRACTION_MASK;
+  using UP::SIGN_MASK;
+  using UP::TOTAL_LEN;
   using UP::UP;
 
+  using UP::get_biased_exponent;
+  using UP::is_zero;
   // Constants.
   static constexpr int MAX_BIASED_EXPONENT = (1 << EXP_LEN) - 1;
-  static constexpr StorageType MIN_NORMAL = UP::min_normal(false);
-  static constexpr StorageType MAX_NORMAL = UP::max_normal(false);
-  static constexpr StorageType MIN_SUBNORMAL = UP::min_subnormal(false);
-  static constexpr StorageType MAX_SUBNORMAL = UP::max_subnormal(false);
+  static constexpr StorageType MIN_SUBNORMAL = StorageType(1);
+  static constexpr StorageType MAX_SUBNORMAL = FRACTION_MASK;
+  static constexpr StorageType MIN_NORMAL = (StorageType(1) << FRACTION_LEN);
+  static constexpr StorageType MAX_NORMAL =
+      (StorageType(MAX_BIASED_EXPONENT - 1) << SIG_LEN) | SIG_MASK;
 
   // Constructors.
   LIBC_INLINE constexpr FPBits() = default;
@@ -633,56 +338,88 @@ template <typename T> struct FPBits : public internal::FPRep<get_fp_type<T>()> {
 
   LIBC_INLINE constexpr explicit operator T() const { return get_val(); }
 
-  LIBC_INLINE constexpr bool is_inf_or_nan() const { return !UP::is_finite(); }
+  // 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() {
+    return ((get_biased_exponent() > 0 && !is_inf_or_nan())
+                ? (FRACTION_MASK + 1)
+                : 0) |
+           (FRACTION_MASK & bits);
+  }
+
+  LIBC_INLINE constexpr bool is_inf() const {
+    return (bits & EXP_SIG_MASK) == EXP_MASK;
+  }
+
+  LIBC_INLINE constexpr bool is_nan() const {
+    return (bits & EXP_SIG_MASK) > EXP_MASK;
+  }
+
+  LIBC_INLINE constexpr bool is_quiet_nan() const {
+    return (bits & EXP_SIG_MASK) >= (EXP_MASK | QUIET_NAN_MASK);
+  }
+
+  LIBC_INLINE constexpr bool is_inf_or_nan() const {
+    return (bits & EXP_MASK) == EXP_MASK;
+  }
 
   LIBC_INLINE constexpr FPBits abs() const {
-    return FPBits(bits & UP::EXP_SIG_MASK);
+    return FPBits(bits & EXP_SIG_MASK);
   }
 
   // Methods below this are used by tests.
 
   LIBC_INLINE static constexpr T zero(bool sign = false) {
-    return FPBits(UP::zero(sign)).get_val();
+    StorageType rep = (sign ? SIGN_MASK : StorageType(0)) // sign
+                      | 0                                 // exponent
+                      | 0;                                // mantissa
+    return FPBits(rep).get_val();
   }
 
   LIBC_INLINE static constexpr T neg_zero() { return zero(true); }
 
   LIBC_INLINE static constexpr T inf(bool sign = false) {
-    return FPBits(UP::inf(sign)).get_val();
+    StorageType rep = (sign ? SIGN_MASK : StorageType(0)) // sign
+                      | EXP_MASK                          // exponent
+                      | 0;                                // mantissa
+    return FPBits(rep).get_val();
   }
 
   LIBC_INLINE static constexpr T neg_inf() { return inf(true); }
 
   LIBC_INLINE static constexpr T min_normal() {
-    return FPBits(UP::min_normal(false)).get_val();
+    return FPBits(MIN_NORMAL).get_val();
   }
 
   LIBC_INLINE static constexpr T max_normal() {
-    return FPBits(UP::max_normal(false)).get_val();
+    return FPBits(MAX_NORMAL).get_val();
   }
 
   LIBC_INLINE static constexpr T min_denormal() {
-    return FPBits(UP::min_subnormal(false)).get_val();
+    re...
[truncated]

@nickdesaulniers
Copy link
Member Author

https://lab.llvm.org/buildbot/#/builders/98/builds/31617 the fuchsia build bot is also broken for 32b arm

@nickdesaulniers nickdesaulniers merged commit 337b771 into llvm:main Jan 16, 2024
5 checks passed
@nickdesaulniers nickdesaulniers deleted the fix_fpbits_arm branch January 16, 2024 20:10
MaheshRavishankar added a commit to iree-org/iree that referenced this pull request Jan 23, 2024
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
…ization (llvm#78192)" (llvm#78329)

This reverts commit fdbf255.

Causes build breakage on 32b arm (see reports:
llvm#78192).

These are reproducible for the 32b arm baremetal target on x86 hosts as
well.
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.

None yet

3 participants