[flang-commits] [flang] [flang] Fold character array constructor with unknown length (PR #123983)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Wed Jan 22 10:45:41 PST 2025
https://github.com/klausler created https://github.com/llvm/llvm-project/pull/123983
When a character array constructor does not have an explicit type with a constant length, the compiler can still fold it if all of its elements are constants. These array constructors will have been wrapped up in the internal %SET_LENGTH operation, which will determine the final length of the folded value, so use the maximum length of the constant elements as the length of the folded array constructor.
Fixes https://github.com/llvm/llvm-project/issues/123766.
>From ac28188023c2fee715d7b0bc58e448a041c1a70a Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Wed, 22 Jan 2025 10:40:17 -0800
Subject: [PATCH] [flang] Fold character array constructor with unknown length
When a character array constructor does not have an explicit type
with a constant length, the compiler can still fold it if all of
its elements are constants. These array constructors will have
been wrapped up in the internal %SET_LENGTH operation, which
will determine the final length of the folded value, so use the
maximum length of the constant elements as the length of the folded
array constructor.
Fixes https://github.com/llvm/llvm-project/issues/123766.
---
flang/lib/Evaluate/fold-implementation.h | 22 ++++++++++++++++------
flang/test/Evaluate/bug123766.f90 | 5 +++++
2 files changed, 21 insertions(+), 6 deletions(-)
create mode 100644 flang/test/Evaluate/bug123766.f90
diff --git a/flang/lib/Evaluate/fold-implementation.h b/flang/lib/Evaluate/fold-implementation.h
index 31d043f490fd85..56b36504c1dffd 100644
--- a/flang/lib/Evaluate/fold-implementation.h
+++ b/flang/lib/Evaluate/fold-implementation.h
@@ -1263,6 +1263,12 @@ template <typename T> class ArrayConstructorFolder {
explicit ArrayConstructorFolder(FoldingContext &c) : context_{c} {}
Expr<T> FoldArray(ArrayConstructor<T> &&array) {
+ if constexpr (T::category == TypeCategory::Character) {
+ if (const auto *len{array.LEN()}) {
+ charLength_ = ToInt64(Fold(context_, common::Clone(*len)));
+ knownCharLength_ = charLength_.has_value();
+ }
+ }
// Calls FoldArray(const ArrayConstructorValues<T> &) below
if (FoldArray(array)) {
auto n{static_cast<ConstantSubscript>(elements_.size())};
@@ -1270,12 +1276,9 @@ template <typename T> class ArrayConstructorFolder {
return Expr<T>{Constant<T>{array.GetType().GetDerivedTypeSpec(),
std::move(elements_), ConstantSubscripts{n}}};
} else if constexpr (T::category == TypeCategory::Character) {
- if (const auto *len{array.LEN()}) {
- auto length{Fold(context_, common::Clone(*len))};
- if (std::optional<ConstantSubscript> lengthValue{ToInt64(length)}) {
- return Expr<T>{Constant<T>{
- *lengthValue, std::move(elements_), ConstantSubscripts{n}}};
- }
+ if (charLength_) {
+ return Expr<T>{Constant<T>{
+ *charLength_, std::move(elements_), ConstantSubscripts{n}}};
}
} else {
return Expr<T>{
@@ -1296,6 +1299,11 @@ template <typename T> class ArrayConstructorFolder {
elements_.emplace_back(c->At(index));
} while (c->IncrementSubscripts(index));
}
+ if constexpr (T::category == TypeCategory::Character) {
+ if (!knownCharLength_) {
+ charLength_ = std::max(c->LEN(), charLength_.value_or(-1));
+ }
+ }
return true;
} else {
return false;
@@ -1345,6 +1353,8 @@ template <typename T> class ArrayConstructorFolder {
FoldingContext &context_;
std::vector<Scalar<T>> elements_;
+ std::optional<ConstantSubscript> charLength_;
+ bool knownCharLength_{false};
};
template <typename T>
diff --git a/flang/test/Evaluate/bug123766.f90 b/flang/test/Evaluate/bug123766.f90
new file mode 100644
index 00000000000000..b58989e6c26d85
--- /dev/null
+++ b/flang/test/Evaluate/bug123766.f90
@@ -0,0 +1,5 @@
+! RUN: %python %S/test_folding.py %s %flang_fc1
+character(10), parameter :: a = '0123456789'
+character(3), parameter :: arr(3) = [(a(1:i), i=1,3)]
+logical, parameter :: test1 = all(arr == ["0", "01", "012"])
+end
More information about the flang-commits
mailing list