[flang-commits] [flang] [flang][runtime] Add alternate SELECTED_(INT|REAL)_KIND APIs (PR #105887)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Fri Aug 23 13:16:13 PDT 2024


https://github.com/klausler created https://github.com/llvm/llvm-project/pull/105887

Add extended versions of SELECTED_INT_KIND and SELECTED_REAL_KIND runtime APIs that permit lowering to pass along a bit mask of acceptable kinds.  The existing APIs call the new ones with a full bit mask.  If lowering transitions to always use the new APIs the old ones can then be deleted.

>From b932703d64fdbd2cf05a2e9bcfbd89970e6eee94 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Fri, 23 Aug 2024 13:12:55 -0700
Subject: [PATCH] [flang][runtime] Add alternate SELECTED_(INT|REAL)_KIND APIs

Add extended versions of SELECTED_INT_KIND and SELECTED_REAL_KIND
runtime APIs that permit lowering to pass along a bit mask of
acceptable kinds.  The existing APIs call the new ones with a
full bit mask.  If lowering transitions to always use the new APIs
the old ones can then be deleted.
---
 flang/include/flang/Runtime/numeric.h |  4 ++
 flang/runtime/numeric.cpp             | 94 +++++++++++++++------------
 2 files changed, 55 insertions(+), 43 deletions(-)

diff --git a/flang/include/flang/Runtime/numeric.h b/flang/include/flang/Runtime/numeric.h
index e051e864316630..6e1979790e3c61 100644
--- a/flang/include/flang/Runtime/numeric.h
+++ b/flang/include/flang/Runtime/numeric.h
@@ -377,6 +377,8 @@ CppTypeFor<TypeCategory::Integer, 4> RTDECL(SelectedCharKind)(
 // SELECTED_INT_KIND
 CppTypeFor<TypeCategory::Integer, 4> RTDECL(SelectedIntKind)(
     const char *, int, void *, int);
+CppTypeFor<TypeCategory::Integer, 4> RTDECL(SelectedIntKindMasked)(
+    const char *, int, void *, int, int);
 
 // SELECTED_LOGICAL_KIND
 CppTypeFor<TypeCategory::Integer, 4> RTDECL(SelectedLogicalKind)(
@@ -385,6 +387,8 @@ CppTypeFor<TypeCategory::Integer, 4> RTDECL(SelectedLogicalKind)(
 // SELECTED_REAL_KIND
 CppTypeFor<TypeCategory::Integer, 4> RTDECL(SelectedRealKind)(
     const char *, int, void *, int, void *, int, void *, int);
+CppTypeFor<TypeCategory::Integer, 4> RTDECL(SelectedRealKindMasked)(
+    const char *, int, void *, int, void *, int, void *, int, int);
 
 // SPACING
 CppTypeFor<TypeCategory::Real, 4> RTDECL(Spacing4)(
diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp
index 40bacf07157a27..b5e0851a16cd1e 100644
--- a/flang/runtime/numeric.cpp
+++ b/flang/runtime/numeric.cpp
@@ -95,20 +95,22 @@ template <typename T> inline RT_API_ATTRS T Scale(T x, std::int64_t p) {
 }
 
 // SELECTED_INT_KIND (16.9.169)
-template <typename T>
-inline RT_API_ATTRS CppTypeFor<TypeCategory::Integer, 4> SelectedIntKind(T x) {
-  if (x <= 2) {
+template <typename X, typename M>
+inline RT_API_ATTRS CppTypeFor<TypeCategory::Integer, 4> SelectedIntKind(
+    X x, M mask) {
+#if !defined __SIZEOF_INT128__ || defined FLANG_RUNTIME_NO_INTEGER_16
+  mask &= ~(1 << 16);
+#endif
+  if (x <= 2 && (mask & (1 << 1))) {
     return 1;
-  } else if (x <= 4) {
+  } else if (x <= 4 && (mask & (1 << 2))) {
     return 2;
-  } else if (x <= 9) {
+  } else if (x <= 9 && (mask & (1 << 4))) {
     return 4;
-  } else if (x <= 18) {
+  } else if (x <= 18 && (mask & (1 << 8))) {
     return 8;
-#if defined __SIZEOF_INT128__ && !defined FLANG_RUNTIME_NO_INTEGER_16
-  } else if (x <= 38) {
+  } else if (x <= 38 && (mask & (1 << 16))) {
     return 16;
-#endif
   }
   return -1;
 }
@@ -130,60 +132,52 @@ inline RT_API_ATTRS CppTypeFor<TypeCategory::Integer, 4> SelectedLogicalKind(
 }
 
 // SELECTED_REAL_KIND (16.9.170)
-template <typename P, typename R, typename D>
+template <typename P, typename R, typename D, typename M>
 inline RT_API_ATTRS CppTypeFor<TypeCategory::Integer, 4> SelectedRealKind(
-    P p, R r, D d) {
+    P p, R r, D d, M mask) {
   if (d != 2) {
     return -5;
   }
-
-#ifndef FLANG_RUNTIME_NO_REAL_2
-  constexpr bool hasReal2{true};
-#else
-  constexpr bool hasReal2{false};
+#ifdef FLANG_RUNTIME_NO_REAL_2
+  mask &= ~(1 << 2);
 #endif
-#ifndef FLANG_RUNTIME_NO_REAL_3
-  constexpr bool hasReal3{true};
-#else
-  constexpr bool hasReal3{false};
+#ifdef FLANG_RUNTIME_NO_REAL_3
+  mask &= ~(1 << 3);
 #endif
-#if defined LDBL_MANT_DIG == 64 && !defined FLANG_RUNTIME_NO_REAL_10
-  constexpr bool hasReal10{true};
-#else
-  constexpr bool hasReal10{false};
+#if LDBL_MANT_DIG < 64 || defined FLANG_RUNTIME_NO_REAL_10
+  mask &= ~(1 << 10);
 #endif
-#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && \
-    !defined FLANG_RUNTIME_NO_REAL_16
-  constexpr bool hasReal16{true};
-#else
-  constexpr bool hasReal16{false};
+#if LDBL_MANT_DIG < 64 || defined FLANG_RUNTIME_NO_REAL_16
+  mask &= ~(1 << 16);
 #endif
 
   int error{0};
   int kind{0};
-  if (hasReal2 && p <= 3) {
+  if (p <= 3 && (mask & (1 << 2))) {
     kind = 2;
-  } else if (p <= 6) {
+  } else if (p <= 6 && (mask & (1 << 4))) {
     kind = 4;
-  } else if (p <= 15) {
+  } else if (p <= 15 && (mask & (1 << 8))) {
     kind = 8;
-  } else if (hasReal10 && p <= 18) {
+  } else if (p <= 18 && (mask & (1 << 10))) {
     kind = 10;
-  } else if (hasReal16 && p <= 33) {
+  } else if (p <= 33 && (mask & (1 << 16))) {
     kind = 16;
   } else {
     error -= 1;
   }
 
-  if (r <= 4) {
-    kind = kind < 2 ? (hasReal2 ? 2 : 4) : kind;
-  } else if (r <= 37) {
-    kind = kind < 3 ? (hasReal3 && p != 3 ? 3 : 4) : kind;
-  } else if (r <= 307) {
+  if (r <= 4 && (mask & (1 << 2))) {
+    kind = kind < 2 ? 2 : kind;
+  } else if (r <= 37 && p != 3 && (mask & (1 << 3))) {
+    kind = kind < 3 ? 3 : kind;
+  } else if (r <= 37 && (mask & (1 << 4))) {
+    kind = kind < 4 ? 4 : kind;
+  } else if (r <= 307 && (mask & (1 << 8))) {
     kind = kind < 8 ? 8 : kind;
-  } else if (hasReal10 && r <= 4931) {
+  } else if (r <= 4931 && (mask & (1 << 10))) {
     kind = kind < 10 ? 10 : kind;
-  } else if (hasReal16 && r <= 4931) {
+  } else if (r <= 4931 && (mask & (1 << 16))) {
     kind = kind < 16 ? 16 : kind;
   } else {
     error -= 2;
@@ -790,6 +784,12 @@ CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedCharKind)(
 // SELECTED_INT_KIND
 CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedIntKind)(
     const char *source, int line, void *x, int xKind) {
+  return RTNAME(SelectedIntKindMasked)(source, line, x, xKind,
+      (1 << 1) | (1 << 2) | (1 << 4) | (1 << 8) | (1 << 16));
+}
+
+CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedIntKindMasked)(
+    const char *source, int line, void *x, int xKind, int mask) {
 #ifdef __SIZEOF_INT128__
   CppTypeFor<TypeCategory::Integer, 16> r =
       GetIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>(
@@ -798,7 +798,7 @@ CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedIntKind)(
   std::int64_t r = GetIntArgValue<std::int64_t>(
       source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 8);
 #endif
-  return SelectedIntKind(r);
+  return SelectedIntKind(r, mask);
 }
 
 // SELECTED_LOGICAL_KIND
@@ -819,6 +819,14 @@ CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedLogicalKind)(
 CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedRealKind)(const char *source,
     int line, void *precision, int pKind, void *range, int rKind, void *radix,
     int dKind) {
+  return RTNAME(SelectedRealKindMasked)(source, line, precision, pKind, range,
+      rKind, radix, dKind,
+      (1 << 2) | (1 << 3) | (1 << 4) | (1 << 8) | (1 << 10) | (1 << 16));
+}
+
+CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedRealKindMasked)(
+    const char *source, int line, void *precision, int pKind, void *range,
+    int rKind, void *radix, int dKind, int mask) {
 #ifdef __SIZEOF_INT128__
   CppTypeFor<TypeCategory::Integer, 16> p =
       GetIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>(
@@ -837,7 +845,7 @@ CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedRealKind)(const char *source,
   std::int64_t d = GetIntArgValue<std::int64_t>(
       source, line, radix, dKind, /*defaultValue*/ 2, /*resKind*/ 8);
 #endif
-  return SelectedRealKind(p, r, d);
+  return SelectedRealKind(p, r, d, mask);
 }
 
 CppTypeFor<TypeCategory::Real, 4> RTDEF(Spacing4)(



More information about the flang-commits mailing list