[clang] f70967f - [OPENMP52] Support Support omp_cur_iteration modifier for doacross

Jennifer Yu via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 6 11:53:35 PDT 2023


Author: Jennifer Yu
Date: 2023-07-06T11:40:02-07:00
New Revision: f70967fdc4736a5c5150db294be55fa9e7792bb8

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

LOG: [OPENMP52] Support Support omp_cur_iteration modifier for doacross
clause.

This is just syntax to make it easier for the user. It doesn't add any
new functionality.

for
doacross(sink: omp_cur_iteration - 1)
Equivalent to
doacross(sink: ConterVar - 1, ...)

doacross(source: omp_cur_iteration)
Equivalent to
doacross(source)

And restriction is:
OMP5.2 p.327

If vector is specified with the omp_cur_iteration keyword and with
sink as the dependence-type then it must be omp_cur_iteration - 1.

If vector is specified with source as the dependence-type then it must be
omp_cur_iteration.

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

Added: 
    

Modified: 
    clang/include/clang/Basic/DiagnosticParseKinds.td
    clang/include/clang/Basic/OpenMPKinds.def
    clang/lib/AST/OpenMPClause.cpp
    clang/lib/CodeGen/CGOpenMPRuntime.h
    clang/lib/Parse/ParseOpenMP.cpp
    clang/lib/Sema/SemaOpenMP.cpp
    clang/test/OpenMP/ordered_ast_print.cpp
    clang/test/OpenMP/ordered_doacross_codegen.c
    clang/test/OpenMP/ordered_messages.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 4a375bb5c66552..40e1a381eb77f6 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1363,6 +1363,7 @@ def err_omp_expected_punc_after_iterator : Error<
   "expected ',' or ')' after iterator specifier">;
 def err_omp_decl_in_declare_simd_variant : Error<
   "function declaration is expected after 'declare %select{simd|variant}0' directive">;
+def err_omp_sink_and_source_iteration_not_allowd: Error<" '%0 %select{sink:|source:}1' must be with '%select{omp_cur_iteration - 1|omp_cur_iteration}1'">;
 def err_omp_unknown_map_type : Error<
   "incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'">;
 def err_omp_unknown_map_type_modifier : Error<

diff  --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def
index eb5037c629dbf7..c999b8b9c4ff59 100644
--- a/clang/include/clang/Basic/OpenMPKinds.def
+++ b/clang/include/clang/Basic/OpenMPKinds.def
@@ -207,6 +207,8 @@ OPENMP_NUMTASKS_MODIFIER(strict)
 // Modifiers for the 'doacross' clause.
 OPENMP_DOACROSS_MODIFIER(source)
 OPENMP_DOACROSS_MODIFIER(sink)
+OPENMP_DOACROSS_MODIFIER(sink_omp_cur_iteration)
+OPENMP_DOACROSS_MODIFIER(source_omp_cur_iteration)
 
 #undef OPENMP_NUMTASKS_MODIFIER
 #undef OPENMP_GRAINSIZE_MODIFIER

diff  --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 4fc63093a87133..98870b368789c2 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -2513,7 +2513,23 @@ void OMPClausePrinter::VisitOMPXDynCGroupMemClause(
 void OMPClausePrinter::VisitOMPDoacrossClause(OMPDoacrossClause *Node) {
   OS << "doacross(";
   OpenMPDoacrossClauseModifier DepType = Node->getDependenceType();
-  OS << (DepType == OMPC_DOACROSS_source ? "source:" : "sink:");
+
+  switch (DepType) {
+  case OMPC_DOACROSS_source:
+    OS << "source:";
+    break;
+  case OMPC_DOACROSS_sink:
+    OS << "sink:";
+    break;
+  case OMPC_DOACROSS_source_omp_cur_iteration:
+    OS << "source: omp_cur_iteration";
+    break;
+  case OMPC_DOACROSS_sink_omp_cur_iteration:
+    OS << "sink: omp_cur_iteration - 1";
+    break;
+  default:
+    llvm_unreachable("unknown docaross modifier");
+  }
   VisitOMPClauseList(Node, ' ');
   OS << ")";
 }

diff  --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h
index 20525feca05c32..af801e312c966d 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.h
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -2310,10 +2310,12 @@ template <> class OMPDoacrossKind<OMPDependClause> {
 template <> class OMPDoacrossKind<OMPDoacrossClause> {
 public:
   bool isSource(const OMPDoacrossClause *C) {
-    return (C->getDependenceType() == OMPC_DOACROSS_source);
+    return C->getDependenceType() == OMPC_DOACROSS_source ||
+           C->getDependenceType() == OMPC_DOACROSS_source_omp_cur_iteration;
   }
   bool isSink(const OMPDoacrossClause *C) {
-    return (C->getDependenceType() == OMPC_DOACROSS_sink);
+    return C->getDependenceType() == OMPC_DOACROSS_sink ||
+           C->getDependenceType() == OMPC_DOACROSS_sink_omp_cur_iteration;
   }
 };
 } // namespace

diff  --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 8c4cf306bde2c4..fc7f0070ff06a3 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -4410,16 +4410,55 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
     }
     if (Tok.is(tok::colon)) {
       Data.ColonLoc = ConsumeToken();
-    } else {
+    } else if (Kind != OMPC_doacross || Tok.isNot(tok::r_paren)) {
       Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
                                       : diag::warn_pragma_expected_colon)
           << (Kind == OMPC_depend ? "dependency type" : "dependence-type");
     }
-    // Special processing for doacross(source) clause.
-    if (Kind == OMPC_doacross && Data.ExtraModifier == OMPC_DOACROSS_source) {
-      // Parse ')'.
-      T.consumeClose();
-      return false;
+    if (Kind == OMPC_doacross) {
+      if (Tok.is(tok::identifier) &&
+          Tok.getIdentifierInfo()->isStr("omp_cur_iteration")) {
+        Data.ExtraModifier = Data.ExtraModifier == OMPC_DOACROSS_source
+                                 ? OMPC_DOACROSS_source_omp_cur_iteration
+                                 : OMPC_DOACROSS_sink_omp_cur_iteration;
+        ConsumeToken();
+      }
+      if (Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration) {
+        if (Tok.isNot(tok::minus)) {
+          Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
+              << getOpenMPClauseName(Kind) << 0 << 0;
+          SkipUntil(tok::r_paren);
+          return false;
+        } else {
+          ConsumeToken();
+          SourceLocation Loc = Tok.getLocation();
+          uint64_t Value = 0;
+          if (Tok.isNot(tok::numeric_constant) ||
+              (PP.parseSimpleIntegerLiteral(Tok, Value) && Value != 1)) {
+            Diag(Loc, diag::err_omp_sink_and_source_iteration_not_allowd)
+                << getOpenMPClauseName(Kind) << 0 << 0;
+            SkipUntil(tok::r_paren);
+            return false;
+          }
+        }
+      }
+      if (Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration) {
+        if (Tok.isNot(tok::r_paren)) {
+          Diag(Tok, diag::err_omp_sink_and_source_iteration_not_allowd)
+              << getOpenMPClauseName(Kind) << 1 << 1;
+          SkipUntil(tok::r_paren);
+          return false;
+        }
+      }
+      // Only the 'sink' case has the expression list.
+      if (Kind == OMPC_doacross &&
+          (Data.ExtraModifier == OMPC_DOACROSS_source ||
+           Data.ExtraModifier == OMPC_DOACROSS_source_omp_cur_iteration ||
+           Data.ExtraModifier == OMPC_DOACROSS_sink_omp_cur_iteration)) {
+        // Parse ')'.
+        T.consumeClose();
+        return false;
+      }
     }
   } else if (Kind == OMPC_linear) {
     // Try to parse modifier if any.

diff  --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 17cedd6061c8aa..cc52306d481bbf 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -9165,6 +9165,22 @@ void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
   }
 }
 
+namespace {
+// Utility for openmp doacross clause kind
+class OMPDoacrossKind {
+public:
+  bool isSource(const OMPDoacrossClause *C) {
+    return C->getDependenceType() == OMPC_DOACROSS_source ||
+           C->getDependenceType() == OMPC_DOACROSS_source_omp_cur_iteration;
+  }
+  bool isSink(const OMPDoacrossClause *C) {
+    return C->getDependenceType() == OMPC_DOACROSS_sink;
+  }
+  bool isSinkIter(const OMPDoacrossClause *C) {
+    return C->getDependenceType() == OMPC_DOACROSS_sink_omp_cur_iteration;
+  }
+};
+} // namespace
 /// Called on a for stmt to check and extract its iteration space
 /// for further processing (such as collapsing).
 static bool checkOpenMPIterationSpace(
@@ -9332,7 +9348,8 @@ static bool checkOpenMPIterationSpace(
         DependC->setLoopData(CurrentNestedLoopCount, nullptr);
         continue;
       }
-      if (DoacrossC && DoacrossC->getDependenceType() == OMPC_DOACROSS_sink &&
+      OMPDoacrossKind ODK;
+      if (DoacrossC && ODK.isSink(DoacrossC) &&
           Pair.second.size() <= CurrentNestedLoopCount) {
         // Erroneous case - clause has some problems.
         DoacrossC->setLoopData(CurrentNestedLoopCount, nullptr);
@@ -9342,12 +9359,27 @@ static bool checkOpenMPIterationSpace(
       SourceLocation DepLoc =
           DependC ? DependC->getDependencyLoc() : DoacrossC->getDependenceLoc();
       if ((DependC && DependC->getDependencyKind() == OMPC_DEPEND_source) ||
-          (DoacrossC && DoacrossC->getDependenceType() == OMPC_DOACROSS_source))
+          (DoacrossC && ODK.isSource(DoacrossC)))
         CntValue = ISC.buildOrderedLoopData(
             DSA.getCurScope(),
             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
             DepLoc);
-      else
+      else if (DoacrossC && ODK.isSinkIter(DoacrossC)) {
+        Expr *Cnt = SemaRef
+                        .DefaultLvalueConversion(
+                            ResultIterSpaces[CurrentNestedLoopCount].CounterVar)
+                        .get();
+        if (!Cnt)
+          continue;
+        // build CounterVar - 1
+        Expr *Inc =
+            SemaRef.ActOnIntegerConstant(DoacrossC->getColonLoc(), /*Val=*/1)
+                .get();
+        CntValue = ISC.buildOrderedLoopData(
+            DSA.getCurScope(),
+            ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
+            DepLoc, Inc, clang::OO_Minus);
+      } else
         CntValue = ISC.buildOrderedLoopData(
             DSA.getCurScope(),
             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
@@ -11284,8 +11316,9 @@ StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
     if (DC || DOC) {
       DependFound = DC ? C : nullptr;
       DoacrossFound = DOC ? C : nullptr;
+      OMPDoacrossKind ODK;
       if ((DC && DC->getDependencyKind() == OMPC_DEPEND_source) ||
-          (DOC && DOC->getDependenceType() == OMPC_DOACROSS_source)) {
+          (DOC && (ODK.isSource(DOC)))) {
         if ((DC && DependSourceClause) || (DOC && DoacrossSourceClause)) {
           Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
               << getOpenMPDirectiveName(OMPD_ordered)
@@ -11303,7 +11336,7 @@ StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
           ErrorFound = true;
         }
       } else if ((DC && DC->getDependencyKind() == OMPC_DEPEND_sink) ||
-                 (DOC && DOC->getDependenceType() == OMPC_DOACROSS_sink)) {
+                 (DOC && (ODK.isSink(DOC) || ODK.isSinkIter(DOC)))) {
         if (DependSourceClause || DoacrossSourceClause) {
           Diag(C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
               << (DC ? "depend" : "doacross") << 1;
@@ -24025,7 +24058,10 @@ OMPClause *Sema::ActOnOpenMPDoacrossClause(
     SourceLocation LParenLoc, SourceLocation EndLoc) {
 
   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
-      DepType != OMPC_DOACROSS_source && DepType != OMPC_DOACROSS_sink) {
+      DepType != OMPC_DOACROSS_source && DepType != OMPC_DOACROSS_sink &&
+      DepType != OMPC_DOACROSS_sink_omp_cur_iteration &&
+      DepType != OMPC_DOACROSS_source_omp_cur_iteration &&
+      DepType != OMPC_DOACROSS_source) {
     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_doacross);
     return nullptr;
@@ -24035,7 +24071,11 @@ OMPClause *Sema::ActOnOpenMPDoacrossClause(
   DSAStackTy::OperatorOffsetTy OpsOffs;
   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
   DoacrossDataInfoTy VarOffset = ProcessOpenMPDoacrossClauseCommon(
-      *this, DepType == OMPC_DOACROSS_source, VarList, DSAStack, EndLoc);
+      *this,
+      DepType == OMPC_DOACROSS_source ||
+          DepType == OMPC_DOACROSS_source_omp_cur_iteration ||
+          DepType == OMPC_DOACROSS_sink_omp_cur_iteration,
+      VarList, DSAStack, EndLoc);
   Vars = VarOffset.Vars;
   OpsOffs = VarOffset.OpsOffs;
   TotalDepCount = VarOffset.TotalDepCount;

diff  --git a/clang/test/OpenMP/ordered_ast_print.cpp b/clang/test/OpenMP/ordered_ast_print.cpp
index 298d52132e9744..e64c22abc3c7eb 100644
--- a/clang/test/OpenMP/ordered_ast_print.cpp
+++ b/clang/test/OpenMP/ordered_ast_print.cpp
@@ -55,6 +55,8 @@ T tmain (T argc) {
 #if _OPENMP >= 202111
   #pragma omp ordered doacross(source:)
   #pragma omp ordered doacross(sink:i+N)
+  #pragma omp ordered doacross(sink: omp_cur_iteration - 1)
+  #pragma omp ordered doacross(source: omp_cur_iteration)
 #else
   #pragma omp ordered depend(source)
   #pragma omp ordered depend(sink:i+N)
@@ -100,6 +102,8 @@ T tmain (T argc) {
 #if _OPENMP >= 202111
 // OMP52: #pragma omp ordered doacross(source:)
 // OMP52-NEXT: #pragma omp ordered doacross(sink: i + N)
+// OMP52-NEXT: #pragma omp ordered doacross(sink: omp_cur_iteration - 1)
+// OMP52-NEXT: #pragma omp ordered doacross(source: omp_cur_iteration)
 #else
 // OMP51: #pragma omp ordered depend(source)
 // OMP51-NEXT: #pragma omp ordered depend(sink : i + N)
@@ -142,6 +146,8 @@ T tmain (T argc) {
 #if _OPENMP >= 202111
 // OMP52: #pragma omp ordered doacross(source:)
 // OMP52-NEXT: #pragma omp ordered doacross(sink: i + 3)
+// OMP52-NEXT: #pragma omp ordered doacross(sink: omp_cur_iteration - 1)
+// OMP52-NEXT: #pragma omp ordered doacross(source: omp_cur_iteration)
 #else
 // OMP51: #pragma omp ordered depend(source)
 // OMP51-NEXT: #pragma omp ordered depend(sink : i + 3)
@@ -189,6 +195,8 @@ int main (int argc, char **argv) {
 #if _OPENMP >= 202111
   #pragma omp ordered doacross(source:)
   #pragma omp ordered doacross(sink: i - 5)
+  #pragma omp ordered doacross(sink: omp_cur_iteration - 1)
+  #pragma omp ordered doacross(source: omp_cur_iteration)
 #else
   #pragma omp ordered depend(source)
   #pragma omp ordered depend(sink: i - 5)
@@ -230,6 +238,8 @@ int main (int argc, char **argv) {
 #if _OPENMP >= 202111
 // OMP52: #pragma omp ordered doacross(source:)
 // OMP52-NEXT: #pragma omp ordered doacross(sink: i - 5)
+// OMP52-NEXT: #pragma omp ordered doacross(sink: omp_cur_iteration - 1)
+// OMP52-NEXT: #pragma omp ordered doacross(source: omp_cur_iteration)
 #else
 // OMP51: #pragma omp ordered depend(source)
 // OMP51-NEXT: #pragma omp ordered depend(sink : i - 5)

diff  --git a/clang/test/OpenMP/ordered_doacross_codegen.c b/clang/test/OpenMP/ordered_doacross_codegen.c
index 787672a05f27f6..48e075346ca11a 100644
--- a/clang/test/OpenMP/ordered_doacross_codegen.c
+++ b/clang/test/OpenMP/ordered_doacross_codegen.c
@@ -84,6 +84,43 @@ int main(void) {
 #pragma omp ordered depend(sink : i - 2)
 #endif
     d[i] = a[i - 2];
+    foo();
+// CHECK: call void @foo()
+// CHECK: load i32, ptr [[I]],
+// CHECK-NEXT: sub nsw i32 %{{.+}}, 1
+// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
+// CHECK-NEXT: sdiv i32 %{{.+}}, 1
+// CHECK-NEXT: sext i32 %{{.+}} to i64
+// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], ptr [[CNT:%.+]], i64 0, i64 0
+// CHECK-NEXT: store i64 %{{.+}}, ptr [[TMP]],
+// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], ptr [[CNT]], i64 0, i64 0
+// CHECK-NORMAL-NEXT: call void @__kmpc_doacross_wait(ptr [[IDENT]], i32 [[GTID]], ptr [[TMP]])
+// CHECK-IRBUILDER-NEXT: [[GTID2:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[IDENT:@.+]])
+// CHECK-IRBUILDER-NEXT: call void @__kmpc_doacross_wait(ptr [[IDENT]], i32 [[GTID2]], ptr [[TMP]])
+#ifdef OMP52
+#pragma omp ordered doacross(sink :omp_cur_iteration - 1)
+#else
+#pragma omp ordered depend(sink : i - 1)
+#endif
+    d[i] = a[i - 1];
+    foo();
+// CHECK: call void @foo()
+// CHECK: load i32, ptr [[I:%.+]],
+// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
+// CHECK-NEXT: sdiv i32 %{{.+}}, 1
+// CHECK-NEXT: sext i32 %{{.+}} to i64
+// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], ptr [[CNT:%.+]], i64 0, i64 0
+// CHECK-NEXT: store i64 %{{.+}}, ptr [[TMP]],
+// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], ptr [[CNT]], i64 0, i64 0
+// CHECK-NORMAL-NEXT: call void @__kmpc_doacross_post(ptr [[IDENT]], i32 [[GTID]], ptr [[TMP]])
+// CHECK-IRBUILDER-NEXT: [[GTID1:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[IDENT:@.+]])
+// CHECK-IRBUILDER-NEXT: call void @__kmpc_doacross_post(ptr [[IDENT]], i32 [[GTID1]], ptr [[TMP]])
+#if OMP52
+#pragma omp ordered doacross(source:omp_cur_iteration)
+#else
+#pragma omp ordered depend(source)
+#endif
+    c[i] = c[i] + 1;
   }
   // CHECK: call void @__kmpc_for_static_fini(
   // CHECK-NORMAL: call void @__kmpc_doacross_fini(ptr [[IDENT]], i32 [[GTID]])

diff  --git a/clang/test/OpenMP/ordered_messages.cpp b/clang/test/OpenMP/ordered_messages.cpp
index 3711693688c519..2af4c1eec51ac2 100644
--- a/clang/test/OpenMP/ordered_messages.cpp
+++ b/clang/test/OpenMP/ordered_messages.cpp
@@ -132,7 +132,11 @@ T foo() {
     {
       foo();
     }
+#if _OPENMP >= 202111
+    #pragma omp ordered doacross(source:omp_cur_iteration) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+#else
     #pragma omp ordered depend(source) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+#endif
   }
 #pragma omp parallel for ordered
   for (int i = 0; i < 10; ++i) {
@@ -155,6 +159,10 @@ T foo() {
 #pragma omp ordered doacross(sink : // omp52-error {{expected ')'}} omp52-note {{to match this '('}} omp52-error {{expected expression}} omp52-error {{expected 'i' loop iteration variable}}
 #pragma omp ordered doacross(sink : i // omp52-error {{expected ')'}} omp52-note {{to match this '('}} omp52-error {{expected 'j' loop iteration variable}}
 #pragma omp ordered doacross(sink : i) // omp52-error {{expected 'j' loop iteration variable}}
+#pragma omp ordered doacross(sink:omp_cur_iteration + 1) // omp52-error {{'doacross sink:' must be with 'omp_cur_iteration - 1'}}
+#pragma omp ordered doacross(sink:omp_cur_iteration - 2) // omp52-error {{'doacross sink:' must be with 'omp_cur_iteration - 1'}}
+#pragma omp ordered doacross(sink:omp_cur_iteration) // omp52-error {{'doacross sink:' must be with 'omp_cur_iteration - 1'}}
+#pragma omp ordered doacross(source:omp_cur_iteration - 1) // omp52-error {{'doacross source:' must be with 'omp_cur_iteration'}}
 #pragma omp ordered doacross(source:)
                            if (i == j)
 #pragma omp ordered doacross(source:) // omp52-error {{'#pragma omp ordered' with 'doacross' clause cannot be an immediate substatement}}
@@ -309,7 +317,11 @@ int k;
     {
       foo();
     }
+#if _OPENMP >= 202111
+    #pragma omp ordered doacross(source:omp_cur_iteration) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+#else
     #pragma omp ordered depend(source) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+#endif
   }
 #pragma omp parallel for ordered
   for (int i = 0; i < 10; ++i) {


        


More information about the cfe-commits mailing list