r373939 - [OPENMP50]Treat range-based for as canonical loop.

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 7 11:54:57 PDT 2019


Author: abataev
Date: Mon Oct  7 11:54:57 2019
New Revision: 373939

URL: http://llvm.org/viewvc/llvm-project?rev=373939&view=rev
Log:
[OPENMP50]Treat range-based for as canonical loop.

According to OpenMP 5.0, range-based for is also considered as a
canonical form of loops.

Modified:
    cfe/trunk/include/clang/AST/StmtOpenMP.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Sema/SemaOpenMP.cpp
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp
    cfe/trunk/test/OpenMP/distribute_simd_loop_messages.cpp
    cfe/trunk/test/OpenMP/for_ast_print.cpp
    cfe/trunk/test/OpenMP/for_loop_messages.cpp
    cfe/trunk/test/OpenMP/for_simd_loop_messages.cpp
    cfe/trunk/test/OpenMP/parallel_for_codegen.cpp
    cfe/trunk/test/OpenMP/parallel_for_loop_messages.cpp
    cfe/trunk/test/OpenMP/parallel_for_simd_loop_messages.cpp
    cfe/trunk/test/OpenMP/simd_loop_messages.cpp
    cfe/trunk/test/OpenMP/target_parallel_for_loop_messages.cpp
    cfe/trunk/test/OpenMP/target_parallel_for_simd_loop_messages.cpp
    cfe/trunk/test/OpenMP/target_simd_loop_messages.cpp
    cfe/trunk/test/OpenMP/target_teams_distribute_loop_messages.cpp
    cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp
    cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp
    cfe/trunk/test/OpenMP/taskloop_loop_messages.cpp
    cfe/trunk/test/OpenMP/taskloop_simd_loop_messages.cpp
    cfe/trunk/test/OpenMP/teams_distribute_loop_messages.cpp
    cfe/trunk/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp
    cfe/trunk/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp
    cfe/trunk/test/OpenMP/teams_distribute_simd_loop_messages.cpp

Modified: cfe/trunk/include/clang/AST/StmtOpenMP.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtOpenMP.h?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/StmtOpenMP.h (original)
+++ cfe/trunk/include/clang/AST/StmtOpenMP.h Mon Oct  7 11:54:57 2019
@@ -17,6 +17,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/OpenMPClause.h"
 #include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
 #include "clang/Basic/OpenMPKinds.h"
 #include "clang/Basic/SourceLocation.h"
 
@@ -1087,10 +1088,22 @@ public:
     // This relies on the loop form is already checked by Sema.
     const Stmt *Body =
         getInnermostCapturedStmt()->getCapturedStmt()->IgnoreContainers();
-    Body = cast<ForStmt>(Body)->getBody();
+    if (auto *For = dyn_cast<ForStmt>(Body)) {
+      Body = For->getBody();
+    } else {
+      assert(isa<CXXForRangeStmt>(Body) &&
+             "Expected caonical for loop or range-based for loop.");
+      Body = cast<CXXForRangeStmt>(Body)->getBody();
+    }
     for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
       Body = Body->IgnoreContainers();
-      Body = cast<ForStmt>(Body)->getBody();
+      if (auto *For = dyn_cast<ForStmt>(Body)) {
+        Body = For->getBody();
+      } else {
+        assert(isa<CXXForRangeStmt>(Body) &&
+               "Expected caonical for loop or range-based for loop.");
+        Body = cast<CXXForRangeStmt>(Body)->getBody();
+      }
     }
     return Body;
   }

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Oct  7 11:54:57 2019
@@ -9154,6 +9154,10 @@ public:
   /// construct.
   void startOpenMPLoop();
 
+  /// If the current region is a range loop-based region, mark the start of the
+  /// loop construct.
+  void startOpenMPCXXRangeFor();
+
   /// Check if the specified variable is used in 'private' clause.
   /// \param Level Relative level of nested OpenMP construct for that the check
   /// is performed.

Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Mon Oct  7 11:54:57 2019
@@ -142,6 +142,24 @@ class OMPLoopScope : public CodeGenFunct
       }
     }
     (void)PreCondVars.apply(CGF);
+    // Emit init, __range and __end variables for C++ range loops.
+    const Stmt *Body =
+        S.getInnermostCapturedStmt()->getCapturedStmt()->IgnoreContainers();
+    for (unsigned Cnt = 0; Cnt < S.getCollapsedNumber(); ++Cnt) {
+      Body = Body->IgnoreContainers();
+      if (auto *For = dyn_cast<ForStmt>(Body)) {
+        Body = For->getBody();
+      } else {
+        assert(isa<CXXForRangeStmt>(Body) &&
+               "Expected caonical for loop or range-based for loop.");
+        auto *CXXFor = cast<CXXForRangeStmt>(Body);
+        if (const Stmt *Init = CXXFor->getInit())
+          CGF.EmitStmt(Init);
+        CGF.EmitStmt(CXXFor->getRangeStmt());
+        CGF.EmitStmt(CXXFor->getEndStmt());
+        Body = CXXFor->getBody();
+      }
+    }
     if (const auto *PreInits = cast_or_null<DeclStmt>(S.getPreInits())) {
       for (const auto *I : PreInits->decls())
         CGF.EmitVarDecl(cast<VarDecl>(*I));
@@ -1350,6 +1368,21 @@ void CodeGenFunction::EmitOMPLoopBody(co
                          getProfileCount(D.getBody()));
     EmitBlock(NextBB);
   }
+  // Emit loop variables for C++ range loops.
+  const Stmt *Body =
+      D.getInnermostCapturedStmt()->getCapturedStmt()->IgnoreContainers();
+  for (unsigned Cnt = 0; Cnt < D.getCollapsedNumber(); ++Cnt) {
+    Body = Body->IgnoreContainers();
+    if (auto *For = dyn_cast<ForStmt>(Body)) {
+      Body = For->getBody();
+    } else {
+      assert(isa<CXXForRangeStmt>(Body) &&
+             "Expected caonical for loop or range-based for loop.");
+      auto *CXXFor = cast<CXXForRangeStmt>(Body);
+      EmitStmt(CXXFor->getLoopVarStmt());
+      Body = CXXFor->getBody();
+    }
+  }
   // Emit loop body.
   EmitStmt(D.getBody());
   // The end (updates/cleanups).

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Oct  7 11:54:57 2019
@@ -2100,6 +2100,8 @@ Parser::DeclGroupPtrTy Parser::ParseDecl
     bool IsForRangeLoop = false;
     if (TryConsumeToken(tok::colon, FRI->ColonLoc)) {
       IsForRangeLoop = true;
+      if (getLangOpts().OpenMP)
+        Actions.startOpenMPCXXRangeFor();
       if (Tok.is(tok::l_brace))
         FRI->RangeExpr = ParseBraceInitializer();
       else

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Mon Oct  7 11:54:57 2019
@@ -2008,6 +2008,14 @@ void Sema::startOpenMPLoop() {
     DSAStack->loopInit();
 }
 
+void Sema::startOpenMPCXXRangeFor() {
+  assert(LangOpts.OpenMP && "OpenMP must be enabled.");
+  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
+    DSAStack->resetPossibleLoopCounter();
+    DSAStack->loopStart();
+  }
+}
+
 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const {
   assert(LangOpts.OpenMP && "OpenMP is not allowed");
   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
@@ -6490,10 +6498,13 @@ static bool checkOpenMPIterationSpace(
     Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
     llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
-  // OpenMP [2.6, Canonical Loop Form]
+  // OpenMP [2.9.1, Canonical Loop Form]
   //   for (init-expr; test-expr; incr-expr) structured-block
+  //   for (range-decl: range-expr) structured-block
   auto *For = dyn_cast_or_null<ForStmt>(S);
-  if (!For) {
+  auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
+  // Ranged for is supported only in OpenMP 5.0.
+  if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
         << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
         << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
@@ -6515,12 +6526,14 @@ static bool checkOpenMPIterationSpace(
     }
     return true;
   }
-  assert(For->getBody());
+  assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
+         "No loop body.");
 
-  OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc());
+  OpenMPIterationSpaceChecker ISC(SemaRef, DSA,
+                                  For ? For->getForLoc() : CXXFor->getForLoc());
 
   // Check init.
-  Stmt *Init = For->getInit();
+  Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
   if (ISC.checkAndSetInit(Init))
     return true;
 
@@ -6556,18 +6569,18 @@ static bool checkOpenMPIterationSpace(
     assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
 
     // Check test-expr.
-    HasErrors |= ISC.checkAndSetCond(For->getCond());
+    HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
 
     // Check incr-expr.
-    HasErrors |= ISC.checkAndSetInc(For->getInc());
+    HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
   }
 
   if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
     return HasErrors;
 
   // Build the loop's iteration space representation.
-  ResultIterSpaces[CurrentNestedLoopCount].PreCond =
-      ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures);
+  ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
+      DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
   ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
       ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
                              (isOpenMPWorksharingDirective(DKind) ||
@@ -6881,7 +6894,14 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin
     // All loops associated with the construct must be perfectly nested; that
     // is, there must be no intervening code nor any OpenMP directive between
     // any two loops.
-    CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
+    if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
+      CurStmt = For->getBody();
+    } else {
+      assert(isa<CXXForRangeStmt>(CurStmt) &&
+             "Expected canonical for or range-based for loops.");
+      CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
+    }
+    CurStmt = CurStmt->IgnoreContainers();
   }
   for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
     if (checkOpenMPIterationSpace(
@@ -6901,7 +6921,14 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin
     // All loops associated with the construct must be perfectly nested; that
     // is, there must be no intervening code nor any OpenMP directive between
     // any two loops.
-    CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
+    if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
+      CurStmt = For->getBody();
+    } else {
+      assert(isa<CXXForRangeStmt>(CurStmt) &&
+             "Expected canonical for or range-based for loops.");
+      CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
+    }
+    CurStmt = CurStmt->IgnoreContainers();
   }
 
   Built.clear(/* size */ NestedLoopCount);

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Mon Oct  7 11:54:57 2019
@@ -2674,6 +2674,11 @@ StmtResult Sema::BuildCXXForRangeStmt(So
   if (Kind == BFRK_Check)
     return StmtResult();
 
+  // In OpenMP loop region loop control variable must be private. Perform
+  // analysis of first part (if any).
+  if (getLangOpts().OpenMP >= 50 && BeginDeclStmt.isUsable())
+    ActOnOpenMPLoopInitialization(ForLoc, BeginDeclStmt.get());
+
   return new (Context) CXXForRangeStmt(
       InitStmt, RangeDS, cast_or_null<DeclStmt>(BeginDeclStmt.get()),
       cast_or_null<DeclStmt>(EndDeclStmt.get()), NotEqExpr.get(),

Modified: cfe/trunk/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -379,7 +379,7 @@ int test_iteration_spaces() {
 
 #pragma omp target
 #pragma omp teams
-// expected-error at +2 {{statement after '#pragma omp distribute parallel for simd' must be a for loop}}
+// omp4-error at +2 {{statement after '#pragma omp distribute parallel for simd' must be a for loop}}
 #pragma omp distribute parallel for simd
   for (auto &item : a) {
     item = item + 1;

Modified: cfe/trunk/test/OpenMP/distribute_simd_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/distribute_simd_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/distribute_simd_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/distribute_simd_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -376,7 +376,7 @@ int test_iteration_spaces() {
 
   #pragma omp target
   #pragma omp teams
-  // expected-error at +2 {{statement after '#pragma omp distribute simd' must be a for loop}}
+  // omp4-error at +2 {{statement after '#pragma omp distribute simd' must be a for loop}}
   #pragma omp distribute simd
   for (auto &item : a) {
     item = item + 1;

Modified: cfe/trunk/test/OpenMP/for_ast_print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_ast_print.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/for_ast_print.cpp (original)
+++ cfe/trunk/test/OpenMP/for_ast_print.cpp Mon Oct  7 11:54:57 2019
@@ -1,10 +1,10 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
-
-// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
@@ -103,6 +103,7 @@ public:
 template <class T, int N>
 T tmain(T argc) {
   T b = argc, c, d, e, f, g;
+  T arr[N];
   static T a;
 // CHECK: static T a;
 #pragma omp for schedule(dynamic) linear(a) allocate(a)
@@ -113,6 +114,7 @@ T tmain(T argc) {
 // CHECK-NEXT: a = 2;
 #pragma omp parallel
 #pragma omp for allocate(argc) private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered(N) nowait
+  for (auto &x : arr)
   for (int i = 0; i < 2; ++i)
     for (int j = 0; j < 2; ++j)
       for (int j = 0; j < 2; ++j)
@@ -126,6 +128,7 @@ T tmain(T argc) {
             foo();
   // CHECK-NEXT: #pragma omp parallel
   // CHECK-NEXT: #pragma omp for allocate(argc) private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered(N) nowait
+  // CHECK-NEXT: for (auto &x : arr)
   // CHECK-NEXT: for (int i = 0; i < 2; ++i)
   // CHECK-NEXT: for (int j = 0; j < 2; ++j)
   // CHECK-NEXT: for (int j = 0; j < 2; ++j)
@@ -143,6 +146,7 @@ T tmain(T argc) {
 int main(int argc, char **argv) {
 // CHECK: int main(int argc, char **argv) {
   int b = argc, c, d, e, f, g;
+  float arr[20];
   static int a;
 // CHECK: static int a;
 #pragma omp for schedule(guided, argc) reduction(+:argv[0][:1])
@@ -152,15 +156,17 @@ int main(int argc, char **argv) {
 // CHECK-NEXT: for (int i = 0; i < 2; ++i)
 // CHECK-NEXT: a = 2;
 #pragma omp parallel
-#pragma omp for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered nowait linear(g:-1)
+#pragma omp for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(3) schedule(auto) ordered nowait linear(g:-1)
   for (int i = 0; i < 10; ++i)
     for (int j = 0; j < 10; ++j)
-      foo();
+      for (auto x : arr)
+        foo(), (void)x;
   // CHECK-NEXT: #pragma omp parallel
-  // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered nowait linear(g: -1)
+  // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(3) schedule(auto) ordered nowait linear(g: -1)
   // CHECK-NEXT: for (int i = 0; i < 10; ++i)
   // CHECK-NEXT: for (int j = 0; j < 10; ++j)
-  // CHECK-NEXT: foo();
+  // CHECK-NEXT: for (auto x : arr)
+  // CHECK-NEXT: foo() , (void)x;
   char buf[9] = "01234567";
   char *p, *q;
 #pragma omp parallel

Modified: cfe/trunk/test/OpenMP/for_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/for_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/for_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -370,7 +370,7 @@ int test_iteration_spaces() {
   }
 
 #pragma omp parallel
-// expected-error at +2 {{statement after '#pragma omp for' must be a for loop}}
+// omp4-error at +2 {{statement after '#pragma omp for' must be a for loop}}
 #pragma omp for
   for (auto &item : a) {
     item = item + 1;

Modified: cfe/trunk/test/OpenMP/for_simd_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_simd_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/for_simd_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/for_simd_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -333,7 +333,7 @@ int test_iteration_spaces() {
   }
 
 #pragma omp parallel
-// expected-error at +2 {{statement after '#pragma omp for simd' must be a for loop}}
+// omp4-error at +2 {{statement after '#pragma omp for simd' must be a for loop}}
 #pragma omp for simd
   for (auto &item : a) {
     item = item + 1;

Modified: cfe/trunk/test/OpenMP/parallel_for_codegen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_codegen.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_for_codegen.cpp (original)
+++ cfe/trunk/test/OpenMP/parallel_for_codegen.cpp Mon Oct  7 11:54:57 2019
@@ -469,6 +469,165 @@ int decrement_nowait () {
   return 0;
 // OMP5: ret i32 0
 }
+
+// OMP5-LABEL: range_for_single
+void range_for_single() {
+  int arr[10] = {0};
+// OMP5: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* {{.+}}, i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [10 x i32]*)* [[OUTLINED:@.+]] to void (i32*, i32*, ...)*), [10 x i32]* %{{.+}})
+#pragma omp parallel for
+  for (auto &a : arr)
+    (void)a;
+}
+
+// OMP5: define internal void @.omp_outlined.(i32* {{.+}}, i32* {{.+}}, [10 x i32]* dereferenceable(40) %arr)
+// OMP5: [[ARR_ADDR:%.+]] = alloca [10 x i32]*,
+// OMP5: [[IV:%.+]] = alloca i64,
+// OMP5: [[RANGE_ADDR:%.+]] = alloca [10 x i32]*,
+// OMP5: [[END_ADDR:%.+]] = alloca i32*,
+// OMP5: alloca i32*,
+// OMP5: alloca i32*,
+// OMP5: alloca i64,
+// OMP5: [[BEGIN_INIT:%.+]] = alloca i32*,
+// OMP5: [[LB:%.+]] = alloca i64,
+// OMP5: [[UB:%.+]] = alloca i64,
+// OMP5: [[STRIDE:%.+]] = alloca i64,
+// OMP5: [[IS_LAST:%.+]] = alloca i32,
+// OMP5: [[BEGIN:%.+]] = alloca i32*,
+// OMP5: [[A_PTR:%.+]] = alloca i32*,
+// OMP5: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(
+
+// __range = arr;
+// OMP5: [[ARR:%.+]] = load [10 x i32]*, [10 x i32]** [[ARR_ADDR]],
+// OMP5: store [10 x i32]* [[ARR]], [10 x i32]** [[RANGE_ADDR]],
+
+// __end = end(_range);
+// OMP5: [[RANGE:%.+]] = load [10 x i32]*, [10 x i32]** [[RANGE_ADDR]],
+// OMP5: [[RANGE_0:%.+]] = getelementptr inbounds [10 x i32], [10 x i32]* [[RANGE]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// OMP5: [[RANGE_10:%.+]] = getelementptr inbounds i32, i32* [[RANGE_0]], i{{[0-9]+}} 10
+// OMP5: store i32* [[RANGE_10]], i32** [[END_ADDR]],
+
+// OMP5: [[RANGE:%.+]] = load [10 x i32]*, [10 x i32]** [[RANGE_ADDR]],
+// OMP5: [[RANGE_0:%.+]] = getelementptr inbounds [10 x i32], [10 x i32]* [[RANGE]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// OMP5: store i32* [[RANGE_0]], i32** [[CAP1:%.+]],
+// OMP5: [[END:%.+]] = load i32*, i32** [[END_ADDR]],
+// OMP5: store i32* [[END]], i32** [[CAP2:%.+]],
+
+// calculate number of elements.
+// OMP5: [[CAP2_VAL:%.+]] = load i32*, i32** [[CAP2]],
+// OMP5: [[CAP1_VAL:%.+]] = load i32*, i32** [[CAP1]],
+// OMP5: [[CAP2_I64:%.+]] = ptrtoint i32* [[CAP2_VAL]] to i64
+// OMP5: [[CAP1_I64:%.+]] = ptrtoint i32* [[CAP1_VAL]] to i64
+// OMP5: [[DIFF:%.+]] = sub i64 [[CAP2_I64]], [[CAP1_I64]]
+// OMP5: [[NUM:%.+]] = sdiv exact i64 [[DIFF]], 4
+// OMP5: [[NUM1:%.+]] = sub nsw i64 [[NUM]], 1
+// OMP5: [[NUM2:%.+]] = add nsw i64 [[NUM1]], 1
+// OMP5: [[NUM3:%.+]] = sdiv i64 [[NUM2]], 1
+// OMP5: [[NUM4:%.+]] = sub nsw i64 [[NUM3]], 1
+// OMP5: store i64 [[NUM4]], i64* [[CAP3:%.+]],
+// OMP5: [[RANGE_0:%.+]] = load i32*, i32** [[CAP1]],
+
+// __begin = begin(range);
+// OMP5: store i32* [[RANGE_0]], i32** [[BEGIN_INIT]],
+// OMP5: [[CAP1_VAL:%.+]] = load i32*, i32** [[CAP1]],
+// OMP5: [[CAP2_VAL:%.+]] = load i32*, i32** [[CAP2]],
+// OMP5: [[CMP:%.+]] = icmp ult i32* [[CAP1_VAL]], [[CAP2_VAL]]
+
+// __begin >= __end ? goto then : goto exit;
+// OMP5: br i1 [[CMP]], label %[[THEN:.+]], label %[[EXIT:.+]]
+
+// OMP5: [[THEN]]:
+
+// lb = 0;
+// OMP5: store i64 0, i64* [[LB]],
+
+// ub = number of elements
+// OMP5: [[NUM:%.+]] = load i64, i64* [[CAP3]],
+// OMP5: store i64 [[NUM]], i64* [[UB]],
+
+// stride = 1;
+// OMP5: store i64 1, i64* [[STRIDE]],
+
+// is_last = 0;
+// OMP5: store i32 0, i32* [[IS_LAST]],
+
+// loop.
+// OMP5: call void @__kmpc_for_static_init_8(%struct.ident_t* {{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST]], i64* [[LB]], i64* [[UB]], i64* [[STRIDE]], i64 1, i64 1)
+
+// ub = (ub > number_of_elems ? number_of_elems : ub);
+// OMP5: [[UB_VAL:%.+]] = load i64, i64* [[UB]],
+// OMP5: [[NUM_VAL:%.+]] = load i64, i64* [[CAP3]],
+// OMP5: [[CMP:%.+]] = icmp sgt i64 [[UB_VAL]], [[NUM_VAL]]
+// OMP5: br i1 [[CMP]], label %[[TRUE:.+]], label %[[FALSE:.+]]
+
+// OMP5: [[TRUE]]:
+// OMP5: [[NUM_VAL:%.+]] = load i64, i64* [[CAP3]],
+// OMP5: br label %[[END:.+]]
+
+// OMP5: [[FALSE]]:
+// OMP5: [[UB_VAL:%.+]] = load i64, i64* [[UB]],
+// OMP5: br label %[[END:.+]]
+
+// OMP5: [[END]]:
+// OMP5: [[MIN:%.+]] = phi i64 [ [[NUM_VAL]], %[[TRUE]] ], [ [[UB_VAL]], %[[FALSE]] ]
+// OMP%: store i64 [[MIN]], i64* [[UB]],
+
+// iv = lb;
+// OMP5: [[LB_VAL:%.+]] = load i64, i64* [[LB]],
+// OMP5: store i64 [[LB_VAL]], i64* [[IV]],
+
+// goto loop;
+// loop:
+// OMP5: br label %[[LOOP:.+]]
+
+// OMP5: [[LOOP]]:
+
+// iv <= ub ? goto body : goto end;
+// OMP5: [[IV_VAL:%.+]] = load i64, i64* [[IV]],
+// OMP5: [[UB_VAL:%.+]] = load i64, i64* [[UB]],
+// OMP5: [[CMP:%.+]] = icmp sle i64 [[IV_VAL]], [[UB_VAL]]
+// OMP5: br i1 [[CMP]], label %[[BODY:.+]], label %[[END:.+]]
+
+// body:
+// __begin = begin(arr) + iv * 1;
+// OMP5: [[BODY]]:
+// OMP5: [[CAP1_VAL:%.+]] = load i32*, i32** [[CAP1]],
+// OMP5: [[IV_VAL:%.+]] = load i64, i64* [[IV]],
+// OMP5: [[MUL:%.+]] = mul nsw i64 [[IV_VAL]], 1
+// OMP5: [[ADDR:%.+]] = getelementptr inbounds i32, i32* [[CAP1_VAL]], i64 [[MUL]]
+// OMP5: store i32* [[ADDR]], i32** [[BEGIN]],
+
+// a = *__begin;
+// OMP5: [[BEGIN_VAL:%.+]] = load i32*, i32** [[BEGIN]],
+// OMP5: store i32* [[BEGIN_VAL]], i32** [[A_PTR]],
+
+// (void)a;
+// OMP5: load i32*, i32** [[A_PTR]],
+
+// iv += 1;
+// OMP5: [[IV_VAL:%.+]] = load i64, i64* [[IV]],
+// OMP5: [[IV_VAL_ADD_1:%.+]] = add nsw i64 [[IV_VAL]], 1
+// OMP5: store i64 [[IV_VAL_ADD_1]], i64* [[IV]],
+
+// goto loop;
+// OMP5: br label %[[LOOP]]
+
+// end:
+// OMP5: [[END]]:
+// OMP5: call void @__kmpc_for_static_fini(%struct.ident_t* {{.+}}, i32 [[GTID]])
+// exit:
+// OMP5: [[EXIT]]:
+// OMP5: ret void
+
+// OMP5-LABEL: range_for_collapsed
+void range_for_collapsed() {
+  int arr[10] = {0};
+// OMP5: call void @__kmpc_for_static_init_8(%struct.ident_t* {{.+}}, i32 [[GTID%.+]], i32 34, i32* %{{.+}}, i64* %{{.+}}, i64* %{{.+}}, i64* %{{.+}}, i64 1, i64 1)
+#pragma omp parallel for collapse(2)
+  for (auto &a : arr)
+    for (auto b : arr)
+      a = b;
+// OMP5: call void @__kmpc_for_static_fini(%struct.ident_t* {{.+}}, i32 [[GTID]])
+}
 #endif // OMP5
 
 #endif // HEADER

Modified: cfe/trunk/test/OpenMP/parallel_for_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_for_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/parallel_for_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -281,7 +281,7 @@ int test_iteration_spaces() {
       c[globalii] += a[globalii] + ii;
   }
 
-// expected-error at +2 {{statement after '#pragma omp parallel for' must be a for loop}}
+// omp4-error at +2 {{statement after '#pragma omp parallel for' must be a for loop}}
 #pragma omp parallel for
   for (auto &item : a) {
     item = item + 1;

Modified: cfe/trunk/test/OpenMP/parallel_for_simd_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_simd_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_for_simd_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/parallel_for_simd_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -283,7 +283,7 @@ int test_iteration_spaces() {
       c[globalii] += a[globalii] + ii;
   }
 
-// expected-error at +2 {{statement after '#pragma omp parallel for simd' must be a for loop}}
+// omp4-error at +2 {{statement after '#pragma omp parallel for simd' must be a for loop}}
 #pragma omp parallel for simd
   for (auto &item : a) {
     item = item + 1;

Modified: cfe/trunk/test/OpenMP/simd_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/simd_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/simd_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/simd_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -300,7 +300,7 @@ int test_iteration_spaces() {
       c[globalii] += a[globalii] + ii;
   }
 
-  // expected-error at +2 {{statement after '#pragma omp simd' must be a for loop}}
+  // omp4-error at +2 {{statement after '#pragma omp simd' must be a for loop}}
   #pragma omp simd
   for (auto &item : a) {
     item = item + 1;

Modified: cfe/trunk/test/OpenMP/target_parallel_for_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_parallel_for_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/target_parallel_for_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/target_parallel_for_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -281,7 +281,7 @@ int test_iteration_spaces() {
       c[globalii] += a[globalii] + ii;
   }
 
-// expected-error at +2 {{statement after '#pragma omp target parallel for' must be a for loop}}
+// omp4-error at +2 {{statement after '#pragma omp target parallel for' must be a for loop}}
 #pragma omp target parallel for
   for (auto &item : a) {
     item = item + 1;

Modified: cfe/trunk/test/OpenMP/target_parallel_for_simd_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_parallel_for_simd_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/target_parallel_for_simd_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/target_parallel_for_simd_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -283,7 +283,7 @@ int test_iteration_spaces() {
       c[globalii] += a[globalii] + ii;
   }
 
-// expected-error at +2 {{statement after '#pragma omp target parallel for simd' must be a for loop}}
+// omp4-error at +2 {{statement after '#pragma omp target parallel for simd' must be a for loop}}
 #pragma omp target parallel for simd
   for (auto &item : a) {
     item = item + 1;

Modified: cfe/trunk/test/OpenMP/target_simd_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_simd_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/target_simd_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/target_simd_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -283,7 +283,7 @@ int test_iteration_spaces() {
       c[globalii] += a[globalii] + ii;
   }
 
-// expected-error at +2 {{statement after '#pragma omp target simd' must be a for loop}}
+// omp4-error at +2 {{statement after '#pragma omp target simd' must be a for loop}}
 #pragma omp target simd
   for (auto &item : a) {
     item = item + 1;

Modified: cfe/trunk/test/OpenMP/target_teams_distribute_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_teams_distribute_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/target_teams_distribute_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/target_teams_distribute_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -269,7 +269,7 @@ int test_iteration_spaces() {
   }
 
 #pragma omp target teams distribute
-// expected-error at +1 {{statement after '#pragma omp target teams distribute' must be a for loop}}
+// omp4-error at +1 {{statement after '#pragma omp target teams distribute' must be a for loop}}
   for (auto &item : a) {
     item = item + 1;
   }

Modified: cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -267,7 +267,7 @@ int test_iteration_spaces() {
   }
 
 #pragma omp target teams distribute parallel for
-// expected-error at +1 {{statement after '#pragma omp target teams distribute parallel for' must be a for loop}}
+// omp4-error at +1 {{statement after '#pragma omp target teams distribute parallel for' must be a for loop}}
   for (auto &item : a) {
     item = item + 1;
   }

Modified: cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -269,7 +269,7 @@ int test_iteration_spaces() {
       c[globalii] += a[globalii] + ii;
   }
 
-// expected-error at +2 {{statement after '#pragma omp target teams distribute parallel for simd' must be a for loop}}
+// omp4-error at +2 {{statement after '#pragma omp target teams distribute parallel for simd' must be a for loop}}
 #pragma omp target teams distribute parallel for simd
   for (auto &item : a) {
     item = item + 1;

Modified: cfe/trunk/test/OpenMP/taskloop_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/taskloop_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/taskloop_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/taskloop_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -350,7 +350,7 @@ int test_iteration_spaces() {
   }
 
 #pragma omp parallel
-// expected-error at +2 {{statement after '#pragma omp taskloop' must be a for loop}}
+// omp4-error at +2 {{statement after '#pragma omp taskloop' must be a for loop}}
 #pragma omp taskloop
   for (auto &item : a) {
     item = item + 1;

Modified: cfe/trunk/test/OpenMP/taskloop_simd_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/taskloop_simd_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/taskloop_simd_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/taskloop_simd_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -352,7 +352,7 @@ int test_iteration_spaces() {
   }
 
 #pragma omp parallel
-// expected-error at +2 {{statement after '#pragma omp taskloop simd' must be a for loop}}
+// omp4-error at +2 {{statement after '#pragma omp taskloop simd' must be a for loop}}
 #pragma omp taskloop simd
   for (auto &item : a) {
     item = item + 1;

Modified: cfe/trunk/test/OpenMP/teams_distribute_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/teams_distribute_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/teams_distribute_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/teams_distribute_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -317,7 +317,7 @@ int test_iteration_spaces() {
 
 #pragma omp target
 #pragma omp teams distribute
-// expected-error at +1 {{statement after '#pragma omp teams distribute' must be a for loop}}
+// omp4-error at +1 {{statement after '#pragma omp teams distribute' must be a for loop}}
   for (auto &item : a) {
     item = item + 1;
   }

Modified: cfe/trunk/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -315,7 +315,7 @@ int test_iteration_spaces() {
 
 #pragma omp target
 #pragma omp teams distribute parallel for
-// expected-error at +1 {{statement after '#pragma omp teams distribute parallel for' must be a for loop}}
+// omp4-error at +1 {{statement after '#pragma omp teams distribute parallel for' must be a for loop}}
   for (auto &item : a) {
     item = item + 1;
   }

Modified: cfe/trunk/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -317,7 +317,7 @@ int test_iteration_spaces() {
 
 #pragma omp target
 #pragma omp teams distribute parallel for simd
-// expected-error at +1 {{statement after '#pragma omp teams distribute parallel for simd' must be a for loop}}
+// omp4-error at +1 {{statement after '#pragma omp teams distribute parallel for simd' must be a for loop}}
   for (auto &item : a) {
     item = item + 1;
   }

Modified: cfe/trunk/test/OpenMP/teams_distribute_simd_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/teams_distribute_simd_loop_messages.cpp?rev=373939&r1=373938&r2=373939&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/teams_distribute_simd_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/teams_distribute_simd_loop_messages.cpp Mon Oct  7 11:54:57 2019
@@ -317,7 +317,7 @@ int test_iteration_spaces() {
 
 #pragma omp target
 #pragma omp teams distribute simd
-// expected-error at +1 {{statement after '#pragma omp teams distribute simd' must be a for loop}}
+// omp4-error at +1 {{statement after '#pragma omp teams distribute simd' must be a for loop}}
   for (auto &item : a) {
     item = item + 1;
   }




More information about the cfe-commits mailing list