[flang-commits] [flang] 4daa33f - [flang][runtime] Use __float128 where possible & needed in runtime

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Sun Jun 5 11:02:26 PDT 2022


Author: Peter Klausler
Date: 2022-06-05T09:16:57-07:00
New Revision: 4daa33f6d14b8356c492d8a385d77de7994ff565

URL: https://github.com/llvm/llvm-project/commit/4daa33f6d14b8356c492d8a385d77de7994ff565
DIFF: https://github.com/llvm/llvm-project/commit/4daa33f6d14b8356c492d8a385d77de7994ff565.diff

LOG: [flang][runtime] Use __float128 where possible & needed in runtime

On targets with __float128 available and distinct from long double,
use it to support more kind=16 entry points.  This affects mostly
x86-64 targets.  This means that more runtime entry points are
defined for lowering to call.

Delete Common/long-double.h and its LONG_DOUBLE macro in favor of
testing the standard macro LDBL_MANT_DIG.

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

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

Modified: 
    flang/include/flang/Runtime/cpp-type.h
    flang/include/flang/Runtime/numeric.h
    flang/include/flang/Runtime/reduction.h
    flang/lib/Decimal/binary-to-decimal.cpp
    flang/lib/Evaluate/intrinsics-library.cpp
    flang/runtime/complex-reduction.c
    flang/runtime/dot-product.cpp
    flang/runtime/extrema.cpp
    flang/runtime/findloc.cpp
    flang/runtime/numeric.cpp
    flang/runtime/product.cpp
    flang/runtime/random.cpp
    flang/runtime/sum.cpp
    flang/runtime/tools.h

Removed: 
    flang/include/flang/Common/long-double.h


################################################################################
diff  --git a/flang/include/flang/Common/long-double.h b/flang/include/flang/Common/long-double.h
deleted file mode 100644
index b1d39a982bd5..000000000000
--- a/flang/include/flang/Common/long-double.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*===-- include/flang/Common/config.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.
- * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- *
- * ===-----------------------------------------------------------------------===
- */
-
-/* This header can be used by both C and C++. */
-
-#ifndef FORTRAN_COMMON_LONG_DOUBLE_H
-#define FORTRAN_COMMON_LONG_DOUBLE_H
-
-#ifdef _MSC_VER /* no long double */
-#undef LONG_DOUBLE
-#elif __x86_64__ /* x87 extended precision */
-#define LONG_DOUBLE 80
-#else
-#define LONG_DOUBLE 128
-#endif
-
-#endif /* FORTRAN_COMMON_LONG_DOUBLE_H */

diff  --git a/flang/include/flang/Runtime/cpp-type.h b/flang/include/flang/Runtime/cpp-type.h
index 38a8cf7e7e6c..aa4b6f360124 100644
--- a/flang/include/flang/Runtime/cpp-type.h
+++ b/flang/include/flang/Runtime/cpp-type.h
@@ -13,8 +13,11 @@
 
 #include "flang/Common/Fortran.h"
 #include "flang/Common/uint128.h"
+#include "flang/Runtime/float128.h"
+#include <cfloat>
 #include <complex>
 #include <cstdint>
+#include <type_traits>
 
 namespace Fortran::runtime {
 
@@ -24,6 +27,12 @@ template <TypeCategory CAT, int KIND> struct CppTypeForHelper {};
 template <TypeCategory CAT, int KIND>
 using CppTypeFor = typename CppTypeForHelper<CAT, KIND>::type;
 
+template <TypeCategory CAT, int KIND, bool SFINAE = false>
+constexpr bool HasCppTypeFor{false};
+template <TypeCategory CAT, int KIND>
+constexpr bool HasCppTypeFor<CAT, KIND, true>{
+    !std::is_void_v<typename CppTypeForHelper<CAT, KIND>::type>};
+
 template <int KIND> struct CppTypeForHelper<TypeCategory::Integer, KIND> {
   using type = common::HostSignedIntType<8 * KIND>;
 };
@@ -35,12 +44,21 @@ template <> struct CppTypeForHelper<TypeCategory::Real, 4> {
 template <> struct CppTypeForHelper<TypeCategory::Real, 8> {
   using type = double;
 };
+#if LDBL_MANT_DIG == 64
 template <> struct CppTypeForHelper<TypeCategory::Real, 10> {
   using type = long double;
 };
+#endif
+#if LDBL_MANT_DIG == 113
+using CppFloat128Type = long double;
+#elif HAS_FLOAT128
+using CppFloat128Type = __float128;
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 template <> struct CppTypeForHelper<TypeCategory::Real, 16> {
-  using type = long double;
+  using type = CppFloat128Type;
 };
+#endif
 
 template <int KIND> struct CppTypeForHelper<TypeCategory::Complex, KIND> {
   using type = std::complex<CppTypeFor<TypeCategory::Real, KIND>>;

diff  --git a/flang/include/flang/Runtime/float128.h b/flang/include/flang/Runtime/float128.h
new file mode 100644
index 000000000000..a5f96cae9feb
--- /dev/null
+++ b/flang/include/flang/Runtime/float128.h
@@ -0,0 +1,32 @@
+/*===-- flang/Runtime/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.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===----------------------------------------------------------------------===*/
+
+/* This header is usable in both C and C++ code.
+ * Isolates build compiler checks to determine the presence of an IEEE-754
+ * quad-precision type named __float128 type that isn't __ibm128
+ * (double/double). We don't care whether the type has underlying hardware
+ * support or is emulated.
+ *
+ * 128-bit arithmetic may be available via "long double"; this can
+ * be determined by LDBL_MANT_DIG == 113.  A machine may have both 128-bit
+ * long double and __float128; prefer long double by testing for it first.
+ */
+
+#ifndef FORTRAN_RUNTIME_FLOAT128_H_
+#define FORTRAN_RUNTIME_FLOAT128_H_
+
+#undef HAS_FLOAT128
+#if __x86_64__
+#if __GNUC__ >= 7 || __clang_major >= 7
+#define HAS_FLOAT128 1
+#endif
+#elif defined __PPC__ && __GNUC__ >= 8
+#define HAS_FLOAT128 1
+#endif
+
+#endif /* FORTRAN_RUNTIME_FLOAT128_H_ */

diff  --git a/flang/include/flang/Runtime/numeric.h b/flang/include/flang/Runtime/numeric.h
index a1645eb4ef67..d68c5b4a9604 100644
--- a/flang/include/flang/Runtime/numeric.h
+++ b/flang/include/flang/Runtime/numeric.h
@@ -23,60 +23,84 @@ CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint4_4)(
     CppTypeFor<TypeCategory::Real, 4>);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint4_8)(
     CppTypeFor<TypeCategory::Real, 4>);
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint4_10)(
     CppTypeFor<TypeCategory::Real, 4>);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint4_16)(
     CppTypeFor<TypeCategory::Real, 4>);
+#endif
 CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint8_4)(
     CppTypeFor<TypeCategory::Real, 8>);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint8_8)(
     CppTypeFor<TypeCategory::Real, 8>);
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint8_10)(
     CppTypeFor<TypeCategory::Real, 8>);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint8_16)(
     CppTypeFor<TypeCategory::Real, 8>);
+#endif
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint10_4)(
     CppTypeFor<TypeCategory::Real, 10>);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint10_8)(
     CppTypeFor<TypeCategory::Real, 10>);
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint10_10)(
     CppTypeFor<TypeCategory::Real, 10>);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint16_4)(
     CppTypeFor<TypeCategory::Real, 16>);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint16_8)(
     CppTypeFor<TypeCategory::Real, 16>);
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint16_16)(
     CppTypeFor<TypeCategory::Real, 16>);
+#endif
 
 // ANINT
 CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint4_4)(
     CppTypeFor<TypeCategory::Real, 4>);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint4_8)(
     CppTypeFor<TypeCategory::Real, 4>);
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint4_10)(
     CppTypeFor<TypeCategory::Real, 4>);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint4_16)(
     CppTypeFor<TypeCategory::Real, 4>);
+#endif
 CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint8_4)(
     CppTypeFor<TypeCategory::Real, 8>);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint8_8)(
     CppTypeFor<TypeCategory::Real, 8>);
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint8_10)(
     CppTypeFor<TypeCategory::Real, 8>);
+#endif
+#if LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint8_16)(
     CppTypeFor<TypeCategory::Real, 8>);
+#endif
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint10_4)(
     CppTypeFor<TypeCategory::Real, 10>);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint10_8)(
     CppTypeFor<TypeCategory::Real, 10>);
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint10_10)(
     CppTypeFor<TypeCategory::Real, 10>);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint16_4)(
     CppTypeFor<TypeCategory::Real, 16>);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint16_8)(
     CppTypeFor<TypeCategory::Real, 16>);
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint16_16)(
     CppTypeFor<TypeCategory::Real, 16>);
+#endif
 
 // CEILING
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling4_1)(
@@ -103,6 +127,7 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling8_8)(
 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling8_16)(
     CppTypeFor<TypeCategory::Real, 8>);
 #endif
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling10_1)(
     CppTypeFor<TypeCategory::Real, 10>);
 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling10_2)(
@@ -115,6 +140,8 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling10_8)(
 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling10_16)(
     CppTypeFor<TypeCategory::Real, 10>);
 #endif
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling16_1)(
     CppTypeFor<TypeCategory::Real, 16>);
 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling16_2)(
@@ -127,6 +154,7 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling16_8)(
 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling16_16)(
     CppTypeFor<TypeCategory::Real, 16>);
 #endif
+#endif
 
 // EXPONENT is defined to return default INTEGER; support INTEGER(4 & 8)
 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent4_4)(
@@ -137,14 +165,18 @@ CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent8_4)(
     CppTypeFor<TypeCategory::Real, 8>);
 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent8_8)(
     CppTypeFor<TypeCategory::Real, 8>);
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent10_4)(
     CppTypeFor<TypeCategory::Real, 10>);
 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent10_8)(
     CppTypeFor<TypeCategory::Real, 10>);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT
 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent16_4)(
     CppTypeFor<TypeCategory::Real, 16>);
 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent16_8)(
     CppTypeFor<TypeCategory::Real, 16>);
+#endif
 
 // FLOOR
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor4_1)(
@@ -171,6 +203,7 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor8_8)(
 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor8_16)(
     CppTypeFor<TypeCategory::Real, 8>);
 #endif
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor10_1)(
     CppTypeFor<TypeCategory::Real, 10>);
 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor10_2)(
@@ -183,6 +216,8 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor10_8)(
 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor10_16)(
     CppTypeFor<TypeCategory::Real, 10>);
 #endif
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor16_1)(
     CppTypeFor<TypeCategory::Real, 16>);
 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor16_2)(
@@ -195,22 +230,31 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor16_8)(
 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor16_16)(
     CppTypeFor<TypeCategory::Real, 16>);
 #endif
+#endif
 
 // FRACTION
 CppTypeFor<TypeCategory::Real, 4> RTNAME(Fraction4)(
     CppTypeFor<TypeCategory::Real, 4>);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(Fraction8)(
     CppTypeFor<TypeCategory::Real, 8>);
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Fraction10)(
     CppTypeFor<TypeCategory::Real, 10>);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Fraction16)(
     CppTypeFor<TypeCategory::Real, 16>);
+#endif
 
 // ISNAN / IEEE_IS_NAN
 bool RTNAME(IsNaN4)(CppTypeFor<TypeCategory::Real, 4>);
 bool RTNAME(IsNaN8)(CppTypeFor<TypeCategory::Real, 8>);
+#if LDBL_MANT_DIG == 64
 bool RTNAME(IsNaN10)(CppTypeFor<TypeCategory::Real, 10>);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 bool RTNAME(IsNaN16)(CppTypeFor<TypeCategory::Real, 16>);
+#endif
 
 // MOD & MODULO
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModInteger1)(
@@ -237,12 +281,16 @@ CppTypeFor<TypeCategory::Real, 4> RTNAME(ModReal4)(
 CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
     CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>,
     const char *sourceFile = nullptr, int sourceLine = 0);
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
     CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>,
     const char *sourceFile = nullptr, int sourceLine = 0);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
     CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>,
     const char *sourceFile = nullptr, int sourceLine = 0);
+#endif
 
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModuloInteger1)(
     CppTypeFor<TypeCategory::Integer, 1>, CppTypeFor<TypeCategory::Integer, 1>,
@@ -268,12 +316,16 @@ CppTypeFor<TypeCategory::Real, 4> RTNAME(ModuloReal4)(
 CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
     CppTypeFor<TypeCategory::Real, 8>, CppTypeFor<TypeCategory::Real, 8>,
     const char *sourceFile = nullptr, int sourceLine = 0);
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
     CppTypeFor<TypeCategory::Real, 10>, CppTypeFor<TypeCategory::Real, 10>,
     const char *sourceFile = nullptr, int sourceLine = 0);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
     CppTypeFor<TypeCategory::Real, 16>, CppTypeFor<TypeCategory::Real, 16>,
     const char *sourceFile = nullptr, int sourceLine = 0);
+#endif
 
 // NINT
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint4_1)(
@@ -300,6 +352,7 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint8_8)(
 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint8_16)(
     CppTypeFor<TypeCategory::Real, 8>);
 #endif
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint10_1)(
     CppTypeFor<TypeCategory::Real, 10>);
 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint10_2)(
@@ -312,6 +365,8 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint10_8)(
 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint10_16)(
     CppTypeFor<TypeCategory::Real, 10>);
 #endif
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint16_1)(
     CppTypeFor<TypeCategory::Real, 16>);
 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint16_2)(
@@ -320,10 +375,11 @@ CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint16_4)(
     CppTypeFor<TypeCategory::Real, 16>);
 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint16_8)(
     CppTypeFor<TypeCategory::Real, 16>);
-#ifdef __SIZEOF_INT128__
+#if defined __SIZEOF_INT128__
 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint16_16)(
     CppTypeFor<TypeCategory::Real, 16>);
 #endif
+#endif
 
 // NEAREST
 // The second argument to NEAREST is the result of a comparison
@@ -332,50 +388,71 @@ CppTypeFor<TypeCategory::Real, 4> RTNAME(Nearest4)(
     CppTypeFor<TypeCategory::Real, 4>, bool positive);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(Nearest8)(
     CppTypeFor<TypeCategory::Real, 8>, bool positive);
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Nearest10)(
     CppTypeFor<TypeCategory::Real, 10>, bool positive);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Nearest16)(
     CppTypeFor<TypeCategory::Real, 16>, bool positive);
+#endif
 
 // RRSPACING
 CppTypeFor<TypeCategory::Real, 4> RTNAME(RRSpacing4)(
     CppTypeFor<TypeCategory::Real, 4>);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(RRSpacing8)(
     CppTypeFor<TypeCategory::Real, 8>);
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(RRSpacing10)(
     CppTypeFor<TypeCategory::Real, 10>);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(RRSpacing16)(
     CppTypeFor<TypeCategory::Real, 16>);
+#endif
 
 // SET_EXPONENT's I= argument can be any INTEGER kind; upcast it to 64-bit
 CppTypeFor<TypeCategory::Real, 4> RTNAME(SetExponent4)(
     CppTypeFor<TypeCategory::Real, 4>, std::int64_t);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(SetExponent8)(
     CppTypeFor<TypeCategory::Real, 8>, std::int64_t);
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(SetExponent10)(
     CppTypeFor<TypeCategory::Real, 10>, std::int64_t);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(SetExponent16)(
     CppTypeFor<TypeCategory::Real, 16>, std::int64_t);
+#endif
 
 // SCALE
 CppTypeFor<TypeCategory::Real, 4> RTNAME(Scale4)(
     CppTypeFor<TypeCategory::Real, 4>, std::int64_t);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(Scale8)(
     CppTypeFor<TypeCategory::Real, 8>, std::int64_t);
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Scale10)(
     CppTypeFor<TypeCategory::Real, 10>, std::int64_t);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Scale16)(
     CppTypeFor<TypeCategory::Real, 16>, std::int64_t);
+#endif
 
 // SPACING
 CppTypeFor<TypeCategory::Real, 4> RTNAME(Spacing4)(
     CppTypeFor<TypeCategory::Real, 4>);
 CppTypeFor<TypeCategory::Real, 8> RTNAME(Spacing8)(
     CppTypeFor<TypeCategory::Real, 8>);
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Spacing10)(
     CppTypeFor<TypeCategory::Real, 10>);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Spacing16)(
     CppTypeFor<TypeCategory::Real, 16>);
+#endif
+
 } // extern "C"
 } // namespace Fortran::runtime
 #endif // FORTRAN_RUNTIME_NUMERIC_H_

diff  --git a/flang/include/flang/Runtime/reduction.h b/flang/include/flang/Runtime/reduction.h
index b4aeaad6fe17..411b90432a1c 100644
--- a/flang/include/flang/Runtime/reduction.h
+++ b/flang/include/flang/Runtime/reduction.h
@@ -12,7 +12,10 @@
 #define FORTRAN_RUNTIME_REDUCTION_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>
 #include <cstdint>
@@ -65,10 +68,14 @@ float RTNAME(SumReal4)(const Descriptor &, const char *source, int line,
     int dim = 0, const Descriptor *mask = nullptr);
 double RTNAME(SumReal8)(const Descriptor &, const char *source, int line,
     int dim = 0, const Descriptor *mask = nullptr);
+#if LDBL_MANT_DIG == 64
 long double RTNAME(SumReal10)(const Descriptor &, const char *source, int line,
     int dim = 0, const Descriptor *mask = nullptr);
-long double RTNAME(SumReal16)(const Descriptor &, const char *source, int line,
-    int dim = 0, const Descriptor *mask = nullptr);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
+CppFloat128Type RTNAME(SumReal16)(const Descriptor &, const char *source,
+    int line, int dim = 0, const Descriptor *mask = nullptr);
+#endif
 
 void RTNAME(CppSumComplex2)(std::complex<float> &, const Descriptor &,
     const char *source, int line, int dim = 0,
@@ -117,10 +124,14 @@ float RTNAME(ProductReal4)(const Descriptor &, const char *source, int line,
     int dim = 0, const Descriptor *mask = nullptr);
 double RTNAME(ProductReal8)(const Descriptor &, const char *source, int line,
     int dim = 0, const Descriptor *mask = nullptr);
+#if LDBL_MANT_DIG == 64
 long double RTNAME(ProductReal10)(const Descriptor &, const char *source,
     int line, int dim = 0, const Descriptor *mask = nullptr);
-long double RTNAME(ProductReal16)(const Descriptor &, const char *source,
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
+CppFloat128Type RTNAME(ProductReal16)(const Descriptor &, const char *source,
     int line, int dim = 0, const Descriptor *mask = nullptr);
+#endif
 
 void RTNAME(CppProductComplex2)(std::complex<float> &, const Descriptor &,
     const char *source, int line, int dim = 0,
@@ -234,10 +245,14 @@ float RTNAME(MaxvalReal4)(const Descriptor &, const char *source, int line,
     int dim = 0, const Descriptor *mask = nullptr);
 double RTNAME(MaxvalReal8)(const Descriptor &, const char *source, int line,
     int dim = 0, const Descriptor *mask = nullptr);
+#if LDBL_MANT_DIG == 64
 long double RTNAME(MaxvalReal10)(const Descriptor &, const char *source,
     int line, int dim = 0, const Descriptor *mask = nullptr);
-long double RTNAME(MaxvalReal16)(const Descriptor &, const char *source,
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
+CppFloat128Type RTNAME(MaxvalReal16)(const Descriptor &, const char *source,
     int line, int dim = 0, const Descriptor *mask = nullptr);
+#endif
 void RTNAME(MaxvalCharacter)(Descriptor &, const Descriptor &,
     const char *source, int line, const Descriptor *mask = nullptr);
 
@@ -261,10 +276,14 @@ float RTNAME(MinvalReal4)(const Descriptor &, const char *source, int line,
     int dim = 0, const Descriptor *mask = nullptr);
 double RTNAME(MinvalReal8)(const Descriptor &, const char *source, int line,
     int dim = 0, const Descriptor *mask = nullptr);
+#if LDBL_MANT_DIG == 64
 long double RTNAME(MinvalReal10)(const Descriptor &, const char *source,
     int line, int dim = 0, const Descriptor *mask = nullptr);
-long double RTNAME(MinvalReal16)(const Descriptor &, const char *source,
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
+CppFloat128Type RTNAME(MinvalReal16)(const Descriptor &, const char *source,
     int line, int dim = 0, const Descriptor *mask = nullptr);
+#endif
 void RTNAME(MinvalCharacter)(Descriptor &, const Descriptor &,
     const char *source, int line, const Descriptor *mask = nullptr);
 
@@ -282,10 +301,13 @@ float RTNAME(Norm2_4)(const Descriptor &, const char *source, int line,
     int dim = 0, const Descriptor *mask = nullptr);
 double RTNAME(Norm2_8)(const Descriptor &, const char *source, int line,
     int dim = 0, const Descriptor *mask = nullptr);
+#if LDBL_MANT_DIG == 64
 long double RTNAME(Norm2_10)(const Descriptor &, const char *source, int line,
     int dim = 0, const Descriptor *mask = nullptr);
+#elif LDBL_MANT_DIG == 113
 long double RTNAME(Norm2_16)(const Descriptor &, const char *source, int line,
     int dim = 0, const Descriptor *mask = nullptr);
+#endif
 void RTNAME(Norm2Dim)(Descriptor &, const Descriptor &, int dim,
     const char *source, int line, const Descriptor *mask = nullptr);
 
@@ -326,10 +348,14 @@ float RTNAME(DotProductReal4)(const Descriptor &, const Descriptor &,
     const char *source = nullptr, int line = 0);
 double RTNAME(DotProductReal8)(const Descriptor &, const Descriptor &,
     const char *source = nullptr, int line = 0);
+#if LDBL_MANT_DIG == 64
 long double RTNAME(DotProductReal10)(const Descriptor &, const Descriptor &,
     const char *source = nullptr, int line = 0);
-long double RTNAME(DotProductReal16)(const Descriptor &, const Descriptor &,
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
+CppFloat128Type RTNAME(DotProductReal16)(const Descriptor &, const Descriptor &,
     const char *source = nullptr, int line = 0);
+#endif
 void RTNAME(CppDotProductComplex2)(std::complex<float> &, const Descriptor &,
     const Descriptor &, const char *source = nullptr, int line = 0);
 void RTNAME(CppDotProductComplex3)(std::complex<float> &, const Descriptor &,
@@ -338,12 +364,16 @@ void RTNAME(CppDotProductComplex4)(std::complex<float> &, const Descriptor &,
     const Descriptor &, const char *source = nullptr, int line = 0);
 void RTNAME(CppDotProductComplex8)(std::complex<double> &, const Descriptor &,
     const Descriptor &, const char *source = nullptr, int line = 0);
+#if LDBL_MANT_DIG == 64
 void RTNAME(CppDotProductComplex10)(std::complex<long double> &,
     const Descriptor &, const Descriptor &, const char *source = nullptr,
     int line = 0);
-void RTNAME(CppDotProductComplex16)(std::complex<long double> &,
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
+void RTNAME(CppDotProductComplex16)(std::complex<CppFloat128Type> &,
     const Descriptor &, const Descriptor &, const char *source = nullptr,
     int line = 0);
+#endif
 bool RTNAME(DotProductLogical)(const Descriptor &, const Descriptor &,
     const char *source = nullptr, int line = 0);
 

diff  --git a/flang/lib/Decimal/binary-to-decimal.cpp b/flang/lib/Decimal/binary-to-decimal.cpp
index c9efb3485798..7b31d02b292e 100644
--- a/flang/lib/Decimal/binary-to-decimal.cpp
+++ b/flang/lib/Decimal/binary-to-decimal.cpp
@@ -9,6 +9,7 @@
 #include "big-radix-floating-point.h"
 #include "flang/Decimal/decimal.h"
 #include <cassert>
+#include <cfloat>
 #include <string>
 
 namespace Fortran::decimal {
@@ -349,14 +350,14 @@ ConversionToDecimalResult ConvertDoubleToDecimal(char *buffer, std::size_t size,
       rounding, Fortran::decimal::BinaryFloatingPointNumber<53>(x));
 }
 
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 ConversionToDecimalResult ConvertLongDoubleToDecimal(char *buffer,
     std::size_t size, enum DecimalConversionFlags flags, int digits,
     enum FortranRounding rounding, long double x) {
   return Fortran::decimal::ConvertToDecimal(buffer, size, flags, digits,
       rounding, Fortran::decimal::BinaryFloatingPointNumber<64>(x));
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 ConversionToDecimalResult ConvertLongDoubleToDecimal(char *buffer,
     std::size_t size, enum DecimalConversionFlags flags, int digits,
     enum FortranRounding rounding, long double x) {

diff  --git a/flang/lib/Evaluate/intrinsics-library.cpp b/flang/lib/Evaluate/intrinsics-library.cpp
index 160a5894f38e..e33c9fe52591 100644
--- a/flang/lib/Evaluate/intrinsics-library.cpp
+++ b/flang/lib/Evaluate/intrinsics-library.cpp
@@ -16,6 +16,7 @@
 #include "host.h"
 #include "flang/Common/static-multimap-view.h"
 #include "flang/Evaluate/expression.h"
+#include <cfloat>
 #include <cmath>
 #include <complex>
 #include <functional>
@@ -324,8 +325,7 @@ template <> struct HostRuntimeLibrary<double, LibraryVersion::LibmExtensions> {
   static_assert(map.Verify(), "map must be sorted");
 };
 
-#if !defined(__PPC__) || defined(__LONG_DOUBLE_IEEE128__)
-// TODO: use HostTypeExists instead?
+#if LDBL_MANT_DIG == 80 || LDBL_MANT_DIG == 113
 template <>
 struct HostRuntimeLibrary<long double, LibraryVersion::LibmExtensions> {
   using F = FuncPointer<long double, long double>;
@@ -341,7 +341,7 @@ struct HostRuntimeLibrary<long double, LibraryVersion::LibmExtensions> {
   static constexpr HostRuntimeMap map{table};
   static_assert(map.Verify(), "map must be sorted");
 };
-#endif // !defined(__PPC__) || defined(__LONG_DOUBLE_IEEE128__)
+#endif // LDBL_MANT_DIG == 80 || LDBL_MANT_DIG == 113
 #endif
 
 /// Define pgmath description

diff  --git a/flang/runtime/complex-reduction.c b/flang/runtime/complex-reduction.c
index 0e40c047adee..d77e1c0a5500 100644
--- a/flang/runtime/complex-reduction.c
+++ b/flang/runtime/complex-reduction.c
@@ -8,7 +8,7 @@
  */
 
 #include "complex-reduction.h"
-#include "flang/Common/long-double.h"
+#include <float.h>
 
 struct CppComplexFloat {
   float r, i;
@@ -90,10 +90,10 @@ ADAPT_REDUCTION(SumComplex4, float_Complex_t, CppComplexFloat, CMPLXF,
     REDUCTION_ARGS, REDUCTION_ARG_NAMES)
 ADAPT_REDUCTION(SumComplex8, double_Complex_t, CppComplexDouble, CMPLX,
     REDUCTION_ARGS, REDUCTION_ARG_NAMES)
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 ADAPT_REDUCTION(SumComplex10, long_double_Complex_t, CppComplexLongDouble,
     CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES)
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 ADAPT_REDUCTION(SumComplex16, long_double_Complex_t, CppComplexLongDouble,
     CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES)
 #endif
@@ -103,10 +103,10 @@ ADAPT_REDUCTION(ProductComplex4, float_Complex_t, CppComplexFloat, CMPLXF,
     REDUCTION_ARGS, REDUCTION_ARG_NAMES)
 ADAPT_REDUCTION(ProductComplex8, double_Complex_t, CppComplexDouble, CMPLX,
     REDUCTION_ARGS, REDUCTION_ARG_NAMES)
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 ADAPT_REDUCTION(ProductComplex10, long_double_Complex_t, CppComplexLongDouble,
     CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES)
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 ADAPT_REDUCTION(ProductComplex16, long_double_Complex_t, CppComplexLongDouble,
     CMPLXL, REDUCTION_ARGS, REDUCTION_ARG_NAMES)
 #endif
@@ -116,10 +116,10 @@ ADAPT_REDUCTION(DotProductComplex4, float_Complex_t, CppComplexFloat, CMPLXF,
     DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)
 ADAPT_REDUCTION(DotProductComplex8, double_Complex_t, CppComplexDouble, CMPLX,
     DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 ADAPT_REDUCTION(DotProductComplex10, long_double_Complex_t,
     CppComplexLongDouble, CMPLXL, DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 ADAPT_REDUCTION(DotProductComplex16, long_double_Complex_t,
     CppComplexLongDouble, CMPLXL, DOT_PRODUCT_ARGS, DOT_PRODUCT_ARG_NAMES)
 #endif

diff  --git a/flang/runtime/dot-product.cpp b/flang/runtime/dot-product.cpp
index 4b2873222859..2f9debbfccaa 100644
--- a/flang/runtime/dot-product.cpp
+++ b/flang/runtime/dot-product.cpp
@@ -6,11 +6,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "float.h"
 #include "terminator.h"
 #include "tools.h"
 #include "flang/Runtime/cpp-type.h"
 #include "flang/Runtime/descriptor.h"
 #include "flang/Runtime/reduction.h"
+#include <cfloat>
 #include <cinttypes>
 
 namespace Fortran::runtime {
@@ -178,13 +180,14 @@ double RTNAME(DotProductReal8)(
     const Descriptor &x, const Descriptor &y, const char *source, int line) {
   return DotProduct<TypeCategory::Real, 8>{}(x, y, source, line);
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 long double RTNAME(DotProductReal10)(
     const Descriptor &x, const Descriptor &y, const char *source, int line) {
   return DotProduct<TypeCategory::Real, 10>{}(x, y, source, line);
 }
-#elif LONG_DOUBLE == 128
-long double RTNAME(DotProductReal16)(
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
+CppTypeFor<TypeCategory::Real, 16> RTNAME(DotProductReal16)(
     const Descriptor &x, const Descriptor &y, const char *source, int line) {
   return DotProduct<TypeCategory::Real, 16>{}(x, y, source, line);
 }
@@ -200,13 +203,13 @@ void RTNAME(CppDotProductComplex8)(std::complex<double> &result,
     const Descriptor &x, const Descriptor &y, const char *source, int line) {
   result = DotProduct<TypeCategory::Complex, 8>{}(x, y, source, line);
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 void RTNAME(CppDotProductComplex10)(std::complex<long double> &result,
     const Descriptor &x, const Descriptor &y, const char *source, int line) {
   result = DotProduct<TypeCategory::Complex, 10>{}(x, y, source, line);
 }
-#elif LONG_DOUBLE == 128
-void RTNAME(CppDotProductComplex16)(std::complex<long double> &result,
+#elif LDBL_MANT_DIG == 113
+void RTNAME(CppDotProductComplex16)(std::complex<CppFloat128Type> &result,
     const Descriptor &x, const Descriptor &y, const char *source, int line) {
   result = DotProduct<TypeCategory::Complex, 16>{}(x, y, source, line);
 }

diff  --git a/flang/runtime/extrema.cpp b/flang/runtime/extrema.cpp
index a2634d71ffda..709a032911d4 100644
--- a/flang/runtime/extrema.cpp
+++ b/flang/runtime/extrema.cpp
@@ -11,10 +11,11 @@
 // NORM2 using common infrastructure.
 
 #include "reduction-templates.h"
-#include "flang/Common/long-double.h"
 #include "flang/Runtime/character.h"
+#include "flang/Runtime/float128.h"
 #include "flang/Runtime/reduction.h"
 #include <algorithm>
+#include <cfloat>
 #include <cinttypes>
 #include <cmath>
 #include <optional>
@@ -511,13 +512,14 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(MaxvalReal8)(const Descriptor &x,
   return TotalNumericMaxOrMin<TypeCategory::Real, 8, true>(
       x, source, line, dim, mask, "MAXVAL");
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(MaxvalReal10)(const Descriptor &x,
     const char *source, int line, int dim, const Descriptor *mask) {
   return TotalNumericMaxOrMin<TypeCategory::Real, 10, true>(
       x, source, line, dim, mask, "MAXVAL");
 }
-#elif LONG_DOUBLE == 128
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(MaxvalReal16)(const Descriptor &x,
     const char *source, int line, int dim, const Descriptor *mask) {
   return TotalNumericMaxOrMin<TypeCategory::Real, 16, true>(
@@ -570,13 +572,14 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(MinvalReal8)(const Descriptor &x,
   return TotalNumericMaxOrMin<TypeCategory::Real, 8, false>(
       x, source, line, dim, mask, "MINVAL");
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(MinvalReal10)(const Descriptor &x,
     const char *source, int line, int dim, const Descriptor *mask) {
   return TotalNumericMaxOrMin<TypeCategory::Real, 10, false>(
       x, source, line, dim, mask, "MINVAL");
 }
-#elif LONG_DOUBLE == 128
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(MinvalReal16)(const Descriptor &x,
     const char *source, int line, int dim, const Descriptor *mask) {
   return TotalNumericMaxOrMin<TypeCategory::Real, 16, false>(
@@ -612,8 +615,19 @@ void RTNAME(MinvalDim)(Descriptor &result, const Descriptor &x, int dim,
 template <int KIND> class Norm2Accumulator {
 public:
   using Type = CppTypeFor<TypeCategory::Real, KIND>;
-  // Use at least double precision for accumulators
-  using AccumType = CppTypeFor<TypeCategory::Real, std::max(KIND, 8)>;
+  // Use at least double precision for accumulators.
+  // Don't use __float128, it doesn't work with abs() or sqrt() yet.
+  static constexpr int largestLDKind {
+#if LDBL_MANT_DIG == 113
+    16
+#elif LDBL_MANT_DIG == 64
+    10
+#else
+    8
+#endif
+  };
+  using AccumType = CppTypeFor<TypeCategory::Real,
+      std::max(std::min(largestLDKind, KIND), 8)>;
   explicit Norm2Accumulator(const Descriptor &array) : array_{array} {}
   void Reinitialize() { max_ = sum_ = 0; }
   template <typename A> void GetResult(A *p, int /*zeroBasedDim*/ = -1) const {
@@ -621,7 +635,7 @@ template <int KIND> class Norm2Accumulator {
     *p = static_cast<Type>(max_ * std::sqrt(1 + sum_));
   }
   bool Accumulate(Type x) {
-    auto absX{AccumType{std::abs(x)}};
+    auto absX{std::abs(static_cast<AccumType>(x))};
     if (!max_) {
       max_ = x;
     } else if (absX > max_) {
@@ -666,13 +680,14 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(Norm2_8)(const Descriptor &x,
   return GetTotalReduction<TypeCategory::Real, 8>(
       x, source, line, dim, mask, Norm2Accumulator<8>{x}, "NORM2");
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Norm2_10)(const Descriptor &x,
     const char *source, int line, int dim, const Descriptor *mask) {
   return GetTotalReduction<TypeCategory::Real, 10>(
       x, source, line, dim, mask, Norm2Accumulator<10>{x}, "NORM2");
 }
-#elif LONG_DOUBLE == 128
+#endif
+#if LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Norm2_16)(const Descriptor &x,
     const char *source, int line, int dim, const Descriptor *mask) {
   return GetTotalReduction<TypeCategory::Real, 16>(

diff  --git a/flang/runtime/findloc.cpp b/flang/runtime/findloc.cpp
index 6a3aaef88207..339e0c75f05f 100644
--- a/flang/runtime/findloc.cpp
+++ b/flang/runtime/findloc.cpp
@@ -10,7 +10,6 @@
 // integer kinds.
 
 #include "reduction-templates.h"
-#include "flang/Common/long-double.h"
 #include "flang/Runtime/character.h"
 #include "flang/Runtime/reduction.h"
 #include <cinttypes>

diff  --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp
index 4ffb282a87c7..391837bc4752 100644
--- a/flang/runtime/numeric.cpp
+++ b/flang/runtime/numeric.cpp
@@ -6,9 +6,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "terminator.h"
 #include "flang/Runtime/numeric.h"
-#include "flang/Common/long-double.h"
+#include "terminator.h"
+#include "flang/Runtime/float128.h"
+#include <cfloat>
 #include <climits>
 #include <cmath>
 #include <limits>
@@ -175,7 +176,7 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint8_8)(
     CppTypeFor<TypeCategory::Real, 8> x) {
   return Aint<CppTypeFor<TypeCategory::Real, 8>>(x);
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint4_10)(
     CppTypeFor<TypeCategory::Real, 4> x) {
   return Aint<CppTypeFor<TypeCategory::Real, 10>>(x);
@@ -196,7 +197,7 @@ CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint10_10)(
     CppTypeFor<TypeCategory::Real, 10> x) {
   return Aint<CppTypeFor<TypeCategory::Real, 10>>(x);
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint4_16)(
     CppTypeFor<TypeCategory::Real, 4> x) {
   return Aint<CppTypeFor<TypeCategory::Real, 16>>(x);
@@ -235,7 +236,7 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint8_8)(
     CppTypeFor<TypeCategory::Real, 8> x) {
   return Anint<CppTypeFor<TypeCategory::Real, 8>>(x);
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint4_10)(
     CppTypeFor<TypeCategory::Real, 4> x) {
   return Anint<CppTypeFor<TypeCategory::Real, 10>>(x);
@@ -256,7 +257,7 @@ CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint10_10)(
     CppTypeFor<TypeCategory::Real, 10> x) {
   return Anint<CppTypeFor<TypeCategory::Real, 10>>(x);
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint4_16)(
     CppTypeFor<TypeCategory::Real, 4> x) {
   return Anint<CppTypeFor<TypeCategory::Real, 16>>(x);
@@ -323,7 +324,7 @@ CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling8_16)(
   return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
 }
 #endif
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling10_1)(
     CppTypeFor<TypeCategory::Real, 10> x) {
   return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
@@ -346,7 +347,7 @@ CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling10_16)(
   return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
 }
 #endif
-#else
+#elif LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling16_1)(
     CppTypeFor<TypeCategory::Real, 16> x) {
   return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
@@ -387,7 +388,7 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent8_8)(
     CppTypeFor<TypeCategory::Real, 8> x) {
   return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent10_4)(
     CppTypeFor<TypeCategory::Real, 10> x) {
   return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
@@ -396,7 +397,7 @@ CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent10_8)(
     CppTypeFor<TypeCategory::Real, 10> x) {
   return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent16_4)(
     CppTypeFor<TypeCategory::Real, 16> x) {
   return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
@@ -451,7 +452,7 @@ CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor8_16)(
   return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
 }
 #endif
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor10_1)(
     CppTypeFor<TypeCategory::Real, 10> x) {
   return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
@@ -474,7 +475,7 @@ CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor10_16)(
   return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
 }
 #endif
-#else
+#elif LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor16_1)(
     CppTypeFor<TypeCategory::Real, 16> x) {
   return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
@@ -507,12 +508,12 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(Fraction8)(
     CppTypeFor<TypeCategory::Real, 8> x) {
   return Fraction(x);
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Fraction10)(
     CppTypeFor<TypeCategory::Real, 10> x) {
   return Fraction(x);
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Fraction16)(
     CppTypeFor<TypeCategory::Real, 16> x) {
   return Fraction(x);
@@ -525,11 +526,11 @@ bool RTNAME(IsFinite4)(CppTypeFor<TypeCategory::Real, 4> x) {
 bool RTNAME(IsFinite8)(CppTypeFor<TypeCategory::Real, 8> x) {
   return std::isfinite(x);
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 bool RTNAME(IsFinite10)(CppTypeFor<TypeCategory::Real, 10> x) {
   return std::isfinite(x);
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 bool RTNAME(IsFinite16)(CppTypeFor<TypeCategory::Real, 16> x) {
   return std::isfinite(x);
 }
@@ -541,11 +542,11 @@ bool RTNAME(IsNaN4)(CppTypeFor<TypeCategory::Real, 4> x) {
 bool RTNAME(IsNaN8)(CppTypeFor<TypeCategory::Real, 8> x) {
   return std::isnan(x);
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 bool RTNAME(IsNaN10)(CppTypeFor<TypeCategory::Real, 10> x) {
   return std::isnan(x);
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 bool RTNAME(IsNaN16)(CppTypeFor<TypeCategory::Real, 16> x) {
   return std::isnan(x);
 }
@@ -593,13 +594,13 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
     const char *sourceFile, int sourceLine) {
   return RealMod<false>(x, p, sourceFile, sourceLine);
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
     CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p,
     const char *sourceFile, int sourceLine) {
   return RealMod<false>(x, p, sourceFile, sourceLine);
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
     CppTypeFor<TypeCategory::Real, 16> x, CppTypeFor<TypeCategory::Real, 16> p,
     const char *sourceFile, int sourceLine) {
@@ -649,13 +650,13 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
     const char *sourceFile, int sourceLine) {
   return RealMod<true>(x, p, sourceFile, sourceLine);
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
     CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p,
     const char *sourceFile, int sourceLine) {
   return RealMod<true>(x, p, sourceFile, sourceLine);
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
     CppTypeFor<TypeCategory::Real, 16> x, CppTypeFor<TypeCategory::Real, 16> p,
     const char *sourceFile, int sourceLine) {
@@ -671,12 +672,12 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(Nearest8)(
     CppTypeFor<TypeCategory::Real, 8> x, bool positive) {
   return Nearest<53>(x, positive);
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Nearest10)(
     CppTypeFor<TypeCategory::Real, 10> x, bool positive) {
   return Nearest<64>(x, positive);
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Nearest16)(
     CppTypeFor<TypeCategory::Real, 16> x, bool positive) {
   return Nearest<113>(x, positive);
@@ -727,7 +728,7 @@ CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint8_16)(
   return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
 }
 #endif
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint10_1)(
     CppTypeFor<TypeCategory::Real, 10> x) {
   return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
@@ -750,7 +751,7 @@ CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint10_16)(
   return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
 }
 #endif
-#else
+#elif LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint16_1)(
     CppTypeFor<TypeCategory::Real, 16> x) {
   return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
@@ -783,12 +784,12 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(RRSpacing8)(
     CppTypeFor<TypeCategory::Real, 8> x) {
   return RRSpacing<53>(x);
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(RRSpacing10)(
     CppTypeFor<TypeCategory::Real, 10> x) {
   return RRSpacing<64>(x);
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Real, 16> RTNAME(RRSpacing16)(
     CppTypeFor<TypeCategory::Real, 16> x) {
   return RRSpacing<113>(x);
@@ -803,12 +804,12 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(SetExponent8)(
     CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
   return SetExponent(x, p);
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(SetExponent10)(
     CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
   return SetExponent(x, p);
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Real, 16> RTNAME(SetExponent16)(
     CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) {
   return SetExponent(x, p);
@@ -823,12 +824,12 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(Scale8)(
     CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
   return Scale(x, p);
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Scale10)(
     CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
   return Scale(x, p);
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Scale16)(
     CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) {
   return Scale(x, p);
@@ -843,12 +844,12 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(Spacing8)(
     CppTypeFor<TypeCategory::Real, 8> x) {
   return Spacing<53>(x);
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(Spacing10)(
     CppTypeFor<TypeCategory::Real, 10> x) {
   return Spacing<64>(x);
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Real, 16> RTNAME(Spacing16)(
     CppTypeFor<TypeCategory::Real, 16> x) {
   return Spacing<113>(x);

diff  --git a/flang/runtime/product.cpp b/flang/runtime/product.cpp
index d245e0da8a45..072e2fed2c28 100644
--- a/flang/runtime/product.cpp
+++ b/flang/runtime/product.cpp
@@ -9,8 +9,9 @@
 // Implements PRODUCT for all required operand types and shapes.
 
 #include "reduction-templates.h"
-#include "flang/Common/long-double.h"
+#include "flang/Runtime/float128.h"
 #include "flang/Runtime/reduction.h"
+#include <cfloat>
 #include <cinttypes>
 #include <complex>
 
@@ -105,14 +106,14 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(ProductReal8)(const Descriptor &x,
       NonComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 8>>{x},
       "PRODUCT");
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(ProductReal10)(const Descriptor &x,
     const char *source, int line, int dim, const Descriptor *mask) {
   return GetTotalReduction<TypeCategory::Real, 10>(x, source, line, dim, mask,
       NonComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 10>>{x},
       "PRODUCT");
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 CppTypeFor<TypeCategory::Real, 16> RTNAME(ProductReal16)(const Descriptor &x,
     const char *source, int line, int dim, const Descriptor *mask) {
   return GetTotalReduction<TypeCategory::Real, 16>(x, source, line, dim, mask,
@@ -135,7 +136,7 @@ void RTNAME(CppProductComplex8)(CppTypeFor<TypeCategory::Complex, 8> &result,
       mask, ComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 8>>{x},
       "PRODUCT");
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 void RTNAME(CppProductComplex10)(CppTypeFor<TypeCategory::Complex, 10> &result,
     const Descriptor &x, const char *source, int line, int dim,
     const Descriptor *mask) {
@@ -143,7 +144,7 @@ void RTNAME(CppProductComplex10)(CppTypeFor<TypeCategory::Complex, 10> &result,
       mask, ComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 10>>{x},
       "PRODUCT");
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 void RTNAME(CppProductComplex16)(CppTypeFor<TypeCategory::Complex, 16> &result,
     const Descriptor &x, const char *source, int line, int dim,
     const Descriptor *mask) {

diff  --git a/flang/runtime/random.cpp b/flang/runtime/random.cpp
index 56138db7615d..0f6a6a2be623 100644
--- a/flang/runtime/random.cpp
+++ b/flang/runtime/random.cpp
@@ -15,6 +15,7 @@
 #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>
@@ -113,23 +114,28 @@ void RTNAME(RandomNumber)(
   // TODO: REAL (2 & 3)
   case 4:
     Generate<CppTypeFor<TypeCategory::Real, 4>, 24>(harvest);
-    break;
+    return;
   case 8:
     Generate<CppTypeFor<TypeCategory::Real, 8>, 53>(harvest);
-    break;
-#if LONG_DOUBLE == 80
+    return;
   case 10:
-    Generate<CppTypeFor<TypeCategory::Real, 10>, 64>(harvest);
+    if constexpr (HasCppTypeFor<TypeCategory::Real, 10>) {
+#if LDBL_MANT_DIG == 64
+      Generate<CppTypeFor<TypeCategory::Real, 10>, 64>(harvest);
+      return;
+#endif
+    }
     break;
-#elif LONG_DOUBLE == 128
   case 16:
-    Generate<CppTypeFor<TypeCategory::Real, 16>, 113>(harvest);
-    break;
+    if constexpr (HasCppTypeFor<TypeCategory::Real, 16>) {
+#if LDBL_MANT_DIG == 113
+      Generate<CppTypeFor<TypeCategory::Real, 16>, 113>(harvest);
+      return;
 #endif
-  default:
-    terminator.Crash(
-        "not yet implemented: RANDOM_NUMBER(): REAL kind %d", kind);
+    }
+    break;
   }
+  terminator.Crash("not yet implemented: RANDOM_NUMBER(): REAL kind %d", kind);
 }
 
 void RTNAME(RandomSeedSize)(

diff  --git a/flang/runtime/sum.cpp b/flang/runtime/sum.cpp
index 6bdb599eea75..ba0e75d017a2 100644
--- a/flang/runtime/sum.cpp
+++ b/flang/runtime/sum.cpp
@@ -13,8 +13,9 @@
 // (basically the same as manual "double-double").
 
 #include "reduction-templates.h"
-#include "flang/Common/long-double.h"
+#include "flang/Runtime/float128.h"
 #include "flang/Runtime/reduction.h"
+#include <cfloat>
 #include <cinttypes>
 #include <complex>
 
@@ -129,13 +130,14 @@ CppTypeFor<TypeCategory::Real, 8> RTNAME(SumReal8)(const Descriptor &x,
   return GetTotalReduction<TypeCategory::Real, 8>(
       x, source, line, dim, mask, RealSumAccumulator<double>{x}, "SUM");
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 CppTypeFor<TypeCategory::Real, 10> RTNAME(SumReal10)(const Descriptor &x,
     const char *source, int line, int dim, const Descriptor *mask) {
   return GetTotalReduction<TypeCategory::Real, 10>(
       x, source, line, dim, mask, RealSumAccumulator<long double>{x}, "SUM");
 }
-#elif LONG_DOUBLE == 128
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
 CppTypeFor<TypeCategory::Real, 16> RTNAME(SumReal16)(const Descriptor &x,
     const char *source, int line, int dim, const Descriptor *mask) {
   return GetTotalReduction<TypeCategory::Real, 16>(
@@ -155,14 +157,14 @@ void RTNAME(CppSumComplex8)(CppTypeFor<TypeCategory::Complex, 8> &result,
   result = GetTotalReduction<TypeCategory::Complex, 8>(
       x, source, line, dim, mask, ComplexSumAccumulator<double>{x}, "SUM");
 }
-#if LONG_DOUBLE == 80
+#if LDBL_MANT_DIG == 64
 void RTNAME(CppSumComplex10)(CppTypeFor<TypeCategory::Complex, 10> &result,
     const Descriptor &x, const char *source, int line, int dim,
     const Descriptor *mask) {
   result = GetTotalReduction<TypeCategory::Complex, 10>(
       x, source, line, dim, mask, ComplexSumAccumulator<long double>{x}, "SUM");
 }
-#elif LONG_DOUBLE == 128
+#elif LDBL_MANT_DIG == 113
 void RTNAME(CppSumComplex16)(CppTypeFor<TypeCategory::Complex, 16> &result,
     const Descriptor &x, const char *source, int line, int dim,
     const Descriptor *mask) {

diff  --git a/flang/runtime/tools.h b/flang/runtime/tools.h
index dd35917b58e9..a9c942d53eea 100644
--- a/flang/runtime/tools.h
+++ b/flang/runtime/tools.h
@@ -10,7 +10,6 @@
 #define FORTRAN_RUNTIME_TOOLS_H_
 
 #include "terminator.h"
-#include "flang/Common/long-double.h"
 #include "flang/Runtime/cpp-type.h"
 #include "flang/Runtime/descriptor.h"
 #include "flang/Runtime/memory.h"
@@ -148,16 +147,18 @@ inline RESULT ApplyType(
       return FUNC<TypeCategory::Real, 4>{}(std::forward<A>(x)...);
     case 8:
       return FUNC<TypeCategory::Real, 8>{}(std::forward<A>(x)...);
-#if LONG_DOUBLE == 80
     case 10:
-      return FUNC<TypeCategory::Real, 10>{}(std::forward<A>(x)...);
-#elif LONG_DOUBLE == 128
+      if constexpr (HasCppTypeFor<TypeCategory::Real, 10>) {
+        return FUNC<TypeCategory::Real, 10>{}(std::forward<A>(x)...);
+      }
+      break;
     case 16:
-      return FUNC<TypeCategory::Real, 16>{}(std::forward<A>(x)...);
-#endif
-    default:
-      terminator.Crash("not yet implemented: REAL(KIND=%d)", kind);
+      if constexpr (HasCppTypeFor<TypeCategory::Real, 16>) {
+        return FUNC<TypeCategory::Real, 16>{}(std::forward<A>(x)...);
+      }
+      break;
     }
+    terminator.Crash("not yet implemented: REAL(KIND=%d)", kind);
   case TypeCategory::Complex:
     switch (kind) {
 #if 0 // TODO: COMPLEX(2 & 3)
@@ -170,16 +171,18 @@ inline RESULT ApplyType(
       return FUNC<TypeCategory::Complex, 4>{}(std::forward<A>(x)...);
     case 8:
       return FUNC<TypeCategory::Complex, 8>{}(std::forward<A>(x)...);
-#if LONG_DOUBLE == 80
     case 10:
-      return FUNC<TypeCategory::Complex, 10>{}(std::forward<A>(x)...);
-#elif LONG_DOUBLE == 128
+      if constexpr (HasCppTypeFor<TypeCategory::Real, 10>) {
+        return FUNC<TypeCategory::Complex, 10>{}(std::forward<A>(x)...);
+      }
+      break;
     case 16:
-      return FUNC<TypeCategory::Complex, 16>{}(std::forward<A>(x)...);
-#endif
-    default:
-      terminator.Crash("not yet implemented: COMPLEX(KIND=%d)", kind);
+      if constexpr (HasCppTypeFor<TypeCategory::Real, 16>) {
+        return FUNC<TypeCategory::Complex, 16>{}(std::forward<A>(x)...);
+      }
+      break;
     }
+    terminator.Crash("not yet implemented: COMPLEX(KIND=%d)", kind);
   case TypeCategory::Character:
     switch (kind) {
     case 1:
@@ -246,16 +249,18 @@ inline RESULT ApplyFloatingPointKind(
     return FUNC<4>{}(std::forward<A>(x)...);
   case 8:
     return FUNC<8>{}(std::forward<A>(x)...);
-#if LONG_DOUBLE == 80
   case 10:
-    return FUNC<10>{}(std::forward<A>(x)...);
-#elif LONG_DOUBLE == 128
+    if constexpr (HasCppTypeFor<TypeCategory::Real, 10>) {
+      return FUNC<10>{}(std::forward<A>(x)...);
+    }
+    break;
   case 16:
-    return FUNC<16>{}(std::forward<A>(x)...);
-#endif
-  default:
-    terminator.Crash("not yet implemented: REAL/COMPLEX(KIND=%d)", kind);
+    if constexpr (HasCppTypeFor<TypeCategory::Real, 16>) {
+      return FUNC<16>{}(std::forward<A>(x)...);
+    }
+    break;
   }
+  terminator.Crash("not yet implemented: REAL/COMPLEX(KIND=%d)", kind);
 }
 
 template <template <int KIND> class FUNC, typename RESULT, typename... A>


        


More information about the flang-commits mailing list