[libc-commits] [libc] [llvm] [libc] Make daddf128 use emulated Float128 type (PR #236437)

Sachin 🗲 via libc-commits libc-commits at lists.llvm.org
Wed Oct 28 08:01:16 PDT 2026


https://github.com/s4chinjha created https://github.com/llvm/llvm-project/pull/236437

this pr implements support for daddf128 to use the emulated f128 type

addresses #234601.

ref: #216560, #216575, #216508, #223769, #229855.

>From 6f26d1eacb75d28fa173b55af0b5a53f2b32fb25 Mon Sep 17 00:00:00 2001
From: s4chinjha <s4chinjha at gmail.com>
Date: Wed, 28 Oct 2026 19:46:06 +0530
Subject: [PATCH] [libc] add emulated f128 support for daddf128

---
 libc/config/baremetal/aarch64/entrypoints.txt |   2 +-
 libc/config/baremetal/arm/entrypoints.txt     |   2 +-
 libc/config/baremetal/hexagon/entrypoints.txt |   2 +-
 libc/config/baremetal/riscv/entrypoints.txt   |   2 +-
 libc/config/darwin/aarch64/entrypoints.txt    |   2 +-
 libc/config/darwin/x86_64/entrypoints.txt     |   1 +
 libc/config/freebsd/x86_64/entrypoints.txt    |   2 +-
 libc/config/gpu/amdgpu/entrypoints.txt        |   1 +
 libc/config/gpu/nvptx/entrypoints.txt         |   1 +
 libc/config/linux/aarch64/entrypoints.txt     |   2 +-
 libc/config/linux/arm/entrypoints.txt         |   1 +
 libc/config/linux/riscv/entrypoints.txt       |   2 +-
 libc/config/linux/x86_64/entrypoints.txt      |   2 +-
 libc/config/windows/entrypoints.txt           |   2 +-
 libc/shared/math/daddf128.h                   |   6 -
 libc/src/__support/math/CMakeLists.txt        |   2 +-
 libc/src/__support/math/daddf128.h            |  11 +-
 libc/src/math/daddf128.h                      |   5 +
 libc/src/math/generic/CMakeLists.txt          |   1 +
 libc/src/math/generic/daddf128.cpp            |   5 +-
 libc/test/shared/CMakeLists.txt               |   1 +
 .../shared/shared_math_constexpr_test.cpp     |   2 +
 libc/test/shared/shared_math_test.cpp         |   4 +-
 libc/test/src/math/CMakeLists.txt             |  13 ++
 libc/test/src/math/daddf128_test.cpp          | 111 ++++++++++++++++++
 libc/test/src/math/smoke/CMakeLists.txt       |   1 +
 libc/test/src/math/smoke/daddf128_test.cpp    |   6 +-
 libc/utils/MPFRWrapper/MPFRUtils.cpp          |   5 +
 .../llvm-project-overlay/libc/BUILD.bazel     |   4 +-
 .../libc/test/src/math/BUILD.bazel            |   7 ++
 .../libc/test/src/math/smoke/BUILD.bazel      |   3 +
 31 files changed, 183 insertions(+), 28 deletions(-)
 create mode 100644 libc/test/src/math/daddf128_test.cpp

diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 7ec212d8709692..aa2e95b43761cf 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -387,6 +387,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.cosf
     libc.src.math.coshf
     libc.src.math.cospif
+    libc.src.math.daddf128
     libc.src.math.dfmal
     libc.src.math.dmull
     libc.src.math.dsqrtl
@@ -766,7 +767,6 @@ if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     # math.h C23 _Float128 entrypoints
     libc.src.math.canonicalizef128
-    libc.src.math.daddf128
     libc.src.math.ddivf128
     libc.src.math.dfmaf128
     libc.src.math.dmulf128
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 779d9fc23b28e8..aa1db12949dcb7 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -399,6 +399,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.cosf
     libc.src.math.coshf
     libc.src.math.cospif
+    libc.src.math.daddf128
     libc.src.math.dfmal
     libc.src.math.dmull
     libc.src.math.dsqrtl
@@ -777,7 +778,6 @@ if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     # math.h C23 _Float128 entrypoints
     libc.src.math.canonicalizef128
-    libc.src.math.daddf128
     libc.src.math.ddivf128
     libc.src.math.dfmaf128
     libc.src.math.dmulf128
diff --git a/libc/config/baremetal/hexagon/entrypoints.txt b/libc/config/baremetal/hexagon/entrypoints.txt
index 61f869457b3282..3c7617bfa529b3 100644
--- a/libc/config/baremetal/hexagon/entrypoints.txt
+++ b/libc/config/baremetal/hexagon/entrypoints.txt
@@ -386,6 +386,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.cosf
     libc.src.math.coshf
     libc.src.math.cospif
+    libc.src.math.daddf128
     libc.src.math.dfmal
     libc.src.math.dmull
     libc.src.math.dsqrtl
@@ -741,7 +742,6 @@ if(LIBC_TYPES_HAS_FLOAT128)
     libc.src.math.canonicalizef128
     libc.src.math.ceilf128
     libc.src.math.copysignf128
-    libc.src.math.daddf128
     libc.src.math.ddivf128
     libc.src.math.dfmaf128
     libc.src.math.dmulf128
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index b847a2bb1f47f0..c98608be7aa907 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -390,6 +390,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.cosf
     libc.src.math.coshf
     libc.src.math.cospif
+    libc.src.math.daddf128
     libc.src.math.dfmal
     libc.src.math.dmull
     libc.src.math.dsqrtl
@@ -769,7 +770,6 @@ if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     # math.h C23 _Float128 entrypoints
     libc.src.math.canonicalizef128
-    libc.src.math.daddf128
     libc.src.math.ddivf128
     libc.src.math.dfmaf128
     libc.src.math.dmulf128
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 5600b82ad3410b..094a01f6aee2cc 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -208,6 +208,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.cosf
     libc.src.math.coshf
     libc.src.math.cospif
+    libc.src.math.daddf128
     libc.src.math.dfmal
     libc.src.math.dmull
     libc.src.math.dsqrtl
@@ -588,7 +589,6 @@ if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     # math.h C23 _Float128 entrypoints
     libc.src.math.canonicalizef128
-    libc.src.math.daddf128
     libc.src.math.ddivf128
     libc.src.math.dfmaf128
     libc.src.math.dmulf128
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index e3fc845d2ed3af..546f46735b32c0 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -129,6 +129,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     #libc.src.math.ceill
     #libc.src.math.coshf
     #libc.src.math.cosf
+    #libc.src.math.daddf128
     #libc.src.math.daddl
     #libc.src.math.ddivl
     #libc.src.math.dfmal
diff --git a/libc/config/freebsd/x86_64/entrypoints.txt b/libc/config/freebsd/x86_64/entrypoints.txt
index 8f6c178301c2f2..b7fccf0b693e50 100644
--- a/libc/config/freebsd/x86_64/entrypoints.txt
+++ b/libc/config/freebsd/x86_64/entrypoints.txt
@@ -141,6 +141,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.cos
     libc.src.math.cosf
     libc.src.math.coshf
+    libc.src.math.daddf128
     libc.src.math.daddl
     libc.src.math.ddivl
     libc.src.math.dfmal
@@ -521,7 +522,6 @@ if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     libc.src.math.atan2l
     libc.src.math.canonicalizef128
-    libc.src.math.daddf128
     libc.src.math.ddivf128
     libc.src.math.dfmaf128
     libc.src.math.dmulf128
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 2eaef608e9a7ac..e6aaa4fde75a72 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -333,6 +333,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.cosf
     libc.src.math.coshf
     libc.src.math.cospif
+    libc.src.math.daddf128
     libc.src.math.ddivl
     libc.src.math.dfmal
     libc.src.math.dmull
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index 79d0c733ec3c01..5fa2076d720922 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -329,6 +329,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.cosf
     libc.src.math.coshf
     libc.src.math.cospif
+    libc.src.math.daddf128
     libc.src.math.ddivl
     libc.src.math.dfmal
     libc.src.math.dmull
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 995d286b420653..bfbb1077970df2 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -626,6 +626,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.cosf
     libc.src.math.coshf
     libc.src.math.cospif
+    libc.src.math.daddf128
     libc.src.math.daddl
     libc.src.math.ddivl
     libc.src.math.dfmal
@@ -995,7 +996,6 @@ if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     # math.h C23 _Float128 entrypoints
     libc.src.math.canonicalizef128
-    libc.src.math.daddf128
     libc.src.math.ddivf128
     libc.src.math.dfmaf128
     libc.src.math.dmulf128
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 68df92046241a1..7572f54f03f333 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -421,6 +421,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.cos
     libc.src.math.cosf
     libc.src.math.coshf
+    libc.src.math.daddf128
     libc.src.math.dfmal
     libc.src.math.dsqrtl
     libc.src.math.erff
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 6138d25f0981f3..59efff725c236f 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -679,6 +679,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.cosf
     libc.src.math.coshf
     libc.src.math.cospif
+    libc.src.math.daddf128
     libc.src.math.daddl
     libc.src.math.ddivl
     libc.src.math.dfmal
@@ -1069,7 +1070,6 @@ if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
     # math.h C23 _Float128 entrypoints
     libc.src.math.atan2l
     libc.src.math.canonicalizef128
-    libc.src.math.daddf128
     libc.src.math.ddivf128
     libc.src.math.dfmaf128
     libc.src.math.dmulf128
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index f736986da9cf93..eec32d391a8542 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -701,6 +701,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.cosf
     libc.src.math.coshf
     libc.src.math.cospif
+    libc.src.math.daddf128
     libc.src.math.daddl
     libc.src.math.ddivl
     libc.src.math.dfmal
@@ -1091,7 +1092,6 @@ if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
     # math.h C23 _Float128 entrypoints
     libc.src.math.atan2l
     libc.src.math.canonicalizef128
-    libc.src.math.daddf128
     libc.src.math.ddivf128
     libc.src.math.dfmaf128
     libc.src.math.dmulf128
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 1712b2ad26fda4..1dc3d4868ff385 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -173,6 +173,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.cos
     libc.src.math.cosf
     libc.src.math.coshf
+    libc.src.math.daddf128
     libc.src.math.daddl
     libc.src.math.ddivl
     libc.src.math.dfmal
@@ -437,4 +438,3 @@ set(TARGET_LLVMLIBC_ENTRYPOINTS
   ${TARGET_LIBC_ENTRYPOINTS}
   ${TARGET_LIBM_ENTRYPOINTS}
 )
-
diff --git a/libc/shared/math/daddf128.h b/libc/shared/math/daddf128.h
index 5a1adbf1be637e..f9e81cf70baa38 100644
--- a/libc/shared/math/daddf128.h
+++ b/libc/shared/math/daddf128.h
@@ -9,10 +9,6 @@
 #ifndef LLVM_LIBC_SHARED_MATH_DADDF128_H
 #define LLVM_LIBC_SHARED_MATH_DADDF128_H
 
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
 #include "shared/libc_common.h"
 #include "src/__support/math/daddf128.h"
 
@@ -24,6 +20,4 @@ using math::daddf128;
 } // namespace shared
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
 #endif // LLVM_LIBC_SHARED_MATH_DADDF128_H
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 58f0730cba5756..1d726a3b3a5d11 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -2977,7 +2977,7 @@ add_header_library(
   HDRS
     daddf128.h
   DEPENDS
-    libc.include.llvm-libc-types.float128
+    libc.src.__support.FPUtil.float128
     libc.src.__support.FPUtil.generic.add_sub
     libc.src.__support.macros.config
 )
diff --git a/libc/src/__support/math/daddf128.h b/libc/src/__support/math/daddf128.h
index 4877455c059c34..f58c07ccbb569a 100644
--- a/libc/src/__support/math/daddf128.h
+++ b/libc/src/__support/math/daddf128.h
@@ -9,23 +9,20 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_MATH_DADDF128_H
 #define LLVM_LIBC_SRC___SUPPORT_MATH_DADDF128_H
 
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
+#include "src/__support/FPUtil/float128.h"
 #include "src/__support/FPUtil/generic/add_sub.h"
 #include "src/__support/macros/config.h"
 
 namespace LIBC_NAMESPACE_DECL {
 namespace math {
 
-LIBC_INLINE double daddf128(float128 x, float128 y) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr double daddf128(Float128 x, Float128 y) {
   return fputil::generic::add<double>(x, y);
 }
 
 } // namespace math
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
 #endif // LLVM_LIBC_SRC___SUPPORT_MATH_DADDF128_H
diff --git a/libc/src/math/daddf128.h b/libc/src/math/daddf128.h
index cf6c1999d9d030..dff2999eb47fa2 100644
--- a/libc/src/math/daddf128.h
+++ b/libc/src/math/daddf128.h
@@ -9,11 +9,16 @@
 #ifndef LLVM_LIBC_SRC_MATH_DADDF128_H
 #define LLVM_LIBC_SRC_MATH_DADDF128_H
 
+#include "src/__support/FPUtil/float128.h"
 #include "src/__support/macros/config.h"
 #include "src/__support/macros/properties/types.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
+#ifndef LIBC_TYPES_HAS_NATIVE_FLOAT128
+using float128 = LIBC_NAMESPACE::fputil::Float128;
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
+
 double daddf128(float128 x, float128 y);
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 17f586036396f1..0efb1edec1c216 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -193,6 +193,7 @@ add_entrypoint_object(
   HDRS
     ../daddf128.h
   DEPENDS
+    libc.src.__support.CPP.bit
     libc.src.__support.math.daddf128
 )
 
diff --git a/libc/src/math/generic/daddf128.cpp b/libc/src/math/generic/daddf128.cpp
index 10b3ec6c30c6c7..cc0727f70f49f8 100644
--- a/libc/src/math/generic/daddf128.cpp
+++ b/libc/src/math/generic/daddf128.cpp
@@ -7,12 +7,15 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/math/daddf128.h"
+#include "src/__support/CPP/bit.h"
 #include "src/__support/math/daddf128.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
+using LIBC_NAMESPACE::fputil::Float128;
+
 LLVM_LIBC_FUNCTION(double, daddf128, (float128 x, float128 y)) {
-  return math::daddf128(x, y);
+  return math::daddf128(cpp::bit_cast<Float128>(x), cpp::bit_cast<Float128>(y));
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index 9d46e7691d2625..a6f7413099e8a3 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -550,6 +550,7 @@ else()
       libc.src.__support.math.copysignf128
       libc.src.__support.math.copysignf16
       libc.src.__support.math.copysignl
+      libc.src.__support.math.daddf128
       libc.src.__support.math.ddivf128
       libc.src.__support.math.ddivl
       libc.src.__support.math.dmulf128
diff --git a/libc/test/shared/shared_math_constexpr_test.cpp b/libc/test/shared/shared_math_constexpr_test.cpp
index ec7f99a9ff40c0..5cf82f76fd9e8d 100644
--- a/libc/test/shared/shared_math_constexpr_test.cpp
+++ b/libc/test/shared/shared_math_constexpr_test.cpp
@@ -402,6 +402,8 @@ static_assert(Float128(0.0) == LIBC_NAMESPACE::shared::ceilf128(Float128(0.0)));
 static_assert(Float128(0.0) ==
               LIBC_NAMESPACE::shared::copysignf128(Float128(0.0),
                                                    Float128(0.0)));
+static_assert(0.0 ==
+              LIBC_NAMESPACE::shared::daddf128(Float128(0.0), Float128(0.0)));
 static_assert(Float128(1.0) ==
               LIBC_NAMESPACE::shared::fabsf128(Float128(-1.0)));
 static_assert(Float128(1.0) ==
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index d0581b5dababa9..88c0d7bf49e59b 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -588,6 +588,8 @@ TEST(LlvmLibcSharedMathTest, AllEmuFloat128) {
   EXPECT_FP_EQ(Float128(0.0), LIBC_NAMESPACE::shared::ceilf128(Float128(0.0)));
   EXPECT_FP_EQ(Float128(0.0), LIBC_NAMESPACE::shared::copysignf128(
                                   Float128(0.0), Float128(0.0)));
+  EXPECT_FP_EQ(0.0,
+               LIBC_NAMESPACE::shared::daddf128(Float128(0.0), Float128(0.0)));
   EXPECT_FP_EQ(Float128(0.0), LIBC_NAMESPACE::shared::fabsf128(Float128(0.0)));
   EXPECT_FP_EQ(Float128(0.0),
                LIBC_NAMESPACE::shared::fdimf128(Float128(0.0), Float128(0.0)));
@@ -671,7 +673,7 @@ TEST(LlvmLibcSharedMathTest, AllFloat128) {
                                   float128(0.0), float128(0.0)));
   EXPECT_FP_EQ(bfloat16(2.0), LIBC_NAMESPACE::shared::bf16divf128(
                                   float128(4.0), float128(2.0)));
-  EXPECT_FP_EQ(float128(0.0),
+  EXPECT_FP_EQ(0.0,
                LIBC_NAMESPACE::shared::daddf128(float128(0.0), float128(0.0)));
   EXPECT_FP_EQ(1.0,
                LIBC_NAMESPACE::shared::ddivf128(float128(1.0), float128(1.0)));
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 764dd56d95b138..37ded798acbaae 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -70,6 +70,19 @@ add_fp_unittest(
     libc.src.math.cospif16
 )
 
+add_fp_unittest(
+  daddf128_test
+  NEED_MPFR_F128
+  SUITE
+    libc-math-unittests
+  SRCS
+    daddf128_test.cpp
+  DEPENDS
+    libc.src.math.daddf128
+    libc.src.__support.FPUtil.float128
+    libc.src.__support.FPUtil.fp_bits
+)
+
 add_fp_unittest(
   daddl_test
   NEED_MPFR
diff --git a/libc/test/src/math/daddf128_test.cpp b/libc/test/src/math/daddf128_test.cpp
new file mode 100644
index 00000000000000..5f2e5fcc059229
--- /dev/null
+++ b/libc/test/src/math/daddf128_test.cpp
@@ -0,0 +1,111 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// MPFR tests for the daddf128 function.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/float128.h"
+#include "src/math/daddf128.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+#ifndef LIBC_TYPES_HAS_NATIVE_FLOAT128
+using float128 = LIBC_NAMESPACE::fputil::Float128;
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+using LlvmLibcDaddf128MPFRTest = LIBC_NAMESPACE::testing::FPTest<float128>;
+using LIBC_NAMESPACE::testing::tlog;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+TEST_F(LlvmLibcDaddf128MPFRTest, InQuadRange) {
+  constexpr StorageType X_COUNT = 123;
+  constexpr StorageType X_START = FPBits(static_cast<float128>(0.25)).uintval();
+  constexpr StorageType X_STOP = FPBits(static_cast<float128>(4.0)).uintval();
+  constexpr StorageType X_STEP = (X_STOP - X_START) / X_COUNT;
+
+  constexpr StorageType Y_COUNT = 137;
+  constexpr StorageType Y_START = FPBits(static_cast<float128>(0.25)).uintval();
+  constexpr StorageType Y_STOP = FPBits(static_cast<float128>(4.0)).uintval();
+  constexpr StorageType Y_STEP = (Y_STOP - Y_START) / Y_COUNT;
+
+  auto test = [&](mpfr::RoundingMode rounding_mode) {
+    mpfr::ForceRoundingMode __r(rounding_mode);
+    if (!__r.success)
+      return;
+
+    uint64_t fails = 0;
+    uint64_t finite_count = 0;
+    uint64_t total_count = 0;
+    float128 failed_x = 0.0, failed_y = 0.0;
+    double failed_r = 0.0;
+    double tol = 0.5;
+
+    for (StorageType i = 0, v = X_START; i <= X_COUNT; ++i, v += X_STEP) {
+      float128 x = FPBits(v).get_val();
+      if (FPBits(x).is_inf_or_nan() || x < float128(0.0))
+        continue;
+
+      for (StorageType j = 0, w = Y_START; j <= Y_COUNT; ++j, w += Y_STEP) {
+        float128 y = FPBits(w).get_val();
+        if (FPBits(y).is_inf_or_nan() || y < float128(0.0))
+          continue;
+
+        double result = LIBC_NAMESPACE::daddf128(x, y);
+        ++total_count;
+        if (LIBC_NAMESPACE::fputil::FPBits<double>(result).is_inf_or_nan())
+          continue;
+
+        ++finite_count;
+        mpfr::BinaryInput<float128> inputs{x, y};
+
+        // daddf128 is correctly rounded to double, so require 0.5 ULP.
+        if (!TEST_MPFR_MATCH_ROUNDING_SILENTLY(mpfr::Operation::Add, inputs,
+                                               result, 0.5, rounding_mode)) {
+          ++fails;
+          while (!TEST_MPFR_MATCH_ROUNDING_SILENTLY(
+              mpfr::Operation::Add, inputs, result, tol, rounding_mode)) {
+            failed_x = x;
+            failed_y = y;
+            failed_r = result;
+
+            if (tol > 1000.0)
+              break;
+
+            tol *= 2.0;
+          }
+        }
+      }
+    }
+    if (fails || (finite_count < total_count)) {
+      tlog << " daddf128 failed: " << fails << "/" << finite_count << "/"
+           << total_count << " tests.\n"
+           << "   Max ULPs is at most: " << static_cast<uint64_t>(tol) << ".\n";
+    }
+    if (fails) {
+      mpfr::BinaryInput<float128> inputs{failed_x, failed_y};
+      EXPECT_MPFR_MATCH(mpfr::Operation::Add, inputs, failed_r, 0.5,
+                        rounding_mode);
+    }
+  };
+
+  tlog << " Test Rounding To Nearest...\n";
+  test(mpfr::RoundingMode::Nearest);
+
+  tlog << " Test Rounding Downward...\n";
+  test(mpfr::RoundingMode::Downward);
+
+  tlog << " Test Rounding Upward...\n";
+  test(mpfr::RoundingMode::Upward);
+
+  tlog << " Test Rounding Toward Zero...\n";
+  test(mpfr::RoundingMode::TowardZero);
+}
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index ca299171fc6b8f..2ca924443bf426 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -6399,6 +6399,7 @@ add_fp_unittest(
     libc.hdr.errno_macros
     libc.hdr.fenv_macros
     libc.src.math.daddf128
+    libc.src.__support.FPUtil.float128
     libc.src.__support.macros.properties.os
 )
 
diff --git a/libc/test/src/math/smoke/daddf128_test.cpp b/libc/test/src/math/smoke/daddf128_test.cpp
index 6595f0e4f068a9..90f7319418be15 100644
--- a/libc/test/src/math/smoke/daddf128_test.cpp
+++ b/libc/test/src/math/smoke/daddf128_test.cpp
@@ -7,7 +7,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "AddTest.h"
-
+#include "src/__support/FPUtil/float128.h"
 #include "src/math/daddf128.h"
 
+#ifndef LIBC_TYPES_HAS_NATIVE_FLOAT128
+using float128 = LIBC_NAMESPACE::fputil::Float128;
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
+
 LIST_ADD_TESTS(Daddf128, double, float128, LIBC_NAMESPACE::daddf128)
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp
index 83500cb59de9d8..c8a9f8ed927a3d 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.cpp
+++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp
@@ -440,6 +440,8 @@ template void explain_binary_operation_one_output_error(
     defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE)
 template void explain_binary_operation_one_output_error(
     Operation, const BinaryInput<float128> &, float128, double, RoundingMode);
+template void explain_binary_operation_one_output_error(
+    Operation, const BinaryInput<float128> &, double, double, RoundingMode);
 #endif
 template void explain_binary_operation_one_output_error(
     Operation, const BinaryInput<bfloat16> &, bfloat16, double, RoundingMode);
@@ -724,6 +726,9 @@ template bool compare_binary_operation_one_output(Operation,
                                                   const BinaryInput<float128> &,
                                                   float128, double,
                                                   RoundingMode);
+template bool compare_binary_operation_one_output(Operation,
+                                                  const BinaryInput<float128> &,
+                                                  double, double, RoundingMode);
 #endif
 template bool compare_binary_operation_one_output(Operation,
                                                   const BinaryInput<bfloat16> &,
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 58708f0f1b72a2..2eebe136d09962 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -8732,7 +8732,7 @@ libc_support_library(
     deps = [
         ":__support_fputil_basic_operations",
         ":__support_macros_config",
-        ":llvm_libc_types_float128",
+        ":__support_fputil_float128",
     ],
 )
 
@@ -12953,6 +12953,8 @@ libc_math_function(
 libc_math_function(
     name = "daddf128",
     additional_deps = [
+        ":__support_cpp_bit",
+        ":__support_fputil_float128",
         ":__support_math_daddf128",
     ],
 )
diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel
index cdb8d203c06e11..6835059ad43d4b 100644
--- a/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel
@@ -144,6 +144,13 @@ math_mpfr_test(
     ],
 )
 
+math_mpfr_test(
+    name = "daddf128",
+    deps = [
+        "//libc:__support_fputil_float128",
+    ],
+)
+
 math_mpfr_test(
     name = "daddl",
     hdrs = ["AddTest.h"],
diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/math/smoke/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/math/smoke/BUILD.bazel
index 40e8163f8a86e9..0ec4d6170229d7 100644
--- a/utils/bazel/llvm-project-overlay/libc/test/src/math/smoke/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/test/src/math/smoke/BUILD.bazel
@@ -267,6 +267,9 @@ math_test(
 math_test(
     name = "daddf128",
     hdrs = ["AddTest.h"],
+    deps = [
+        "//libc:__support_fputil_float128",
+    ],
 )
 
 math_test(



More information about the libc-commits mailing list