[libc-commits] [libc] [libc] Modify `atan2f128` to use emulated Float128 type (PR #216508)

via libc-commits libc-commits at lists.llvm.org
Sun Aug 16 01:02:54 PDT 2026


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

>From 4520ab21427d861acdfc64d5e8e0fd7369c8765d Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 16 Aug 2026 02:06:31 +0530
Subject: [PATCH 1/6] initial commit

---
 libc/config/baremetal/aarch64/entrypoints.txt | 2 +-
 libc/config/baremetal/arm/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           | 1 +
 13 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 81958d224f70d..b107d7c765507 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -359,6 +359,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.asinpif
     libc.src.math.atan2
     libc.src.math.atan2f
+    libc.src.math.atan2f128
     # libc.src.math.atan2l
     libc.src.math.atan
     libc.src.math.atanf
@@ -731,7 +732,6 @@ endif()
 if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     # math.h C23 _Float128 entrypoints
-    libc.src.math.atan2f128
     libc.src.math.canonicalizef128
     libc.src.math.copysignf128
     libc.src.math.daddf128
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index ee3ec63132cc2..b574cd9190862 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -371,6 +371,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.asinpif
     libc.src.math.atan2
     libc.src.math.atan2f
+    libc.src.math.atan2f128
     libc.src.math.atan2l
     libc.src.math.atan
     libc.src.math.atanf
@@ -742,7 +743,6 @@ endif()
 if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     # math.h C23 _Float128 entrypoints
-    libc.src.math.atan2f128
     libc.src.math.canonicalizef128
     libc.src.math.copysignf128
     libc.src.math.daddf128
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index c9f7c042bf4a8..3b250b0be6e5b 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -367,6 +367,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.asinpif
     libc.src.math.atan2
     libc.src.math.atan2f
+    libc.src.math.atan2f128
     # libc.src.math.atan2l
     libc.src.math.atan
     libc.src.math.atanf
@@ -739,7 +740,6 @@ endif()
 if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     # math.h C23 _Float128 entrypoints
-    libc.src.math.atan2f128
     libc.src.math.canonicalizef128
     libc.src.math.copysignf128
     libc.src.math.daddf128
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 0ca00419a916c..d66c509756d5c 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -179,6 +179,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.asinpif
     libc.src.math.atan2
     libc.src.math.atan2f
+    libc.src.math.atan2f128
     libc.src.math.atan
     libc.src.math.atanf
     libc.src.math.atanhf
@@ -551,7 +552,6 @@ endif()
 if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     # math.h C23 _Float128 entrypoints
-    libc.src.math.atan2f128
     libc.src.math.canonicalizef128
     libc.src.math.copysignf128
     libc.src.math.daddf128
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index 136d5a458d484..118d5d48ce37b 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -118,6 +118,7 @@ set(TARGET_LIBM_ENTRYPOINTS
 
     ## Currently disabled for failing tests.
     # math.h entrypoints
+    #libc.src.math.atan2f128
     #libc.src.math.copysign
     #libc.src.math.copysignf
     #libc.src.math.copysignl
diff --git a/libc/config/freebsd/x86_64/entrypoints.txt b/libc/config/freebsd/x86_64/entrypoints.txt
index 2223504718444..d096a542e726b 100644
--- a/libc/config/freebsd/x86_64/entrypoints.txt
+++ b/libc/config/freebsd/x86_64/entrypoints.txt
@@ -125,6 +125,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.asinhf
     libc.src.math.atan2
     libc.src.math.atan2f
+    libc.src.math.atan2f128
     libc.src.math.atanf
     libc.src.math.atanhf
     libc.src.math.cbrt
@@ -489,7 +490,6 @@ endif()
 
 if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
-    libc.src.math.atan2f128
     libc.src.math.atan2l
     libc.src.math.canonicalizef128
     libc.src.math.copysignf128
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 12783aa4e5316..25b8b3c077d4c 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -311,6 +311,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.atan
     libc.src.math.atan2
     libc.src.math.atan2f
+    libc.src.math.atan2f128
     libc.src.math.atan2l
     libc.src.math.atanf
     libc.src.math.atanhf
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index 5820448e06663..98274141410d4 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -307,6 +307,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.atan
     libc.src.math.atan2
     libc.src.math.atan2f
+    libc.src.math.atan2f128
     libc.src.math.atan2l
     libc.src.math.atanf
     libc.src.math.atanhf
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 071a7830b43d3..95de08a934471 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -517,6 +517,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.asinpif
     libc.src.math.atan2
     libc.src.math.atan2f
+    libc.src.math.atan2f128
     libc.src.math.atan
     libc.src.math.atanf
     libc.src.math.atanhf
@@ -878,7 +879,6 @@ endif()
 if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     # math.h C23 _Float128 entrypoints
-    libc.src.math.atan2f128
     libc.src.math.canonicalizef128
     libc.src.math.copysignf128
     libc.src.math.daddf128
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 1adbb04bb4cbe..371afe56307a8 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -357,6 +357,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.asinpif
     libc.src.math.atan2
     libc.src.math.atan2f
+    libc.src.math.atan2f128
     libc.src.math.atan
     libc.src.math.atanf
     libc.src.math.atanhf
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 66dd9dd790737..458729ca769ea 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -586,6 +586,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.asinpif
     libc.src.math.atan2
     libc.src.math.atan2f
+    libc.src.math.atan2f128
     libc.src.math.atan
     libc.src.math.atanf
     libc.src.math.atanhf
@@ -967,7 +968,6 @@ endif()
 if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     # math.h C23 _Float128 entrypoints
-    libc.src.math.atan2f128
     libc.src.math.atan2l
     libc.src.math.canonicalizef128
     libc.src.math.copysignf128
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 6045886c2f11c..1dc33d59150ee 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -591,6 +591,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.asinpif
     libc.src.math.atan2
     libc.src.math.atan2f
+    libc.src.math.atan2f128
     libc.src.math.atan
     libc.src.math.atanf
     libc.src.math.atanhf
@@ -972,7 +973,6 @@ endif()
 if(LIBC_TYPES_HAS_NATIVE_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     # math.h C23 _Float128 entrypoints
-    libc.src.math.atan2f128
     libc.src.math.atan2l
     libc.src.math.canonicalizef128
     libc.src.math.copysignf128
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 142b83e71efe6..339eff084d653 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -155,6 +155,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.asinpif
     libc.src.math.atan2
     libc.src.math.atan2f
+    libc.src.math.atan2f128
     libc.src.math.atan
     libc.src.math.atanf
     libc.src.math.atanhf

>From 3be5e30755ca5b4c37cb52b2d599437f2b1caf56 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 16 Aug 2026 02:29:07 +0530
Subject: [PATCH 2/6] modify atanf128 to use emulated type + tests

---
 libc/shared/math/atan2f128.h                |  6 ---
 libc/src/__support/math/CMakeLists.txt      |  1 +
 libc/src/__support/math/atan2f128.h         | 19 ++++------
 libc/src/math/atan2f128.h                   |  5 +++
 libc/src/math/generic/CMakeLists.txt        |  1 +
 libc/src/math/generic/atan2f128.cpp         |  6 ++-
 libc/test/shared/shared_math_test.cpp       |  4 +-
 libc/test/src/math/CMakeLists.txt           |  1 +
 libc/test/src/math/atan2f128_test.cpp       | 17 +++++----
 libc/test/src/math/smoke/CMakeLists.txt     |  2 +
 libc/test/src/math/smoke/atan2f128_test.cpp | 41 ++++++++++++++++-----
 11 files changed, 66 insertions(+), 37 deletions(-)

diff --git a/libc/shared/math/atan2f128.h b/libc/shared/math/atan2f128.h
index 45a970c814b06..7a7fab1c37642 100644
--- a/libc/shared/math/atan2f128.h
+++ b/libc/shared/math/atan2f128.h
@@ -9,10 +9,6 @@
 #ifndef LLVM_LIBC_SHARED_MATH_ATAN2F128_H
 #define LLVM_LIBC_SHARED_MATH_ATAN2F128_H
 
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
 #include "shared/libc_common.h"
 #include "src/__support/math/atan2f128.h"
 
@@ -24,6 +20,4 @@ using math::atan2f128;
 } // namespace shared
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
 #endif // LLVM_LIBC_SHARED_MATH_ATAN2F128_H
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index db514db61a9df..5facf9f282923 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -318,6 +318,7 @@ add_header_library(
     libc.src.__support.uint128
     libc.src.__support.FPUtil.dyadic_float
     libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.float128
     libc.src.__support.FPUtil.multiply_add
     libc.src.__support.FPUtil.nearest_integer
     libc.src.__support.macros.optimization
diff --git a/libc/src/__support/math/atan2f128.h b/libc/src/__support/math/atan2f128.h
index 5907f54a540c5..2c42b02a51265 100644
--- a/libc/src/__support/math/atan2f128.h
+++ b/libc/src/__support/math/atan2f128.h
@@ -9,13 +9,10 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ATAN2F128_H
 #define LLVM_LIBC_SRC___SUPPORT_MATH_ATAN2F128_H
 
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
 #include "atan_utils.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/dyadic_float.h"
+#include "src/__support/FPUtil/float128.h"
 #include "src/__support/FPUtil/nearest_integer.h"
 #include "src/__support/integer_literals.h"
 #include "src/__support/macros/config.h"
@@ -26,6 +23,8 @@ namespace LIBC_NAMESPACE_DECL {
 
 namespace math {
 
+using LIBC_NAMESPACE::fputil::Float128;
+
 // There are several range reduction steps we can take for atan2(y, x) as
 // follow:
 
@@ -81,7 +80,7 @@ namespace math {
 // and relative errors bounded by:
 //   |(atan(u) - P(u)) / P(u)| < 2^-114.
 
-LIBC_INLINE float128 atan2f128(float128 y, float128 x) {
+LIBC_INLINE Float128 atan2f128(Float128 y, Float128 x) {
   using DFloat128 = fputil::DyadicFloat<128>;
 
   constexpr DFloat128 ZERO = {Sign::POS, 0, 0_u128};
@@ -106,7 +105,7 @@ LIBC_INLINE float128 atan2f128(float128 y, float128 x) {
       {{MPI, PI_OVER_2}, {MPI, PI_OVER_2}}};
 
   using namespace atan_internal;
-  using FPBits = fputil::FPBits<float128>;
+  using FPBits = fputil::FPBits<Float128>;
   using DFloat128 = fputil::DyadicFloat<128>;
 
   FPBits x_bits(x), y_bits(y);
@@ -151,7 +150,7 @@ LIBC_INLINE float128 atan2f128(float128 y, float128 x) {
       DFloat128 r = EXCEPTS[y_except][x_except][x_sign];
       if (y_sign)
         r.sign = r.sign.negate();
-      return static_cast<float128>(r);
+      return static_cast<Float128>(r);
     }
   }
 
@@ -165,7 +164,7 @@ LIBC_INLINE float128 atan2f128(float128 y, float128 x) {
     DFloat128 result = quick_add(const_term, quotient);
     if (final_sign)
       result.sign = result.sign.negate();
-    return static_cast<float128>(result);
+    return static_cast<Float128>(result);
   }
 
   // Take 24 leading bits of num and den to convert to float for fast division.
@@ -203,13 +202,11 @@ LIBC_INLINE float128 atan2f128(float128 y, float128 x) {
   if (final_sign)
     r.sign = r.sign.negate();
 
-  return static_cast<float128>(r);
+  return static_cast<Float128>(r);
 }
 
 } // namespace math
 
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
 #endif // LLVM_LIBC_SRC___SUPPORT_MATH_ATAN2F128_H
diff --git a/libc/src/math/atan2f128.h b/libc/src/math/atan2f128.h
index 26f7ec624940c..a15a7a52497b5 100644
--- a/libc/src/math/atan2f128.h
+++ b/libc/src/math/atan2f128.h
@@ -9,9 +9,14 @@
 #ifndef LLVM_LIBC_SRC_MATH_ATAN2F128_H
 #define LLVM_LIBC_SRC_MATH_ATAN2F128_H
 
+#include "src/__support/FPUtil/float128.h"
 #include "src/__support/macros/config.h"
 #include "src/__support/macros/properties/types.h"
 
+#ifndef LIBC_TYPES_HAS_NATIVE_FLOAT128
+using float128 = LIBC_NAMESPACE::fputil::Float128;
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
+
 namespace LIBC_NAMESPACE_DECL {
 
 float128 atan2f128(float128 x, float128 y);
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 80c2053066f16..70507fff2fa9a 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4039,6 +4039,7 @@ add_entrypoint_object(
     ../atan2f128.h
   DEPENDS
     libc.src.__support.math.atan2f128
+    libc.src.__support.CPP.bit
 )
 
 add_entrypoint_object(
diff --git a/libc/src/math/generic/atan2f128.cpp b/libc/src/math/generic/atan2f128.cpp
index ec051ddd4e00b..06cbd03188b51 100644
--- a/libc/src/math/generic/atan2f128.cpp
+++ b/libc/src/math/generic/atan2f128.cpp
@@ -7,12 +7,16 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/math/atan2f128.h"
+#include "src/__support/CPP/bit.h"
 #include "src/__support/math/atan2f128.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
+using LIBC_NAMESPACE::fputil::Float128;
+
 LLVM_LIBC_FUNCTION(float128, atan2f128, (float128 y, float128 x)) {
-  return math::atan2f128(y, x);
+  return cpp::bit_cast<float128>(
+      math::atan2f128(cpp::bit_cast<Float128>(y), cpp::bit_cast<Float128>(x)));
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index 8850deda1c805..d6a7b4ac099ad 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -582,6 +582,8 @@ TEST(LlvmLibcSharedMathTest, AllLongDouble) {
 // Emulated float128 tests
 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::atan2f128(Float128(0.0), Float128(0.0)));
 }
 
 #ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
@@ -590,8 +592,6 @@ TEST(LlvmLibcSharedMathTest, AllFloat128) {
   using FPBits = LIBC_NAMESPACE::fputil::FPBits<float128>;
   int exponent;
 
-  EXPECT_FP_EQ(float128(0.0),
-               LIBC_NAMESPACE::shared::atan2f128(float128(0.0), float128(0.0)));
   EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::shared::ffmaf128(
                          float128(0.0), float128(0.0), float128(0.0)));
   EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::shared::fsqrtf128(float128(1.0f)));
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index bf337783bfe23..15b07f2dd7d9f 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2874,6 +2874,7 @@ add_fp_unittest(
     atan2f128_test.cpp
   DEPENDS
     libc.src.math.atan2f128
+    libc.src.__support.FPUtil.float128
     libc.src.__support.FPUtil.fp_bits
 )
 
diff --git a/libc/test/src/math/atan2f128_test.cpp b/libc/test/src/math/atan2f128_test.cpp
index 0bfec1bd276ed..824a0765c2192 100644
--- a/libc/test/src/math/atan2f128_test.cpp
+++ b/libc/test/src/math/atan2f128_test.cpp
@@ -6,11 +6,16 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "src/__support/FPUtil/float128.h"
 #include "src/math/atan2f128.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 LlvmLibcAtan2f128Test = LIBC_NAMESPACE::testing::FPTest<float128>;
 using LIBC_NAMESPACE::testing::tlog;
 
@@ -18,15 +23,13 @@ namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
 
 TEST_F(LlvmLibcAtan2f128Test, InQuadRange) {
   constexpr StorageType X_COUNT = 123;
-  constexpr StorageType X_START =
-      FPBits(static_cast<float128>(0.25q)).uintval();
-  constexpr StorageType X_STOP = FPBits(static_cast<float128>(4.0q)).uintval();
+  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.25q)).uintval();
-  constexpr StorageType Y_STOP = FPBits(static_cast<float128>(4.0q)).uintval();
+  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) {
@@ -42,7 +45,7 @@ TEST_F(LlvmLibcAtan2f128Test, InQuadRange) {
 
     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 < 0.0q)
+      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) {
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 91d76f2c7973c..8efa4a3ba3eb3 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -5065,6 +5065,8 @@ add_fp_unittest(
     atan2f128_test.cpp
   DEPENDS
     libc.src.math.atan2f128
+    libc.src.__support.FPUtil.float128
+    libc.src.__support.integer_literals
 )
 
 add_fp_unittest(
diff --git a/libc/test/src/math/smoke/atan2f128_test.cpp b/libc/test/src/math/smoke/atan2f128_test.cpp
index 82feb28173ff6..7443a383aee92 100644
--- a/libc/test/src/math/smoke/atan2f128_test.cpp
+++ b/libc/test/src/math/smoke/atan2f128_test.cpp
@@ -6,17 +6,32 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "src/__support/FPUtil/float128.h"
+#include "src/__support/integer_literals.h"
 #include "src/math/atan2f128.h"
 #include "test/UnitTest/FPMatcher.h"
 #include "test/UnitTest/Test.h"
 
+#ifndef LIBC_TYPES_HAS_NATIVE_FLOAT128
+using float128 = LIBC_NAMESPACE::fputil::Float128;
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+using LIBC_NAMESPACE::operator""_u128;
+
 using LlvmLibcAtan2f128Test = LIBC_NAMESPACE::testing::FPTest<float128>;
 
 TEST_F(LlvmLibcAtan2f128Test, SpecialNumbers) {
-  constexpr float128 PI = 0x1.921fb54442d18469898cc51701b8p+1q;
-  constexpr float128 PI_OVER_2 = 0x1.921fb54442d18469898cc51701b8p+0q;
-  constexpr float128 PI_OVER_4 = 0x1.921fb54442d18469898cc51701b8p-1q;
-  constexpr float128 THREE_PI_OVER_4 = 0x1.2d97c7f3321d234f272993d1414ap+1q;
+  const float128 PI = FPBits(0x4000921f'b54442d1'8469898c'c51701b8_u128)
+                          .get_val(); // 0x1.921fb54442d18469898cc51701b8p+1q
+  const float128 PI_OVER_2 =
+      FPBits(0x3fff921f'b54442d1'8469898c'c51701b8_u128)
+          .get_val(); // 0x1.921fb54442d18469898cc51701b8p+0q
+  const float128 PI_OVER_4 =
+      FPBits(0x3ffe921f'b54442d1'8469898c'c51701b8_u128)
+          .get_val(); // 0x1.921fb54442d18469898cc51701b8p-1q
+  const float128 THREE_PI_OVER_4 =
+      FPBits(0x40002d97'c7f3321d'234f2729'93d1414a_u128)
+          .get_val(); // 0x1.2d97c7f3321d234f272993d1414ap+1q
 
   EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::atan2f128(zero, inf));
   EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, LIBC_NAMESPACE::atan2f128(neg_zero, inf));
@@ -38,13 +53,19 @@ TEST_F(LlvmLibcAtan2f128Test, SpecialNumbers) {
   EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::atan2f128(1.0, inf));
   EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, LIBC_NAMESPACE::atan2f128(-1.0, inf));
 
-  float128 x = 0x1.ffffffffffffffffffffffffffe7p1q;
-  float128 y = 0x1.fffffffffffffffffffffffffff2p1q;
-  float128 r = 0x1.921fb54442d18469898cc51701b3p-1q;
+  float128 x = FPBits(0x4000ffff'ffffffff'ffffffff'ffffffe7_u128)
+                   .get_val(); // 0x1.ffffffffffffffffffffffffffe7p1q
+  float128 y = FPBits(0x4000ffff'ffffffff'ffffffff'fffffff2_u128)
+                   .get_val(); // 0x1.fffffffffffffffffffffffffff2p1q
+  float128 r = FPBits(0x3ffe921f'b54442d1'8469898c'c51701b3_u128)
+                   .get_val(); // 0x1.921fb54442d18469898cc51701b3p-1q
   EXPECT_FP_EQ(r, LIBC_NAMESPACE::atan2f128(x, y));
 
-  x = -0x1.f122e07fff556143p+3524q;
-  y = 0x1.f122e07fff55615b75p+6316q;
-  r = -0x1.ffffffffffffffe6cfcdc604fc99p-2793q;
+  x = FPBits(0xcdc3f122'e07fff55'61430000'00000000_u128)
+          .get_val(); // -0x1.f122e07fff556143p+3524q
+  y = FPBits(0x58abf122'e07fff55'615b7500'00000000_u128)
+          .get_val(); // 0x1.f122e07fff55615b75p+6316q
+  r = FPBits(0xb516ffff'ffffffff'ffe6cfcd'c604fc99_u128)
+          .get_val(); // -0x1.ffffffffffffffe6cfcdc604fc99p-2793q
   EXPECT_FP_EQ(r, LIBC_NAMESPACE::atan2f128(x, y));
 }

>From dccc6840f3a18926ce9c428633e8df118416b9b2 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 16 Aug 2026 12:59:21 +0530
Subject: [PATCH 3/6] Add/force direct Float128<->Dyadic

---
 libc/src/__support/math/CMakeLists.txt |  1 +
 libc/src/__support/math/atan2f128.h    | 13 ++++++++-----
 libc/src/math/atan2f128.h              |  4 ++--
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 5facf9f282923..a9983e8f447a0 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -316,6 +316,7 @@ add_header_library(
     .atan_utils
     libc.src.__support.integer_literals
     libc.src.__support.uint128
+    libc.src.__support.FPUtil.cast
     libc.src.__support.FPUtil.dyadic_float
     libc.src.__support.FPUtil.fp_bits
     libc.src.__support.FPUtil.float128
diff --git a/libc/src/__support/math/atan2f128.h b/libc/src/__support/math/atan2f128.h
index 2c42b02a51265..0d6e518c08c2b 100644
--- a/libc/src/__support/math/atan2f128.h
+++ b/libc/src/__support/math/atan2f128.h
@@ -129,8 +129,8 @@ LIBC_INLINE Float128 atan2f128(Float128 y, Float128 x) {
   if (LIBC_UNLIKELY(max_exp >= 0x7fffU || min_exp == 0U)) {
     if (x_bits.is_nan() || y_bits.is_nan())
       return FPBits::quiet_nan().get_val();
-    unsigned x_except = x == 0 ? 0 : (FPBits(x_abs).is_inf() ? 2 : 1);
-    unsigned y_except = y == 0 ? 0 : (FPBits(y_abs).is_inf() ? 2 : 1);
+    unsigned x_except = x == Float128(0) ? 0 : (FPBits(x_abs).is_inf() ? 2 : 1);
+    unsigned y_except = y == Float128(0) ? 0 : (FPBits(y_abs).is_inf() ? 2 : 1);
 
     // Exceptional cases:
     //   EXCEPT[y_except][x_except][x_is_neg]
@@ -150,7 +150,8 @@ LIBC_INLINE Float128 atan2f128(Float128 y, Float128 x) {
       DFloat128 r = EXCEPTS[y_except][x_except][x_sign];
       if (y_sign)
         r.sign = r.sign.negate();
-      return static_cast<Float128>(r);
+      return r.template as<Float128, /*ShouldSignalExceptions=*/false>();
+      (r);
     }
   }
 
@@ -164,7 +165,8 @@ LIBC_INLINE Float128 atan2f128(Float128 y, Float128 x) {
     DFloat128 result = quick_add(const_term, quotient);
     if (final_sign)
       result.sign = result.sign.negate();
-    return static_cast<Float128>(result);
+    return result.template as<Float128, /*ShouldSignalExceptions=*/false>();
+    (result);
   }
 
   // Take 24 leading bits of num and den to convert to float for fast division.
@@ -202,7 +204,8 @@ LIBC_INLINE Float128 atan2f128(Float128 y, Float128 x) {
   if (final_sign)
     r.sign = r.sign.negate();
 
-  return static_cast<Float128>(r);
+  return r.template as<Float128, /*ShouldSignalExceptions=*/false>();
+  (r);
 }
 
 } // namespace math
diff --git a/libc/src/math/atan2f128.h b/libc/src/math/atan2f128.h
index a15a7a52497b5..1f78947005a53 100644
--- a/libc/src/math/atan2f128.h
+++ b/libc/src/math/atan2f128.h
@@ -13,12 +13,12 @@
 #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
 
-namespace LIBC_NAMESPACE_DECL {
-
 float128 atan2f128(float128 x, float128 y);
 
 } // namespace LIBC_NAMESPACE_DECL

>From f6547338f00ab010472578b8b48c8389a1aa03e1 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 16 Aug 2026 13:10:55 +0530
Subject: [PATCH 4/6] atan2f128

---
 libc/src/math/generic/atan2l.cpp | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/libc/src/math/generic/atan2l.cpp b/libc/src/math/generic/atan2l.cpp
index ce7948229c740..e61fc779ddbd3 100644
--- a/libc/src/math/generic/atan2l.cpp
+++ b/libc/src/math/generic/atan2l.cpp
@@ -19,14 +19,9 @@ LLVM_LIBC_FUNCTION(long double, atan2l, (long double y, long double x)) {
 #if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
   return static_cast<long double>(
       math::atan2(static_cast<double>(y), static_cast<double>(x)));
-#elif defined(LIBC_TYPES_HAS_NATIVE_FLOAT128)
-  // TODO: Once we have a software implementation of float128,
-  // we can use it here unconditionally, even if float128 is not
-  // available as a host type.
-  return fputil::cast<long double>(
-      math::atan2f128(fputil::cast<float128>(y), fputil::cast<float128>(x)));
 #else
-#error "Extended precision is not yet supported"
+  return fputil::cast<long double>(math::atan2f128(
+      fputil::cast<fputil::Float128>(y), fputil::cast<fputil::Float128>(x)));
 #endif
 }
 

>From 9492413b8825d9101ae9cae7336d6a51ddb2fca5 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 16 Aug 2026 13:28:20 +0530
Subject: [PATCH 5/6] nit

---
 libc/test/src/math/smoke/atan2f128_test.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/libc/test/src/math/smoke/atan2f128_test.cpp b/libc/test/src/math/smoke/atan2f128_test.cpp
index 7443a383aee92..092d139b49e1e 100644
--- a/libc/test/src/math/smoke/atan2f128_test.cpp
+++ b/libc/test/src/math/smoke/atan2f128_test.cpp
@@ -49,9 +49,12 @@ TEST_F(LlvmLibcAtan2f128Test, SpecialNumbers) {
   EXPECT_FP_EQ(-THREE_PI_OVER_4, LIBC_NAMESPACE::atan2f128(neg_inf, neg_inf));
 
   EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan2f128(aNaN, zero));
-  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan2f128(1.0, aNaN));
-  EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::atan2f128(1.0, inf));
-  EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, LIBC_NAMESPACE::atan2f128(-1.0, inf));
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN,
+                            LIBC_NAMESPACE::atan2f128(Float128(1.0), aNaN));
+  EXPECT_FP_EQ_ALL_ROUNDING(zero,
+                            LIBC_NAMESPACE::atan2f128(Float128(1.0), inf));
+  EXPECT_FP_EQ_ALL_ROUNDING(neg_zero,
+                            LIBC_NAMESPACE::atan2f128(Float128(-1.0), inf));
 
   float128 x = FPBits(0x4000ffff'ffffffff'ffffffff'ffffffe7_u128)
                    .get_val(); // 0x1.ffffffffffffffffffffffffffe7p1q

>From 3c6a064b96d780d970fb1c5d1088820542a554bc Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 16 Aug 2026 13:32:36 +0530
Subject: [PATCH 6/6] nit

---
 libc/test/src/math/smoke/atan2f128_test.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libc/test/src/math/smoke/atan2f128_test.cpp b/libc/test/src/math/smoke/atan2f128_test.cpp
index 092d139b49e1e..9957fa74728de 100644
--- a/libc/test/src/math/smoke/atan2f128_test.cpp
+++ b/libc/test/src/math/smoke/atan2f128_test.cpp
@@ -50,11 +50,11 @@ TEST_F(LlvmLibcAtan2f128Test, SpecialNumbers) {
 
   EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan2f128(aNaN, zero));
   EXPECT_FP_EQ_ALL_ROUNDING(aNaN,
-                            LIBC_NAMESPACE::atan2f128(Float128(1.0), aNaN));
+                            LIBC_NAMESPACE::atan2f128(float128(1.0), aNaN));
   EXPECT_FP_EQ_ALL_ROUNDING(zero,
-                            LIBC_NAMESPACE::atan2f128(Float128(1.0), inf));
+                            LIBC_NAMESPACE::atan2f128(float128(1.0), inf));
   EXPECT_FP_EQ_ALL_ROUNDING(neg_zero,
-                            LIBC_NAMESPACE::atan2f128(Float128(-1.0), inf));
+                            LIBC_NAMESPACE::atan2f128(float128(-1.0), inf));
 
   float128 x = FPBits(0x4000ffff'ffffffff'ffffffff'ffffffe7_u128)
                    .get_val(); // 0x1.ffffffffffffffffffffffffffe7p1q



More information about the libc-commits mailing list