https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/118128
>From cfcf8d1e7ffdcec92dc0dfffccb3c620a2df804f Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek <krzysztof.parzys...@amd.com> Date: Wed, 27 Nov 2024 08:34:33 -0600 Subject: [PATCH 1/2] [flang][OpenMP] Use new modifiers in IF/LASTPRIVATE The usual changes, added more references to OpenMP specs. --- flang/examples/FeatureList/FeatureList.cpp | 3 +- .../FlangOmpReport/FlangOmpReportVisitor.cpp | 5 +- .../FlangOmpReport/FlangOmpReportVisitor.h | 2 +- flang/include/flang/Parser/dump-parse-tree.h | 7 +- flang/include/flang/Parser/parse-tree.h | 50 ++++++-- .../flang/Semantics/openmp-modifiers.h | 2 + flang/lib/Lower/OpenMP/Clauses.cpp | 36 ++---- flang/lib/Parser/CMakeLists.txt | 1 + flang/lib/Parser/openmp-parsers.cpp | 73 ++++++++--- flang/lib/Parser/unparse.cpp | 15 ++- flang/lib/Semantics/check-omp-structure.cpp | 121 +++++++++++------- flang/lib/Semantics/openmp-modifiers.cpp | 34 +++++ .../test/Parser/OpenMP/if-clause-unparse.f90 | 20 +-- flang/test/Parser/OpenMP/if-clause.f90 | 22 ++-- .../test/Parser/OpenMP/lastprivate-clause.f90 | 4 +- .../Semantics/OpenMP/clause-validity01.f90 | 4 +- flang/test/Semantics/OpenMP/if-clause.f90 | 64 ++++----- 17 files changed, 297 insertions(+), 166 deletions(-) diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp index c5cb8c8fdf40bb..41a6255207976d 100644 --- a/flang/examples/FeatureList/FeatureList.cpp +++ b/flang/examples/FeatureList/FeatureList.cpp @@ -492,7 +492,8 @@ struct NodeVisitor { READ_FEATURE(OmpPrescriptiveness) READ_FEATURE(OmpPrescriptiveness::Value) READ_FEATURE(OmpIfClause) - READ_FEATURE(OmpIfClause::DirectiveNameModifier) + READ_FEATURE(OmpIfClause::Modifier) + READ_FEATURE(OmpDirectiveNameModifier) READ_FEATURE(OmpLinearClause) READ_FEATURE(OmpLinearClause::WithModifier) READ_FEATURE(OmpLinearClause::WithoutModifier) diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp index afabd564ad5bdc..2dc480f0c901b1 100644 --- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp +++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp @@ -8,6 +8,7 @@ #include "FlangOmpReportVisitor.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Frontend/OpenMP/OMP.h" namespace Fortran { namespace parser { @@ -238,9 +239,9 @@ void OpenMPCounterVisitor::Post(const OmpScheduleClause::Kind &c) { clauseDetails += "type=" + std::string{OmpScheduleClause::EnumToString(c)} + ";"; } -void OpenMPCounterVisitor::Post(const OmpIfClause::DirectiveNameModifier &c) { +void OpenMPCounterVisitor::Post(const OmpDirectiveNameModifier &c) { clauseDetails += - "name_modifier=" + std::string{OmpIfClause::EnumToString(c)} + ";"; + "name_modifier=" + llvm::omp::getOpenMPDirectiveName(c.v).str() + ";"; } void OpenMPCounterVisitor::Post(const OmpCancelType::Type &c) { clauseDetails += "type=" + std::string{OmpCancelType::EnumToString(c)} + ";"; diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h index ed202e8ed2a4c7..59bdac8594cb7c 100644 --- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h +++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h @@ -77,7 +77,7 @@ struct OpenMPCounterVisitor { void Post(const OmpTaskDependenceType::Value &c); void Post(const OmpMapType::Value &c); void Post(const OmpScheduleClause::Kind &c); - void Post(const OmpIfClause::DirectiveNameModifier &c); + void Post(const OmpDirectiveNameModifier &c); void Post(const OmpCancelType::Type &c); void Post(const OmpClause &c); void PostClauseCommon(const ClauseInfo &ci); diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 1ec38de29b85d6..b0b8d8d7ccc556 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -548,10 +548,13 @@ class ParseTreeDumper { NODE(OmpFromClause, Modifier) NODE(parser, OmpExpectation) NODE_ENUM(OmpExpectation, Value) + NODE(parser, OmpDirectiveNameModifier) NODE(parser, OmpIfClause) - NODE_ENUM(OmpIfClause, DirectiveNameModifier) - NODE_ENUM(OmpLastprivateClause, LastprivateModifier) + NODE(OmpIfClause, Modifier) NODE(parser, OmpLastprivateClause) + NODE(OmpLastprivateClause, Modifier) + NODE(parser, OmpLastprivateModifier) + NODE_ENUM(OmpLastprivateModifier, Value) NODE(parser, OmpLinearClause) NODE(OmpLinearClause, WithModifier) NODE(OmpLinearClause, WithoutModifier) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index c00560b1f1726a..06c32831d2c60c 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3543,6 +3543,23 @@ struct OmpDeviceModifier { WRAPPER_CLASS_BOILERPLATE(OmpDeviceModifier, Value); }; +// Ref: [5.2:72-73,230-323], in 4.5-5.1 it's scattered over individual +// directives that allow the IF clause. +// +// directive-name-modifier -> +// PARALLEL | TARGET | TARGET DATA | +// TARGET ENTER DATA | TARGET EXIT DATA | +// TARGET UPDATE | TASK | TASKLOOP | // since 4.5 +// CANCEL[*] | SIMD | // since 5.0 +// TEAMS // since 5.2 +// +// [*] The IF clause is allowed on CANCEL in OpenMP 4.5, but only without +// the directive-name-modifier. For the sake of uniformity CANCEL can be +// considered a valid value in 4.5 as well. +struct OmpDirectiveNameModifier { + WRAPPER_CLASS_BOILERPLATE(OmpDirectiveNameModifier, llvm::omp::Directive); +}; + // Ref: [5.1:205-209], [5.2:166-168] // // motion-modifier -> @@ -3566,6 +3583,15 @@ struct OmpIterator { WRAPPER_CLASS_BOILERPLATE(OmpIterator, std::list<OmpIteratorSpecifier>); }; +// Ref: [5.0:288-290], [5.1:321-322], [5.2:115-117] +// +// lastprivate-modifier -> +// CONDITIONAL // since 5.0 +struct OmpLastprivateModifier { + ENUM_CLASS(Value, Conditional) + WRAPPER_CLASS_BOILERPLATE(OmpLastprivateModifier, Value); +}; + // Ref: [4.5:207-210], [5.0:290-293], [5.1:323-325], [5.2:117-120] // // linear-modifier -> @@ -3898,12 +3924,16 @@ struct OmpGrainsizeClause { std::tuple<MODIFIERS(), ScalarIntExpr> t; }; -// 2.12 if-clause -> IF ([ directive-name-modifier :] scalar-logical-expr) +// Ref: [5.2:72-73], in 4.5-5.1 it's scattered over individual directives +// that allow the IF clause. +// +// if-clause -> +// IF([directive-name-modifier:] +// scalar-logical-expression) // since 4.5 struct OmpIfClause { TUPLE_CLASS_BOILERPLATE(OmpIfClause); - ENUM_CLASS(DirectiveNameModifier, Parallel, Simd, Target, TargetData, - TargetEnterData, TargetExitData, TargetUpdate, Task, Taskloop, Teams) - std::tuple<std::optional<DirectiveNameModifier>, ScalarLogicalExpr> t; + MODIFIER_BOILERPLATE(OmpDirectiveNameModifier); + std::tuple<MODIFIERS(), ScalarLogicalExpr> t; }; // OMP 5.0 2.19.5.6 in_reduction-clause -> IN_REDUCTION (reduction-identifier: @@ -3913,13 +3943,15 @@ struct OmpInReductionClause { std::tuple<OmpReductionIdentifier, OmpObjectList> t; }; -// OMP 5.0 2.19.4.5 lastprivate-clause -> -// LASTPRIVATE ([lastprivate-modifier :] list) -// lastprivate-modifier -> CONDITIONAL +// Ref: [4.5:199-201], [5.0:288-290], [5.1:321-322], [5.2:115-117] +// +// lastprivate-clause -> +// LASTPRIVATE(list) | // since 4.5 +// LASTPRIVATE([lastprivate-modifier:] list) // since 5.0 struct OmpLastprivateClause { TUPLE_CLASS_BOILERPLATE(OmpLastprivateClause); - ENUM_CLASS(LastprivateModifier, Conditional); - std::tuple<std::optional<LastprivateModifier>, OmpObjectList> t; + MODIFIER_BOILERPLATE(OmpLastprivateModifier); + std::tuple<MODIFIERS(), OmpObjectList> t; }; // 2.15.3.7 linear-clause -> LINEAR (linear-list[ : linear-step]) diff --git a/flang/include/flang/Semantics/openmp-modifiers.h b/flang/include/flang/Semantics/openmp-modifiers.h index dbc554198df21f..4025ce112d9cab 100644 --- a/flang/include/flang/Semantics/openmp-modifiers.h +++ b/flang/include/flang/Semantics/openmp-modifiers.h @@ -74,8 +74,10 @@ DECLARE_DESCRIPTOR(parser::OmpAllocatorSimpleModifier); DECLARE_DESCRIPTOR(parser::OmpChunkModifier); DECLARE_DESCRIPTOR(parser::OmpDependenceType); DECLARE_DESCRIPTOR(parser::OmpDeviceModifier); +DECLARE_DESCRIPTOR(parser::OmpDirectiveNameModifier); DECLARE_DESCRIPTOR(parser::OmpExpectation); DECLARE_DESCRIPTOR(parser::OmpIterator); +DECLARE_DESCRIPTOR(parser::OmpLastprivateModifier); DECLARE_DESCRIPTOR(parser::OmpLinearModifier); DECLARE_DESCRIPTOR(parser::OmpMapper); DECLARE_DESCRIPTOR(parser::OmpMapType); diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp index ff2667983d4367..10c31963ec493a 100644 --- a/flang/lib/Lower/OpenMP/Clauses.cpp +++ b/flang/lib/Lower/OpenMP/Clauses.cpp @@ -825,27 +825,13 @@ Holds make(const parser::OmpClause::Holds &inp, If make(const parser::OmpClause::If &inp, semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpIfClause - using wrapped = parser::OmpIfClause; - - CLAUSET_ENUM_CONVERT( // - convert, wrapped::DirectiveNameModifier, llvm::omp::Directive, - // clang-format off - MS(Parallel, OMPD_parallel) - MS(Simd, OMPD_simd) - MS(Target, OMPD_target) - MS(TargetData, OMPD_target_data) - MS(TargetEnterData, OMPD_target_enter_data) - MS(TargetExitData, OMPD_target_exit_data) - MS(TargetUpdate, OMPD_target_update) - MS(Task, OMPD_task) - MS(Taskloop, OMPD_taskloop) - MS(Teams, OMPD_teams) - // clang-format on - ); - auto &t0 = std::get<std::optional<wrapped::DirectiveNameModifier>>(inp.v.t); + auto &mods = semantics::OmpGetModifiers(inp.v); + auto *m0 = + semantics::OmpGetUniqueModifier<parser::OmpDirectiveNameModifier>(mods); auto &t1 = std::get<parser::ScalarLogicalExpr>(inp.v.t); - return If{{/*DirectiveNameModifier=*/maybeApply(convert, t0), - /*IfExpression=*/makeExpr(t1, semaCtx)}}; + return If{ + {/*DirectiveNameModifier=*/maybeApplyToV([](auto &&s) { return s; }, m0), + /*IfExpression=*/makeExpr(t1, semaCtx)}}; } // Inbranch: empty @@ -889,20 +875,20 @@ IsDevicePtr make(const parser::OmpClause::IsDevicePtr &inp, Lastprivate make(const parser::OmpClause::Lastprivate &inp, semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpLastprivateClause - using wrapped = parser::OmpLastprivateClause; - CLAUSET_ENUM_CONVERT( // - convert, parser::OmpLastprivateClause::LastprivateModifier, + convert, parser::OmpLastprivateModifier::Value, Lastprivate::LastprivateModifier, // clang-format off MS(Conditional, Conditional) // clang-format on ); - auto &t0 = std::get<std::optional<wrapped::LastprivateModifier>>(inp.v.t); + auto &mods = semantics::OmpGetModifiers(inp.v); + auto *m0 = + semantics::OmpGetUniqueModifier<parser::OmpLastprivateModifier>(mods); auto &t1 = std::get<parser::OmpObjectList>(inp.v.t); - return Lastprivate{{/*LastprivateModifier=*/maybeApply(convert, t0), + return Lastprivate{{/*LastprivateModifier=*/maybeApplyToV(convert, m0), /*List=*/makeObjects(t1, semaCtx)}}; } diff --git a/flang/lib/Parser/CMakeLists.txt b/flang/lib/Parser/CMakeLists.txt index 600a2f67df4431..d364671d7a3229 100644 --- a/flang/lib/Parser/CMakeLists.txt +++ b/flang/lib/Parser/CMakeLists.txt @@ -30,6 +30,7 @@ add_flang_library(FortranParser LINK_COMPONENTS Support FrontendOpenACC + FrontendOpenMP DEPENDS omp_gen diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 1d3dd518601995..920f97f7ca0f21 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -16,6 +16,10 @@ #include "token-parsers.h" #include "type-parser-implementation.h" #include "flang/Parser/parse-tree.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Frontend/OpenMP/OMP.h" // OpenMP Directives and Clauses namespace Fortran::parser { @@ -23,6 +27,47 @@ namespace Fortran::parser { constexpr auto startOmpLine = skipStuffBeforeStatement >> "!$OMP "_sptok; constexpr auto endOmpLine = space >> endOfLine; +/// Parse OpenMP directive name (this includes compound directives). +struct OmpDirectiveNameParser { + using resultType = llvm::omp::Directive; + using Token = TokenStringMatch<false, false>; + + std::optional<resultType> Parse(ParseState &state) const { + for (const NameWithId &nid : directives()) { + if (attempt(Token(nid.first.data())).Parse(state)) { + return nid.second; + } + } + return std::nullopt; + } + +private: + using NameWithId = std::pair<std::string, llvm::omp::Directive>; + + llvm::iterator_range<const NameWithId *> directives() const; + void initTokens(NameWithId *) const; +}; + +llvm::iterator_range<const OmpDirectiveNameParser::NameWithId *> +OmpDirectiveNameParser::directives() const { + static NameWithId table[llvm::omp::Directive_enumSize]; + [[maybe_unused]] static bool init = (initTokens(table), true); + return llvm::make_range(std::cbegin(table), std::cend(table)); +} + +void OmpDirectiveNameParser::initTokens(NameWithId *table) const { + for (size_t i{0}, e{llvm::omp::Directive_enumSize}; i != e; ++i) { + auto id{static_cast<llvm::omp::Directive>(i)}; + llvm::StringRef name{llvm::omp::getOpenMPDirectiveName(id)}; + table[i] = std::make_pair(name.str(), id); + } + // Sort the table with respect to the directive name length in a descending + // order. This is to make sure that longer names are tried first, before + // any potential prefix (e.g. "target update" before "target"). + std::sort(table, table + llvm::omp::Directive_enumSize, + [](auto &a, auto &b) { return a.first.size() > b.first.size(); }); +} + template <typename Clause, typename Separator> struct ModifierList { constexpr ModifierList(Separator sep) : sep_(sep) {} constexpr ModifierList(const ModifierList &) = default; @@ -136,6 +181,9 @@ TYPE_PARSER(construct<OmpIterator>( // "ITERATOR" >> parenthesized(nonemptyList(sourced(Parser<OmpIteratorSpecifier>{}))))) +TYPE_PARSER(construct<OmpLastprivateModifier>( + "CONDITIONAL" >> pure(OmpLastprivateModifier::Value::Conditional))) + // 2.15.3.7 LINEAR (linear-list: linear-step) // linear-list -> list | modifier(list) // linear-modifier -> REF | VAL | UVAL @@ -232,6 +280,11 @@ TYPE_PARSER(sourced(construct<OmpFromClause::Modifier>( TYPE_PARSER(sourced( construct<OmpGrainsizeClause::Modifier>(Parser<OmpPrescriptiveness>{}))) +TYPE_PARSER(sourced(construct<OmpIfClause::Modifier>(OmpDirectiveNameParser{}))) + +TYPE_PARSER(sourced(construct<OmpLastprivateClause::Modifier>( + Parser<OmpLastprivateModifier>{}))) + TYPE_PARSER(sourced(construct<OmpMapClause::Modifier>( sourced(construct<OmpMapClause::Modifier>(Parser<OmpMapTypeModifier>{}) || construct<OmpMapClause::Modifier>(Parser<OmpMapper>{}) || @@ -345,22 +398,7 @@ TYPE_PARSER(construct<OmpDeviceTypeClause>( // 2.12 IF (directive-name-modifier: scalar-logical-expr) TYPE_PARSER(construct<OmpIfClause>( - maybe( - ("PARALLEL" >> pure(OmpIfClause::DirectiveNameModifier::Parallel) || - "SIMD" >> pure(OmpIfClause::DirectiveNameModifier::Simd) || - "TARGET ENTER DATA" >> - pure(OmpIfClause::DirectiveNameModifier::TargetEnterData) || - "TARGET EXIT DATA" >> - pure(OmpIfClause::DirectiveNameModifier::TargetExitData) || - "TARGET DATA" >> - pure(OmpIfClause::DirectiveNameModifier::TargetData) || - "TARGET UPDATE" >> - pure(OmpIfClause::DirectiveNameModifier::TargetUpdate) || - "TARGET" >> pure(OmpIfClause::DirectiveNameModifier::Target) || - "TASK"_id >> pure(OmpIfClause::DirectiveNameModifier::Task) || - "TASKLOOP" >> pure(OmpIfClause::DirectiveNameModifier::Taskloop) || - "TEAMS" >> pure(OmpIfClause::DirectiveNameModifier::Teams)) / - ":"), + maybe(nonemptyList(Parser<OmpIfClause::Modifier>{}) / ":"), scalarLogicalExpr)) TYPE_PARSER(construct<OmpReductionClause>( @@ -460,8 +498,7 @@ TYPE_PARSER( // OMP 5.0 2.19.4.5 LASTPRIVATE ([lastprivate-modifier :] list) TYPE_PARSER(construct<OmpLastprivateClause>( - maybe("CONDITIONAL" >> - pure(OmpLastprivateClause::LastprivateModifier::Conditional) / ":"), + maybe(nonemptyList(Parser<OmpLastprivateClause::Modifier>{}) / ":"), Parser<OmpObjectList>{})) // OMP 5.2 11.7.1 BIND ( PARALLEL | TEAMS | THREAD ) diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index cd025333a077d3..43c7ef540cb7af 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2074,6 +2074,9 @@ class UnparseVisitor { }, x.u); } + void Unparse(const OmpDirectiveNameModifier &x) { + Word(llvm::omp::getOpenMPDirectiveName(x.v)); + } void Unparse(const OmpIteratorSpecifier &x) { Walk(std::get<TypeDeclarationStmt>(x.t)); Put(" = "); @@ -2090,9 +2093,8 @@ class UnparseVisitor { Put(")"); } void Unparse(const OmpLastprivateClause &x) { - Walk( - std::get<std::optional<OmpLastprivateClause::LastprivateModifier>>(x.t), - ":"); + using Modifier = OmpLastprivateClause::Modifier; + Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": "); Walk(std::get<OmpObjectList>(x.t)); } void Unparse(const OmpMapClause &x) { @@ -2127,7 +2129,8 @@ class UnparseVisitor { Walk(std::get<OmpObjectList>(x.t)); } void Unparse(const OmpIfClause &x) { - Walk(std::get<std::optional<OmpIfClause::DirectiveNameModifier>>(x.t), ":"); + using Modifier = OmpIfClause::Modifier; + Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": "); Walk(std::get<ScalarLogicalExpr>(x.t)); } void Unparse(const OmpLinearClause::WithoutModifier &x) { @@ -2826,8 +2829,7 @@ class UnparseVisitor { WALK_NESTED_ENUM(OmpDefaultClause, DataSharingAttribute) // OMP default WALK_NESTED_ENUM(OmpDefaultmapClause, ImplicitBehavior) // OMP defaultmap WALK_NESTED_ENUM(OmpVariableCategory, Value) // OMP variable-category - WALK_NESTED_ENUM( - OmpLastprivateClause, LastprivateModifier) // OMP lastprivate-modifier + WALK_NESTED_ENUM(OmpLastprivateModifier, Value) // OMP lastprivate-modifier WALK_NESTED_ENUM(OmpChunkModifier, Value) // OMP chunk-modifier WALK_NESTED_ENUM(OmpLinearModifier, Value) // OMP linear-modifier WALK_NESTED_ENUM(OmpOrderingModifier, Value) // OMP ordering-modifier @@ -2838,7 +2840,6 @@ class UnparseVisitor { OmpDeviceTypeClause, DeviceTypeDescription) // OMP device_type WALK_NESTED_ENUM(OmpReductionModifier, Value) // OMP reduction-modifier WALK_NESTED_ENUM(OmpExpectation, Value) // OMP motion-expectation - WALK_NESTED_ENUM(OmpIfClause, DirectiveNameModifier) // OMP directive-modifier WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type WALK_NESTED_ENUM(OmpOrderClause, Ordering) // OMP ordering WALK_NESTED_ENUM(OmpOrderModifier, Value) // OMP order-modifier diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 9e589067c8868d..a88aba5a54a023 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -3428,36 +3428,81 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Defaultmap &x) { void OmpStructureChecker::Enter(const parser::OmpClause::If &x) { CheckAllowedClause(llvm::omp::Clause::OMPC_if); - using dirNameModifier = parser::OmpIfClause::DirectiveNameModifier; - // TODO Check that, when multiple 'if' clauses are applied to a combined - // construct, at most one of them applies to each directive. - static std::unordered_map<dirNameModifier, OmpDirectiveSet> - dirNameModifierMap{{dirNameModifier::Parallel, llvm::omp::allParallelSet}, - {dirNameModifier::Simd, llvm::omp::allSimdSet}, - {dirNameModifier::Target, llvm::omp::allTargetSet}, - {dirNameModifier::TargetData, - {llvm::omp::Directive::OMPD_target_data}}, - {dirNameModifier::TargetEnterData, - {llvm::omp::Directive::OMPD_target_enter_data}}, - {dirNameModifier::TargetExitData, - {llvm::omp::Directive::OMPD_target_exit_data}}, - {dirNameModifier::TargetUpdate, - {llvm::omp::Directive::OMPD_target_update}}, - {dirNameModifier::Task, {llvm::omp::Directive::OMPD_task}}, - {dirNameModifier::Taskloop, llvm::omp::allTaskloopSet}, - {dirNameModifier::Teams, llvm::omp::allTeamsSet}}; - if (const auto &directiveName{ - std::get<std::optional<dirNameModifier>>(x.v.t)}) { - auto search{dirNameModifierMap.find(*directiveName)}; - if (search == dirNameModifierMap.end() || - !search->second.test(GetContext().directive)) { - context_ - .Say(GetContext().clauseSource, - "Unmatched directive name modifier %s on the IF clause"_err_en_US, - parser::ToUpperCaseLetters( - parser::OmpIfClause::EnumToString(*directiveName))) - .Attach( - GetContext().directiveSource, "Cannot apply to directive"_en_US); + unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Directive dir{GetContext().directive}; + + auto isConstituent{[](llvm::omp::Directive dir, llvm::omp::Directive part) { + using namespace llvm::omp; + llvm::ArrayRef<Directive> dirLeafs{getLeafConstructsOrSelf(dir)}; + llvm::ArrayRef<Directive> partLeafs{getLeafConstructsOrSelf(part)}; + // Maybe it's sufficient to check if every leaf of `part` is also a leaf + // of `dir`, but to be safe check if `partLeafs` is a sub-sequence of + // `dirLeafs`. + size_t dirSize{dirLeafs.size()}, partSize{partLeafs.size()}; + // Find the first leaf from `part` in `dir`. + if (auto first = llvm::find(dirLeafs, partLeafs.front()); + first != dirLeafs.end()) { + // A leaf can only appear once in a compound directive, so if `part` + // is a subsequence of `dir`, it must start here. + long firstPos{std::distance(dirLeafs.begin(), first)}; + llvm::ArrayRef<Directive> subSeq{ + first, std::min<size_t>(dirSize - firstPos, partSize)}; + return subSeq == partLeafs; + } + return false; + }}; + + if (OmpVerifyModifiers( + x.v, llvm::omp::OMPC_if, GetContext().clauseSource, context_)) { + auto &modifiers{OmpGetModifiers(x.v)}; + if (auto *dnm{OmpGetUniqueModifier<parser::OmpDirectiveNameModifier>( + modifiers)}) { + llvm::omp::Directive sub{dnm->v}; + std::string subName{parser::ToUpperCaseLetters( + llvm::omp::getOpenMPDirectiveName(sub).str())}; + std::string dirName{parser::ToUpperCaseLetters( + llvm::omp::getOpenMPDirectiveName(dir).str())}; + + parser::CharBlock modifierSource{OmpGetModifierSource(modifiers, dnm)}; + auto desc{OmpGetDescriptor<parser::OmpDirectiveNameModifier>()}; + std::string modName{desc.name.str()}; + + if (!isConstituent(dir, sub)) { + context_ + .Say(modifierSource, + "%s is not a constituent of the %s directive"_err_en_US, + subName, dirName) + .Attach(GetContext().directiveSource, + "Cannot apply to directive"_en_US); + } else { + static llvm::omp::Directive valid45[]{ + llvm::omp::OMPD_cancel, // + llvm::omp::OMPD_parallel, // + /* OMP 5.0+ also allows OMPD_simd */ + llvm::omp::OMPD_target, // + llvm::omp::OMPD_target_data, // + llvm::omp::OMPD_target_enter_data, // + llvm::omp::OMPD_target_exit_data, // + llvm::omp::OMPD_target_update, // + llvm::omp::OMPD_task, // + llvm::omp::OMPD_taskloop, // + /* OMP 5.2+ also allows OMPD_teams */ + }; + if (version < 50 && sub == llvm::omp::OMPD_simd) { + context_.Say(modifierSource, + "%s is not allowed as '%s' in %s, %s"_warn_en_US, subName, + modName, ThisVersion(version), TryVersion(50)); + } else if (version < 52 && sub == llvm::omp::OMPD_teams) { + context_.Say(modifierSource, + "%s is not allowed as '%s' in %s, %s"_warn_en_US, subName, + modName, ThisVersion(version), TryVersion(52)); + } else if (!llvm::is_contained(valid45, sub) && + sub != llvm::omp::OMPD_simd && sub != llvm::omp::OMPD_teams) { + context_.Say(modifierSource, + "%s is not allowed as '%s' in %s"_err_en_US, subName, modName, + ThisVersion(version)); + } + } } } } @@ -3857,20 +3902,8 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &x) { CheckPrivateSymbolsInOuterCxt( currSymbols, dirClauseTriple, llvm::omp::Clause::OMPC_lastprivate); - using LastprivateModifier = parser::OmpLastprivateClause::LastprivateModifier; - const auto &maybeMod{std::get<std::optional<LastprivateModifier>>(x.v.t)}; - if (maybeMod) { - unsigned version{context_.langOptions().OpenMPVersion}; - unsigned allowedInVersion = 50; - if (version < allowedInVersion) { - std::string thisVersion{ - std::to_string(version / 10) + "." + std::to_string(version % 10)}; - context_.Say(GetContext().clauseSource, - "LASTPRIVATE clause with CONDITIONAL modifier is not " - "allowed in %s, %s"_err_en_US, - ThisVersion(version), TryVersion(allowedInVersion)); - } - } + OmpVerifyModifiers( + x.v, llvm::omp::OMPC_lastprivate, GetContext().clauseSource, context_); } void OmpStructureChecker::Enter(const parser::OmpClause::Copyin &x) { diff --git a/flang/lib/Semantics/openmp-modifiers.cpp b/flang/lib/Semantics/openmp-modifiers.cpp index e384b0270e6eae..f8f81e6c6ffa15 100644 --- a/flang/lib/Semantics/openmp-modifiers.cpp +++ b/flang/lib/Semantics/openmp-modifiers.cpp @@ -190,6 +190,23 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpDeviceModifier>() { return desc; } +template <> +const OmpModifierDescriptor & +OmpGetDescriptor<parser::OmpDirectiveNameModifier>() { + static const OmpModifierDescriptor desc{ + /*name=*/"directive-name-modifier", + /*props=*/ + { + {45, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {45, {Clause::OMPC_if}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpExpectation>() { static const OmpModifierDescriptor desc{ @@ -225,6 +242,23 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpIterator>() { return desc; } +template <> +const OmpModifierDescriptor & +OmpGetDescriptor<parser::OmpLastprivateModifier>() { + static const OmpModifierDescriptor desc{ + /*name=*/"lastprivate-modifier", + /*props=*/ + { + {50, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {50, {Clause::OMPC_lastprivate}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpLinearModifier>() { static const OmpModifierDescriptor desc{ diff --git a/flang/test/Parser/OpenMP/if-clause-unparse.f90 b/flang/test/Parser/OpenMP/if-clause-unparse.f90 index 20f7b36e743e1a..ce058caa54a938 100644 --- a/flang/test/Parser/OpenMP/if-clause-unparse.f90 +++ b/flang/test/Parser/OpenMP/if-clause-unparse.f90 @@ -10,50 +10,50 @@ program if_unparse !$omp target update if(cond) ! CHECK: !$OMP TARGET UPDATE - ! CHECK-SAME: IF(TARGETUPDATE:cond) + ! CHECK-SAME: IF(TARGET UPDATE: cond) !$omp target update if(target update: cond) ! CHECK: !$OMP TARGET UPDATE - ! CHECK-SAME: IF(TARGETUPDATE:cond) + ! CHECK-SAME: IF(TARGET UPDATE: cond) !$omp target update if(targetupdate: cond) ! CHECK: !$OMP TARGET ENTER DATA - ! CHECK-SAME: IF(TARGETENTERDATA:cond) + ! CHECK-SAME: IF(TARGET ENTER DATA: cond) !$omp target enter data map(to: i) if(target enter data: cond) ! CHECK: !$OMP TARGET EXIT DATA - ! CHECK-SAME: IF(TARGETEXITDATA:cond) + ! CHECK-SAME: IF(TARGET EXIT DATA: cond) !$omp target exit data map(from: i) if(target exit data: cond) ! CHECK: !$OMP TARGET DATA - ! CHECK-SAME: IF(TARGETDATA:cond) + ! CHECK-SAME: IF(TARGET DATA: cond) !$omp target data map(tofrom: i) if(target data: cond) !$omp end target data ! CHECK: !$OMP TARGET - ! CHECK-SAME: IF(TARGET:cond) + ! CHECK-SAME: IF(TARGET: cond) !$omp target if(target: cond) !$omp end target ! CHECK: !$OMP TEAMS - ! CHECK-SAME: IF(TEAMS:cond) + ! CHECK-SAME: IF(TEAMS: cond) !$omp teams if(teams: cond) !$omp end teams ! CHECK: !$OMP PARALLEL DO SIMD - ! CHECK-SAME: IF(PARALLEL:i<10) IF(SIMD:.FALSE.) + ! CHECK-SAME: IF(PARALLEL: i<10) IF(SIMD: .FALSE.) !$omp parallel do simd if(parallel: i < 10) if(simd: .false.) do i = 1, 10 end do !$omp end parallel do simd ! CHECK: !$OMP TASK - ! CHECK-SAME: IF(TASK:cond) + ! CHECK-SAME: IF(TASK: cond) !$omp task if(task: cond) !$omp end task ! CHECK: !$OMP TASKLOOP - ! CHECK-SAME: IF(TASKLOOP:cond) + ! CHECK-SAME: IF(TASKLOOP: cond) !$omp taskloop if(taskloop: cond) do i = 1, 10 end do diff --git a/flang/test/Parser/OpenMP/if-clause.f90 b/flang/test/Parser/OpenMP/if-clause.f90 index 6d69e16e7cc731..b3e3913f8bd1cf 100644 --- a/flang/test/Parser/OpenMP/if-clause.f90 +++ b/flang/test/Parser/OpenMP/if-clause.f90 @@ -1,4 +1,4 @@ -! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck %s +! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=52 %s | FileCheck %s program openmp_parse_if logical :: cond @@ -11,34 +11,34 @@ program openmp_parse_if ! CHECK: OmpSimpleStandaloneDirective -> llvm::omp::Directive = target update ! CHECK-NEXT: OmpClause -> If -> OmpIfClause - ! CHECK-NEXT: DirectiveNameModifier = TargetUpdate + ! CHECK-NEXT: OmpDirectiveNameModifier -> llvm::omp::Directive = target update !$omp target update if(target update: cond) to(i) ! CHECK: OmpSimpleStandaloneDirective -> llvm::omp::Directive = target enter data ! CHECK: OmpClause -> If -> OmpIfClause - ! CHECK-NEXT: DirectiveNameModifier = TargetEnterData + ! CHECK-NEXT: OmpDirectiveNameModifier -> llvm::omp::Directive = target enter data !$omp target enter data map(to: i) if(target enter data: cond) ! CHECK: OmpSimpleStandaloneDirective -> llvm::omp::Directive = target exit data ! CHECK: OmpClause -> If -> OmpIfClause - ! CHECK-NEXT: DirectiveNameModifier = TargetExitData + ! CHECK-NEXT: OmpDirectiveNameModifier -> llvm::omp::Directive = target exit data !$omp target exit data map(from: i) if(target exit data: cond) ! CHECK: OmpBlockDirective -> llvm::omp::Directive = target data ! CHECK: OmpClause -> If -> OmpIfClause - ! CHECK-NEXT: DirectiveNameModifier = TargetData + ! CHECK-NEXT: OmpDirectiveNameModifier -> llvm::omp::Directive = target data !$omp target data map(tofrom: i) if(target data: cond) !$omp end target data ! CHECK: OmpLoopDirective -> llvm::omp::Directive = target teams distribute parallel do simd ! CHECK: OmpClause -> If -> OmpIfClause - ! CHECK-NEXT: DirectiveNameModifier = Target + ! CHECK-NEXT: OmpDirectiveNameModifier -> llvm::omp::Directive = target ! CHECK: OmpClause -> If -> OmpIfClause - ! CHECK-NEXT: DirectiveNameModifier = Teams + ! CHECK-NEXT: OmpDirectiveNameModifier -> llvm::omp::Directive = teams ! CHECK: OmpClause -> If -> OmpIfClause - ! CHECK-NEXT: DirectiveNameModifier = Parallel + ! CHECK-NEXT: OmpDirectiveNameModifier -> llvm::omp::Directive = parallel ! CHECK: OmpClause -> If -> OmpIfClause - ! CHECK-NEXT: DirectiveNameModifier = Simd + ! CHECK-NEXT: OmpDirectiveNameModifier -> llvm::omp::Directive = simd !$omp target teams distribute parallel do simd if(target: cond) & !$omp& if(teams: cond) if(parallel: cond) if(simd: cond) do i = 1, 10 @@ -47,13 +47,13 @@ program openmp_parse_if ! CHECK: OmpBlockDirective -> llvm::omp::Directive = task ! CHECK-NEXT: OmpClause -> If -> OmpIfClause - ! CHECK-NEXT: DirectiveNameModifier = Task + ! CHECK-NEXT: OmpDirectiveNameModifier -> llvm::omp::Directive = task !$omp task if(task: cond) !$omp end task ! CHECK: OmpLoopDirective -> llvm::omp::Directive = taskloop ! CHECK-NEXT: OmpClause -> If -> OmpIfClause - ! CHECK-NEXT: DirectiveNameModifier = Taskloop + ! CHECK-NEXT: DirectiveNameModifier -> llvm::omp::Directive = taskloop !$omp taskloop if(taskloop: cond) do i = 1, 10 end do diff --git a/flang/test/Parser/OpenMP/lastprivate-clause.f90 b/flang/test/Parser/OpenMP/lastprivate-clause.f90 index 382f02c75e7f14..ac25174f3cc427 100644 --- a/flang/test/Parser/OpenMP/lastprivate-clause.f90 +++ b/flang/test/Parser/OpenMP/lastprivate-clause.f90 @@ -39,7 +39,7 @@ subroutine foo2() !UNPARSE: SUBROUTINE foo2 !UNPARSE: INTEGER x, i !UNPARSE: x=1_4 -!UNPARSE: !$OMP PARALLEL DO LASTPRIVATE(CONDITIONAL:x) +!UNPARSE: !$OMP PARALLEL DO LASTPRIVATE(CONDITIONAL: x) !UNPARSE: DO i=1_4,100_4 !UNPARSE: x=x+1_4 !UNPARSE: END DO @@ -49,6 +49,6 @@ subroutine foo2() !PARSE-TREE: Name = 'foo2' !PARSE-TREE: OmpLoopDirective -> llvm::omp::Directive = parallel do !PARSE-TREE: OmpClauseList -> OmpClause -> Lastprivate -> OmpLastprivateClause -!PARSE-TREE: LastprivateModifier = Conditional +!PARSE-TREE: Modifier -> OmpLastprivateModifier -> Value = Conditional !PARSE-TREE: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' !PARSE-TREE: EndSubroutineStmt diff --git a/flang/test/Semantics/OpenMP/clause-validity01.f90 b/flang/test/Semantics/OpenMP/clause-validity01.f90 index bc9d2d37060fc2..66e11e4b540f0f 100644 --- a/flang/test/Semantics/OpenMP/clause-validity01.f90 +++ b/flang/test/Semantics/OpenMP/clause-validity01.f90 @@ -241,7 +241,7 @@ enddo !$omp end parallel do simd - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the PARALLEL DO directive !$omp parallel do if(target:a>1.) do i = 1, N enddo @@ -532,7 +532,7 @@ a = 1. !$omp end task - !ERROR: Unmatched directive name modifier TASKLOOP on the IF clause + !ERROR: TASKLOOP is not a constituent of the TASK directive !$omp task private(a) if(taskloop:a.eq.1) a = 1. !$omp end task diff --git a/flang/test/Semantics/OpenMP/if-clause.f90 b/flang/test/Semantics/OpenMP/if-clause.f90 index 7aeb617e535630..23be4a751c8926 100644 --- a/flang/test/Semantics/OpenMP/if-clause.f90 +++ b/flang/test/Semantics/OpenMP/if-clause.f90 @@ -18,7 +18,7 @@ program main end do !$omp end distribute parallel do - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the DISTRIBUTE PARALLEL DO directive !$omp distribute parallel do if(target: .true.) do i = 1, 10 end do @@ -45,7 +45,7 @@ program main end do !$omp end distribute parallel do simd - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the DISTRIBUTE PARALLEL DO SIMD directive !$omp distribute parallel do simd if(target: .true.) do i = 1, 10 end do @@ -66,7 +66,7 @@ program main end do !$omp end distribute simd - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the DISTRIBUTE SIMD directive !$omp distribute simd if(target: .true.) do i = 1, 10 end do @@ -92,7 +92,7 @@ program main end do !$omp end do simd - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the DO SIMD directive !$omp do simd if(target: .true.) do i = 1, 10 end do @@ -113,7 +113,7 @@ program main !$omp parallel if(parallel: .true.) !$omp end parallel - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the PARALLEL directive !$omp parallel if(target: .true.) !$omp end parallel @@ -134,7 +134,7 @@ program main end do !$omp end parallel do - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the PARALLEL DO directive !$omp parallel do if(target: .true.) do i = 1, 10 end do @@ -159,7 +159,7 @@ program main end do !$omp end parallel do simd - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the PARALLEL DO SIMD directive !$omp parallel do simd if(target: .true.) do i = 1, 10 end do @@ -174,7 +174,7 @@ program main !$omp parallel sections if(parallel: .true.) !$omp end parallel sections - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the PARALLEL SECTIONS directive !$omp parallel sections if(target: .true.) !$omp end parallel sections @@ -191,7 +191,7 @@ program main !$omp parallel workshare if(parallel: .true.) !$omp end parallel workshare - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the PARALLEL WORKSHARE directive !$omp parallel workshare if(target: .true.) !$omp end parallel workshare @@ -212,7 +212,7 @@ program main end do !$omp end simd - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the SIMD directive !$omp simd if(target: .true.) do i = 1, 10 end do @@ -233,7 +233,7 @@ program main !$omp target if(target: .true.) !$omp end target - !ERROR: Unmatched directive name modifier PARALLEL on the IF clause + !ERROR: PARALLEL is not a constituent of the TARGET directive !$omp target if(parallel: .true.) !$omp end target @@ -250,7 +250,7 @@ program main !$omp target data map(tofrom: i) if(target data: .true.) !$omp end target data - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the TARGET DATA directive !$omp target data map(tofrom: i) if(target: .true.) !$omp end target data @@ -265,7 +265,7 @@ program main !$omp target enter data map(to: i) if(target enter data: .true.) - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the TARGET ENTER DATA directive !$omp target enter data map(to: i) if(target: .true.) !ERROR: At most one IF clause can appear on the TARGET ENTER DATA directive @@ -278,7 +278,7 @@ program main !$omp target exit data map(from: i) if(target exit data: .true.) - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the TARGET EXIT DATA directive !$omp target exit data map(from: i) if(target: .true.) !ERROR: At most one IF clause can appear on the TARGET EXIT DATA directive @@ -293,7 +293,7 @@ program main !$omp target parallel if(target: .true.) if(parallel: .false.) !$omp end target parallel - !ERROR: Unmatched directive name modifier SIMD on the IF clause + !ERROR: SIMD is not a constituent of the TARGET PARALLEL directive !$omp target parallel if(simd: .true.) !$omp end target parallel @@ -310,7 +310,7 @@ program main end do !$omp end target parallel do - !ERROR: Unmatched directive name modifier SIMD on the IF clause + !ERROR: SIMD is not a constituent of the TARGET PARALLEL DO directive !$omp target parallel do if(simd: .true.) do i = 1, 10 end do @@ -330,7 +330,7 @@ program main end do !$omp end target parallel do simd - !ERROR: Unmatched directive name modifier TEAMS on the IF clause + !ERROR: TEAMS is not a constituent of the TARGET PARALLEL DO SIMD directive !$omp target parallel do simd if(teams: .true.) do i = 1, 10 end do @@ -349,7 +349,7 @@ program main end do !$omp end target simd - !ERROR: Unmatched directive name modifier PARALLEL on the IF clause + !ERROR: PARALLEL is not a constituent of the TARGET SIMD directive !$omp target simd if(parallel: .true.) do i = 1, 10 end do @@ -364,7 +364,7 @@ program main !$omp target teams if(target: .true.) if(teams: .false.) !$omp end target teams - !ERROR: Unmatched directive name modifier PARALLEL on the IF clause + !ERROR: PARALLEL is not a constituent of the TARGET TEAMS directive !$omp target teams if(parallel: .true.) !$omp end target teams @@ -381,7 +381,7 @@ program main end do !$omp end target teams distribute - !ERROR: Unmatched directive name modifier PARALLEL on the IF clause + !ERROR: PARALLEL is not a constituent of the TARGET TEAMS DISTRIBUTE directive !$omp target teams distribute if(parallel: .true.) do i = 1, 10 end do @@ -401,7 +401,7 @@ program main end do !$omp end target teams distribute parallel do - !ERROR: Unmatched directive name modifier SIMD on the IF clause + !ERROR: SIMD is not a constituent of the TARGET TEAMS DISTRIBUTE PARALLEL DO directive !$omp target teams distribute parallel do if(simd: .true.) do i = 1, 10 end do @@ -422,7 +422,7 @@ program main end do !$omp end target teams distribute parallel do simd - !ERROR: Unmatched directive name modifier TASK on the IF clause + !ERROR: TASK is not a constituent of the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive !$omp target teams distribute parallel do simd if(task: .true.) do i = 1, 10 end do @@ -442,7 +442,7 @@ program main end do !$omp end target teams distribute simd - !ERROR: Unmatched directive name modifier PARALLEL on the IF clause + !ERROR: PARALLEL is not a constituent of the TARGET TEAMS DISTRIBUTE SIMD directive !$omp target teams distribute simd if(parallel: .true.) do i = 1, 10 end do @@ -455,7 +455,7 @@ program main !$omp target update to(i) if(target update: .true.) - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the TARGET UPDATE directive !$omp target update to(i) if(target: .true.) !ERROR: At most one IF clause can appear on the TARGET UPDATE directive @@ -470,7 +470,7 @@ program main !$omp task if(task: .true.) !$omp end task - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the TASK directive !$omp task if(target: .true.) !$omp end task @@ -491,7 +491,7 @@ program main end do !$omp end taskloop - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the TASKLOOP directive !$omp taskloop if(target: .true.) do i = 1, 10 end do @@ -516,7 +516,7 @@ program main end do !$omp end taskloop simd - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the TASKLOOP SIMD directive !$omp taskloop simd if(target: .true.) do i = 1, 10 end do @@ -531,7 +531,7 @@ program main !$omp teams if(teams: .true.) !$omp end teams - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the TEAMS directive !$omp teams if(target: .true.) !$omp end teams @@ -552,7 +552,7 @@ program main end do !$omp end teams distribute - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the TEAMS DISTRIBUTE directive !$omp teams distribute if(target: .true.) do i = 1, 10 end do @@ -577,7 +577,7 @@ program main end do !$omp end teams distribute parallel do - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the TEAMS DISTRIBUTE PARALLEL DO directive !$omp teams distribute parallel do if(target: .true.) do i = 1, 10 end do @@ -597,7 +597,7 @@ program main end do !$omp end teams distribute parallel do simd - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the TEAMS DISTRIBUTE PARALLEL DO SIMD directive !$omp teams distribute parallel do simd if(target: .true.) do i = 1, 10 end do @@ -616,7 +616,7 @@ program main end do !$omp end teams distribute simd - !ERROR: Unmatched directive name modifier TARGET on the IF clause + !ERROR: TARGET is not a constituent of the TEAMS DISTRIBUTE SIMD directive !$omp teams distribute simd if(target: .true.) do i = 1, 10 end do >From 1292aebcbf29e3c2740d86b399b0a2b1c8b1d225 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek <krzysztof.parzys...@amd.com> Date: Fri, 29 Nov 2024 14:27:55 -0600 Subject: [PATCH 2/2] add explicit cast --- flang/lib/Semantics/check-omp-structure.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index a88aba5a54a023..d722067d27bfd1 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -3444,7 +3444,8 @@ void OmpStructureChecker::Enter(const parser::OmpClause::If &x) { first != dirLeafs.end()) { // A leaf can only appear once in a compound directive, so if `part` // is a subsequence of `dir`, it must start here. - long firstPos{std::distance(dirLeafs.begin(), first)}; + size_t firstPos{ + static_cast<size_t>(std::distance(dirLeafs.begin(), first))}; llvm::ArrayRef<Directive> subSeq{ first, std::min<size_t>(dirSize - firstPos, partSize)}; return subSeq == partLeafs; _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits