[libc-commits] [libc] [llvm] [libc] Modify `atan2f128` to use emulated Float128 type (PR #216508)
via libc-commits
libc-commits at lists.llvm.org
Wed Aug 19 02:18:18 PDT 2026
https://github.com/Sukumarsawant updated https://github.com/llvm/llvm-project/pull/216508
>From 3e93031c7c6a2a11e0e7276fbca1e2457722f3cb Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 16 Aug 2026 02:06:31 +0530
Subject: [PATCH 01/10] 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 ac91edabb3ef6..fc798bb528dde 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
@@ -733,7 +734,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 143bf6c552545..e79bfe4304a14 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
@@ -744,7 +745,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 9ade4f9954d7e..e0abebf1c0a2e 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
@@ -741,7 +742,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 4f04feafb3dab..1201a34ee2bf8 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
@@ -553,7 +554,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 f5a0cab82b26a..dec48a3800d03 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 4497748fc7443..9103f481f196e 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
@@ -491,7 +492,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 83c44d37bc5b7..b6f46fd5a2fa1 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 2d7e824d54d8c..3f437ade637c9 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 8174cc59b5e94..ce5a165631fda 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -523,6 +523,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
@@ -886,7 +887,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 381fab85d46d4..be25168104c48 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 fc6aaacf51dd8..48b08925f7904 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -587,6 +587,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
@@ -970,7 +971,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 011b27079e1e8..42b82150defa2 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -597,6 +597,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
@@ -980,7 +981,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 3c7bb5968b433..bca17c61b6e25 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 200d6af78843a06613a196fe1b4199e6d840f535 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 16 Aug 2026 02:29:07 +0530
Subject: [PATCH 02/10] 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 681e12527458e..9b32e2486a35d 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 d6d9f768ac1d9..4c863ef21e1a1 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4041,6 +4041,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 bb62515ba4eec..4e36af2b7018c 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)));
EXPECT_FP_EQ(Float128(0.0), LIBC_NAMESPACE::shared::floorf128(Float128(0.0)));
EXPECT_FP_EQ(Float128(1.0), LIBC_NAMESPACE::shared::sqrtf128(Float128(1.0)));
}
@@ -592,8 +594,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 362eb946a02f6..f7edfb3210a4d 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2892,6 +2892,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 1b055a4743c3e..d7efbba3e290e 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -5069,6 +5069,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 eebbeaed995026ba9e7f67d248db1817f3cca704 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 16 Aug 2026 12:59:21 +0530
Subject: [PATCH 03/10] 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 9b32e2486a35d..923ab71c35016 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 4113499e17ce8c6c8199f94eb96d7d5b70c339d4 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 16 Aug 2026 13:10:55 +0530
Subject: [PATCH 04/10] 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 b68c46ea5854bd867acd40bbc630cd855a0a40ac Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 16 Aug 2026 13:28:20 +0530
Subject: [PATCH 05/10] 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 0b504c58238659e558d18a951a21a430189aa9f4 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 16 Aug 2026 13:32:36 +0530
Subject: [PATCH 06/10] 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
>From 4d82c0103958158ce01d210dbf720890e64a5bc2 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 18 Aug 2026 13:39:18 +0530
Subject: [PATCH 07/10] nits
---
libc/src/__support/math/CMakeLists.txt | 5 ++---
libc/src/__support/math/atan2f128.h | 9 +++------
2 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 923ab71c35016..4db173cfd33a8 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -314,15 +314,14 @@ add_header_library(
atan2f128.h
DEPENDS
.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
libc.src.__support.FPUtil.multiply_add
libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.integer_literals
libc.src.__support.macros.optimization
+ libc.src.__support.uint128
)
add_header_library(
diff --git a/libc/src/__support/math/atan2f128.h b/libc/src/__support/math/atan2f128.h
index 0d6e518c08c2b..5df9071acc51b 100644
--- a/libc/src/__support/math/atan2f128.h
+++ b/libc/src/__support/math/atan2f128.h
@@ -150,8 +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 r.template as<Float128, /*ShouldSignalExceptions=*/false>();
- (r);
+ return r.template as<Float128, /*ShouldSignalExceptions=*/true>();
}
}
@@ -165,8 +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 result.template as<Float128, /*ShouldSignalExceptions=*/false>();
- (result);
+ return result.template as<Float128, /*ShouldSignalExceptions=*/true>();
}
// Take 24 leading bits of num and den to convert to float for fast division.
@@ -204,8 +202,7 @@ LIBC_INLINE Float128 atan2f128(Float128 y, Float128 x) {
if (final_sign)
r.sign = r.sign.negate();
- return r.template as<Float128, /*ShouldSignalExceptions=*/false>();
- (r);
+ return r.template as<Float128, /*ShouldSignalExceptions=*/true>();
}
} // namespace math
>From ab5590023d709daec8575fa2a47f49bd98ad8d2e Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 19 Aug 2026 13:38:33 +0530
Subject: [PATCH 08/10] bazel
---
utils/bazel/llvm-project-overlay/libc/BUILD.bazel | 4 +++-
.../libc/test/src/math/smoke/BUILD.bazel | 8 ++++++++
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 300155e4fab0b..a14b70d381b7e 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -4796,6 +4796,7 @@ libc_support_library(
hdrs = ["src/__support/math/atan2f128.h"],
deps = [
":__support_fputil_dyadic_float",
+ ":__support_fputil_float128",
":__support_fputil_fp_bits",
":__support_fputil_nearest_integer",
":__support_integer_literals",
@@ -4803,7 +4804,6 @@ libc_support_library(
":__support_macros_optimization",
":__support_math_atan_utils",
":__support_uint128",
- ":llvm_libc_types_float128",
],
)
@@ -10636,6 +10636,8 @@ libc_math_function(
libc_math_function(
name = "atan2f128",
additional_deps = [
+ ":__support_cpp_bit",
+ ":__support_fputil_float128",
":__support_math_atan2f128",
],
)
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 0d0d58f0ec071..8b0c8f819c41f 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
@@ -28,6 +28,14 @@ math_test(name = "atan2f")
math_test(name = "atan2f16")
+math_test(
+ name = "atan2f128",
+ deps = [
+ "//libc:__support_fputil_float128",
+ "//libc:__support_integer_literals",
+ ],
+)
+
math_test(name = "atan")
math_test(name = "atanf")
>From 34c8e1ccdffb46462993308ed267e5ce0f9b243d Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 19 Aug 2026 14:20:09 +0530
Subject: [PATCH 09/10] src/math/bazel
---
.../libc/test/src/math/BUILD.bazel | 14 ++++++++++++++
1 file changed, 14 insertions(+)
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 aeacfc5933f61..a063be652aa9b 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
@@ -24,6 +24,11 @@ math_mpfr_test(name = "atan2")
math_mpfr_test(name = "atan2f")
+math_mpfr_test(
+ name = "atan2f128",
+ deps = ["//libc:__support_fputil_float128"],
+)
+
math_mpfr_test(name = "atan")
math_mpfr_test(name = "atanf")
@@ -568,6 +573,15 @@ math_mpfr_test(
hdrs = ["SqrtTest.h"],
)
+math_mpfr_test(
+ name = "sqrtf128",
+ hdrs = ["SqrtTest.h"],
+ deps = [
+ "//libc:__support_fputil_float128",
+ "//libc:__support_integer_literals",
+ ],
+)
+
math_mpfr_test(
name = "f16sqrt",
hdrs = ["SqrtTest.h"],
>From 41d0258077035deb6607aa8941963a4b39d3b31c Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 19 Aug 2026 14:47:56 +0530
Subject: [PATCH 10/10] nit:order
---
libc/test/shared/shared_math_test.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index 4e36af2b7018c..950d8c2eebe1a 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -581,9 +581,9 @@ 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)));
+ EXPECT_FP_EQ(Float128(0.0), LIBC_NAMESPACE::shared::ceilf128(Float128(0.0)));
EXPECT_FP_EQ(Float128(0.0), LIBC_NAMESPACE::shared::floorf128(Float128(0.0)));
EXPECT_FP_EQ(Float128(1.0), LIBC_NAMESPACE::shared::sqrtf128(Float128(1.0)));
}
More information about the libc-commits
mailing list