[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