Skip to content

Commit 5dbfe27

Browse files
committed
Allow do concurrent with LOOP construct
There's some obscure language in OpenMP 6.0: > If the collapsed loop is a DO CONCURRENT loop, neither the > data-sharing attribute clauses nor the collapse clause may be specified. From the surrounding context, I think "collapsed loop" just means the loop that the LOOP construct applies to. So I will interpret this to mean that DO CONCURRENT can only be used with the LOOP construct if it does not contain the COLLAPSE clause. This also fixes a bug where the associated clause was never cleared after it was set.
1 parent eed0acb commit 5dbfe27

File tree

2 files changed

+50
-10
lines changed

2 files changed

+50
-10
lines changed

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "flang/Semantics/openmp-modifiers.h"
2424
#include "flang/Semantics/symbol.h"
2525
#include "flang/Semantics/tools.h"
26+
#include "llvm/Frontend/OpenMP/OMP.h.inc"
2627
#include "llvm/Support/Debug.h"
2728
#include <list>
2829
#include <map>
@@ -737,9 +738,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
737738
}
738739

739740
const parser::OmpClause *associatedClause{nullptr};
740-
void SetAssociatedClause(const parser::OmpClause &c) {
741-
associatedClause = &c;
742-
}
741+
void SetAssociatedClause(const parser::OmpClause *c) { associatedClause = c; }
743742
const parser::OmpClause *GetAssociatedClause() { return associatedClause; }
744743

745744
private:
@@ -1916,12 +1915,17 @@ std::int64_t OmpAttributeVisitor::GetAssociatedLoopLevelFromClauses(
19161915
}
19171916

19181917
if (orderedLevel && (!collapseLevel || orderedLevel >= collapseLevel)) {
1919-
SetAssociatedClause(*ordClause);
1918+
SetAssociatedClause(ordClause);
19201919
return orderedLevel;
19211920
} else if (!orderedLevel && collapseLevel) {
1922-
SetAssociatedClause(*collClause);
1921+
SetAssociatedClause(collClause);
19231922
return collapseLevel;
1924-
} // orderedLevel < collapseLevel is an error handled in structural checks
1923+
} else {
1924+
SetAssociatedClause(nullptr);
1925+
}
1926+
// orderedLevel < collapseLevel is an error handled in structural
1927+
// checks
1928+
19251929
return 1; // default is outermost loop
19261930
}
19271931

@@ -1949,14 +1953,30 @@ void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel(
19491953
ivDSA = Symbol::Flag::OmpLastPrivate;
19501954
}
19511955

1956+
bool isLoopConstruct{
1957+
GetContext().directive == llvm::omp::Directive::OMPD_loop};
1958+
const parser::OmpClause *clause{GetAssociatedClause()};
1959+
bool hasCollapseClause{
1960+
clause ? (clause->Id() == llvm::omp::OMPC_collapse) : false};
1961+
19521962
const auto &outer{std::get<std::optional<parser::DoConstruct>>(x.t)};
19531963
if (outer.has_value()) {
19541964
for (const parser::DoConstruct *loop{&*outer}; loop && level > 0; --level) {
19551965
if (loop->IsDoConcurrent()) {
1956-
auto &stmt =
1957-
std::get<parser::Statement<parser::NonLabelDoStmt>>(loop->t);
1958-
context_.Say(stmt.source,
1959-
"DO CONCURRENT loops cannot form part of a loop nest."_err_en_US);
1966+
// DO CONCURRENT is explicitly allowed for the LOOP construct so long as
1967+
// there isn't a COLLAPSE clause
1968+
if (isLoopConstruct) {
1969+
if (hasCollapseClause) {
1970+
// hasCollapseClause implies clause != nullptr
1971+
context_.Say(clause->source,
1972+
"DO CONCURRENT loops cannot be used with the COLLAPSE clause."_err_en_US);
1973+
}
1974+
} else {
1975+
auto &stmt =
1976+
std::get<parser::Statement<parser::NonLabelDoStmt>>(loop->t);
1977+
context_.Say(stmt.source,
1978+
"DO CONCURRENT loops cannot form part of a loop nest."_err_en_US);
1979+
}
19601980
}
19611981
// go through all the nested do-loops and resolve index variables
19621982
const parser::Name *iv{GetLoopIndex(*loop)};

flang/test/Semantics/OpenMP/do-concurrent-collapse.f90

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,24 @@
1616
print *, j
1717
end do
1818
end do
19+
20+
!$omp parallel do
21+
! ERROR: DO CONCURRENT loops cannot form part of a loop nest.
22+
do concurrent (j = 1:2)
23+
print *, j
24+
end do
25+
26+
!$omp loop
27+
! Do concurrent is explicitly allowed inside of omp loop
28+
do concurrent (j = 1:2)
29+
print *, j
30+
end do
31+
32+
! ERROR: DO CONCURRENT loops cannot be used with the COLLAPSE clause.
33+
!$omp loop collapse(2)
34+
do i = 1, 1
35+
do concurrent (j = 1:2)
36+
print *, j
37+
end do
38+
end do
1939
end

0 commit comments

Comments
 (0)