[libc-commits] [libc] [libc] Float128 Emulation in LLVM libc (PR #200565)
via libc-commits
libc-commits at lists.llvm.org
Tue Jun 2 01:36:28 PDT 2026
https://github.com/Sukumarsawant updated https://github.com/llvm/llvm-project/pull/200565
>From 24bab4317fccfb41595421b41681d60d5a30e30f Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sat, 30 May 2026 02:08:42 +0530
Subject: [PATCH 1/3] test: float128 skeleton
---
libc/src/__support/FPUtil/CMakeLists.txt | 11 ++++++
libc/src/__support/FPUtil/float128.h | 45 ++++++++++++++++++++++++
2 files changed, 56 insertions(+)
create mode 100644 libc/src/__support/FPUtil/float128.h
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index d45dd82560788..a88986b4992f8 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -294,4 +294,15 @@ add_header_library(
libc.src.__support.macros.properties.types
)
+add_header_library(
+ float128
+ HDRS
+ float128.h
+ DEPENDS
+ .fp_bits
+ libc.hdr.fenv_macros
+ libc.src.__support.CPP.bit
+ libc.src.__support.uint128
+)
+
add_subdirectory(generic)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
new file mode 100644
index 0000000000000..73f450f1d41a8
--- /dev/null
+++ b/libc/src/__support/FPUtil/float128.h
@@ -0,0 +1,45 @@
+//===-- Utilities for Float128 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_FLOAT128_H
+#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
+
+#include "FPBits.h"
+#include "hdr/fenv_macros.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/uint128.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+
+struct Float128 {
+ UInt128 bits;
+ // Testing
+ constexpr Float128() = default;
+ /* TODO: precision
+ TODO: explicit so it does not convert without warn ( Done )
+ VERIFY : template <cpp::enable_if_t<fputil::get_fp_type<Double>() ==
+ fputil::FPType::IEEE754_Binary64,
+ int> = 0>
+ */
+ constexpr explicit Float128(double x) {
+ FPBits<double> x_bits(x);
+ uint64_t val = x_bits.uintval();
+ bits = static_cast<UInt128>(val) << 64;
+ }
+
+ constexpr explicit operator double() const {
+ uint64_t val = static_cast<uint64_t>(bits >> 64U);
+ return cpp::bit_cast<double>(val);
+ }
+};
+
+} // namespace fputil
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
>From 5bae1c688d5c221bd854c04c1c1b7049758b1172 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 2 Jun 2026 14:00:26 +0530
Subject: [PATCH 2/3] Add small smoke test
---
.../CPP/type_traits/is_floating_point.h | 2 +-
libc/src/__support/FPUtil/CMakeLists.txt | 4 +-
libc/src/__support/FPUtil/FPBits.h | 13 +++++-
libc/src/__support/FPUtil/float128.h | 41 +++++++++++--------
libc/src/__support/macros/properties/types.h | 8 ++++
libc/test/src/math/smoke/CMakeLists.txt | 10 +++++
libc/test/src/math/smoke/float128_test.cpp | 25 +++++++++++
7 files changed, 81 insertions(+), 22 deletions(-)
create mode 100644 libc/test/src/math/smoke/float128_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 9dc77ad7ee0ea..ab4191868517e 100644
--- a/libc/src/__support/CPP/type_traits/is_floating_point.h
+++ b/libc/src/__support/CPP/type_traits/is_floating_point.h
@@ -37,7 +37,7 @@ template <typename T> struct is_floating_point {
float128
#endif
,
- bfloat16>();
+ bfloat16, fputil::Float128>();
};
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 a88986b4992f8..20e1c01bb8ca1 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -299,9 +299,9 @@ add_header_library(
HDRS
float128.h
DEPENDS
- .fp_bits
- libc.hdr.fenv_macros
libc.src.__support.CPP.bit
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
libc.src.__support.uint128
)
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index c52699e17e225..5b7461a44cff5 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -37,7 +37,8 @@ enum class FPType {
IEEE754_Binary64,
IEEE754_Binary128,
X86_Binary80,
- BFloat16
+ BFloat16,
+ Float128
};
// The classes hierarchy is as follows:
@@ -146,6 +147,14 @@ template <> struct FPLayout<FPType::BFloat16> {
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SIG_LEN;
};
+template <> struct FPLayout<FPType::Float128> {
+ using StorageType = UInt128;
+ 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 = 112;
+ LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SIG_LEN;
+};
+
// FPStorage derives useful constants from the FPLayout above.
template <FPType fp_type> struct FPStorage : public FPLayout<fp_type> {
using UP = FPLayout<fp_type>;
@@ -813,6 +822,8 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
#endif
else if constexpr (cpp::is_same_v<UnqualT, bfloat16>)
return FPType::BFloat16;
+ else if constexpr (cpp::is_same_v<UnqualT, Float128>)
+ return FPType::Float128;
else
static_assert(cpp::always_false<UnqualT>, "Unsupported type");
}
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index 73f450f1d41a8..ca5c49ddf11d7 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -1,4 +1,8 @@
+<<<<<<< HEAD
//===-- Utilities for Float128 data type -----------------------*- C++ -*-===//
+=======
+//===-- Definition for Float128 data type -----------------------*- C++ -*-===//
+>>>>>>> f128-test
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,33 +13,34 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
-#include "FPBits.h"
-#include "hdr/fenv_macros.h"
-#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/bit.h" // cpp::bit_cast
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
#include "src/__support/uint128.h"
+#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
struct Float128 {
UInt128 bits;
- // Testing
- constexpr Float128() = default;
- /* TODO: precision
- TODO: explicit so it does not convert without warn ( Done )
- VERIFY : template <cpp::enable_if_t<fputil::get_fp_type<Double>() ==
- fputil::FPType::IEEE754_Binary64,
- int> = 0>
- */
- constexpr explicit Float128(double x) {
- FPBits<double> x_bits(x);
- uint64_t val = x_bits.uintval();
- bits = static_cast<UInt128>(val) << 64;
+
+ LIBC_INLINE Float128() = default;
+
+ LIBC_INLINE constexpr explicit Float128(double x) : bits(0) {
+ uint64_t d = cpp::bit_cast<uint64_t>(x);
+ bits = static_cast<UInt128>(d) << 64U;
}
- constexpr explicit operator double() const {
- uint64_t val = static_cast<uint64_t>(bits >> 64U);
- return cpp::bit_cast<double>(val);
+ LIBC_INLINE constexpr explicit operator double() const {
+ return cpp::bit_cast<double>(static_cast<uint64_t>(bits >> 64U));
+ }
+
+ LIBC_INLINE constexpr bool operator==(Float128 other) const {
+ return bits == other.bits;
+ }
+ LIBC_INLINE constexpr bool operator!=(Float128 other) const {
+ return bits != other.bits;
}
};
diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index 3259c8a6a1d12..d94f6068984df 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -58,6 +58,14 @@ using float16 = _Float16;
// LIBC_TYPES_HAS_FLOAT128 and 'float128' type are provided by
// "include/llvm-libc-types/float128.h"
+// -- Emulated float128 support ------------------------------------------------
+// Float128 is always available regardless of native __float128 support.
+namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+struct Float128;
+}
+} // namespace LIBC_NAMESPACE_DECL
+
// -- bfloat16 support ---------------------------------------------------------
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index bb462afb71b91..bc911ea8a798f 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -1,6 +1,16 @@
add_custom_target(libc-math-smoke-tests)
add_dependencies(libc-math-unittests libc-math-smoke-tests)
+add_libc_unittest(
+ float128_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ float128_test.cpp
+ DEPENDS
+ libc.src.__support.FPUtil.float128
+)
+
add_fp_unittest(
cosf_test
SUITE
diff --git a/libc/test/src/math/smoke/float128_test.cpp b/libc/test/src/math/smoke/float128_test.cpp
new file mode 100644
index 0000000000000..738e5ec703f00
--- /dev/null
+++ b/libc/test/src/math/smoke/float128_test.cpp
@@ -0,0 +1,25 @@
+//===-- Unittests for Float128 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 "src/__support/FPUtil/float128.h"
+#include "src/__support/uint128.h"
+#include "test/UnitTest/Test.h"
+
+using LIBC_NAMESPACE::fputil::Float128;
+
+TEST(LlvmLibcFloat128Test, DefaultConstructor) {
+ Float128 x;
+ (void)x;
+}
+
+TEST(LlvmLibcFloat128Test, Equality) {
+ Float128 a(1.0), b(1.0), c(2.0);
+ ASSERT_TRUE(a == b);
+ ASSERT_TRUE(a != c);
+ ASSERT_TRUE(b != c);
+}
>From 2a40be15e405131a6c16a6bf2f17baffe5ac94b6 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 2 Jun 2026 14:06:05 +0530
Subject: [PATCH 3/3] nit
---
libc/src/__support/FPUtil/float128.h | 4 ----
1 file changed, 4 deletions(-)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index ca5c49ddf11d7..c7835d7376853 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -1,8 +1,4 @@
-<<<<<<< HEAD
-//===-- Utilities for Float128 data type -----------------------*- C++ -*-===//
-=======
//===-- Definition for Float128 data type -----------------------*- C++ -*-===//
->>>>>>> f128-test
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
More information about the libc-commits
mailing list