[flang-commits] [flang] 7d7633b - [Flang][OpenMP][OpenACC] Error for loop with no control
Kiran Chandramohan via flang-commits
flang-commits at lists.llvm.org
Mon Feb 27 08:55:39 PST 2023
Author: Kiran Chandramohan
Date: 2023-02-27T16:52:50Z
New Revision: 7d7633bdf489eff66a56984a4cf3d6a21cf36f2b
URL: https://github.com/llvm/llvm-project/commit/7d7633bdf489eff66a56984a4cf3d6a21cf36f2b
DIFF: https://github.com/llvm/llvm-project/commit/7d7633bdf489eff66a56984a4cf3d6a21cf36f2b.diff
LOG: [Flang][OpenMP][OpenACC] Error for loop with no control
Issue error if a DO construct associated with a loop does not have
loop control. Currently, it is issued only for the loop immediately
following the loop construct. This patch extends it to cases like
collapse where there is more than one loop associated. It also fixes
a crash since the existing code always expects loop control.
This is covered in OpenMP 4.5 standard, Section 2.7.1.
"The do-loop cannot be a DO WHILE or a DO loop without loop control."
OpenACC 3.3 covers this indirectly in Section 2.9.1.
The trip count for all loops associated with the collapse clause must
be computable and invariant in all the loops".
Reviewed By: clementval
Differential Revision: https://reviews.llvm.org/D144290
Added:
flang/test/Semantics/OpenMP/omp-do-collapse1.f90
Modified:
flang/lib/Semantics/resolve-directives.cpp
flang/test/Semantics/OpenACC/acc-loop.f90
flang/test/Semantics/OpenMP/do-collapse.f90
Removed:
################################################################################
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 6c876ec69db60..f16f53c578b22 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -97,7 +97,7 @@ template <typename T> class DirectiveAttributeVisitor {
dataSharingAttributeObjects_.clear();
}
bool HasDataSharingAttributeObject(const Symbol &);
- const parser::Name &GetLoopIndex(const parser::DoConstruct &);
+ const parser::Name *GetLoopIndex(const parser::DoConstruct &);
const parser::DoConstruct *GetDoConstructIf(
const parser::ExecutionPartConstruct &);
Symbol *DeclarePrivateAccessEntity(
@@ -560,10 +560,19 @@ bool DirectiveAttributeVisitor<T>::HasDataSharingAttributeObject(
}
template <typename T>
-const parser::Name &DirectiveAttributeVisitor<T>::GetLoopIndex(
+const parser::Name *DirectiveAttributeVisitor<T>::GetLoopIndex(
const parser::DoConstruct &x) {
using Bounds = parser::LoopControl::Bounds;
- return std::get<Bounds>(x.GetLoopControl()->u).name.thing;
+ if (x.GetLoopControl()) {
+ return &std::get<Bounds>(x.GetLoopControl()->u).name.thing;
+ } else {
+ context_
+ .Say(std::get<parser::Statement<parser::NonLabelDoStmt>>(x.t).source,
+ "Loop control is not present in the DO LOOP"_err_en_US)
+ .Attach(GetContext().directiveSource,
+ "associated with the enclosing LOOP construct"_en_US);
+ return nullptr;
+ }
}
template <typename T>
@@ -893,11 +902,13 @@ void AccAttributeVisitor::PrivatizeAssociatedLoopIndex(
const auto &outer{std::get<std::optional<parser::DoConstruct>>(x.t)};
for (const parser::DoConstruct *loop{&*outer}; loop && level > 0; --level) {
// go through all the nested do-loops and resolve index variables
- const parser::Name &iv{GetLoopIndex(*loop)};
- if (auto *symbol{ResolveAcc(iv, ivDSA, currScope())}) {
- symbol->set(Symbol::Flag::AccPreDetermined);
- iv.symbol = symbol; // adjust the symbol within region
- AddToContextObjectWithDSA(*symbol, ivDSA);
+ const parser::Name *iv{GetLoopIndex(*loop)};
+ if (iv) {
+ if (auto *symbol{ResolveAcc(*iv, ivDSA, currScope())}) {
+ symbol->set(Symbol::Flag::AccPreDetermined);
+ iv->symbol = symbol; // adjust the symbol within region
+ AddToContextObjectWithDSA(*symbol, ivDSA);
+ }
}
const auto &block{std::get<parser::Block>(loop->t)};
@@ -1278,20 +1289,21 @@ bool OmpAttributeVisitor::Pre(const parser::DoConstruct &x) {
// TODO:[OpenMP 5.1] DO CONCURRENT indices are private
if (x.IsDoNormal()) {
if (!dirContext_.empty() && GetContext().withinConstruct) {
- if (const auto &iv{GetLoopIndex(x)}; iv.symbol) {
- if (!iv.symbol->test(Symbol::Flag::OmpPreDetermined)) {
- ResolveSeqLoopIndexInParallelOrTaskConstruct(iv);
+ const parser::Name *iv{GetLoopIndex(x)};
+ if (iv && iv->symbol) {
+ if (!iv->symbol->test(Symbol::Flag::OmpPreDetermined)) {
+ ResolveSeqLoopIndexInParallelOrTaskConstruct(*iv);
} else {
// TODO: conflict checks with explicitly determined DSA
}
ordCollapseLevel--;
if (ordCollapseLevel) {
- if (const auto *details{iv.symbol->detailsIf<HostAssocDetails>()}) {
+ if (const auto *details{iv->symbol->detailsIf<HostAssocDetails>()}) {
const Symbol *tpSymbol = &details->symbol();
if (tpSymbol->test(Symbol::Flag::OmpThreadprivate)) {
- context_.Say(iv.source,
+ context_.Say(iv->source,
"Loop iteration variable %s is not allowed in THREADPRIVATE."_err_en_US,
- iv.ToString());
+ iv->ToString());
}
}
}
@@ -1362,16 +1374,18 @@ void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel(
const auto &outer{std::get<std::optional<parser::DoConstruct>>(x.t)};
for (const parser::DoConstruct *loop{&*outer}; loop && level > 0; --level) {
// go through all the nested do-loops and resolve index variables
- const parser::Name &iv{GetLoopIndex(*loop)};
- if (auto *symbol{ResolveOmp(iv, ivDSA, currScope())}) {
- symbol->set(Symbol::Flag::OmpPreDetermined);
- iv.symbol = symbol; // adjust the symbol within region
- AddToContextObjectWithDSA(*symbol, ivDSA);
- }
+ const parser::Name *iv{GetLoopIndex(*loop)};
+ if (iv) {
+ if (auto *symbol{ResolveOmp(*iv, ivDSA, currScope())}) {
+ symbol->set(Symbol::Flag::OmpPreDetermined);
+ iv->symbol = symbol; // adjust the symbol within region
+ AddToContextObjectWithDSA(*symbol, ivDSA);
+ }
- const auto &block{std::get<parser::Block>(loop->t)};
- const auto it{block.begin()};
- loop = it != block.end() ? GetDoConstructIf(*it) : nullptr;
+ const auto &block{std::get<parser::Block>(loop->t)};
+ const auto it{block.begin()};
+ loop = it != block.end() ? GetDoConstructIf(*it) : nullptr;
+ }
}
CheckAssocLoopLevel(level, GetAssociatedClause());
}
diff --git a/flang/test/Semantics/OpenACC/acc-loop.f90 b/flang/test/Semantics/OpenACC/acc-loop.f90
index 75e09958909cd..371569b861872 100644
--- a/flang/test/Semantics/OpenACC/acc-loop.f90
+++ b/flang/test/Semantics/OpenACC/acc-loop.f90
@@ -250,4 +250,11 @@ program openacc_loop_validity
end do
!$acc end parallel
+ !$acc loop collapse(2)
+ do i = 1, N
+ !ERROR: Loop control is not present in the DO LOOP
+ do
+ a(i) = 3.14
+ end do
+ end do
end program openacc_loop_validity
diff --git a/flang/test/Semantics/OpenMP/do-collapse.f90 b/flang/test/Semantics/OpenMP/do-collapse.f90
index bc5412b3f9037..145b7b75d28df 100644
--- a/flang/test/Semantics/OpenMP/do-collapse.f90
+++ b/flang/test/Semantics/OpenMP/do-collapse.f90
@@ -22,5 +22,12 @@ program omp_doCollapse
!$omp end do
end do
end do
+
+ !$omp parallel do collapse(2)
+ do i = 1, 3
+ !ERROR: Loop control is not present in the DO LOOP
+ do
+ end do
+ end do
end program omp_doCollapse
diff --git a/flang/test/Semantics/OpenMP/omp-do-collapse1.f90 b/flang/test/Semantics/OpenMP/omp-do-collapse1.f90
new file mode 100644
index 0000000000000..81f87d8239e53
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/omp-do-collapse1.f90
@@ -0,0 +1,14 @@
+! RUN: not %flang_fc1 -fdebug-unparse-with-symbols -fopenmp %s 2>&1 | FileCheck %s
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+program omp_doCollapse
+ integer:: i
+ !$omp parallel do collapse(2)
+ do i = 1, 3
+ !CHECK: Loop control is not present in the DO LOOP
+ !CHECK: associated with the enclosing LOOP construct
+ do
+ end do
+ end do
+end program omp_doCollapse
+
More information about the flang-commits
mailing list