[libc-commits] [libc] [libc] Enables MPFR for float80 and adds tests for it (PR #223800)

via libc-commits libc-commits at lists.llvm.org
Fri Sep 18 13:05:35 PDT 2026


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

>From 8de0f9c178bf66dea8eadee528a39d82e841acab Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 16 Sep 2026 01:10:10 +0530
Subject: [PATCH 1/5] add mpfr for float80 and tests for it

---
 libc/test/src/__support/FPUtil/CMakeLists.txt   |  1 +
 libc/test/src/__support/FPUtil/float80_test.cpp | 17 +++++++++++++++++
 libc/utils/MPFRWrapper/CMakeLists.txt           |  1 +
 libc/utils/MPFRWrapper/MPCommon.cpp             |  7 +++++++
 libc/utils/MPFRWrapper/MPCommon.h               | 13 ++++++++++++-
 5 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/libc/test/src/__support/FPUtil/CMakeLists.txt b/libc/test/src/__support/FPUtil/CMakeLists.txt
index b5d9ca23316972..994cc1fef4d0b9 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
   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 c59be71240b9d6..e9850caa219f29 100644
--- a/libc/test/src/__support/FPUtil/float80_test.cpp
+++ b/libc/test/src/__support/FPUtil/float80_test.cpp
@@ -11,6 +11,7 @@
 #include "src/__support/FPUtil/float80.h"
 #include "test/UnitTest/FPMatcher.h"
 #include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPCommon.h"
 
 using LIBC_NAMESPACE::Sign;
 using LIBC_NAMESPACE::fputil::Float80;
@@ -134,6 +135,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 8efa6fc1f0b126..53ad5ef4aa48cd 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 2422bcf45222f7..2901bed3914160 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 38fd15fcc956c1..2503e68bc64dbb 100644
--- a/libc/utils/MPFRWrapper/MPCommon.h
+++ b/libc/utils/MPFRWrapper/MPCommon.h
@@ -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
+
 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
+                             ,
+                             int> = 0>
   explicit MPFRNumber(XType x,
                       unsigned int precision = ExtraPrecision<XType>::VALUE,
                       RoundingMode rounding = RoundingMode::Nearest)

>From 21e1b85b04b1f324a192de5b85db521e0bb99ed7 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 16 Sep 2026 01:17:12 +0530
Subject: [PATCH 2/5] nit

---
 libc/utils/MPFRWrapper/MPCommon.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libc/utils/MPFRWrapper/MPCommon.h b/libc/utils/MPFRWrapper/MPCommon.h
index 2503e68bc64dbb..07d1228724ccce 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;
@@ -148,7 +148,7 @@ class MPFRNumber {
             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
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
                              ,
                              int> = 0>
   explicit MPFRNumber(XType x,

>From e40767306d10471a6db2dfa1512ae274a3fa7d27 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 16 Sep 2026 11:46:23 +0530
Subject: [PATCH 3/5] nits

---
 libc/test/src/__support/FPUtil/float80_test.cpp | 10 ++++++----
 libc/utils/MPFRWrapper/MPCommon.h               |  2 +-
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/libc/test/src/__support/FPUtil/float80_test.cpp b/libc/test/src/__support/FPUtil/float80_test.cpp
index e9850caa219f29..562ebc2006b476 100644
--- a/libc/test/src/__support/FPUtil/float80_test.cpp
+++ b/libc/test/src/__support/FPUtil/float80_test.cpp
@@ -11,7 +11,6 @@
 #include "src/__support/FPUtil/float80.h"
 #include "test/UnitTest/FPMatcher.h"
 #include "test/UnitTest/Test.h"
-#include "utils/MPFRWrapper/MPCommon.h"
 
 using LIBC_NAMESPACE::Sign;
 using LIBC_NAMESPACE::fputil::Float80;
@@ -102,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>;
 
@@ -139,9 +141,9 @@ 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),
+      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) {
diff --git a/libc/utils/MPFRWrapper/MPCommon.h b/libc/utils/MPFRWrapper/MPCommon.h
index 07d1228724ccce..1deda67da64e6c 100644
--- a/libc/utils/MPFRWrapper/MPCommon.h
+++ b/libc/utils/MPFRWrapper/MPCommon.h
@@ -69,7 +69,7 @@ template <> struct ExtraPrecision<float128> {
 template <> struct ExtraPrecision<float80> {
   static constexpr unsigned int VALUE = 256;
 };
-#endif
+#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
 
 template <> struct ExtraPrecision<bfloat16> {
   static constexpr unsigned int VALUE = 64;

>From bed89a132180979085737c59b8f2d9b4c5abcf9e Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sat, 19 Sep 2026 01:29:50 +0530
Subject: [PATCH 4/5] add NEED_MPFR_F80

---
 libc/test/src/CMakeLists.txt                  | 10 +++++++++-
 libc/test/src/__support/FPUtil/CMakeLists.txt |  2 +-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index 463485768dcdee..38feadb7c59871 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 x86 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 994cc1fef4d0b9..8ce44b22128820 100644
--- a/libc/test/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/test/src/__support/FPUtil/CMakeLists.txt
@@ -54,7 +54,7 @@ add_fp_unittest(
 
 add_fp_unittest(
   float80_test
-  NEED_MPFR
+  NEED_MPFR_F80
   SUITE
     libc-fputil-tests
   SRCS

>From fef1d112e75ae250b375e7fb4f4fc9ccca504677 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sat, 19 Sep 2026 01:35:12 +0530
Subject: [PATCH 5/5] clang-format

---
 libc/test/src/CMakeLists.txt                    | 2 +-
 libc/test/src/__support/FPUtil/float80_test.cpp | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index 38feadb7c59871..5018f7e15b66da 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -19,7 +19,7 @@ function(add_fp_unittest name)
   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 x86 float80 support in MPFR is not available.")
+      message(VERBOSE "Math test ${name} will be skipped as float80 support in MPFR is not available.")
       return()
     endif()
   endif()
diff --git a/libc/test/src/__support/FPUtil/float80_test.cpp b/libc/test/src/__support/FPUtil/float80_test.cpp
index 562ebc2006b476..dffea501cde0ee 100644
--- a/libc/test/src/__support/FPUtil/float80_test.cpp
+++ b/libc/test/src/__support/FPUtil/float80_test.cpp
@@ -141,9 +141,9 @@ 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),
+      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) {



More information about the libc-commits mailing list