[flang-commits] [flang] d189201 - [Flang][OpenMP] Fix nested PARALLEL SECTIONS validation (#179419)
via flang-commits
flang-commits at lists.llvm.org
Tue Feb 17 00:55:28 PST 2026
Author: jay0x
Date: 2026-02-17T14:25:23+05:30
New Revision: d189201d17c0ff5b9837e75b79bca281f4b6821a
URL: https://github.com/llvm/llvm-project/commit/d189201d17c0ff5b9837e75b79bca281f4b6821a
DIFF: https://github.com/llvm/llvm-project/commit/d189201d17c0ff5b9837e75b79bca281f4b6821a.diff
LOG: [Flang][OpenMP] Fix nested PARALLEL SECTIONS validation (#179419)
### Problem
Flang’s OpenMP semantic checker was mistakenly rejecting valid nested
constructs such as PARALLEL SECTIONS, PARALLEL DO, and other combined
parallel work-sharing directives.
The checker treated all work-sharing constructs identically and enforced
the work-sharing region nesting rules, even for a combined parallel
work-sharing construct that defined its own parallel region.
This resulted in the checker reporting the use of nested PARALLEL
SECTIONS within another parallel region as illegal OpenMP code
### Fixes: https://github.com/llvm/llvm-project/issues/179250
---------
Co-authored-by: Jay Satish Kumar Patel <kumarpat at pe31.hpc.amslabs.hpecorp.net>
Added:
flang/test/Semantics/OpenMP/nested_parallel_sections_valid.f90
Modified:
flang/lib/Semantics/check-omp-loop.cpp
flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/check-omp-structure.h
flang/test/Semantics/OpenMP/workshare04.f90
flang/test/Semantics/OpenMP/workshare05.f90
Removed:
################################################################################
diff --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index 02580e16a8bf4..80d2b90baf939 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -459,8 +459,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
// ordered-clause
// nesting check
- HasInvalidWorksharingNesting(
- beginName.source, llvm::omp::nestedWorkshareErrSet);
+ HasInvalidWorksharingNesting(beginName, llvm::omp::nestedWorkshareErrSet);
}
SetLoopInfo(x);
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 0e004a8e26501..89f1cdb5213cb 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -633,13 +633,30 @@ void OmpStructureChecker::CheckMultListItems() {
CheckMultipleOccurrence(listVars, nameList, clause->source, "LINEAR");
}
}
+bool OmpStructureChecker::IsCombinedParallelWorksharing(
+ llvm::omp::Directive directive) const {
+ // Combined parallel-worksharing constructs create their own parallel region
+ // They should not be subject to worksharing nesting restrictions
+ switch (directive) {
+ case llvm::omp::OMPD_parallel_do:
+ case llvm::omp::OMPD_parallel_do_simd:
+ case llvm::omp::OMPD_parallel_sections:
+ case llvm::omp::OMPD_parallel_workshare:
+ return true;
+ default:
+ return false;
+ }
+}
bool OmpStructureChecker::HasInvalidWorksharingNesting(
- const parser::CharBlock &source, const OmpDirectiveSet &set) {
+ const parser::OmpDirectiveName &name, const OmpDirectiveSet &set) {
// set contains all the invalid closely nested directives
// for the given directive (`source` here)
+ if (IsCombinedParallelWorksharing(name.v)) {
+ return false;
+ }
if (IsCloselyNestedRegion(set)) {
- context_.Say(source,
+ context_.Say(name.source,
"A worksharing region may not be closely nested inside a "
"worksharing, explicit task, taskloop, critical, ordered, atomic, or "
"master region"_err_en_US);
@@ -1056,7 +1073,8 @@ void OmpStructureChecker::Enter(const parser::OmpBlockConstruct &x) {
case llvm::omp::OMPD_parallel_workshare:
CheckWorkshareBlockStmts(block, beginSpec.source);
HasInvalidWorksharingNesting(
- beginSpec.source, llvm::omp::nestedWorkshareErrSet);
+ std::get<parser::OmpDirectiveName>(beginSpec.t),
+ llvm::omp::nestedWorkshareErrSet);
break;
case llvm::omp::OMPD_workdistribute:
if (!CurrentDirectiveIsNested()) {
@@ -1074,7 +1092,8 @@ void OmpStructureChecker::Enter(const parser::OmpBlockConstruct &x) {
// TODO: This check needs to be extended while implementing nesting of
// regions checks.
HasInvalidWorksharingNesting(
- beginSpec.source, llvm::omp::nestedWorkshareErrSet);
+ std::get<parser::OmpDirectiveName>(beginSpec.t),
+ llvm::omp::nestedWorkshareErrSet);
break;
case llvm::omp::Directive::OMPD_task:
for (const auto &clause : beginSpec.Clauses().v) {
@@ -1233,8 +1252,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPSectionsConstruct &x) {
CheckNoBranching(
std::get<parser::Block>(section.t), beginName.v, beginName.source);
}
- HasInvalidWorksharingNesting(
- beginName.source, llvm::omp::nestedWorkshareErrSet);
+ HasInvalidWorksharingNesting(std::get<parser::OmpDirectiveName>(beginSpec.t),
+ llvm::omp::nestedWorkshareErrSet);
}
void OmpStructureChecker::Leave(const parser::OpenMPSectionsConstruct &) {
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 9b5b0525dd27f..3bbfd61ca4d2b 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -193,9 +193,11 @@ class OmpStructureChecker : public OmpStructureCheckerBase {
void CheckStructureComponent(
const parser::OmpObjectList &objects, llvm::omp::Clause clauseId);
bool HasInvalidWorksharingNesting(
- const parser::CharBlock &, const OmpDirectiveSet &);
+ const parser::OmpDirectiveName &name, const OmpDirectiveSet &);
+
bool IsCloselyNestedRegion(const OmpDirectiveSet &set);
bool IsNestedInDirective(llvm::omp::Directive directive);
+ bool IsCombinedParallelWorksharing(llvm::omp::Directive directive) const;
bool InTargetRegion();
void HasInvalidTeamsNesting(
const llvm::omp::Directive &dir, const parser::CharBlock &source);
diff --git a/flang/test/Semantics/OpenMP/nested_parallel_sections_valid.f90 b/flang/test/Semantics/OpenMP/nested_parallel_sections_valid.f90
new file mode 100644
index 0000000000000..0c57fe2b4ef78
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/nested_parallel_sections_valid.f90
@@ -0,0 +1,60 @@
+! RUN: %flang -fopenmp -c %s
+! Regression test for nested PARALLEL SECTIONS
+! This test verifies that combined parallel-worksharing constructs
+! can be properly nested as they create their own implicit parallel regions.
+
+program test_parallel_sections_nesting
+ implicit none
+ integer :: i, j, n
+ real :: a(10), b(10), c(10)
+
+ n = 10
+
+ ! Test 1: PARALLEL SECTIONS nesting PARALLEL SECTIONS
+ !$OMP PARALLEL SECTIONS
+ !$OMP SECTION
+ !$OMP PARALLEL SECTIONS
+ !$OMP SECTION
+ do i = 1, n
+ a(i) = real(i)
+ end do
+ !$OMP SECTION
+ do j = 1, n
+ b(j) = real(j * 2)
+ end do
+ !$OMP END PARALLEL SECTIONS
+ !$OMP SECTION
+ !$OMP PARALLEL DO
+ do i = 1, n
+ c(i) = a(i) + b(i)
+ end do
+ !$OMP END PARALLEL DO
+ !$OMP END PARALLEL SECTIONS
+
+ ! Test 2: PARALLEL SECTIONS inside PARALLEL
+ !$OMP PARALLEL
+ !$OMP PARALLEL SECTIONS
+ !$OMP SECTION
+ do i = 1, n
+ a(i) = a(i) * 2
+ end do
+ !$OMP SECTION
+ do j = 1, n
+ b(j) = b(j) * 2
+ end do
+ !$OMP END PARALLEL SECTIONS
+ !$OMP END PARALLEL
+
+ ! Test 3: PARALLEL DO inside PARALLEL SECTIONS
+ !$OMP PARALLEL SECTIONS
+ !$OMP SECTION
+ !$OMP PARALLEL DO
+ do i = 1, n
+ c(i) = c(i) + a(i)
+ end do
+ !$OMP END PARALLEL DO
+ !$OMP SECTION
+ c = c + 1.0
+ !$OMP END PARALLEL SECTIONS
+
+end program test_parallel_sections_nesting
\ No newline at end of file
diff --git a/flang/test/Semantics/OpenMP/workshare04.f90 b/flang/test/Semantics/OpenMP/workshare04.f90
index 0ec635e52d2b7..e5d6334eaf373 100644
--- a/flang/test/Semantics/OpenMP/workshare04.f90
+++ b/flang/test/Semantics/OpenMP/workshare04.f90
@@ -18,7 +18,6 @@ subroutine omp_workshare(aa, bb, cc, dd, ee, ff, n)
!$omp end parallel
!ERROR: OpenMP constructs enclosed in WORKSHARE construct may consist of ATOMIC, CRITICAL or PARALLEL constructs only
- !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
!$omp parallel workshare
!ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
!$omp single
diff --git a/flang/test/Semantics/OpenMP/workshare05.f90 b/flang/test/Semantics/OpenMP/workshare05.f90
index b57053e092e67..0bee882341342 100644
--- a/flang/test/Semantics/OpenMP/workshare05.f90
+++ b/flang/test/Semantics/OpenMP/workshare05.f90
@@ -40,7 +40,7 @@ program omp_workshare
!$omp end single
!$omp end parallel
- !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+
!$omp parallel sections
!$omp section
aa = my_func()
More information about the flang-commits
mailing list