[flang-commits] [flang] 75c3105 - [flang] Semantic checks for OpenMP combined constructs.
David Truby via flang-commits
flang-commits at lists.llvm.org
Mon Apr 27 04:41:05 PDT 2020
Author: David Truby
Date: 2020-04-27T12:40:49+01:00
New Revision: 75c31057a76228dea73aff100e7403c0e9a00c30
URL: https://github.com/llvm/llvm-project/commit/75c31057a76228dea73aff100e7403c0e9a00c30
DIFF: https://github.com/llvm/llvm-project/commit/75c31057a76228dea73aff100e7403c0e9a00c30.diff
LOG: [flang] Semantic checks for OpenMP combined constructs.
Summary:
This includes a refactor of the existing combined construct checks
that were present, as well as adding the remaining combined constructs
that had not been implemented yet.
Reviewers: jdoerfert
Subscribers: yaxunl, guansong, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77812
Added:
flang/test/Semantics/omp-combined-constructs.f90
Modified:
flang/include/flang/Common/enum-set.h
flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/resolve-names.cpp
flang/test/Semantics/omp-device-constructs.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Common/enum-set.h b/flang/include/flang/Common/enum-set.h
index 185c48825621..5346cceaadfa 100644
--- a/flang/include/flang/Common/enum-set.h
+++ b/flang/include/flang/Common/enum-set.h
@@ -111,6 +111,13 @@ template <typename ENUM, std::size_t BITS> class EnumSet {
return result;
}
+ constexpr EnumSet operator+(enumerationType v) const {
+ return {*this | EnumSet{v}};
+ }
+ constexpr EnumSet operator-(enumerationType v) const {
+ return {*this & ~EnumSet{v}};
+ }
+
constexpr bool operator==(const EnumSet &that) const {
return bitset_ == that.bitset_;
}
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index b1864fbda62a..9a1c656afb97 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -13,6 +13,52 @@
namespace Fortran::semantics {
+static constexpr inline OmpClauseSet doAllowedClauses{OmpClause::PRIVATE,
+ OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE, OmpClause::LINEAR,
+ OmpClause::REDUCTION};
+static constexpr inline OmpClauseSet doAllowedOnceClauses{
+ OmpClause::SCHEDULE, OmpClause::COLLAPSE, OmpClause::ORDERED};
+
+static constexpr inline OmpClauseSet simdAllowedClauses{OmpClause::LINEAR,
+ OmpClause::ALIGNED, OmpClause::PRIVATE, OmpClause::LASTPRIVATE,
+ OmpClause::REDUCTION};
+static constexpr inline OmpClauseSet simdAllowedOnceClauses{
+ OmpClause::COLLAPSE, OmpClause::SAFELEN, OmpClause::SIMDLEN};
+
+static constexpr inline OmpClauseSet parallelAllowedClauses{OmpClause::DEFAULT,
+ OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE, OmpClause::SHARED,
+ OmpClause::COPYIN, OmpClause::REDUCTION};
+static constexpr inline OmpClauseSet parallelAllowedOnceClauses{
+ OmpClause::IF, OmpClause::NUM_THREADS, OmpClause::PROC_BIND};
+
+static constexpr inline OmpClauseSet taskloopAllowedClauses{OmpClause::SHARED,
+ OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE,
+ OmpClause::DEFAULT, OmpClause::UNTIED, OmpClause::MERGEABLE,
+ OmpClause::NOGROUP};
+static constexpr inline OmpClauseSet taskloopAllowedOnceClauses{
+ OmpClause::COLLAPSE, OmpClause::IF, OmpClause::FINAL, OmpClause::PRIORITY};
+static constexpr inline OmpClauseSet taskloopAllowedExclusiveClauses{
+ OmpClause::GRAINSIZE, OmpClause::NUM_TASKS};
+
+static constexpr inline OmpClauseSet distributeAllowedClauses{
+ OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE};
+static constexpr inline OmpClauseSet distributeAllowedOnceClauses{
+ OmpClause::COLLAPSE, OmpClause::DIST_SCHEDULE};
+
+static constexpr inline OmpClauseSet targetAllowedClauses{OmpClause::IF,
+ OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE, OmpClause::MAP,
+ OmpClause::IS_DEVICE_PTR, OmpClause::DEPEND};
+static constexpr inline OmpClauseSet targetAllowedOnceClauses{
+ OmpClause::DEVICE, OmpClause::DEFAULTMAP, OmpClause::NOWAIT};
+
+static constexpr inline OmpClauseSet teamsAllowedClauses{OmpClause::PRIVATE,
+ OmpClause::FIRSTPRIVATE, OmpClause::SHARED, OmpClause::REDUCTION};
+static constexpr inline OmpClauseSet teamsAllowedOnceClauses{
+ OmpClause::NUM_TEAMS, OmpClause::THREAD_LIMIT, OmpClause::DEFAULT};
+
+static constexpr inline OmpClauseSet sectionsAllowedClauses{OmpClause::PRIVATE,
+ OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE, OmpClause::REDUCTION};
+
std::string OmpStructureChecker::ContextDirectiveAsFortran() {
auto dir{EnumToString(GetContext().directive)};
std::replace(dir.begin(), dir.end(), '_', ' ');
@@ -145,26 +191,16 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
OmpDirective::MASTER});
PushContext(beginDir.source, OmpDirective::DO);
- OmpClauseSet allowed{OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE,
- OmpClause::LASTPRIVATE, OmpClause::LINEAR, OmpClause::REDUCTION};
- SetContextAllowed(allowed);
- OmpClauseSet allowedOnce{
- OmpClause::SCHEDULE, OmpClause::COLLAPSE, OmpClause::ORDERED};
- SetContextAllowedOnce(allowedOnce);
+ SetContextAllowed(doAllowedClauses);
+ SetContextAllowedOnce(doAllowedOnceClauses);
} break;
// 2.11.1 parallel-do-clause -> parallel-clause |
// do-clause
case parser::OmpLoopDirective::Directive::ParallelDo: {
PushContext(beginDir.source, OmpDirective::PARALLEL_DO);
- OmpClauseSet allowed{OmpClause::DEFAULT, OmpClause::PRIVATE,
- OmpClause::FIRSTPRIVATE, OmpClause::SHARED, OmpClause::COPYIN,
- OmpClause::REDUCTION, OmpClause::LASTPRIVATE, OmpClause::LINEAR};
- SetContextAllowed(allowed);
- OmpClauseSet allowedOnce{OmpClause::IF, OmpClause::NUM_THREADS,
- OmpClause::PROC_BIND, OmpClause::SCHEDULE, OmpClause::COLLAPSE,
- OmpClause::ORDERED};
- SetContextAllowedOnce(allowedOnce);
+ SetContextAllowed(parallelAllowedClauses | doAllowedClauses);
+ SetContextAllowedOnce(parallelAllowedOnceClauses | doAllowedOnceClauses);
} break;
// 2.8.1 simd-clause -> safelen-clause |
@@ -177,40 +213,26 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
// collapse-clause
case parser::OmpLoopDirective::Directive::Simd: {
PushContext(beginDir.source, OmpDirective::SIMD);
- OmpClauseSet allowed{OmpClause::LINEAR, OmpClause::ALIGNED,
- OmpClause::PRIVATE, OmpClause::LASTPRIVATE, OmpClause::REDUCTION};
- SetContextAllowed(allowed);
- OmpClauseSet allowedOnce{
- OmpClause::COLLAPSE, OmpClause::SAFELEN, OmpClause::SIMDLEN};
- SetContextAllowedOnce(allowedOnce);
+ SetContextAllowed(simdAllowedClauses);
+ SetContextAllowedOnce(simdAllowedOnceClauses);
} break;
// 2.8.3 do-simd-clause -> do-clause |
// simd-clause
case parser::OmpLoopDirective::Directive::DoSimd: {
PushContext(beginDir.source, OmpDirective::DO_SIMD);
- OmpClauseSet allowed{OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE,
- OmpClause::LASTPRIVATE, OmpClause::LINEAR, OmpClause::REDUCTION,
- OmpClause::ALIGNED};
- SetContextAllowed(allowed);
- OmpClauseSet allowedOnce{OmpClause::SCHEDULE, OmpClause::COLLAPSE,
- OmpClause::ORDERED, OmpClause::SAFELEN, OmpClause::SIMDLEN};
- SetContextAllowedOnce(allowedOnce);
+ SetContextAllowed(doAllowedClauses | simdAllowedClauses);
+ SetContextAllowedOnce(doAllowedOnceClauses | simdAllowedOnceClauses);
} break;
// 2.11.4 parallel-do-simd-clause -> parallel-clause |
// do-simd-clause
case parser::OmpLoopDirective::Directive::ParallelDoSimd: {
PushContext(beginDir.source, OmpDirective::PARALLEL_DO_SIMD);
- OmpClauseSet allowed{OmpClause::DEFAULT, OmpClause::PRIVATE,
- OmpClause::FIRSTPRIVATE, OmpClause::SHARED, OmpClause::COPYIN,
- OmpClause::REDUCTION, OmpClause::LASTPRIVATE, OmpClause::LINEAR,
- OmpClause::ALIGNED};
- SetContextAllowed(allowed);
- OmpClauseSet allowedOnce{OmpClause::IF, OmpClause::NUM_THREADS,
- OmpClause::PROC_BIND, OmpClause::SCHEDULE, OmpClause::COLLAPSE,
- OmpClause::ORDERED, OmpClause::SAFELEN, OmpClause::SIMDLEN};
- SetContextAllowedOnce(allowedOnce);
+ SetContextAllowed(
+ parallelAllowedClauses | doAllowedClauses | simdAllowedClauses);
+ SetContextAllowedOnce(parallelAllowedOnceClauses | doAllowedOnceClauses |
+ simdAllowedOnceClauses);
} break;
// 2.9.2 taskloop-clause -> if-clause |
@@ -229,32 +251,19 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
// nogroup-clause
case parser::OmpLoopDirective::Directive::Taskloop: {
PushContext(beginDir.source, OmpDirective::TASKLOOP);
- OmpClauseSet allowed{OmpClause::SHARED, OmpClause::PRIVATE,
- OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE, OmpClause::DEFAULT,
- OmpClause::UNTIED, OmpClause::MERGEABLE, OmpClause::NOGROUP};
- SetContextAllowed(allowed);
- OmpClauseSet allowedOnce{OmpClause::COLLAPSE, OmpClause::IF,
- OmpClause::FINAL, OmpClause::PRIORITY};
- SetContextAllowedOnce(allowedOnce);
- OmpClauseSet allowedExclusive{OmpClause::GRAINSIZE, OmpClause::NUM_TASKS};
- SetContextAllowedExclusive(allowedExclusive);
+ SetContextAllowed(taskloopAllowedClauses);
+ SetContextAllowedOnce(taskloopAllowedOnceClauses);
+ SetContextAllowedExclusive(taskloopAllowedExclusiveClauses);
} break;
// 2.9.3 taskloop-simd-clause -> taskloop-clause |
// simd-clause
case parser::OmpLoopDirective::Directive::TaskloopSimd: {
PushContext(beginDir.source, OmpDirective::TASKLOOP_SIMD);
- OmpClauseSet allowed{OmpClause::LINEAR, OmpClause::ALIGNED,
- OmpClause::SHARED, OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE,
- OmpClause::LASTPRIVATE, OmpClause::DEFAULT, OmpClause::UNTIED,
- OmpClause::MERGEABLE, OmpClause::NOGROUP};
- SetContextAllowed(allowed);
- OmpClauseSet allowedOnce{OmpClause::COLLAPSE, OmpClause::SAFELEN,
- OmpClause::SIMDLEN, OmpClause::IF, OmpClause::FINAL,
- OmpClause::PRIORITY};
- SetContextAllowedOnce(allowedOnce);
- OmpClauseSet allowedExclusive{OmpClause::GRAINSIZE, OmpClause::NUM_TASKS};
- SetContextAllowedExclusive(allowedExclusive);
+ SetContextAllowed(
+ taskloopAllowedClauses | simdAllowedClauses - OmpClause::REDUCTION);
+ SetContextAllowedOnce(taskloopAllowedOnceClauses | simdAllowedOnceClauses);
+ SetContextAllowedExclusive(taskloopAllowedExclusiveClauses);
} break;
// 2.10.8 distribute-clause -> private-clause |
@@ -264,16 +273,159 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
// dist-schedule-clause
case parser::OmpLoopDirective::Directive::Distribute: {
PushContext(beginDir.source, OmpDirective::DISTRIBUTE);
- OmpClauseSet allowed{
- OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE};
- SetContextAllowed(allowed);
- OmpClauseSet allowedOnce{OmpClause::COLLAPSE, OmpClause::DIST_SCHEDULE};
- SetContextAllowedOnce(allowedOnce);
+ SetContextAllowed(distributeAllowedClauses);
+ SetContextAllowedOnce(distributeAllowedOnceClauses);
} break;
- default:
- // TODO others
- break;
+ // 2.10.9 distribute-simd-clause -> distribute-clause |
+ // simd-clause
+ case parser::OmpLoopDirective::Directive::DistributeSimd: {
+ PushContext(beginDir.source, OmpDirective::DISTRIBUTE_SIMD);
+ SetContextAllowed(distributeAllowedClauses | simdAllowedClauses);
+ SetContextAllowedOnce(
+ distributeAllowedOnceClauses | simdAllowedOnceClauses);
+ } break;
+
+ // 2.10.10 distribute-parallel-do-clause -> distribute-clause |
+ // parallel-do-clause
+ case parser::OmpLoopDirective::Directive::DistributeParallelDo: {
+ PushContext(beginDir.source, OmpDirective::DISTRIBUTE_PARALLEL_DO);
+ SetContextAllowed(
+ distributeAllowedClauses | parallelAllowedClauses | doAllowedClauses);
+ SetContextAllowedOnce(distributeAllowedOnceClauses |
+ parallelAllowedOnceClauses | doAllowedOnceClauses);
+ } break;
+
+ // 2.10.11 distribute-parallel-do-simd-clause -> distribute-clause |
+ // parallel-do-simd-clause
+ case parser::OmpLoopDirective::Directive::DistributeParallelDoSimd: {
+ PushContext(beginDir.source, OmpDirective::DISTRIBUTE_PARALLEL_DO_SIMD);
+ SetContextAllowed(distributeAllowedClauses | parallelAllowedClauses |
+ doAllowedClauses | simdAllowedClauses);
+ SetContextAllowedOnce(distributeAllowedOnceClauses |
+ parallelAllowedOnceClauses | doAllowedOnceClauses | simdAllowedClauses);
+ } break;
+
+ // 2.11.6 target-parallel-do-clause -> target-clause |
+ // parallel-do-clause
+ case parser::OmpLoopDirective::Directive::TargetParallelDo: {
+ PushContext(beginDir.source, OmpDirective::TARGET_PARALLEL_DO);
+ SetContextAllowed(
+ targetAllowedClauses | parallelAllowedClauses | doAllowedClauses);
+ SetContextAllowedOnce(
+ (targetAllowedOnceClauses | parallelAllowedOnceClauses |
+ doAllowedOnceClauses) -
+ OmpClause::NOWAIT);
+ } break;
+
+ // 2.11.7 target-parallel-do-simd-clause -> target-clause |
+ // parallel-do-simd-clause
+ case parser::OmpLoopDirective::Directive::TargetParallelDoSimd: {
+ PushContext(beginDir.source, OmpDirective::TARGET_PARALLEL_DO_SIMD);
+ SetContextAllowed(targetAllowedClauses | parallelAllowedClauses |
+ doAllowedClauses | simdAllowedClauses);
+ SetContextAllowedOnce(
+ (targetAllowedOnceClauses | parallelAllowedOnceClauses |
+ doAllowedOnceClauses | simdAllowedOnceClauses) -
+ OmpClause::NOWAIT);
+ } break;
+
+ // 2.11.8 target-simd-clause -> target-clause |
+ // simd-clause
+ case parser::OmpLoopDirective::Directive::TargetSimd: {
+ PushContext(beginDir.source, OmpDirective::TARGET_SIMD);
+ SetContextAllowed(targetAllowedClauses | simdAllowedClauses);
+ SetContextAllowedOnce(targetAllowedOnceClauses | simdAllowedOnceClauses);
+ } break;
+
+ // 2.11.10 teams-distribute-clause -> teams-clause |
+ // distribute-clause
+ case parser::OmpLoopDirective::Directive::TeamsDistribute: {
+ PushContext(beginDir.source, OmpDirective::TEAMS_DISTRIBUTE);
+ SetContextAllowed(teamsAllowedClauses | distributeAllowedClauses);
+ SetContextAllowedOnce(
+ teamsAllowedOnceClauses | distributeAllowedOnceClauses);
+ } break;
+
+ // 2.11.11 teams-distribute-simd-clause -> teams-clause |
+ // distribute-simd-clause
+ case parser::OmpLoopDirective::Directive::TeamsDistributeSimd: {
+ PushContext(beginDir.source, OmpDirective::TEAMS_DISTRIBUTE_SIMD);
+ SetContextAllowed(
+ teamsAllowedClauses | distributeAllowedClauses | simdAllowedClauses);
+ SetContextAllowedOnce(teamsAllowedOnceClauses |
+ distributeAllowedOnceClauses | simdAllowedOnceClauses);
+ } break;
+
+ // 2.11.12 target-teams-distribute-clause -> target-clause |
+ // teams-distribute-clause
+ case parser::OmpLoopDirective::Directive::TargetTeamsDistribute: {
+ PushContext(beginDir.source, OmpDirective::TARGET_TEAMS_DISTRIBUTE);
+ SetContextAllowed(
+ targetAllowedClauses | teamsAllowedClauses | distributeAllowedClauses);
+ SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses |
+ distributeAllowedOnceClauses);
+ } break;
+
+ // 2.11.13 target-teams-distribute-simd-clause -> target-clause |
+ // teams-distribute-simd-clause
+ case parser::OmpLoopDirective::Directive::TargetTeamsDistributeSimd: {
+ PushContext(beginDir.source, OmpDirective::TARGET_TEAMS_DISTRIBUTE_SIMD);
+ SetContextAllowed(targetAllowedClauses | teamsAllowedClauses |
+ distributeAllowedClauses | simdAllowedClauses);
+ SetContextAllowed(targetAllowedOnceClauses | teamsAllowedOnceClauses |
+ distributeAllowedOnceClauses | simdAllowedOnceClauses);
+ } break;
+
+ // 2.11.14 teams-distribute-parallel-do-clause -> teams-clause |
+ // distribute-parallel-do-clause
+ case parser::OmpLoopDirective::Directive::TeamsDistributeParallelDo: {
+ PushContext(beginDir.source, OmpDirective::TEAMS_DISTRIBUTE_PARALLEL_DO);
+ SetContextAllowed(teamsAllowedClauses | distributeAllowedClauses |
+ parallelAllowedClauses | doAllowedClauses);
+ SetContextAllowedOnce(teamsAllowedOnceClauses |
+ distributeAllowedOnceClauses | parallelAllowedOnceClauses |
+ doAllowedOnceClauses);
+ } break;
+
+ // 2.11.15 target-teams-distribute-parallel-do-clause -> target-clause |
+ // teams-distribute-parallel-do-clause
+ case parser::OmpLoopDirective::Directive::TargetTeamsDistributeParallelDo: {
+ PushContext(
+ beginDir.source, OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO);
+ SetContextAllowed(targetAllowedClauses | teamsAllowedClauses |
+ distributeAllowedClauses | parallelAllowedClauses | doAllowedClauses);
+ SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses |
+ distributeAllowedOnceClauses | parallelAllowedOnceClauses |
+ doAllowedOnceClauses);
+ } break;
+
+ // 2.11.16 teams-distribute-parallel-do-clause -> teams-clause |
+ // distribute-parallel-do-simd-clause
+ case parser::OmpLoopDirective::Directive::TeamsDistributeParallelDoSimd: {
+ PushContext(
+ beginDir.source, OmpDirective::TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD);
+ SetContextAllowed(teamsAllowedClauses | distributeAllowedClauses |
+ parallelAllowedClauses | doAllowedClauses | simdAllowedClauses);
+ SetContextAllowedOnce(teamsAllowedOnceClauses |
+ distributeAllowedOnceClauses | parallelAllowedOnceClauses |
+ doAllowedOnceClauses | simdAllowedOnceClauses);
+ } break;
+
+ case parser::OmpLoopDirective::Directive::
+ TargetTeamsDistributeParallelDoSimd: {
+ PushContext(beginDir.source,
+ OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD);
+ SetContextAllowed(targetAllowedClauses | teamsAllowedClauses |
+ distributeAllowedClauses | parallelAllowedClauses | doAllowedClauses |
+ simdAllowedClauses);
+ SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses |
+ distributeAllowedOnceClauses | parallelAllowedOnceClauses |
+ doAllowedOnceClauses | simdAllowedOnceClauses);
+ }
+
+ // TODO others
+ break;
}
}
@@ -320,13 +472,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
case parser::OmpBlockDirective::Directive::Parallel: {
// reserve for nesting check
PushContext(beginDir.source, OmpDirective::PARALLEL);
- OmpClauseSet allowed{OmpClause::DEFAULT, OmpClause::PRIVATE,
- OmpClause::FIRSTPRIVATE, OmpClause::SHARED, OmpClause::COPYIN,
- OmpClause::REDUCTION};
- SetContextAllowed(allowed);
- OmpClauseSet allowedOnce{
- OmpClause::IF, OmpClause::NUM_THREADS, OmpClause::PROC_BIND};
- SetContextAllowedOnce(allowedOnce);
+ SetContextAllowed(parallelAllowedClauses);
+ SetContextAllowedOnce(parallelAllowedOnceClauses);
} break;
// 2.7.3 single-clause -> private-clause |
// firstprivate-clause
@@ -338,6 +485,12 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
case parser::OmpBlockDirective::Directive::Workshare:
PushContext(beginDir.source, OmpDirective::WORKSHARE);
break;
+ // 2.11.3 parallel-workshare-clause -> parallel-clause
+ case parser::OmpBlockDirective::Directive::ParallelWorkshare: {
+ PushContext(beginDir.source, OmpDirective::PARALLEL_WORKSHARE);
+ SetContextAllowed(parallelAllowedClauses);
+ SetContextAllowedOnce(parallelAllowedOnceClauses);
+ } break;
// 2.9.1 task-clause -> if-clause |
// final-clause |
// untied-clause |
@@ -369,13 +522,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
// depend-clause
case parser::OmpBlockDirective::Directive::Target: {
PushContext(beginDir.source, OmpDirective::TARGET);
- OmpClauseSet allowed{OmpClause::IF, OmpClause::PRIVATE,
- OmpClause::FIRSTPRIVATE, OmpClause::MAP, OmpClause::IS_DEVICE_PTR,
- OmpClause::DEPEND};
- SetContextAllowed(allowed);
- OmpClauseSet allowedOnce{
- OmpClause::DEVICE, OmpClause::DEFAULTMAP, OmpClause::NOWAIT};
- SetContextAllowedOnce(allowedOnce);
+ SetContextAllowed(targetAllowedClauses);
+ SetContextAllowedOnce(targetAllowedOnceClauses);
} break;
// 2.10.7 teams-clause -> num-teams-clause |
// thread-limit-clause |
@@ -386,12 +534,15 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
// reduction-clause
case parser::OmpBlockDirective::Directive::Teams: {
PushContext(beginDir.source, OmpDirective::TEAMS);
- OmpClauseSet allowed{OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE,
- OmpClause::SHARED, OmpClause::REDUCTION};
- SetContextAllowed(allowed);
- OmpClauseSet allowedOnce{
- OmpClause::NUM_TEAMS, OmpClause::THREAD_LIMIT, OmpClause::DEFAULT};
- SetContextAllowedOnce(allowedOnce);
+ SetContextAllowed(teamsAllowedClauses);
+ SetContextAllowedOnce(teamsAllowedOnceClauses);
+ } break;
+ // 2.11.9 target-teams -> target-clause |
+ // teams-clause
+ case parser::OmpBlockDirective::Directive::TargetTeams: {
+ PushContext(beginDir.source, OmpDirective::TARGET_TEAMS);
+ SetContextAllowed(targetAllowedClauses | teamsAllowedClauses);
+ SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses);
} break;
// 2.10.1 target-data-clause -> if-clause |
// device-clause |
@@ -409,6 +560,15 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
case parser::OmpBlockDirective::Directive::Master:
PushContext(beginDir.source, OmpDirective::MASTER);
break;
+ // 2.11.5 target-parallel-clause -> target-clause |
+ // parallel-clause
+ case parser::OmpBlockDirective::Directive::TargetParallel: {
+ PushContext(beginDir.source, OmpDirective::TARGET_PARALLEL);
+ SetContextAllowed(
+ (targetAllowedClauses | parallelAllowedClauses) - OmpClause::COPYIN);
+ SetContextAllowedOnce(
+ targetAllowedOnceClauses | parallelAllowedOnceClauses);
+ } break;
default:
// TODO others
break;
@@ -433,19 +593,14 @@ void OmpStructureChecker::Enter(const parser::OpenMPSectionsConstruct &x) {
// reduction-clause
case parser::OmpSectionsDirective::Directive::Sections: {
PushContext(beginDir.source, OmpDirective::SECTIONS);
- OmpClauseSet allowed{OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE,
- OmpClause::LASTPRIVATE, OmpClause::REDUCTION};
- SetContextAllowed(allowed);
+ SetContextAllowed(sectionsAllowedClauses);
} break;
+ // 2.11.2 -> parallel-sections-clause -> parallel-clause |
+ // sections-clause
case parser::OmpSectionsDirective::Directive::ParallelSections: {
PushContext(beginDir.source, OmpDirective::PARALLEL_SECTIONS);
- OmpClauseSet allowed{OmpClause::DEFAULT, OmpClause::PRIVATE,
- OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE, OmpClause::SHARED,
- OmpClause::COPYIN, OmpClause::REDUCTION};
- SetContextAllowed(allowed);
- OmpClauseSet allowedOnce{
- OmpClause::IF, OmpClause::NUM_THREADS, OmpClause::PROC_BIND};
- SetContextAllowedOnce(allowedOnce);
+ SetContextAllowed(parallelAllowedClauses | sectionsAllowedClauses);
+ SetContextAllowedOnce(parallelAllowedOnceClauses);
} break;
}
}
@@ -913,6 +1068,11 @@ void OmpStructureChecker::Enter(const parser::OmpMapClause &x) {
const Type &type{std::get<Type>(maptype->t)};
switch (GetContext().directive) {
case OmpDirective::TARGET:
+ case OmpDirective::TARGET_TEAMS:
+ case OmpDirective::TARGET_TEAMS_DISTRIBUTE:
+ case OmpDirective::TARGET_TEAMS_DISTRIBUTE_SIMD:
+ case OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
+ case OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
case OmpDirective::TARGET_DATA: {
if (type != Type::To && type != Type::From && type != Type::Tofrom &&
type != Type::Alloc) {
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index f32fce7c743e..6d04c7f229ed 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -6300,6 +6300,15 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
case parser::OmpBlockDirective::Directive::Workshare:
PushContext(beginDir.source, OmpDirective::WORKSHARE);
break;
+ case parser::OmpBlockDirective::Directive::ParallelWorkshare:
+ PushContext(beginDir.source, OmpDirective::PARALLEL_WORKSHARE);
+ break;
+ case parser::OmpBlockDirective::Directive::TargetTeams:
+ PushContext(beginDir.source, OmpDirective::TARGET_TEAMS);
+ break;
+ case parser::OmpBlockDirective::Directive::TargetParallel:
+ PushContext(beginDir.source, OmpDirective::TARGET_PARALLEL);
+ break;
default:
// TODO others
break;
diff --git a/flang/test/Semantics/omp-combined-constructs.f90 b/flang/test/Semantics/omp-combined-constructs.f90
new file mode 100644
index 000000000000..c7ff9f02afbf
--- /dev/null
+++ b/flang/test/Semantics/omp-combined-constructs.f90
@@ -0,0 +1,509 @@
+! RUN: %B/test/Semantics/test_errors.sh %s %flang %t
+! OPTIONS: -fopenmp
+
+program main
+ implicit none
+ integer :: N
+ integer :: i
+ real(8) :: a(256), b(256)
+ N = 256
+
+ !$omp distribute simd
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end distribute simd
+
+ !$omp target parallel device(0)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel
+
+ !ERROR: At most one DEVICE clause can appear on the TARGET PARALLEL directive
+ !$omp target parallel device(0) device(1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel
+
+ !$omp target parallel defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel
+
+ !ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
+ !$omp target parallel defaultmap(tofrom)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel
+
+ !ERROR: At most one DEFAULTMAP clause can appear on the TARGET PARALLEL directive
+ !$omp target parallel defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel
+
+ !$omp target parallel map(tofrom:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel
+
+ !ERROR: COPYIN clause is not allowed on the TARGET PARALLEL directive
+ !$omp target parallel copyin(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel
+
+ !$omp target parallel do device(0)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel do
+
+ !ERROR: At most one DEVICE clause can appear on the TARGET PARALLEL DO directive
+ !$omp target parallel do device(0) device(1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel do
+
+ !$omp target parallel do defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel do
+
+ !ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
+ !$omp target parallel do defaultmap(tofrom)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel do
+
+ !ERROR: At most one DEFAULTMAP clause can appear on the TARGET PARALLEL DO directive
+ !$omp target parallel do defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel do
+
+ !$omp target parallel do map(tofrom:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel do
+
+ !$omp target parallel do copyin(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel do
+
+ !$omp target teams map(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !$omp target teams device(0)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: At most one DEVICE clause can appear on the TARGET TEAMS directive
+ !$omp target teams device(0) device(1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: SCHEDULE clause is not allowed on the TARGET TEAMS directive
+ !$omp target teams schedule(static)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !$omp target teams defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
+ !$omp target teams defaultmap(tofrom)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: At most one DEFAULTMAP clause can appear on the TARGET TEAMS directive
+ !$omp target teams defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !$omp target teams num_teams(3) thread_limit(10) default(shared) private(i) shared(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: At most one NUM_TEAMS clause can appear on the TARGET TEAMS directive
+ !$omp target teams num_teams(2) num_teams(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: The parameter of the NUM_TEAMS clause must be a positive integer expression
+ !$omp target teams num_teams(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: At most one THREAD_LIMIT clause can appear on the TARGET TEAMS directive
+ !$omp target teams thread_limit(2) thread_limit(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: The parameter of the THREAD_LIMIT clause must be a positive integer expression
+ !$omp target teams thread_limit(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: At most one DEFAULT clause can appear on the TARGET TEAMS directive
+ !$omp target teams default(shared) default(private)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !$omp target teams num_teams(2) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !$omp target teams map(tofrom:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: Only the TO, FROM, TOFROM, or ALLOC map types are permitted for MAP clauses on the TARGET TEAMS directive
+ !$omp target teams map(delete:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+
+ !$omp target teams distribute map(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !$omp target teams distribute device(0)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: At most one DEVICE clause can appear on the TARGET TEAMS DISTRIBUTE directive
+ !$omp target teams distribute device(0) device(1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !$omp target teams distribute defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
+ !$omp target teams distribute defaultmap(tofrom)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: At most one DEFAULTMAP clause can appear on the TARGET TEAMS DISTRIBUTE directive
+ !$omp target teams distribute defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !$omp target teams distribute num_teams(3) thread_limit(10) default(shared) private(i) shared(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: At most one NUM_TEAMS clause can appear on the TARGET TEAMS DISTRIBUTE directive
+ !$omp target teams distribute num_teams(2) num_teams(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: The parameter of the NUM_TEAMS clause must be a positive integer expression
+ !$omp target teams distribute num_teams(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: At most one THREAD_LIMIT clause can appear on the TARGET TEAMS DISTRIBUTE directive
+ !$omp target teams distribute thread_limit(2) thread_limit(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: The parameter of the THREAD_LIMIT clause must be a positive integer expression
+ !$omp target teams distribute thread_limit(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: At most one DEFAULT clause can appear on the TARGET TEAMS DISTRIBUTE directive
+ !$omp target teams distribute default(shared) default(private)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !$omp target teams distribute num_teams(2) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !$omp target teams distribute map(tofrom:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: Only the TO, FROM, TOFROM, or ALLOC map types are permitted for MAP clauses on the TARGET TEAMS DISTRIBUTE directive
+ !$omp target teams distribute map(delete:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !$omp target teams distribute parallel do device(0)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: At most one DEVICE clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
+ !$omp target teams distribute parallel do device(0) device(1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !$omp target teams distribute parallel do defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
+ !$omp target teams distribute parallel do defaultmap(tofrom)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: At most one DEFAULTMAP clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
+ !$omp target teams distribute parallel do defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !$omp target teams distribute parallel do num_teams(3) thread_limit(10) default(shared) private(i) shared(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: At most one NUM_TEAMS clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
+ !$omp target teams distribute parallel do num_teams(2) num_teams(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: The parameter of the NUM_TEAMS clause must be a positive integer expression
+ !$omp target teams distribute parallel do num_teams(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: At most one THREAD_LIMIT clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
+ !$omp target teams distribute parallel do thread_limit(2) thread_limit(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: The parameter of the THREAD_LIMIT clause must be a positive integer expression
+ !$omp target teams distribute parallel do thread_limit(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: At most one DEFAULT clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
+ !$omp target teams distribute parallel do default(shared) default(private)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !$omp target teams distribute parallel do num_teams(2) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !$omp target teams distribute parallel do map(tofrom:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: Only the TO, FROM, TOFROM, or ALLOC map types are permitted for MAP clauses on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
+ !$omp target teams distribute parallel do map(delete:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+
+ !$omp target teams distribute parallel do simd map(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !$omp target teams distribute parallel do simd device(0)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: At most one DEVICE clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
+ !$omp target teams distribute parallel do simd device(0) device(1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !$omp target teams distribute parallel do simd defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
+ !$omp target teams distribute parallel do simd defaultmap(tofrom)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: At most one DEFAULTMAP clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
+ !$omp target teams distribute parallel do simd defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !$omp target teams distribute parallel do simd num_teams(3) thread_limit(10) default(shared) private(i) shared(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: At most one NUM_TEAMS clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
+ !$omp target teams distribute parallel do simd num_teams(2) num_teams(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: The parameter of the NUM_TEAMS clause must be a positive integer expression
+ !$omp target teams distribute parallel do simd num_teams(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: At most one THREAD_LIMIT clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
+ !$omp target teams distribute parallel do simd thread_limit(2) thread_limit(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: The parameter of the THREAD_LIMIT clause must be a positive integer expression
+ !$omp target teams distribute parallel do simd thread_limit(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: At most one DEFAULT clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
+ !$omp target teams distribute parallel do simd default(shared) default(private)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !$omp target teams distribute parallel do simd num_teams(2) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !$omp target teams distribute parallel do simd map(tofrom:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: Only the TO, FROM, TOFROM, or ALLOC map types are permitted for MAP clauses on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
+ !$omp target teams distribute parallel do simd map(delete:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+
+end program main
+
diff --git a/flang/test/Semantics/omp-device-constructs.f90 b/flang/test/Semantics/omp-device-constructs.f90
index 15daec33580a..23a8d3c58c65 100644
--- a/flang/test/Semantics/omp-device-constructs.f90
+++ b/flang/test/Semantics/omp-device-constructs.f90
@@ -98,6 +98,12 @@ program main
enddo
!$omp end teams
+ !$omp target teams num_teams(2) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end target teams
+
!$omp target map(tofrom:a)
do i = 1, N
a = 3.14
More information about the flang-commits
mailing list