@@ -284,9 +284,27 @@ static std::complex<HostT> StdPowF2B(
284284#endif
285285
286286extern " C" {
287+ float _Complex cacosf (float _Complex );
288+ double _Complex cacos (double _Complex );
287289float _Complex csqrtf (float _Complex );
288290double _Complex csqrt (double _Complex );
289291}
292+
293+ enum CRI { Real, Imag };
294+ template <typename TR, typename TA> static TR &reIm (TA &x, CRI n) {
295+ return reinterpret_cast <TR (&)[2 ]>(x)[n];
296+ }
297+ template <typename TR, typename T> static TR CppToC (const std::complex <T> &x) {
298+ TR r;
299+ reIm<T, TR>(r, CRI::Real) = x.real ();
300+ reIm<T, TR>(r, CRI::Imag) = x.imag ();
301+ return r;
302+ }
303+ template <typename T, typename TA> static std::complex <T> CToCpp (const TA &x) {
304+ TA &z{const_cast <TA&>(x)};
305+ return std::complex <T>(reIm<T, TA>(z, CRI::Real),
306+ reIm<T, TA>(z, CRI::Imag));
307+ }
290308#endif
291309
292310template <typename HostT>
@@ -296,19 +314,11 @@ static std::complex<HostT> CSqrt(const std::complex<HostT> &x) {
296314 // On AIX, the implementation of csqrt[f] and std::sqrt is different,
297315 // use csqrt[f] in folding.
298316 if constexpr (std::is_same_v<HostT, float >) {
299- float _Complex c;
300- reinterpret_cast <HostT (&)[2 ]>(c)[0 ] = x.real ();
301- reinterpret_cast <HostT (&)[2 ]>(c)[1 ] = x.imag ();
302- float _Complex r{csqrtf (c)};
303- res.real (reinterpret_cast <HostT (&)[2 ]>(r)[0 ]);
304- res.imag (reinterpret_cast <HostT (&)[2 ]>(r)[1 ]);
317+ float _Complex r{csqrtf (CppToC<float _Complex , float >(x))};
318+ res = CToCpp<float , float _Complex >(r);
305319 } else if constexpr (std::is_same_v<HostT, double >) {
306- double _Complex c;
307- reinterpret_cast <HostT (&)[2 ]>(c)[0 ] = x.real ();
308- reinterpret_cast <HostT (&)[2 ]>(c)[1 ] = x.imag ();
309- double _Complex r{csqrt (c)};
310- res.real (reinterpret_cast <HostT (&)[2 ]>(r)[0 ]);
311- res.imag (reinterpret_cast <HostT (&)[2 ]>(r)[1 ]);
320+ double _Complex r{csqrt (CppToC<double _Complex , double >(x))};
321+ res = CToCpp<double , double _Complex >(r);
312322 } else {
313323 DIE (" bad complex component type" );
314324 }
@@ -318,6 +328,27 @@ static std::complex<HostT> CSqrt(const std::complex<HostT> &x) {
318328 return res;
319329}
320330
331+ template <typename HostT>
332+ static std::complex <HostT> CAcos (const std::complex <HostT> &x) {
333+ std::complex <HostT> res;
334+ #ifdef _AIX
335+ // On AIX, the implementation of cacos[f] and std::acos is different,
336+ // use cacos[f] in folding.
337+ if constexpr (std::is_same_v<HostT, float >) {
338+ float _Complex r{cacosf (CppToC<float _Complex , float >(x))};
339+ res = CToCpp<float , float _Complex >(r);
340+ } else if constexpr (std::is_same_v<HostT, double >) {
341+ double _Complex r{cacos (CppToC<double _Complex , double >(x))};
342+ res = CToCpp<double , double _Complex >(r);
343+ } else {
344+ DIE (" bad complex component type" );
345+ }
346+ #else
347+ res = std::acos (x);
348+ #endif
349+ return res;
350+ }
351+
321352template <typename HostT>
322353struct HostRuntimeLibrary <std::complex <HostT>, LibraryVersion::Libm> {
323354 using F = FuncPointer<std::complex <HostT>, const std::complex <HostT> &>;
@@ -328,7 +359,7 @@ struct HostRuntimeLibrary<std::complex<HostT>, LibraryVersion::Libm> {
328359 using F2B = FuncPointer<std::complex <HostT>, const std::complex <HostT> &,
329360 const HostT &>;
330361 static constexpr HostRuntimeFunction table[]{
331- FolderFactory<F, F{std::acos }>::Create (" acos" ),
362+ FolderFactory<F, F{CAcos }>::Create (" acos" ),
332363 FolderFactory<F, F{std::acosh}>::Create (" acosh" ),
333364 FolderFactory<F, F{std::asin}>::Create (" asin" ),
334365 FolderFactory<F, F{std::asinh}>::Create (" asinh" ),
0 commit comments