1515#include " fold-implementation.h"
1616#include " host.h"
1717#include " flang/Common/erfc-scaled.h"
18+ #include " flang/Common/idioms.h"
1819#include " flang/Common/static-multimap-view.h"
1920#include " flang/Evaluate/expression.h"
2021#include < cfloat>
@@ -277,6 +278,76 @@ static std::complex<HostT> StdPowF2B(
277278 return std::pow (x, y);
278279}
279280
281+ #ifdef _AIX
282+ #ifdef __clang_major__
283+ #pragma clang diagnostic ignored "-Wc99-extensions"
284+ #endif
285+
286+ extern " C" {
287+ float _Complex cacosf (float _Complex );
288+ double _Complex cacos (double _Complex );
289+ float _Complex csqrtf (float _Complex );
290+ double _Complex csqrt (double _Complex );
291+ }
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), reIm<T, TA>(z, CRI::Imag));
306+ }
307+ #endif
308+
309+ template <typename HostT>
310+ static std::complex <HostT> CSqrt (const std::complex <HostT> &x) {
311+ std::complex <HostT> res;
312+ #ifdef _AIX
313+ // On AIX, the implementation of csqrt[f] and std::sqrt is different,
314+ // use csqrt[f] in folding.
315+ if constexpr (std::is_same_v<HostT, float >) {
316+ float _Complex r{csqrtf (CppToC<float _Complex , float >(x))};
317+ res = CToCpp<float , float _Complex >(r);
318+ } else if constexpr (std::is_same_v<HostT, double >) {
319+ double _Complex r{csqrt (CppToC<double _Complex , double >(x))};
320+ res = CToCpp<double , double _Complex >(r);
321+ } else {
322+ DIE (" bad complex component type" );
323+ }
324+ #else
325+ res = std::sqrt (x);
326+ #endif
327+ return res;
328+ }
329+
330+ template <typename HostT>
331+ static std::complex <HostT> CAcos (const std::complex <HostT> &x) {
332+ std::complex <HostT> res;
333+ #ifdef _AIX
334+ // On AIX, the implementation of cacos[f] and std::acos is different,
335+ // use cacos[f] in folding.
336+ if constexpr (std::is_same_v<HostT, float >) {
337+ float _Complex r{cacosf (CppToC<float _Complex , float >(x))};
338+ res = CToCpp<float , float _Complex >(r);
339+ } else if constexpr (std::is_same_v<HostT, double >) {
340+ double _Complex r{cacos (CppToC<double _Complex , double >(x))};
341+ res = CToCpp<double , double _Complex >(r);
342+ } else {
343+ DIE (" bad complex component type" );
344+ }
345+ #else
346+ res = std::acos (x);
347+ #endif
348+ return res;
349+ }
350+
280351template <typename HostT>
281352struct HostRuntimeLibrary <std::complex <HostT>, LibraryVersion::Libm> {
282353 using F = FuncPointer<std::complex <HostT>, const std::complex <HostT> &>;
@@ -287,7 +358,7 @@ struct HostRuntimeLibrary<std::complex<HostT>, LibraryVersion::Libm> {
287358 using F2B = FuncPointer<std::complex <HostT>, const std::complex <HostT> &,
288359 const HostT &>;
289360 static constexpr HostRuntimeFunction table[]{
290- FolderFactory<F, F{std::acos }>::Create (" acos" ),
361+ FolderFactory<F, F{CAcos }>::Create (" acos" ),
291362 FolderFactory<F, F{std::acosh}>::Create (" acosh" ),
292363 FolderFactory<F, F{std::asin}>::Create (" asin" ),
293364 FolderFactory<F, F{std::asinh}>::Create (" asinh" ),
@@ -302,7 +373,7 @@ struct HostRuntimeLibrary<std::complex<HostT>, LibraryVersion::Libm> {
302373 FolderFactory<F2B, F2B{StdPowF2B}>::Create (" pow" ),
303374 FolderFactory<F, F{std::sin}>::Create (" sin" ),
304375 FolderFactory<F, F{std::sinh}>::Create (" sinh" ),
305- FolderFactory<F, F{std::sqrt }>::Create (" sqrt" ),
376+ FolderFactory<F, F{CSqrt }>::Create (" sqrt" ),
306377 FolderFactory<F, F{std::tan}>::Create (" tan" ),
307378 FolderFactory<F, F{std::tanh}>::Create (" tanh" ),
308379 };
0 commit comments