From 460c2eaa4ad5dd2b19339d65affa25b00782dcb0 Mon Sep 17 00:00:00 2001 From: Kiran Chandramohan Date: Thu, 9 Mar 2023 14:05:08 +0000 Subject: [PATCH] [Flang][OpenMP] Restrict check to worksharing construct reductions The outer context private check for reduction variables was firing for all constructs. This check is not applicable to non-worksharing constructs. OpenMP 5.2: Section 5.5.8 A list item that appears in a reduction clause on a worksharing construct must be shared in the parallel region to which a correspodning worksharing region binds. Reviewed By: peixin Differential Revision: https://reviews.llvm.org/D144824 --- flang/lib/Semantics/check-omp-structure.cpp | 10 +++++-- flang/lib/Semantics/check-omp-structure.h | 2 +- flang/test/Semantics/OpenMP/reduction07.f90 | 46 +++++++---------------------- 3 files changed, 19 insertions(+), 39 deletions(-) diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index b30ea41..cffdabf 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -1981,7 +1981,13 @@ void OmpStructureChecker::CheckReductionTypeList( CheckIntentInPointerAndDefinable( ompObjectList, llvm::omp::Clause::OMPC_reduction); CheckReductionArraySection(ompObjectList); - CheckMultipleAppearanceAcrossContext(ompObjectList); + // If this is a worksharing construct then ensure the reduction variable + // is not private in the parallel region that it binds to. + OmpDirectiveSet workshareSet{llvm::omp::Directive::OMPD_do, + llvm::omp::Directive::OMPD_sections, llvm::omp::Directive::OMPD_do_simd}; + if (workshareSet.test(GetContext().directive)) { + CheckSharedBindingInOuterContext(ompObjectList); + } } void OmpStructureChecker::CheckIntentInPointerAndDefinable( @@ -2026,7 +2032,7 @@ void OmpStructureChecker::CheckReductionArraySection( } } -void OmpStructureChecker::CheckMultipleAppearanceAcrossContext( +void OmpStructureChecker::CheckSharedBindingInOuterContext( const parser::OmpObjectList &redObjectList) { // TODO: Verify the assumption here that the immediately enclosing region is // the parallel region to which the worksharing construct having reduction diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h index 2751cdd..992531a 100644 --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -259,7 +259,7 @@ private: const parser::OmpObjectList &, const llvm::omp::Clause); void CheckArraySection(const parser::ArrayElement &arrayElement, const parser::Name &name, const llvm::omp::Clause clause); - void CheckMultipleAppearanceAcrossContext( + void CheckSharedBindingInOuterContext( const parser::OmpObjectList &ompObjectList); const parser::OmpObjectList *GetOmpObjectList(const parser::OmpClause &); void CheckPredefinedAllocatorRestriction(const parser::CharBlock &source, diff --git a/flang/test/Semantics/OpenMP/reduction07.f90 b/flang/test/Semantics/OpenMP/reduction07.f90 index a3b5876..98ed69a 100644 --- a/flang/test/Semantics/OpenMP/reduction07.f90 +++ b/flang/test/Semantics/OpenMP/reduction07.f90 @@ -78,42 +78,6 @@ a = a + 10 !$omp parallel reduction(*:a) !$omp end parallel - -!$omp parallel reduction(+:a) -!ERROR: REDUCTION clause is not allowed on the WORKSHARE directive -!ERROR: REDUCTION variable 'a' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. -!$omp workshare reduction(*:a) -a = a + 10 -!$omp end workshare -!$omp end parallel - -!$omp parallel reduction(*:a) -!$omp end parallel - - -!$omp parallel reduction(+:a) -!ERROR: REDUCTION clause is not allowed on the SINGLE directive -!ERROR: REDUCTION variable 'a' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. -!$omp single reduction(*:a) -a = a + 10 -!$omp end single -!$omp end parallel - -!$omp parallel reduction(+:a) -!$omp end parallel - - -!$omp parallel reduction(+:a) -!ERROR: REDUCTION clause is not allowed on the SINGLE directive -!ERROR: REDUCTION variable 'a' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. -!$omp single reduction(iand:a) -a = a + 10 -!$omp end single -!$omp end parallel - -!$omp parallel reduction(iand:a) -!$omp end parallel - !$omp parallel reduction(ieor:a) !ERROR: REDUCTION variable 'a' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind. !$omp sections reduction(+:a) @@ -121,7 +85,17 @@ a = ieor(a, 10) !$omp end sections !$omp end parallel +!$omp parallel private(a) !$omp parallel reduction(ieor:a) !$omp end parallel +!$omp end parallel + +!$omp task firstprivate(a) +!$omp parallel do reduction(+:a) +do i=1,10 + a=a+j +end do +!$omp end parallel do +!$omp end task end program omp_reduction -- 2.7.4