Skip to content

[flang][runtime] Added F128 wrappers for LDBL_MANT_DIG == 113 targets. #83102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions flang/runtime/Float128Math/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
# will have a dependency on the third-party library that is being
# used for building this FortranFloat128Math library.

if (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libquadmath" OR
${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "quadmath")
include(CheckLibraryExists)

if (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libquadmath")
check_include_file(quadmath.h FOUND_QUADMATH_HEADER)
if(FOUND_QUADMATH_HEADER)
add_compile_definitions(HAS_QUADMATHLIB)
Expand All @@ -25,7 +26,18 @@ if (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libquadmath" OR
"to be available: ${FLANG_RUNTIME_F128_MATH_LIB}"
)
endif()
else()
elseif (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libm")
check_library_exists(m sinl "" FOUND_LIBM)
check_library_exists(m sinf128 "" FOUND_LIBMF128)
if (FOUND_LIBM)
add_compile_definitions(HAS_LIBM)
endif()
if (FOUND_LIBMF128)
add_compile_definitions(HAS_LIBMF128)
endif()
endif()

if (NOT FOUND_QUADMATH_HEADER AND NOT FOUND_LIBM)
message(FATAL_ERROR
"Unsupported third-party library for Fortran F128 math runtime: "
"${FLANG_RUNTIME_F128_MATH_LIB}"
Expand Down
68 changes: 66 additions & 2 deletions flang/runtime/Float128Math/math-entries.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "tools.h"
#include "flang/Common/float128.h"
#include "flang/Runtime/entry-names.h"
#include <cfloat>
#include <type_traits>

namespace Fortran::runtime {
Expand Down Expand Up @@ -42,7 +43,8 @@ namespace Fortran::runtime {
#define DEFINE_SIMPLE_ALIAS(caller, callee) \
template <typename RT, typename... ATs, RT (*p)(ATs...)> struct caller<p> { \
static RT invoke(ATs... args) { \
static_assert(std::is_invocable_r_v<RT, decltype(callee), ATs...>); \
static_assert(std::is_invocable_r_v<RT, \
decltype(callee(std::declval<ATs>()...))(ATs...), ATs...>); \
if constexpr (std::is_same_v<RT, void>) { \
callee(args...); \
} else { \
Expand Down Expand Up @@ -98,7 +100,69 @@ typedef _Complex float __attribute__((mode(TC))) ComplexF128;
typedef _Complex float __attribute__((mode(KC))) ComplexF128;
#endif

#if HAS_QUADMATHLIB
#if HAS_LIBM
// Define wrapper callers for libm.
#include <ccomplex>
#include <cmath>

#if LDBL_MANT_DIG == 113
// Use STD math functions. They provide IEEE-754 128-bit float
// support either via 'long double' or __float128.
// The Bessel's functions are not present in STD namespace.
DEFINE_SIMPLE_ALIAS(Acos, std::acos)
DEFINE_SIMPLE_ALIAS(Acosh, std::acosh)
DEFINE_SIMPLE_ALIAS(Asin, std::asin)
DEFINE_SIMPLE_ALIAS(Asinh, std::asinh)
DEFINE_SIMPLE_ALIAS(Atan, std::atan)
DEFINE_SIMPLE_ALIAS(Atan2, std::atan2)
DEFINE_SIMPLE_ALIAS(Atanh, std::atanh)
// TODO: enable complex abs, when ABI adjustment for complex
// data type is resolved.
// DEFINE_SIMPLE_ALIAS(CAbs, std::abs)
DEFINE_SIMPLE_ALIAS(Ceil, std::ceil)
DEFINE_SIMPLE_ALIAS(Cos, std::cos)
DEFINE_SIMPLE_ALIAS(Cosh, std::cosh)
DEFINE_SIMPLE_ALIAS(Erf, std::erf)
DEFINE_SIMPLE_ALIAS(Erfc, std::erfc)
DEFINE_SIMPLE_ALIAS(Exp, std::exp)
DEFINE_SIMPLE_ALIAS(Floor, std::floor)
DEFINE_SIMPLE_ALIAS(Hypot, std::hypot)
DEFINE_SIMPLE_ALIAS(J0, j0l)
DEFINE_SIMPLE_ALIAS(J1, j1l)
DEFINE_SIMPLE_ALIAS(Jn, jnl)
DEFINE_SIMPLE_ALIAS(Lgamma, std::lgamma)
DEFINE_SIMPLE_ALIAS(Llround, std::llround)
DEFINE_SIMPLE_ALIAS(Lround, std::lround)
DEFINE_SIMPLE_ALIAS(Log, std::log)
DEFINE_SIMPLE_ALIAS(Log10, std::log10)
DEFINE_SIMPLE_ALIAS(Pow, std::pow)
DEFINE_SIMPLE_ALIAS(Round, std::round)
DEFINE_SIMPLE_ALIAS(Sin, std::sin)
DEFINE_SIMPLE_ALIAS(Sinh, std::sinh)
DEFINE_SIMPLE_ALIAS(Sqrt, std::sqrt)
DEFINE_SIMPLE_ALIAS(Tan, std::tan)
DEFINE_SIMPLE_ALIAS(Tanh, std::tanh)
DEFINE_SIMPLE_ALIAS(Tgamma, std::tgamma)
DEFINE_SIMPLE_ALIAS(Trunc, std::trunc)
DEFINE_SIMPLE_ALIAS(Y0, y0l)
DEFINE_SIMPLE_ALIAS(Y1, y1l)
DEFINE_SIMPLE_ALIAS(Yn, ynl)
#else // LDBL_MANT_DIG != 113
#if !HAS_LIBMF128
// glibc >=2.26 seems to have complete support for __float128
// versions of the math functions.
#error "FLANG_RUNTIME_F128_MATH_LIB=libm build requires libm >=2.26"
#endif

// We can use __float128 versions of libm functions.
// __STDC_WANT_IEC_60559_TYPES_EXT__ needs to be defined
// before including cmath to enable the *f128 prototypes.
// TODO: this needs to be enabled separately, especially
// for complex data types that require C++ complex to C complex
// adjustment to match the ABIs.
#error "Unsupported FLANG_RUNTIME_F128_MATH_LIB=libm build"
#endif // LDBL_MANT_DIG != 113
#elif HAS_QUADMATHLIB
// Define wrapper callers for libquadmath.
#include "quadmath.h"
DEFINE_SIMPLE_ALIAS(Acos, acosq)
Expand Down