[libc-commits] [libc] [libc] Float80 Emulation in LLVM libc (PR #214447)

via libc-commits libc-commits at lists.llvm.org
Sat Aug 22 04:55:27 PDT 2026


https://github.com/Sukumarsawant updated https://github.com/llvm/llvm-project/pull/214447

>From bd318c1c3016cf788543c902c2eafcd701ddee00 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 23 Jul 2026 00:10:21 +0530
Subject: [PATCH 01/17] initial temp skeleton

---
 .../CPP/type_traits/is_floating_point.h       |   4 +-
 libc/src/__support/FPUtil/CMakeLists.txt      |  18 ++
 libc/src/__support/FPUtil/FPBits.h            |   2 +
 libc/src/__support/FPUtil/float80.h           | 161 ++++++++++++++++++
 libc/src/__support/macros/properties/types.h  |   9 +
 libc/test/src/__support/FPUtil/CMakeLists.txt |  12 ++
 .../src/__support/FPUtil/float80_test.cpp     |  19 +++
 7 files changed, 224 insertions(+), 1 deletion(-)
 create mode 100644 libc/src/__support/FPUtil/float80.h
 create mode 100644 libc/test/src/__support/FPUtil/float80_test.cpp

diff --git a/libc/src/__support/CPP/type_traits/is_floating_point.h b/libc/src/__support/CPP/type_traits/is_floating_point.h
index b8c3bf05b4ebb..82a4ede7124c6 100644
--- a/libc/src/__support/CPP/type_traits/is_floating_point.h
+++ b/libc/src/__support/CPP/type_traits/is_floating_point.h
@@ -44,7 +44,9 @@ template <typename T> struct is_floating_point {
                               bfloat16
 
                               ,
-                              fputil::Float128>();
+                              fputil::Float128,
+
+                              fputil::Float80>();
 };
 template <typename T>
 LIBC_INLINE_VAR constexpr bool is_floating_point_v =
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index 4673ef794c80b..96fbb6d80a669 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -313,4 +313,22 @@ add_header_library(
     libc.src.__support.uint128
 )
 
+add_header_library(
+  float80
+  HDRS
+    float80.h
+  DEPENDS
+    .cast
+    .comparison_operations
+    .dyadic_float
+    libc.hdr.stdint_proxy
+    libc.src.__support.CPP.type_traits
+    libc.src.__support.FPUtil.generic.add_sub
+    libc.src.__support.FPUtil.generic.div
+    libc.src.__support.FPUtil.generic.mul
+    libc.src.__support.macros.attributes
+    libc.src.__support.macros.config
+    libc.src.__support.uint128
+)
+
 add_subdirectory(generic)
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 0a7aee7ae232e..deeca3b082b70 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -816,6 +816,8 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
     return FPType::BFloat16;
   else if constexpr (cpp::is_same_v<UnqualT, Float128>)
     return FPType::IEEE754_Binary128;
+  else if constexpr (cpp::is_same_v<UnqualT, Float80>)
+    return FPType::IEEE754_Binary128;
   else
     static_assert(cpp::always_false<UnqualT>, "Unsupported type");
 }
diff --git a/libc/src/__support/FPUtil/float80.h b/libc/src/__support/FPUtil/float80.h
new file mode 100644
index 0000000000000..edd63aab47ba7
--- /dev/null
+++ b/libc/src/__support/FPUtil/float80.h
@@ -0,0 +1,161 @@
+//===-- Definition for Float80 data type -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT80_H
+#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT80_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/comparison_operations.h"
+#include "src/__support/FPUtil/dyadic_float.h"
+#include "src/__support/FPUtil/generic/add_sub.h"
+#include "src/__support/FPUtil/generic/div.h"
+#include "src/__support/FPUtil/generic/mul.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/uint128.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+
+struct Float80 {
+  UInt128 bits;
+
+  LIBC_INLINE Float80() = default;
+  LIBC_INLINE constexpr Float80(const Float80 &) = default;
+  LIBC_INLINE constexpr Float80(Float80 &&) = default;
+  LIBC_INLINE constexpr Float80 &operator=(const Float80 &) = default;
+  LIBC_INLINE constexpr Float80 &operator=(Float80 &&) = default;
+
+  // Floating point type and integer type
+  template <typename T>
+  LIBC_INLINE constexpr explicit Float80(T value) : bits(0U) {
+    if constexpr (cpp::is_floating_point_v<T>) {
+      bits = fputil::cast<Float80>(value).bits;
+    } else if constexpr (cpp::is_integral_v<T>) {
+      Sign sign = Sign::POS;
+      auto unsigned_value = static_cast<cpp::make_unsigned_t<T>>(value);
+
+      if constexpr (cpp::is_signed_v<T>) {
+        if (value < 0) {
+          sign = Sign::NEG;
+          unsigned_value = -unsigned_value;
+        }
+      }
+
+      fputil::DyadicFloat<FPBits<Float80>::STORAGE_LEN> xd(sign, 0,
+                                                           unsigned_value);
+      bits = xd.template as<Float80, /*ShouldSignalExceptions=*/true>().bits;
+
+    } else if constexpr (cpp::is_convertible_v<T, Float80>) {
+      bits = value.operator Float80().bits;
+    } else {
+      bits = fputil::cast<Float80>(static_cast<float>(value)).bits;
+    }
+  }
+
+  template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T> &&
+                                             !cpp::is_same_v<T, Float80>,
+                                         int> = 0>
+  LIBC_INLINE LIBC_CONSTEXPR_DEFAULT operator T() const {
+    return fputil::cast<T>(*this);
+  }
+
+  template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0>
+  LIBC_INLINE constexpr explicit operator T() const {
+    FPBits<Float80> x_bits(*this);
+    // Raise FE_INVALID for inf and NaN
+    if (x_bits.is_inf_or_nan()) {
+      raise_except_if_required(FE_INVALID);
+    }
+    int x_bits_exp =
+        x_bits.get_explicit_exponent() - FPBits<Float80>::FRACTION_LEN;
+    // sign * 2^(exp-bias) * mantissa
+    DyadicFloat<FPBits<Float80>::STORAGE_LEN> xd(
+        x_bits.sign(), x_bits_exp, x_bits.get_explicit_mantissa());
+    return static_cast<T>(xd.as_mantissa_type());
+  }
+
+  // unary
+  LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR Float80 operator-() const {
+    fputil::FPBits<Float80> result(*this);
+    result.set_sign(result.is_pos() ? Sign::NEG : Sign::POS);
+    return result.get_val();
+  }
+  // operator overloads
+  LIBC_INLINE constexpr Float80 operator+(const Float80 &other) const {
+    return fputil::generic::add<Float80>(*this, other);
+  }
+
+  LIBC_INLINE constexpr Float80 operator-(const Float80 &other) const {
+    return fputil::generic::sub<Float80>(*this, other);
+  }
+
+  LIBC_INLINE constexpr Float80 operator*(const Float80 &other) const {
+    return fputil::generic::mul<Float80>(*this, other);
+  }
+
+  LIBC_INLINE constexpr Float80 operator/(const Float80 &other) const {
+    return fputil::generic::div<Float80>(*this, other);
+  }
+
+  LIBC_INLINE constexpr Float80 &operator*=(const Float80 &other) {
+    *this = *this * other;
+    return *this;
+  }
+
+  LIBC_INLINE constexpr Float80 &operator+=(const Float80 &other) {
+    *this = *this + other;
+    return *this;
+  }
+
+  LIBC_INLINE constexpr Float80 &operator-=(const Float80 &other) {
+    *this = *this - other;
+    return *this;
+  }
+
+  LIBC_INLINE constexpr Float80 &operator/=(const Float80 &other) {
+    *this = *this / other;
+    return *this;
+  }
+
+  LIBC_INLINE constexpr bool operator==(const Float80 &other) const {
+    return fputil::equals(*this, other);
+  }
+
+  LIBC_INLINE constexpr bool operator!=(const Float80 &other) const {
+    return !fputil::equals(*this, other);
+  }
+
+  LIBC_INLINE constexpr bool operator<(const Float80 &other) const {
+    return fputil::less_than(*this, other);
+  }
+
+  LIBC_INLINE constexpr bool operator<=(const Float80 &other) const {
+    return fputil::less_than_or_equals(*this, other);
+  }
+
+  LIBC_INLINE constexpr bool operator>(const Float80 &other) const {
+    return fputil::greater_than(*this, other);
+  }
+
+  LIBC_INLINE constexpr bool operator>=(const Float80 &other) const {
+    return fputil::greater_than_or_equals(*this, other);
+  }
+};
+
+static_assert(LIBC_NAMESPACE::cpp::is_trivially_constructible<
+              LIBC_NAMESPACE::fputil::Float80>::value);
+static_assert(LIBC_NAMESPACE::cpp::is_trivially_copyable<
+              LIBC_NAMESPACE::fputil::Float80>::value);
+
+} // namespace fputil
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_Float80_H
diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index ec42b2ef033a6..65e897dbb841a 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -93,6 +93,15 @@ struct Float128;
 // TODO: Commented till we modify all required functions to support emulated
 // Float128.
 
+// -- Emulated float80 support ------------------------------------------------
+
+namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+struct Float80;
+}
+} // namespace LIBC_NAMESPACE_DECL
+using float128 = LIBC_NAMESPACE::fputil::Float128;
+
 // -- bfloat16 support ---------------------------------------------------------
 
 namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/test/src/__support/FPUtil/CMakeLists.txt b/libc/test/src/__support/FPUtil/CMakeLists.txt
index 87fd10aaacd90..b5d9ca2331697 100644
--- a/libc/test/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/test/src/__support/FPUtil/CMakeLists.txt
@@ -52,6 +52,18 @@ add_fp_unittest(
     libc.src.__support.macros.properties.types
 )
 
+add_fp_unittest(
+  float80_test
+  SUITE
+    libc-fputil-tests
+  SRCS
+    float80_test.cpp
+  DEPENDS
+    libc.hdr.limits_macros
+    libc.src.__support.FPUtil.fenv_impl
+    libc.src.__support.FPUtil.float80
+)
+
 # TODO: Temporally disable bfloat16 test until MPCommon target is updated
 # https://github.com/llvm/llvm-project/pull/149678
 if(LLVM_LIBC_FULL_BUILD)
diff --git a/libc/test/src/__support/FPUtil/float80_test.cpp b/libc/test/src/__support/FPUtil/float80_test.cpp
new file mode 100644
index 0000000000000..c7245fa45cd1a
--- /dev/null
+++ b/libc/test/src/__support/FPUtil/float80_test.cpp
@@ -0,0 +1,19 @@
+//===-- Unittests for Float80 emulated type ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/limits_macros.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/float80.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LIBC_NAMESPACE::Sign;
+using LIBC_NAMESPACE::fputil::Float80;
+using FPBits = LIBC_NAMESPACE::fputil::FPBits<Float80>;
+
+TEST(LlvmLibcFloat80Test, temp) { Float80 a(1.0f); }

>From 1c2b7b4ce375a5868d1ac76edc6e26d011ae6e8a Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 23 Jul 2026 00:15:36 +0530
Subject: [PATCH 02/17] nit

---
 libc/src/__support/macros/properties/types.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index 65e897dbb841a..ddf7294ab15ea 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -100,7 +100,7 @@ namespace fputil {
 struct Float80;
 }
 } // namespace LIBC_NAMESPACE_DECL
-using float128 = LIBC_NAMESPACE::fputil::Float128;
+using float80 = LIBC_NAMESPACE::fputil::Float80;
 
 // -- bfloat16 support ---------------------------------------------------------
 

>From 2c1b7d6d0bcc3fe9429f45af69fb3d34753a1666 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 30 Jul 2026 20:30:14 +0530
Subject: [PATCH 03/17] Removed temporarliy for 128bit container only

---
 libc/src/__support/FPUtil/FPBits.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index deeca3b082b70..95002155324e8 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -127,11 +127,11 @@ template <> struct FPLayout<FPType::IEEE754_Binary128> {
 };
 
 template <> struct FPLayout<FPType::X86_Binary80> {
-#if __SIZEOF_LONG_DOUBLE__ == 12
-  using StorageType = UInt<__SIZEOF_LONG_DOUBLE__ * CHAR_BIT>;
-#else
+// #if __SIZEOF_LONG_DOUBLE__ == 12
+//   using StorageType = UInt<__SIZEOF_LONG_DOUBLE__ * CHAR_BIT>;
+// #else
   using StorageType = UInt128;
-#endif
+// #endif
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
   LIBC_INLINE_VAR static constexpr int EXP_LEN = 15;
   LIBC_INLINE_VAR static constexpr int SIG_LEN = 64;

>From 58eb829bbebe246f2220a2b35292de75ca38ce83 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 30 Jul 2026 20:36:32 +0530
Subject: [PATCH 04/17] test

---
 libc/src/__support/FPUtil/FPBits.h       | 8 ++++----
 libc/src/__support/FPUtil/dyadic_float.h | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 95002155324e8..694665346ac60 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -127,11 +127,11 @@ template <> struct FPLayout<FPType::IEEE754_Binary128> {
 };
 
 template <> struct FPLayout<FPType::X86_Binary80> {
-// #if __SIZEOF_LONG_DOUBLE__ == 12
-//   using StorageType = UInt<__SIZEOF_LONG_DOUBLE__ * CHAR_BIT>;
-// #else
+  // #if __SIZEOF_LONG_DOUBLE__ == 12
+  //   using StorageType = UInt<__SIZEOF_LONG_DOUBLE__ * CHAR_BIT>;
+  // #else
   using StorageType = UInt128;
-// #endif
+  // #endif
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
   LIBC_INLINE_VAR static constexpr int EXP_LEN = 15;
   LIBC_INLINE_VAR static constexpr int SIG_LEN = 64;
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 2effcfcb4a34d..12a2753c796d5 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -438,7 +438,8 @@ template <size_t Bits> struct DyadicFloat {
                                             (FPBits<T>::FRACTION_LEN < Bits),
                                         void>>
   LIBC_INLINE LIBC_CONSTEXPR_DEFAULT T as() const {
-    if constexpr (cpp::is_same_v<T, bfloat16> || cpp::is_same_v<T, Float128>
+    if constexpr (cpp::is_same_v<T, bfloat16> || cpp::is_same_v<T, Float128> ||
+                  cpp::is_same_v<T, Float80>
 #if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
                   || cpp::is_same_v<T, float16>
 #endif

>From 13fcf9011eb0747b04b1dca236f10aff13659620 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 6 Aug 2026 13:10:13 +0530
Subject: [PATCH 05/17] nit

---
 libc/src/__support/FPUtil/FPBits.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 694665346ac60..d2b875e896233 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -127,11 +127,11 @@ template <> struct FPLayout<FPType::IEEE754_Binary128> {
 };
 
 template <> struct FPLayout<FPType::X86_Binary80> {
-  // #if __SIZEOF_LONG_DOUBLE__ == 12
-  //   using StorageType = UInt<__SIZEOF_LONG_DOUBLE__ * CHAR_BIT>;
-  // #else
+  #if __SIZEOF_LONG_DOUBLE__ == 12
+    using StorageType = UInt<__SIZEOF_LONG_DOUBLE__ * CHAR_BIT>;
+  #else
   using StorageType = UInt128;
-  // #endif
+  #endif
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
   LIBC_INLINE_VAR static constexpr int EXP_LEN = 15;
   LIBC_INLINE_VAR static constexpr int SIG_LEN = 64;
@@ -817,7 +817,7 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
   else if constexpr (cpp::is_same_v<UnqualT, Float128>)
     return FPType::IEEE754_Binary128;
   else if constexpr (cpp::is_same_v<UnqualT, Float80>)
-    return FPType::IEEE754_Binary128;
+    return FPType::IEEE754_Binary80;
   else
     static_assert(cpp::always_false<UnqualT>, "Unsupported type");
 }

>From 7b5224438e6bdb5cd96f1f1859e1e1ae155af3a0 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 6 Aug 2026 13:15:10 +0530
Subject: [PATCH 06/17] formatting

---
 libc/src/__support/FPUtil/FPBits.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index d2b875e896233..6127dede03f4a 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -127,11 +127,11 @@ template <> struct FPLayout<FPType::IEEE754_Binary128> {
 };
 
 template <> struct FPLayout<FPType::X86_Binary80> {
-  #if __SIZEOF_LONG_DOUBLE__ == 12
-    using StorageType = UInt<__SIZEOF_LONG_DOUBLE__ * CHAR_BIT>;
-  #else
+#if __SIZEOF_LONG_DOUBLE__ == 12
+  using StorageType = UInt<__SIZEOF_LONG_DOUBLE__ * CHAR_BIT>;
+#else
   using StorageType = UInt128;
-  #endif
+#endif
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
   LIBC_INLINE_VAR static constexpr int EXP_LEN = 15;
   LIBC_INLINE_VAR static constexpr int SIG_LEN = 64;
@@ -817,7 +817,7 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
   else if constexpr (cpp::is_same_v<UnqualT, Float128>)
     return FPType::IEEE754_Binary128;
   else if constexpr (cpp::is_same_v<UnqualT, Float80>)
-    return FPType::IEEE754_Binary80;
+    return FPType::X86_Binary80;
   else
     static_assert(cpp::always_false<UnqualT>, "Unsupported type");
 }

>From 449a364acd8d1c48ec2c25805e9be1d490dfdf82 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 6 Aug 2026 13:24:45 +0530
Subject: [PATCH 07/17] add fputiL::cast support

---
 libc/src/__support/FPUtil/cast.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libc/src/__support/FPUtil/cast.h b/libc/src/__support/FPUtil/cast.h
index 4fc5ea0893ebe..2a9bfd5a9f62e 100644
--- a/libc/src/__support/FPUtil/cast.h
+++ b/libc/src/__support/FPUtil/cast.h
@@ -33,7 +33,9 @@ cast(InType x) {
     if constexpr (cpp::is_same_v<OutType, bfloat16> ||
                   cpp::is_same_v<InType, bfloat16> ||
                   cpp::is_same_v<OutType, Float128> ||
-                  cpp::is_same_v<InType, Float128>
+                  cpp::is_same_v<InType, Float128> ||
+                  cpp::is_same_v<OutType, Float80> ||
+                  cpp::is_same_v<InType, Float80>
 #if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
                   || cpp::is_same_v<OutType, float16> ||
                   cpp::is_same_v<InType, float16>

>From 4ae7902b1c5d581565c61f048220d8f898fd889b Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 6 Aug 2026 15:50:02 +0530
Subject: [PATCH 08/17] feat: add tests

---
 libc/src/__support/FPUtil/float80.h           | 85 ++++---------------
 .../src/__support/FPUtil/float80_test.cpp     | 59 +++++++++++++
 2 files changed, 75 insertions(+), 69 deletions(-)

diff --git a/libc/src/__support/FPUtil/float80.h b/libc/src/__support/FPUtil/float80.h
index edd63aab47ba7..d6823f7bedb76 100644
--- a/libc/src/__support/FPUtil/float80.h
+++ b/libc/src/__support/FPUtil/float80.h
@@ -69,85 +69,32 @@ struct Float80 {
 
   template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0>
   LIBC_INLINE constexpr explicit operator T() const {
+    constexpr T MIN_T = cpp::numeric_limits<T>::min();
+    constexpr T MAX_T = cpp::numeric_limits<T>::max();
     FPBits<Float80> x_bits(*this);
     // Raise FE_INVALID for inf and NaN
     if (x_bits.is_inf_or_nan()) {
       raise_except_if_required(FE_INVALID);
+      return x_bits.is_neg() ? MIN_T : MAX_T;
     }
-    int x_bits_exp =
-        x_bits.get_explicit_exponent() - FPBits<Float80>::FRACTION_LEN;
+    int exponent = x_bits.get_explicit_exponent();
+    constexpr int EXPONENT_LIMIT = cpp::numeric_limits<T>::digits;
+    if (exponent > EXPONENT_LIMIT) {
+      raise_except_if_required(FE_INVALID);
+      return x_bits.is_neg() ? MIN_T : MAX_T;
+    } else if (exponent == EXPONENT_LIMIT) {
+      if (x_bits.is_pos() || x_bits.get_mantissa() != 0) {
+        raise_except_if_required(FE_INVALID);
+        return x_bits.is_neg() ? MIN_T : MAX_T;
+      }
+    }
+
+    int x_bits_exp = exponent - FPBits<Float80>::FRACTION_LEN;
     // sign * 2^(exp-bias) * mantissa
     DyadicFloat<FPBits<Float80>::STORAGE_LEN> xd(
         x_bits.sign(), x_bits_exp, x_bits.get_explicit_mantissa());
     return static_cast<T>(xd.as_mantissa_type());
   }
-
-  // unary
-  LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR Float80 operator-() const {
-    fputil::FPBits<Float80> result(*this);
-    result.set_sign(result.is_pos() ? Sign::NEG : Sign::POS);
-    return result.get_val();
-  }
-  // operator overloads
-  LIBC_INLINE constexpr Float80 operator+(const Float80 &other) const {
-    return fputil::generic::add<Float80>(*this, other);
-  }
-
-  LIBC_INLINE constexpr Float80 operator-(const Float80 &other) const {
-    return fputil::generic::sub<Float80>(*this, other);
-  }
-
-  LIBC_INLINE constexpr Float80 operator*(const Float80 &other) const {
-    return fputil::generic::mul<Float80>(*this, other);
-  }
-
-  LIBC_INLINE constexpr Float80 operator/(const Float80 &other) const {
-    return fputil::generic::div<Float80>(*this, other);
-  }
-
-  LIBC_INLINE constexpr Float80 &operator*=(const Float80 &other) {
-    *this = *this * other;
-    return *this;
-  }
-
-  LIBC_INLINE constexpr Float80 &operator+=(const Float80 &other) {
-    *this = *this + other;
-    return *this;
-  }
-
-  LIBC_INLINE constexpr Float80 &operator-=(const Float80 &other) {
-    *this = *this - other;
-    return *this;
-  }
-
-  LIBC_INLINE constexpr Float80 &operator/=(const Float80 &other) {
-    *this = *this / other;
-    return *this;
-  }
-
-  LIBC_INLINE constexpr bool operator==(const Float80 &other) const {
-    return fputil::equals(*this, other);
-  }
-
-  LIBC_INLINE constexpr bool operator!=(const Float80 &other) const {
-    return !fputil::equals(*this, other);
-  }
-
-  LIBC_INLINE constexpr bool operator<(const Float80 &other) const {
-    return fputil::less_than(*this, other);
-  }
-
-  LIBC_INLINE constexpr bool operator<=(const Float80 &other) const {
-    return fputil::less_than_or_equals(*this, other);
-  }
-
-  LIBC_INLINE constexpr bool operator>(const Float80 &other) const {
-    return fputil::greater_than(*this, other);
-  }
-
-  LIBC_INLINE constexpr bool operator>=(const Float80 &other) const {
-    return fputil::greater_than_or_equals(*this, other);
-  }
 };
 
 static_assert(LIBC_NAMESPACE::cpp::is_trivially_constructible<
diff --git a/libc/test/src/__support/FPUtil/float80_test.cpp b/libc/test/src/__support/FPUtil/float80_test.cpp
index c7245fa45cd1a..68b38a63c23b4 100644
--- a/libc/test/src/__support/FPUtil/float80_test.cpp
+++ b/libc/test/src/__support/FPUtil/float80_test.cpp
@@ -17,3 +17,62 @@ using LIBC_NAMESPACE::fputil::Float80;
 using FPBits = LIBC_NAMESPACE::fputil::FPBits<Float80>;
 
 TEST(LlvmLibcFloat80Test, temp) { Float80 a(1.0f); }
+
+TEST(LlvmLibcFloat80Test, IntegerConversion) {
+  // Float80 to Integer conversion test
+  ASSERT_EQ(static_cast<int>(Float80(0.0f)), 0);
+  ASSERT_EQ(static_cast<int>(Float80(1.0f)), 1);
+  ASSERT_EQ(static_cast<long long>(Float80(1000000000.0)),
+            static_cast<long long>(1000000000));
+  ASSERT_EQ(static_cast<unsigned>(Float80(7.0f)), 7U);
+  ASSERT_EQ(static_cast<int>(Float80(1.9f)), 1);
+
+  // Border values
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  ASSERT_EQ(static_cast<int>(Float80(INT_MAX)), INT_MAX);
+  ASSERT_EQ(static_cast<long long>(Float80(LLONG_MAX)), LLONG_MAX);
+  ASSERT_EQ(static_cast<unsigned>(Float80(UINT_MAX)), UINT_MAX);
+  EXPECT_EQ(LIBC_NAMESPACE::fputil::test_except(FE_INVALID), 0);
+
+  // FP exceptions
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  ASSERT_EQ(static_cast<int>(FPBits::quiet_nan().get_val()), INT_MAX);
+  EXPECT_FP_EXCEPTION(FE_INVALID);
+
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  ASSERT_EQ(static_cast<int>(FPBits::inf().get_val()), INT_MAX);
+  EXPECT_FP_EXCEPTION(FE_INVALID);
+
+  // Extreme values
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  ASSERT_EQ(static_cast<int>(Float80(1e300)), INT_MAX);
+  EXPECT_FP_EXCEPTION(FE_INVALID);
+
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  ASSERT_EQ(static_cast<int>(FPBits::inf(Sign::POS).get_val()), INT_MAX);
+  EXPECT_FP_EXCEPTION(FE_INVALID);
+
+  // Small values
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  ASSERT_EQ(static_cast<int>(Float80(1e-300)), 0);
+  ASSERT_EQ(static_cast<int>(Float80(0.5)), 0);
+  EXPECT_EQ(LIBC_NAMESPACE::fputil::test_except(FE_INVALID), 0);
+}
+
+TEST(LlvmLibcFloat80Test, FromIntegralTypes) {
+  // Integer to Float80 conversion test
+  ASSERT_EQ(FPBits(Float80(42)).uintval(), FPBits(Float80(42.0f)).uintval());
+  ASSERT_EQ(FPBits(Float80(0)).uintval(), FPBits(Float80(0.0f)).uintval());
+  ASSERT_EQ(FPBits(Float80(7U)).uintval(), FPBits(Float80(7.0f)).uintval());
+  ASSERT_EQ(FPBits(Float80(123456789LL)).uintval(),
+            FPBits(Float80(123456789.0)).uintval());
+
+  // 2147483648.0 or 2^31 is out of bound in signed and not in unsigned
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  ASSERT_EQ(static_cast<int>(Float80(2147483648.0)), INT_MAX);
+  EXPECT_FP_EXCEPTION(FE_INVALID);
+
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  ASSERT_EQ(static_cast<unsigned>(Float80(2147483648.0)), 2147483648U);
+  EXPECT_EQ(LIBC_NAMESPACE::fputil::test_except(FE_INVALID), 0);
+}

>From aaeeeb5e2e00305280ece8ea1433005ee0b79236 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 6 Aug 2026 16:56:36 +0530
Subject: [PATCH 09/17] add explicit bit handling for dyadic_float as per
 FPBits

---
 libc/src/__support/FPUtil/dyadic_float.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 12a2753c796d5..353f1b56b014d 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -262,6 +262,8 @@ template <size_t Bits> struct DyadicFloat {
       sticky = (mantissa & sticky_mask) != 0;
 
       out_mantissa = static_cast<StorageType>(mantissa >> extra_fraction_len);
+      if constexpr (get_fp_type<T>() == FPType::X86_Binary80)
+        out_mantissa |= FPBits::EXPLICIT_BIT_MASK;
     }
 
     bool lsb = (out_mantissa & 1) != 0;

>From beb434deac224eecb8d7261b550a9ec2cdee8c18 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 6 Aug 2026 16:58:38 +0530
Subject: [PATCH 10/17] nit

---
 libc/src/__support/FPUtil/dyadic_float.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 353f1b56b014d..12102ef0b4acd 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -262,6 +262,7 @@ template <size_t Bits> struct DyadicFloat {
       sticky = (mantissa & sticky_mask) != 0;
 
       out_mantissa = static_cast<StorageType>(mantissa >> extra_fraction_len);
+      // Takes into consideration the explicit bit for number for types like float 80
       if constexpr (get_fp_type<T>() == FPType::X86_Binary80)
         out_mantissa |= FPBits::EXPLICIT_BIT_MASK;
     }

>From 77e3852eed3c9c8411254c5fc687c0e91c66f0a6 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 6 Aug 2026 17:03:13 +0530
Subject: [PATCH 11/17] nit

---
 libc/src/__support/FPUtil/dyadic_float.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 12102ef0b4acd..10cf0369dc819 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -262,7 +262,8 @@ template <size_t Bits> struct DyadicFloat {
       sticky = (mantissa & sticky_mask) != 0;
 
       out_mantissa = static_cast<StorageType>(mantissa >> extra_fraction_len);
-      // Takes into consideration the explicit bit for number for types like float 80
+      // Takes into consideration the explicit bit for number for types like
+      // float 80
       if constexpr (get_fp_type<T>() == FPType::X86_Binary80)
         out_mantissa |= FPBits::EXPLICIT_BIT_MASK;
     }

>From 8dbc6bb88963e730855dbe2a07818d55404ebd41 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 6 Aug 2026 17:25:32 +0530
Subject: [PATCH 12/17] test: limit EXTRA_FRAC_LEN to be non-negative

test

test

nit

revert

revert

only add >0 condition

format
---
 libc/src/__support/FPUtil/dyadic_float.h | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 10cf0369dc819..e32906e3cf9cf 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -256,16 +256,14 @@ template <size_t Bits> struct DyadicFloat {
             static_cast<StorageType>(unbiased_exp + FPBits::EXP_BIAS);
       }
 
-      MantissaType round_mask = MantissaType(1) << (extra_fraction_len - 1);
-      round = (mantissa & round_mask) != 0;
-      MantissaType sticky_mask = round_mask - 1;
-      sticky = (mantissa & sticky_mask) != 0;
+      if (extra_fraction_len > 0) {
+        MantissaType round_mask = MantissaType(1) << (extra_fraction_len - 1);
+        round = (mantissa & round_mask) != 0;
+        MantissaType sticky_mask = round_mask - 1;
+        sticky = (mantissa & sticky_mask) != 0;
+      }
 
       out_mantissa = static_cast<StorageType>(mantissa >> extra_fraction_len);
-      // Takes into consideration the explicit bit for number for types like
-      // float 80
-      if constexpr (get_fp_type<T>() == FPType::X86_Binary80)
-        out_mantissa |= FPBits::EXPLICIT_BIT_MASK;
     }
 
     bool lsb = (out_mantissa & 1) != 0;

>From 99e8734f984f1e720156cad7b2644340e07df005 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sat, 8 Aug 2026 12:33:18 +0530
Subject: [PATCH 13/17] add edge cases test

---
 .../src/__support/FPUtil/float80_test.cpp     | 40 ++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/libc/test/src/__support/FPUtil/float80_test.cpp b/libc/test/src/__support/FPUtil/float80_test.cpp
index 68b38a63c23b4..65a95838cd087 100644
--- a/libc/test/src/__support/FPUtil/float80_test.cpp
+++ b/libc/test/src/__support/FPUtil/float80_test.cpp
@@ -16,7 +16,10 @@ using LIBC_NAMESPACE::Sign;
 using LIBC_NAMESPACE::fputil::Float80;
 using FPBits = LIBC_NAMESPACE::fputil::FPBits<Float80>;
 
-TEST(LlvmLibcFloat80Test, temp) { Float80 a(1.0f); }
+TEST(LlvmLibcFloat80Test, temp) { 
+  Float80 a(1.0f);
+
+}
 
 TEST(LlvmLibcFloat80Test, IntegerConversion) {
   // Float80 to Integer conversion test
@@ -59,6 +62,41 @@ TEST(LlvmLibcFloat80Test, IntegerConversion) {
   EXPECT_EQ(LIBC_NAMESPACE::fputil::test_except(FE_INVALID), 0);
 }
 
+#ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+TEST(LlvmLibcFloat80Test, randomTest) {
+  using FPBits = LIBC_NAMESPACE::fputil::FPBits<long double>;
+
+  const FPBits::StorageType EDGE_CASES[] = {
+      FPBits::zero(Sign::POS).uintval(),
+      FPBits::zero(Sign::NEG).uintval(),
+      FPBits::inf(Sign::POS).uintval(),
+      FPBits::inf(Sign::NEG).uintval(),
+      FPBits::quiet_nan().uintval(),
+      FPBits::signaling_nan().uintval(),
+      FPBits::min_subnormal(Sign::POS).uintval(),
+      FPBits::min_subnormal(Sign::NEG).uintval(),
+      FPBits::max_subnormal(Sign::POS).uintval(),
+      FPBits::max_subnormal(Sign::NEG).uintval(),
+      FPBits::min_normal(Sign::POS).uintval(),
+      FPBits::min_normal(Sign::NEG).uintval(),
+      FPBits::max_normal(Sign::POS).uintval(),
+      FPBits::max_normal(Sign::NEG).uintval(),
+      FPBits::one(Sign::POS).uintval(),
+      FPBits::one(Sign::NEG).uintval(),
+  };
+
+  for (FPBits::StorageType bits : EDGE_CASES) {
+    long double native = FPBits(bits).get_val();
+    Float80 emulated(native);
+    if (FPBits(bits).is_nan()) {
+      EXPECT_TRUE(FPBits(emulated).is_nan());
+    } else {
+      EXPECT_EQ(FPBits(emulated).uintval(), bits);
+    }
+  }
+}
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+
 TEST(LlvmLibcFloat80Test, FromIntegralTypes) {
   // Integer to Float80 conversion test
   ASSERT_EQ(FPBits(Float80(42)).uintval(), FPBits(Float80(42.0f)).uintval());

>From c5fb162cd8209d6f8afe913750aa3f4c981fa6c6 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sat, 8 Aug 2026 12:36:59 +0530
Subject: [PATCH 14/17] clang-format

---
 libc/test/src/__support/FPUtil/float80_test.cpp | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/libc/test/src/__support/FPUtil/float80_test.cpp b/libc/test/src/__support/FPUtil/float80_test.cpp
index 65a95838cd087..dbe85378b5f95 100644
--- a/libc/test/src/__support/FPUtil/float80_test.cpp
+++ b/libc/test/src/__support/FPUtil/float80_test.cpp
@@ -16,10 +16,7 @@ using LIBC_NAMESPACE::Sign;
 using LIBC_NAMESPACE::fputil::Float80;
 using FPBits = LIBC_NAMESPACE::fputil::FPBits<Float80>;
 
-TEST(LlvmLibcFloat80Test, temp) { 
-  Float80 a(1.0f);
-
-}
+TEST(LlvmLibcFloat80Test, temp) { Float80 a(1.0f); }
 
 TEST(LlvmLibcFloat80Test, IntegerConversion) {
   // Float80 to Integer conversion test

>From b36b5802d7fbd1223f8eabc5b12a86721e26acd9 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 13 Aug 2026 18:45:04 +0530
Subject: [PATCH 15/17] test: modify for comparing native<->float80

edge cases

test: modify for comparing native<->float80

nit
---
 .../src/__support/FPUtil/float80_test.cpp     | 59 ++++++++++---------
 1 file changed, 32 insertions(+), 27 deletions(-)

diff --git a/libc/test/src/__support/FPUtil/float80_test.cpp b/libc/test/src/__support/FPUtil/float80_test.cpp
index dbe85378b5f95..930c669bb41ea 100644
--- a/libc/test/src/__support/FPUtil/float80_test.cpp
+++ b/libc/test/src/__support/FPUtil/float80_test.cpp
@@ -61,37 +61,42 @@ TEST(LlvmLibcFloat80Test, IntegerConversion) {
 
 #ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
 TEST(LlvmLibcFloat80Test, randomTest) {
-  using FPBits = LIBC_NAMESPACE::fputil::FPBits<long double>;
-
-  const FPBits::StorageType EDGE_CASES[] = {
-      FPBits::zero(Sign::POS).uintval(),
-      FPBits::zero(Sign::NEG).uintval(),
-      FPBits::inf(Sign::POS).uintval(),
-      FPBits::inf(Sign::NEG).uintval(),
-      FPBits::quiet_nan().uintval(),
-      FPBits::signaling_nan().uintval(),
-      FPBits::min_subnormal(Sign::POS).uintval(),
-      FPBits::min_subnormal(Sign::NEG).uintval(),
-      FPBits::max_subnormal(Sign::POS).uintval(),
-      FPBits::max_subnormal(Sign::NEG).uintval(),
-      FPBits::min_normal(Sign::POS).uintval(),
-      FPBits::min_normal(Sign::NEG).uintval(),
-      FPBits::max_normal(Sign::POS).uintval(),
-      FPBits::max_normal(Sign::NEG).uintval(),
-      FPBits::one(Sign::POS).uintval(),
-      FPBits::one(Sign::NEG).uintval(),
+  using FPBitsL = LIBC_NAMESPACE::fputil::FPBits<long double>;
+
+  const FPBitsL::StorageType EDGE_CASES[] = {
+      FPBitsL::zero(Sign::POS).uintval(),
+      FPBitsL::zero(Sign::NEG).uintval(),
+      FPBitsL::inf(Sign::POS).uintval(),
+      FPBitsL::inf(Sign::NEG).uintval(),
+      FPBitsL::quiet_nan().uintval(),
+      FPBitsL::signaling_nan().uintval(),
+      FPBitsL::min_subnormal(Sign::POS).uintval(),
+      FPBitsL::min_subnormal(Sign::NEG).uintval(),
+      FPBitsL::max_subnormal(Sign::POS).uintval(),
+      FPBitsL::max_subnormal(Sign::NEG).uintval(),
+      FPBitsL::min_normal(Sign::POS).uintval(),
+      FPBitsL::min_normal(Sign::NEG).uintval(),
+      FPBitsL::max_normal(Sign::POS).uintval(),
+      FPBitsL::max_normal(Sign::NEG).uintval(),
+      FPBitsL::one(Sign::POS).uintval(),
+      FPBitsL::one(Sign::NEG).uintval(),
   };
 
-  for (FPBits::StorageType bits : EDGE_CASES) {
-    long double native = FPBits(bits).get_val();
-    Float80 emulated(native);
-    if (FPBits(bits).is_nan()) {
-      EXPECT_TRUE(FPBits(emulated).is_nan());
-    } else {
-      EXPECT_EQ(FPBits(emulated).uintval(), bits);
-    }
+  for (FPBitsL::StorageType bits : EDGE_CASES) {
+    if (FPBitsL(bits).is_signaling_nan())
+      continue;
+
+    long double native = FPBitsL(bits).get_val();
+
+    Float80 f80_temp = LIBC_NAMESPACE::fputil::cast<Float80>(native);
+    EXPECT_EQ(FPBits(f80_temp).uintval(), bits);
+
+    long double ld_temp =
+        LIBC_NAMESPACE::fputil::cast<long double>(FPBits(bits).get_val());
+    EXPECT_EQ(FPBitsL(ld_temp).uintval(), bits);
   }
 }
+
 #endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
 
 TEST(LlvmLibcFloat80Test, FromIntegralTypes) {

>From e96a7ddc9c2d548a30c16bd114c88a0cf7dde280 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 20 Aug 2026 21:52:57 +0530
Subject: [PATCH 16/17] nits and cleanup

---
 .../src/__support/CPP/type_traits/is_floating_point.h |  3 ++-
 libc/src/__support/FPUtil/dyadic_float.h              | 11 ++++-------
 libc/src/__support/FPUtil/float80.h                   |  5 -----
 libc/src/__support/macros/properties/types.h          |  1 +
 libc/test/src/__support/FPUtil/float80_test.cpp       |  6 ------
 5 files changed, 7 insertions(+), 19 deletions(-)

diff --git a/libc/src/__support/CPP/type_traits/is_floating_point.h b/libc/src/__support/CPP/type_traits/is_floating_point.h
index 82a4ede7124c6..4a5984e38a8cf 100644
--- a/libc/src/__support/CPP/type_traits/is_floating_point.h
+++ b/libc/src/__support/CPP/type_traits/is_floating_point.h
@@ -44,8 +44,9 @@ template <typename T> struct is_floating_point {
                               bfloat16
 
                               ,
-                              fputil::Float128,
+                              fputil::Float128
 
+                              ,
                               fputil::Float80>();
 };
 template <typename T>
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index e32906e3cf9cf..59fd989f3407e 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -256,13 +256,10 @@ template <size_t Bits> struct DyadicFloat {
             static_cast<StorageType>(unbiased_exp + FPBits::EXP_BIAS);
       }
 
-      if (extra_fraction_len > 0) {
-        MantissaType round_mask = MantissaType(1) << (extra_fraction_len - 1);
-        round = (mantissa & round_mask) != 0;
-        MantissaType sticky_mask = round_mask - 1;
-        sticky = (mantissa & sticky_mask) != 0;
-      }
-
+      MantissaType round_mask = MantissaType(1) << (extra_fraction_len - 1);
+      round = (mantissa & round_mask) != 0;
+      MantissaType sticky_mask = round_mask - 1;
+      sticky = (mantissa & sticky_mask) != 0;
       out_mantissa = static_cast<StorageType>(mantissa >> extra_fraction_len);
     }
 
diff --git a/libc/src/__support/FPUtil/float80.h b/libc/src/__support/FPUtil/float80.h
index d6823f7bedb76..7cbb1300ca12a 100644
--- a/libc/src/__support/FPUtil/float80.h
+++ b/libc/src/__support/FPUtil/float80.h
@@ -97,11 +97,6 @@ struct Float80 {
   }
 };
 
-static_assert(LIBC_NAMESPACE::cpp::is_trivially_constructible<
-              LIBC_NAMESPACE::fputil::Float80>::value);
-static_assert(LIBC_NAMESPACE::cpp::is_trivially_copyable<
-              LIBC_NAMESPACE::fputil::Float80>::value);
-
 } // namespace fputil
 } // namespace LIBC_NAMESPACE_DECL
 
diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index ddf7294ab15ea..aad4c41005c45 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -100,6 +100,7 @@ namespace fputil {
 struct Float80;
 }
 } // namespace LIBC_NAMESPACE_DECL
+
 using float80 = LIBC_NAMESPACE::fputil::Float80;
 
 // -- bfloat16 support ---------------------------------------------------------
diff --git a/libc/test/src/__support/FPUtil/float80_test.cpp b/libc/test/src/__support/FPUtil/float80_test.cpp
index 930c669bb41ea..549c414cea811 100644
--- a/libc/test/src/__support/FPUtil/float80_test.cpp
+++ b/libc/test/src/__support/FPUtil/float80_test.cpp
@@ -16,8 +16,6 @@ using LIBC_NAMESPACE::Sign;
 using LIBC_NAMESPACE::fputil::Float80;
 using FPBits = LIBC_NAMESPACE::fputil::FPBits<Float80>;
 
-TEST(LlvmLibcFloat80Test, temp) { Float80 a(1.0f); }
-
 TEST(LlvmLibcFloat80Test, IntegerConversion) {
   // Float80 to Integer conversion test
   ASSERT_EQ(static_cast<int>(Float80(0.0f)), 0);
@@ -69,7 +67,6 @@ TEST(LlvmLibcFloat80Test, randomTest) {
       FPBitsL::inf(Sign::POS).uintval(),
       FPBitsL::inf(Sign::NEG).uintval(),
       FPBitsL::quiet_nan().uintval(),
-      FPBitsL::signaling_nan().uintval(),
       FPBitsL::min_subnormal(Sign::POS).uintval(),
       FPBitsL::min_subnormal(Sign::NEG).uintval(),
       FPBitsL::max_subnormal(Sign::POS).uintval(),
@@ -83,9 +80,6 @@ TEST(LlvmLibcFloat80Test, randomTest) {
   };
 
   for (FPBitsL::StorageType bits : EDGE_CASES) {
-    if (FPBitsL(bits).is_signaling_nan())
-      continue;
-
     long double native = FPBitsL(bits).get_val();
 
     Float80 f80_temp = LIBC_NAMESPACE::fputil::cast<Float80>(native);

>From ae87a40fffc36e2ba7bb5ba58d5a7cdf36f8b6bb Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sat, 22 Aug 2026 17:23:07 +0530
Subject: [PATCH 17/17] add the extra_frac_len check back

---
 libc/src/__support/FPUtil/dyadic_float.h | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 59fd989f3407e..e32906e3cf9cf 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -256,10 +256,13 @@ template <size_t Bits> struct DyadicFloat {
             static_cast<StorageType>(unbiased_exp + FPBits::EXP_BIAS);
       }
 
-      MantissaType round_mask = MantissaType(1) << (extra_fraction_len - 1);
-      round = (mantissa & round_mask) != 0;
-      MantissaType sticky_mask = round_mask - 1;
-      sticky = (mantissa & sticky_mask) != 0;
+      if (extra_fraction_len > 0) {
+        MantissaType round_mask = MantissaType(1) << (extra_fraction_len - 1);
+        round = (mantissa & round_mask) != 0;
+        MantissaType sticky_mask = round_mask - 1;
+        sticky = (mantissa & sticky_mask) != 0;
+      }
+
       out_mantissa = static_cast<StorageType>(mantissa >> extra_fraction_len);
     }
 



More information about the libc-commits mailing list