[flang-commits] [flang] 2e26459 - [Flang][OpenMP] Add semantic checks for OpenMP Depend clause.
Praveen G via flang-commits
flang-commits at lists.llvm.org
Mon Nov 16 10:16:50 PST 2020
Author: Praveen G
Date: 2020-11-16T13:11:28-05:00
New Revision: 2e26459fabcab31221c6144633f10883bc1d3926
URL: https://github.com/llvm/llvm-project/commit/2e26459fabcab31221c6144633f10883bc1d3926
DIFF: https://github.com/llvm/llvm-project/commit/2e26459fabcab31221c6144633f10883bc1d3926.diff
LOG: [Flang][OpenMP] Add semantic checks for OpenMP Depend clause.
Add the semantic checks for the OpenMP 4.5 - 2.13.9 Depend clause.
1. List items in depend clause should not be zero length array sections.
2. A variable that is part of another variable like structure component
should not be specified on a depend clause.
Test cases : omp-depend01.f90, omp-depend02.f90, omp-depend03.f90
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D89934
Added:
flang/test/Semantics/omp-depend01.f90
flang/test/Semantics/omp-depend02.f90
flang/test/Semantics/omp-depend03.f90
Modified:
flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/check-omp-structure.h
Removed:
################################################################################
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 56eeed259697..93787672b444 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -424,7 +424,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) {
// Following clauses have a seperate node in parse-tree.h.
CHECK_SIMPLE_PARSER_CLAUSE(OmpAllocateClause, OMPC_allocate)
CHECK_SIMPLE_PARSER_CLAUSE(OmpDefaultClause, OMPC_default)
-CHECK_SIMPLE_PARSER_CLAUSE(OmpDependClause, OMPC_depend)
CHECK_SIMPLE_PARSER_CLAUSE(OmpDistScheduleClause, OMPC_dist_schedule)
CHECK_SIMPLE_PARSER_CLAUSE(OmpNowait, OMPC_nowait)
CHECK_SIMPLE_PARSER_CLAUSE(OmpProcBindClause, OMPC_proc_bind)
@@ -597,6 +596,23 @@ void OmpStructureChecker::Enter(const parser::OmpScheduleClause &x) {
}
}
+void OmpStructureChecker::Enter(const parser::OmpDependClause &x) {
+ CheckAllowed(llvm::omp::Clause::OMPC_depend);
+ if (const auto *inOut{std::get_if<parser::OmpDependClause::InOut>(&x.u)}) {
+ const auto &designators{std::get<std::list<parser::Designator>>(inOut->t)};
+ for (const auto &ele : designators) {
+ if (const auto *dataRef{std::get_if<parser::DataRef>(&ele.u)}) {
+ CheckDependList(*dataRef);
+ if (const auto *arr{
+ std::get_if<common::Indirection<parser::ArrayElement>>(
+ &dataRef->u)}) {
+ CheckDependArraySection(*arr, GetLastName(*dataRef));
+ }
+ }
+ }
+ }
+}
+
llvm::StringRef OmpStructureChecker::getClauseName(llvm::omp::Clause clause) {
return llvm::omp::getOpenMPClauseName(clause);
}
@@ -606,4 +622,54 @@ llvm::StringRef OmpStructureChecker::getDirectiveName(
return llvm::omp::getOpenMPDirectiveName(directive);
}
+void OmpStructureChecker::CheckDependList(const parser::DataRef &d) {
+ std::visit(
+ common::visitors{
+ [&](const common::Indirection<parser::ArrayElement> &elem) {
+ // Check if the base element is valid on Depend Clause
+ CheckDependList(elem.value().base);
+ },
+ [&](const common::Indirection<parser::StructureComponent> &) {
+ context_.Say(GetContext().clauseSource,
+ "A variable that is part of another variable "
+ "(such as an element of a structure) but is not an array "
+ "element or an array section cannot appear in a DEPEND "
+ "clause"_err_en_US);
+ },
+ [&](const common::Indirection<parser::CoindexedNamedObject> &) {
+ context_.Say(GetContext().clauseSource,
+ "Coarrays are not supported in DEPEND clause"_err_en_US);
+ },
+ [&](const parser::Name &) { return; },
+ },
+ d.u);
+}
+
+void OmpStructureChecker::CheckDependArraySection(
+ const common::Indirection<parser::ArrayElement> &arr,
+ const parser::Name &name) {
+ for (const auto &subscript : arr.value().subscripts) {
+ if (const auto *triplet{
+ std::get_if<parser::SubscriptTriplet>(&subscript.u)}) {
+ if (std::get<2>(triplet->t)) {
+ context_.Say(GetContext().clauseSource,
+ "Stride should not be specified for array section in DEPEND "
+ "clause"_err_en_US);
+ }
+ const auto &lower{std::get<0>(triplet->t)};
+ const auto &upper{std::get<1>(triplet->t)};
+ if (lower && upper) {
+ const auto lval{GetIntValue(lower)};
+ const auto uval{GetIntValue(upper)};
+ if (lval && uval && *uval < *lval) {
+ context_.Say(GetContext().clauseSource,
+ "'%s' in DEPEND clause is a zero size array section"_err_en_US,
+ name.ToString());
+ break;
+ }
+ }
+ }
+ }
+}
+
} // namespace Fortran::semantics
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 738ceabb8a22..fbb319f30f9f 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -165,7 +165,6 @@ class OmpStructureChecker
void Enter(const parser::OmpScheduleClause &);
private:
-
bool HasInvalidWorksharingNesting(
const parser::CharBlock &, const OmpDirectiveSet &);
@@ -175,6 +174,10 @@ class OmpStructureChecker
llvm::StringRef getClauseName(llvm::omp::Clause clause) override;
llvm::StringRef getDirectiveName(llvm::omp::Directive directive) override;
+
+ void CheckDependList(const parser::DataRef &);
+ void CheckDependArraySection(
+ const common::Indirection<parser::ArrayElement> &, const parser::Name &);
};
} // namespace Fortran::semantics
#endif // FORTRAN_SEMANTICS_CHECK_OMP_STRUCTURE_H_
diff --git a/flang/test/Semantics/omp-depend01.f90 b/flang/test/Semantics/omp-depend01.f90
new file mode 100644
index 000000000000..c40b8c652c8d
--- /dev/null
+++ b/flang/test/Semantics/omp-depend01.f90
@@ -0,0 +1,28 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
+! OpenMP Version 4.5
+! 2.13.9 Depend Clause
+! List items used in depend clauses cannot be zero-length array sections.
+
+program omp_depend
+ integer :: a(10) , b(10,10)
+ a = 10
+ b = 20
+
+ !$omp parallel
+ !$omp single
+
+ !ERROR: 'a' in DEPEND clause is a zero size array section
+ !ERROR: 'b' in DEPEND clause is a zero size array section
+ !$omp task shared(a,b) depend(out: a(2:1), b(3:1, 1:-1))
+ a(2:1) = b(2, 2)
+ !$omp end task
+
+ !ERROR: Stride should not be specified for array section in DEPEND clause
+ !$omp task shared(x) depend(in: a(5:10:1))
+ print *, a(5:10), b
+ !$omp end task
+
+ !$omp end single
+ !$omp end parallel
+
+end program omp_depend
diff --git a/flang/test/Semantics/omp-depend02.f90 b/flang/test/Semantics/omp-depend02.f90
new file mode 100644
index 000000000000..20c2fee69afa
--- /dev/null
+++ b/flang/test/Semantics/omp-depend02.f90
@@ -0,0 +1,49 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
+! OpenMP Version 4.5
+! 2.13.9 Depend Clause
+! A variable that is part of another variable
+! (such as an element of a structure) but is not an array element or
+! an array section cannot appear in a DEPEND clause
+
+subroutine vec_mult(N)
+ implicit none
+ integer :: i, N
+ real, allocatable :: p(:), v1(:), v2(:)
+
+ type my_type
+ integer :: a(10)
+ end type my_type
+
+ type(my_type) :: my_var
+ allocate( p(N), v1(N), v2(N) )
+
+ !$omp parallel num_threads(2)
+ !$omp single
+
+ !$omp task depend(out:v1)
+ call init(v1, N)
+ !$omp end task
+
+ !$omp task depend(out:v2)
+ call init(v2, N)
+ !$omp end task
+
+ !ERROR: A variable that is part of another variable (such as an element of a structure) but is not an array element or an array section cannot appear in a DEPEND clause
+ !$omp target nowait depend(in:v1,v2, my_var%a) depend(out:p) &
+ !$omp& map(to:v1,v2) map(from: p)
+ !$omp parallel do
+ do i=1,N
+ p(i) = v1(i) * v2(i)
+ end do
+ !$omp end target
+
+ !$omp task depend(in:p)
+ call output(p, N)
+ !$omp end task
+
+ !$omp end single
+ !$omp end parallel
+
+ deallocate( p, v1, v2 )
+
+end subroutine
diff --git a/flang/test/Semantics/omp-depend03.f90 b/flang/test/Semantics/omp-depend03.f90
new file mode 100644
index 000000000000..32dd73899651
--- /dev/null
+++ b/flang/test/Semantics/omp-depend03.f90
@@ -0,0 +1,24 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
+! OpenMP Version 4.5
+! 2.13.9 Depend Clause
+! Coarrays are not supported in depend clause
+
+program omp_depend_coarray
+ integer :: a(3)[*], b(3) , k
+
+ a(:) = this_image()
+ b(:) = a(:)[1]
+ k = 10
+
+ !$omp parallel
+ !$omp single
+ !ERROR: Coarrays are not supported in DEPEND clause
+ !$omp task shared(b) depend(out: a(:)[1])
+ b = a + k
+ !$omp end task
+ !$omp end single
+ !$omp end parallel
+
+ print *, a, b
+
+end program omp_depend_coarray
More information about the flang-commits
mailing list