Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libcxx] replaces sqrt(complex<T>) implementation with builtin #122391

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

cjdb
Copy link
Contributor

@cjdb cjdb commented Jan 9, 2025

This significantly improves the accuracy of the function.

Fixes #122172

This significantly improves the accuracy of the function.

Fixes llvm#122172
@cjdb cjdb requested a review from a team as a code owner January 9, 2025 23:46
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Jan 9, 2025
@llvmbot
Copy link
Member

llvmbot commented Jan 9, 2025

@llvm/pr-subscribers-libcxx

Author: Christopher Di Bella (cjdb)

Changes

This significantly improves the accuracy of the function.

Fixes #122172


Full diff: https://github.com/llvm/llvm-project/pull/122391.diff

1 Files Affected:

  • (modified) libcxx/include/complex (+13-8)
diff --git a/libcxx/include/complex b/libcxx/include/complex
index df18159595b34d..3858a07d34eea6 100644
--- a/libcxx/include/complex
+++ b/libcxx/include/complex
@@ -1059,16 +1059,21 @@ inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> log10(const complex<_Tp>& __x) {
 
 // sqrt
 
+_LIBCPP_HIDE_FROM_ABI inline _Complex float __csqrt(_Complex float __v) {
+  return __builtin_csqrtf(__v);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline _Complex double __csqrt(_Complex double __v) {
+  return __builtin_csqrt(__v);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline _Complex long double __csqrt(_Complex long double __v) {
+  return __builtin_csqrtl(__v);
+}
+
 template <class _Tp>
 _LIBCPP_HIDE_FROM_ABI complex<_Tp> sqrt(const complex<_Tp>& __x) {
-  if (std::isinf(__x.imag()))
-    return complex<_Tp>(_Tp(INFINITY), __x.imag());
-  if (std::isinf(__x.real())) {
-    if (__x.real() > _Tp(0))
-      return complex<_Tp>(__x.real(), std::isnan(__x.imag()) ? __x.imag() : std::copysign(_Tp(0), __x.imag()));
-    return complex<_Tp>(std::isnan(__x.imag()) ? __x.imag() : _Tp(0), std::copysign(__x.real(), __x.imag()));
-  }
-  return std::polar(std::sqrt(std::abs(__x)), std::arg(__x) / _Tp(2));
+  return complex<_Tp>(__from_builtin_tag(), std::__csqrt(__x.__builtin()));
 }
 
 // exp

Copy link

github-actions bot commented Jan 9, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

std::sqrt(std::complex<T>) produces incorrect results for large real components
2 participants