aboutsummaryrefslogtreecommitdiff
path: root/flang/runtime/numeric.cpp
diff options
context:
space:
mode:
authorPeixin Qiao <qiaopeixin@huawei.com>2022-07-26 00:33:27 +0800
committerPeixin Qiao <qiaopeixin@huawei.com>2022-07-26 00:33:27 +0800
commitf532c07211091ec399566a05043479774589f66f (patch)
treee37402847104a0d60a4cf9c7ccd90e79df0da828 /flang/runtime/numeric.cpp
parent640c0ad0d5807140c4c31fc60cd3b261fc03bfbd (diff)
downloadllvm-f532c07211091ec399566a05043479774589f66f.zip
llvm-f532c07211091ec399566a05043479774589f66f.tar.gz
llvm-f532c07211091ec399566a05043479774589f66f.tar.bz2
[flang] Support intrinsic `selected_int_kind` for variables
As Fortran 2018 16.9.169, the argument of selected_int_kind is integer scalar, and result is default integer scalar. The constant expression in this intrinsic has been supported by folding the constant expression. This supports lowering and runtime for variables in this intrinsic. Reviewed By: Jean Perier Differential Revision: https://reviews.llvm.org/D129959
Diffstat (limited to 'flang/runtime/numeric.cpp')
-rw-r--r--flang/runtime/numeric.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp
index 958ea86..0a37fc9 100644
--- a/flang/runtime/numeric.cpp
+++ b/flang/runtime/numeric.cpp
@@ -142,6 +142,25 @@ template <typename T> inline T Scale(T x, std::int64_t p) {
return std::ldexp(x, p); // x*2**p
}
+// SELECTED_INT_KIND (16.9.169)
+template <typename T>
+inline CppTypeFor<TypeCategory::Integer, 4> SelectedIntKind(T x) {
+ if (x <= 2) {
+ return 1;
+ } else if (x <= 4) {
+ return 2;
+ } else if (x <= 9) {
+ return 4;
+ } else if (x <= 18) {
+ return 8;
+#ifdef __SIZEOF_INT128__
+ } else if (x <= 38) {
+ return 16;
+#endif
+ }
+ return -1;
+}
+
// SELECTED_REAL_KIND (16.9.170)
template <typename P, typename R, typename D>
inline CppTypeFor<TypeCategory::Integer, 4> SelectedRealKind(P p, R r, D d) {
@@ -794,6 +813,20 @@ CppTypeFor<TypeCategory::Real, 16> RTNAME(Scale16)(
}
#endif
+// SELECTED_INT_KIND
+CppTypeFor<TypeCategory::Integer, 4> RTNAME(SelectedIntKind)(
+ const char *source, int line, void *x, int xKind) {
+#ifdef __SIZEOF_INT128__
+ CppTypeFor<TypeCategory::Integer, 16> r =
+ getIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>(
+ source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 16);
+#else
+ std::int64_t r = getIntArgValue<std::int64_t>(
+ source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 8);
+#endif
+ return SelectedIntKind(r);
+}
+
// SELECTED_REAL_KIND
CppTypeFor<TypeCategory::Integer, 4> RTNAME(SelectedRealKind)(
const char *source, int line, void *precision, int pKind, void *range,