[flang-commits] [flang] 154135c - [flang][OpenMP] Add semantic checks of nesting of region about ordered construct

via flang-commits flang-commits at lists.llvm.org
Wed Apr 13 07:28:54 PDT 2022


Author: PeixinQiao
Date: 2022-04-13T22:27:58+08:00
New Revision: 154135c11c2b53cdaa2f49001830659e47f815fc

URL: https://github.com/llvm/llvm-project/commit/154135c11c2b53cdaa2f49001830659e47f815fc
DIFF: https://github.com/llvm/llvm-project/commit/154135c11c2b53cdaa2f49001830659e47f815fc.diff

LOG: [flang][OpenMP] Add semantic checks of nesting of region about ordered construct

This patch supports the following checks for ORDERED construct:

```
[5.1] 2.19.9 ORDERED Construct
The worksharing-loop or worksharing-loop SIMD region to which an ordered
region corresponding to an ordered construct without a depend clause
binds must have an ordered clause without the parameter specified on the
corresponding worksharing-loop or worksharing-loop SIMD directive.
The worksharing-loop region to which an ordered region that corresponds
to an ordered construct with any depend clauses binds must have an
ordered clause with the parameter specified on the corresponding
worksharing-loop directive.
An ordered construct with the depend clause specified must be closely
nested inside a worksharing-loop (or parallel worksharing-loop)
construct.
An ordered region that corresponds to an ordered construct with the simd
clause specified must be closely nested inside a simd or
worksharing-loop SIMD region.
```

Reviewed By: kiranchandramohan, shraiysh, NimishMishra

Differential Revision: https://reviews.llvm.org/D113399

Added: 
    flang/test/Semantics/omp-ordered02.f90
    flang/test/Semantics/omp-ordered03.f90

Modified: 
    flang/lib/Semantics/check-directive-structure.h
    flang/lib/Semantics/check-omp-structure.cpp
    flang/lib/Semantics/check-omp-structure.h
    flang/test/Semantics/omp-do-ordered-positivecases.f90
    flang/test/Semantics/omp-do-ordered.f90
    flang/test/Semantics/omp-do06.f90
    flang/test/Semantics/omp-ordered-simd.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/check-directive-structure.h b/flang/lib/Semantics/check-directive-structure.h
index c1b00d2cac959..4dc653071ef8e 100644
--- a/flang/lib/Semantics/check-directive-structure.h
+++ b/flang/lib/Semantics/check-directive-structure.h
@@ -250,9 +250,12 @@ class DirectiveStructureChecker : public virtual BaseChecker {
   }
 
   // Check if the given clause is present in the current context
-  const PC *FindClause(C type) {
-    auto it{GetContext().clauseInfo.find(type)};
-    if (it != GetContext().clauseInfo.end()) {
+  const PC *FindClause(C type) { return FindClause(GetContext(), type); }
+
+  // Check if the given clause is present in the given context
+  const PC *FindClause(DirectiveContext &context, C type) {
+    auto it{context.clauseInfo.find(type)};
+    if (it != context.clauseInfo.end()) {
       return it->second;
     }
     return nullptr;

diff  --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 2f8da1120a900..47a860874ae32 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -673,7 +673,6 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
   }
 
   if (CurrentDirectiveIsNested()) {
-    CheckIfDoOrderedClause(beginDir);
     if (llvm::omp::teamSet.test(GetContextParent().directive)) {
       HasInvalidTeamsNesting(beginDir.v, beginDir.source);
     }
@@ -740,27 +739,6 @@ void OmpStructureChecker::CheckMasterNesting(
   }
 }
 
-void OmpStructureChecker::CheckIfDoOrderedClause(
-    const parser::OmpBlockDirective &blkDirective) {
-  if (blkDirective.v == llvm::omp::OMPD_ordered) {
-    // Loops
-    if (llvm::omp::doSet.test(GetContextParent().directive) &&
-        !FindClauseParent(llvm::omp::Clause::OMPC_ordered)) {
-      context_.Say(blkDirective.source,
-          "The ORDERED clause must be present on the loop"
-          " construct if any ORDERED region ever binds"
-          " to a loop region arising from the loop construct."_err_en_US);
-    }
-    // Other disallowed nestings, these directives do not support
-    // ordered clause in them, so no need to check
-    else if (IsCloselyNestedRegion(llvm::omp::nestedOrderedErrSet)) {
-      context_.Say(blkDirective.source,
-          "`ORDERED` region may not be closely nested inside of "
-          "`CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region."_err_en_US);
-    }
-  }
-}
-
 void OmpStructureChecker::Leave(const parser::OpenMPBlockConstruct &) {
   if (GetDirectiveNest(TargetBlockOnlyTeams)) {
     ExitDirectiveNest(TargetBlockOnlyTeams);
@@ -776,6 +754,68 @@ void OmpStructureChecker::ChecksOnOrderedAsBlock() {
     context_.Say(GetContext().clauseSource,
         "DEPEND(*) clauses are not allowed when ORDERED construct is a block"
         " construct with an ORDERED region"_err_en_US);
+    return;
+  }
+
+  OmpDirectiveSet notAllowedParallelSet{llvm::omp::Directive::OMPD_parallel,
+      llvm::omp::Directive::OMPD_target_parallel,
+      llvm::omp::Directive::OMPD_parallel_sections,
+      llvm::omp::Directive::OMPD_parallel_workshare};
+  bool isNestedInDo{false};
+  bool isNestedInDoSIMD{false};
+  bool isNestedInSIMD{false};
+  bool noOrderedClause{false};
+  bool isOrderedClauseWithPara{false};
+  bool isCloselyNestedRegion{true};
+  if (CurrentDirectiveIsNested()) {
+    for (int i = (int)dirContext_.size() - 2; i >= 0; i--) {
+      if (llvm::omp::nestedOrderedErrSet.test(dirContext_[i].directive)) {
+        context_.Say(GetContext().directiveSource,
+            "`ORDERED` region may not be closely nested inside of `CRITICAL`, "
+            "`ORDERED`, explicit `TASK` or `TASKLOOP` region."_err_en_US);
+        break;
+      } else if (llvm::omp::doSet.test(dirContext_[i].directive)) {
+        isNestedInDo = true;
+        isNestedInDoSIMD = llvm::omp::doSimdSet.test(dirContext_[i].directive);
+        if (const auto *clause{
+                FindClause(dirContext_[i], llvm::omp::Clause::OMPC_ordered)}) {
+          const auto &orderedClause{
+              std::get<parser::OmpClause::Ordered>(clause->u)};
+          const auto orderedValue{GetIntValue(orderedClause.v)};
+          isOrderedClauseWithPara = orderedValue > 0;
+        } else {
+          noOrderedClause = true;
+        }
+        break;
+      } else if (llvm::omp::simdSet.test(dirContext_[i].directive)) {
+        isNestedInSIMD = true;
+        break;
+      } else if (notAllowedParallelSet.test(dirContext_[i].directive)) {
+        isCloselyNestedRegion = false;
+        break;
+      }
+    }
+  }
+
+  if (!isCloselyNestedRegion) {
+    context_.Say(GetContext().directiveSource,
+        "An ORDERED directive without the DEPEND clause must be closely nested "
+        "in a SIMD, worksharing-loop, or worksharing-loop SIMD "
+        "region"_err_en_US);
+  } else {
+    if (CurrentDirectiveIsNested() &&
+        FindClause(llvm::omp::Clause::OMPC_simd) &&
+        (!isNestedInDoSIMD && !isNestedInSIMD)) {
+      context_.Say(GetContext().directiveSource,
+          "An ORDERED directive with SIMD clause must be closely nested in a "
+          "SIMD or worksharing-loop SIMD region"_err_en_US);
+    }
+    if (isNestedInDo && (noOrderedClause || isOrderedClauseWithPara)) {
+      context_.Say(GetContext().directiveSource,
+          "An ORDERED directive without the DEPEND clause must be closely "
+          "nested in a worksharing-loop (or worksharing-loop SIMD) region with "
+          "ORDERED clause without the parameter"_err_en_US);
+    }
   }
 }
 
@@ -1063,6 +1103,50 @@ void OmpStructureChecker::ChecksOnOrderedAsStandalone() {
           "region"_err_en_US);
     }
   }
+
+  OmpDirectiveSet allowedDoSet{llvm::omp::Directive::OMPD_do,
+      llvm::omp::Directive::OMPD_parallel_do,
+      llvm::omp::Directive::OMPD_target_parallel_do};
+  bool isNestedInDoOrderedWithPara{false};
+  if (CurrentDirectiveIsNested() &&
+      allowedDoSet.test(GetContextParent().directive)) {
+    if (const auto *clause{
+            FindClause(GetContextParent(), llvm::omp::Clause::OMPC_ordered)}) {
+      const auto &orderedClause{
+          std::get<parser::OmpClause::Ordered>(clause->u)};
+      const auto orderedValue{GetIntValue(orderedClause.v)};
+      if (orderedValue > 0) {
+        isNestedInDoOrderedWithPara = true;
+        CheckOrderedDependClause(orderedValue);
+      }
+    }
+  }
+
+  if (FindClause(llvm::omp::Clause::OMPC_depend) &&
+      !isNestedInDoOrderedWithPara) {
+    context_.Say(GetContext().clauseSource,
+        "An ORDERED construct with the DEPEND clause must be closely nested "
+        "in a worksharing-loop (or parallel worksharing-loop) construct with "
+        "ORDERED clause with a parameter"_err_en_US);
+  }
+}
+
+void OmpStructureChecker::CheckOrderedDependClause(
+    std::optional<std::int64_t> orderedValue) {
+  auto clauseAll{FindClauses(llvm::omp::Clause::OMPC_depend)};
+  for (auto itr = clauseAll.first; itr != clauseAll.second; ++itr) {
+    const auto &dependClause{
+        std::get<parser::OmpClause::Depend>(itr->second->u)};
+    if (const auto *sinkVectors{
+            std::get_if<parser::OmpDependClause::Sink>(&dependClause.v.u)}) {
+      std::int64_t numVar = sinkVectors->v.size();
+      if (orderedValue != numVar) {
+        context_.Say(itr->second->source,
+            "The number of variables in DEPEND(SINK: vec) clause does not "
+            "match the parameter specified in ORDERED clause"_err_en_US);
+      }
+    }
+  }
 }
 
 void OmpStructureChecker::Enter(

diff  --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 88005ad4b64d5..6352b80bfa604 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -241,7 +241,6 @@ class OmpStructureChecker
   void CheckCancellationNest(
       const parser::CharBlock &source, const parser::OmpCancelType::Type &type);
   std::int64_t GetOrdCollapseLevel(const parser::OpenMPLoopConstruct &x);
-  void CheckIfDoOrderedClause(const parser::OmpBlockDirective &blkDirectiv);
   bool CheckReductionOperators(const parser::OmpClause::Reduction &);
   bool CheckIntrinsicOperator(
       const parser::DefinedOperator::IntrinsicOperator &);
@@ -250,6 +249,7 @@ class OmpStructureChecker
   void ChecksOnOrderedAsBlock();
   void CheckBarrierNesting(const parser::OpenMPSimpleStandaloneConstruct &x);
   void ChecksOnOrderedAsStandalone();
+  void CheckOrderedDependClause(std::optional<std::int64_t> orderedValue);
   void CheckReductionArraySection(const parser::OmpObjectList &ompObjectList);
   void CheckIntentInPointerAndDefinable(
       const parser::OmpObjectList &, const llvm::omp::Clause);

diff  --git a/flang/test/Semantics/omp-do-ordered-positivecases.f90 b/flang/test/Semantics/omp-do-ordered-positivecases.f90
index e2f9ec085f78b..91a17215abc36 100644
--- a/flang/test/Semantics/omp-do-ordered-positivecases.f90
+++ b/flang/test/Semantics/omp-do-ordered-positivecases.f90
@@ -30,7 +30,7 @@ program omp_doordered
     end do
   end do
 
-  !$omp do  ordered(1)
+  !$omp do ordered
   !DEF: /omp_doordered/Block3/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
   do i=1,10
     !$omp ordered
@@ -53,7 +53,7 @@ program omp_doordered
   !$omp end do
 
   !$omp parallel  num_threads(4)
-  !$omp do  ordered(1) collapse(1)
+  !$omp do ordered collapse(1)
   !DEF: /omp_doordered/Block5/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
   do i=1,10
     !$omp ordered

diff  --git a/flang/test/Semantics/omp-do-ordered.f90 b/flang/test/Semantics/omp-do-ordered.f90
index 77a8476394970..f0cbd44ef0de1 100644
--- a/flang/test/Semantics/omp-do-ordered.f90
+++ b/flang/test/Semantics/omp-do-ordered.f90
@@ -27,6 +27,7 @@ program omp_doOrdered
   !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
   !$omp do ordered(2)
   do i = 1,10
+    !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
     !$omp ordered
     do j = 1, 10
        print *, "hello"
@@ -48,6 +49,7 @@ program omp_doOrdered
   !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
   !$omp do ordered(2) collapse(1)
   do i = 1,10
+    !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
     !$omp ordered
     do j = 1, 10
        print *, "hello"

diff  --git a/flang/test/Semantics/omp-do06.f90 b/flang/test/Semantics/omp-do06.f90
index 1374e6357585c..7902e688af30c 100644
--- a/flang/test/Semantics/omp-do06.f90
+++ b/flang/test/Semantics/omp-do06.f90
@@ -9,7 +9,7 @@ program omp_do
 
   !$omp do
   do i = 1, 10
-    !ERROR: The ORDERED clause must be present on the loop construct if any ORDERED region ever binds to a loop region arising from the loop construct.
+    !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
     !$omp ordered
     call my_func()
     !$omp end ordered
@@ -21,7 +21,7 @@ program omp_do
     !$omp parallel do
     do j = 1, 10
       print *,i
-      !ERROR: The ORDERED clause must be present on the loop construct if any ORDERED region ever binds to a loop region arising from the loop construct.
+      !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
       !$omp ordered
       print *,i
       !$omp end ordered

diff  --git a/flang/test/Semantics/omp-ordered-simd.f90 b/flang/test/Semantics/omp-ordered-simd.f90
index 3c544e97d9058..a577572a57816 100644
--- a/flang/test/Semantics/omp-ordered-simd.f90
+++ b/flang/test/Semantics/omp-ordered-simd.f90
@@ -26,7 +26,7 @@ SUBROUTINE ORDERED_BAD(N)
   DO I = 1,N
     IF (I <= 10) THEN
       !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
-      !ERROR: The ORDERED clause must be present on the loop construct if any ORDERED region ever binds to a loop region arising from the loop construct.
+      !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
       !$OMP ORDERED 
       CALL WORK(I)
       !$OMP END ORDERED
@@ -37,7 +37,7 @@ SUBROUTINE ORDERED_BAD(N)
   !$OMP PARALLEL DO
   DO I = 1,N
     IF (I <= 10) THEN
-      !ERROR: The ORDERED clause must be present on the loop construct if any ORDERED region ever binds to a loop region arising from the loop construct.
+      !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
       !$OMP ORDERED 
       CALL WORK(I)
       !$OMP END ORDERED

diff  --git a/flang/test/Semantics/omp-ordered02.f90 b/flang/test/Semantics/omp-ordered02.f90
new file mode 100644
index 0000000000000..8b89912fb1457
--- /dev/null
+++ b/flang/test/Semantics/omp-ordered02.f90
@@ -0,0 +1,146 @@
+! RUN: %python %S/test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.19.9 Ordered Construct
+
+subroutine sub1()
+  integer :: i, j, N = 10
+  real :: arrayA(10), arrayB(10)
+  real, external :: foo, bar
+
+  !$omp ordered
+  arrayA(i) = foo(i)
+  !$omp end ordered
+
+  !$omp ordered threads
+  arrayA(i) = foo(i)
+  !$omp end ordered
+
+  !$omp ordered simd
+  arrayA(i) = foo(i)
+  !$omp end ordered
+
+  !$omp sections
+  do i = 1, N
+    !$omp ordered
+    arrayA(i) = foo(i)
+    !$omp end ordered
+  end do
+  !$omp end sections
+
+  !$omp do ordered
+  do i = 1, N
+    arrayB(i) = bar(i)
+    !$omp ordered
+    arrayA(i) = foo(i)
+    !$omp end ordered
+  end do
+  !$omp end do
+
+  !$omp sections
+  do i = 1, N
+    !ERROR: An ORDERED directive with SIMD clause must be closely nested in a SIMD or worksharing-loop SIMD region
+    !$omp ordered simd
+    arrayA(i) = foo(i)
+    !$omp end ordered
+  end do
+  !$omp end sections
+
+  !$omp do ordered
+  do i = 1, N
+    !$omp parallel
+    do j = 1, N
+      !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a SIMD, worksharing-loop, or worksharing-loop SIMD region
+      !$omp ordered
+      arrayA(i) = foo(i)
+      !$omp end ordered
+    end do
+    !$omp end parallel
+  end do
+  !$omp end do
+
+  !$omp do ordered
+  do i = 1, N
+    !$omp target parallel
+    do j = 1, N
+      !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a SIMD, worksharing-loop, or worksharing-loop SIMD region
+      !$omp ordered
+      arrayA(i) = foo(i)
+      !$omp end ordered
+    end do
+    !$omp end target parallel
+  end do
+  !$omp end do
+
+  !$omp do
+  do i = 1, N
+    !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+    !$omp ordered
+    arrayA(i) = foo(i)
+    !$omp end ordered
+  end do
+  !$omp end do
+
+  !$omp do
+  do i = 1, N
+    !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+    !$omp ordered threads
+    arrayA(i) = foo(i)
+    !$omp end ordered
+  end do
+  !$omp end do
+
+  !$omp do ordered(1)
+  do i = 1, N
+    !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+    !$omp ordered
+    arrayA(i) = foo(i)
+    !$omp end ordered
+  end do
+  !$omp end do
+
+  !$omp do ordered(1)
+  do i = 1, N
+    !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+    !$omp ordered threads
+    arrayA(i) = foo(i)
+    !$omp end ordered
+  end do
+  !$omp end do
+
+  !$omp parallel do ordered(1)
+  do i = 1, N
+    !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+    !$omp ordered
+    arrayA(i) = foo(i)
+    !$omp end ordered
+  end do
+  !$omp end parallel do
+
+  !$omp parallel do ordered(1)
+  do i = 1, N
+    !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+    !$omp ordered threads
+    arrayA(i) = foo(i)
+    !$omp end ordered
+  end do
+  !$omp end parallel do
+
+  !$omp target parallel do ordered(1)
+  do i = 1, N
+    !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+    !$omp ordered
+    arrayA(i) = foo(i)
+    !$omp end ordered
+  end do
+  !$omp end target parallel do
+
+  !$omp target parallel do ordered(1)
+  do i = 1, N
+    !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+    !$omp ordered threads
+    arrayA(i) = foo(i)
+    !$omp end ordered
+  end do
+  !$omp end target parallel do
+end

diff  --git a/flang/test/Semantics/omp-ordered03.f90 b/flang/test/Semantics/omp-ordered03.f90
new file mode 100644
index 0000000000000..4d8b28cf43336
--- /dev/null
+++ b/flang/test/Semantics/omp-ordered03.f90
@@ -0,0 +1,122 @@
+! RUN: %python %S/test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.19.9 Ordered Construct
+
+subroutine sub1()
+  integer :: i, j, N = 10
+  real :: arrayA(10), arrayB(10)
+  real, external :: foo, bar
+
+  !$omp do ordered(1)
+  do i = 1, N
+    !$omp ordered depend(source)
+    arrayA(i) = foo(i)
+    !$omp ordered depend(sink: i - 1)
+    arrayB(i) = bar(i - 1)
+  end do
+  !$omp end do
+
+  !$omp do ordered(1)
+  do i = 1, N
+    !$omp target
+    do j = 1, N
+      !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+      !$omp ordered depend(source)
+      arrayA(i) = foo(i)
+      !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+      !$omp ordered depend(sink: i - 1)
+      arrayB(i) = bar(i - 1)
+    end do
+    !$omp end target
+  end do
+  !$omp end do
+
+  !$omp target
+  !$omp parallel do ordered(1)
+  do i = 1, N
+    !$omp ordered depend(source)
+    arrayA(i) = foo(i)
+    !$omp ordered depend(sink: i - 1)
+    arrayB(i) = bar(i - 1)
+  end do
+  !$omp end parallel do
+  !$omp end target
+
+  !$omp target parallel do ordered(1)
+  do i = 1, N
+    !$omp ordered depend(source)
+    arrayA(i) = foo(i)
+    !$omp ordered depend(sink: i - 1)
+    arrayB(i) = bar(i - 1)
+  end do
+  !$omp end target parallel do
+
+  !$omp target teams distribute parallel do ordered(1)
+  do i = 1, N
+    !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+    !$omp ordered depend(source)
+    arrayA(i) = foo(i)
+    !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+    !$omp ordered depend(sink: i - 1)
+    arrayB(i) = bar(i - 1)
+  end do
+  !$omp end target teams distribute parallel do
+
+  !$omp do ordered
+  do i = 1, N
+    !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+    !$omp ordered depend(source)
+    arrayA(i) = foo(i)
+    !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+    !$omp ordered depend(sink: i - 1)
+    arrayB(i) = bar(i - 1)
+  end do
+  !$omp end do
+
+  !$omp parallel do ordered
+  do i = 1, N
+    !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+    !$omp ordered depend(source)
+    arrayA(i) = foo(i)
+    !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+    !$omp ordered depend(sink: i - 1)
+    arrayB(i) = bar(i - 1)
+  end do
+  !$omp end parallel do
+
+  !$omp target parallel do ordered
+  do i = 1, N
+    !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+    !$omp ordered depend(source)
+    arrayA(i) = foo(i)
+    !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+    !$omp ordered depend(sink: i - 1)
+    arrayB(i) = bar(i - 1)
+  end do
+  !$omp end target parallel do
+
+  !$omp do ordered(1)
+  do i = 1, N
+    !ERROR: The number of variables in DEPEND(SINK: vec) clause does not match the parameter specified in ORDERED clause
+    !$omp ordered depend(sink: i - 1) depend(sink: i - 1, j)
+    arrayB(i) = bar(i - 1, j)
+  end do
+  !$omp end do
+
+  !$omp do ordered(2)
+  do i = 1, N
+    do j = 1, N
+      !ERROR: The number of variables in DEPEND(SINK: vec) clause does not match the parameter specified in ORDERED clause
+      !$omp ordered depend(sink: i - 1) depend(sink: i - 1, j)
+      arrayB(i) = foo(i - 1) + bar(i - 1, j)
+    end do
+  end do
+  !$omp end do
+
+  !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+  !$omp ordered depend(source)
+
+  !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+  !$omp ordered depend(sink: i - 1)
+end


        


More information about the flang-commits mailing list