[libc-commits] [libc] 4d70d87 - [libc] Add atan2l implementation fallback to atan2f128. (#182587)

via libc-commits libc-commits at lists.llvm.org
Wed Feb 25 09:28:03 PST 2026


Author: Alexey Samsonov
Date: 2026-02-25T09:27:59-08:00
New Revision: 4d70d8787f98c99894c4abc5434bdd694447d83d

URL: https://github.com/llvm/llvm-project/commit/4d70d8787f98c99894c4abc5434bdd694447d83d
DIFF: https://github.com/llvm/llvm-project/commit/4d70d8787f98c99894c4abc5434bdd694447d83d.diff

LOG: [libc] Add atan2l implementation fallback to atan2f128. (#182587)

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).

Added: 
    libc/test/src/math/smoke/atan2l_test.cpp

Modified: 
    libc/config/linux/x86_64/entrypoints.txt
    libc/src/math/generic/CMakeLists.txt
    libc/src/math/generic/atan2l.cpp
    libc/test/src/math/smoke/CMakeLists.txt

Removed: 
    


################################################################################
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 354c3cf912d77..1115af9683fa6 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4209,7 +4209,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 
diff erently depending on the varying
+  // size of long double on 
diff erent platforms.
+}


        


More information about the libc-commits mailing list