[llvm-branch-commits] [flang] [flang][openmp] Add parser/semantic support for workdistribute (PR #154377)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Aug 21 00:06:27 PDT 2025
https://github.com/skc7 updated https://github.com/llvm/llvm-project/pull/154377
>From 4442fced8216bf8e26522e2b88884b127e4cfc40 Mon Sep 17 00:00:00 2001
From: skc7 <Krishna.Sankisa at amd.com>
Date: Tue, 19 Aug 2025 21:43:06 +0530
Subject: [PATCH 1/2] [flang][openmp] Add parser/semantic support for
workdistribute
---
.../flang/Semantics/openmp-directive-sets.h | 7 ++
flang/lib/Parser/openmp-parsers.cpp | 6 +-
flang/lib/Semantics/check-omp-structure.cpp | 95 +++++++++++++++++++
flang/lib/Semantics/check-omp-structure.h | 1 +
flang/lib/Semantics/resolve-directives.cpp | 8 +-
flang/test/Parser/OpenMP/workdistribute.f90 | 27 ++++++
.../Semantics/OpenMP/workdistribute01.f90 | 16 ++++
.../Semantics/OpenMP/workdistribute02.f90 | 34 +++++++
.../Semantics/OpenMP/workdistribute03.f90 | 34 +++++++
9 files changed, 226 insertions(+), 2 deletions(-)
create mode 100644 flang/test/Parser/OpenMP/workdistribute.f90
create mode 100644 flang/test/Semantics/OpenMP/workdistribute01.f90
create mode 100644 flang/test/Semantics/OpenMP/workdistribute02.f90
create mode 100644 flang/test/Semantics/OpenMP/workdistribute03.f90
diff --git a/flang/include/flang/Semantics/openmp-directive-sets.h b/flang/include/flang/Semantics/openmp-directive-sets.h
index cc66cc833e8b7..01e8481e05721 100644
--- a/flang/include/flang/Semantics/openmp-directive-sets.h
+++ b/flang/include/flang/Semantics/openmp-directive-sets.h
@@ -143,6 +143,7 @@ static const OmpDirectiveSet topTargetSet{
Directive::OMPD_target_teams_distribute_parallel_do_simd,
Directive::OMPD_target_teams_distribute_simd,
Directive::OMPD_target_teams_loop,
+ Directive::OMPD_target_teams_workdistribute,
};
static const OmpDirectiveSet allTargetSet{topTargetSet};
@@ -172,6 +173,7 @@ static const OmpDirectiveSet topTeamsSet{
Directive::OMPD_teams_distribute_parallel_do_simd,
Directive::OMPD_teams_distribute_simd,
Directive::OMPD_teams_loop,
+ Directive::OMPD_teams_workdistribute,
};
static const OmpDirectiveSet bottomTeamsSet{
@@ -187,6 +189,7 @@ static const OmpDirectiveSet allTeamsSet{
Directive::OMPD_target_teams_distribute_parallel_do_simd,
Directive::OMPD_target_teams_distribute_simd,
Directive::OMPD_target_teams_loop,
+ Directive::OMPD_target_teams_workdistribute,
} | topTeamsSet,
};
@@ -230,6 +233,9 @@ static const OmpDirectiveSet blockConstructSet{
Directive::OMPD_taskgroup,
Directive::OMPD_teams,
Directive::OMPD_workshare,
+ Directive::OMPD_target_teams_workdistribute,
+ Directive::OMPD_teams_workdistribute,
+ Directive::OMPD_workdistribute,
};
static const OmpDirectiveSet loopConstructSet{
@@ -376,6 +382,7 @@ static const OmpDirectiveSet nestedReduceWorkshareAllowedSet{
};
static const OmpDirectiveSet nestedTeamsAllowedSet{
+ Directive::OMPD_workdistribute,
Directive::OMPD_distribute,
Directive::OMPD_distribute_parallel_do,
Directive::OMPD_distribute_parallel_do_simd,
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 56cee4ab38e9b..51b49a591b02f 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1870,11 +1870,15 @@ TYPE_PARSER( //
MakeBlockConstruct(llvm::omp::Directive::OMPD_target_data) ||
MakeBlockConstruct(llvm::omp::Directive::OMPD_target_parallel) ||
MakeBlockConstruct(llvm::omp::Directive::OMPD_target_teams) ||
+ MakeBlockConstruct(
+ llvm::omp::Directive::OMPD_target_teams_workdistribute) ||
MakeBlockConstruct(llvm::omp::Directive::OMPD_target) ||
MakeBlockConstruct(llvm::omp::Directive::OMPD_task) ||
MakeBlockConstruct(llvm::omp::Directive::OMPD_taskgroup) ||
MakeBlockConstruct(llvm::omp::Directive::OMPD_teams) ||
- MakeBlockConstruct(llvm::omp::Directive::OMPD_workshare))
+ MakeBlockConstruct(llvm::omp::Directive::OMPD_teams_workdistribute) ||
+ MakeBlockConstruct(llvm::omp::Directive::OMPD_workshare) ||
+ MakeBlockConstruct(llvm::omp::Directive::OMPD_workdistribute))
#undef MakeBlockConstruct
// OMP SECTIONS Directive
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 2b36b085ae08d..4c4e17c39c03a 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -141,6 +141,67 @@ class OmpWorkshareBlockChecker {
parser::CharBlock source_;
};
+// 'OmpWorkdistributeBlockChecker' is used to check the validity of the
+// assignment statements and the expressions enclosed in an OpenMP
+// workdistribute construct
+class OmpWorkdistributeBlockChecker {
+public:
+ OmpWorkdistributeBlockChecker(
+ SemanticsContext &context, parser::CharBlock source)
+ : context_{context}, source_{source} {}
+
+ template <typename T> bool Pre(const T &) { return true; }
+ template <typename T> void Post(const T &) {}
+
+ bool Pre(const parser::AssignmentStmt &assignment) {
+ const auto &var{std::get<parser::Variable>(assignment.t)};
+ const auto &expr{std::get<parser::Expr>(assignment.t)};
+ const auto *lhs{GetExpr(context_, var)};
+ const auto *rhs{GetExpr(context_, expr)};
+ if (lhs && rhs) {
+ Tristate isDefined{semantics::IsDefinedAssignment(
+ lhs->GetType(), lhs->Rank(), rhs->GetType(), rhs->Rank())};
+ if (isDefined == Tristate::Yes) {
+ context_.Say(expr.source,
+ "Defined assignment statement is not "
+ "allowed in a WORKDISTRIBUTE construct"_err_en_US);
+ }
+ }
+ return true;
+ }
+
+ bool Pre(const parser::Expr &expr) {
+ if (const auto *e{GetExpr(context_, expr)}) {
+ for (const Symbol &symbol : evaluate::CollectSymbols(*e)) {
+ const Symbol &root{GetAssociationRoot(symbol)};
+ if (IsFunction(root)) {
+ std::string attrs{""};
+ if (!IsElementalProcedure(root)) {
+ attrs = " non-ELEMENTAL";
+ }
+ if (root.attrs().test(Attr::IMPURE)) {
+ if (attrs != "") {
+ attrs = "," + attrs;
+ }
+ attrs = " IMPURE" + attrs;
+ }
+ if (attrs != "") {
+ context_.Say(expr.source,
+ "User defined%s function '%s' is not allowed in a "
+ "WORKDISTRIBUTE construct"_err_en_US,
+ attrs, root.name());
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+private:
+ SemanticsContext &context_;
+ parser::CharBlock source_;
+};
+
// `OmpUnitedTaskDesignatorChecker` is used to check if the designator
// can appear within the TASK construct
class OmpUnitedTaskDesignatorChecker {
@@ -813,6 +874,13 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
"TARGET construct with nested TEAMS region contains statements or "
"directives outside of the TEAMS construct"_err_en_US);
}
+ if (GetContext().directive == llvm::omp::Directive::OMPD_workdistribute &&
+ GetContextParent().directive != llvm::omp::Directive::OMPD_teams) {
+ context_.Say(x.BeginDir().DirName().source,
+ "%s region can only be strictly nested within the "
+ "teams region"_err_en_US,
+ ContextDirectiveAsFortran());
+ }
}
CheckNoBranching(block, beginSpec.DirId(), beginSpec.source);
@@ -896,6 +964,17 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
HasInvalidWorksharingNesting(
beginSpec.source, llvm::omp::nestedWorkshareErrSet);
break;
+ case llvm::omp::OMPD_workdistribute:
+ if (!CurrentDirectiveIsNested()) {
+ context_.Say(beginSpec.source,
+ "A workdistribute region must be nested inside teams region only."_err_en_US);
+ }
+ CheckWorkdistributeBlockStmts(block, beginSpec.source);
+ break;
+ case llvm::omp::OMPD_teams_workdistribute:
+ case llvm::omp::OMPD_target_teams_workdistribute:
+ CheckWorkdistributeBlockStmts(block, beginSpec.source);
+ break;
case llvm::omp::Directive::OMPD_scope:
case llvm::omp::Directive::OMPD_single:
// TODO: This check needs to be extended while implementing nesting of
@@ -4497,6 +4576,22 @@ void OmpStructureChecker::CheckWorkshareBlockStmts(
}
}
+void OmpStructureChecker::CheckWorkdistributeBlockStmts(
+ const parser::Block &block, parser::CharBlock source) {
+ OmpWorkdistributeBlockChecker ompWorkdistributeBlockChecker{context_, source};
+
+ for (auto it{block.begin()}; it != block.end(); ++it) {
+ if (parser::Unwrap<parser::AssignmentStmt>(*it)) {
+ parser::Walk(*it, ompWorkdistributeBlockChecker);
+ } else {
+ context_.Say(source,
+ "The structured block in a WORKDISTRIBUTE construct may consist of "
+ "only "
+ "SCALAR or ARRAY assignments"_err_en_US);
+ }
+ }
+}
+
void OmpStructureChecker::CheckIfContiguous(const parser::OmpObject &object) {
if (auto contig{IsContiguous(context_, object)}; contig && !*contig) {
const parser::Name *name{GetObjectName(object)};
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index b548a455ee077..08519c4836ed8 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -245,6 +245,7 @@ class OmpStructureChecker
llvmOmpClause clause, const parser::OmpObjectList &ompObjectList);
bool CheckTargetBlockOnlyTeams(const parser::Block &);
void CheckWorkshareBlockStmts(const parser::Block &, parser::CharBlock);
+ void CheckWorkdistributeBlockStmts(const parser::Block &, parser::CharBlock);
void CheckIteratorRange(const parser::OmpIteratorSpecifier &x);
void CheckIteratorModifier(const parser::OmpIterator &x);
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 6a4660c9882ab..069d78554e9c2 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1736,10 +1736,13 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
case llvm::omp::Directive::OMPD_task:
case llvm::omp::Directive::OMPD_taskgroup:
case llvm::omp::Directive::OMPD_teams:
+ case llvm::omp::Directive::OMPD_workdistribute:
case llvm::omp::Directive::OMPD_workshare:
case llvm::omp::Directive::OMPD_parallel_workshare:
case llvm::omp::Directive::OMPD_target_teams:
+ case llvm::omp::Directive::OMPD_target_teams_workdistribute:
case llvm::omp::Directive::OMPD_target_parallel:
+ case llvm::omp::Directive::OMPD_teams_workdistribute:
PushContext(dirSpec.source, dirId);
break;
default:
@@ -1769,9 +1772,12 @@ void OmpAttributeVisitor::Post(const parser::OpenMPBlockConstruct &x) {
case llvm::omp::Directive::OMPD_target:
case llvm::omp::Directive::OMPD_task:
case llvm::omp::Directive::OMPD_teams:
+ case llvm::omp::Directive::OMPD_workdistribute:
case llvm::omp::Directive::OMPD_parallel_workshare:
case llvm::omp::Directive::OMPD_target_teams:
- case llvm::omp::Directive::OMPD_target_parallel: {
+ case llvm::omp::Directive::OMPD_target_parallel:
+ case llvm::omp::Directive::OMPD_target_teams_workdistribute:
+ case llvm::omp::Directive::OMPD_teams_workdistribute: {
bool hasPrivate;
for (const auto *allocName : allocateNames_) {
hasPrivate = false;
diff --git a/flang/test/Parser/OpenMP/workdistribute.f90 b/flang/test/Parser/OpenMP/workdistribute.f90
new file mode 100644
index 0000000000000..874538d5f0296
--- /dev/null
+++ b/flang/test/Parser/OpenMP/workdistribute.f90
@@ -0,0 +1,27 @@
+!RUN: %flang_fc1 -fdebug-unparse -fopenmp %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
+
+!UNPARSE: SUBROUTINE teams_workdistribute
+!UNPARSE: USE :: iso_fortran_env
+!UNPARSE: REAL(KIND=4_4) a
+!UNPARSE: REAL(KIND=4_4), DIMENSION(10_4) :: x
+!UNPARSE: REAL(KIND=4_4), DIMENSION(10_4) :: y
+!UNPARSE: !$OMP TEAMS WORKDISTRIBUTE
+!UNPARSE: y=a*x+y
+!UNPARSE: !$OMP END TEAMS WORKDISTRIBUTE
+!UNPARSE: END SUBROUTINE teams_workdistribute
+
+!PARSE-TREE: | | | OmpBeginDirective
+!PARSE-TREE: | | | | OmpDirectiveName -> llvm::omp::Directive = teams workdistribute
+!PARSE-TREE: | | | OmpEndDirective
+!PARSE-TREE: | | | | OmpDirectiveName -> llvm::omp::Directive = teams workdistribute
+
+subroutine teams_workdistribute()
+ use iso_fortran_env
+ real(kind=real32) :: a
+ real(kind=real32), dimension(10) :: x
+ real(kind=real32), dimension(10) :: y
+ !$omp teams workdistribute
+ y = a * x + y
+ !$omp end teams workdistribute
+end subroutine teams_workdistribute
diff --git a/flang/test/Semantics/OpenMP/workdistribute01.f90 b/flang/test/Semantics/OpenMP/workdistribute01.f90
new file mode 100644
index 0000000000000..76ddbc74ea4ec
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/workdistribute01.f90
@@ -0,0 +1,16 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 6.0
+! workdistribute Construct
+! Invalid do construct inside !$omp workdistribute
+
+subroutine workdistribute()
+ integer n, i
+ !ERROR: A workdistribute region must be nested inside teams region only.
+ !ERROR: The structured block in a WORKDISTRIBUTE construct may consist of only SCALAR or ARRAY assignments
+ !$omp workdistribute
+ do i = 1, n
+ print *, "omp workdistribute"
+ end do
+ !$omp end workdistribute
+
+end subroutine workdistribute
diff --git a/flang/test/Semantics/OpenMP/workdistribute02.f90 b/flang/test/Semantics/OpenMP/workdistribute02.f90
new file mode 100644
index 0000000000000..ad2cde2c3daf0
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/workdistribute02.f90
@@ -0,0 +1,34 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 6.0
+! workdistribute Construct
+! The !omp workdistribute construct must not contain any user defined
+! function calls unless the function is ELEMENTAL.
+
+module my_mod
+ contains
+ integer function my_func()
+ my_func = 10
+ end function my_func
+
+ impure integer function impure_my_func()
+ impure_my_func = 20
+ end function impure_my_func
+
+ impure elemental integer function impure_ele_my_func()
+ impure_ele_my_func = 20
+ end function impure_ele_my_func
+end module my_mod
+
+subroutine workdistribute(aa, bb, cc, n)
+ use my_mod
+ integer n
+ real aa(n), bb(n), cc(n)
+ !$omp teams
+ !$omp workdistribute
+ !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKDISTRIBUTE construct
+ aa = my_func()
+ aa = bb * cc
+ !$omp end workdistribute
+ !$omp end teams
+
+end subroutine workdistribute
diff --git a/flang/test/Semantics/OpenMP/workdistribute03.f90 b/flang/test/Semantics/OpenMP/workdistribute03.f90
new file mode 100644
index 0000000000000..eac28cb39c47f
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/workdistribute03.f90
@@ -0,0 +1,34 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 6.0
+! workdistribute Construct
+! All array assignments, scalar assignments, and masked array assignments
+! must be intrinsic assignments.
+
+module defined_assign
+ interface assignment(=)
+ module procedure work_assign
+ end interface
+
+ contains
+ subroutine work_assign(a,b)
+ integer, intent(out) :: a
+ logical, intent(in) :: b(:)
+ end subroutine work_assign
+end module defined_assign
+
+program omp_workdistribute
+ use defined_assign
+
+ integer :: a, aa(10), bb(10)
+ logical :: l(10)
+ l = .TRUE.
+
+ !$omp teams
+ !$omp workdistribute
+ !ERROR: Defined assignment statement is not allowed in a WORKDISTRIBUTE construct
+ a = l
+ aa = bb
+ !$omp end workdistribute
+ !$omp end teams
+
+end program omp_workdistribute
>From 029719370c496c83a7892be69be13d0eda7580c7 Mon Sep 17 00:00:00 2001
From: skc7 <Krishna.Sankisa at amd.com>
Date: Thu, 21 Aug 2025 12:23:17 +0530
Subject: [PATCH 2/2] Fix error messages.
---
flang/lib/Semantics/check-omp-structure.cpp | 41 +++++++++----------
flang/test/Parser/OpenMP/workdistribute.f90 | 4 +-
.../Semantics/OpenMP/workdistribute01.f90 | 4 +-
.../Semantics/OpenMP/workdistribute02.f90 | 2 +-
.../Semantics/OpenMP/workdistribute03.f90 | 2 +-
.../Semantics/OpenMP/workdistribute04.f90 | 15 +++++++
6 files changed, 41 insertions(+), 27 deletions(-)
create mode 100644 flang/test/Semantics/OpenMP/workdistribute04.f90
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 4c4e17c39c03a..6f76c9a4420e7 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -143,7 +143,7 @@ class OmpWorkshareBlockChecker {
// 'OmpWorkdistributeBlockChecker' is used to check the validity of the
// assignment statements and the expressions enclosed in an OpenMP
-// workdistribute construct
+// WORKDISTRIBUTE construct
class OmpWorkdistributeBlockChecker {
public:
OmpWorkdistributeBlockChecker(
@@ -163,8 +163,7 @@ class OmpWorkdistributeBlockChecker {
lhs->GetType(), lhs->Rank(), rhs->GetType(), rhs->Rank())};
if (isDefined == Tristate::Yes) {
context_.Say(expr.source,
- "Defined assignment statement is not "
- "allowed in a WORKDISTRIBUTE construct"_err_en_US);
+ "Defined assignment statement is not allowed in a WORKDISTRIBUTE construct"_err_en_US);
}
}
return true;
@@ -172,25 +171,23 @@ class OmpWorkdistributeBlockChecker {
bool Pre(const parser::Expr &expr) {
if (const auto *e{GetExpr(context_, expr)}) {
+ if (!e)
+ return false;
for (const Symbol &symbol : evaluate::CollectSymbols(*e)) {
const Symbol &root{GetAssociationRoot(symbol)};
if (IsFunction(root)) {
- std::string attrs{""};
+ std::vector<std::string> attrs;
if (!IsElementalProcedure(root)) {
- attrs = " non-ELEMENTAL";
+ attrs.push_back("non-ELEMENTAL");
}
if (root.attrs().test(Attr::IMPURE)) {
- if (attrs != "") {
- attrs = "," + attrs;
- }
- attrs = " IMPURE" + attrs;
- }
- if (attrs != "") {
- context_.Say(expr.source,
- "User defined%s function '%s' is not allowed in a "
- "WORKDISTRIBUTE construct"_err_en_US,
- attrs, root.name());
+ attrs.push_back("IMPURE");
}
+ std::string attrsStr =
+ attrs.empty() ? "" : " " + llvm::join(attrs, ", ");
+ context_.Say(expr.source,
+ "User defined%s function '%s' is not allowed in a WORKDISTRIBUTE construct"_err_en_US,
+ attrsStr, root.name());
}
}
}
@@ -877,8 +874,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
if (GetContext().directive == llvm::omp::Directive::OMPD_workdistribute &&
GetContextParent().directive != llvm::omp::Directive::OMPD_teams) {
context_.Say(x.BeginDir().DirName().source,
- "%s region can only be strictly nested within the "
- "teams region"_err_en_US,
+ "%s region can only be strictly nested within TEAMS region"_err_en_US,
ContextDirectiveAsFortran());
}
}
@@ -967,7 +963,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
case llvm::omp::OMPD_workdistribute:
if (!CurrentDirectiveIsNested()) {
context_.Say(beginSpec.source,
- "A workdistribute region must be nested inside teams region only."_err_en_US);
+ "A WORKDISTRIBUTE region must be nested inside TEAMS region only."_err_en_US);
}
CheckWorkdistributeBlockStmts(block, beginSpec.source);
break;
@@ -4578,6 +4574,11 @@ void OmpStructureChecker::CheckWorkshareBlockStmts(
void OmpStructureChecker::CheckWorkdistributeBlockStmts(
const parser::Block &block, parser::CharBlock source) {
+ unsigned version{context_.langOptions().OpenMPVersion};
+ if (version < 60)
+ context_.Say(source,
+ "WORKDISTRIBUTE construct is only supported from openMP 6.0"_err_en_US);
+
OmpWorkdistributeBlockChecker ompWorkdistributeBlockChecker{context_, source};
for (auto it{block.begin()}; it != block.end(); ++it) {
@@ -4585,9 +4586,7 @@ void OmpStructureChecker::CheckWorkdistributeBlockStmts(
parser::Walk(*it, ompWorkdistributeBlockChecker);
} else {
context_.Say(source,
- "The structured block in a WORKDISTRIBUTE construct may consist of "
- "only "
- "SCALAR or ARRAY assignments"_err_en_US);
+ "The structured block in a WORKDISTRIBUTE construct may consist of only SCALAR or ARRAY assignments"_err_en_US);
}
}
}
diff --git a/flang/test/Parser/OpenMP/workdistribute.f90 b/flang/test/Parser/OpenMP/workdistribute.f90
index 874538d5f0296..09273ab0485cd 100644
--- a/flang/test/Parser/OpenMP/workdistribute.f90
+++ b/flang/test/Parser/OpenMP/workdistribute.f90
@@ -1,5 +1,5 @@
-!RUN: %flang_fc1 -fdebug-unparse -fopenmp %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
+!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=60 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
+!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=60 %s | FileCheck --check-prefix="PARSE-TREE" %s
!UNPARSE: SUBROUTINE teams_workdistribute
!UNPARSE: USE :: iso_fortran_env
diff --git a/flang/test/Semantics/OpenMP/workdistribute01.f90 b/flang/test/Semantics/OpenMP/workdistribute01.f90
index 76ddbc74ea4ec..f7e36976dfb65 100644
--- a/flang/test/Semantics/OpenMP/workdistribute01.f90
+++ b/flang/test/Semantics/OpenMP/workdistribute01.f90
@@ -1,11 +1,11 @@
-! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=60
! OpenMP Version 6.0
! workdistribute Construct
! Invalid do construct inside !$omp workdistribute
subroutine workdistribute()
integer n, i
- !ERROR: A workdistribute region must be nested inside teams region only.
+ !ERROR: A WORKDISTRIBUTE region must be nested inside TEAMS region only.
!ERROR: The structured block in a WORKDISTRIBUTE construct may consist of only SCALAR or ARRAY assignments
!$omp workdistribute
do i = 1, n
diff --git a/flang/test/Semantics/OpenMP/workdistribute02.f90 b/flang/test/Semantics/OpenMP/workdistribute02.f90
index ad2cde2c3daf0..6de3a55f545b5 100644
--- a/flang/test/Semantics/OpenMP/workdistribute02.f90
+++ b/flang/test/Semantics/OpenMP/workdistribute02.f90
@@ -1,4 +1,4 @@
-! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=60
! OpenMP Version 6.0
! workdistribute Construct
! The !omp workdistribute construct must not contain any user defined
diff --git a/flang/test/Semantics/OpenMP/workdistribute03.f90 b/flang/test/Semantics/OpenMP/workdistribute03.f90
index eac28cb39c47f..828170a016ed2 100644
--- a/flang/test/Semantics/OpenMP/workdistribute03.f90
+++ b/flang/test/Semantics/OpenMP/workdistribute03.f90
@@ -1,4 +1,4 @@
-! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=60
! OpenMP Version 6.0
! workdistribute Construct
! All array assignments, scalar assignments, and masked array assignments
diff --git a/flang/test/Semantics/OpenMP/workdistribute04.f90 b/flang/test/Semantics/OpenMP/workdistribute04.f90
new file mode 100644
index 0000000000000..7f8e358279bc6
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/workdistribute04.f90
@@ -0,0 +1,15 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50
+! OpenMP Version 6.0
+! workdistribute Construct
+! Invalid do construct inside !$omp workdistribute
+
+subroutine teams_workdistribute()
+ use iso_fortran_env
+ real(kind=real32) :: a
+ real(kind=real32), dimension(10) :: x
+ real(kind=real32), dimension(10) :: y
+ !ERROR: WORKDISTRIBUTE construct is only supported from openMP 6.0
+ !$omp teams workdistribute
+ y = a * x + y
+ !$omp end teams workdistribute
+end subroutine teams_workdistribute
More information about the llvm-branch-commits
mailing list