Skip to content

Conversation

@Thirumalai-Shaktivel
Copy link
Member

@Thirumalai-Shaktivel Thirumalai-Shaktivel commented Oct 7, 2024

Add missing semantic checks for Workshare construct:
OpenMP 5.2: 11.4 workshare Construct

  • The construct must not contain any user-defined function calls unless either the function is pure and elemental or the function call is contained inside a parallel construct that is nested inside the workshare construct.
    • Flang-new used to check only the elemental function, but now it needs to be impure elemental function
  • At most one NoWait clause can appear in the Workshare construct.
  • Add tests for the same.

@Thirumalai-Shaktivel Thirumalai-Shaktivel added flang Flang issues not falling into any other category flang:openmp flang:semantics labels Oct 7, 2024
@llvmbot llvmbot added the clang:openmp OpenMP related changes to Clang label Oct 7, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 7, 2024

@llvm/pr-subscribers-flang-semantics

@llvm/pr-subscribers-flang-openmp

Author: Thirumalai Shaktivel (Thirumalai-Shaktivel)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/111358.diff

3 Files Affected:

  • (modified) flang/lib/Semantics/check-omp-structure.cpp (+14-5)
  • (modified) flang/test/Semantics/OpenMP/workshare02.f90 (+18)
  • (modified) llvm/include/llvm/Frontend/OpenMP/OMP.td (+1-1)
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 5ef504aa72326e..890e5f8b159888 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -68,11 +68,20 @@ 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 (symbol.attrs().test(Attr::IMPURE)) {
+            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());
+          }
         }
       }
     }
diff --git a/flang/test/Semantics/OpenMP/workshare02.f90 b/flang/test/Semantics/OpenMP/workshare02.f90
index 11f33d63a3eb80..da8fd76542a865 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
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index fcf087d1f9c6e4..dbcbe75458677b 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -1162,7 +1162,7 @@ def OMP_Workshare : Directive<"workshare"> {
   let category = CA_Executable;
 }
 def OMP_EndWorkshare : Directive<"end workshare"> {
-  let allowedClauses = [
+  let allowedOnceClauses = [
     VersionedClause<OMPC_NoWait>,
   ];
   let leafConstructs = OMP_Workshare.leafConstructs;

Copy link
Contributor

@kiranchandramohan kiranchandramohan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you update the summary to mention which checks you are adding? And a reference to the standard and section as well.

"'%s' is not allowed in a WORKSHARE construct"_err_en_US,
root.name());
if (IsFunction(root)) {
std::string attrs = "";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use braced initialization in frontend code.

j = j - my_func()
!$omp end atomic

!ERROR: User defined IMPURE non-ELEMENTAL function 'impure_my_func' is not allowed in a WORKSHARE construct
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be a comma?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Between the IMPURE and non-ElEMENTAL?

User defined IMPURE, non-ELEMENTAL function

@Thirumalai-Shaktivel
Copy link
Member Author

I addressed the comment in the recent commit, @kiranchandramohan

@Thirumalai-Shaktivel Thirumalai-Shaktivel marked this pull request as ready for review October 9, 2024 05:57
}
def OMP_EndWorkshare : Directive<"end workshare"> {
let allowedClauses = [
let allowedOnceClauses = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: please could you add a test for this check as well. Something in flang/test/ is okay

Otherwise this LGTM

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh my mistake

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues, @tblah. Thanks for the review!

Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@Thirumalai-Shaktivel Thirumalai-Shaktivel force-pushed the llvm/workshare_01 branch 2 times, most recently from 72d5344 to 82b77c3 Compare October 10, 2024 06:01
Copy link
Contributor

@kiranchandramohan kiranchandramohan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG.

@Thirumalai-Shaktivel
Copy link
Member Author

Thanks for the reviews. As this PR is approved, I'm merging it.

@Thirumalai-Shaktivel Thirumalai-Shaktivel merged commit 2526455 into llvm:main Oct 18, 2024
@Thirumalai-Shaktivel Thirumalai-Shaktivel deleted the llvm/workshare_01 branch October 18, 2024 04:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:openmp OpenMP related changes to Clang flang:openmp flang:semantics flang Flang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants