[flang-commits] [flang] [flang][AIX] Handle more trig functions with complex argument to have consistent results in folding (PR #124203)
via flang-commits
flang-commits at lists.llvm.org
Fri Jan 24 03:20:59 PST 2025
================
@@ -304,48 +332,145 @@ template <typename T, typename TA> static std::complex<T> CToCpp(const TA &x) {
TA &z{const_cast<TA &>(x)};
return std::complex<T>(reIm<T, TA>(z, CRI::Real), reIm<T, TA>(z, CRI::Imag));
}
+
+using FTypeCmplxFlt = _Complex float (*)(_Complex float);
+using FTypeCmplxDble = _Complex double (*)(_Complex double);
+template <typename T>
+using FTypeStdCmplx = std::complex<T> (*)(const std::complex<T> &);
+
+std::map<trigFunc, std::tuple<FTypeCmplxFlt, FTypeCmplxDble>> mapLibmTrigFunc{
----------------
jeanPerier wrote:
Can you make that data structure constexpr using common::StaticMultimapView somehow or change the dispatching here so that this std::map is not needed?
A goal of this file is to have all the maps created at flang compile time so that there is no C++ global constructor and no cost of building maps when looking for a folder.
I would actually advise to split the AIX/normal path at the table flow like it was done for pgmath complex functions when they were here (https://github.com/llvm/llvm-project/blob/eb305631bec6bf6765c44dcfbb7ec9e8eca41be4/flang/lib/Evaluate/intrinsics-library.cpp).
You could have something like below that would preserve the current mapping approach:
```
#define COMPLEX_SIGNATURES(HOST_T) \
using F = FuncPointer<std::complex<HOST_T>, const std::complex<HOST_T> &>; \
using F2 = FuncPointer<std::complex<HOST_T>, const std::complex<HOST_T> &, \
const std::complex<HOST_T> &>; \
using F2A = FuncPointer<std::complex<HOST_T>, const HOST_T &, \
const std::complex<HOST_T> &>; \
using F2B = FuncPointer<std::complex<HOST_T>, const std::complex<HOST_T> &, \
const HOST_T &>;
#ifndef _AIX
template <typename HostT>
struct HostRuntimeLibrary<std::complex<HostT>, LibraryVersion::Libm> {
COMPLEX_SIGNATURES(HostT)
static constexpr HostRuntimeFunction table[]{
FolderFactory<F, F{std::acos}>::Create("acos"),
FolderFactory<F, F{std::acosh}>::Create("acosh"),
// ... STL versions like currently
};
static constexpr HostRuntimeMap map{table};
static_assert(map.Verify(), "map must be sorted");
};
#else
// On AIX std implementation is different than libm. Use libm to get same
// precision than at runtime.
#ifdef __clang_major__
#pragma clang diagnostic ignored "-Wc99-extensions"
#endif
extern "C" {
float _Complex cacosf(float _Complex);
double _Complex cacos(double _Complex);
float _Complex cacoshf(float _Complex);
double _Complex cacosh(double _Complex);
// ...
}
template <typename T> struct ToStdComplex {
using Type = T;
using AType = Type;
};
template <> struct ToStdComplex<float _Complex> {
using Type = std::complex<float>;
using AType = const Type &;
};
template <> struct ToStdComplex<double _Complex> {
using Type = std::complex<double>;
using AType = const Type &;
};
template <typename F, F func> struct CComplexFunc {};
template <typename R, typename... A, FuncPointer<R, A...> func>
struct CComplexFunc<FuncPointer<R, A...>, func> {
static typename ToStdComplex<R>::Type wrapper(
typename ToStdComplex<A>::AType... args) {
R res{func(*reinterpret_cast<const A *>(&args)...)};
return *reinterpret_cast<typename ToStdComplex<R>::Type *>(&res);
}
};
#define C_COMPLEX_FUNC(func) CComplexFunc<decltype(&func), &func>::wrapper
template <>
struct HostRuntimeLibrary<std::complex<float>, LibraryVersion::Libm> {
COMPLEX_SIGNATURES(float)
static constexpr HostRuntimeFunction table[]{
FolderFactory<F, C_COMPLEX_FUNC(cacosf)>::Create("acos"),
FolderFactory<F, C_COMPLEX_FUNC(cacoshf)>::Create("acosh"),
// ...
};
static constexpr HostRuntimeMap map{table};
static_assert(map.Verify(), "map must be sorted");
};
template <>
struct HostRuntimeLibrary<std::complex<double>, LibraryVersion::Libm> {
COMPLEX_SIGNATURES(double)
static constexpr HostRuntimeFunction table[]{
FolderFactory<F, C_COMPLEX_FUNC(cacos)>::Create("acos"),
FolderFactory<F, C_COMPLEX_FUNC(cacosh)>::Create("acosh"),
// ...
};
static constexpr HostRuntimeMap map{table};
static_assert(map.Verify(), "map must be sorted");
};
#endif // _AIX
```
https://github.com/llvm/llvm-project/pull/124203
More information about the flang-commits
mailing list