From be5cfaa5c73ba3baa7b373e91e9d3cd4924363cf Mon Sep 17 00:00:00 2001 From: Jean Perier Date: Wed, 27 Mar 2019 08:08:12 -0700 Subject: [PATCH] [flang] fix clang errors and warnings Original-commit: flang-compiler/f18@410f96384fd8d6652689956cda13147c6cd0c9f4 Tree-same-pre-rewrite: false --- flang/lib/evaluate/intrinsics-library.cc | 127 +++++++++++++++++++------------ flang/test/evaluate/CMakeLists.txt | 1 + 2 files changed, 80 insertions(+), 48 deletions(-) diff --git a/flang/lib/evaluate/intrinsics-library.cc b/flang/lib/evaluate/intrinsics-library.cc index f97a02a..c0cea69 100644 --- a/flang/lib/evaluate/intrinsics-library.cc +++ b/flang/lib/evaluate/intrinsics-library.cc @@ -52,26 +52,33 @@ bool HostIntrinsicProceduresLibrary::HasEquivalentProcedure( // Define which host runtime functions will be used for folding -// C++ Bessel functions take a floating point as first arguments. -// Fortran Bessel functions take an integer. -template static HostT Bessel_j0(HostT x) { - return std::cyl_bessel_j(0., x); -} -template static HostT Bessel_y0(HostT x) { - return std::cyl_neumann(0., x); -} -template static HostT Bessel_j1(HostT x) { - return std::cyl_bessel_j(1., x); -} -template static HostT Bessel_y1(HostT x) { - return std::cyl_neumann(1., x); -} -template static HostT Bessel_jn(int n, HostT x) { - return std::cyl_bessel_j(static_cast(n), x); -} -template static HostT Bessel_yn(int n, HostT x) { - return std::cyl_neumann(static_cast(n), x); -} +// C++17 defined standard Bessel math functions std::cyl_bessel_j +// and std::cyl_neumann that can be used for Fortran j and y +// bessel functions. However, they are not yet implemented in +// clang libc++ (ok in GNU libstdc++). C maths functions are used +// in the meantime. They are not C standard but a GNU extension. +// However, they seem widespread enough to be used. + +enum class Bessel { j0, j1, jn, y0, y1, yn }; +template constexpr auto Sym{0}; +template<> constexpr auto Sym{j0f}; +template<> constexpr auto Sym{j0}; +template<> constexpr auto Sym{j0l}; +template<> constexpr auto Sym{j1f}; +template<> constexpr auto Sym{j1}; +template<> constexpr auto Sym{j1l}; +template<> constexpr auto Sym{jnf}; +template<> constexpr auto Sym{jn}; +template<> constexpr auto Sym{jnl}; +template<> constexpr auto Sym{y0f}; +template<> constexpr auto Sym{y0}; +template<> constexpr auto Sym{y0l}; +template<> constexpr auto Sym{y1f}; +template<> constexpr auto Sym{y1}; +template<> constexpr auto Sym{y1l}; +template<> constexpr auto Sym{ynf}; +template<> constexpr auto Sym{yn}; +template<> constexpr auto Sym{ynl}; template static void AddLibmRealHostProcedures( @@ -82,12 +89,12 @@ static void AddLibmRealHostProcedures( {"acosh", F{std::acosh}, true}, {"asin", F{std::asin}, true}, {"asinh", F{std::asinh}, true}, {"atan", F{std::atan}, true}, {"atan", F2{std::atan2}, true}, {"atanh", F{std::atanh}, true}, - {"bessel_j0", &Bessel_j0, true}, - {"bessel_y0", &Bessel_y0, true}, - {"bessel_j1", &Bessel_j1, true}, - {"bessel_y1", &Bessel_y1, true}, - {"bessel_jn", &Bessel_jn, true}, - {"bessel_yn", &Bessel_yn, true}, {"cos", F{std::cos}, true}, + {"bessel_j0", Sym, true}, + {"bessel_j1", Sym, true}, + {"bessel_jn", Sym, true}, + {"bessel_y0", Sym, true}, + {"bessel_y1", Sym, true}, + {"bessel_yn", Sym, true}, {"cos", F{std::cos}, true}, {"cosh", F{std::cosh}, true}, {"erf", F{std::erf}, true}, {"erfc", F{std::erfc}, true}, {"exp", F{std::exp}, true}, {"gamma", F{std::tgamma}, true}, {"hypot", F2{std::hypot}, true}, @@ -188,9 +195,6 @@ struct NoSuchRuntimeSymbol {}; template constexpr auto Sym{NoSuchRuntimeSymbol{}}; // Macros to declare fast/relaxed/precise libpgmath variants. -// Note: std::complex and _complex are layout compatible but only std::comlpex -// should be used here so that templatized functions work as expected (_Complex -// and std::complex are different from a type point of view). #define DECLARE_PGMATH_FAST_REAL(func) \ extern "C" float __fs_##func##_1(float); \ extern "C" double __fd_##func##_1(double); \ @@ -198,8 +202,8 @@ template constexpr auto Sym{NoSuchRuntimeSymbol{}}; template<> constexpr auto Sym{__fd_##func##_1}; #define DECLARE_PGMATH_FAST_COMPLEX(func) \ - extern "C" std::complex __fc_##func##_1(std::complex); \ - extern "C" std::complex __fz_##func##_1(std::complex); \ + extern "C" float _Complex __fc_##func##_1(float _Complex); \ + extern "C" double _Complex __fz_##func##_1(double _Complex); \ template<> \ constexpr auto Sym>{__fc_##func##_1}; \ template<> \ @@ -216,8 +220,8 @@ template constexpr auto Sym{NoSuchRuntimeSymbol{}}; template<> constexpr auto Sym{__pd_##func##_1}; #define DECLARE_PGMATH_PRECISE_COMPLEX(func) \ - extern "C" std::complex __pc_##func##_1(std::complex); \ - extern "C" std::complex __pz_##func##_1(std::complex); \ + extern "C" float _Complex __pc_##func##_1(float _Complex); \ + extern "C" double _Complex __pz_##func##_1(double _Complex); \ template<> \ constexpr auto Sym>{__pc_##func##_1}; \ template<> \ @@ -234,8 +238,8 @@ template constexpr auto Sym{NoSuchRuntimeSymbol{}}; template<> constexpr auto Sym{__rd_##func##_1}; #define DECLARE_PGMATH_RELAXED_COMPLEX(func) \ - extern "C" std::complex __rc_##func##_1(std::complex); \ - extern "C" std::complex __rz_##func##_1(std::complex); \ + extern "C" float _Complex __rc_##func##_1(float _Complex); \ + extern "C" double _Complex __rz_##func##_1(double _Complex); \ template<> \ constexpr auto Sym>{__rc_##func##_1}; \ template<> \ @@ -388,6 +392,23 @@ static void AddLibpgmathRealHostProcedures( } } +// Note: std::complex and _complex are layout compatible but are not guaranteed +// to be linkage compatible. For instance, on i386, float _Complex is returned +// by a pair of register but std::complex is returned by structure +// address. To fix the issue, wrapper around C _Complex functions are defined +// below. +template func> +static std::complex ComplexCFuncWrapper(std::complex &arg) { + float _Complex res{func(*reinterpret_cast(&arg))}; + return *reinterpret_cast *>(&res); +} + +template func> +static std::complex ComplexCFuncWrapper(std::complex &arg) { + double _Complex res{func(*reinterpret_cast(&arg))}; + return *reinterpret_cast *>(&res); +} + template static void AddLibpgmathComplexHostProcedures( HostIntrinsicProceduresLibrary &hostIntrinsicLibrary) { @@ -397,20 +418,21 @@ static void AddLibpgmathComplexHostProcedures( using CmathF = FuncPointer; HostRuntimeIntrinsicProcedure pgmathSymbols[]{ {"abs", FuncPointer{std::abs}, true}, - {"acos", Sym, true}, + {"acos", ComplexCFuncWrapper>, true}, {"acosh", CmathF{std::acosh}, true}, - {"asin", Sym, true}, - {"asinh", CmathF{std::asinh}, true}, {"atan", CmathF{std::atan}, true}, + {"asin", ComplexCFuncWrapper>, true}, + {"asinh", CmathF{std::asinh}, true}, + {"atan", ComplexCFuncWrapper>, true}, {"atanh", CmathF{std::atanh}, true}, - {"cos", Sym, true}, - {"cosh", Sym, true}, - {"exp", Sym, true}, - {"log", Sym, true}, - {"sin", Sym, true}, - {"sinh", Sym, true}, - {"sqrt", Sym, true}, - {"tan", Sym, true}, - {"tanh", Sym, true}}; + {"cos", ComplexCFuncWrapper>, true}, + {"cosh", ComplexCFuncWrapper>, true}, + {"exp", ComplexCFuncWrapper>, true}, + {"log", ComplexCFuncWrapper>, true}, + {"sin", ComplexCFuncWrapper>, true}, + {"sinh", ComplexCFuncWrapper>, true}, + {"sqrt", ComplexCFuncWrapper>, true}, + {"tan", ComplexCFuncWrapper>, true}, + {"tanh", ComplexCFuncWrapper>, true}}; for (auto sym : pgmathSymbols) { hostIntrinsicLibrary.AddProcedure(std::move(sym)); @@ -437,7 +459,16 @@ HostIntrinsicProceduresLibrary::HostIntrinsicProceduresLibrary() { // available, this needs to be revisited to take it into account. So far, // default to libpgmath if F18 is built with it. #if LINK_WITH_LIBPGMATH - pgmath::InitHostIntrinsicLibraryWithLibpgmath(*this); + // This looks and is stupid for now (until TODO above), but it is needed + // to silence clang warnings on unused symbols if all declared pgmath + // symbols are not used somewhere. + if (true) { + pgmath::InitHostIntrinsicLibraryWithLibpgmath(*this); + } else if (false) { + pgmath::InitHostIntrinsicLibraryWithLibpgmath(*this); + } else { + pgmath::InitHostIntrinsicLibraryWithLibpgmath(*this); + } #else InitHostIntrinsicLibraryWithLibm(*this); #endif diff --git a/flang/test/evaluate/CMakeLists.txt b/flang/test/evaluate/CMakeLists.txt index 7c1abdb..db373de 100644 --- a/flang/test/evaluate/CMakeLists.txt +++ b/flang/test/evaluate/CMakeLists.txt @@ -118,6 +118,7 @@ target_link_libraries(folding-test set(FOLDING_TESTS folding01.f90 + folding02.f90 ) -- 2.7.4