diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 23a29aecf11dd..868c64651bc30 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -267,16 +267,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) { // ordered-clause // nesting check - HasInvalidWorksharingNesting(beginDir.source, - {llvm::omp::Directive::OMPD_do, llvm::omp::Directive::OMPD_sections, - llvm::omp::Directive::OMPD_single, - llvm::omp::Directive::OMPD_workshare, - llvm::omp::Directive::OMPD_task, - llvm::omp::Directive::OMPD_taskloop, - llvm::omp::Directive::OMPD_critical, - llvm::omp::Directive::OMPD_ordered, - llvm::omp::Directive::OMPD_atomic, - llvm::omp::Directive::OMPD_master}); + HasInvalidWorksharingNesting( + beginDir.source, llvm::omp::nestedWorkshareErrSet); } SetLoopInfo(x); @@ -420,12 +412,6 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) { PushContextAndClauseSets(beginDir.source, beginDir.v); - // TODO: This check needs to be extended while implementing nesting of regions - // checks. - if (beginDir.v == llvm::omp::Directive::OMPD_single) { - HasInvalidWorksharingNesting( - beginDir.source, {llvm::omp::Directive::OMPD_do}); - } if (CurrentDirectiveIsNested()) { CheckIfDoOrderedClause(beginDir); if (llvm::omp::teamSet.test(GetContextParent().directive)) { @@ -439,6 +425,14 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) { case llvm::omp::OMPD_workshare: case llvm::omp::OMPD_parallel_workshare: CheckWorkshareBlockStmts(block, beginDir.source); + HasInvalidWorksharingNesting( + beginDir.source, llvm::omp::nestedWorkshareErrSet); + break; + case llvm::omp::Directive::OMPD_single: + // TODO: This check needs to be extended while implementing nesting of + // regions checks. + HasInvalidWorksharingNesting( + beginDir.source, llvm::omp::nestedWorkshareErrSet); break; default: break; @@ -484,6 +478,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPSectionsConstruct &x) { for (const auto &block : sectionBlocks.v) { CheckNoBranching(block, beginDir.v, beginDir.source); } + HasInvalidWorksharingNesting( + beginDir.source, 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 ad3d4065f287c..8c76530551a3f 100644 --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -42,10 +42,10 @@ static OmpDirectiveSet parallelSet{Directive::OMPD_distribute_parallel_do, Directive::OMPD_teams_distribute_parallel_do, Directive::OMPD_teams_distribute_parallel_do_simd}; static OmpDirectiveSet doSet{Directive::OMPD_distribute_parallel_do, - Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_parallel, - Directive::OMPD_parallel_do, Directive::OMPD_parallel_do_simd, - Directive::OMPD_do, Directive::OMPD_do_simd, - Directive::OMPD_target_parallel_do, Directive::OMPD_target_parallel_do_simd, + Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_parallel_do, + Directive::OMPD_parallel_do_simd, Directive::OMPD_do, + Directive::OMPD_do_simd, Directive::OMPD_target_parallel_do, + Directive::OMPD_target_parallel_do_simd, Directive::OMPD_target_teams_distribute_parallel_do, Directive::OMPD_target_teams_distribute_parallel_do_simd, Directive::OMPD_teams_distribute_parallel_do, @@ -55,6 +55,11 @@ static OmpDirectiveSet doSimdSet{Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_target_parallel_do_simd, Directive::OMPD_target_teams_distribute_parallel_do_simd, Directive::OMPD_teams_distribute_parallel_do_simd}; +static OmpDirectiveSet workShareSet{ + OmpDirectiveSet{Directive::OMPD_workshare, + Directive::OMPD_parallel_workshare, Directive::OMPD_parallel_sections, + Directive::OMPD_sections, Directive::OMPD_single} | + doSet}; static OmpDirectiveSet taskloopSet{ Directive::OMPD_taskloop, Directive::OMPD_taskloop_simd}; static OmpDirectiveSet targetSet{Directive::OMPD_target, @@ -83,6 +88,11 @@ static OmpDirectiveSet taskGeneratingSet{ static OmpDirectiveSet nestedOrderedErrSet{Directive::OMPD_critical, Directive::OMPD_ordered, Directive::OMPD_atomic, Directive::OMPD_task, Directive::OMPD_taskloop}; +static OmpDirectiveSet nestedWorkshareErrSet{ + OmpDirectiveSet{Directive::OMPD_task, Directive::OMPD_taskloop, + Directive::OMPD_critical, Directive::OMPD_ordered, + Directive::OMPD_atomic, Directive::OMPD_master} | + workShareSet}; static OmpClauseSet privateSet{ Clause::OMPC_private, Clause::OMPC_firstprivate, Clause::OMPC_lastprivate}; static OmpClauseSet privateReductionSet{ diff --git a/flang/test/Semantics/omp-do05.f90 b/flang/test/Semantics/omp-do05.f90 index 345bf15e3dce8..e2e899959d6f9 100644 --- a/flang/test/Semantics/omp-do05.f90 +++ b/flang/test/Semantics/omp-do05.f90 @@ -18,6 +18,96 @@ program omp_do end do !$omp end do + !$omp parallel do + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end parallel do + + !$omp parallel do simd + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end parallel do simd + + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$omp distribute parallel do + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end distribute parallel do + + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$omp distribute parallel do simd + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end distribute parallel do simd + + !$omp target parallel do + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end target parallel do + + !$omp target parallel do simd + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end target parallel do simd + + !$omp target teams distribute parallel do + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end target teams distribute parallel do + + !$omp target teams distribute parallel do simd + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end target teams distribute parallel do simd + !$omp do do i=1,10 !$omp task diff --git a/flang/test/Semantics/omp-workshare01.f90 b/flang/test/Semantics/omp-workshare01.f90 index 1a1f19421aa45..2f8a48b613d21 100644 --- a/flang/test/Semantics/omp-workshare01.f90 +++ b/flang/test/Semantics/omp-workshare01.f90 @@ -15,6 +15,7 @@ subroutine workshare(aa, bb, cc, dd, ee, ff, n) end do !$omp critical + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region !$omp single aa = bb !$omp end single diff --git a/flang/test/Semantics/omp-workshare04.f90 b/flang/test/Semantics/omp-workshare04.f90 index 6742174cea796..ab8ec039a01c6 100644 --- a/flang/test/Semantics/omp-workshare04.f90 +++ b/flang/test/Semantics/omp-workshare04.f90 @@ -18,7 +18,9 @@ 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 ee = ff !$omp end single diff --git a/flang/test/Semantics/omp-workshare05.f90 b/flang/test/Semantics/omp-workshare05.f90 index ab0f6d0b18a85..372df32a5a558 100644 --- a/flang/test/Semantics/omp-workshare05.f90 +++ b/flang/test/Semantics/omp-workshare05.f90 @@ -40,6 +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()