[flang] Remove non standard use of bessel C functions

Original-commit: flang-compiler/f18@a40559372a
Tree-same-pre-rewrite: false
This commit is contained in:
Jean Perier 2019-03-28 04:25:13 -07:00
parent 1d4323ddd5
commit 07f6963dbb
3 changed files with 56 additions and 66 deletions

View File

@ -52,34 +52,6 @@ bool HostIntrinsicProceduresLibrary::HasEquivalentProcedure(
// Define which host runtime functions will be used for folding
// 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<Bessel, typename T> constexpr auto Sym{0};
template<> constexpr auto Sym<Bessel::j0, float>{j0f};
template<> constexpr auto Sym<Bessel::j0, double>{j0};
template<> constexpr auto Sym<Bessel::j0, long double>{j0l};
template<> constexpr auto Sym<Bessel::j1, float>{j1f};
template<> constexpr auto Sym<Bessel::j1, double>{j1};
template<> constexpr auto Sym<Bessel::j1, long double>{j1l};
template<> constexpr auto Sym<Bessel::jn, float>{jnf};
template<> constexpr auto Sym<Bessel::jn, double>{jn};
template<> constexpr auto Sym<Bessel::jn, long double>{jnl};
template<> constexpr auto Sym<Bessel::y0, float>{y0f};
template<> constexpr auto Sym<Bessel::y0, double>{y0};
template<> constexpr auto Sym<Bessel::y0, long double>{y0l};
template<> constexpr auto Sym<Bessel::y1, float>{y1f};
template<> constexpr auto Sym<Bessel::y1, double>{y1};
template<> constexpr auto Sym<Bessel::y1, long double>{y1l};
template<> constexpr auto Sym<Bessel::yn, float>{ynf};
template<> constexpr auto Sym<Bessel::yn, double>{yn};
template<> constexpr auto Sym<Bessel::yn, long double>{ynl};
template<typename HostT>
static void AddLibmRealHostProcedures(
HostIntrinsicProceduresLibrary &hostIntrinsicLibrary) {
@ -89,22 +61,25 @@ 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", Sym<Bessel::j0, HostT>, true},
{"bessel_j1", Sym<Bessel::j1, HostT>, true},
{"bessel_jn", Sym<Bessel::jn, HostT>, true},
{"bessel_y0", Sym<Bessel::y0, HostT>, true},
{"bessel_y1", Sym<Bessel::y1, HostT>, true},
{"bessel_yn", Sym<Bessel::yn, HostT>, 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},
{"log", F{std::log}, true}, {"log10", F{std::log10}, true},
{"log_gamma", F{std::lgamma}, true}, {"mod", F2{std::fmod}, true},
{"sin", F{std::sin}, true}, {"sinh", F{std::sinh}, true},
{"sqrt", F{std::sqrt}, true}, {"tan", F{std::tan}, true},
{"tanh", F{std::tanh}, 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}, {"log", F{std::log}, true},
{"log10", F{std::log10}, true}, {"log_gamma", F{std::lgamma}, true},
{"mod", F2{std::fmod}, true}, {"sin", F{std::sin}, true},
{"sinh", F{std::sinh}, true}, {"sqrt", F{std::sqrt}, true},
{"tan", F{std::tan}, true}, {"tanh", F{std::tanh}, true}};
// Note: cmath does not have modulo and erfc_scaled equivalent
// Note regarding lack of bessel function support:
// 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 j0...
// are not C standard but a GNU extension so they are not used
// to avoid introducing incompatibilities.
// Use libpgmath to get bessel function folding support.
for (auto sym : libmSymbols) {
if (!hostIntrinsicLibrary.HasEquivalentProcedure(sym)) {
hostIntrinsicLibrary.AddProcedure(std::move(sym));

View File

@ -49,19 +49,11 @@ module m
TEST_R4(atan2, atan2(1.5_4, 1._4), 0.982793748378753662109375_4)
TEST_R4(atan_2, atan(1.5_4, 1._4), 0.982793748378753662109375_4)
TEST_R4(atanh, atanh(0.8_4), 1.098612308502197265625_4)
TEST_R4(bessel_j0, bessel_j0(0.5_4), 0.938469827175140380859375_4)
TEST_R4(bessel_j1, bessel_j1(1.8_4), 0.5815169811248779296875_4)
TEST_R4(bessel_jn, bessel_jn(2, 3._4), 0.4860912859439849853515625_4)
TEST_R4(bessel_y0, bessel_y0(2._4), 0.510375678539276123046875_4)
TEST_R4(bessel_y1, bessel_y1(1._4), (-0.78121280670166015625_4))
TEST_R4(bessel_yn, bessel_yn(2, 1.5_4), (-0.932193756103515625_4))
TEST_R4(cos, cos(0.5_4), 0.877582550048828125_4)
TEST_R4(cosh, cosh(0.1_4), 1.0050041675567626953125_4)
TEST_R4(erf, erf(1._4), 0.842700779438018798828125_4)
TEST_R4(erfc, erfc(0.1_4), 0.887537062168121337890625_4)
TEST_R4(exp, exp(0.1_4), 1.1051709651947021484375_4)
! erfc_scaled can only be tested with libpgmath
! TEST_R4(erfc_scaled, erfc_scaled(0.1_4), 0.8964569568634033203125_4)
TEST_R4(gamma, gamma(0.9_4), 1.06862866878509521484375_4)
TEST_R4(hypot, hypot(1.1_4, 0.1_4), 1.10453617572784423828125_4)
TEST_R4(log, log(3._4), 1.098612308502197265625_4)
@ -98,18 +90,6 @@ module m
0.98279372324732905408239957978366874158382415771484375_8)
TEST_R8(atanh, atanh(0.8_8), &
1.0986122886681097821082175869378261268138885498046875_8)
TEST_R8(bessel_j0, bessel_j0(0.5_8), &
0.938469807240812858850631528184749186038970947265625_8)
TEST_R8(bessel_j1, bessel_j1(1.8_8), &
0.5815169517311653546443039886071346700191497802734375_8)
TEST_R8(bessel_jn, bessel_jn(2, 3._8), &
0.486091260585891082879328450871980749070644378662109375_8)
TEST_R8(bessel_y0, bessel_y0(2._8), &
0.51037567264974514902320379405864514410495758056640625_8)
TEST_R8(bessel_y1, bessel_y1(1._8), &
(-0.781212821300288684511770043172873556613922119140625_8))
TEST_R8(bessel_yn, bessel_yn(2, 1.5_8), &
(-0.93219375976297402797143831776338629424571990966796875_8))
TEST_R8(cos, cos(0.5_8), &
0.8775825618903727587394314468838274478912353515625_8)
TEST_R8(cosh, cosh(0.1_8), &
@ -118,9 +98,6 @@ module m
0.84270079294971489414223242420121096074581146240234375_8)
TEST_R8(erfc, erfc(0.1_8), &
0.8875370839817151580319887216319330036640167236328125_8)
! erfc_scaled can only be tested with libpgmath
! TEST_R8(erfc_scaled, erfc_scaled(0.1_8), &
! 0.89645697996912654392787089818739332258701324462890625_8)
TEST_R8(exp, exp(0.1_8), &
1.10517091807564771244187795673497021198272705078125_8)
TEST_R8(gamma, gamma(0.9_8), &
@ -236,4 +213,32 @@ module m
TEST_C8(tanh, tanh((0.4_8, 1.1_8)), &
(1.1858270353667335061942367246956564486026763916015625_8, &
(1.07952982287592025301137255155481398105621337890625_8)))
#ifdef TEST_LIBPGMATH
! Bessel functions and erfc_scaled can only be folded if libpgmath
! is used.
TEST_R4(bessel_j0, bessel_j0(0.5_4), 0.938469827175140380859375_4)
TEST_R4(bessel_j1, bessel_j1(1.8_4), 0.5815169811248779296875_4)
TEST_R4(bessel_jn, bessel_jn(2, 3._4), 0.4860912859439849853515625_4)
TEST_R4(bessel_y0, bessel_y0(2._4), 0.510375678539276123046875_4)
TEST_R4(bessel_y1, bessel_y1(1._4), (-0.78121280670166015625_4))
TEST_R4(bessel_yn, bessel_yn(2, 1.5_4), (-0.932193756103515625_4))
TEST_R4(erfc_scaled, erfc_scaled(0.1_4), 0.8964569568634033203125_4)
TEST_R8(bessel_j0, bessel_j0(0.5_8), &
0.938469807240812858850631528184749186038970947265625_8)
TEST_R8(bessel_j1, bessel_j1(1.8_8), &
0.5815169517311653546443039886071346700191497802734375_8)
TEST_R8(bessel_jn, bessel_jn(2, 3._8), &
0.486091260585891082879328450871980749070644378662109375_8)
TEST_R8(bessel_y0, bessel_y0(2._8), &
0.51037567264974514902320379405864514410495758056640625_8)
TEST_R8(bessel_y1, bessel_y1(1._8), &
(-0.781212821300288684511770043172873556613922119140625_8))
TEST_R8(bessel_yn, bessel_yn(2, 1.5_8), &
(-0.93219375976297402797143831776338629424571990966796875_8))
TEST_R8(erfc_scaled, erfc_scaled(0.1_8), &
0.89645697996912654392787089818739332258701324462890625_8)
#endif
end

View File

@ -37,7 +37,17 @@
PATH=/usr/bin:/bin
srcdir=$(dirname $0)
CMD="${F18:-../../tools/f18/f18} -fdebug-dump-symbols -fparse-only"
F18CC=${F18:-../../tools/f18/f18}
CMD="$F18CC -fdebug-dump-symbols -fparse-only"
# Check if libpgmath has been linked
lpgmath=$(ldd $F18CC | grep "pgmath")
if [ -z "$lpgmath" ]; then
echo "Assuming no libpgmath support"
else
CMD="$CMD -DTEST_LIBPGMATH"
echo "Assuming libpgmath support"
fi
if [[ $# != 1 ]]; then
echo "Usage: $0 <fortran-source>"