diff --git a/flang/include/flang/Evaluate/target.h b/flang/include/flang/Evaluate/target.h index 80deac5952301..10033d02a5409 100644 --- a/flang/include/flang/Evaluate/target.h +++ b/flang/include/flang/Evaluate/target.h @@ -70,6 +70,7 @@ class TargetCharacteristics { bool IsTypeEnabled(common::TypeCategory category, std::int64_t kind) const; int SelectedIntKind(std::int64_t precision = 0) const; + int SelectedLogicalKind(std::int64_t bits = 1) const; int SelectedRealKind(std::int64_t precision = 0, std::int64_t range = 0, std::int64_t radix = 2) const; diff --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp index 53659d2c36d7c..2c67880771c62 100644 --- a/flang/lib/Evaluate/fold-integer.cpp +++ b/flang/lib/Evaluate/fold-integer.cpp @@ -1151,6 +1151,10 @@ Expr> FoldIntrinsicFunction( if (auto p{ToInt64(args[0])}) { return Expr{context.targetCharacteristics().SelectedIntKind(*p)}; } + } else if (name == "selected_logical_kind") { + if (auto p{ToInt64(args[0])}) { + return Expr{context.targetCharacteristics().SelectedLogicalKind(*p)}; + } } else if (name == "selected_real_kind" || name == "__builtin_ieee_selected_real_kind") { if (auto p{GetInt64ArgOr(args[0], 0)}) { diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp index 67c68dd9d7941..0f3404999962f 100644 --- a/flang/lib/Evaluate/intrinsics.cpp +++ b/flang/lib/Evaluate/intrinsics.cpp @@ -778,6 +778,8 @@ static const IntrinsicInterface genericIntrinsicFunction[]{ Rank::scalar, IntrinsicClass::transformationalFunction}, {"selected_int_kind", {{"r", AnyInt, Rank::scalar}}, DefaultInt, Rank::scalar, IntrinsicClass::transformationalFunction}, + {"selected_logical_kind", {{"bits", AnyInt, Rank::scalar}}, DefaultInt, + Rank::scalar, IntrinsicClass::transformationalFunction}, {"selected_real_kind", {{"p", AnyInt, Rank::scalar}, {"r", AnyInt, Rank::scalar, Optionality::optional}, diff --git a/flang/lib/Evaluate/target.cpp b/flang/lib/Evaluate/target.cpp index 98925b2be617e..1e2cf6b0d298d 100644 --- a/flang/lib/Evaluate/target.cpp +++ b/flang/lib/Evaluate/target.cpp @@ -143,6 +143,36 @@ int TargetCharacteristics::SelectedIntKind(std::int64_t precision) const { } } +// SELECTED_LOGICAL_KIND() -- F'2023 16.9.182 +class SelectedLogicalKindVisitor { +public: + SelectedLogicalKindVisitor( + const TargetCharacteristics &targetCharacteristics, std::int64_t bits) + : targetCharacteristics_{targetCharacteristics}, bits_{bits} {} + using Result = std::optional; + using Types = LogicalTypes; + template Result Test() const { + if (Scalar::bits >= bits_ && + targetCharacteristics_.IsTypeEnabled(T::category, T::kind)) { + return T::kind; + } else { + return std::nullopt; + } + } + +private: + const TargetCharacteristics &targetCharacteristics_; + std::int64_t bits_; +}; + +int TargetCharacteristics::SelectedLogicalKind(std::int64_t bits) const { + if (auto kind{common::SearchTypes(SelectedLogicalKindVisitor{*this, bits})}) { + return *kind; + } else { + return -1; + } +} + // SELECTED_REAL_KIND() -- F'2018 16.9.170 class SelectedRealKindVisitor { public: diff --git a/flang/test/Evaluate/fold-selected_logical_kind.f90 b/flang/test/Evaluate/fold-selected_logical_kind.f90 new file mode 100644 index 0000000000000..f941f22c120f9 --- /dev/null +++ b/flang/test/Evaluate/fold-selected_logical_kind.f90 @@ -0,0 +1,17 @@ +! RUN: %python %S/test_folding.py %s %flang_fc1 +module m + logical, parameter :: test_0 = selected_logical_kind( 0) == 1 + logical, parameter :: test_1 = selected_logical_kind( 1) == 1 + logical, parameter :: test_7 = selected_logical_kind( 7) == 1 + logical, parameter :: test_8 = selected_logical_kind( 8) == 1 + logical, parameter :: test_9 = selected_logical_kind( 9) == 2 + logical, parameter :: test_15 = selected_logical_kind(15) == 2 + logical, parameter :: test_16 = selected_logical_kind(16) == 2 + logical, parameter :: test_17 = selected_logical_kind(17) == 4 + logical, parameter :: test_31 = selected_logical_kind(31) == 4 + logical, parameter :: test_32 = selected_logical_kind(32) == 4 + logical, parameter :: test_33 = selected_logical_kind(33) == 8 + logical, parameter :: test_63 = selected_logical_kind(63) == 8 + logical, parameter :: test_64 = selected_logical_kind(64) == 8 + logical, parameter :: test_65 = selected_logical_kind(65) == -1 +end