[libc-commits] [libc] 82b9a76 - [libc] Enables MPFR for float80 and adds tests for it (#223800)
via libc-commits
libc-commits at lists.llvm.org
Sat Sep 19 08:34:57 PDT 2026
Author: Zorojuro
Date: 2026-09-19T21:04:49+05:30
New Revision: 82b9a76acb072b5ee6dc5dd123d30b883fcc4222
URL: https://github.com/llvm/llvm-project/commit/82b9a76acb072b5ee6dc5dd123d30b883fcc4222
DIFF: https://github.com/llvm/llvm-project/commit/82b9a76acb072b5ee6dc5dd123d30b883fcc4222.diff
LOG: [libc] Enables MPFR for float80 and adds tests for it (#223800)
This temporarily only enables them where its natively avaialble i.e
where long double is float80 (x86)
Added:
libc/cmake/modules/compiler_features/check_float80.cpp
Modified:
libc/cmake/modules/CheckCompilerFeatures.cmake
libc/test/src/CMakeLists.txt
libc/test/src/__support/FPUtil/CMakeLists.txt
libc/test/src/__support/FPUtil/float80_test.cpp
libc/utils/MPFRWrapper/CMakeLists.txt
libc/utils/MPFRWrapper/MPCommon.cpp
libc/utils/MPFRWrapper/MPCommon.h
Removed:
################################################################################
diff --git a/libc/cmake/modules/CheckCompilerFeatures.cmake b/libc/cmake/modules/CheckCompilerFeatures.cmake
index 84f657a540b21..eaf702710b1cc 100644
--- a/libc/cmake/modules/CheckCompilerFeatures.cmake
+++ b/libc/cmake/modules/CheckCompilerFeatures.cmake
@@ -12,6 +12,7 @@ set(
"builtin_roundeven"
"float16"
"float16_conversion"
+ "float80"
"float128"
"fixed_point"
"cfloat16"
@@ -26,6 +27,7 @@ list(SORT ALL_COMPILER_FEATURES)
# Compiler features that are unavailable on GPU targets with the in-tree Clang.
set(
CPU_ONLY_COMPILER_FEATURES
+ "float80"
"float128"
)
@@ -117,6 +119,8 @@ foreach(feature IN LISTS ALL_COMPILER_FEATURES)
set(LIBC_TYPES_HAS_FLOAT16 TRUE)
elseif(${feature} STREQUAL "float16_conversion")
add_compile_definitions(__LIBC_USE_FLOAT16_CONVERSION)
+ elseif(${feature} STREQUAL "float80")
+ set(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80 TRUE)
elseif(${feature} STREQUAL "float128")
set(LIBC_TYPES_HAS_NATIVE_FLOAT128 TRUE)
elseif(${feature} STREQUAL "fixed_point")
diff --git a/libc/cmake/modules/compiler_features/check_float80.cpp b/libc/cmake/modules/compiler_features/check_float80.cpp
new file mode 100644
index 0000000000000..52e80027bce4a
--- /dev/null
+++ b/libc/cmake/modules/compiler_features/check_float80.cpp
@@ -0,0 +1,5 @@
+#include "src/__support/macros/properties/types.h"
+
+#ifndef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+#error unsupported
+#endif
diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index 463485768dcde..5018f7e15b66d 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -1,7 +1,7 @@
function(add_fp_unittest name)
cmake_parse_arguments(
"MATH_UNITTEST"
- "NEED_MPFR;NEED_MPFR_F128;NEED_MPC;FULL_BUILD_ONLY;OVERLAY_BUILD_ONLY" # Optional arguments
+ "NEED_MPFR;NEED_MPFR_F80;NEED_MPFR_F128;NEED_MPC;FULL_BUILD_ONLY;OVERLAY_BUILD_ONLY" # Optional arguments
"" # Single value arguments
"LINK_LIBRARIES;DEPENDS" # Multi-value arguments
${ARGN}
@@ -16,6 +16,14 @@ function(add_fp_unittest name)
list(APPEND MATH_UNITTEST_LINK_LIBRARIES libcMPCWrapper)
endif()
+ if(MATH_UNITTEST_NEED_MPFR_F80)
+ set(MATH_UNITTEST_NEED_MPFR TRUE)
+ if(NOT LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+ message(VERBOSE "Math test ${name} will be skipped as float80 support in MPFR is not available.")
+ return()
+ endif()
+ endif()
+
# TODO: To be removed when we find a workaround to run MPFR tests for
# emulated type where compiler doesn't support the native float128
# TODO: Check mpfr_buildopt_float128_p() returns non-zero.
diff --git a/libc/test/src/__support/FPUtil/CMakeLists.txt b/libc/test/src/__support/FPUtil/CMakeLists.txt
index b5d9ca2331697..8ce44b2212882 100644
--- a/libc/test/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/test/src/__support/FPUtil/CMakeLists.txt
@@ -54,6 +54,7 @@ add_fp_unittest(
add_fp_unittest(
float80_test
+ NEED_MPFR_F80
SUITE
libc-fputil-tests
SRCS
diff --git a/libc/test/src/__support/FPUtil/float80_test.cpp b/libc/test/src/__support/FPUtil/float80_test.cpp
index c59be71240b9d..dffea501cde0e 100644
--- a/libc/test/src/__support/FPUtil/float80_test.cpp
+++ b/libc/test/src/__support/FPUtil/float80_test.cpp
@@ -101,6 +101,9 @@ TEST(LlvmLibcFloat80Test, IntegerConversion) {
}
#ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+
+#include "utils/MPFRWrapper/MPCommon.h"
+
TEST(LlvmLibcFloat80Test, randomTest) {
using FPBitsL = LIBC_NAMESPACE::fputil::FPBits<long double>;
@@ -134,6 +137,22 @@ TEST(LlvmLibcFloat80Test, randomTest) {
}
}
+TEST(LlvmLibcFloat80Test, MPFRConversion) {
+ using LIBC_NAMESPACE::testing::mpfr::MPFRNumber;
+
+ Float80 values[] = {
+ Float80(0.0f), Float80(-0.0f), Float80(1.0f),
+ Float80(-1.0f), Float80(2.0f), Float80(0.5f),
+ Float80(100.0), Float80(12345.6789), Float80(1e10f),
+ };
+
+ for (Float80 val : values) {
+ MPFRNumber mpfr_val(val);
+ Float80 result = mpfr_val.as<Float80>();
+ EXPECT_TRUE(val == result);
+ }
+}
+
#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
TEST(LlvmLibcFloat80Test, FromIntegralTypes) {
diff --git a/libc/utils/MPFRWrapper/CMakeLists.txt b/libc/utils/MPFRWrapper/CMakeLists.txt
index 8efa6fc1f0b12..53ad5ef4aa48c 100644
--- a/libc/utils/MPFRWrapper/CMakeLists.txt
+++ b/libc/utils/MPFRWrapper/CMakeLists.txt
@@ -16,6 +16,7 @@ if(LIBC_TESTS_CAN_USE_MPFR OR LIBC_TESTS_CAN_USE_MPC)
libc.src.__support.CPP.type_traits
libc.src.__support.FPUtil.bfloat16
libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.float80
libc.src.__support.FPUtil.fp_bits
libc.test.UnitTest.FPTestHelpers
)
diff --git a/libc/utils/MPFRWrapper/MPCommon.cpp b/libc/utils/MPFRWrapper/MPCommon.cpp
index 2422bcf45222f..2901bed391416 100644
--- a/libc/utils/MPFRWrapper/MPCommon.cpp
+++ b/libc/utils/MPFRWrapper/MPCommon.cpp
@@ -11,6 +11,7 @@
#include "src/__support/CPP/string_view.h"
#include "src/__support/FPUtil/bfloat16.h"
#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/float80.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/types.h"
@@ -646,6 +647,12 @@ template <> float128 MPFRNumber::as<float128>() const {
}
#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
+#ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+template <> float80 MPFRNumber::as<float80>() const {
+ return fputil::cast<float80>(mpfr_get_ld(value, mpfr_rounding));
+}
+#endif
+
template <> bfloat16 MPFRNumber::as<bfloat16>() const {
return fputil::cast<bfloat16>(mpfr_get_flt(value, mpfr_rounding));
}
diff --git a/libc/utils/MPFRWrapper/MPCommon.h b/libc/utils/MPFRWrapper/MPCommon.h
index 38fd15fcc956c..1deda67da64e6 100644
--- a/libc/utils/MPFRWrapper/MPCommon.h
+++ b/libc/utils/MPFRWrapper/MPCommon.h
@@ -24,7 +24,7 @@ extern "C" {
int mpfr_set_float128(mpfr_ptr, float128, mpfr_rnd_t);
float128 mpfr_get_float128(mpfr_srcptr, mpfr_rnd_t);
}
-#endif
+#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
namespace LIBC_NAMESPACE_DECL {
namespace testing {
@@ -41,7 +41,7 @@ template <typename T> struct ExtraPrecision;
template <> struct ExtraPrecision<float16> {
static constexpr unsigned int VALUE = 128;
};
-#endif
+#endif // LIBC_TYPES_HAS_FLOAT16
template <> struct ExtraPrecision<float> {
static constexpr unsigned int VALUE = 128;
@@ -65,6 +65,12 @@ template <> struct ExtraPrecision<float128> {
};
#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
+#ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+template <> struct ExtraPrecision<float80> {
+ static constexpr unsigned int VALUE = 256;
+};
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+
template <> struct ExtraPrecision<bfloat16> {
static constexpr unsigned int VALUE = 64;
};
@@ -139,7 +145,12 @@ class MPFRNumber {
}
template <typename XType,
- cpp::enable_if_t<cpp::is_same_v<long double, XType>, int> = 0>
+ cpp::enable_if_t<cpp::is_same_v<long double, XType>
+#ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+ || cpp::is_same_v<float80, XType>
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+ ,
+ int> = 0>
explicit MPFRNumber(XType x,
unsigned int precision = ExtraPrecision<XType>::VALUE,
RoundingMode rounding = RoundingMode::Nearest)
More information about the libc-commits
mailing list