[llvm-branch-commits] [flang] [flang][OpenMP] Semantic checks for DYN_GROUPPRIVATE (PR #154550)
Krzysztof Parzyszek via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Aug 20 07:33:40 PDT 2025
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.Parzyszek at 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
More information about the llvm-branch-commits
mailing list