[flang] [llvm] [flang][OpenMP] Frontend support for DIMS modifier (PR #171454)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 9 07:11:03 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Krzysztof Parzyszek (kparzysz)
<details>
<summary>Changes</summary>
Add parsing and semantic checks for DIMS modifier on NUM_TEAMS, NUM_THREADS, and THREAD_LIMIT.
---
Patch is 25.10 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/171454.diff
12 Files Affected:
- (modified) flang/include/flang/Parser/dump-parse-tree.h (+8)
- (modified) flang/include/flang/Parser/parse-tree.h (+51)
- (modified) flang/include/flang/Semantics/openmp-modifiers.h (+2)
- (modified) flang/lib/Lower/OpenMP/Clauses.cpp (+12-6)
- (modified) flang/lib/Parser/openmp-parsers.cpp (+30-3)
- (modified) flang/lib/Parser/unparse.cpp (+21)
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+76-3)
- (modified) flang/lib/Semantics/check-omp-structure.h (+2)
- (modified) flang/lib/Semantics/openmp-modifiers.cpp (+34)
- (added) flang/test/Parser/OpenMP/dims-modifier.f90 (+93)
- (added) flang/test/Semantics/OpenMP/dims-modifier.f90 (+26)
- (modified) llvm/include/llvm/Frontend/OpenMP/OMP.td (+3-3)
``````````diff
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 58fa48e9f04c3..d0d62e570cba3 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -587,6 +587,7 @@ class ParseTreeDumper {
NODE(parser, OmpDeviceSafesyncClause)
NODE(parser, OmpDeviceTypeClause)
NODE_ENUM(OmpDeviceTypeClause, DeviceTypeDescription)
+ NODE(parser, OmpDimsModifier)
NODE(parser, OmpDirectiveName)
NODE(parser, OmpDirectiveSpecification)
NODE_ENUM(OmpDirectiveSpecification, Flag)
@@ -646,6 +647,7 @@ class ParseTreeDumper {
NODE(parser, OmpLocator)
NODE(parser, OmpLocatorList)
NODE(parser, OmpLooprangeClause)
+ NODE(parser, OmpLowerBound)
NODE(parser, OmpMapClause)
NODE(OmpMapClause, Modifier)
NODE(parser, OmpMapper)
@@ -662,6 +664,10 @@ class ParseTreeDumper {
NODE(parser, OmpNoParallelismClause)
NODE(parser, OmpNothingDirective)
NODE(parser, OmpNumTasksClause)
+ NODE(parser, OmpNumTeamsClause)
+ NODE(OmpNumTeamsClause, Modifier)
+ NODE(parser, OmpNumThreadsClause)
+ NODE(OmpNumThreadsClause, Modifier)
NODE(OmpNumTasksClause, Modifier)
NODE(parser, OmpObject)
NODE(OmpObject, Invalid)
@@ -709,6 +715,8 @@ class ParseTreeDumper {
NODE_ENUM(OmpTaskDependenceType, Value)
NODE(parser, OmpTaskReductionClause)
NODE(OmpTaskReductionClause, Modifier)
+ NODE(parser, OmpThreadLimitClause)
+ NODE(OmpThreadLimitClause, Modifier)
NODE(parser, OmpThreadsetClause)
NODE_ENUM(OmpThreadsetClause, ThreadsetPolicy)
NODE(parser, OmpToClause)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index c4ace2d8a2135..ff3f900f122dc 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3979,6 +3979,14 @@ struct OmpDeviceModifier {
WRAPPER_CLASS_BOILERPLATE(OmpDeviceModifier, Value);
};
+// Ref: TODO
+//
+// dims-modifier ->
+// constant integer expression // since 6.1
+struct OmpDimsModifier {
+ WRAPPER_CLASS_BOILERPLATE(OmpDimsModifier, ScalarIntConstantExpr);
+};
+
// Ref: [5.2:72-73,230-323], in 4.5-5.1 it's scattered over individual
// directives that allow the IF clause.
//
@@ -4089,6 +4097,14 @@ struct OmpLinearModifier {
WRAPPER_CLASS_BOILERPLATE(OmpLinearModifier, Value);
};
+// Ref: [5.1:100-104], [5.2:277], [6.0:452-453]
+//
+// lower-bound ->
+// scalar-integer-expression // since 5.1
+struct OmpLowerBound {
+ WRAPPER_CLASS_BOILERPLATE(OmpLowerBound, ScalarIntExpr);
+};
+
// Ref: [5.0:176-180], [5.1:205-210], [5.2:149-150]
//
// mapper ->
@@ -4750,6 +4766,30 @@ struct OmpNumTasksClause {
std::tuple<MODIFIERS(), ScalarIntExpr> t;
};
+// Ref: [4.5:114-116], [5.0:82-85], [5.1:100-104], [5.2:277], [6.0:452-453]
+//
+// num-teams-clause ->
+// NUM_TEAMS(expr) | // since 4.5
+// NUM_TEAMS([lower-bound:] upper-bound) | // since 5.1
+// NUM_TEAMS([dims: upper-bound...) // since 6.1
+struct OmpNumTeamsClause {
+ TUPLE_CLASS_BOILERPLATE(OmpNumTeamsClause);
+ MODIFIER_BOILERPLATE(OmpDimsModifier, OmpLowerBound);
+ std::tuple<MODIFIERS(), std::list<ScalarIntExpr>> t;
+};
+
+// Ref: [4.5:46-50], [5.0:74-78], [5.1:92-96], [5.2:227], [6.0:388-389]
+//
+// num-threads-clause
+// NUM_THREADS(expr) | // since 4.5
+// NUM_THREADS(expr...) | // since 6.0
+// NUM_THREADS([dims-modifier:] expr...) // since 6.1
+struct OmpNumThreadsClause {
+ TUPLE_CLASS_BOILERPLATE(OmpNumThreadsClause);
+ MODIFIER_BOILERPLATE(OmpDimsModifier);
+ std::tuple<MODIFIERS(), std::list<ScalarIntExpr>> t;
+};
+
// Ref: [5.0:101-109], [5.1:126-134], [5.2:233-234]
//
// order-clause ->
@@ -4855,6 +4895,17 @@ struct OmpTaskReductionClause {
std::tuple<MODIFIERS(), OmpObjectList> t;
};
+// Ref: [4.5:114-116], [5.0:82-85], [5.1:100-104], [5.2:277], [6.0:452-453]
+//
+// thread-limit-clause ->
+// THREAD_LIMIT(threadlim) // since 4.5
+// THREAD_LIMIT([dims-modifier:] threadlim...) // since 6.1
+struct OmpThreadLimitClause {
+ TUPLE_CLASS_BOILERPLATE(OmpThreadLimitClause);
+ MODIFIER_BOILERPLATE(OmpDimsModifier);
+ std::tuple<MODIFIERS(), std::list<ScalarIntExpr>> t;
+};
+
// Ref: [6.0:442]
// threadset-clause ->
// THREADSET(omp_pool|omp_team)
diff --git a/flang/include/flang/Semantics/openmp-modifiers.h b/flang/include/flang/Semantics/openmp-modifiers.h
index 283bf2a4c895e..7d228ae024cdd 100644
--- a/flang/include/flang/Semantics/openmp-modifiers.h
+++ b/flang/include/flang/Semantics/openmp-modifiers.h
@@ -81,6 +81,7 @@ DECLARE_DESCRIPTOR(parser::OmpContextSelector);
DECLARE_DESCRIPTOR(parser::OmpDeleteModifier);
DECLARE_DESCRIPTOR(parser::OmpDependenceType);
DECLARE_DESCRIPTOR(parser::OmpDeviceModifier);
+DECLARE_DESCRIPTOR(parser::OmpDimsModifier);
DECLARE_DESCRIPTOR(parser::OmpDirectiveNameModifier);
DECLARE_DESCRIPTOR(parser::OmpExpectation);
DECLARE_DESCRIPTOR(parser::OmpFallbackModifier);
@@ -89,6 +90,7 @@ DECLARE_DESCRIPTOR(parser::OmpInteropType);
DECLARE_DESCRIPTOR(parser::OmpIterator);
DECLARE_DESCRIPTOR(parser::OmpLastprivateModifier);
DECLARE_DESCRIPTOR(parser::OmpLinearModifier);
+DECLARE_DESCRIPTOR(parser::OmpLowerBound);
DECLARE_DESCRIPTOR(parser::OmpMapper);
DECLARE_DESCRIPTOR(parser::OmpMapType);
DECLARE_DESCRIPTOR(parser::OmpMapTypeModifier);
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index 61430fceafe2a..e7849947ae279 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -1251,16 +1251,20 @@ NumTasks make(const parser::OmpClause::NumTasks &inp,
NumTeams make(const parser::OmpClause::NumTeams &inp,
semantics::SemanticsContext &semaCtx) {
- // inp.v -> parser::ScalarIntExpr
+ // inp.v -> parser::OmpNumTeamsClause
+ auto &t1 = std::get<std::list<parser::ScalarIntExpr>>(inp.v.t);
+ assert(!t1.empty());
List<NumTeams::Range> v{{{/*LowerBound=*/std::nullopt,
- /*UpperBound=*/makeExpr(inp.v, semaCtx)}}};
+ /*UpperBound=*/makeExpr(t1.front(), semaCtx)}}};
return NumTeams{/*List=*/v};
}
NumThreads make(const parser::OmpClause::NumThreads &inp,
semantics::SemanticsContext &semaCtx) {
- // inp.v -> parser::ScalarIntExpr
- return NumThreads{/*Nthreads=*/makeExpr(inp.v, semaCtx)};
+ // inp.v -> parser::OmpNumThreadsClause
+ auto &t1 = std::get<std::list<parser::ScalarIntExpr>>(inp.v.t);
+ assert(!t1.empty());
+ return NumThreads{/*Nthreads=*/makeExpr(t1.front(), semaCtx)};
}
// OmpxAttribute: empty
@@ -1502,8 +1506,10 @@ TaskReduction make(const parser::OmpClause::TaskReduction &inp,
ThreadLimit make(const parser::OmpClause::ThreadLimit &inp,
semantics::SemanticsContext &semaCtx) {
- // inp.v -> parser::ScalarIntExpr
- return ThreadLimit{/*Threadlim=*/makeExpr(inp.v, semaCtx)};
+ // inp.v -> parser::OmpThreadLimitClause
+ auto &t1 = std::get<std::list<parser::ScalarIntExpr>>(inp.v.t);
+ assert(!t1.empty());
+ return ThreadLimit{/*Threadlim=*/makeExpr(t1.front(), semaCtx)};
}
Threadset make(const parser::OmpClause::Threadset &inp,
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 6b3bcd00c5bec..31a8eb52e42f8 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -817,6 +817,9 @@ TYPE_PARSER(construct<OmpDeviceModifier>(
"ANCESTOR" >> pure(OmpDeviceModifier::Value::Ancestor) ||
"DEVICE_NUM" >> pure(OmpDeviceModifier::Value::Device_Num)))
+TYPE_PARSER(construct<OmpDimsModifier>( //
+ "DIMS" >> parenthesized(scalarIntConstantExpr)))
+
TYPE_PARSER(construct<OmpDirectiveNameModifier>(OmpDirectiveNameParser{}))
TYPE_PARSER(construct<OmpExpectation>( //
@@ -871,6 +874,8 @@ TYPE_PARSER(construct<OmpLinearModifier>( //
"VAL" >> pure(OmpLinearModifier::Value::Val) ||
"UVAL" >> pure(OmpLinearModifier::Value::Uval)))
+TYPE_PARSER(construct<OmpLowerBound>(scalarIntExpr))
+
TYPE_PARSER(construct<OmpMapper>( //
"MAPPER"_tok >> parenthesized(Parser<ObjectName>{})))
@@ -1015,6 +1020,13 @@ TYPE_PARSER(
TYPE_PARSER(sourced(
construct<OmpNumTasksClause::Modifier>(Parser<OmpPrescriptiveness>{})))
+TYPE_PARSER(sourced( //
+ construct<OmpNumTeamsClause::Modifier>(Parser<OmpDimsModifier>{}) ||
+ construct<OmpNumTeamsClause::Modifier>(Parser<OmpLowerBound>{})))
+
+TYPE_PARSER(sourced(
+ construct<OmpNumThreadsClause::Modifier>(Parser<OmpDimsModifier>{})))
+
TYPE_PARSER(sourced(construct<OmpReductionClause::Modifier>(sourced(
construct<OmpReductionClause::Modifier>(Parser<OmpReductionModifier>{}) ||
construct<OmpReductionClause::Modifier>(
@@ -1027,6 +1039,9 @@ TYPE_PARSER(sourced(construct<OmpScheduleClause::Modifier>(sourced(
TYPE_PARSER(sourced(construct<OmpTaskReductionClause::Modifier>(
Parser<OmpReductionIdentifier>{})))
+TYPE_PARSER(sourced(
+ construct<OmpThreadLimitClause::Modifier>(Parser<OmpDimsModifier>{})))
+
TYPE_PARSER(sourced(construct<OmpToClause::Modifier>(
sourced(construct<OmpToClause::Modifier>(Parser<OmpExpectation>{}) ||
construct<OmpToClause::Modifier>(Parser<OmpMapper>{}) ||
@@ -1197,6 +1212,10 @@ TYPE_PARSER(construct<OmpTaskReductionClause>(
maybe(nonemptyList(Parser<OmpTaskReductionClause::Modifier>{}) / ":"),
Parser<OmpObjectList>{}))
+TYPE_PARSER(construct<OmpThreadLimitClause>(
+ maybe(nonemptyList(Parser<OmpThreadLimitClause::Modifier>{}) / ":"),
+ nonemptyList(scalarIntExpr)))
+
TYPE_PARSER(construct<OmpTransparentClause>(scalarIntExpr))
TYPE_PARSER(construct<OmpThreadsetClause>(
@@ -1328,6 +1347,14 @@ TYPE_PARSER(construct<OmpNumTasksClause>(
maybe(nonemptyList(Parser<OmpNumTasksClause::Modifier>{}) / ":"),
scalarIntExpr))
+TYPE_PARSER(construct<OmpNumTeamsClause>(
+ maybe(nonemptyList(Parser<OmpNumTeamsClause::Modifier>{}) / ":"),
+ nonemptyList(scalarIntExpr)))
+
+TYPE_PARSER(construct<OmpNumThreadsClause>(
+ maybe(nonemptyList(Parser<OmpNumThreadsClause::Modifier>{}) / ":"),
+ nonemptyList(scalarIntExpr)))
+
TYPE_PARSER( //
construct<OmpObject>(designator) ||
"/" >> construct<OmpObject>(name) / "/" ||
@@ -1501,9 +1528,9 @@ TYPE_PARSER( //
"NUM_TASKS" >> construct<OmpClause>(construct<OmpClause::NumTasks>(
parenthesized(Parser<OmpNumTasksClause>{}))) ||
"NUM_TEAMS" >> construct<OmpClause>(construct<OmpClause::NumTeams>(
- parenthesized(scalarIntExpr))) ||
+ parenthesized(Parser<OmpNumTeamsClause>{}))) ||
"NUM_THREADS" >> construct<OmpClause>(construct<OmpClause::NumThreads>(
- parenthesized(scalarIntExpr))) ||
+ parenthesized(Parser<OmpNumThreadsClause>{}))) ||
"OMPX_BARE" >> construct<OmpClause>(construct<OmpClause::OmpxBare>()) ||
"ORDER" >> construct<OmpClause>(construct<OmpClause::Order>(
parenthesized(Parser<OmpOrderClause>{}))) ||
@@ -1558,7 +1585,7 @@ TYPE_PARSER( //
"THREADSET" >> construct<OmpClause>(construct<OmpClause::Threadset>(
parenthesized(Parser<OmpThreadsetClause>{}))) ||
"THREAD_LIMIT" >> construct<OmpClause>(construct<OmpClause::ThreadLimit>(
- parenthesized(scalarIntExpr))) ||
+ parenthesized(Parser<OmpThreadLimitClause>{}))) ||
"TO" >> construct<OmpClause>(construct<OmpClause::To>(
parenthesized(Parser<OmpToClause>{}))) ||
"TRANSPARENT" >>
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index f90e32975132d..4b49f0eee6c0b 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2225,6 +2225,12 @@ class UnparseVisitor {
unsigned ompVersion{langOpts_.OpenMPVersion};
Word(llvm::omp::getOpenMPDirectiveName(x.v, ompVersion));
}
+ void Unparse(const OmpDimsModifier &x) {
+ Word("DIMS");
+ Put("(");
+ Walk(x.v);
+ Put(")");
+ }
void Unparse(const OmpStylizedDeclaration &x) {
// empty
}
@@ -2448,6 +2454,21 @@ class UnparseVisitor {
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
Walk(std::get<ScalarIntExpr>(x.t));
}
+ void Unparse(const OmpNumTeamsClause &x) {
+ using Modifier = OmpNumTeamsClause::Modifier;
+ Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ":");
+ Walk(std::get<std::list<ScalarIntExpr>>(x.t));
+ }
+ void Unparse(const OmpNumThreadsClause &x) {
+ using Modifier = OmpNumThreadsClause::Modifier;
+ Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ":");
+ Walk(std::get<std::list<ScalarIntExpr>>(x.t));
+ }
+ void Unparse(const OmpThreadLimitClause &x) {
+ using Modifier = OmpThreadLimitClause::Modifier;
+ Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ":");
+ Walk(std::get<std::list<ScalarIntExpr>>(x.t));
+ }
void Unparse(const OmpDoacross::Sink &x) {
Word("SINK: ");
Walk(x.v.v);
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index b6b0f86eb4cce..360934527bc1c 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -5363,6 +5363,82 @@ void OmpStructureChecker::Enter(const parser::OmpClause::SelfMaps &x) {
CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_self_maps);
}
+void OmpStructureChecker::CheckDimsModifier(parser::CharBlock source,
+ size_t numValues, const parser::OmpDimsModifier &x) {
+ std::string name{OmpGetDescriptor<parser::OmpDimsModifier>().name.str()};
+
+ if (auto dimsVal{GetIntValue(x.v)}) {
+ if (*dimsVal > 0) {
+ if (static_cast<size_t>(*dimsVal) < numValues) {
+ context_.Say(source,
+ "The %s specifies %d dimensions but %zu values were provided"_err_en_US,
+ name, *dimsVal, numValues);
+ }
+ } else {
+ context_.Say(
+ source, "The argument to the %s should be positive"_err_en_US, name);
+ }
+ }
+ // The non-constant expression case is diagnosed elsewhere.
+}
+
+void OmpStructureChecker::Enter(const parser::OmpClause::NumTeams &x) {
+ constexpr auto clauseId{llvm::omp::Clause::OMPC_num_teams};
+ CheckAllowedClause(clauseId);
+ parser::CharBlock source{GetContext().clauseSource};
+ auto &values{std::get<std::list<parser::ScalarIntExpr>>(x.v.t)};
+
+ if (OmpVerifyModifiers(x.v, clauseId, source, context_)) {
+ auto &modifiers{OmpGetModifiers(x.v)};
+ if (auto *dims{OmpGetUniqueModifier<parser::OmpDimsModifier>(modifiers)}) {
+ CheckDimsModifier(
+ OmpGetModifierSource(modifiers, dims), values.size(), *dims);
+ }
+ }
+
+ for (auto &val : values) {
+ RequiresPositiveParameter(clauseId, val);
+ }
+}
+
+void OmpStructureChecker::Enter(const parser::OmpClause::NumThreads &x) {
+ constexpr auto clauseId{llvm::omp::Clause::OMPC_num_threads};
+ CheckAllowedClause(clauseId);
+ parser::CharBlock source{GetContext().clauseSource};
+ auto &values{std::get<std::list<parser::ScalarIntExpr>>(x.v.t)};
+
+ if (OmpVerifyModifiers(x.v, clauseId, source, context_)) {
+ auto &modifiers{OmpGetModifiers(x.v)};
+ if (auto *dims{OmpGetUniqueModifier<parser::OmpDimsModifier>(modifiers)}) {
+ CheckDimsModifier(
+ OmpGetModifierSource(modifiers, dims), values.size(), *dims);
+ }
+ }
+
+ for (auto &val : values) {
+ RequiresPositiveParameter(clauseId, val);
+ }
+}
+
+void OmpStructureChecker::Enter(const parser::OmpClause::ThreadLimit &x) {
+ constexpr auto clauseId{llvm::omp::Clause::OMPC_thread_limit};
+ CheckAllowedClause(clauseId);
+ parser::CharBlock source{GetContext().clauseSource};
+ auto &values{std::get<std::list<parser::ScalarIntExpr>>(x.v.t)};
+
+ if (OmpVerifyModifiers(x.v, clauseId, source, context_)) {
+ auto &modifiers{OmpGetModifiers(x.v)};
+ if (auto *dims{OmpGetUniqueModifier<parser::OmpDimsModifier>(modifiers)}) {
+ CheckDimsModifier(
+ OmpGetModifierSource(modifiers, dims), values.size(), *dims);
+ }
+ }
+
+ for (auto &val : values) {
+ RequiresPositiveParameter(clauseId, val);
+ }
+}
+
void OmpStructureChecker::Enter(const parser::OpenMPInteropConstruct &x) {
bool isDependClauseOccured{false};
int targetCount{0}, targetSyncCount{0};
@@ -5569,11 +5645,8 @@ CHECK_SIMPLE_CLAUSE(UsesAllocators, OMPC_uses_allocators)
CHECK_SIMPLE_CLAUSE(Weak, OMPC_weak)
CHECK_SIMPLE_CLAUSE(Write, OMPC_write)
-CHECK_REQ_SCALAR_INT_CLAUSE(NumTeams, OMPC_num_teams)
-CHECK_REQ_SCALAR_INT_CLAUSE(NumThreads, OMPC_num_threads)
CHECK_REQ_SCALAR_INT_CLAUSE(OmpxDynCgroupMem, OMPC_ompx_dyn_cgroup_mem)
CHECK_REQ_SCALAR_INT_CLAUSE(Priority, OMPC_priority)
-CHECK_REQ_SCALAR_INT_CLAUSE(ThreadLimit, OMPC_thread_limit)
CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Collapse, OMPC_collapse)
CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Safelen, OMPC_safelen)
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 5bd5ae050be64..d9a860490b4aa 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -241,6 +241,8 @@ class OmpStructureChecker : public OmpStructureCheckerBase {
void CheckDependArraySection(
const common::Indirection<parser::ArrayElement> &, const parser::Name &);
void CheckDoacross(const parser::OmpDoacross &doa);
+ void CheckDimsModifier(parser::CharBlock source, size_t numValues,
+ const parser::OmpDimsModifier &x);
bool IsDataRefTypeParamInquiry(const parser::DataRef *dataRef);
void CheckVarIsNotPartOfAnotherVar(const parser::CharBlock &source,
const parser::OmpObject &obj, llvm::StringRef clause = "");
diff --git a/flang/lib/Semantics/openmp-modifiers.cpp b/flang/lib/Semantics/openmp-modifiers.cpp
index f191b4de2d579..bed74e0018b28 100644
--- a/flang/lib/Semantics/openmp-modifiers.cpp
+++ b/flang/lib/Semantics/openmp-modifiers.cpp
@@ -288,6 +288,24 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpDependenceType>() {
return desc;
}
+template <>
+const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpDimsModifier>() {
+ static const OmpModifierDescriptor desc{
+ /*name=*/"dims-modifier",
+ /*props=*/
+ {
+ {61, {OmpProperty::Unique}},
+ },
+ /*clauses=*/
+ {
+ {61,
+ {Clause::OMPC_num_teams, Clause::OMPC_num_threads,
+ Clause::OMPC_thread_limit}},
+ },
+ };
+ return desc;
+}
+
template <>
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpDeviceModifier>() {
static const OmpModifierDescriptor desc{
@@ -437,6 +455,22 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpLinearModifier>() {
return desc;
}
+template <>
+const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpLowerBound>() {
+ static const OmpModifierDescriptor desc{
+ /*name=*/"lower-bound",
+ /*props=*/
+ {
+ {51, {OmpProperty::Unique, OmpProperty::Ultimate}},
+ },
+ /*clauses=*/
+ {
+ {51, {Clause::OMPC_num_teams}},
+ },
+ };
+ return desc;
+}
+
template <> //
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpMapper>() {
static const OmpModifierDescriptor desc{
diff --git a/flang/test/Parser/OpenMP/dims-modifier.f90 b/flang/test/Parser/OpenMP/dims-modifier.f90
new file mode 100644
index 0000000000000..28dc1b5965903
--- /dev/null
+++ b/flang/test/Parser/OpenMP/dims-modifier.f90
@@ -0,0 +1,93 @@
+!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=61 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
+!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=61 %s | FileCheck --check-prefix="PARSE-TREE" %s
+
+subroutine f00
+ !$omp teams num_teams(dims(2): 10, 4)
+ !$omp end teams
+end
+
+!UNPARSE: SUBROUTINE f00
+!UNPARSE: !$OMP TEAMS NUM_TEAMS(DIMS(2_4):10_4, 4_4)
+!UNPARSE: !$OMP END TEAMS
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: OmpBeginDirective
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = teams
+!PARSE-TREE: | OmpClauseList -> OmpClause -> NumTeams -> OmpNumTeamsClause
+!PARSE-TREE: | | Modifier -> OmpDimsModifier -> Scalar -> Integer -> Constant -> Expr = '2_4'
+!PARSE-TREE: | | | LiteralConstant -> IntLiteralConstant = '2...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/171454
More information about the llvm-commits
mailing list