diff options
author | Peixin Qiao <qiaopeixin@huawei.com> | 2022-07-26 00:33:27 +0800 |
---|---|---|
committer | Peixin Qiao <qiaopeixin@huawei.com> | 2022-07-26 00:33:27 +0800 |
commit | f532c07211091ec399566a05043479774589f66f (patch) | |
tree | e37402847104a0d60a4cf9c7ccd90e79df0da828 /flang/runtime/numeric.cpp | |
parent | 640c0ad0d5807140c4c31fc60cd3b261fc03bfbd (diff) | |
download | llvm-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.cpp | 33 |
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, |