[flang-commits] [flang] c4360b4 - [flang] Fix folding of ac-implied-do indices in structure c'tors
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Thu Dec 9 18:03:14 PST 2021
Author: Peter Klausler
Date: 2021-12-09T18:03:04-08:00
New Revision: c4360b4547168f7c0356b49d90646666d5b778da
URL: https://github.com/llvm/llvm-project/commit/c4360b4547168f7c0356b49d90646666d5b778da
DIFF: https://github.com/llvm/llvm-project/commit/c4360b4547168f7c0356b49d90646666d5b778da.diff
LOG: [flang] Fix folding of ac-implied-do indices in structure c'tors
Array constructors with implied DO loops that oversee structure
constructors were being prematurely folded into invalid constants
containing symbolic references to the ac-implied-do indices,
because they are indeed "constant expressions" as that term is
used in the Fortran standard and implemented as IsConstantExpr().
What's actually needed in structure constructor folding is a
test for actual constant values, which is what results from
folding them later with repetition in the context of folding
an ac-implied-do.
Differential Revision: https://reviews.llvm.org/D115470
Added:
flang/test/Evaluate/folding30.f90
Modified:
flang/lib/Evaluate/fold-implementation.h
flang/lib/Evaluate/fold.cpp
Removed:
################################################################################
diff --git a/flang/lib/Evaluate/fold-implementation.h b/flang/lib/Evaluate/fold-implementation.h
index 4f885413b3964..4b1ea9be7ff5a 100644
--- a/flang/lib/Evaluate/fold-implementation.h
+++ b/flang/lib/Evaluate/fold-implementation.h
@@ -1094,7 +1094,7 @@ Expr<ImpliedDoIndex::Result> FoldOperation(FoldingContext &, ImpliedDoIndex &&);
// Array constructor folding
template <typename T> class ArrayConstructorFolder {
public:
- explicit ArrayConstructorFolder(const FoldingContext &c) : context_{c} {}
+ explicit ArrayConstructorFolder(FoldingContext &c) : context_{c} {}
Expr<T> FoldArray(ArrayConstructor<T> &&array) {
// Calls FoldArray(const ArrayConstructorValues<T> &) below
@@ -1118,8 +1118,8 @@ template <typename T> class ArrayConstructorFolder {
}
private:
- bool FoldArray(const common::CopyableIndirection<Expr<T>> &expr) {
- Expr<T> folded{Fold(context_, common::Clone(expr.value()))};
+ bool FoldArray(const Expr<T> &expr) {
+ Expr<T> folded{Fold(context_, common::Clone(expr))};
if (const auto *c{UnwrapConstantValue<T>(folded)}) {
// Copy elements in Fortran array element order
if (!c->empty()) {
@@ -1133,6 +1133,9 @@ template <typename T> class ArrayConstructorFolder {
return false;
}
}
+ bool FoldArray(const common::CopyableIndirection<Expr<T>> &expr) {
+ return FoldArray(expr.value());
+ }
bool FoldArray(const ImpliedDo<T> &iDo) {
Expr<SubscriptInteger> lower{
Fold(context_, Expr<SubscriptInteger>{iDo.lower()})};
@@ -1172,7 +1175,7 @@ template <typename T> class ArrayConstructorFolder {
return true;
}
- FoldingContext context_;
+ FoldingContext &context_;
std::vector<Scalar<T>> elements_;
};
diff --git a/flang/lib/Evaluate/fold.cpp b/flang/lib/Evaluate/fold.cpp
index 40556e30ebaf2..c6397e46c48e0 100644
--- a/flang/lib/Evaluate/fold.cpp
+++ b/flang/lib/Evaluate/fold.cpp
@@ -65,29 +65,32 @@ std::optional<Constant<SubscriptInteger>> GetConstantSubscript(
Expr<SomeDerived> FoldOperation(
FoldingContext &context, StructureConstructor &&structure) {
StructureConstructor ctor{structure.derivedTypeSpec()};
- bool constantExtents{true};
+ bool isConstant{true};
for (auto &&[symbol, value] : std::move(structure)) {
auto expr{Fold(context, std::move(value.value()))};
- if (!IsPointer(symbol)) {
- bool ok{false};
+ if (IsPointer(symbol)) {
+ if (IsProcedure(symbol)) {
+ isConstant &= IsInitialProcedureTarget(expr);
+ } else {
+ isConstant &= IsInitialDataTarget(expr);
+ }
+ } else {
+ isConstant &= IsActuallyConstant(expr);
if (auto valueShape{GetConstantExtents(context, expr)}) {
if (auto componentShape{GetConstantExtents(context, symbol)}) {
if (GetRank(*componentShape) > 0 && GetRank(*valueShape) == 0) {
expr = ScalarConstantExpander{std::move(*componentShape)}.Expand(
std::move(expr));
- ok = expr.Rank() > 0;
+ isConstant &= expr.Rank() > 0;
} else {
- ok = *valueShape == *componentShape;
+ isConstant &= *valueShape == *componentShape;
}
}
}
- if (!ok) {
- constantExtents = false;
- }
}
- ctor.Add(symbol, Fold(context, std::move(expr)));
+ ctor.Add(symbol, std::move(expr));
}
- if (constantExtents && IsConstantExpr(ctor)) {
+ if (isConstant) {
return Expr<SomeDerived>{Constant<SomeDerived>{std::move(ctor)}};
} else {
return Expr<SomeDerived>{std::move(ctor)};
diff --git a/flang/test/Evaluate/folding30.f90 b/flang/test/Evaluate/folding30.f90
new file mode 100644
index 0000000000000..23da29bbfaf98
--- /dev/null
+++ b/flang/test/Evaluate/folding30.f90
@@ -0,0 +1,11 @@
+! RUN: %python %S/test_folding.py %s %flang_fc1
+! Tests folding of structure constructors in array constructors
+module m
+ type :: t1
+ integer :: n
+ end type
+ type(t1), parameter :: xs1(*) = [(t1(j),j=1,5,2)]
+ type(t1), parameter :: xs2(*) = [(t1(j),j=5,1,-2)]
+ logical, parameter :: test_1 = all(xs1%n == [1, 3, 5])
+ logical, parameter :: test_2 = all(xs2%n == [5, 3, 1])
+end module
More information about the flang-commits
mailing list