[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