Skip to content

Commit 612b6c1

Browse files
committed
Add cacos
1 parent 1b5253d commit 612b6c1

File tree

1 file changed

+44
-13
lines changed

1 file changed

+44
-13
lines changed

flang/lib/Evaluate/intrinsics-library.cpp

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -284,9 +284,27 @@ static std::complex<HostT> StdPowF2B(
284284
#endif
285285

286286
extern "C" {
287+
float _Complex cacosf(float _Complex);
288+
double _Complex cacos(double _Complex);
287289
float _Complex csqrtf(float _Complex);
288290
double _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

292310
template <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+
321352
template <typename HostT>
322353
struct 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

Comments
 (0)