[libcxx-commits] [libcxx] [libc++] Use libc functions for complex calculations when available (PR #99677)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Sun Nov 17 02:19:23 PST 2024


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/99677

>From 811186764d1add4d83972db3ad0d2e7c96bb15a7 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sat, 16 Nov 2024 19:23:20 +0100
Subject: [PATCH 1/2] [libc++] Fix a few problems found by clang-tidy

---
 libcxx/include/__flat_map/flat_map.h          | 4 ++--
 libcxx/include/__locale_dir/locale_base_api.h | 6 +++---
 libcxx/include/__ranges/to.h                  | 8 ++++----
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/libcxx/include/__flat_map/flat_map.h b/libcxx/include/__flat_map/flat_map.h
index 073b63cd8f0a66..58b362ad7a706f 100644
--- a/libcxx/include/__flat_map/flat_map.h
+++ b/libcxx/include/__flat_map/flat_map.h
@@ -113,7 +113,7 @@ class flat_map {
   class value_compare {
   private:
     key_compare __comp_;
-    value_compare(key_compare __c) : __comp_(__c) {}
+    _LIBCPP_HIDE_FROM_ABI value_compare(key_compare __c) : __comp_(__c) {}
     friend flat_map;
 
   public:
@@ -659,7 +659,7 @@ class flat_map {
 
   template <class _InputIterator>
     requires __has_input_iterator_category<_InputIterator>::value
-  void insert(sorted_unique_t, _InputIterator __first, _InputIterator __last) {
+  _LIBCPP_HIDE_FROM_ABI void insert(sorted_unique_t, _InputIterator __first, _InputIterator __last) {
     if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) {
       __reserve(__last - __first);
     }
diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h
index 5cbe91207ca74e..8ed4c29cb8732f 100644
--- a/libcxx/include/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__locale_dir/locale_base_api.h
@@ -265,17 +265,17 @@ _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") // GCC doesn't support [[g
 template <class... _Args>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __snprintf(
     char* __s, size_t __n, __locale_t __loc, const char* __format, _Args&&... __args) {
-  return __libcpp_snprintf_l(__s, __n, __loc, __format, std::forward<_Args>(__args)...);
+  return std::__libcpp_snprintf_l(__s, __n, __loc, __format, std::forward<_Args>(__args)...);
 }
 template <class... _Args>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf(
     char** __s, __locale_t __loc, const char* __format, _Args&&... __args) {
-  return __libcpp_asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
+  return std::__libcpp_asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
 }
 template <class... _Args>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf(
     const char* __s, __locale_t __loc, const char* __format, _Args&&... __args) {
-  return __libcpp_sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
+  return std::__libcpp_sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
 }
 _LIBCPP_DIAGNOSTIC_POP
 #  undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT
diff --git a/libcxx/include/__ranges/to.h b/libcxx/include/__ranges/to.h
index 76249bdd9891c8..c937b0656de87d 100644
--- a/libcxx/include/__ranges/to.h
+++ b/libcxx/include/__ranges/to.h
@@ -111,14 +111,14 @@ template <class _Container, input_range _Range, class... _Args>
 
       for (auto&& __ref : __range) {
         using _Ref = decltype(__ref);
-        if constexpr (requires { __result.emplace_back(declval<_Ref>()); }) {
+        if constexpr (requires { __result.emplace_back(std::declval<_Ref>()); }) {
           __result.emplace_back(std::forward<_Ref>(__ref));
-        } else if constexpr (requires { __result.push_back(declval<_Ref>()); }) {
+        } else if constexpr (requires { __result.push_back(std::declval<_Ref>()); }) {
           __result.push_back(std::forward<_Ref>(__ref));
-        } else if constexpr (requires { __result.emplace(__result.end(), declval<_Ref>()); }) {
+        } else if constexpr (requires { __result.emplace(__result.end(), std::declval<_Ref>()); }) {
           __result.emplace(__result.end(), std::forward<_Ref>(__ref));
         } else {
-          static_assert(requires { __result.insert(__result.end(), declval<_Ref>()); });
+          static_assert(requires { __result.insert(__result.end(), std::declval<_Ref>()); });
           __result.insert(__result.end(), std::forward<_Ref>(__ref));
         }
       }

>From 8aa9d165d8b90f14869fd3076e7231d62f4cd5bd Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Fri, 27 Jan 2023 09:41:14 +0100
Subject: [PATCH 2/2] [libc++] Forward complex math to libm

---
 libcxx/include/complex | 86 +++++++++++++++---------------------------
 1 file changed, 30 insertions(+), 56 deletions(-)

diff --git a/libcxx/include/complex b/libcxx/include/complex
index 2dc6d298e44f69..1be19eee3655e6 100644
--- a/libcxx/include/complex
+++ b/libcxx/include/complex
@@ -1125,77 +1125,51 @@ inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> __sqr(const complex<_Tp>& __x) {
 
 // asinh
 
-template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI inline _Complex float __casinh(_Complex float __v) { return __builtin_casinhf(__v); }
+_LIBCPP_HIDE_FROM_ABI inline _Complex double __casinh(_Complex double __v) { return __builtin_casinh(__v); }
+_LIBCPP_HIDE_FROM_ABI inline _Complex long double __casinh(_Complex long double __v) { return __builtin_casinhl(__v); }
+
+template <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI complex<_Tp> asinh(const complex<_Tp>& __x) {
+  return complex<_Tp>(__from_builtin_tag(), std::__casinh(__x.__builtin()));
+}
+
+template <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> = 0>
 _LIBCPP_HIDE_FROM_ABI complex<_Tp> asinh(const complex<_Tp>& __x) {
-  const _Tp __pi(atan2(+0., -0.));
-  if (std::isinf(__x.real())) {
-    if (std::isnan(__x.imag()))
-      return __x;
-    if (std::isinf(__x.imag()))
-      return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag()));
-    return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag()));
-  }
-  if (std::isnan(__x.real())) {
-    if (std::isinf(__x.imag()))
-      return complex<_Tp>(__x.imag(), __x.real());
-    if (__x.imag() == 0)
-      return __x;
-    return complex<_Tp>(__x.real(), __x.real());
-  }
-  if (std::isinf(__x.imag()))
-    return complex<_Tp>(std::copysign(__x.imag(), __x.real()), std::copysign(__pi / _Tp(2), __x.imag()));
   complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) + _Tp(1)));
   return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag()));
 }
 
 // acosh
 
-template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI inline _Complex float __cacosh(_Complex float __v) { return __builtin_cacoshf(__v); }
+_LIBCPP_HIDE_FROM_ABI inline _Complex double __cacosh(_Complex double __v) { return __builtin_cacosh(__v); }
+_LIBCPP_HIDE_FROM_ABI inline _Complex long double __cacosh(_Complex long double __v) { return __builtin_cacoshl(__v); }
+
+template <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI complex<_Tp> acosh(const complex<_Tp>& __x) {
+  return complex<_Tp>(__from_builtin_tag(), std::__cacosh(__x.__builtin()));
+}
+
+template <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> = 0>
 _LIBCPP_HIDE_FROM_ABI complex<_Tp> acosh(const complex<_Tp>& __x) {
-  const _Tp __pi(atan2(+0., -0.));
-  if (std::isinf(__x.real())) {
-    if (std::isnan(__x.imag()))
-      return complex<_Tp>(std::abs(__x.real()), __x.imag());
-    if (std::isinf(__x.imag())) {
-      if (__x.real() > 0)
-        return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag()));
-      else
-        return complex<_Tp>(-__x.real(), std::copysign(__pi * _Tp(0.75), __x.imag()));
-    }
-    if (__x.real() < 0)
-      return complex<_Tp>(-__x.real(), std::copysign(__pi, __x.imag()));
-    return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag()));
-  }
-  if (std::isnan(__x.real())) {
-    if (std::isinf(__x.imag()))
-      return complex<_Tp>(std::abs(__x.imag()), __x.real());
-    return complex<_Tp>(__x.real(), __x.real());
-  }
-  if (std::isinf(__x.imag()))
-    return complex<_Tp>(std::abs(__x.imag()), std::copysign(__pi / _Tp(2), __x.imag()));
   complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1)));
   return complex<_Tp>(std::copysign(__z.real(), _Tp(0)), std::copysign(__z.imag(), __x.imag()));
 }
 
 // atanh
 
-template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI inline _Complex float __catanh(_Complex float __v) { return __builtin_catanhf(__v); }
+_LIBCPP_HIDE_FROM_ABI inline _Complex double __catanh(_Complex double __v) { return __builtin_catanh(__v); }
+_LIBCPP_HIDE_FROM_ABI inline _Complex long double __catanh(_Complex long double __v) { return __builtin_catanhl(__v); }
+
+template <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI complex<_Tp> atanh(const complex<_Tp>& __v) {
+  return complex<_Tp>(__from_builtin_tag(), std::__catanh(__v.__builtin()));
+}
+
+template <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> = 0>
 _LIBCPP_HIDE_FROM_ABI complex<_Tp> atanh(const complex<_Tp>& __x) {
-  const _Tp __pi(atan2(+0., -0.));
-  if (std::isinf(__x.imag())) {
-    return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi / _Tp(2), __x.imag()));
-  }
-  if (std::isnan(__x.imag())) {
-    if (std::isinf(__x.real()) || __x.real() == 0)
-      return complex<_Tp>(std::copysign(_Tp(0), __x.real()), __x.imag());
-    return complex<_Tp>(__x.imag(), __x.imag());
-  }
-  if (std::isnan(__x.real())) {
-    return complex<_Tp>(__x.real(), __x.real());
-  }
-  if (std::isinf(__x.real())) {
-    return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi / _Tp(2), __x.imag()));
-  }
   if (std::abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0)) {
     return complex<_Tp>(std::copysign(_Tp(INFINITY), __x.real()), std::copysign(_Tp(0), __x.imag()));
   }



More information about the libcxx-commits mailing list