Skip to content

[flang][OpenMP] Don't allow DO CONCURRENT inside of a loop nest #144506

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 32 additions & 6 deletions flang/lib/Semantics/resolve-directives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "flang/Semantics/openmp-modifiers.h"
#include "flang/Semantics/symbol.h"
#include "flang/Semantics/tools.h"
#include "llvm/Frontend/OpenMP/OMP.h.inc"
#include "llvm/Support/Debug.h"
#include <list>
#include <map>
Expand Down Expand Up @@ -737,9 +738,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
}

const parser::OmpClause *associatedClause{nullptr};
void SetAssociatedClause(const parser::OmpClause &c) {
associatedClause = &c;
}
void SetAssociatedClause(const parser::OmpClause *c) { associatedClause = c; }
const parser::OmpClause *GetAssociatedClause() { return associatedClause; }

private:
Expand Down Expand Up @@ -1916,12 +1915,17 @@ std::int64_t OmpAttributeVisitor::GetAssociatedLoopLevelFromClauses(
}

if (orderedLevel && (!collapseLevel || orderedLevel >= collapseLevel)) {
SetAssociatedClause(*ordClause);
SetAssociatedClause(ordClause);
return orderedLevel;
} else if (!orderedLevel && collapseLevel) {
SetAssociatedClause(*collClause);
SetAssociatedClause(collClause);
return collapseLevel;
} // orderedLevel < collapseLevel is an error handled in structural checks
} else {
SetAssociatedClause(nullptr);
}
// orderedLevel < collapseLevel is an error handled in structural
// checks

return 1; // default is outermost loop
}

Expand Down Expand Up @@ -1949,9 +1953,31 @@ void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel(
ivDSA = Symbol::Flag::OmpLastPrivate;
}

bool isLoopConstruct{
GetContext().directive == llvm::omp::Directive::OMPD_loop};
const parser::OmpClause *clause{GetAssociatedClause()};
bool hasCollapseClause{
clause ? (clause->Id() == llvm::omp::OMPC_collapse) : false};

const auto &outer{std::get<std::optional<parser::DoConstruct>>(x.t)};
if (outer.has_value()) {
for (const parser::DoConstruct *loop{&*outer}; loop && level > 0; --level) {
if (loop->IsDoConcurrent()) {
// DO CONCURRENT is explicitly allowed for the LOOP construct so long as
// there isn't a COLLAPSE clause
if (isLoopConstruct) {
if (hasCollapseClause) {
// hasCollapseClause implies clause != nullptr
context_.Say(clause->source,
"DO CONCURRENT loops cannot be used with the COLLAPSE clause."_err_en_US);
}
} else {
auto &stmt =
std::get<parser::Statement<parser::NonLabelDoStmt>>(loop->t);
context_.Say(stmt.source,
"DO CONCURRENT loops cannot form part of a loop nest."_err_en_US);
}
}
// go through all the nested do-loops and resolve index variables
const parser::Name *iv{GetLoopIndex(*loop)};
if (iv) {
Expand Down
10 changes: 0 additions & 10 deletions flang/test/Lower/OpenMP/Todo/omp-doconcurrent.f90

This file was deleted.

39 changes: 39 additions & 0 deletions flang/test/Semantics/OpenMP/do-concurrent-collapse.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
!RUN: %python %S/../test_errors.py %s %flang -fopenmp

integer :: i, j
!$omp parallel do collapse(2)
do i = 1, 1
! ERROR: DO CONCURRENT loops cannot form part of a loop nest.
do concurrent (j = 1:2)
print *, j
end do
end do

!$omp parallel do
do i = 1, 1
! This should not lead to an error because it is not part of a loop nest:
do concurrent (j = 1:2)
print *, j
end do
end do

!$omp parallel do
! ERROR: DO CONCURRENT loops cannot form part of a loop nest.
do concurrent (j = 1:2)
print *, j
end do

!$omp loop
! Do concurrent is explicitly allowed inside of omp loop
do concurrent (j = 1:2)
print *, j
end do

! ERROR: DO CONCURRENT loops cannot be used with the COLLAPSE clause.
!$omp loop collapse(2)
do i = 1, 1
do concurrent (j = 1:2)
print *, j
end do
end do
end