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

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).

>From e00ef602a8fb143d963ec2ec4264f96544929a34 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <krzysztof.parzys...@amd.com>
Date: Thu, 14 Aug 2025 13:26:23 -0500
Subject: [PATCH] [flang][OpenMP] Semantic checks for DYN_GROUPPRIVATE

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).
---
 .../flang/Semantics/openmp-modifiers.h        |  1 +
 flang/lib/Semantics/check-omp-structure.cpp   | 68 ++++++++++++++++++-
 flang/lib/Semantics/openmp-modifiers.cpp      | 19 ++++++
 .../OpenMP/prescriptiveness-modifier.f90      | 47 +++++++++++++
 4 files changed, 132 insertions(+), 3 deletions(-)
 create mode 100644 flang/test/Semantics/OpenMP/prescriptiveness-modifier.f90

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

_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to