[libc-commits] [libc] [libc] Add atan2l implementation fallback to atan2f128. (PR #182587)
via libc-commits
libc-commits at lists.llvm.org
Fri Feb 20 12:14:54 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Alexey Samsonov (vonosmas)
<details>
<summary>Changes</summary>
Add implementation for `atan2l` that falls back to `atan2f128` if float128 support is available.
We do this for now in lieu of 80-bit-specific implementation. Going forward, we should
be choosing 64-bit, 80-bit, or 128-bit specific implementation based on the specific "long double"
implementation. Also, once llvm-libc will have its own software implementation of float128,
depending on host type presence would not be needed.
`atan2l` is one of the remaining dependencies needed for building libc++ against llvm-libc
(it's used in `<complex>` header).
---
Full diff: https://github.com/llvm/llvm-project/pull/182587.diff
5 Files Affected:
- (modified) libc/config/linux/x86_64/entrypoints.txt (+1)
- (modified) libc/src/math/generic/CMakeLists.txt (+2)
- (modified) libc/src/math/generic/atan2l.cpp (+8-1)
- (modified) libc/test/src/math/smoke/CMakeLists.txt (+10)
- (added) libc/test/src/math/smoke/atan2l_test.cpp (+26)
``````````diff
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 6f0ecf0c6885d..6485c24f5736a 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -845,6 +845,7 @@ if(LIBC_TYPES_HAS_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.ceilf128
libc.src.math.copysignf128
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 29105974f5af2..840c00c6c3bb4 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4223,7 +4223,9 @@ add_entrypoint_object(
HDRS
../atan2l.h
DEPENDS
+ libc.src.__support.FPUtil.cast
libc.src.__support.math.atan2
+ libc.src.__support.math.atan2f128
)
add_entrypoint_object(
diff --git a/libc/src/math/generic/atan2l.cpp b/libc/src/math/generic/atan2l.cpp
index a7824c62fd8cc..cd0eb5e56d88f 100644
--- a/libc/src/math/generic/atan2l.cpp
+++ b/libc/src/math/generic/atan2l.cpp
@@ -7,17 +7,24 @@
//===----------------------------------------------------------------------===//
#include "src/math/atan2l.h"
+#include "src/__support/FPUtil/cast.h"
#include "src/__support/common.h"
#include "src/__support/macros/properties/types.h"
#include "src/__support/math/atan2.h"
+#include "src/__support/math/atan2f128.h"
namespace LIBC_NAMESPACE_DECL {
-// TODO: Implement this for extended precision.
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_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"
#endif
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 5afd3a9f22967..b58eeda678149 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -4880,6 +4880,16 @@ add_fp_unittest(
libc.src.math.atan2f128
)
+add_fp_unittest(
+ atan2l_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ atan2l_test.cpp
+ DEPENDS
+ libc.src.math.atan2l
+)
+
add_fp_unittest(
scalbln_test
SUITE
diff --git a/libc/test/src/math/smoke/atan2l_test.cpp b/libc/test/src/math/smoke/atan2l_test.cpp
new file mode 100644
index 0000000000000..2487bc162f8bb
--- /dev/null
+++ b/libc/test/src/math/smoke/atan2l_test.cpp
@@ -0,0 +1,26 @@
+//===-- Unittests for atan2l ----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/atan2l.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAtan2lTest = LIBC_NAMESPACE::testing::FPTest<long double>;
+
+TEST_F(LlvmLibcAtan2lTest, SpecialNumbers) {
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan2l(aNaN, zero));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan2l(1.0, aNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::atan2l(zero, zero));
+ EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, LIBC_NAMESPACE::atan2l(neg_zero, zero));
+ EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::atan2l(1.0, inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, LIBC_NAMESPACE::atan2l(-1.0, inf));
+
+ // We're not validating non-trivial test cases here, since values
+ // like M_PI may be represented differently depending on the varying
+ // size of long double on different platforms.
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/182587
More information about the libc-commits
mailing list