diff --git a/flang/include/flang/Runtime/float128.h b/flang/include/flang/Common/float128.h rename from flang/include/flang/Runtime/float128.h rename to flang/include/flang/Common/float128.h --- 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 --- 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 #include #include diff --git a/flang/include/flang/Runtime/numeric.h b/flang/include/flang/Runtime/numeric.h --- 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 --- 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 #include #include diff --git a/flang/include/flang/Runtime/transformational.h b/flang/include/flang/Runtime/transformational.h --- 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 namespace Fortran::runtime { diff --git a/flang/lib/Evaluate/CMakeLists.txt b/flang/lib/Evaluate/CMakeLists.txt --- a/flang/lib/Evaluate/CMakeLists.txt +++ b/flang/lib/Evaluate/CMakeLists.txt @@ -19,6 +19,12 @@ 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 --- 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 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 #include @@ -156,15 +160,20 @@ long double, UnsupportedType>; }; -template <> -struct HostTypeHelper< - Type> { +#if HAS_QUADMATHLIB +template <> struct HostTypeHelper> { + // IEEE 754 128bits + using Type = __float128; +}; +#else +template <> struct HostTypeHelper> { // IEEE 754 128bits using Type = std::conditional_t::digits == 113 && std::numeric_limits::max_exponent == 16384, long double, UnsupportedType>; }; +#endif template struct HostTypeHelper> { using RealT = Fortran::evaluate::Type; @@ -172,6 +181,13 @@ std::complex>, UnsupportedType>; }; +#if HAS_QUADMATHLIB +template <> struct HostTypeHelper> { + using RealT = Fortran::evaluate::Type; + using Type = __complex128; +}; +#endif + template struct HostTypeHelper> { using Type = std::conditional_t; }; diff --git a/flang/lib/Evaluate/intrinsics-library.cpp b/flang/lib/Evaluate/intrinsics-library.cpp --- a/flang/lib/Evaluate/intrinsics-library.cpp +++ b/flang/lib/Evaluate/intrinsics-library.cpp @@ -20,6 +20,10 @@ #include #include #include +#if HAS_QUADMATHLIB +#include "quadmath.h" +#include "flang/Common/float128.h" +#endif #include namespace Fortran::evaluate { @@ -313,6 +317,62 @@ }; #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::Create("acos"), + FolderFactory::Create("acosh"), + FolderFactory::Create("asin"), + FolderFactory::Create("asinh"), + FolderFactory::Create("atan"), + FolderFactory::Create("atan2"), + FolderFactory::Create("atanh"), + FolderFactory::Create("cos"), + FolderFactory::Create("cosh"), + FolderFactory::Create("erf"), + FolderFactory::Create("erfc"), + FolderFactory::Create("exp"), + FolderFactory::Create("gamma"), + FolderFactory::Create("log"), + FolderFactory::Create("log10"), + FolderFactory::Create("log_gamma"), + FolderFactory::Create("pow"), + FolderFactory::Create("sin"), + FolderFactory::Create("sinh"), + FolderFactory::Create("tan"), + FolderFactory::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::Create("acos"), + FolderFactory::Create("acosh"), + FolderFactory::Create("asin"), + FolderFactory::Create("asinh"), + FolderFactory::Create("atan"), + FolderFactory::Create("atanh"), + FolderFactory::Create("cos"), + FolderFactory::Create("cosh"), + FolderFactory::Create("exp"), + FolderFactory::Create("log"), + FolderFactory::Create("pow"), + FolderFactory::Create("sin"), + FolderFactory::Create("sinh"), + FolderFactory::Create("sqrt"), + FolderFactory::Create("tan"), + FolderFactory::Create("tanh"), + }; + static constexpr HostRuntimeMap map{table}; + static_assert(map.Verify(), "map must be sorted"); +}; +#endif + template <> struct HostRuntimeLibrary { using F = FuncPointer; using FN = FuncPointer; @@ -345,7 +405,7 @@ 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 @@ GetHostRuntimeMapHelper(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, version>( @@ -470,6 +536,12 @@ 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 --- 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 @@ MLIRTargetLLVMIRImport ${dialect_libs} ${extension_libs} + ${QUADMATHLIB} LINK_COMPONENTS Passes diff --git a/flang/runtime/dot-product.cpp b/flang/runtime/dot-product.cpp --- 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 --- 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 #include diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp --- 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 #include #include diff --git a/flang/runtime/product.cpp b/flang/runtime/product.cpp --- 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 #include diff --git a/flang/runtime/random.cpp b/flang/runtime/random.cpp --- 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 #include #include diff --git a/flang/runtime/sum.cpp b/flang/runtime/sum.cpp --- 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 #include diff --git a/flang/runtime/transformational.cpp b/flang/runtime/transformational.cpp --- 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 --- a/flang/tools/bbc/CMakeLists.txt +++ b/flang/tools/bbc/CMakeLists.txt @@ -11,6 +11,13 @@ 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 @@ FortranEvaluate FortranSemantics FortranLower +${QUADMATHLIB} ) diff --git a/flang/unittests/Evaluate/CMakeLists.txt b/flang/unittests/Evaluate/CMakeLists.txt --- a/flang/unittests/Evaluate/CMakeLists.txt +++ b/flang/unittests/Evaluate/CMakeLists.txt @@ -8,8 +8,15 @@ 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 --- 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 #include diff --git a/flang/unittests/Runtime/Reduction.cpp b/flang/unittests/Runtime/Reduction.cpp --- 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 --- 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