From 554361b17a88fcbdea4fabd5851d27dd00a48b7b Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Mon, 7 Oct 2024 10:34:59 +0000 Subject: [PATCH 1/3] [LLVM-Flang][OpenMP] Add a semantic check for Worshare construct --- flang/lib/Semantics/check-omp-structure.cpp | 22 ++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index a54fa14730321..9c2c7f05892f9 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -68,11 +68,23 @@ class OmpWorkshareBlockChecker { if (const auto *e{GetExpr(context_, expr)}) { for (const Symbol &symbol : evaluate::CollectSymbols(*e)) { const Symbol &root{GetAssociationRoot(symbol)}; - if (IsFunction(root) && !IsElementalProcedure(root)) { - context_.Say(expr.source, - "User defined non-ELEMENTAL function " - "'%s' is not allowed in a WORKSHARE construct"_err_en_US, - root.name()); + if (IsFunction(root)) { + std::string attrs{""}; + if (!IsElementalProcedure(root)) { + attrs = " non-ELEMENTAL"; + } + if (root.attrs().test(Attr::IMPURE)) { + if (attrs != "") { + attrs = "," + attrs; + } + attrs = " IMPURE" + attrs; + } + if (attrs != "") { + context_.Say(expr.source, + "User defined%s function '%s' is not allowed in a " + "WORKSHARE construct"_err_en_US, + attrs, root.name()); + } } } } From b1400b1a457170e7ed825e7d6da6d2e6b1c0a438 Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Mon, 7 Oct 2024 10:35:40 +0000 Subject: [PATCH 2/3] [Flang][OpenMP] Allow Nowait clause only once in the workshare construct --- llvm/include/llvm/Frontend/OpenMP/OMP.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index f2f09812a8690..f784c37cbe955 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -1170,7 +1170,7 @@ def OMP_Workshare : Directive<"workshare"> { let category = CA_Executable; } def OMP_EndWorkshare : Directive<"end workshare"> { - let allowedClauses = [ + let allowedOnceClauses = [ VersionedClause, ]; let leafConstructs = OMP_Workshare.leafConstructs; From 82b77c34dd43339197e7bac576d017b22074b6ff Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Mon, 7 Oct 2024 10:36:05 +0000 Subject: [PATCH 3/3] [Test] Add tests --- flang/test/Semantics/OpenMP/workshare02.f90 | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/flang/test/Semantics/OpenMP/workshare02.f90 b/flang/test/Semantics/OpenMP/workshare02.f90 index 11f33d63a3eb8..dddaa354fff9f 100644 --- a/flang/test/Semantics/OpenMP/workshare02.f90 +++ b/flang/test/Semantics/OpenMP/workshare02.f90 @@ -9,6 +9,14 @@ module my_mod integer function my_func() my_func = 10 end function my_func + + impure integer function impure_my_func() + impure_my_func = 20 + end function impure_my_func + + impure elemental integer function impure_ele_my_func() + impure_ele_my_func = 20 + end function impure_ele_my_func end module my_mod subroutine workshare(aa, bb, cc, dd, ee, ff, n) @@ -61,6 +69,16 @@ subroutine workshare(aa, bb, cc, dd, ee, ff, n) j = j - my_func() !$omp end atomic + !ERROR: User defined IMPURE, non-ELEMENTAL function 'impure_my_func' is not allowed in a WORKSHARE construct + cc = impure_my_func() + !ERROR: User defined IMPURE function 'impure_ele_my_func' is not allowed in a WORKSHARE construct + aa(1) = impure_ele_my_func() + !$omp end workshare + !$omp workshare + j = j + 1 + !ERROR: At most one NOWAIT clause can appear on the END WORKSHARE directive + !$omp end workshare nowait nowait + end subroutine workshare