[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:21:48 PST 2024
https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/99677
>From e74324802c1d9670ba6f4572cbbadc8ed76c2af5 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] [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