[flang-commits] [flang] [Flang][OpenMP] Allow copyprivate and nowait on the directive clauses (PR #127769)
Thirumalai Shaktivel via flang-commits
flang-commits at lists.llvm.org
Mon Feb 24 01:02:24 PST 2025
https://github.com/Thirumalai-Shaktivel updated https://github.com/llvm/llvm-project/pull/127769
>From 50cdcf65c9f21dc80f3867960bc8b3daa6b09bd5 Mon Sep 17 00:00:00 2001
From: Thirumalai-Shaktivel <thirumalaishaktivel at gmail.com>
Date: Wed, 19 Feb 2025 08:54:19 +0000
Subject: [PATCH 1/4] [Flang][OpenMP] Allow copyprivate and nowait on the
directive clauses
Issue:
- Single construct used to throw semantic error for copyprivate and
nowiat clause when used in the single directive.
- Also, the Nowait and copyprivate restrictions has be removed from
OpenMP 6.0
Fix:
- The above mentioned semantic error was valid until OpenMP 5.1.
- From OpenMP 5.2, copyprivate and nowait is allowed in both
clause and end-clause
>From Reference guide (OpenMP 5.2, 2.10.2):
```
!$omp single [clause[ [,]clause] ... ]
loosely-structured-block
!$omp end single [end-clause[ [,]end-clause] ...]
clause:
copyprivate (list)
nowait
[...]
end-clause:
copyprivate (list)
nowait
```
---
flang/lib/Semantics/check-omp-structure.cpp | 57 ++++++++++++++++---
.../Semantics/OpenMP/clause-validity01.f90 | 6 +-
flang/test/Semantics/OpenMP/single03.f90 | 54 ++++++++++++++++++
.../test/Semantics/OpenMP/threadprivate04.f90 | 2 +-
4 files changed, 106 insertions(+), 13 deletions(-)
create mode 100644 flang/test/Semantics/OpenMP/single03.f90
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 1d6fe6c8d4249..93f71c1951658 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1203,6 +1203,40 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
deviceConstructFound_ = true;
}
+ unsigned version{context_.langOptions().OpenMPVersion};
+ if (version >= 52 &&
+ GetContext().directive == llvm::omp::Directive::OMPD_single) {
+ bool foundCopyPrivate{false};
+ bool foundNowait{false};
+ parser::CharBlock NowaitSource{""};
+ auto catchCopyPrivateNowaitClauses = [&](const auto &dir) {
+ for (auto &clause : std::get<parser::OmpClauseList>(dir.t).v) {
+ if (clause.Id() == llvm::omp::Clause::OMPC_copyprivate) {
+ if (foundCopyPrivate) {
+ context_.Say(clause.source,
+ "At most one COPYPRIVATE clause can appear on the SINGLE directive"_err_en_US);
+ } else {
+ foundCopyPrivate = true;
+ }
+ } else if (clause.Id() == llvm::omp::Clause::OMPC_nowait) {
+ if (foundNowait) {
+ context_.Say(clause.source,
+ "At most one NOWAIT clause can appear on the SINGLE directive"_err_en_US);
+ } else {
+ foundNowait = true;
+ NowaitSource = clause.source;
+ }
+ }
+ }
+ };
+ catchCopyPrivateNowaitClauses(beginBlockDir);
+ catchCopyPrivateNowaitClauses(endBlockDir);
+ if (version == 52 && foundCopyPrivate && foundNowait) {
+ context_.Say(NowaitSource,
+ "NOWAIT clause must not be used with COPYPRIVATE clause on the SINGLE directive"_err_en_US);
+ }
+ }
+
switch (beginDir.v) {
case llvm::omp::Directive::OMPD_target:
if (CheckTargetBlockOnlyTeams(block)) {
@@ -2853,7 +2887,8 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
CheckMultListItems();
// 2.7.3 Single Construct Restriction
- if (GetContext().directive == llvm::omp::Directive::OMPD_end_single) {
+ if (context_.langOptions().OpenMPVersion < 52 &&
+ GetContext().directive == llvm::omp::Directive::OMPD_end_single) {
CheckNotAllowedIfClause(
llvm::omp::Clause::OMPC_copyprivate, {llvm::omp::Clause::OMPC_nowait});
}
@@ -3481,14 +3516,16 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Private &x) {
void OmpStructureChecker::Enter(const parser::OmpClause::Nowait &x) {
CheckAllowedClause(llvm::omp::Clause::OMPC_nowait);
- if (llvm::omp::noWaitClauseNotAllowedSet.test(GetContext().directive)) {
+ if (context_.langOptions().OpenMPVersion < 52 &&
+ llvm::omp::noWaitClauseNotAllowedSet.test(GetContext().directive)) {
+ std::string dirName{
+ parser::ToUpperCaseLetters(GetContext().directiveSource.ToString())};
context_.Say(GetContext().clauseSource,
"%s clause is not allowed on the OMP %s directive,"
- " use it on OMP END %s directive "_err_en_US,
+ " use it on OMP END %s directive or %s"_err_en_US,
parser::ToUpperCaseLetters(
getClauseName(llvm::omp::Clause::OMPC_nowait).str()),
- parser::ToUpperCaseLetters(GetContext().directiveSource.ToString()),
- parser::ToUpperCaseLetters(GetContext().directiveSource.ToString()));
+ dirName, dirName, TryVersion(52));
}
}
@@ -4220,14 +4257,16 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Copyprivate &x) {
CheckIntentInPointer(symbols, llvm::omp::Clause::OMPC_copyprivate);
CheckCopyingPolymorphicAllocatable(
symbols, llvm::omp::Clause::OMPC_copyprivate);
- if (GetContext().directive == llvm::omp::Directive::OMPD_single) {
+ if (context_.langOptions().OpenMPVersion < 52 &&
+ GetContext().directive == llvm::omp::Directive::OMPD_single) {
+ std::string dirName{
+ parser::ToUpperCaseLetters(GetContext().directiveSource.ToString())};
context_.Say(GetContext().clauseSource,
"%s clause is not allowed on the OMP %s directive,"
- " use it on OMP END %s directive "_err_en_US,
+ " use it on OMP END %s directive or %s"_err_en_US,
parser::ToUpperCaseLetters(
getClauseName(llvm::omp::Clause::OMPC_copyprivate).str()),
- parser::ToUpperCaseLetters(GetContext().directiveSource.ToString()),
- parser::ToUpperCaseLetters(GetContext().directiveSource.ToString()));
+ dirName, dirName, TryVersion(52));
}
}
diff --git a/flang/test/Semantics/OpenMP/clause-validity01.f90 b/flang/test/Semantics/OpenMP/clause-validity01.f90
index e8114154a809b..0349a5a760753 100644
--- a/flang/test/Semantics/OpenMP/clause-validity01.f90
+++ b/flang/test/Semantics/OpenMP/clause-validity01.f90
@@ -330,7 +330,7 @@
!$omp parallel
b = 1
!ERROR: LASTPRIVATE clause is not allowed on the SINGLE directive
- !ERROR: NOWAIT clause is not allowed on the OMP SINGLE directive, use it on OMP END SINGLE directive
+ !ERROR: NOWAIT clause is not allowed on the OMP SINGLE directive, use it on OMP END SINGLE directive or try -fopenmp-version=52
!$omp single private(a) lastprivate(c) nowait
a = 3.14
!ERROR: Clause NOWAIT is not allowed if clause COPYPRIVATE appears on the END SINGLE directive
@@ -351,7 +351,7 @@
a = 1.0
!ERROR: COPYPRIVATE clause is not allowed on the END WORKSHARE directive
!$omp end workshare nowait copyprivate(a)
- !ERROR: NOWAIT clause is not allowed on the OMP WORKSHARE directive, use it on OMP END WORKSHARE directive
+ !ERROR: NOWAIT clause is not allowed on the OMP WORKSHARE directive, use it on OMP END WORKSHARE directive or try -fopenmp-version=52
!$omp workshare nowait
!$omp end workshare
!$omp end parallel
@@ -420,7 +420,7 @@
!$omp parallel
!ERROR: No ORDERED clause with a parameter can be specified on the DO SIMD directive
!ERROR: NOGROUP clause is not allowed on the DO SIMD directive
- !ERROR: NOWAIT clause is not allowed on the OMP DO SIMD directive, use it on OMP END DO SIMD directive
+ !ERROR: NOWAIT clause is not allowed on the OMP DO SIMD directive, use it on OMP END DO SIMD directive or try -fopenmp-version=52
!$omp do simd ordered(2) NOGROUP nowait
do i = 1, N
do j = 1, N
diff --git a/flang/test/Semantics/OpenMP/single03.f90 b/flang/test/Semantics/OpenMP/single03.f90
new file mode 100644
index 0000000000000..bc7647b66e39f
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/single03.f90
@@ -0,0 +1,54 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -fopenmp-version=52
+!
+! OpenMP Version 5.2
+!
+! 2.10.2 single Construct
+! Copyprivate and Nowait clauses are allowed in both clause and end clause
+
+subroutine omp_single
+ integer, save :: i
+ integer :: j
+ i = 10; j = 11
+
+ !ERROR: COPYPRIVATE variable 'i' is not PRIVATE or THREADPRIVATE in outer context
+ !ERROR: NOWAIT clause must not be used with COPYPRIVATE clause on the SINGLE directive
+ !$omp single copyprivate(i) nowait
+ print *, "omp single", i
+ !$omp end single
+
+ !$omp parallel private(i)
+ !$omp single copyprivate(i)
+ print *, "omp single", i
+ !$omp end single
+ !$omp end parallel
+
+ !$omp parallel
+ !ERROR: NOWAIT clause must not be used with COPYPRIVATE clause on the SINGLE directive
+ !$omp single nowait
+ print *, "omp single", i
+ !ERROR: COPYPRIVATE variable 'i' is not PRIVATE or THREADPRIVATE in outer context
+ !$omp end single copyprivate(i)
+
+ !ERROR: COPYPRIVATE variable 'i' is not PRIVATE or THREADPRIVATE in outer context
+ !$omp single copyprivate(i)
+ print *, "omp single", i
+ !ERROR: NOWAIT clause must not be used with COPYPRIVATE clause on the SINGLE directive
+ !$omp end single nowait
+
+ !ERROR: COPYPRIVATE variable 'j' may not appear on a PRIVATE or FIRSTPRIVATE clause on a SINGLE construct
+ !$omp single private(j) copyprivate(j)
+ print *, "omp single", j
+ !ERROR: At most one COPYPRIVATE clause can appear on the SINGLE directive
+ !ERROR: COPYPRIVATE variable 'j' may not appear on a PRIVATE or FIRSTPRIVATE clause on a SINGLE construct
+ !$omp end single copyprivate(j)
+
+ !$omp single nowait
+ print *, "omp single", j
+ !ERROR: At most one NOWAIT clause can appear on the SINGLE directive
+ !$omp end single nowait
+ !$omp end parallel
+
+ !$omp single nowait
+ print *, "omp single", i
+ !$omp end single
+end subroutine omp_single
diff --git a/flang/test/Semantics/OpenMP/threadprivate04.f90 b/flang/test/Semantics/OpenMP/threadprivate04.f90
index 3d8c7fb8de8fa..db23cdb06ed96 100644
--- a/flang/test/Semantics/OpenMP/threadprivate04.f90
+++ b/flang/test/Semantics/OpenMP/threadprivate04.f90
@@ -14,7 +14,7 @@ program main
!$omp parallel num_threads(x1)
!$omp end parallel
- !ERROR: COPYPRIVATE clause is not allowed on the OMP SINGLE directive, use it on OMP END SINGLE directive
+ !ERROR: COPYPRIVATE clause is not allowed on the OMP SINGLE directive, use it on OMP END SINGLE directive or try -fopenmp-version=52
!$omp single copyprivate(x2, /blk1/)
!$omp end single
>From 2ebb099bac421c7faa310227d0c97e84899b689c Mon Sep 17 00:00:00 2001
From: Thirumalai-Shaktivel <thirumalaishaktivel at gmail.com>
Date: Mon, 24 Feb 2025 06:18:34 +0000
Subject: [PATCH 2/4] [Flang] Remove semantic checks for Copyprivate and nowait
---
flang/lib/Semantics/check-omp-structure.cpp | 32 +++----------------
.../Semantics/OpenMP/clause-validity01.f90 | 9 ++----
.../test/Semantics/OpenMP/threadprivate04.f90 | 1 -
3 files changed, 7 insertions(+), 35 deletions(-)
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 93f71c1951658..af609cc89a336 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1203,9 +1203,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
deviceConstructFound_ = true;
}
- unsigned version{context_.langOptions().OpenMPVersion};
- if (version >= 52 &&
- GetContext().directive == llvm::omp::Directive::OMPD_single) {
+ if (GetContext().directive == llvm::omp::Directive::OMPD_single) {
bool foundCopyPrivate{false};
bool foundNowait{false};
parser::CharBlock NowaitSource{""};
@@ -1231,7 +1229,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
};
catchCopyPrivateNowaitClauses(beginBlockDir);
catchCopyPrivateNowaitClauses(endBlockDir);
- if (version == 52 && foundCopyPrivate && foundNowait) {
+ unsigned version{context_.langOptions().OpenMPVersion};
+ if (version <= 52 && foundCopyPrivate && foundNowait) {
context_.Say(NowaitSource,
"NOWAIT clause must not be used with COPYPRIVATE clause on the SINGLE directive"_err_en_US);
}
@@ -2887,8 +2886,7 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
CheckMultListItems();
// 2.7.3 Single Construct Restriction
- if (context_.langOptions().OpenMPVersion < 52 &&
- GetContext().directive == llvm::omp::Directive::OMPD_end_single) {
+ if (GetContext().directive == llvm::omp::Directive::OMPD_end_single) {
CheckNotAllowedIfClause(
llvm::omp::Clause::OMPC_copyprivate, {llvm::omp::Clause::OMPC_nowait});
}
@@ -3516,17 +3514,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Private &x) {
void OmpStructureChecker::Enter(const parser::OmpClause::Nowait &x) {
CheckAllowedClause(llvm::omp::Clause::OMPC_nowait);
- if (context_.langOptions().OpenMPVersion < 52 &&
- llvm::omp::noWaitClauseNotAllowedSet.test(GetContext().directive)) {
- std::string dirName{
- parser::ToUpperCaseLetters(GetContext().directiveSource.ToString())};
- context_.Say(GetContext().clauseSource,
- "%s clause is not allowed on the OMP %s directive,"
- " use it on OMP END %s directive or %s"_err_en_US,
- parser::ToUpperCaseLetters(
- getClauseName(llvm::omp::Clause::OMPC_nowait).str()),
- dirName, dirName, TryVersion(52));
- }
}
bool OmpStructureChecker::IsDataRefTypeParamInquiry(
@@ -4257,17 +4244,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Copyprivate &x) {
CheckIntentInPointer(symbols, llvm::omp::Clause::OMPC_copyprivate);
CheckCopyingPolymorphicAllocatable(
symbols, llvm::omp::Clause::OMPC_copyprivate);
- if (context_.langOptions().OpenMPVersion < 52 &&
- GetContext().directive == llvm::omp::Directive::OMPD_single) {
- std::string dirName{
- parser::ToUpperCaseLetters(GetContext().directiveSource.ToString())};
- context_.Say(GetContext().clauseSource,
- "%s clause is not allowed on the OMP %s directive,"
- " use it on OMP END %s directive or %s"_err_en_US,
- parser::ToUpperCaseLetters(
- getClauseName(llvm::omp::Clause::OMPC_copyprivate).str()),
- dirName, dirName, TryVersion(52));
- }
}
void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &x) {
diff --git a/flang/test/Semantics/OpenMP/clause-validity01.f90 b/flang/test/Semantics/OpenMP/clause-validity01.f90
index 0349a5a760753..f6a252d8c7535 100644
--- a/flang/test/Semantics/OpenMP/clause-validity01.f90
+++ b/flang/test/Semantics/OpenMP/clause-validity01.f90
@@ -330,7 +330,6 @@
!$omp parallel
b = 1
!ERROR: LASTPRIVATE clause is not allowed on the SINGLE directive
- !ERROR: NOWAIT clause is not allowed on the OMP SINGLE directive, use it on OMP END SINGLE directive or try -fopenmp-version=52
!$omp single private(a) lastprivate(c) nowait
a = 3.14
!ERROR: Clause NOWAIT is not allowed if clause COPYPRIVATE appears on the END SINGLE directive
@@ -351,7 +350,6 @@
a = 1.0
!ERROR: COPYPRIVATE clause is not allowed on the END WORKSHARE directive
!$omp end workshare nowait copyprivate(a)
- !ERROR: NOWAIT clause is not allowed on the OMP WORKSHARE directive, use it on OMP END WORKSHARE directive or try -fopenmp-version=52
!$omp workshare nowait
!$omp end workshare
!$omp end parallel
@@ -420,7 +418,6 @@
!$omp parallel
!ERROR: No ORDERED clause with a parameter can be specified on the DO SIMD directive
!ERROR: NOGROUP clause is not allowed on the DO SIMD directive
- !ERROR: NOWAIT clause is not allowed on the OMP DO SIMD directive, use it on OMP END DO SIMD directive or try -fopenmp-version=52
!$omp do simd ordered(2) NOGROUP nowait
do i = 1, N
do j = 1, N
@@ -428,7 +425,7 @@
enddo
enddo
!omp end do nowait
- !$omp end parallel
+ !$omp end parallel
! 2.11.4 parallel-do-simd-clause -> parallel-clause |
! do-simd-clause
@@ -586,7 +583,7 @@
allc = 3.14
enddo
- !$omp target enter data map(alloc:A) device(0)
- !$omp target exit data map(delete:A) device(0)
+ !$omp target enter data map(alloc:A) device(0)
+ !$omp target exit data map(delete:A) device(0)
end program
diff --git a/flang/test/Semantics/OpenMP/threadprivate04.f90 b/flang/test/Semantics/OpenMP/threadprivate04.f90
index db23cdb06ed96..d261f33b4dbd7 100644
--- a/flang/test/Semantics/OpenMP/threadprivate04.f90
+++ b/flang/test/Semantics/OpenMP/threadprivate04.f90
@@ -14,7 +14,6 @@ program main
!$omp parallel num_threads(x1)
!$omp end parallel
- !ERROR: COPYPRIVATE clause is not allowed on the OMP SINGLE directive, use it on OMP END SINGLE directive or try -fopenmp-version=52
!$omp single copyprivate(x2, /blk1/)
!$omp end single
>From 656864e62a088d432e25b8b62a3ed2a1ef74c7c9 Mon Sep 17 00:00:00 2001
From: Thirumalai-Shaktivel <thirumalaishaktivel at gmail.com>
Date: Mon, 24 Feb 2025 07:32:33 +0000
Subject: [PATCH 3/4] Fix failures
---
flang/test/Semantics/OpenMP/clause-validity01.f90 | 3 +++
1 file changed, 3 insertions(+)
diff --git a/flang/test/Semantics/OpenMP/clause-validity01.f90 b/flang/test/Semantics/OpenMP/clause-validity01.f90
index f6a252d8c7535..9d1c932b59456 100644
--- a/flang/test/Semantics/OpenMP/clause-validity01.f90
+++ b/flang/test/Semantics/OpenMP/clause-validity01.f90
@@ -330,10 +330,13 @@
!$omp parallel
b = 1
!ERROR: LASTPRIVATE clause is not allowed on the SINGLE directive
+ !ERROR: NOWAIT clause must not be used with COPYPRIVATE clause on the SINGLE directive
!$omp single private(a) lastprivate(c) nowait
a = 3.14
!ERROR: Clause NOWAIT is not allowed if clause COPYPRIVATE appears on the END SINGLE directive
!ERROR: COPYPRIVATE variable 'a' may not appear on a PRIVATE or FIRSTPRIVATE clause on a SINGLE construct
+ !ERROR: At most one NOWAIT clause can appear on the SINGLE directive
+ !ERROR: At most one NOWAIT clause can appear on the SINGLE directive
!ERROR: At most one NOWAIT clause can appear on the END SINGLE directive
!$omp end single copyprivate(a) nowait nowait
c = 2
>From 6cbaf66bc0041f223307d95b97d88a53a97cb8cb Mon Sep 17 00:00:00 2001
From: Thirumalai-Shaktivel <thirumalaishaktivel at gmail.com>
Date: Mon, 24 Feb 2025 09:01:51 +0000
Subject: [PATCH 4/4] Remove duplicate checks
---
flang/lib/Semantics/check-omp-structure.cpp | 6 ------
flang/test/Semantics/OpenMP/clause-validity01.f90 | 7 +++----
2 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index af609cc89a336..e2afff9d4120a 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -2885,12 +2885,6 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
// clause
CheckMultListItems();
- // 2.7.3 Single Construct Restriction
- if (GetContext().directive == llvm::omp::Directive::OMPD_end_single) {
- CheckNotAllowedIfClause(
- llvm::omp::Clause::OMPC_copyprivate, {llvm::omp::Clause::OMPC_nowait});
- }
-
auto testThreadprivateVarErr = [&](Symbol sym, parser::Name name,
llvmOmpClause clauseTy) {
if (sym.test(Symbol::Flag::OmpThreadprivate))
diff --git a/flang/test/Semantics/OpenMP/clause-validity01.f90 b/flang/test/Semantics/OpenMP/clause-validity01.f90
index 9d1c932b59456..5e0d91914c441 100644
--- a/flang/test/Semantics/OpenMP/clause-validity01.f90
+++ b/flang/test/Semantics/OpenMP/clause-validity01.f90
@@ -333,7 +333,6 @@
!ERROR: NOWAIT clause must not be used with COPYPRIVATE clause on the SINGLE directive
!$omp single private(a) lastprivate(c) nowait
a = 3.14
- !ERROR: Clause NOWAIT is not allowed if clause COPYPRIVATE appears on the END SINGLE directive
!ERROR: COPYPRIVATE variable 'a' may not appear on a PRIVATE or FIRSTPRIVATE clause on a SINGLE construct
!ERROR: At most one NOWAIT clause can appear on the SINGLE directive
!ERROR: At most one NOWAIT clause can appear on the SINGLE directive
@@ -428,7 +427,7 @@
enddo
enddo
!omp end do nowait
- !$omp end parallel
+ !$omp end parallel
! 2.11.4 parallel-do-simd-clause -> parallel-clause |
! do-simd-clause
@@ -586,7 +585,7 @@
allc = 3.14
enddo
- !$omp target enter data map(alloc:A) device(0)
- !$omp target exit data map(delete:A) device(0)
+ !$omp target enter data map(alloc:A) device(0)
+ !$omp target exit data map(delete:A) device(0)
end program
More information about the flang-commits
mailing list