[libc-commits] [libc] Float128 fpbits integration (PR #186938)

via libc-commits libc-commits at lists.llvm.org
Mon Mar 16 19:08:33 PDT 2026


https://github.com/Emmaliu2006git created https://github.com/llvm/llvm-project/pull/186938

This patch improves the integration of fputil::Float128 with FPBits.

In the previous patch, support for Float128 in FPBits relied on an ad-hoc check in get_fp_type to recognize the wrapper type. This patch removes that special case and instead relies on the is_floating_point type trait specialization for fputil::Float128.

With this change, Float128 is treated consistently with other floating-point types in libc. FPBits can now correctly recognize fputil::Float128 through the existing floating-point trait mechanism.

Additional unit tests are added to verify:
- FPBits instantiation with fputil::Float128
- correct raw bit storage through UInt128
- FP type detection through get_fp_type
- recognition by the is_floating_point trait

This patch builds on top of PR #186901.

>From 820a8008bd05311d38ce5f91a71683b6b277c3f7 Mon Sep 17 00:00:00 2001
From: Emma Liu <yueqil2 at illinois.edu>
Date: Mon, 16 Mar 2026 14:22:17 -0500
Subject: [PATCH 1/6] [libc] Add software Float128 fallback wrapper

Introduce a minimal fputil::Float128 type used as a fallback when no native float128 type is available.
---
 libc/include/llvm-libc-types/float128.h |  3 ++
 libc/src/__support/FPUtil/float128.h    | 37 +++++++++++++++++++++++++
 2 files changed, 40 insertions(+)
 create mode 100644 libc/src/__support/FPUtil/float128.h

diff --git a/libc/include/llvm-libc-types/float128.h b/libc/include/llvm-libc-types/float128.h
index 82ebb79f1f580..d507be24e9ace 100644
--- a/libc/include/llvm-libc-types/float128.h
+++ b/libc/include/llvm-libc-types/float128.h
@@ -31,6 +31,9 @@ typedef __float128 float128;
 #elif (LDBL_MANT_DIG == 113)
 #define LIBC_TYPES_HAS_FLOAT128
 typedef long double float128;
+#else
+#include "src/__support/FPUtil/float128.h"
+typedef LIBC_NAMESPACE::fputil::Float128 float128;
 #endif
 
 #endif // LLVM_LIBC_TYPES_FLOAT128_H
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
new file mode 100644
index 0000000000000..5cf5685fa0892
--- /dev/null
+++ b/libc/src/__support/FPUtil/float128.h
@@ -0,0 +1,37 @@
+//===-- Float128 software wrapper ----------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a minimal software-backed Float128 wrapper type used when
+// the host compiler does not provide a native 128-bit floating-point type.
+// The wrapper currently only stores the raw 128-bit representation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SUPPORT_FPUTIL_FLOAT128_H
+#define LLVM_LIBC_SRC_SUPPORT_FPUTIL_FLOAT128_H
+
+#include "src/__support/uint128.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+
+class Float128 {
+private:
+  UInt128 bits_;
+
+public:
+  constexpr Float128() = default;
+
+  constexpr explicit Float128(UInt128 value) : bits_(value) {}
+
+  constexpr UInt128 get_bits() const { return bits_; }
+};
+} // namespace fputil
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SUPPORT_FPUTIL_FLOAT128_H
\ No newline at end of file

>From c625b9cb93a51677debb8a70af3e0bbf69fba8ae Mon Sep 17 00:00:00 2001
From: Emma Liu <yueqil2 at illinois.edu>
Date: Mon, 16 Mar 2026 16:58:20 -0500
Subject: [PATCH 2/6] [libc] Initialize Float128 bits_ to zero

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

diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index 5cf5685fa0892..a9ad68080b907 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -22,14 +22,14 @@ namespace fputil {
 
 class Float128 {
 private:
-  UInt128 bits_;
+  UInt128 bits_ = 0;
 
 public:
-  constexpr Float128() = default;
+    constexpr Float128() = default;
 
-  constexpr explicit Float128(UInt128 value) : bits_(value) {}
+    constexpr explicit Float128(UInt128 value) : bits_(value) {}
 
-  constexpr UInt128 get_bits() const { return bits_; }
+    constexpr UInt128 get_bits() const { return bits_; }
 };
 } // namespace fputil
 } // namespace LIBC_NAMESPACE_DECL

>From af6f666231bb3a04358b68d8a05e0a2ba83b5e9e Mon Sep 17 00:00:00 2001
From: Emma Liu <yueqil2 at illinois.edu>
Date: Mon, 16 Mar 2026 17:11:43 -0500
Subject: [PATCH 3/6] [libc] Add FPBits support for Float128

---
 libc/src/__support/FPUtil/FPBits.h             | 6 +++++-
 libc/test/src/__support/FPUtil/fpbits_test.cpp | 6 ++++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index ce4925bae125a..a64e6bc773658 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -26,6 +26,7 @@
 #include "src/__support/math_extras.h"             // mask_trailing_ones
 #include "src/__support/sign.h"                    // Sign
 #include "src/__support/uint128.h"
+#include "src/__support/FPUtil/float128.h"  //include float128.h
 
 namespace LIBC_NAMESPACE_DECL {
 namespace fputil {
@@ -809,6 +810,8 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
   else if constexpr (cpp::is_same_v<UnqualT, float128>)
     return FPType::IEEE754_Binary128;
 #endif
+  else if constexpr (cpp::is_same_v<UnqualT, LIBC_NAMESPACE::fputil::Float128>)
+    return FPType::IEEE754_Binary128;
   else if constexpr (cpp::is_same_v<UnqualT, bfloat16>)
     return FPType::BFloat16;
   else
@@ -825,7 +828,8 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
 // It derives its functionality to FPRepImpl above.
 template <typename T>
 struct FPBits final : public internal::FPRepImpl<get_fp_type<T>(), FPBits<T>> {
-  static_assert(cpp::is_floating_point_v<T>,
+  static_assert(cpp::is_floating_point_v<T>
+                ||cpp::is_same_v<T, LIBC_NAMESPACE::fputil::Float128>,
                 "FPBits instantiated with invalid type.");
   using UP = internal::FPRepImpl<get_fp_type<T>(), FPBits<T>>;
   using StorageType = typename UP::StorageType;
diff --git a/libc/test/src/__support/FPUtil/fpbits_test.cpp b/libc/test/src/__support/FPUtil/fpbits_test.cpp
index 6953d3aace58f..99b86ff1a9c77 100644
--- a/libc/test/src/__support/FPUtil/fpbits_test.cpp
+++ b/libc/test/src/__support/FPUtil/fpbits_test.cpp
@@ -778,3 +778,9 @@ TEST(LlvmLibcFPBitsTest, Float128Type) {
   EXPECT_EQ(quiet_nan.is_quiet_nan(), true);
 }
 #endif // LIBC_TYPES_HAS_FLOAT128
+
+TEST(LlvmLibcFPBitsTest, Float128WrapperInstantiation) {
+  LIBC_NAMESPACE::fputil::Float128 x;
+  LIBC_NAMESPACE::fputil::FPBits<LIBC_NAMESPACE::fputil::Float128> bits(x);
+  EXPECT_TRUE(bits.is_zero());
+}
\ No newline at end of file

>From b0946635e68efdd6cf065af8fa723928a02cbc40 Mon Sep 17 00:00:00 2001
From: Emma Liu <yueqil2 at illinois.edu>
Date: Mon, 16 Mar 2026 18:35:30 -0500
Subject: [PATCH 4/6] Add newline at end of float128.h

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

diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index a9ad68080b907..52b78b516b47a 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -34,4 +34,4 @@ class Float128 {
 } // namespace fputil
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LLVM_LIBC_SRC_SUPPORT_FPUTIL_FLOAT128_H
\ No newline at end of file
+#endif // LLVM_LIBC_SRC_SUPPORT_FPUTIL_FLOAT128_H

>From 9cda9c69044d65e55b26dc7d02adfc51ab1dc102 Mon Sep 17 00:00:00 2001
From: Emma Liu <yueqil2 at illinois.edu>
Date: Mon, 16 Mar 2026 20:58:16 -0500
Subject: [PATCH 5/6] [libc] Integrate fputil::Float128 with FPBits using type
 traits

---
 libc/src/__support/CPP/type_traits/is_floating_point.h | 8 +++++++-
 libc/src/__support/FPUtil/FPBits.h                     | 3 +--
 2 files changed, 8 insertions(+), 3 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 9dc77ad7ee0ea..1804742e55943 100644
--- a/libc/src/__support/CPP/type_traits/is_floating_point.h
+++ b/libc/src/__support/CPP/type_traits/is_floating_point.h
@@ -15,6 +15,9 @@
 #include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_FLOAT128
 
 namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+class Float128;
+}
 namespace cpp {
 
 // is_floating_point
@@ -42,7 +45,10 @@ template <typename T> struct is_floating_point {
 template <typename T>
 LIBC_INLINE_VAR constexpr bool is_floating_point_v =
     is_floating_point<T>::value;
-
+template <>
+struct is_floating_point<fputil::Float128> { //Float128 class -> is_floating_point = true
+  LIBC_INLINE_VAR static constexpr bool value = true;
+};
 } // namespace cpp
 } // namespace LIBC_NAMESPACE_DECL
 
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index a64e6bc773658..2b682e745371e 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -828,8 +828,7 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
 // It derives its functionality to FPRepImpl above.
 template <typename T>
 struct FPBits final : public internal::FPRepImpl<get_fp_type<T>(), FPBits<T>> {
-  static_assert(cpp::is_floating_point_v<T>
-                ||cpp::is_same_v<T, LIBC_NAMESPACE::fputil::Float128>,
+  static_assert(cpp::is_floating_point_v<T>,
                 "FPBits instantiated with invalid type.");
   using UP = internal::FPRepImpl<get_fp_type<T>(), FPBits<T>>;
   using StorageType = typename UP::StorageType;

>From 9c087570abf193f5d0cb66efb6cd1384d5d8a5d7 Mon Sep 17 00:00:00 2001
From: Emma Liu <yueqil2 at illinois.edu>
Date: Mon, 16 Mar 2026 20:58:58 -0500
Subject: [PATCH 6/6] Add unit tests for Float128 FPBits integration

---
 .../test/src/__support/FPUtil/fpbits_test.cpp | 34 +++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/libc/test/src/__support/FPUtil/fpbits_test.cpp b/libc/test/src/__support/FPUtil/fpbits_test.cpp
index 99b86ff1a9c77..26dbfa1741996 100644
--- a/libc/test/src/__support/FPUtil/fpbits_test.cpp
+++ b/libc/test/src/__support/FPUtil/fpbits_test.cpp
@@ -780,7 +780,37 @@ TEST(LlvmLibcFPBitsTest, Float128Type) {
 #endif // LIBC_TYPES_HAS_FLOAT128
 
 TEST(LlvmLibcFPBitsTest, Float128WrapperInstantiation) {
-  LIBC_NAMESPACE::fputil::Float128 x;
-  LIBC_NAMESPACE::fputil::FPBits<LIBC_NAMESPACE::fputil::Float128> bits(x);
+  using LIBC_NAMESPACE::fputil::Float128;
+  using Float128Bits = LIBC_NAMESPACE::fputil::FPBits<Float128>;
+
+  Float128 x;
+  Float128Bits bits(x);
+
   EXPECT_TRUE(bits.is_zero());
+}
+
+TEST(LlvmLibcFPBitsTest, Float128BitsStorage) {
+  using LIBC_NAMESPACE::fputil::Float128;
+
+  UInt128 raw(123);
+  Float128 x(raw);
+
+  EXPECT_EQ(x.get_bits(), raw);
+}
+
+TEST(LlvmLibcFPBitsTest, Float128GetFPType) {
+  using LIBC_NAMESPACE::fputil::Float128;
+
+  constexpr auto type =
+      LIBC_NAMESPACE::fputil::get_fp_type<Float128>();
+
+  EXPECT_EQ(type,
+            LIBC_NAMESPACE::fputil::FPType::IEEE754_Binary128);
+}
+
+TEST(LlvmLibcFPBitsTest, Float128IsFloatingPoint) {
+  using LIBC_NAMESPACE::fputil::Float128;
+
+  EXPECT_TRUE(
+      LIBC_NAMESPACE::cpp::is_floating_point<Float128>::value);
 }
\ No newline at end of file



More information about the libc-commits mailing list