Skip to content

Commit 9d9c012

Browse files
authored
[flang][runtime] Added F128 wrappers for LDBL_MANT_DIG == 113 targets. (#83102)
We can use 'long double' variants of the math functions in this case. I used the callees from STD namespace, except for the Bessel's functions. The new code can be enabled with -DFLANG_RUNTIME_F128_MATH_LIB=libm. Support for complex data types is pending.
1 parent ae94354 commit 9d9c012

File tree

2 files changed

+81
-5
lines changed

2 files changed

+81
-5
lines changed

flang/runtime/Float128Math/CMakeLists.txt

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
# will have a dependency on the third-party library that is being
1515
# used for building this FortranFloat128Math library.
1616

17-
if (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libquadmath" OR
18-
${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "quadmath")
17+
include(CheckLibraryExists)
18+
19+
if (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libquadmath")
1920
check_include_file(quadmath.h FOUND_QUADMATH_HEADER)
2021
if(FOUND_QUADMATH_HEADER)
2122
add_compile_definitions(HAS_QUADMATHLIB)
@@ -25,7 +26,18 @@ if (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libquadmath" OR
2526
"to be available: ${FLANG_RUNTIME_F128_MATH_LIB}"
2627
)
2728
endif()
28-
else()
29+
elseif (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libm")
30+
check_library_exists(m sinl "" FOUND_LIBM)
31+
check_library_exists(m sinf128 "" FOUND_LIBMF128)
32+
if (FOUND_LIBM)
33+
add_compile_definitions(HAS_LIBM)
34+
endif()
35+
if (FOUND_LIBMF128)
36+
add_compile_definitions(HAS_LIBMF128)
37+
endif()
38+
endif()
39+
40+
if (NOT FOUND_QUADMATH_HEADER AND NOT FOUND_LIBM)
2941
message(FATAL_ERROR
3042
"Unsupported third-party library for Fortran F128 math runtime: "
3143
"${FLANG_RUNTIME_F128_MATH_LIB}"

flang/runtime/Float128Math/math-entries.h

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "tools.h"
1313
#include "flang/Common/float128.h"
1414
#include "flang/Runtime/entry-names.h"
15+
#include <cfloat>
1516
#include <type_traits>
1617

1718
namespace Fortran::runtime {
@@ -42,7 +43,8 @@ namespace Fortran::runtime {
4243
#define DEFINE_SIMPLE_ALIAS(caller, callee) \
4344
template <typename RT, typename... ATs, RT (*p)(ATs...)> struct caller<p> { \
4445
static RT invoke(ATs... args) { \
45-
static_assert(std::is_invocable_r_v<RT, decltype(callee), ATs...>); \
46+
static_assert(std::is_invocable_r_v<RT, \
47+
decltype(callee(std::declval<ATs>()...))(ATs...), ATs...>); \
4648
if constexpr (std::is_same_v<RT, void>) { \
4749
callee(args...); \
4850
} else { \
@@ -98,7 +100,69 @@ typedef _Complex float __attribute__((mode(TC))) ComplexF128;
98100
typedef _Complex float __attribute__((mode(KC))) ComplexF128;
99101
#endif
100102

101-
#if HAS_QUADMATHLIB
103+
#if HAS_LIBM
104+
// Define wrapper callers for libm.
105+
#include <ccomplex>
106+
#include <cmath>
107+
108+
#if LDBL_MANT_DIG == 113
109+
// Use STD math functions. They provide IEEE-754 128-bit float
110+
// support either via 'long double' or __float128.
111+
// The Bessel's functions are not present in STD namespace.
112+
DEFINE_SIMPLE_ALIAS(Acos, std::acos)
113+
DEFINE_SIMPLE_ALIAS(Acosh, std::acosh)
114+
DEFINE_SIMPLE_ALIAS(Asin, std::asin)
115+
DEFINE_SIMPLE_ALIAS(Asinh, std::asinh)
116+
DEFINE_SIMPLE_ALIAS(Atan, std::atan)
117+
DEFINE_SIMPLE_ALIAS(Atan2, std::atan2)
118+
DEFINE_SIMPLE_ALIAS(Atanh, std::atanh)
119+
// TODO: enable complex abs, when ABI adjustment for complex
120+
// data type is resolved.
121+
// DEFINE_SIMPLE_ALIAS(CAbs, std::abs)
122+
DEFINE_SIMPLE_ALIAS(Ceil, std::ceil)
123+
DEFINE_SIMPLE_ALIAS(Cos, std::cos)
124+
DEFINE_SIMPLE_ALIAS(Cosh, std::cosh)
125+
DEFINE_SIMPLE_ALIAS(Erf, std::erf)
126+
DEFINE_SIMPLE_ALIAS(Erfc, std::erfc)
127+
DEFINE_SIMPLE_ALIAS(Exp, std::exp)
128+
DEFINE_SIMPLE_ALIAS(Floor, std::floor)
129+
DEFINE_SIMPLE_ALIAS(Hypot, std::hypot)
130+
DEFINE_SIMPLE_ALIAS(J0, j0l)
131+
DEFINE_SIMPLE_ALIAS(J1, j1l)
132+
DEFINE_SIMPLE_ALIAS(Jn, jnl)
133+
DEFINE_SIMPLE_ALIAS(Lgamma, std::lgamma)
134+
DEFINE_SIMPLE_ALIAS(Llround, std::llround)
135+
DEFINE_SIMPLE_ALIAS(Lround, std::lround)
136+
DEFINE_SIMPLE_ALIAS(Log, std::log)
137+
DEFINE_SIMPLE_ALIAS(Log10, std::log10)
138+
DEFINE_SIMPLE_ALIAS(Pow, std::pow)
139+
DEFINE_SIMPLE_ALIAS(Round, std::round)
140+
DEFINE_SIMPLE_ALIAS(Sin, std::sin)
141+
DEFINE_SIMPLE_ALIAS(Sinh, std::sinh)
142+
DEFINE_SIMPLE_ALIAS(Sqrt, std::sqrt)
143+
DEFINE_SIMPLE_ALIAS(Tan, std::tan)
144+
DEFINE_SIMPLE_ALIAS(Tanh, std::tanh)
145+
DEFINE_SIMPLE_ALIAS(Tgamma, std::tgamma)
146+
DEFINE_SIMPLE_ALIAS(Trunc, std::trunc)
147+
DEFINE_SIMPLE_ALIAS(Y0, y0l)
148+
DEFINE_SIMPLE_ALIAS(Y1, y1l)
149+
DEFINE_SIMPLE_ALIAS(Yn, ynl)
150+
#else // LDBL_MANT_DIG != 113
151+
#if !HAS_LIBMF128
152+
// glibc >=2.26 seems to have complete support for __float128
153+
// versions of the math functions.
154+
#error "FLANG_RUNTIME_F128_MATH_LIB=libm build requires libm >=2.26"
155+
#endif
156+
157+
// We can use __float128 versions of libm functions.
158+
// __STDC_WANT_IEC_60559_TYPES_EXT__ needs to be defined
159+
// before including cmath to enable the *f128 prototypes.
160+
// TODO: this needs to be enabled separately, especially
161+
// for complex data types that require C++ complex to C complex
162+
// adjustment to match the ABIs.
163+
#error "Unsupported FLANG_RUNTIME_F128_MATH_LIB=libm build"
164+
#endif // LDBL_MANT_DIG != 113
165+
#elif HAS_QUADMATHLIB
102166
// Define wrapper callers for libquadmath.
103167
#include "quadmath.h"
104168
DEFINE_SIMPLE_ALIAS(Acos, acosq)

0 commit comments

Comments
 (0)