Skip to content

Commit 17b9d0e

Browse files
harishch4kbluck
authored andcommitted
[Flang][OpenMP]Make Do concurrent indices private (llvm#93785)
Fixes: llvm#85538
1 parent 86905c2 commit 17b9d0e

File tree

2 files changed

+55
-18
lines changed

2 files changed

+55
-18
lines changed

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,26 +1708,46 @@ void OmpAttributeVisitor::ResolveSeqLoopIndexInParallelOrTaskConstruct(
17081708
// Use of DO CONCURRENT inside OpenMP construct is unspecified behavior
17091709
// till OpenMP-5.0 standard.
17101710
// In above both cases we skip the privatization of iteration variables.
1711+
// [OpenMP 5.1] DO CONCURRENT indices are private
17111712
bool OmpAttributeVisitor::Pre(const parser::DoConstruct &x) {
1712-
// TODO:[OpenMP 5.1] DO CONCURRENT indices are private
1713-
if (x.IsDoNormal()) {
1714-
if (!dirContext_.empty() && GetContext().withinConstruct) {
1713+
if (!dirContext_.empty() && GetContext().withinConstruct) {
1714+
llvm::SmallVector<const parser::Name *> ivs;
1715+
if (x.IsDoNormal()) {
17151716
const parser::Name *iv{GetLoopIndex(x)};
1716-
if (iv && iv->symbol) {
1717-
if (!iv->symbol->test(Symbol::Flag::OmpPreDetermined)) {
1718-
ResolveSeqLoopIndexInParallelOrTaskConstruct(*iv);
1719-
} else {
1720-
// TODO: conflict checks with explicitly determined DSA
1721-
}
1722-
ordCollapseLevel--;
1723-
if (ordCollapseLevel) {
1724-
if (const auto *details{iv->symbol->detailsIf<HostAssocDetails>()}) {
1725-
const Symbol *tpSymbol = &details->symbol();
1726-
if (tpSymbol->test(Symbol::Flag::OmpThreadprivate)) {
1727-
context_.Say(iv->source,
1728-
"Loop iteration variable %s is not allowed in THREADPRIVATE."_err_en_US,
1729-
iv->ToString());
1730-
}
1717+
if (iv && iv->symbol)
1718+
ivs.push_back(iv);
1719+
} else if (x.IsDoConcurrent()) {
1720+
const Fortran::parser::LoopControl *loopControl = &*x.GetLoopControl();
1721+
const Fortran::parser::LoopControl::Concurrent &concurrent =
1722+
std::get<Fortran::parser::LoopControl::Concurrent>(loopControl->u);
1723+
const Fortran::parser::ConcurrentHeader &concurrentHeader =
1724+
std::get<Fortran::parser::ConcurrentHeader>(concurrent.t);
1725+
const std::list<Fortran::parser::ConcurrentControl> &controls =
1726+
std::get<std::list<Fortran::parser::ConcurrentControl>>(
1727+
concurrentHeader.t);
1728+
for (const auto &control : controls) {
1729+
const parser::Name *iv{&std::get<0>(control.t)};
1730+
if (iv && iv->symbol)
1731+
ivs.push_back(iv);
1732+
}
1733+
}
1734+
ordCollapseLevel--;
1735+
for (auto iv : ivs) {
1736+
if (!iv->symbol->test(Symbol::Flag::OmpPreDetermined)) {
1737+
ResolveSeqLoopIndexInParallelOrTaskConstruct(*iv);
1738+
} else {
1739+
// TODO: conflict checks with explicitly determined DSA
1740+
}
1741+
if (ordCollapseLevel) {
1742+
if (const auto *details{iv->symbol->detailsIf<HostAssocDetails>()}) {
1743+
const Symbol *tpSymbol = &details->symbol();
1744+
// TODO: DoConcurrent won't capture the following check because a new
1745+
// symbol is declared in ResolveIndexName(), which will not have the
1746+
// OmpThreadprivate flag.
1747+
if (tpSymbol->test(Symbol::Flag::OmpThreadprivate)) {
1748+
context_.Say(iv->source,
1749+
"Loop iteration variable %s is not allowed in THREADPRIVATE."_err_en_US,
1750+
iv->ToString());
17311751
}
17321752
}
17331753
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
2+
3+
! OpenMP 5.1.1
4+
! DO Concurrent indices are private
5+
6+
!DEF: /private_iv (Subroutine)Subprogram
7+
subroutine private_iv
8+
!DEF: /private_iv/i ObjectEntity INTEGER(4)
9+
integer i
10+
!$omp parallel default(private)
11+
!$omp single
12+
!DEF: /private_iv/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
13+
do concurrent(i=1:2)
14+
end do
15+
!$omp end single
16+
!$omp end parallel
17+
end subroutine

0 commit comments

Comments
 (0)