]> granicus.if.org Git - clang/commitdiff
[OpenMP] Prepare sema to support combined constructs with omp distribute and omp for
authorCarlo Bertolli <cbertol@us.ibm.com>
Thu, 20 Apr 2017 00:39:39 +0000 (00:39 +0000)
committerCarlo Bertolli <cbertol@us.ibm.com>
Thu, 20 Apr 2017 00:39:39 +0000 (00:39 +0000)
https://reviews.llvm.org/D32237

This patch prepares sema with additional fields to support all those composite and combined constructs of OpenMP that include pragma 'distribute' and 'for', such as 'distribute parallel for'. It also extends the regression tests for 'distribute parallel for' and adds a new one.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@300802 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/StmtOpenMP.h
lib/AST/StmtOpenMP.cpp
lib/Basic/OpenMPKinds.cpp
lib/Sema/SemaOpenMP.cpp
lib/Serialization/ASTReaderStmt.cpp
lib/Serialization/ASTWriterStmt.cpp
test/OpenMP/distribute_parallel_for_ast_print.cpp
test/OpenMP/distribute_parallel_for_messages.cpp [new file with mode: 0644]

index 13af142ca3ab8e4dba2760542b6ee9d79fb9064c..463af06fddaba64343fe9a0d5ac5657c875128d7 100644 (file)
@@ -318,8 +318,9 @@ class OMPLoopDirective : public OMPExecutableDirective {
   /// \brief Offsets to the stored exprs.
   /// This enumeration contains offsets to all the pointers to children
   /// expressions stored in OMPLoopDirective.
-  /// The first 9 children are nesessary for all the loop directives, and
-  /// the next 10 are specific to the worksharing ones.
+  /// The first 9 children are necessary for all the loop directives,
+  /// the next 8 are specific to the worksharing ones, and the next 11 are
+  /// used for combined constructs containing two pragmas associated to loops.
   /// After the fixed children, three arrays of length CollapsedNum are
   /// allocated: loop counters, their updates and final values.
   /// PrevLowerBound and PrevUpperBound are used to communicate blocking
@@ -344,7 +345,7 @@ class OMPLoopDirective : public OMPExecutableDirective {
     // specify the offset to the end (and start of the following counters/
     // updates/finals arrays).
     DefaultEnd = 9,
-    // The following 12 exprs are used by worksharing and distribute loops only.
+    // The following 8 exprs are used by worksharing and distribute loops only.
     IsLastIterVariableOffset = 9,
     LowerBoundVariableOffset = 10,
     UpperBoundVariableOffset = 11,
@@ -353,13 +354,22 @@ class OMPLoopDirective : public OMPExecutableDirective {
     NextLowerBoundOffset = 14,
     NextUpperBoundOffset = 15,
     NumIterationsOffset = 16,
+    // Offset to the end for worksharing loop directives.
+    WorksharingEnd = 17,
     PrevLowerBoundVariableOffset = 17,
     PrevUpperBoundVariableOffset = 18,
     DistIncOffset = 19,
     PrevEnsureUpperBoundOffset = 20,
+    CombinedLowerBoundVariableOffset = 21,
+    CombinedUpperBoundVariableOffset = 22,
+    CombinedEnsureUpperBoundOffset = 23,
+    CombinedInitOffset = 24,
+    CombinedConditionOffset = 25,
+    CombinedNextLowerBoundOffset = 26,
+    CombinedNextUpperBoundOffset = 27,
     // Offset to the end (and start of the following counters/updates/finals
-    // arrays) for worksharing loop directives.
-    WorksharingEnd = 21,
+    // arrays) for combined distribute loop directives.
+    CombinedDistributeEnd = 28,
   };
 
   /// \brief Get the counters storage.
@@ -423,11 +433,12 @@ protected:
 
   /// \brief Offset to the start of children expression arrays.
   static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
-    return (isOpenMPWorksharingDirective(Kind) ||
-            isOpenMPTaskLoopDirective(Kind) ||
-            isOpenMPDistributeDirective(Kind))
-               ? WorksharingEnd
-               : DefaultEnd;
+    if (isOpenMPLoopBoundSharingDirective(Kind))
+      return CombinedDistributeEnd;
+    if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) ||
+        isOpenMPDistributeDirective(Kind))
+      return WorksharingEnd;
+    return DefaultEnd;
   }
 
   /// \brief Children number.
@@ -515,33 +526,60 @@ protected:
     *std::next(child_begin(), NumIterationsOffset) = NI;
   }
   void setPrevLowerBoundVariable(Expr *PrevLB) {
-    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
-            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
-            isOpenMPDistributeDirective(getDirectiveKind())) &&
-           "expected worksharing loop directive");
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
     *std::next(child_begin(), PrevLowerBoundVariableOffset) = PrevLB;
   }
   void setPrevUpperBoundVariable(Expr *PrevUB) {
-    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
-            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
-            isOpenMPDistributeDirective(getDirectiveKind())) &&
-           "expected worksharing loop directive");
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
     *std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB;
   }
   void setDistInc(Expr *DistInc) {
-    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
-            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
-            isOpenMPDistributeDirective(getDirectiveKind())) &&
-           "expected worksharing loop directive");
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
     *std::next(child_begin(), DistIncOffset) = DistInc;
   }
   void setPrevEnsureUpperBound(Expr *PrevEUB) {
-    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
-            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
-            isOpenMPDistributeDirective(getDirectiveKind())) &&
-           "expected worksharing loop directive");
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
     *std::next(child_begin(), PrevEnsureUpperBoundOffset) = PrevEUB;
   }
+  void setCombinedLowerBoundVariable(Expr *CombLB) {
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
+    *std::next(child_begin(), CombinedLowerBoundVariableOffset) = CombLB;
+  }
+  void setCombinedUpperBoundVariable(Expr *CombUB) {
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
+    *std::next(child_begin(), CombinedUpperBoundVariableOffset) = CombUB;
+  }
+  void setCombinedEnsureUpperBound(Expr *CombEUB) {
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
+    *std::next(child_begin(), CombinedEnsureUpperBoundOffset) = CombEUB;
+  }
+  void setCombinedInit(Expr *CombInit) {
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
+    *std::next(child_begin(), CombinedInitOffset) = CombInit;
+  }
+  void setCombinedCond(Expr *CombCond) {
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
+    *std::next(child_begin(), CombinedConditionOffset) = CombCond;
+  }
+  void setCombinedNextLowerBound(Expr *CombNLB) {
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
+    *std::next(child_begin(), CombinedNextLowerBoundOffset) = CombNLB;
+  }
+  void setCombinedNextUpperBound(Expr *CombNUB) {
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
+    *std::next(child_begin(), CombinedNextUpperBoundOffset) = CombNUB;
+  }
   void setCounters(ArrayRef<Expr *> A);
   void setPrivateCounters(ArrayRef<Expr *> A);
   void setInits(ArrayRef<Expr *> A);
@@ -549,6 +587,33 @@ protected:
   void setFinals(ArrayRef<Expr *> A);
 
 public:
+  /// The expressions built to support OpenMP loops in combined/composite
+  /// pragmas (e.g. pragma omp distribute parallel for)
+  struct DistCombinedHelperExprs {
+    /// DistributeLowerBound - used when composing 'omp distribute' with
+    /// 'omp for' in a same construct.
+    Expr *LB;
+    /// DistributeUpperBound - used when composing 'omp distribute' with
+    /// 'omp for' in a same construct.
+    Expr *UB;
+    /// DistributeEnsureUpperBound - used when composing 'omp distribute'
+    ///  with 'omp for' in a same construct, EUB depends on DistUB
+    Expr *EUB;
+    /// Distribute loop iteration variable init used when composing 'omp
+    /// distribute'
+    ///  with 'omp for' in a same construct
+    Expr *Init;
+    /// Distribute Loop condition used when composing 'omp distribute'
+    ///  with 'omp for' in a same construct
+    Expr *Cond;
+    /// Update of LowerBound for statically sheduled omp loops for
+    /// outer loop in combined constructs (e.g. 'distribute parallel for')
+    Expr *NLB;
+    /// Update of UpperBound for statically sheduled omp loops for
+    /// outer loop in combined constructs (e.g. 'distribute parallel for')
+    Expr *NUB;
+  };
+
   /// \brief The expressions built for the OpenMP loop CodeGen for the
   /// whole collapsed loop nest.
   struct HelperExprs {
@@ -611,6 +676,9 @@ public:
     /// Init statement for all captured expressions.
     Stmt *PreInits;
 
+    /// Expressions used when combining OpenMP loop pragmas
+    DistCombinedHelperExprs DistCombinedFields;
+
     /// \brief Check if all the expressions are built (does not check the
     /// worksharing ones).
     bool builtAll() {
@@ -654,6 +722,13 @@ public:
         Finals[i] = nullptr;
       }
       PreInits = nullptr;
+      DistCombinedFields.LB = nullptr;
+      DistCombinedFields.UB = nullptr;
+      DistCombinedFields.EUB = nullptr;
+      DistCombinedFields.Init = nullptr;
+      DistCombinedFields.Cond = nullptr;
+      DistCombinedFields.NLB = nullptr;
+      DistCombinedFields.NUB = nullptr;
     }
   };
 
@@ -757,37 +832,71 @@ public:
         *std::next(child_begin(), NumIterationsOffset)));
   }
   Expr *getPrevLowerBoundVariable() const {
-    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
-            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
-            isOpenMPDistributeDirective(getDirectiveKind())) &&
-           "expected worksharing loop directive");
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
         *std::next(child_begin(), PrevLowerBoundVariableOffset)));
   }
   Expr *getPrevUpperBoundVariable() const {
-    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
-            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
-            isOpenMPDistributeDirective(getDirectiveKind())) &&
-           "expected worksharing loop directive");
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
         *std::next(child_begin(), PrevUpperBoundVariableOffset)));
   }
   Expr *getDistInc() const {
-    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
-            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
-            isOpenMPDistributeDirective(getDirectiveKind())) &&
-           "expected worksharing loop directive");
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
         *std::next(child_begin(), DistIncOffset)));
   }
   Expr *getPrevEnsureUpperBound() const {
-    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
-            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
-            isOpenMPDistributeDirective(getDirectiveKind())) &&
-           "expected worksharing loop directive");
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
         *std::next(child_begin(), PrevEnsureUpperBoundOffset)));
   }
+  Expr *getCombinedLowerBoundVariable() const {
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
+    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+        *std::next(child_begin(), CombinedLowerBoundVariableOffset)));
+  }
+  Expr *getCombinedUpperBoundVariable() const {
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
+    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+        *std::next(child_begin(), CombinedUpperBoundVariableOffset)));
+  }
+  Expr *getCombinedEnsureUpperBound() const {
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
+    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+        *std::next(child_begin(), CombinedEnsureUpperBoundOffset)));
+  }
+  Expr *getCombinedInit() const {
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
+    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+        *std::next(child_begin(), CombinedInitOffset)));
+  }
+  Expr *getCombinedCond() const {
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
+    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+        *std::next(child_begin(), CombinedConditionOffset)));
+  }
+  Expr *getCombinedNextLowerBound() const {
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
+    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+        *std::next(child_begin(), CombinedNextLowerBoundOffset)));
+  }
+  Expr *getCombinedNextUpperBound() const {
+    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
+           "expected loop bound sharing directive");
+    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+        *std::next(child_begin(), CombinedNextUpperBoundOffset)));
+  }
   const Stmt *getBody() const {
     // This relies on the loop form is already checked by Sema.
     Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
index a812884cd9278a5e4ba8f34cc2192a6fd0153be6..cccb2f075b657d8221d803325076ae59f3f55aa6 100644 (file)
@@ -147,10 +147,6 @@ OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
   Dir->setNextLowerBound(Exprs.NLB);
   Dir->setNextUpperBound(Exprs.NUB);
   Dir->setNumIterations(Exprs.NumIterations);
-  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
-  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
-  Dir->setDistInc(Exprs.DistInc);
-  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -201,10 +197,6 @@ OMPForSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
   Dir->setNextLowerBound(Exprs.NLB);
   Dir->setNextUpperBound(Exprs.NUB);
   Dir->setNumIterations(Exprs.NumIterations);
-  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
-  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
-  Dir->setDistInc(Exprs.DistInc);
-  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -368,10 +360,6 @@ OMPParallelForDirective *OMPParallelForDirective::Create(
   Dir->setNextLowerBound(Exprs.NLB);
   Dir->setNextUpperBound(Exprs.NUB);
   Dir->setNumIterations(Exprs.NumIterations);
-  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
-  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
-  Dir->setDistInc(Exprs.DistInc);
-  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -421,10 +409,6 @@ OMPParallelForSimdDirective *OMPParallelForSimdDirective::Create(
   Dir->setNextLowerBound(Exprs.NLB);
   Dir->setNextUpperBound(Exprs.NUB);
   Dir->setNumIterations(Exprs.NumIterations);
-  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
-  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
-  Dir->setDistInc(Exprs.DistInc);
-  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -759,10 +743,6 @@ OMPTargetParallelForDirective *OMPTargetParallelForDirective::Create(
   Dir->setNextLowerBound(Exprs.NLB);
   Dir->setNextUpperBound(Exprs.NUB);
   Dir->setNumIterations(Exprs.NumIterations);
-  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
-  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
-  Dir->setDistInc(Exprs.DistInc);
-  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -904,10 +884,6 @@ OMPTaskLoopDirective *OMPTaskLoopDirective::Create(
   Dir->setNextLowerBound(Exprs.NLB);
   Dir->setNextUpperBound(Exprs.NUB);
   Dir->setNumIterations(Exprs.NumIterations);
-  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
-  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
-  Dir->setDistInc(Exprs.DistInc);
-  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -957,10 +933,6 @@ OMPTaskLoopSimdDirective *OMPTaskLoopSimdDirective::Create(
   Dir->setNextLowerBound(Exprs.NLB);
   Dir->setNextUpperBound(Exprs.NUB);
   Dir->setNumIterations(Exprs.NumIterations);
-  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
-  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
-  Dir->setDistInc(Exprs.DistInc);
-  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1009,10 +981,6 @@ OMPDistributeDirective *OMPDistributeDirective::Create(
   Dir->setNextLowerBound(Exprs.NLB);
   Dir->setNextUpperBound(Exprs.NUB);
   Dir->setNumIterations(Exprs.NumIterations);
-  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
-  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
-  Dir->setDistInc(Exprs.DistInc);
-  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1095,6 +1063,13 @@ OMPDistributeParallelForDirective *OMPDistributeParallelForDirective::Create(
   Dir->setUpdates(Exprs.Updates);
   Dir->setFinals(Exprs.Finals);
   Dir->setPreInits(Exprs.PreInits);
+  Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
+  Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
+  Dir->setCombinedEnsureUpperBound(Exprs.DistCombinedFields.EUB);
+  Dir->setCombinedInit(Exprs.DistCombinedFields.Init);
+  Dir->setCombinedCond(Exprs.DistCombinedFields.Cond);
+  Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB);
+  Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB);
   return Dir;
 }
 
@@ -1153,6 +1128,13 @@ OMPDistributeParallelForSimdDirective::Create(
   Dir->setUpdates(Exprs.Updates);
   Dir->setFinals(Exprs.Finals);
   Dir->setPreInits(Exprs.PreInits);
+  Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
+  Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
+  Dir->setCombinedEnsureUpperBound(Exprs.DistCombinedFields.EUB);
+  Dir->setCombinedInit(Exprs.DistCombinedFields.Init);
+  Dir->setCombinedCond(Exprs.DistCombinedFields.Cond);
+  Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB);
+  Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB);
   return Dir;
 }
 
@@ -1200,10 +1182,6 @@ OMPDistributeSimdDirective *OMPDistributeSimdDirective::Create(
   Dir->setNextLowerBound(Exprs.NLB);
   Dir->setNextUpperBound(Exprs.NUB);
   Dir->setNumIterations(Exprs.NumIterations);
-  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
-  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
-  Dir->setDistInc(Exprs.DistInc);
-  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1256,10 +1234,6 @@ OMPTargetParallelForSimdDirective *OMPTargetParallelForSimdDirective::Create(
   Dir->setNextLowerBound(Exprs.NLB);
   Dir->setNextUpperBound(Exprs.NUB);
   Dir->setNumIterations(Exprs.NumIterations);
-  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
-  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
-  Dir->setDistInc(Exprs.DistInc);
-  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1352,10 +1326,6 @@ OMPTeamsDistributeDirective *OMPTeamsDistributeDirective::Create(
   Dir->setNextLowerBound(Exprs.NLB);
   Dir->setNextUpperBound(Exprs.NUB);
   Dir->setNumIterations(Exprs.NumIterations);
-  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
-  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
-  Dir->setDistInc(Exprs.DistInc);
-  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1407,10 +1377,6 @@ OMPTeamsDistributeSimdDirective *OMPTeamsDistributeSimdDirective::Create(
   Dir->setNextLowerBound(Exprs.NLB);
   Dir->setNextUpperBound(Exprs.NUB);
   Dir->setNumIterations(Exprs.NumIterations);
-  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
-  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
-  Dir->setDistInc(Exprs.DistInc);
-  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1474,6 +1440,13 @@ OMPTeamsDistributeParallelForSimdDirective::Create(
   Dir->setUpdates(Exprs.Updates);
   Dir->setFinals(Exprs.Finals);
   Dir->setPreInits(Exprs.PreInits);
+  Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
+  Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
+  Dir->setCombinedEnsureUpperBound(Exprs.DistCombinedFields.EUB);
+  Dir->setCombinedInit(Exprs.DistCombinedFields.Init);
+  Dir->setCombinedCond(Exprs.DistCombinedFields.Cond);
+  Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB);
+  Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB);
   return Dir;
 }
 
@@ -1534,6 +1507,13 @@ OMPTeamsDistributeParallelForDirective::Create(
   Dir->setUpdates(Exprs.Updates);
   Dir->setFinals(Exprs.Finals);
   Dir->setPreInits(Exprs.PreInits);
+  Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
+  Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
+  Dir->setCombinedEnsureUpperBound(Exprs.DistCombinedFields.EUB);
+  Dir->setCombinedInit(Exprs.DistCombinedFields.Init);
+  Dir->setCombinedCond(Exprs.DistCombinedFields.Cond);
+  Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB);
+  Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB);
   return Dir;
 }
 
@@ -1606,10 +1586,6 @@ OMPTargetTeamsDistributeDirective *OMPTargetTeamsDistributeDirective::Create(
   Dir->setNextLowerBound(Exprs.NLB);
   Dir->setNextUpperBound(Exprs.NUB);
   Dir->setNumIterations(Exprs.NumIterations);
-  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
-  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
-  Dir->setDistInc(Exprs.DistInc);
-  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
@@ -1676,6 +1652,13 @@ OMPTargetTeamsDistributeParallelForDirective::Create(
   Dir->setUpdates(Exprs.Updates);
   Dir->setFinals(Exprs.Finals);
   Dir->setPreInits(Exprs.PreInits);
+  Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
+  Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
+  Dir->setCombinedEnsureUpperBound(Exprs.DistCombinedFields.EUB);
+  Dir->setCombinedInit(Exprs.DistCombinedFields.Init);
+  Dir->setCombinedCond(Exprs.DistCombinedFields.Cond);
+  Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB);
+  Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB);
   return Dir;
 }
 
@@ -1739,6 +1722,13 @@ OMPTargetTeamsDistributeParallelForSimdDirective::Create(
   Dir->setUpdates(Exprs.Updates);
   Dir->setFinals(Exprs.Finals);
   Dir->setPreInits(Exprs.PreInits);
+  Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
+  Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
+  Dir->setCombinedEnsureUpperBound(Exprs.DistCombinedFields.EUB);
+  Dir->setCombinedInit(Exprs.DistCombinedFields.Init);
+  Dir->setCombinedCond(Exprs.DistCombinedFields.Cond);
+  Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB);
+  Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB);
   return Dir;
 }
 
@@ -1789,10 +1779,6 @@ OMPTargetTeamsDistributeSimdDirective::Create(
   Dir->setNextLowerBound(Exprs.NLB);
   Dir->setNextUpperBound(Exprs.NUB);
   Dir->setNumIterations(Exprs.NumIterations);
-  Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
-  Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
-  Dir->setDistInc(Exprs.DistInc);
-  Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
   Dir->setCounters(Exprs.Counters);
   Dir->setPrivateCounters(Exprs.PrivateCounters);
   Dir->setInits(Exprs.Inits);
index 5a8bb61eaadf9dfb9c239fa0766f1c0216c1ae9b..76a0e18c2d73f7e2a9ca1173e5f69eeb97ab003e 100644 (file)
@@ -854,14 +854,10 @@ bool clang::isOpenMPTaskingDirective(OpenMPDirectiveKind Kind) {
 bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) {
   return Kind == OMPD_distribute_parallel_for ||
          Kind == OMPD_distribute_parallel_for_simd ||
-         Kind == OMPD_distribute_simd || Kind == OMPD_teams_distribute ||
-         Kind == OMPD_teams_distribute_simd ||
          Kind == OMPD_teams_distribute_parallel_for_simd ||
          Kind == OMPD_teams_distribute_parallel_for ||
-         Kind == OMPD_target_teams_distribute ||
          Kind == OMPD_target_teams_distribute_parallel_for ||
-         Kind == OMPD_target_teams_distribute_parallel_for_simd ||
-         Kind == OMPD_target_teams_distribute_simd;
+         Kind == OMPD_target_teams_distribute_parallel_for_simd;
 }
 
 void clang::getOpenMPCaptureRegions(
index 616ab05eaec80458efc2404b77ca55d97a596dd7..d7a6d2e5885eea562dd4cb72b77540ae9b08c1ec 100644 (file)
@@ -4068,7 +4068,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
   SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
 
   // Build variables passed into runtime, necessary for worksharing directives.
-  ExprResult LB, UB, IL, ST, EUB, PrevLB, PrevUB;
+  ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
       isOpenMPDistributeDirective(DKind)) {
     // Lower bound variable, initialized with zero.
@@ -4116,8 +4116,32 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
     // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
     // by scheduling 'distribute' have to be passed to the schedule of 'for'.
     if (isOpenMPLoopBoundSharingDirective(DKind)) {
-      auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
 
+      // Lower bound variable, initialized with zero.
+      VarDecl *CombLBDecl =
+          buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
+      CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
+      SemaRef.AddInitializerToDecl(
+          CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
+          /*DirectInit*/ false);
+
+      // Upper bound variable, initialized with last iteration number.
+      VarDecl *CombUBDecl =
+          buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
+      CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
+      SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
+                                   /*DirectInit*/ false);
+
+      ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
+          CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
+      ExprResult CombCondOp =
+          SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
+                                     LastIteration.get(), CombUB.get());
+      CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
+                                   CombCondOp.get());
+      CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
+
+      auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
       // We expect to have at least 2 more parameters than the 'parallel'
       // directive does - the lower and upper bounds of the previous schedule.
       assert(CD->getNumParams() >= 4 &&
@@ -4139,7 +4163,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
 
   // Build the iteration variable and its initialization before loop.
   ExprResult IV;
-  ExprResult Init;
+  ExprResult Init, CombInit;
   {
     VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
     IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
@@ -4150,6 +4174,18 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
             : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
     Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
     Init = SemaRef.ActOnFinishFullExpr(Init.get());
+
+    if (isOpenMPLoopBoundSharingDirective(DKind)) {
+      Expr *CombRHS =
+          (isOpenMPWorksharingDirective(DKind) ||
+           isOpenMPTaskLoopDirective(DKind) ||
+           isOpenMPDistributeDirective(DKind))
+              ? CombLB.get()
+              : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
+      CombInit =
+          SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
+      CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
+    }
   }
 
   // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
@@ -4160,7 +4196,11 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
           ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
           : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
                                NumIterations.get());
-
+  ExprResult CombCond;
+  if (isOpenMPLoopBoundSharingDirective(DKind)) {
+    CombCond =
+        SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
+  }
   // Loop increment (IV = IV + 1)
   SourceLocation IncLoc;
   ExprResult Inc =
@@ -4175,7 +4215,9 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
 
   // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
   // Used for directives with static scheduling.
-  ExprResult NextLB, NextUB;
+  // In combined construct, add combined version that use CombLB and CombUB
+  // base variables for the update
+  ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
       isOpenMPDistributeDirective(DKind)) {
     // LB + ST
@@ -4198,9 +4240,32 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
     NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
     if (!NextUB.isUsable())
       return 0;
-  }
-
-  // Create: increment expression for distribute loop when combined in a same
+    if (isOpenMPLoopBoundSharingDirective(DKind)) {
+      CombNextLB =
+          SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
+      if (!NextLB.isUsable())
+        return 0;
+      // LB = LB + ST
+      CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
+                                      CombNextLB.get());
+      CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
+      if (!CombNextLB.isUsable())
+        return 0;
+      // UB + ST
+      CombNextUB =
+          SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
+      if (!CombNextUB.isUsable())
+        return 0;
+      // UB = UB + ST
+      CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
+                                      CombNextUB.get());
+      CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
+      if (!CombNextUB.isUsable())
+        return 0;
+    }
+  }
+
+  // Create increment expression for distribute loop when combined in a same
   // directive with for as IV = IV + ST; ensure upper bound expression based
   // on PrevUB instead of NumIterations - used to implement 'for' when found
   // in combination with 'distribute', like in 'distribute parallel for'
@@ -4346,6 +4411,13 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
   Built.PrevUB = PrevUB.get();
   Built.DistInc = DistInc.get();
   Built.PrevEUB = PrevEUB.get();
+  Built.DistCombinedFields.LB = CombLB.get();
+  Built.DistCombinedFields.UB = CombUB.get();
+  Built.DistCombinedFields.EUB = CombEUB.get();
+  Built.DistCombinedFields.Init = CombInit.get();
+  Built.DistCombinedFields.Cond = CombCond.get();
+  Built.DistCombinedFields.NLB = CombNextLB.get();
+  Built.DistCombinedFields.NUB = CombNextUB.get();
 
   Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get();
   // Fill data for doacross depend clauses.
index a12fb8cf95a0946620c6264dff1ed89c0302b1ec..3d314a85ff17f1266d42090362e0ca70476065ff 100644 (file)
@@ -2578,6 +2578,13 @@ void ASTStmtReader::VisitOMPLoopDirective(OMPLoopDirective *D) {
     D->setPrevUpperBoundVariable(Record.readSubExpr());
     D->setDistInc(Record.readSubExpr());
     D->setPrevEnsureUpperBound(Record.readSubExpr());
+    D->setCombinedLowerBoundVariable(Record.readSubExpr());
+    D->setCombinedUpperBoundVariable(Record.readSubExpr());
+    D->setCombinedEnsureUpperBound(Record.readSubExpr());
+    D->setCombinedInit(Record.readSubExpr());
+    D->setCombinedCond(Record.readSubExpr());
+    D->setCombinedNextLowerBound(Record.readSubExpr());
+    D->setCombinedNextUpperBound(Record.readSubExpr());
   }
   SmallVector<Expr *, 4> Sub;
   unsigned CollapsedNum = D->getCollapsedNumber();
index 1a2edac65886571148fcea7dfd2c227d53cb97f0..90a732e575e2e578761e9c4da0feacdb2b4c9f05 100644 (file)
@@ -2248,6 +2248,13 @@ void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) {
     Record.AddStmt(D->getPrevUpperBoundVariable());
     Record.AddStmt(D->getDistInc());
     Record.AddStmt(D->getPrevEnsureUpperBound());
+    Record.AddStmt(D->getCombinedLowerBoundVariable());
+    Record.AddStmt(D->getCombinedUpperBoundVariable());
+    Record.AddStmt(D->getCombinedEnsureUpperBound());
+    Record.AddStmt(D->getCombinedInit());
+    Record.AddStmt(D->getCombinedCond());
+    Record.AddStmt(D->getCombinedNextLowerBound());
+    Record.AddStmt(D->getCombinedNextUpperBound());
   }
   for (auto I : D->counters()) {
     Record.AddStmt(I);
index 874345b6732781a316fed9cb1e3e5595a23d8c91..54a3649e578b80a74acfeb69f78914e0f12897bc 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -verify -std=c++11 -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
@@ -109,6 +109,41 @@ T tmain(T argc) {
   return T();
 }
 
+void foo(int argc, char **argv) {
+  int b, c, d, e, f, h;
+  static int a;
+// CHECK: static int a;
+  static float g;
+#pragma omp threadprivate(g)
+  [&]() {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a)
+    // CHECK: #pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a)
+    for (int i = 0; i < 2; ++i)
+// CHECK: for (int i = 0; i < 2; ++i)
+      [&]() {
+         a = 2;
+         // CHECK: a = 2;
+       }();
+
+  }();
+  [&]() {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) if (argc) num_threads(a) default(shared) shared(e) reduction(+ : h) dist_schedule(static, b)
+    for (int i = 0; i < 10; ++i)
+      for (int j = 0; j < 10; ++j)
+       [&]() {
+         a++;
+       }();
+    // CHECK: #pragma omp distribute parallel for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) if(argc) num_threads(a) default(shared) shared(e) reduction(+: h) dist_schedule(static, b)
+    // CHECK-NEXT: for (int i = 0; i < 10; ++i)
+    // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+    // CHECK: a++;
+  }();
+}
+
 int main(int argc, char **argv) {
   int b = argc, c, d, e, f, h;
   static int a;
diff --git a/test/OpenMP/distribute_parallel_for_messages.cpp b/test/OpenMP/distribute_parallel_for_messages.cpp
new file mode 100644 (file)
index 0000000..35a61df
--- /dev/null
@@ -0,0 +1,118 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -std=c++11 -o - %s
+
+void foo() {
+}
+
+#pragma omp distribute parallel for // expected-error {{unexpected OpenMP directive '#pragma omp distribute parallel for'}}
+
+int main(int argc, char **argv) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for { // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for ( // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for[ // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for] // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for } // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for unknown()   // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+L1:
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < argc; ++i) {
+    goto L1; // expected-error {{use of undeclared label 'L1'}}
+    argc++;
+  }
+
+  for (int i = 0; i < 10; ++i) {
+    switch (argc) {
+    case (0):
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+      for (int i = 0; i < argc; ++i) {
+        foo();
+        break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+        continue;
+      }
+    default:
+      break;
+    }
+  }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default(none)
+  for (int i = 0; i < 10; ++i)
+    ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+
+  goto L2; // expected-error {{use of undeclared label 'L2'}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < argc; ++i)
+  L2:
+  foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+  for (int i = 0; i < argc; ++i) {
+    return 1; // expected-error {{cannot return from OpenMP region}}
+  }
+
+  [[]] // expected-error {{an attribute list cannot appear here}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+      for (int n = 0; n < 100; ++n) {
+  }
+
+  return 0;
+}
+
+void test_ordered() {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse(2) collapse(3) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'collapse' clause}}
+  for (int i = 0; i < 16; ++i)
+    for (int j = 0; j < 16; ++j)
+    ;
+}
+