[flang-commits] [flang] 478e0b5 - [flang] Quadmath 128 bit floating point intrinsics

Peter Steinfeld via flang-commits flang-commits at lists.llvm.org
Mon Jul 31 11:12:55 PDT 2023


Author: Peter Steinfeld
Date: 2023-07-31T11:12:29-07:00
New Revision: 478e0b58605c4be16f1590f9b67889290ab45dab

URL: https://github.com/llvm/llvm-project/commit/478e0b58605c4be16f1590f9b67889290ab45dab
DIFF: https://github.com/llvm/llvm-project/commit/478e0b58605c4be16f1590f9b67889290ab45dab.diff

LOG: [flang] Quadmath 128 bit floating point intrinsics

This update allows constant folding for many 128 bit floating point intrinsics
through the library quadmath, which is only available on some platforms.

Differential Revision: https://reviews.llvm.org/D156435

Added: 
    flang/include/flang/Common/float128.h

Modified: 
    flang/include/flang/Runtime/cpp-type.h
    flang/include/flang/Runtime/numeric.h
    flang/include/flang/Runtime/reduction.h
    flang/include/flang/Runtime/transformational.h
    flang/lib/Evaluate/CMakeLists.txt
    flang/lib/Evaluate/host.h
    flang/lib/Evaluate/intrinsics-library.cpp
    flang/lib/Frontend/CMakeLists.txt
    flang/runtime/dot-product.cpp
    flang/runtime/extrema.cpp
    flang/runtime/numeric.cpp
    flang/runtime/product.cpp
    flang/runtime/random.cpp
    flang/runtime/sum.cpp
    flang/runtime/transformational.cpp
    flang/tools/bbc/CMakeLists.txt
    flang/unittests/Evaluate/CMakeLists.txt
    flang/unittests/Runtime/Numeric.cpp
    flang/unittests/Runtime/Reduction.cpp
    flang/unittests/Runtime/Transformational.cpp

Removed: 
    flang/include/flang/Runtime/float128.h


################################################################################
diff  --git a/flang/include/flang/Runtime/float128.h b/flang/include/flang/Common/float128.h
similarity index 90%
rename from flang/include/flang/Runtime/float128.h
rename to flang/include/flang/Common/float128.h
index 5121f7f3788f8d..3443aa06437b04 100644
--- a/flang/include/flang/Runtime/float128.h
+++ b/flang/include/flang/Common/float128.h
@@ -1,4 +1,4 @@
-/*===-- flang/Runtime/float128.h ----------------------------------*- C -*-===
+/*===-- flang/Common/float128.h ----------------------------------*- C -*-===
  *
  * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  * See https://llvm.org/LICENSE.txt for license information.
@@ -17,8 +17,8 @@
  * long double and __float128; prefer long double by testing for it first.
  */
 
-#ifndef FORTRAN_RUNTIME_FLOAT128_H_
-#define FORTRAN_RUNTIME_FLOAT128_H_
+#ifndef FORTRAN_COMMON_FLOAT128_H_
+#define FORTRAN_COMMON_FLOAT128_H_
 
 #ifdef __cplusplus
 /*
@@ -49,4 +49,4 @@
 #endif /* (defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)) && \
           !defined(_LIBCPP_VERSION)  && !defined(__CUDA_ARCH__) */
 
-#endif /* FORTRAN_RUNTIME_FLOAT128_H_ */
+#endif /* FORTRAN_COMMON_FLOAT128_H_ */

diff  --git a/flang/include/flang/Runtime/cpp-type.h b/flang/include/flang/Runtime/cpp-type.h
index 00af2c115484e8..5141d0691c5c6c 100644
--- a/flang/include/flang/Runtime/cpp-type.h
+++ b/flang/include/flang/Runtime/cpp-type.h
@@ -12,8 +12,8 @@
 #define FORTRAN_RUNTIME_CPP_TYPE_H_
 
 #include "flang/Common/Fortran.h"
+#include "flang/Common/float128.h"
 #include "flang/Common/uint128.h"
-#include "flang/Runtime/float128.h"
 #include <cfloat>
 #include <complex>
 #include <cstdint>

diff  --git a/flang/include/flang/Runtime/numeric.h b/flang/include/flang/Runtime/numeric.h
index 27106590810131..e4e11a61731a61 100644
--- a/flang/include/flang/Runtime/numeric.h
+++ b/flang/include/flang/Runtime/numeric.h
@@ -12,6 +12,7 @@
 #ifndef FORTRAN_RUNTIME_NUMERIC_H_
 #define FORTRAN_RUNTIME_NUMERIC_H_
 
+#include "flang/Common/float128.h"
 #include "flang/Runtime/cpp-type.h"
 #include "flang/Runtime/entry-names.h"
 

diff  --git a/flang/include/flang/Runtime/reduction.h b/flang/include/flang/Runtime/reduction.h
index 82c67ca4da6b67..a8469cb9dac872 100644
--- a/flang/include/flang/Runtime/reduction.h
+++ b/flang/include/flang/Runtime/reduction.h
@@ -11,10 +11,10 @@
 #ifndef FORTRAN_RUNTIME_REDUCTION_H_
 #define FORTRAN_RUNTIME_REDUCTION_H_
 
+#include "flang/Common/float128.h"
 #include "flang/Common/uint128.h"
 #include "flang/Runtime/cpp-type.h"
 #include "flang/Runtime/entry-names.h"
-#include "flang/Runtime/float128.h"
 #include <cfloat>
 #include <cinttypes>
 #include <complex>

diff  --git a/flang/include/flang/Runtime/transformational.h b/flang/include/flang/Runtime/transformational.h
index 33fe2e54ed5dcd..a39b872f376a69 100644
--- a/flang/include/flang/Runtime/transformational.h
+++ b/flang/include/flang/Runtime/transformational.h
@@ -17,9 +17,9 @@
 #ifndef FORTRAN_RUNTIME_TRANSFORMATIONAL_H_
 #define FORTRAN_RUNTIME_TRANSFORMATIONAL_H_
 
+#include "flang/Common/float128.h"
 #include "flang/Runtime/cpp-type.h"
 #include "flang/Runtime/entry-names.h"
-#include "flang/Runtime/float128.h"
 #include <cinttypes>
 
 namespace Fortran::runtime {

diff  --git a/flang/lib/Evaluate/CMakeLists.txt b/flang/lib/Evaluate/CMakeLists.txt
index 7195edc3c0e564..e75aabafc323fd 100644
--- a/flang/lib/Evaluate/CMakeLists.txt
+++ b/flang/lib/Evaluate/CMakeLists.txt
@@ -19,6 +19,12 @@ if (LIBPGMATH_DIR)
   endif()
 endif()
 
+check_include_file(quadmath.h FOUND_QUADMATH_HEADER)
+check_library_exists(quadmath sinq "" FOUND_QUADMATH_LIB)
+if(FOUND_QUADMATH_HEADER AND FOUND_QUADMATH_LIB)
+  add_compile_definitions(HAS_QUADMATHLIB)
+endif()
+
 add_flang_library(FortranEvaluate
   call.cpp
   characteristics.cpp

diff  --git a/flang/lib/Evaluate/host.h b/flang/lib/Evaluate/host.h
index 49accd83b6b471..7edc254d6d4c74 100644
--- a/flang/lib/Evaluate/host.h
+++ b/flang/lib/Evaluate/host.h
@@ -17,6 +17,10 @@
 // hardware type maps to Fortran intrinsic type T. Then HostType<T> can be used
 // to safely refer to this hardware type.
 
+#if HAS_QUADMATHLIB
+#include "quadmath.h"
+#include "flang/Common/float128.h"
+#endif
 #include "flang/Evaluate/type.h"
 #include <cfenv>
 #include <complex>
@@ -156,15 +160,20 @@ struct HostTypeHelper<
       long double, UnsupportedType>;
 };
 
-template <>
-struct HostTypeHelper<
-    Type<TypeCategory::Real, common::RealKindForPrecision(113)>> {
+#if HAS_QUADMATHLIB
+template <> struct HostTypeHelper<Type<TypeCategory::Real, 16>> {
+  // IEEE 754 128bits
+  using Type = __float128;
+};
+#else
+template <> struct HostTypeHelper<Type<TypeCategory::Real, 16>> {
   // IEEE 754 128bits
   using Type = std::conditional_t<sizeof(long double) == 16 &&
           std::numeric_limits<long double>::digits == 113 &&
           std::numeric_limits<long double>::max_exponent == 16384,
       long double, UnsupportedType>;
 };
+#endif
 
 template <int KIND> struct HostTypeHelper<Type<TypeCategory::Complex, KIND>> {
   using RealT = Fortran::evaluate::Type<TypeCategory::Real, KIND>;
@@ -172,6 +181,13 @@ template <int KIND> struct HostTypeHelper<Type<TypeCategory::Complex, KIND>> {
       std::complex<HostType<RealT>>, UnsupportedType>;
 };
 
+#if HAS_QUADMATHLIB
+template <> struct HostTypeHelper<Type<TypeCategory::Complex, 16>> {
+  using RealT = Fortran::evaluate::Type<TypeCategory::Real, 16>;
+  using Type = __complex128;
+};
+#endif
+
 template <int KIND> struct HostTypeHelper<Type<TypeCategory::Logical, KIND>> {
   using Type = std::conditional_t<KIND <= 8, std::uint8_t, UnsupportedType>;
 };

diff  --git a/flang/lib/Evaluate/intrinsics-library.cpp b/flang/lib/Evaluate/intrinsics-library.cpp
index 3a6d28e4ab040d..892b8d0b6a0639 100644
--- a/flang/lib/Evaluate/intrinsics-library.cpp
+++ b/flang/lib/Evaluate/intrinsics-library.cpp
@@ -20,6 +20,10 @@
 #include <cmath>
 #include <complex>
 #include <functional>
+#if HAS_QUADMATHLIB
+#include "quadmath.h"
+#include "flang/Common/float128.h"
+#endif
 #include <type_traits>
 
 namespace Fortran::evaluate {
@@ -313,6 +317,62 @@ template <> struct HostRuntimeLibrary<float, LibraryVersion::LibmExtensions> {
 };
 #endif
 
+#if HAS_QUADMATHLIB
+template <> struct HostRuntimeLibrary<__float128, LibraryVersion::Libm> {
+  using F = FuncPointer<__float128, __float128>;
+  using F2 = FuncPointer<__float128, __float128, __float128>;
+  static constexpr HostRuntimeFunction table[]{
+      FolderFactory<F, F{::acosq}>::Create("acos"),
+      FolderFactory<F, F{::acoshq}>::Create("acosh"),
+      FolderFactory<F, F{::asinq}>::Create("asin"),
+      FolderFactory<F, F{::asinhq}>::Create("asinh"),
+      FolderFactory<F, F{::atanq}>::Create("atan"),
+      FolderFactory<F2, F2{::atan2q}>::Create("atan2"),
+      FolderFactory<F, F{::atanhq}>::Create("atanh"),
+      FolderFactory<F, F{::cosq}>::Create("cos"),
+      FolderFactory<F, F{::coshq}>::Create("cosh"),
+      FolderFactory<F, F{::erfq}>::Create("erf"),
+      FolderFactory<F, F{::erfcq}>::Create("erfc"),
+      FolderFactory<F, F{::expq}>::Create("exp"),
+      FolderFactory<F, F{::tgammaq}>::Create("gamma"),
+      FolderFactory<F, F{::logq}>::Create("log"),
+      FolderFactory<F, F{::log10q}>::Create("log10"),
+      FolderFactory<F, F{::lgammaq}>::Create("log_gamma"),
+      FolderFactory<F2, F2{::powq}>::Create("pow"),
+      FolderFactory<F, F{::sinq}>::Create("sin"),
+      FolderFactory<F, F{::sinhq}>::Create("sinh"),
+      FolderFactory<F, F{::tanq}>::Create("tan"),
+      FolderFactory<F, F{::tanhq}>::Create("tanh"),
+  };
+  static constexpr HostRuntimeMap map{table};
+  static_assert(map.Verify(), "map must be sorted");
+};
+template <> struct HostRuntimeLibrary<__complex128, LibraryVersion::Libm> {
+  using F = FuncPointer<__complex128, __complex128>;
+  using F2 = FuncPointer<__complex128, __complex128, __complex128>;
+  static constexpr HostRuntimeFunction table[]{
+      FolderFactory<F, F{::cacosq}>::Create("acos"),
+      FolderFactory<F, F{::cacoshq}>::Create("acosh"),
+      FolderFactory<F, F{::casinq}>::Create("asin"),
+      FolderFactory<F, F{::casinhq}>::Create("asinh"),
+      FolderFactory<F, F{::catanq}>::Create("atan"),
+      FolderFactory<F, F{::catanhq}>::Create("atanh"),
+      FolderFactory<F, F{::ccosq}>::Create("cos"),
+      FolderFactory<F, F{::ccoshq}>::Create("cosh"),
+      FolderFactory<F, F{::cexpq}>::Create("exp"),
+      FolderFactory<F, F{::clogq}>::Create("log"),
+      FolderFactory<F2, F2{::cpowq}>::Create("pow"),
+      FolderFactory<F, F{::csinq}>::Create("sin"),
+      FolderFactory<F, F{::csinhq}>::Create("sinh"),
+      FolderFactory<F, F{::csqrtq}>::Create("sqrt"),
+      FolderFactory<F, F{::ctanq}>::Create("tan"),
+      FolderFactory<F, F{::ctanhq}>::Create("tanh"),
+  };
+  static constexpr HostRuntimeMap map{table};
+  static_assert(map.Verify(), "map must be sorted");
+};
+#endif
+
 template <> struct HostRuntimeLibrary<double, LibraryVersion::LibmExtensions> {
   using F = FuncPointer<double, double>;
   using FN = FuncPointer<double, int, double>;
@@ -345,7 +405,7 @@ struct HostRuntimeLibrary<long double, LibraryVersion::LibmExtensions> {
   static_assert(map.Verify(), "map must be sorted");
 };
 #endif // LDBL_MANT_DIG == 80 || LDBL_MANT_DIG == 113
-#endif
+#endif //_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
 
 /// Define pgmath description
 #if LINK_WITH_LIBPGMATH
@@ -455,6 +515,12 @@ static const HostRuntimeMap *GetHostRuntimeMapVersion(DynamicType resultType) {
             GetHostRuntimeMapHelper<long double, version>(resultType)}) {
       return map;
     }
+#if HAS_QUADMATHLIB
+    if (const auto *map{
+            GetHostRuntimeMapHelper<__float128, version>(resultType)}) {
+      return map;
+    }
+#endif
   }
   if (resultType.category() == TypeCategory::Complex) {
     if (const auto *map{GetHostRuntimeMapHelper<std::complex<float>, version>(
@@ -470,6 +536,12 @@ static const HostRuntimeMap *GetHostRuntimeMapVersion(DynamicType resultType) {
                 resultType)}) {
       return map;
     }
+#if HAS_QUADMATHLIB
+    if (const auto *map{
+            GetHostRuntimeMapHelper<__complex128, version>(resultType)}) {
+      return map;
+    }
+#endif
   }
   return nullptr;
 }

diff  --git a/flang/lib/Frontend/CMakeLists.txt b/flang/lib/Frontend/CMakeLists.txt
index a06b610112f209..d31ae5270e5c94 100644
--- a/flang/lib/Frontend/CMakeLists.txt
+++ b/flang/lib/Frontend/CMakeLists.txt
@@ -1,6 +1,12 @@
 get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
 get_property(extension_libs GLOBAL PROPERTY MLIR_EXTENSION_LIBS)
 
+check_include_file(quadmath.h FOUND_QUADMATH_HEADER)
+check_library_exists(quadmath sinq "" FOUND_QUADMATH_LIB)
+if(FOUND_QUADMATH_HEADER AND FOUND_QUADMATH_LIB)
+  set(QUADMATHLIB quadmath)
+endif()
+
 add_flang_library(flangFrontend
   CompilerInstance.cpp
   CompilerInvocation.cpp
@@ -42,6 +48,7 @@ add_flang_library(flangFrontend
   MLIRTargetLLVMIRImport
   ${dialect_libs}
   ${extension_libs}
+  ${QUADMATHLIB}
 
   LINK_COMPONENTS
   Passes

diff  --git a/flang/runtime/dot-product.cpp b/flang/runtime/dot-product.cpp
index 857ed6759817aa..58382863a50067 100644
--- a/flang/runtime/dot-product.cpp
+++ b/flang/runtime/dot-product.cpp
@@ -9,6 +9,7 @@
 #include "float.h"
 #include "terminator.h"
 #include "tools.h"
+#include "flang/Common/float128.h"
 #include "flang/Runtime/cpp-type.h"
 #include "flang/Runtime/descriptor.h"
 #include "flang/Runtime/reduction.h"

diff  --git a/flang/runtime/extrema.cpp b/flang/runtime/extrema.cpp
index d02cf46a6f3b88..70b2c4d3d735a1 100644
--- a/flang/runtime/extrema.cpp
+++ b/flang/runtime/extrema.cpp
@@ -11,8 +11,8 @@
 // NORM2 using common infrastructure.
 
 #include "reduction-templates.h"
+#include "flang/Common/float128.h"
 #include "flang/Runtime/character.h"
-#include "flang/Runtime/float128.h"
 #include "flang/Runtime/reduction.h"
 #include <algorithm>
 #include <cfloat>

diff  --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp
index 5376bcb569fbea..589bd996f668a0 100644
--- a/flang/runtime/numeric.cpp
+++ b/flang/runtime/numeric.cpp
@@ -8,7 +8,7 @@
 
 #include "flang/Runtime/numeric.h"
 #include "terminator.h"
-#include "flang/Runtime/float128.h"
+#include "flang/Common/float128.h"
 #include <cfloat>
 #include <climits>
 #include <cmath>

diff  --git a/flang/runtime/product.cpp b/flang/runtime/product.cpp
index 072e2fed2c28fc..683cb61fe9951a 100644
--- a/flang/runtime/product.cpp
+++ b/flang/runtime/product.cpp
@@ -9,7 +9,7 @@
 // Implements PRODUCT for all required operand types and shapes.
 
 #include "reduction-templates.h"
-#include "flang/Runtime/float128.h"
+#include "flang/Common/float128.h"
 #include "flang/Runtime/reduction.h"
 #include <cfloat>
 #include <cinttypes>

diff  --git a/flang/runtime/random.cpp b/flang/runtime/random.cpp
index 4b9946a7c413d6..b7175d6b63c35f 100644
--- a/flang/runtime/random.cpp
+++ b/flang/runtime/random.cpp
@@ -12,11 +12,11 @@
 #include "flang/Runtime/random.h"
 #include "lock.h"
 #include "terminator.h"
+#include "flang/Common/float128.h"
 #include "flang/Common/leading-zero-bit-count.h"
 #include "flang/Common/uint128.h"
 #include "flang/Runtime/cpp-type.h"
 #include "flang/Runtime/descriptor.h"
-#include "flang/Runtime/float128.h"
 #include <algorithm>
 #include <cmath>
 #include <cstdint>

diff  --git a/flang/runtime/sum.cpp b/flang/runtime/sum.cpp
index ba0e75d017a239..c3c14829638462 100644
--- a/flang/runtime/sum.cpp
+++ b/flang/runtime/sum.cpp
@@ -13,7 +13,7 @@
 // (basically the same as manual "double-double").
 
 #include "reduction-templates.h"
-#include "flang/Runtime/float128.h"
+#include "flang/Common/float128.h"
 #include "flang/Runtime/reduction.h"
 #include <cfloat>
 #include <cinttypes>

diff  --git a/flang/runtime/transformational.cpp b/flang/runtime/transformational.cpp
index b4761497db8c1b..c93c3d65a09539 100644
--- a/flang/runtime/transformational.cpp
+++ b/flang/runtime/transformational.cpp
@@ -20,6 +20,7 @@
 #include "copy.h"
 #include "terminator.h"
 #include "tools.h"
+#include "flang/Common/float128.h"
 #include "flang/Runtime/descriptor.h"
 
 namespace Fortran::runtime {

diff  --git a/flang/tools/bbc/CMakeLists.txt b/flang/tools/bbc/CMakeLists.txt
index 0ff64fb0ab92ab..4c6273d1689225 100644
--- a/flang/tools/bbc/CMakeLists.txt
+++ b/flang/tools/bbc/CMakeLists.txt
@@ -11,6 +11,13 @@ FIROptCodeGenPassIncGen
 llvm_update_compile_flags(bbc)
 get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
 get_property(extension_libs GLOBAL PROPERTY MLIR_EXTENSION_LIBS)
+
+check_include_file(quadmath.h FOUND_QUADMATH_HEADER)
+check_library_exists(quadmath sinq "" FOUND_QUADMATH_LIB)
+if(FOUND_QUADMATH_HEADER AND FOUND_QUADMATH_LIB)
+  set(QUADMATHLIB quadmath)
+endif()
+
 target_link_libraries(bbc PRIVATE
 FIRDialect
 FIRDialectSupport
@@ -28,4 +35,5 @@ FortranParser
 FortranEvaluate
 FortranSemantics
 FortranLower
+${QUADMATHLIB}
 )

diff  --git a/flang/unittests/Evaluate/CMakeLists.txt b/flang/unittests/Evaluate/CMakeLists.txt
index ffd821ac65eb38..e4a4df31b2a2a5 100644
--- a/flang/unittests/Evaluate/CMakeLists.txt
+++ b/flang/unittests/Evaluate/CMakeLists.txt
@@ -8,8 +8,15 @@ if (LLVM_LINK_LLVM_DYLIB)
 else()
   llvm_map_components_to_libnames(llvm_libs Support)
 endif()
+
+check_include_file(quadmath.h FOUND_QUADMATH_HEADER)
+check_library_exists(quadmath sinq "" FOUND_QUADMATH_LIB)
+if(FOUND_QUADMATH_HEADER AND FOUND_QUADMATH_LIB)
+  set(QUADMATHLIB quadmath)
+endif()
+
 target_link_libraries(FortranEvaluateTesting
-    ${llvm_libs})
+  ${llvm_libs} ${QUADMATHLIB})
 
 add_flang_nongtest_unittest(leading-zero-bit-count
   FortranEvaluateTesting

diff  --git a/flang/unittests/Runtime/Numeric.cpp b/flang/unittests/Runtime/Numeric.cpp
index 456d25fa4e1ebe..5afed750c0b183 100644
--- a/flang/unittests/Runtime/Numeric.cpp
+++ b/flang/unittests/Runtime/Numeric.cpp
@@ -8,6 +8,7 @@
 
 #include "flang/Runtime/numeric.h"
 #include "gtest/gtest.h"
+#include "flang/Common/float128.h"
 #include <cmath>
 #include <limits>
 

diff  --git a/flang/unittests/Runtime/Reduction.cpp b/flang/unittests/Runtime/Reduction.cpp
index 064edd4ce3db7f..b17988bc17699d 100644
--- a/flang/unittests/Runtime/Reduction.cpp
+++ b/flang/unittests/Runtime/Reduction.cpp
@@ -9,6 +9,7 @@
 #include "flang/Runtime/reduction.h"
 #include "gtest/gtest.h"
 #include "tools.h"
+#include "flang/Common/float128.h"
 #include "flang/Runtime/allocatable.h"
 #include "flang/Runtime/cpp-type.h"
 #include "flang/Runtime/descriptor.h"

diff  --git a/flang/unittests/Runtime/Transformational.cpp b/flang/unittests/Runtime/Transformational.cpp
index 70ab4241656485..942a20647ded78 100644
--- a/flang/unittests/Runtime/Transformational.cpp
+++ b/flang/unittests/Runtime/Transformational.cpp
@@ -9,6 +9,7 @@
 #include "flang/Runtime/transformational.h"
 #include "gtest/gtest.h"
 #include "tools.h"
+#include "flang/Common/float128.h"
 #include "flang/Runtime/type-code.h"
 #include <vector>
 


        


More information about the flang-commits mailing list