[flang-commits] [flang] [flang] Added F128 wrappers for __LDBL_MANT_DIG__ == 113 targets. (PR #83102)

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Mon Feb 26 20:13:36 PST 2024


https://github.com/vzakhari created https://github.com/llvm/llvm-project/pull/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.


>From 772cddb6451c0994d90d13b00ce4f348b55b936d Mon Sep 17 00:00:00 2001
From: Slava Zakharin <szakharin at nvidia.com>
Date: Mon, 26 Feb 2024 18:56:46 -0800
Subject: [PATCH] [flang] Added F128 wrappers for __LDBL_MANT_DIG__ == 113
 targets.

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.
---
 flang/runtime/Float128Math/CMakeLists.txt | 18 +++++-
 flang/runtime/Float128Math/math-entries.h | 68 ++++++++++++++++++++++-
 2 files changed, 81 insertions(+), 5 deletions(-)

diff --git a/flang/runtime/Float128Math/CMakeLists.txt b/flang/runtime/Float128Math/CMakeLists.txt
index 2e20f4fd612f24..8d276e8f122728 100644
--- a/flang/runtime/Float128Math/CMakeLists.txt
+++ b/flang/runtime/Float128Math/CMakeLists.txt
@@ -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)
@@ -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}"
diff --git a/flang/runtime/Float128Math/math-entries.h b/flang/runtime/Float128Math/math-entries.h
index d7896ac8279137..fe1525468edcaf 100644
--- a/flang/runtime/Float128Math/math-entries.h
+++ b/flang/runtime/Float128Math/math-entries.h
@@ -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 {
@@ -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 { \
@@ -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)



More information about the flang-commits mailing list