[llvm-branch-commits] [flang] [flang][OpenMP] Semantic checks for DYN_GROUPPRIVATE (PR #154550)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Aug 20 07:34:17 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-openmp

Author: Krzysztof Parzyszek (kparzysz)

<details>
<summary>Changes</summary>

Add checks for non-STRICT values of the prescriptiveness modifier on clauses that had accepted it prior to the addition of FALLBACK value (GRAINSIZE and NUM_TASKS).

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


4 Files Affected:

- (modified) flang/include/flang/Semantics/openmp-modifiers.h (+1) 
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+65-3) 
- (modified) flang/lib/Semantics/openmp-modifiers.cpp (+19) 
- (added) flang/test/Semantics/OpenMP/prescriptiveness-modifier.f90 (+47) 


``````````diff
diff --git a/flang/include/flang/Semantics/openmp-modifiers.h b/flang/include/flang/Semantics/openmp-modifiers.h
index e0eae984731c7..f74e58a94f768 100644
--- a/flang/include/flang/Semantics/openmp-modifiers.h
+++ b/flang/include/flang/Semantics/openmp-modifiers.h
@@ -67,6 +67,7 @@ template <typename SpecificTy> const OmpModifierDescriptor &OmpGetDescriptor();
 #define DECLARE_DESCRIPTOR(name) \
   template <> const OmpModifierDescriptor &OmpGetDescriptor<name>()
 
+DECLARE_DESCRIPTOR(parser::OmpAccessGroup);
 DECLARE_DESCRIPTOR(parser::OmpAlignment);
 DECLARE_DESCRIPTOR(parser::OmpAlignModifier);
 DECLARE_DESCRIPTOR(parser::OmpAllocatorComplexModifier);
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 2b36b085ae08d..e83a3616d6965 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -471,6 +471,45 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Hint &x) {
   }
 }
 
+void OmpStructureChecker::Enter(const parser::OmpClause::DynGroupprivate &x) {
+  CheckAllowedClause(llvm::omp::Clause::OMPC_dyn_groupprivate);
+  parser::CharBlock source{GetContext().clauseSource};
+
+  OmpVerifyModifiers(x.v, llvm::omp::OMPC_dyn_groupprivate, source, context_);
+}
+
+void OmpStructureChecker::Enter(const parser::OmpClause::Grainsize &x) {
+  CheckAllowedClause(llvm::omp::Clause::OMPC_grainsize);
+  parser::CharBlock source{GetContext().clauseSource};
+
+  if (OmpVerifyModifiers(x.v, llvm::omp::OMPC_grainsize, source, context_)) {
+    auto &modifiers{OmpGetModifiers(x.v)};
+    for (auto *mod :
+        OmpGetRepeatableModifier<parser::OmpPrescriptiveness>(modifiers)) {
+      if (mod->v != parser::OmpPrescriptiveness::Value::Strict) {
+        context_.Say(OmpGetModifierSource(modifiers, mod),
+            "Only STRICT is allowed as prescriptiveness on this clause"_err_en_US);
+      }
+    }
+  }
+}
+
+void OmpStructureChecker::Enter(const parser::OmpClause::NumTasks &x) {
+  CheckAllowedClause(llvm::omp::Clause::OMPC_num_tasks);
+  parser::CharBlock source{GetContext().clauseSource};
+
+  if (OmpVerifyModifiers(x.v, llvm::omp::OMPC_num_tasks, source, context_)) {
+    auto &modifiers{OmpGetModifiers(x.v)};
+    for (auto *mod :
+        OmpGetRepeatableModifier<parser::OmpPrescriptiveness>(modifiers)) {
+      if (mod->v != parser::OmpPrescriptiveness::Value::Strict) {
+        context_.Say(OmpGetModifierSource(modifiers, mod),
+            "Only STRICT is allowed as prescriptiveness on this clause"_err_en_US);
+      }
+    }
+  }
+}
+
 void OmpStructureChecker::Enter(const parser::OmpDirectiveSpecification &x) {
   // OmpDirectiveSpecification exists on its own only in METADIRECTIVE.
   // In other cases it's a part of other constructs that handle directive
@@ -2542,6 +2581,32 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
     }
   }
 
+  // Default access-group for DYN_GROUPPRIVATE is "cgroup". On a given
+  // construct there can be at most one DYN_GROUPPRIVATE with a given
+  // access-group.
+  const parser::OmpClause
+      *accGrpClause[parser::OmpAccessGroup::Value_enumSize] = {nullptr};
+  for (auto [_, clause] :
+      FindClauses(llvm::omp::Clause::OMPC_dyn_groupprivate)) {
+    auto &wrapper{std::get<parser::OmpClause::DynGroupprivate>(clause->u)};
+    auto &modifiers{OmpGetModifiers(wrapper.v)};
+    auto accGrp{parser::OmpAccessGroup::Value::Cgroup};
+    if (auto *ag{OmpGetUniqueModifier<parser::OmpAccessGroup>(modifiers)}) {
+      accGrp = ag->v;
+    }
+    auto &firstClause{accGrpClause[llvm::to_underlying(accGrp)]};
+    if (firstClause) {
+      context_
+          .Say(clause->source,
+              "The access-group modifier can only occur on a single clause in a construct"_err_en_US)
+          .Attach(firstClause->source,
+              "Previous clause with access-group modifier"_en_US);
+      break;
+    } else {
+      firstClause = clause;
+    }
+  }
+
   CheckRequireAtLeastOneOf();
 }
 
@@ -2593,18 +2658,15 @@ CHECK_SIMPLE_CLAUSE(Default, OMPC_default)
 CHECK_SIMPLE_CLAUSE(Depobj, OMPC_depobj)
 CHECK_SIMPLE_CLAUSE(DeviceType, OMPC_device_type)
 CHECK_SIMPLE_CLAUSE(DistSchedule, OMPC_dist_schedule)
-CHECK_SIMPLE_CLAUSE(DynGroupprivate, OMPC_dyn_groupprivate)
 CHECK_SIMPLE_CLAUSE(Exclusive, OMPC_exclusive)
 CHECK_SIMPLE_CLAUSE(Final, OMPC_final)
 CHECK_SIMPLE_CLAUSE(Flush, OMPC_flush)
 CHECK_SIMPLE_CLAUSE(Full, OMPC_full)
-CHECK_SIMPLE_CLAUSE(Grainsize, OMPC_grainsize)
 CHECK_SIMPLE_CLAUSE(Holds, OMPC_holds)
 CHECK_SIMPLE_CLAUSE(Inclusive, OMPC_inclusive)
 CHECK_SIMPLE_CLAUSE(Initializer, OMPC_initializer)
 CHECK_SIMPLE_CLAUSE(Match, OMPC_match)
 CHECK_SIMPLE_CLAUSE(Nontemporal, OMPC_nontemporal)
-CHECK_SIMPLE_CLAUSE(NumTasks, OMPC_num_tasks)
 CHECK_SIMPLE_CLAUSE(Order, OMPC_order)
 CHECK_SIMPLE_CLAUSE(Read, OMPC_read)
 CHECK_SIMPLE_CLAUSE(Threadprivate, OMPC_threadprivate)
diff --git a/flang/lib/Semantics/openmp-modifiers.cpp b/flang/lib/Semantics/openmp-modifiers.cpp
index af4000c4934ea..7476544177732 100644
--- a/flang/lib/Semantics/openmp-modifiers.cpp
+++ b/flang/lib/Semantics/openmp-modifiers.cpp
@@ -74,6 +74,22 @@ unsigned OmpModifierDescriptor::since(llvm::omp::Clause id) const {
 // Note: The intent for these functions is to have them be automatically-
 // generated in the future.
 
+template <>
+const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAccessGroup>() {
+  static const OmpModifierDescriptor desc{
+      /*name=*/"access-group",
+      /*props=*/
+      {
+          {61, {OmpProperty::Unique}},
+      },
+      /*clauses=*/
+      {
+          {61, {Clause::OMPC_dyn_groupprivate}},
+      },
+  };
+  return desc;
+}
+
 template <>
 const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAlignment>() {
   static const OmpModifierDescriptor desc{
@@ -482,6 +498,9 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpPrescriptiveness>() {
       /*clauses=*/
       {
           {51, {Clause::OMPC_grainsize, Clause::OMPC_num_tasks}},
+          {61,
+              {Clause::OMPC_dyn_groupprivate, Clause::OMPC_grainsize,
+                  Clause::OMPC_num_tasks}},
       },
   };
   return desc;
diff --git a/flang/test/Semantics/OpenMP/prescriptiveness-modifier.f90 b/flang/test/Semantics/OpenMP/prescriptiveness-modifier.f90
new file mode 100644
index 0000000000000..8702d559b9de9
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/prescriptiveness-modifier.f90
@@ -0,0 +1,47 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=61
+
+subroutine f00(x)
+  integer :: x, i
+  !No diagnostic expected
+  !$omp taskloop grainsize(strict: x)
+  do i = 1, 10
+  enddo
+end
+
+subroutine f01(x)
+  integer :: x, i
+  !ERROR: Only STRICT is allowed as prescriptiveness on this clause
+  !$omp taskloop grainsize(fallback: x)
+  do i = 1, 10
+  enddo
+end
+
+subroutine f02(x)
+  integer :: x, i
+  !No diagnostic expected
+  !$omp taskloop num_tasks(strict: x)
+  do i = 1, 10
+  enddo
+end
+
+subroutine f03(x)
+  integer :: x, i
+  !ERROR: Only STRICT is allowed as prescriptiveness on this clause
+  !$omp taskloop num_tasks(fallback: x)
+  do i = 1, 10
+  enddo
+end
+
+subroutine f04(x)
+  integer :: x
+  !No diagnostic expected
+  !$omp target dyn_groupprivate(strict: x)
+  !$omp end target
+end
+
+subroutine f05(x)
+  integer :: x
+  !No diagnostic expected
+  !$omp target dyn_groupprivate(fallback: x)
+  !$omp end target
+end

``````````

</details>


https://github.com/llvm/llvm-project/pull/154550


More information about the llvm-branch-commits mailing list