<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>I think it would be good to backport it. Could you do that,
      Jonas?<br>
    </p>
    <pre class="moz-signature" cols="72">-------------
Best regards,
Alexey Bataev</pre>
    <div class="moz-cite-prefix">15.08.2018 5:02, Jonas Hahnfeld via
      cfe-commits пишет:<br>
    </div>
    <blockquote type="cite"
      cite="mid:%3Cc53f620a922b2ea7405067a42a7c7d4a@hahnjo.de%3E">Alexey,
      Hans,
      <br>
      <br>
      does it make sense to backport for 7.0 as it fixes PR37580?
      <br>
      <br>
      Thanks,
      <br>
      Jonas
      <br>
      <br>
      On 2018-08-13 21:04, Alexey Bataev via cfe-commits wrote:
      <br>
      <blockquote type="cite">Author: abataev
        <br>
        Date: Mon Aug 13 12:04:24 2018
        <br>
        New Revision: 339603
        <br>
        <br>
        URL: <a class="moz-txt-link-freetext" href="http://llvm.org/viewvc/llvm-project?rev=339603&view=rev">http://llvm.org/viewvc/llvm-project?rev=339603&view=rev</a>
        <br>
        Log:
        <br>
        [OPENMP] Fix emission of the loop doacross constructs.
        <br>
        <br>
        The number of loops associated with the OpenMP loop constructs
        should
        <br>
        not be considered as the number loops to collapse.
        <br>
        <br>
        Modified:
        <br>
            cfe/trunk/include/clang/AST/OpenMPClause.h
        <br>
            cfe/trunk/lib/AST/OpenMPClause.cpp
        <br>
            cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
        <br>
            cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h
        <br>
            cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
        <br>
            cfe/trunk/lib/Sema/SemaOpenMP.cpp
        <br>
            cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
        <br>
            cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
        <br>
            cfe/trunk/test/OpenMP/ordered_doacross_codegen.c
        <br>
            cfe/trunk/test/OpenMP/ordered_doacross_codegen.cpp
        <br>
            cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp
        <br>
        <br>
        Modified: cfe/trunk/include/clang/AST/OpenMPClause.h
        <br>
        URL:
        <br>
<a class="moz-txt-link-freetext" href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=339603&r1=339602&r2=339603&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=339603&r1=339602&r2=339603&view=diff</a>
        <br>
==============================================================================
        <br>
        --- cfe/trunk/include/clang/AST/OpenMPClause.h (original)
        <br>
        +++ cfe/trunk/include/clang/AST/OpenMPClause.h Mon Aug 13
        12:04:24 2018
        <br>
        @@ -930,8 +930,11 @@ public:
        <br>
         /// \endcode
        <br>
         /// In this example directive '#pragma omp for' has 'ordered'
        clause with
        <br>
         /// parameter 2.
        <br>
        -class OMPOrderedClause : public OMPClause {
        <br>
        +class OMPOrderedClause final
        <br>
        +    : public OMPClause,
        <br>
        +      private llvm::TrailingObjects<OMPOrderedClause, Expr
        *> {
        <br>
           friend class OMPClauseReader;
        <br>
        +  friend TrailingObjects;
        <br>
        <br>
           /// Location of '('.
        <br>
           SourceLocation LParenLoc;
        <br>
        @@ -939,6 +942,26 @@ class OMPOrderedClause : public OMPClaus
        <br>
           /// Number of for-loops.
        <br>
           Stmt *NumForLoops = nullptr;
        <br>
        <br>
        +  /// Real number of loops.
        <br>
        +  unsigned NumberOfLoops = 0;
        <br>
        +
        <br>
        +  /// Build 'ordered' clause.
        <br>
        +  ///
        <br>
        +  /// \param Num Expression, possibly associated with this
        clause.
        <br>
        +  /// \param NumLoops Number of loops, associated with this
        clause.
        <br>
        +  /// \param StartLoc Starting location of the clause.
        <br>
        +  /// \param LParenLoc Location of '('.
        <br>
        +  /// \param EndLoc Ending location of the clause.
        <br>
        +  OMPOrderedClause(Expr *Num, unsigned NumLoops, SourceLocation
        StartLoc,
        <br>
        +                   SourceLocation LParenLoc, SourceLocation
        EndLoc)
        <br>
        +      : OMPClause(OMPC_ordered, StartLoc, EndLoc),
        LParenLoc(LParenLoc),
        <br>
        +        NumForLoops(Num), NumberOfLoops(NumLoops) {}
        <br>
        +
        <br>
        +  /// Build an empty clause.
        <br>
        +  explicit OMPOrderedClause(unsigned NumLoops)
        <br>
        +      : OMPClause(OMPC_ordered, SourceLocation(),
        SourceLocation()),
        <br>
        +        NumberOfLoops(NumLoops) {}
        <br>
        +
        <br>
           /// Set the number of associated for-loops.
        <br>
           void setNumForLoops(Expr *Num) { NumForLoops = Num; }
        <br>
        <br>
        @@ -946,17 +969,17 @@ public:
        <br>
           /// Build 'ordered' clause.
        <br>
           ///
        <br>
           /// \param Num Expression, possibly associated with this
        clause.
        <br>
        +  /// \param NumLoops Number of loops, associated with this
        clause.
        <br>
           /// \param StartLoc Starting location of the clause.
        <br>
           /// \param LParenLoc Location of '('.
        <br>
           /// \param EndLoc Ending location of the clause.
        <br>
        -  OMPOrderedClause(Expr *Num, SourceLocation StartLoc,
        <br>
        -                    SourceLocation LParenLoc, SourceLocation
        EndLoc)
        <br>
        -      : OMPClause(OMPC_ordered, StartLoc, EndLoc),
        LParenLoc(LParenLoc),
        <br>
        -        NumForLoops(Num) {}
        <br>
        +  static OMPOrderedClause *Create(const ASTContext &C, Expr
        *Num,
        <br>
        +                                  unsigned NumLoops,
        SourceLocation StartLoc,
        <br>
        +                                  SourceLocation LParenLoc,
        <br>
        +                                  SourceLocation EndLoc);
        <br>
        <br>
           /// Build an empty clause.
        <br>
        -  explicit OMPOrderedClause()
        <br>
        -      : OMPClause(OMPC_ordered, SourceLocation(),
        SourceLocation()) {}
        <br>
        +  static OMPOrderedClause* CreateEmpty(const ASTContext &C,
        unsigned NumLoops);
        <br>
        <br>
           /// Sets the location of '('.
        <br>
           void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
        <br>
        @@ -967,6 +990,17 @@ public:
        <br>
           /// Return the number of associated for-loops.
        <br>
           Expr *getNumForLoops() const { return
        cast_or_null<Expr>(NumForLoops); }
        <br>
        <br>
        +  /// Set number of iterations for the specified loop.
        <br>
        +  void setLoopNumIterations(unsigned NumLoop, Expr
        *NumIterations);
        <br>
        +  /// Get number of iterations for all the loops.
        <br>
        +  ArrayRef<Expr *> getLoopNumIterations() const;
        <br>
        +
        <br>
        +  /// Set loop counter for the specified loop.
        <br>
        +  void setLoopCounter(unsigned NumLoop, Expr *Counter);
        <br>
        +  /// Get loops counter for the specified loop.
        <br>
        +  Expr *getLoopCunter(unsigned NumLoop);
        <br>
        +  const Expr *getLoopCunter(unsigned NumLoop) const;
        <br>
        +
        <br>
           child_range children() { return child_range(&NumForLoops,
        <br>
        &NumForLoops + 1); }
        <br>
        <br>
           static bool classof(const OMPClause *T) {
        <br>
        @@ -3095,24 +3129,32 @@ class OMPDependClause final
        <br>
           /// Colon location.
        <br>
           SourceLocation ColonLoc;
        <br>
        <br>
        +  /// Number of loops, associated with the depend clause.
        <br>
        +  unsigned NumLoops = 0;
        <br>
        +
        <br>
           /// Build clause with number of variables \a N.
        <br>
           ///
        <br>
           /// \param StartLoc Starting location of the clause.
        <br>
           /// \param LParenLoc Location of '('.
        <br>
           /// \param EndLoc Ending location of the clause.
        <br>
           /// \param N Number of the variables in the clause.
        <br>
        +  /// \param NumLoops Number of loops that is associated with
        this depend
        <br>
        +  /// clause.
        <br>
           OMPDependClause(SourceLocation StartLoc, SourceLocation
        LParenLoc,
        <br>
        -                  SourceLocation EndLoc, unsigned N)
        <br>
        +                  SourceLocation EndLoc, unsigned N, unsigned
        NumLoops)
        <br>
               : OMPVarListClause<OMPDependClause>(OMPC_depend,
        StartLoc, LParenLoc,
        <br>
        -                                          EndLoc, N) {}
        <br>
        +                                          EndLoc, N),
        NumLoops(NumLoops) {}
        <br>
        <br>
           /// Build an empty clause.
        <br>
           ///
        <br>
           /// \param N Number of variables.
        <br>
        -  explicit OMPDependClause(unsigned N)
        <br>
        +  /// \param NumLoops Number of loops that is associated with
        this depend
        <br>
        +  /// clause.
        <br>
        +  explicit OMPDependClause(unsigned N, unsigned NumLoops)
        <br>
               : OMPVarListClause<OMPDependClause>(OMPC_depend,
        SourceLocation(),
        <br>
                                                   SourceLocation(),
        SourceLocation(),
        <br>
        -                                          N) {}
        <br>
        +                                          N),
        <br>
        +        NumLoops(NumLoops) {}
        <br>
        <br>
           /// Set dependency kind.
        <br>
           void setDependencyKind(OpenMPDependClauseKind K) { DepKind =
        K; }
        <br>
        @@ -3134,16 +3176,23 @@ public:
        <br>
           /// \param DepLoc Location of the dependency type.
        <br>
           /// \param ColonLoc Colon location.
        <br>
           /// \param VL List of references to the variables.
        <br>
        -  static OMPDependClause *
        <br>
        -  Create(const ASTContext &C, SourceLocation StartLoc,
        SourceLocation
        <br>
        LParenLoc,
        <br>
        -         SourceLocation EndLoc, OpenMPDependClauseKind DepKind,
        <br>
        -         SourceLocation DepLoc, SourceLocation ColonLoc,
        ArrayRef<Expr *> VL);
        <br>
        +  /// \param NumLoops Number of loops that is associated with
        this depend
        <br>
        +  /// clause.
        <br>
        +  static OMPDependClause *Create(const ASTContext &C,
        SourceLocation StartLoc,
        <br>
        +                                 SourceLocation LParenLoc,
        <br>
        +                                 SourceLocation EndLoc,
        <br>
        +                                 OpenMPDependClauseKind
        DepKind,
        <br>
        +                                 SourceLocation DepLoc,
        <br>
        SourceLocation ColonLoc,
        <br>
        +                                 ArrayRef<Expr *> VL,
        unsigned NumLoops);
        <br>
        <br>
           /// Creates an empty clause with \a N variables.
        <br>
           ///
        <br>
           /// \param C AST context.
        <br>
           /// \param N The number of variables.
        <br>
        -  static OMPDependClause *CreateEmpty(const ASTContext &C,
        unsigned N);
        <br>
        +  /// \param NumLoops Number of loops that is associated with
        this depend
        <br>
        +  /// clause.
        <br>
        +  static OMPDependClause *CreateEmpty(const ASTContext &C,
        unsigned N,
        <br>
        +                                      unsigned NumLoops);
        <br>
        <br>
           /// Get dependency type.
        <br>
           OpenMPDependClauseKind getDependencyKind() const { return
        DepKind; }
        <br>
        @@ -3154,15 +3203,16 @@ public:
        <br>
           /// Get colon location.
        <br>
           SourceLocation getColonLoc() const { return ColonLoc; }
        <br>
        <br>
        -  /// Set the loop counter value for the depend clauses with
        'sink|source' kind
        <br>
        -  /// of dependency. Required for codegen.
        <br>
        -  void setCounterValue(Expr *V);
        <br>
        -
        <br>
        -  /// Get the loop counter value.
        <br>
        -  Expr *getCounterValue();
        <br>
        +  /// Get number of loops associated with the clause.
        <br>
        +  unsigned getNumLoops() const { return NumLoops; }
        <br>
        <br>
        -  /// Get the loop counter value.
        <br>
        -  const Expr *getCounterValue() const;
        <br>
        +  /// Set the loop data for the depend clauses with
        'sink|source' kind of
        <br>
        +  /// dependency.
        <br>
        +  void setLoopData(unsigned NumLoop, Expr *Cnt);
        <br>
        +
        <br>
        +  /// Get the loop data.
        <br>
        +  Expr *getLoopData(unsigned NumLoop);
        <br>
        +  const Expr *getLoopData(unsigned NumLoop) const;
        <br>
        <br>
           child_range children() {
        <br>
             return child_range(reinterpret_cast<Stmt
        **>(varlist_begin()),
        <br>
        <br>
        Modified: cfe/trunk/lib/AST/OpenMPClause.cpp
        <br>
        URL:
        <br>
<a class="moz-txt-link-freetext" href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/OpenMPClause.cpp?rev=339603&r1=339602&r2=339603&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/OpenMPClause.cpp?rev=339603&r1=339602&r2=339603&view=diff</a>
        <br>
==============================================================================
        <br>
        --- cfe/trunk/lib/AST/OpenMPClause.cpp (original)
        <br>
        +++ cfe/trunk/lib/AST/OpenMPClause.cpp Mon Aug 13 12:04:24 2018
        <br>
        @@ -181,6 +181,57 @@ const OMPClauseWithPostUpdate *OMPClause
        <br>
           return nullptr;
        <br>
         }
        <br>
        <br>
        +OMPOrderedClause *OMPOrderedClause::Create(const ASTContext
        &C, Expr *Num,
        <br>
        +                                           unsigned NumLoops,
        <br>
        +                                           SourceLocation
        StartLoc,
        <br>
        +                                           SourceLocation
        LParenLoc,
        <br>
        +                                           SourceLocation
        EndLoc) {
        <br>
        +  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 *
        NumLoops));
        <br>
        +  auto *Clause =
        <br>
        +      new (Mem) OMPOrderedClause(Num, NumLoops, StartLoc,
        LParenLoc, EndLoc);
        <br>
        +  for (unsigned I = 0; I < NumLoops; ++I) {
        <br>
        +    Clause->setLoopNumIterations(I, nullptr);
        <br>
        +    Clause->setLoopCounter(I, nullptr);
        <br>
        +  }
        <br>
        +  return Clause;
        <br>
        +}
        <br>
        +
        <br>
        +OMPOrderedClause *OMPOrderedClause::CreateEmpty(const
        ASTContext &C,
        <br>
        +                                                unsigned
        NumLoops) {
        <br>
        +  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 *
        NumLoops));
        <br>
        +  auto *Clause = new (Mem) OMPOrderedClause(NumLoops);
        <br>
        +  for (unsigned I = 0; I < NumLoops; ++I) {
        <br>
        +    Clause->setLoopNumIterations(I, nullptr);
        <br>
        +    Clause->setLoopCounter(I, nullptr);
        <br>
        +  }
        <br>
        +  return Clause;
        <br>
        +}
        <br>
        +
        <br>
        +void OMPOrderedClause::setLoopNumIterations(unsigned NumLoop,
        <br>
        +                                            Expr
        *NumIterations) {
        <br>
        +  assert(NumLoop < NumberOfLoops && "out of loops
        number.");
        <br>
        +  getTrailingObjects<Expr *>()[NumLoop] = NumIterations;
        <br>
        +}
        <br>
        +
        <br>
        +ArrayRef<Expr *> OMPOrderedClause::getLoopNumIterations()
        const {
        <br>
        +  return llvm::makeArrayRef(getTrailingObjects<Expr *>(),
        NumberOfLoops);
        <br>
        +}
        <br>
        +
        <br>
        +void OMPOrderedClause::setLoopCounter(unsigned NumLoop, Expr
        *Counter) {
        <br>
        +  assert(NumLoop < NumberOfLoops && "out of loops
        number.");
        <br>
        +  getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop] =
        Counter;
        <br>
        +}
        <br>
        +
        <br>
        +Expr *OMPOrderedClause::getLoopCunter(unsigned NumLoop) {
        <br>
        +  assert(NumLoop < NumberOfLoops && "out of loops
        number.");
        <br>
        +  return getTrailingObjects<Expr *>()[NumberOfLoops +
        NumLoop];
        <br>
        +}
        <br>
        +
        <br>
        +const Expr *OMPOrderedClause::getLoopCunter(unsigned NumLoop)
        const {
        <br>
        +  assert(NumLoop < NumberOfLoops && "out of loops
        number.");
        <br>
        +  return getTrailingObjects<Expr *>()[NumberOfLoops +
        NumLoop];
        <br>
        +}
        <br>
        +
        <br>
         void OMPPrivateClause::setPrivateCopies(ArrayRef<Expr *>
        VL) {
        <br>
           assert(VL.size() == varlist_size() &&
        <br>
                  "Number of private copies is not the same as the
        <br>
        preallocated buffer");
        <br>
        @@ -653,44 +704,58 @@ OMPFlushClause *OMPFlushClause::CreateEm
        <br>
           return new (Mem) OMPFlushClause(N);
        <br>
         }
        <br>
        <br>
        -OMPDependClause *OMPDependClause::Create(
        <br>
        -    const ASTContext &C, SourceLocation StartLoc,
        SourceLocation LParenLoc,
        <br>
        -    SourceLocation EndLoc, OpenMPDependClauseKind DepKind,
        <br>
        -    SourceLocation DepLoc, SourceLocation ColonLoc,
        ArrayRef<Expr *> VL) {
        <br>
        -  void *Mem = C.Allocate(totalSizeToAlloc<Expr
        *>(VL.size() + 1));
        <br>
        -  OMPDependClause *Clause =
        <br>
        -      new (Mem) OMPDependClause(StartLoc, LParenLoc, EndLoc,
        VL.size());
        <br>
        +OMPDependClause *
        <br>
        +OMPDependClause::Create(const ASTContext &C, SourceLocation
        StartLoc,
        <br>
        +                        SourceLocation LParenLoc,
        SourceLocation EndLoc,
        <br>
        +                        OpenMPDependClauseKind DepKind,
        SourceLocation DepLoc,
        <br>
        +                        SourceLocation ColonLoc,
        ArrayRef<Expr *> VL,
        <br>
        +                        unsigned NumLoops) {
        <br>
        +  void *Mem = C.Allocate(totalSizeToAlloc<Expr
        *>(VL.size() + NumLoops));
        <br>
        +  OMPDependClause *Clause = new (Mem)
        <br>
        +      OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size(),
        NumLoops);
        <br>
           Clause->setVarRefs(VL);
        <br>
           Clause->setDependencyKind(DepKind);
        <br>
           Clause->setDependencyLoc(DepLoc);
        <br>
           Clause->setColonLoc(ColonLoc);
        <br>
        -  Clause->setCounterValue(nullptr);
        <br>
        +  for (unsigned I = 0 ; I < NumLoops; ++I)
        <br>
        +    Clause->setLoopData(I, nullptr);
        <br>
           return Clause;
        <br>
         }
        <br>
        <br>
        -OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext
        &C,
        <br>
        unsigned N) {
        <br>
        -  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N +
        1));
        <br>
        -  return new (Mem) OMPDependClause(N);
        <br>
        -}
        <br>
        -
        <br>
        -void OMPDependClause::setCounterValue(Expr *V) {
        <br>
        -  assert(getDependencyKind() == OMPC_DEPEND_sink ||
        <br>
        -         getDependencyKind() == OMPC_DEPEND_source || V ==
        nullptr);
        <br>
        -  *getVarRefs().end() = V;
        <br>
        -}
        <br>
        -
        <br>
        -const Expr *OMPDependClause::getCounterValue() const {
        <br>
        -  auto *V = *getVarRefs().end();
        <br>
        -  assert(getDependencyKind() == OMPC_DEPEND_sink ||
        <br>
        -         getDependencyKind() == OMPC_DEPEND_source || V ==
        nullptr);
        <br>
        -  return V;
        <br>
        -}
        <br>
        -
        <br>
        -Expr *OMPDependClause::getCounterValue() {
        <br>
        -  auto *V = *getVarRefs().end();
        <br>
        -  assert(getDependencyKind() == OMPC_DEPEND_sink ||
        <br>
        -         getDependencyKind() == OMPC_DEPEND_source || V ==
        nullptr);
        <br>
        -  return V;
        <br>
        +OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext
        &C, unsigned N,
        <br>
        +                                              unsigned
        NumLoops) {
        <br>
        +  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N +
        NumLoops));
        <br>
        +  return new (Mem) OMPDependClause(N, NumLoops);
        <br>
        +}
        <br>
        +
        <br>
        +void OMPDependClause::setLoopData(unsigned NumLoop, Expr *Cnt)
        {
        <br>
        +  assert((getDependencyKind() == OMPC_DEPEND_sink ||
        <br>
        +          getDependencyKind() == OMPC_DEPEND_source) &&
        <br>
        +         NumLoop < NumLoops &&
        <br>
        +         "Expected sink or source depend + loop index must be
        less number of "
        <br>
        +         "loops.");
        <br>
        +  auto It = std::next(getVarRefs().end(), NumLoop);
        <br>
        +  *It = Cnt;
        <br>
        +}
        <br>
        +
        <br>
        +Expr *OMPDependClause::getLoopData(unsigned NumLoop) {
        <br>
        +  assert((getDependencyKind() == OMPC_DEPEND_sink ||
        <br>
        +          getDependencyKind() == OMPC_DEPEND_source) &&
        <br>
        +         NumLoop < NumLoops &&
        <br>
        +         "Expected sink or source depend + loop index must be
        less number of "
        <br>
        +         "loops.");
        <br>
        +  auto It = std::next(getVarRefs().end(), NumLoop);
        <br>
        +  return *It;
        <br>
        +}
        <br>
        +
        <br>
        +const Expr *OMPDependClause::getLoopData(unsigned NumLoop)
        const {
        <br>
        +  assert((getDependencyKind() == OMPC_DEPEND_sink ||
        <br>
        +          getDependencyKind() == OMPC_DEPEND_source) &&
        <br>
        +         NumLoop < NumLoops &&
        <br>
        +         "Expected sink or source depend + loop index must be
        less number of "
        <br>
        +         "loops.");
        <br>
        +  auto It = std::next(getVarRefs().end(), NumLoop);
        <br>
        +  return *It;
        <br>
         }
        <br>
        <br>
         unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber(
        <br>
        <br>
        Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
        <br>
        URL:
        <br>
<a class="moz-txt-link-freetext" href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=339603&r1=339602&r2=339603&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=339603&r1=339602&r2=339603&view=diff</a>
        <br>
==============================================================================
        <br>
        --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original)
        <br>
        +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Mon Aug 13
        12:04:24 2018
        <br>
        @@ -8811,7 +8811,8 @@ public:
        <br>
         } // namespace
        <br>
        <br>
         void CGOpenMPRuntime::emitDoacrossInit(CodeGenFunction
        &CGF,
        <br>
        -                                       const OMPLoopDirective
        &D) {
        <br>
        +                                       const OMPLoopDirective
        &D,
        <br>
        +                                       ArrayRef<Expr *>
        NumIterations) {
        <br>
           if (!CGF.HaveInsertPoint())
        <br>
             return;
        <br>
        <br>
        @@ -8834,32 +8835,45 @@ void CGOpenMPRuntime::emitDoacrossInit(C
        <br>
           } else {
        <br>
             RD = cast<RecordDecl>(KmpDimTy->getAsTagDecl());
        <br>
           }
        <br>
        +  llvm::APInt Size(/*numBits=*/32, NumIterations.size());
        <br>
        +  QualType ArrayTy =
        <br>
        +      C.getConstantArrayType(KmpDimTy, Size, ArrayType::Normal,
        0);
        <br>
        <br>
        -  Address DimsAddr = CGF.CreateMemTemp(KmpDimTy, "dims");
        <br>
        -  CGF.EmitNullInitialization(DimsAddr, KmpDimTy);
        <br>
        +  Address DimsAddr = CGF.CreateMemTemp(ArrayTy, "dims");
        <br>
        +  CGF.EmitNullInitialization(DimsAddr, ArrayTy);
        <br>
           enum { LowerFD = 0, UpperFD, StrideFD };
        <br>
           // Fill dims with data.
        <br>
        -  LValue DimsLVal = CGF.MakeAddrLValue(DimsAddr, KmpDimTy);
        <br>
        -  // dims.upper = num_iterations;
        <br>
        -  LValue UpperLVal =
        <br>
        -      CGF.EmitLValueForField(DimsLVal,
        *std::next(RD->field_begin(), UpperFD));
        <br>
        -  llvm::Value *NumIterVal = CGF.EmitScalarConversion(
        <br>
        -      CGF.EmitScalarExpr(D.getNumIterations()),
        <br>
        D.getNumIterations()->getType(),
        <br>
        -      Int64Ty, D.getNumIterations()->getExprLoc());
        <br>
        -  CGF.EmitStoreOfScalar(NumIterVal, UpperLVal);
        <br>
        -  // dims.stride = 1;
        <br>
        -  LValue StrideLVal =
        <br>
        -      CGF.EmitLValueForField(DimsLVal,
        *std::next(RD->field_begin(),
        <br>
        StrideFD));
        <br>
        - 
        CGF.EmitStoreOfScalar(llvm::ConstantInt::getSigned(CGM.Int64Ty,
        /*V=*/1),
        <br>
        -                        StrideLVal);
        <br>
        +  for (unsigned I = 0, E = NumIterations.size(); I < E; ++I)
        {
        <br>
        +    LValue DimsLVal =
        <br>
        +        CGF.MakeAddrLValue(CGF.Builder.CreateConstArrayGEP(
        <br>
        +                               DimsAddr, I,
        C.getTypeSizeInChars(KmpDimTy)),
        <br>
        +                           KmpDimTy);
        <br>
        +    // dims.upper = num_iterations;
        <br>
        +    LValue UpperLVal = CGF.EmitLValueForField(
        <br>
        +        DimsLVal, *std::next(RD->field_begin(), UpperFD));
        <br>
        +    llvm::Value *NumIterVal =
        <br>
        +       
        CGF.EmitScalarConversion(CGF.EmitScalarExpr(NumIterations[I]),
        <br>
        +                                
        D.getNumIterations()->getType(), Int64Ty,
        <br>
        +                                
        D.getNumIterations()->getExprLoc());
        <br>
        +    CGF.EmitStoreOfScalar(NumIterVal, UpperLVal);
        <br>
        +    // dims.stride = 1;
        <br>
        +    LValue StrideLVal = CGF.EmitLValueForField(
        <br>
        +        DimsLVal, *std::next(RD->field_begin(), StrideFD));
        <br>
        +   
        CGF.EmitStoreOfScalar(llvm::ConstantInt::getSigned(CGM.Int64Ty,
        /*V=*/1),
        <br>
        +                          StrideLVal);
        <br>
        +  }
        <br>
        <br>
           // Build call void __kmpc_doacross_init(ident_t *loc,
        kmp_int32 gtid,
        <br>
           // kmp_int32 num_dims, struct kmp_dim * dims);
        <br>
        -  llvm::Value *Args[] = {emitUpdateLocation(CGF,
        D.getBeginLoc()),
        <br>
        -                         getThreadID(CGF, D.getBeginLoc()),
        <br>
        -                        
        llvm::ConstantInt::getSigned(CGM.Int32Ty, 1),
        <br>
        -                        
        CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
        <br>
        -                             DimsAddr.getPointer(),
        CGM.VoidPtrTy)};
        <br>
        +  llvm::Value *Args[] = {
        <br>
        +      emitUpdateLocation(CGF, D.getBeginLoc()),
        <br>
        +      getThreadID(CGF, D.getBeginLoc()),
        <br>
        +      llvm::ConstantInt::getSigned(CGM.Int32Ty,
        NumIterations.size()),
        <br>
        +      CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
        <br>
        +          CGF.Builder
        <br>
        +              .CreateConstArrayGEP(DimsAddr, 0,
        C.getTypeSizeInChars(KmpDimTy))
        <br>
        +              .getPointer(),
        <br>
        +          CGM.VoidPtrTy)};
        <br>
        <br>
           llvm::Value *RTLFn =
        createRuntimeFunction(OMPRTL__kmpc_doacross_init);
        <br>
           CGF.EmitRuntimeCall(RTLFn, Args);
        <br>
        @@ -8874,16 +8888,29 @@ void CGOpenMPRuntime::emitDoacrossOrdere
        <br>
                                                   const OMPDependClause
        *C) {
        <br>
           QualType Int64Ty =
        <br>
               CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64,
        /*Signed=*/1);
        <br>
        -  const Expr *CounterVal = C->getCounterValue();
        <br>
        -  assert(CounterVal);
        <br>
        -  llvm::Value *CntVal =
        <br>
        CGF.EmitScalarConversion(CGF.EmitScalarExpr(CounterVal),
        <br>
        -
        <br>
        CounterVal->getType(), Int64Ty,
        <br>
        -                                                
        CounterVal->getExprLoc());
        <br>
        -  Address CntAddr = CGF.CreateMemTemp(Int64Ty, ".cnt.addr");
        <br>
        -  CGF.EmitStoreOfScalar(CntVal, CntAddr, /*Volatile=*/false,
        Int64Ty);
        <br>
        -  llvm::Value *Args[] = {emitUpdateLocation(CGF,
        C->getBeginLoc()),
        <br>
        -                         getThreadID(CGF, C->getBeginLoc()),
        <br>
        -                         CntAddr.getPointer()};
        <br>
        +  llvm::APInt Size(/*numBits=*/32, C->getNumLoops());
        <br>
        +  QualType ArrayTy = CGM.getContext().getConstantArrayType(
        <br>
        +      Int64Ty, Size, ArrayType::Normal, 0);
        <br>
        +  Address CntAddr = CGF.CreateMemTemp(ArrayTy, ".cnt.addr");
        <br>
        +  for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I)
        {
        <br>
        +    const Expr *CounterVal = C->getLoopData(I);
        <br>
        +    assert(CounterVal);
        <br>
        +    llvm::Value *CntVal = CGF.EmitScalarConversion(
        <br>
        +        CGF.EmitScalarExpr(CounterVal),
        CounterVal->getType(), Int64Ty,
        <br>
        +        CounterVal->getExprLoc());
        <br>
        +    CGF.EmitStoreOfScalar(
        <br>
        +        CntVal,
        <br>
        +        CGF.Builder.CreateConstArrayGEP(
        <br>
        +            CntAddr, I,
        CGM.getContext().getTypeSizeInChars(Int64Ty)),
        <br>
        +        /*Volatile=*/false, Int64Ty);
        <br>
        +  }
        <br>
        +  llvm::Value *Args[] = {
        <br>
        +      emitUpdateLocation(CGF, C->getBeginLoc()),
        <br>
        +      getThreadID(CGF, C->getBeginLoc()),
        <br>
        +      CGF.Builder
        <br>
        +          .CreateConstArrayGEP(CntAddr, 0,
        <br>
        +                              
        CGM.getContext().getTypeSizeInChars(Int64Ty))
        <br>
        +          .getPointer()};
        <br>
           llvm::Value *RTLFn;
        <br>
           if (C->getDependencyKind() == OMPC_DEPEND_source) {
        <br>
             RTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_post);
        <br>
        @@ -9198,7 +9225,8 @@ void CGOpenMPSIMDRuntime::emitTargetData
        <br>
         }
        <br>
        <br>
         void CGOpenMPSIMDRuntime::emitDoacrossInit(CodeGenFunction
        &CGF,
        <br>
        -                                           const
        OMPLoopDirective &D) {
        <br>
        +                                           const
        OMPLoopDirective &D,
        <br>
        +                                           ArrayRef<Expr
        *> NumIterations) {
        <br>
           llvm_unreachable("Not supported in SIMD-only mode");
        <br>
         }
        <br>
        <br>
        <br>
        Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h
        <br>
        URL:
        <br>
<a class="moz-txt-link-freetext" href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h?rev=339603&r1=339602&r2=339603&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h?rev=339603&r1=339602&r2=339603&view=diff</a>
        <br>
==============================================================================
        <br>
        --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h (original)
        <br>
        +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h Mon Aug 13 12:04:24
        2018
        <br>
        @@ -1469,8 +1469,8 @@ public:
        <br>
        <br>
           /// Emit initialization for doacross loop nesting support.
        <br>
           /// \param D Loop-based construct used in doacross nesting
        construct.
        <br>
        -  virtual void emitDoacrossInit(CodeGenFunction &CGF,
        <br>
        -                                const OMPLoopDirective &D);
        <br>
        +  virtual void emitDoacrossInit(CodeGenFunction &CGF, const
        <br>
        OMPLoopDirective &D,
        <br>
        +                                ArrayRef<Expr *>
        NumIterations);
        <br>
        <br>
           /// Emit code for doacross ordered directive with 'depend'
        clause.
        <br>
           /// \param C 'depend' clause with 'sink|source' dependency
        kind.
        <br>
        @@ -2057,8 +2057,8 @@ public:
        <br>
        <br>
           /// Emit initialization for doacross loop nesting support.
        <br>
           /// \param D Loop-based construct used in doacross nesting
        construct.
        <br>
        -  void emitDoacrossInit(CodeGenFunction &CGF,
        <br>
        -                        const OMPLoopDirective &D)
        override;
        <br>
        +  void emitDoacrossInit(CodeGenFunction &CGF, const
        OMPLoopDirective &D,
        <br>
        +                        ArrayRef<Expr *> NumIterations)
        override;
        <br>
        <br>
           /// Emit code for doacross ordered directive with 'depend'
        clause.
        <br>
           /// \param C 'depend' clause with 'sink|source' dependency
        kind.
        <br>
        <br>
        Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
        <br>
        URL:
        <br>
<a class="moz-txt-link-freetext" href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=339603&r1=339602&r2=339603&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=339603&r1=339602&r2=339603&view=diff</a>
        <br>
==============================================================================
        <br>
        --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
        <br>
        +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Mon Aug 13 12:04:24
        2018
        <br>
        @@ -1509,6 +1509,23 @@ void CodeGenFunction::EmitOMPPrivateLoop
        <br>
             }
        <br>
             ++I;
        <br>
           }
        <br>
        +  // Privatize extra loop counters used in loops for ordered(n)
        clauses.
        <br>
        +  for (const auto *C :
        S.getClausesOfKind<OMPOrderedClause>()) {
        <br>
        +    if (!C->getNumForLoops())
        <br>
        +      continue;
        <br>
        +    for (unsigned I = S.getCollapsedNumber(),
        <br>
        +                  E = C->getLoopNumIterations().size();
        <br>
        +         I < E; ++I) {
        <br>
        +      const auto *DRE =
        cast<DeclRefExpr>(C->getLoopCunter(I));
        <br>
        +      const auto *VD = cast<VarDecl>(DRE->getDecl());
        <br>
        +      // Override only those variables that are really emitted
        already.
        <br>
        +      if (LocalDeclMap.count(VD)) {
        <br>
        +        (void)LoopScope.addPrivate(VD, [this, DRE, VD]() {
        <br>
        +          return CreateMemTemp(DRE->getType(),
        VD->getName());
        <br>
        +        });
        <br>
        +      }
        <br>
        +    }
        <br>
        +  }
        <br>
         }
        <br>
        <br>
         static void emitPreCond(CodeGenFunction &CGF, const
        OMPLoopDirective &S,
        <br>
        @@ -2244,7 +2261,7 @@ bool CodeGenFunction::EmitOMPWorksharing
        <br>
             bool Ordered = false;
        <br>
             if (const auto *OrderedClause =
        S.getSingleClause<OMPOrderedClause>()) {
        <br>
               if (OrderedClause->getNumForLoops())
        <br>
        -        RT.emitDoacrossInit(*this, S);
        <br>
        +        RT.emitDoacrossInit(*this, S,
        OrderedClause->getLoopNumIterations());
        <br>
               else
        <br>
                 Ordered = true;
        <br>
             }
        <br>
        @@ -4942,6 +4959,20 @@ void CodeGenFunction::EmitSimpleOMPExecu
        <br>
                       CGF.EmitVarDecl(*VD);
        <br>
                   }
        <br>
                 }
        <br>
        +        for (const auto *C :
        D.getClausesOfKind<OMPOrderedClause>()) {
        <br>
        +          if (!C->getNumForLoops())
        <br>
        +            continue;
        <br>
        +          for (unsigned I = LD->getCollapsedNumber(),
        <br>
        +                        E =
        C->getLoopNumIterations().size();
        <br>
        +               I < E; ++I) {
        <br>
        +            if (const auto *VD =
        dyn_cast<OMPCapturedExprDecl>(
        <br>
        +                   
        cast<DeclRefExpr>(C->getLoopCunter(I))->getDecl()))
        {
        <br>
        +              // Emit only those that were not explicitly
        referenced
        <br>
        in clauses.
        <br>
        +              if (!CGF.LocalDeclMap.count(VD))
        <br>
        +                CGF.EmitVarDecl(*VD);
        <br>
        +            }
        <br>
        +          }
        <br>
        +        }
        <br>
               }
        <br>
              
        CGF.EmitStmt(D.getInnermostCapturedStmt()->getCapturedStmt());
        <br>
             }
        <br>
        <br>
        Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
        <br>
        URL:
        <br>
<a class="moz-txt-link-freetext" href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=339603&r1=339602&r2=339603&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=339603&r1=339602&r2=339603&view=diff</a>
        <br>
==============================================================================
        <br>
        --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
        <br>
        +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Mon Aug 13 12:04:24 2018
        <br>
        @@ -73,6 +73,8 @@ public:
        <br>
           };
        <br>
           using OperatorOffsetTy =
        <br>
               llvm::SmallVector<std::pair<Expr *,
        OverloadedOperatorKind>, 4>;
        <br>
        +  using DoacrossDependMapTy =
        <br>
        +      llvm::DenseMap<OMPDependClause *,
        OperatorOffsetTy>;
        <br>
        <br>
         private:
        <br>
           struct DSAInfo {
        <br>
        @@ -97,8 +99,6 @@ private:
        <br>
               llvm::DenseMap<const ValueDecl *,
        MappedExprComponentTy>;
        <br>
           using CriticalsWithHintsTy =
        <br>
               llvm::StringMap<std::pair<const
        OMPCriticalDirective *, llvm::APSInt>>;
        <br>
        -  using DoacrossDependMapTy =
        <br>
        -      llvm::DenseMap<OMPDependClause *,
        OperatorOffsetTy>;
        <br>
           struct ReductionData {
        <br>
             using BOKPtrType =
        llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
        <br>
             SourceRange ReductionRange;
        <br>
        @@ -137,7 +137,7 @@ private:
        <br>
             /// first argument (Expr *) contains optional argument of
        the
        <br>
             /// 'ordered' clause, the second one is true if the regions
        has 'ordered'
        <br>
             /// clause, false otherwise.
        <br>
        -    llvm::PointerIntPair<const Expr *, 1, bool>
        OrderedRegion;
        <br>
        +    llvm::Optional<std::pair<const Expr *,
        OMPOrderedClause *>> OrderedRegion;
        <br>
             bool NowaitRegion = false;
        <br>
             bool CancelRegion = false;
        <br>
             unsigned AssociatedLoops = 1;
        <br>
        @@ -398,23 +398,42 @@ public:
        <br>
           }
        <br>
        <br>
           /// Marks current region as ordered (it has an 'ordered'
        clause).
        <br>
        -  void setOrderedRegion(bool IsOrdered, const Expr *Param) {
        <br>
        +  void setOrderedRegion(bool IsOrdered, const Expr *Param,
        <br>
        +                        OMPOrderedClause *Clause) {
        <br>
             assert(!isStackEmpty());
        <br>
        -    Stack.back().first.back().OrderedRegion.setInt(IsOrdered);
        <br>
        -    Stack.back().first.back().OrderedRegion.setPointer(Param);
        <br>
        +    if (IsOrdered)
        <br>
        +      Stack.back().first.back().OrderedRegion.emplace(Param,
        Clause);
        <br>
        +    else
        <br>
        +      Stack.back().first.back().OrderedRegion.reset();
        <br>
        +  }
        <br>
        +  /// Returns true, if region is ordered (has associated
        'ordered' clause),
        <br>
        +  /// false - otherwise.
        <br>
        +  bool isOrderedRegion() const {
        <br>
        +    if (isStackEmpty())
        <br>
        +      return false;
        <br>
        +    return
        Stack.back().first.rbegin()->OrderedRegion.hasValue();
        <br>
        +  }
        <br>
        +  /// Returns optional parameter for the ordered region.
        <br>
        +  std::pair<const Expr *, OMPOrderedClause *>
        getOrderedRegionParam() const {
        <br>
        +    if (isStackEmpty() ||
        <br>
        +       
        !Stack.back().first.rbegin()->OrderedRegion.hasValue())
        <br>
        +      return std::make_pair(nullptr, nullptr);
        <br>
        +    return
        Stack.back().first.rbegin()->OrderedRegion.getValue();
        <br>
           }
        <br>
           /// Returns true, if parent region is ordered (has associated
        <br>
           /// 'ordered' clause), false - otherwise.
        <br>
           bool isParentOrderedRegion() const {
        <br>
             if (isStackEmpty() || Stack.back().first.size() == 1)
        <br>
               return false;
        <br>
        -    return
        std::next(Stack.back().first.rbegin())->OrderedRegion.getInt();
        <br>
        +    return
        std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue();
        <br>
           }
        <br>
           /// Returns optional parameter for the ordered region.
        <br>
        -  const Expr *getParentOrderedRegionParam() const {
        <br>
        -    if (isStackEmpty() || Stack.back().first.size() == 1)
        <br>
        -      return nullptr;
        <br>
        -    return
        std::next(Stack.back().first.rbegin())->OrderedRegion.getPointer();
        <br>
        +  std::pair<const Expr *, OMPOrderedClause *>
        <br>
        +  getParentOrderedRegionParam() const {
        <br>
        +    if (isStackEmpty() || Stack.back().first.size() == 1 ||
        <br>
        +       
        !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue())
        <br>
        +      return std::make_pair(nullptr, nullptr);
        <br>
        +    return
        std::next(Stack.back().first.rbegin())->OrderedRegion.getValue();
        <br>
           }
        <br>
           /// Marks current region as nowait (it has a 'nowait'
        clause).
        <br>
           void setNowaitRegion(bool IsNowait = true) {
        <br>
        @@ -3745,6 +3764,13 @@ public:
        <br>
           Expr *buildCounterInit() const;
        <br>
           /// Build step of the counter be used for codegen.
        <br>
           Expr *buildCounterStep() const;
        <br>
        +  /// Build loop data with counter value for depend clauses in
        ordered
        <br>
        +  /// directives.
        <br>
        +  Expr *
        <br>
        +  buildOrderedLoopData(Scope *S, Expr *Counter,
        <br>
        +                       llvm::MapVector<const Expr *,
        DeclRefExpr *> &Captures,
        <br>
        +                       SourceLocation Loc, Expr *Inc = nullptr,
        <br>
        +                       OverloadedOperatorKind OOK = OO_Amp);
        <br>
           /// Return true if any expression is dependent.
        <br>
           bool dependent() const;
        <br>
        <br>
        @@ -3909,7 +3935,12 @@ bool OpenMPIterationSpaceChecker::checkA
        <br>
                     SemaRef.Diag(S->getBeginLoc(),
        <br>
                                  diag::ext_omp_loop_not_canonical_init)
        <br>
                         << S->getSourceRange();
        <br>
        -          return setLCDeclAndLB(Var, nullptr,
        Var->getInit());
        <br>
        +          return setLCDeclAndLB(
        <br>
        +              Var,
        <br>
        +              buildDeclRefExpr(SemaRef, Var,
        <br>
        +                              
        Var->getType().getNonReferenceType(),
        <br>
        +                               DS->getBeginLoc()),
        <br>
        +              Var->getInit());
        <br>
                 }
        <br>
               }
        <br>
             }
        <br>
        @@ -4271,7 +4302,8 @@ Expr *OpenMPIterationSpaceChecker::build
        <br>
        <br>
         /// Build reference expression to the counter be used for
        codegen.
        <br>
         DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
        <br>
        -    llvm::MapVector<const Expr *, DeclRefExpr *>
        &Captures,
        <br>
        DSAStackTy &DSA) const {
        <br>
        +    llvm::MapVector<const Expr *, DeclRefExpr *>
        &Captures,
        <br>
        +    DSAStackTy &DSA) const {
        <br>
           auto *VD = dyn_cast<VarDecl>(LCDecl);
        <br>
           if (!VD) {
        <br>
             VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
        <br>
        @@ -4311,6 +4343,63 @@ Expr *OpenMPIterationSpaceChecker::build
        <br>
         /// Build step of the counter be used for codegen.
        <br>
         Expr *OpenMPIterationSpaceChecker::buildCounterStep() const {
        return Step; }
        <br>
        <br>
        +Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
        <br>
        +    Scope *S, Expr *Counter,
        <br>
        +    llvm::MapVector<const Expr *, DeclRefExpr *>
        &Captures, SourceLocation Loc,
        <br>
        +    Expr *Inc, OverloadedOperatorKind OOK) {
        <br>
        +  Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
        <br>
        +  if (!Cnt)
        <br>
        +    return nullptr;
        <br>
        +  if (Inc) {
        <br>
        +    assert((OOK == OO_Plus || OOK == OO_Minus) &&
        <br>
        +           "Expected only + or - operations for depend
        clauses.");
        <br>
        +    BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add :
        BO_Sub;
        <br>
        +    Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
        <br>
        +    if (!Cnt)
        <br>
        +      return nullptr;
        <br>
        +  }
        <br>
        +  ExprResult Diff;
        <br>
        +  QualType VarType =
        LCDecl->getType().getNonReferenceType();
        <br>
        +  if (VarType->isIntegerType() ||
        VarType->isPointerType() ||
        <br>
        +      SemaRef.getLangOpts().CPlusPlus) {
        <br>
        +    // Upper - Lower
        <br>
        +    Expr *Upper =
        <br>
        +        TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, UB,
        Captures).get();
        <br>
        +    Expr *Lower =
        <br>
        +        TestIsLessOp ? tryBuildCapture(SemaRef, LB,
        Captures).get() : Cnt;
        <br>
        +    if (!Upper || !Lower)
        <br>
        +      return nullptr;
        <br>
        +
        <br>
        +    Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper,
        Lower);
        <br>
        +
        <br>
        +    if (!Diff.isUsable() &&
        VarType->getAsCXXRecordDecl()) {
        <br>
        +      // BuildBinOp already emitted error, this one is to point
        user to upper
        <br>
        +      // and lower bound, and to tell what is passed to
        'operator-'.
        <br>
        +      SemaRef.Diag(Upper->getBeginLoc(),
        diag::err_omp_loop_diff_cxx)
        <br>
        +          << Upper->getSourceRange() <<
        Lower->getSourceRange();
        <br>
        +      return nullptr;
        <br>
        +    }
        <br>
        +  }
        <br>
        +
        <br>
        +  if (!Diff.isUsable())
        <br>
        +    return nullptr;
        <br>
        +
        <br>
        +  // Parentheses (for dumping/debugging purposes only).
        <br>
        +  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc,
        Diff.get());
        <br>
        +  if (!Diff.isUsable())
        <br>
        +    return nullptr;
        <br>
        +
        <br>
        +  ExprResult NewStep = tryBuildCapture(SemaRef, Step,
        Captures);
        <br>
        +  if (!NewStep.isUsable())
        <br>
        +    return nullptr;
        <br>
        +  // (Upper - Lower) / Step
        <br>
        +  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(),
        NewStep.get());
        <br>
        +  if (!Diff.isUsable())
        <br>
        +    return nullptr;
        <br>
        +
        <br>
        +  return Diff.get();
        <br>
        +}
        <br>
        +
        <br>
         /// Iteration space of a single for loop.
        <br>
         struct LoopIterationSpace final {
        <br>
           /// Condition of the loop.
        <br>
        @@ -4370,7 +4459,8 @@ void Sema::ActOnOpenMPLoopInitialization
        <br>
         static bool checkOpenMPIterationSpace(
        <br>
             OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef,
        DSAStackTy &DSA,
        <br>
             unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
        <br>
        -    Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr,
        <br>
        +    unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
        <br>
        +    Expr *OrderedLoopCountExpr,
        <br>
             Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
        <br>
             LoopIterationSpace &ResultIterSpace,
        <br>
             llvm::MapVector<const Expr *, DeclRefExpr *>
        &Captures) {
        <br>
        @@ -4380,9 +4470,9 @@ static bool checkOpenMPIterationSpace(
        <br>
           if (!For) {
        <br>
             SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
        <br>
                 << (CollapseLoopCountExpr != nullptr ||
        OrderedLoopCountExpr
        <br>
        != nullptr)
        <br>
        -        << getOpenMPDirectiveName(DKind) <<
        NestedLoopCount
        <br>
        +        << getOpenMPDirectiveName(DKind) <<
        TotalNestedLoopCount
        <br>
                 << (CurrentNestedLoopCount > 0) <<
        CurrentNestedLoopCount;
        <br>
        -    if (NestedLoopCount > 1) {
        <br>
        +    if (TotalNestedLoopCount > 1) {
        <br>
               if (CollapseLoopCountExpr &&
        OrderedLoopCountExpr)
        <br>
                 SemaRef.Diag(DSA.getConstructLoc(),
        <br>
                              diag::note_omp_collapse_ordered_expr)
        <br>
        @@ -4515,6 +4605,41 @@ static bool checkOpenMPIterationSpace(
        <br>
                         ResultIterSpace.PrivateCounterVar == nullptr ||
        <br>
                         ResultIterSpace.CounterInit == nullptr ||
        <br>
                         ResultIterSpace.CounterStep == nullptr);
        <br>
        +  if (!HasErrors && DSA.isOrderedRegion()) {
        <br>
        +    if
        (DSA.getOrderedRegionParam().second->getNumForLoops()) {
        <br>
        +      if (CurrentNestedLoopCount <
        <br>
        +         
        DSA.getOrderedRegionParam().second->getLoopNumIterations().size())
        {
        <br>
        +       
        DSA.getOrderedRegionParam().second->setLoopNumIterations(
        <br>
        +            CurrentNestedLoopCount,
        ResultIterSpace.NumIterations);
        <br>
        +        DSA.getOrderedRegionParam().second->setLoopCounter(
        <br>
        +            CurrentNestedLoopCount,
        ResultIterSpace.CounterVar);
        <br>
        +      }
        <br>
        +    }
        <br>
        +    for (auto &Pair : DSA.getDoacrossDependClauses()) {
        <br>
        +      if (CurrentNestedLoopCount >=
        Pair.first->getNumLoops()) {
        <br>
        +        // Erroneous case - clause has some problems.
        <br>
        +        continue;
        <br>
        +      }
        <br>
        +      if (Pair.first->getDependencyKind() ==
        OMPC_DEPEND_sink &&
        <br>
        +          Pair.second.size() <= CurrentNestedLoopCount) {
        <br>
        +        // Erroneous case - clause has some problems.
        <br>
        +        Pair.first->setLoopData(CurrentNestedLoopCount,
        nullptr);
        <br>
        +        continue;
        <br>
        +      }
        <br>
        +      Expr *CntValue;
        <br>
        +      if (Pair.first->getDependencyKind() ==
        OMPC_DEPEND_source)
        <br>
        +        CntValue = ISC.buildOrderedLoopData(
        <br>
        +            DSA.getCurScope(), ResultIterSpace.CounterVar,
        Captures,
        <br>
        +            Pair.first->getDependencyLoc());
        <br>
        +      else
        <br>
        +        CntValue = ISC.buildOrderedLoopData(
        <br>
        +            DSA.getCurScope(), ResultIterSpace.CounterVar,
        Captures,
        <br>
        +            Pair.first->getDependencyLoc(),
        <br>
        +            Pair.second[CurrentNestedLoopCount].first,
        <br>
        +            Pair.second[CurrentNestedLoopCount].second);
        <br>
        +      Pair.first->setLoopData(CurrentNestedLoopCount,
        CntValue);
        <br>
        +    }
        <br>
        +  }
        <br>
        <br>
           return HasErrors;
        <br>
         }
        <br>
        @@ -4700,6 +4825,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin
        <br>
             if (CollapseLoopCountExpr->EvaluateAsInt(Result,
        SemaRef.getASTContext()))
        <br>
               NestedLoopCount = Result.getLimitedValue();
        <br>
           }
        <br>
        +  unsigned OrderedLoopCount = 1;
        <br>
           if (OrderedLoopCountExpr) {
        <br>
             // Found 'ordered' clause - calculate collapse number.
        <br>
             llvm::APSInt Result;
        <br>
        @@ -4712,21 +4838,43 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin
        <br>
                              diag::note_collapse_loop_count)
        <br>
                     <<
        CollapseLoopCountExpr->getSourceRange();
        <br>
               }
        <br>
        -      NestedLoopCount = Result.getLimitedValue();
        <br>
        +      OrderedLoopCount = Result.getLimitedValue();
        <br>
             }
        <br>
           }
        <br>
           // This is helper routine for loop directives (e.g., 'for',
        'simd',
        <br>
           // 'for simd', etc.).
        <br>
           llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
        <br>
           SmallVector<LoopIterationSpace, 4> IterSpaces;
        <br>
        -  IterSpaces.resize(NestedLoopCount);
        <br>
        +  IterSpaces.resize(std::max(OrderedLoopCount,
        NestedLoopCount));
        <br>
           Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured
        */ true);
        <br>
           for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
        <br>
        -    if (checkOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA,
        Cnt,
        <br>
        -                                  NestedLoopCount,
        CollapseLoopCountExpr,
        <br>
        -                                  OrderedLoopCountExpr,
        VarsWithImplicitDSA,
        <br>
        -                                  IterSpaces[Cnt], Captures))
        <br>
        +    if (checkOpenMPIterationSpace(
        <br>
        +            DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
        <br>
        +            std::max(OrderedLoopCount, NestedLoopCount),
        CollapseLoopCountExpr,
        <br>
        +            OrderedLoopCountExpr, VarsWithImplicitDSA,
        IterSpaces[Cnt],
        <br>
        +            Captures))
        <br>
        +      return 0;
        <br>
        +    // Move on to the next nested for loop, or to the loop
        body.
        <br>
        +    // OpenMP [2.8.1, simd construct, Restrictions]
        <br>
        +    // All loops associated with the construct must be
        perfectly nested; that
        <br>
        +    // is, there must be no intervening code nor any OpenMP
        directive between
        <br>
        +    // any two loops.
        <br>
        +    CurStmt =
        cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
        <br>
        +  }
        <br>
        +  for (unsigned Cnt = NestedLoopCount; Cnt <
        OrderedLoopCount; ++Cnt) {
        <br>
        +    if (checkOpenMPIterationSpace(
        <br>
        +            DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
        <br>
        +            std::max(OrderedLoopCount, NestedLoopCount),
        CollapseLoopCountExpr,
        <br>
        +            OrderedLoopCountExpr, VarsWithImplicitDSA,
        IterSpaces[Cnt],
        <br>
        +            Captures))
        <br>
               return 0;
        <br>
        +    if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
        <br>
        +      // Handle initialization of captured loop iterator
        variables.
        <br>
        +      auto *DRE =
        cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
        <br>
        +      if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
        <br>
        +        Captures[DRE] = DRE;
        <br>
        +      }
        <br>
        +    }
        <br>
             // Move on to the next nested for loop, or to the loop
        body.
        <br>
             // OpenMP [2.8.1, simd construct, Restrictions]
        <br>
             // All loops associated with the construct must be
        perfectly nested; that
        <br>
        @@ -5113,7 +5261,6 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin
        <br>
           Built.Inits.resize(NestedLoopCount);
        <br>
           Built.Updates.resize(NestedLoopCount);
        <br>
           Built.Finals.resize(NestedLoopCount);
        <br>
        -  SmallVector<Expr *, 4> LoopMultipliers;
        <br>
           {
        <br>
             ExprResult Div;
        <br>
             // Go from inner nested loop to outer.
        <br>
        @@ -5183,7 +5330,6 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin
        <br>
                   HasErrors = true;
        <br>
                   break;
        <br>
                 }
        <br>
        -        LoopMultipliers.push_back(Div.get());
        <br>
               }
        <br>
               if (!Update.isUsable() || !Final.isUsable()) {
        <br>
                 HasErrors = true;
        <br>
        @@ -5231,55 +5377,6 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin
        <br>
           Built.DistCombinedFields.NLB = CombNextLB.get();
        <br>
           Built.DistCombinedFields.NUB = CombNextUB.get();
        <br>
        <br>
        -  Expr *CounterVal =
        SemaRef.DefaultLvalueConversion(IV.get()).get();
        <br>
        -  // Fill data for doacross depend clauses.
        <br>
        -  for (const auto &Pair : DSA.getDoacrossDependClauses()) {
        <br>
        -    if (Pair.first->getDependencyKind() ==
        OMPC_DEPEND_source) {
        <br>
        -      Pair.first->setCounterValue(CounterVal);
        <br>
        -    } else {
        <br>
        -      if (NestedLoopCount != Pair.second.size() ||
        <br>
        -          NestedLoopCount != LoopMultipliers.size() + 1) {
        <br>
        -        // Erroneous case - clause has some problems.
        <br>
        -        Pair.first->setCounterValue(CounterVal);
        <br>
        -        continue;
        <br>
        -      }
        <br>
        -      assert(Pair.first->getDependencyKind() ==
        OMPC_DEPEND_sink);
        <br>
        -      auto I = Pair.second.rbegin();
        <br>
        -      auto IS = IterSpaces.rbegin();
        <br>
        -      auto ILM = LoopMultipliers.rbegin();
        <br>
        -      Expr *UpCounterVal = CounterVal;
        <br>
        -      Expr *Multiplier = nullptr;
        <br>
        -      for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
        <br>
        -        if (I->first) {
        <br>
        -          assert(IS->CounterStep);
        <br>
        -          Expr *NormalizedOffset =
        <br>
        -              SemaRef
        <br>
        -                  .BuildBinOp(CurScope,
        I->first->getExprLoc(), BO_Div,
        <br>
        -                              I->first, IS->CounterStep)
        <br>
        -                  .get();
        <br>
        -          if (Multiplier) {
        <br>
        -            NormalizedOffset =
        <br>
        -                SemaRef
        <br>
        -                    .BuildBinOp(CurScope,
        I->first->getExprLoc(), BO_Mul,
        <br>
        -                                NormalizedOffset, Multiplier)
        <br>
        -                    .get();
        <br>
        -          }
        <br>
        -          assert(I->second == OO_Plus || I->second ==
        OO_Minus);
        <br>
        -          BinaryOperatorKind BOK = (I->second == OO_Plus) ?
        BO_Add : BO_Sub;
        <br>
        -          UpCounterVal = SemaRef
        <br>
        -                             .BuildBinOp(CurScope,
        I->first->getExprLoc(), BOK,
        <br>
        -                                         UpCounterVal,
        NormalizedOffset)
        <br>
        -                             .get();
        <br>
        -        }
        <br>
        -        Multiplier = *ILM;
        <br>
        -        ++I;
        <br>
        -        ++IS;
        <br>
        -        ++ILM;
        <br>
        -      }
        <br>
        -      Pair.first->setCounterValue(UpCounterVal);
        <br>
        -    }
        <br>
        -  }
        <br>
        -
        <br>
           return NestedLoopCount;
        <br>
         }
        <br>
        <br>
        @@ -5847,12 +5944,12 @@ StmtResult Sema::ActOnOpenMPOrderedDirec
        <br>
             Diag(DependFound->getBeginLoc(),
        diag::err_omp_depend_clause_thread_simd)
        <br>
                 << getOpenMPClauseName(TC ?
        TC->getClauseKind() : SC->getClauseKind());
        <br>
             ErrorFound = true;
        <br>
        -  } else if (DependFound &&
        !DSAStack->getParentOrderedRegionParam()) {
        <br>
        +  } else if (DependFound &&
        !DSAStack->getParentOrderedRegionParam().first) {
        <br>
             Diag(DependFound->getBeginLoc(),
        <br>
                  diag::err_omp_ordered_directive_without_param);
        <br>
             ErrorFound = true;
        <br>
           } else if (TC || Clauses.empty()) {
        <br>
        -    if (const Expr *Param =
        DSAStack->getParentOrderedRegionParam()) {
        <br>
        +    if (const Expr *Param =
        DSAStack->getParentOrderedRegionParam().first) {
        <br>
               SourceLocation ErrLoc = TC ? TC->getBeginLoc() :
        StartLoc;
        <br>
               Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
        <br>
                   << (TC != nullptr);
        <br>
        @@ -8628,9 +8725,11 @@ OMPClause *Sema::ActOnOpenMPOrderedClaus
        <br>
           } else {
        <br>
             NumForLoops = nullptr;
        <br>
           }
        <br>
        -  DSAStack->setOrderedRegion(/*IsOrdered=*/true,
        NumForLoops);
        <br>
        -  return new (Context)
        <br>
        -      OMPOrderedClause(NumForLoops, StartLoc, LParenLoc,
        EndLoc);
        <br>
        +  auto *Clause = OMPOrderedClause::Create(
        <br>
        +      Context, NumForLoops, NumForLoops ?
        DSAStack->getAssociatedLoops() : 0,
        <br>
        +      StartLoc, LParenLoc, EndLoc);
        <br>
        +  DSAStack->setOrderedRegion(/*IsOrdered=*/true,
        NumForLoops, Clause);
        <br>
        +  return Clause;
        <br>
         }
        <br>
        <br>
         OMPClause *Sema::ActOnOpenMPSimpleClause(
        <br>
        @@ -11486,8 +11585,9 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe
        <br>
           DSAStackTy::OperatorOffsetTy OpsOffs;
        <br>
           llvm::APSInt DepCounter(/*BitWidth=*/32);
        <br>
           llvm::APSInt TotalDepCount(/*BitWidth=*/32);
        <br>
        -  if (DepKind == OMPC_DEPEND_sink) {
        <br>
        -    if (const Expr *OrderedCountExpr =
        <br>
        DSAStack->getParentOrderedRegionParam()) {
        <br>
        +  if (DepKind == OMPC_DEPEND_sink || DepKind ==
        OMPC_DEPEND_source) {
        <br>
        +    if (const Expr *OrderedCountExpr =
        <br>
        +            DSAStack->getParentOrderedRegionParam().first) {
        <br>
               TotalDepCount =
        OrderedCountExpr->EvaluateKnownConstInt(Context);
        <br>
               TotalDepCount.setIsUnsigned(/*Val=*/true);
        <br>
             }
        <br>
        @@ -11503,7 +11603,7 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe
        <br>
             SourceLocation ELoc = RefExpr->getExprLoc();
        <br>
             Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
        <br>
             if (DepKind == OMPC_DEPEND_sink) {
        <br>
        -      if (DSAStack->getParentOrderedRegionParam() &&
        <br>
        +      if (DSAStack->getParentOrderedRegionParam().first
        &&
        <br>
                   DepCounter >= TotalDepCount) {
        <br>
                 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
        <br>
                 continue;
        <br>
        @@ -11569,7 +11669,7 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe
        <br>
                   continue;
        <br>
               }
        <br>
               if (!CurContext->isDependentContext() &&
        <br>
        -          DSAStack->getParentOrderedRegionParam() &&
        <br>
        +          DSAStack->getParentOrderedRegionParam().first
        &&
        <br>
                   DepCounter !=
        DSAStack->isParentLoopControlVariable(D).first) {
        <br>
                 const ValueDecl *VD =
        <br>
                    
        DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
        <br>
        @@ -11607,7 +11707,7 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe
        <br>
        <br>
           if (!CurContext->isDependentContext() && DepKind
        == OMPC_DEPEND_sink &&
        <br>
               TotalDepCount > VarList.size() &&
        <br>
        -      DSAStack->getParentOrderedRegionParam() &&
        <br>
        +      DSAStack->getParentOrderedRegionParam().first
        &&
        <br>
               DSAStack->getParentLoopControlVariable(VarList.size()
        + 1)) {
        <br>
             Diag(EndLoc,
        diag::err_omp_depend_sink_expected_loop_iteration)
        <br>
                 << 1 <<
        DSAStack->getParentLoopControlVariable(VarList.size() + 1);
        <br>
        @@ -11617,7 +11717,8 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe
        <br>
             return nullptr;
        <br>
        <br>
           auto *C = OMPDependClause::Create(Context, StartLoc,
        LParenLoc, EndLoc,
        <br>
        -                                    DepKind, DepLoc, ColonLoc,
        Vars);
        <br>
        +                                    DepKind, DepLoc, ColonLoc,
        Vars,
        <br>
        +                                   
        TotalDepCount.getZExtValue());
        <br>
           if ((DepKind == OMPC_DEPEND_sink || DepKind ==
        OMPC_DEPEND_source) &&
        <br>
               DSAStack->isParentOrderedRegion())
        <br>
             DSAStack->addDoacrossDependClause(C, OpsOffs);
        <br>
        <br>
        Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
        <br>
        URL:
        <br>
<a class="moz-txt-link-freetext" href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=339603&r1=339602&r2=339603&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=339603&r1=339602&r2=339603&view=diff</a>
        <br>
==============================================================================
        <br>
        --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
        <br>
        +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Mon Aug 13
        12:04:24 2018
        <br>
        @@ -1856,7 +1856,7 @@ OMPClause *OMPClauseReader::readClause()
        <br>
             C = new (Context) OMPScheduleClause();
        <br>
             break;
        <br>
           case OMPC_ordered:
        <br>
        -    C = new (Context) OMPOrderedClause();
        <br>
        +    C = OMPOrderedClause::CreateEmpty(Context,
        Reader->Record.readInt());
        <br>
             break;
        <br>
           case OMPC_nowait:
        <br>
             C = new (Context) OMPNowaitClause();
        <br>
        @@ -1927,9 +1927,12 @@ OMPClause *OMPClauseReader::readClause()
        <br>
           case OMPC_flush:
        <br>
             C = OMPFlushClause::CreateEmpty(Context,
        Reader->Record.readInt());
        <br>
             break;
        <br>
        -  case OMPC_depend:
        <br>
        -    C = OMPDependClause::CreateEmpty(Context,
        Reader->Record.readInt());
        <br>
        +  case OMPC_depend: {
        <br>
        +    unsigned NumVars = Reader->Record.readInt();
        <br>
        +    unsigned NumLoops = Reader->Record.readInt();
        <br>
        +    C = OMPDependClause::CreateEmpty(Context, NumVars,
        NumLoops);
        <br>
             break;
        <br>
        +  }
        <br>
           case OMPC_device:
        <br>
             C = new (Context) OMPDeviceClause();
        <br>
             break;
        <br>
        @@ -2087,6 +2090,10 @@ void OMPClauseReader::VisitOMPScheduleCl
        <br>
        <br>
         void OMPClauseReader::VisitOMPOrderedClause(OMPOrderedClause
        *C) {
        <br>
           C->setNumForLoops(Reader->Record.readSubExpr());
        <br>
        +  for (unsigned I = 0, E = C->NumberOfLoops; I < E; ++I)
        <br>
        +    C->setLoopNumIterations(I,
        Reader->Record.readSubExpr());
        <br>
        +  for (unsigned I = 0, E = C->NumberOfLoops; I < E; ++I)
        <br>
        +    C->setLoopCounter(I, Reader->Record.readSubExpr());
        <br>
           C->setLParenLoc(Reader->ReadSourceLocation());
        <br>
         }
        <br>
        <br>
        @@ -2395,10 +2402,11 @@ void OMPClauseReader::VisitOMPDependClau
        <br>
           unsigned NumVars = C->varlist_size();
        <br>
           SmallVector<Expr *, 16> Vars;
        <br>
           Vars.reserve(NumVars);
        <br>
        -  for (unsigned i = 0; i != NumVars; ++i)
        <br>
        +  for (unsigned I = 0; I != NumVars; ++I)
        <br>
             Vars.push_back(Reader->Record.readSubExpr());
        <br>
           C->setVarRefs(Vars);
        <br>
        -  C->setCounterValue(Reader->Record.readSubExpr());
        <br>
        +  for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I)
        <br>
        +    C->setLoopData(I, Reader->Record.readSubExpr());
        <br>
         }
        <br>
        <br>
         void OMPClauseReader::VisitOMPDeviceClause(OMPDeviceClause *C)
        {
        <br>
        <br>
        Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
        <br>
        URL:
        <br>
<a class="moz-txt-link-freetext" href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=339603&r1=339602&r2=339603&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=339603&r1=339602&r2=339603&view=diff</a>
        <br>
==============================================================================
        <br>
        --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
        <br>
        +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Mon Aug 13
        12:04:24 2018
        <br>
        @@ -1898,7 +1898,12 @@ void OMPClauseWriter::VisitOMPScheduleCl
        <br>
         }
        <br>
        <br>
         void OMPClauseWriter::VisitOMPOrderedClause(OMPOrderedClause
        *C) {
        <br>
        +  Record.push_back(C->getLoopNumIterations().size());
        <br>
           Record.AddStmt(C->getNumForLoops());
        <br>
        +  for (Expr *NumIter : C->getLoopNumIterations())
        <br>
        +    Record.AddStmt(NumIter);
        <br>
        +  for (unsigned I = 0, E = C->getLoopNumIterations().size();
        I <E; ++I)
        <br>
        +    Record.AddStmt(C->getLoopCunter(I));
        <br>
           Record.AddSourceLocation(C->getLParenLoc());
        <br>
         }
        <br>
        <br>
        @@ -2102,13 +2107,15 @@ void OMPClauseWriter::VisitOMPFlushClaus
        <br>
        <br>
         void OMPClauseWriter::VisitOMPDependClause(OMPDependClause *C)
        {
        <br>
           Record.push_back(C->varlist_size());
        <br>
        +  Record.push_back(C->getNumLoops());
        <br>
           Record.AddSourceLocation(C->getLParenLoc());
        <br>
           Record.push_back(C->getDependencyKind());
        <br>
           Record.AddSourceLocation(C->getDependencyLoc());
        <br>
           Record.AddSourceLocation(C->getColonLoc());
        <br>
           for (auto *VE : C->varlists())
        <br>
             Record.AddStmt(VE);
        <br>
        -  Record.AddStmt(C->getCounterValue());
        <br>
        +  for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I)
        <br>
        +    Record.AddStmt(C->getLoopData(I));
        <br>
         }
        <br>
        <br>
         void OMPClauseWriter::VisitOMPDeviceClause(OMPDeviceClause *C)
        {
        <br>
        <br>
      </blockquote>
      <br>
      <blockquote type="cite">Modified:
        cfe/trunk/test/OpenMP/ordered_doacross_codegen.c
        <br>
        URL:
        <br>
<a class="moz-txt-link-freetext" href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/ordered_doacross_codegen.c?rev=339603&r1=339602&r2=339603&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/ordered_doacross_codegen.c?rev=339603&r1=339602&r2=339603&view=diff</a>
        <br>
==============================================================================
        <br>
        --- cfe/trunk/test/OpenMP/ordered_doacross_codegen.c (original)
        <br>
        +++ cfe/trunk/test/OpenMP/ordered_doacross_codegen.c Mon Aug 13
        12:04:24 2018
        <br>
        @@ -19,17 +19,19 @@ void foo();
        <br>
         // CHECK-LABEL: @main()
        <br>
         int main() {
        <br>
           int i;
        <br>
        -// CHECK: [[DIMS:%.+]] = alloca [[KMP_DIM]],
        <br>
        +// CHECK: [[DIMS:%.+]] = alloca [1 x [[KMP_DIM]]],
        <br>
         // CHECK: [[GTID:%.+]] = call i32
        @__kmpc_global_thread_num([[IDENT:%.+]])
        <br>
         // CHECK: icmp
        <br>
         // CHECK-NEXT: br i1 %
        <br>
        -// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
        <br>
        +// CHECK: [[CAST:%.+]] = bitcast [1 x [[KMP_DIM]]]* [[DIMS]] to
        i8*
        <br>
         // CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 [[CAST]],
        i8 0,
        <br>
        i64 24, i1 false)
        <br>
        -// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]*
        [[DIMS]],
        <br>
        i32 0, i32 1
        <br>
        +// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x
        [[KMP_DIM]]], [1
        <br>
        x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0
        <br>
        +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]*
        [[DIM]],
        <br>
        i32 0, i32 1
        <br>
         // CHECK: store i64 %{{.+}}, i64* %
        <br>
        -// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]*
        [[DIMS]],
        <br>
        i32 0, i32 2
        <br>
        +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]*
        [[DIM]],
        <br>
        i32 0, i32 2
        <br>
         // CHECK: store i64 1, i64* %
        <br>
        -// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
        <br>
        +// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x
        [[KMP_DIM]]], [1
        <br>
        x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0
        <br>
        +// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIM]] to i8*
        <br>
         // CHECK: call void @__kmpc_doacross_init([[IDENT]], i32
        [[GTID]],
        <br>
        i32 1, i8* [[CAST]])
        <br>
         // CHECK: call void @__kmpc_for_static_init_4(
        <br>
         #pragma omp for ordered(1)
        <br>
        @@ -37,18 +39,26 @@ int main() {
        <br>
             a[i] = b[i] + 1;
        <br>
             foo();
        <br>
         // CHECK: call void [[FOO:.+]](
        <br>
        -// CHECK: load i32, i32* [[CNT:%.+]],
        <br>
        +// CHECK: load i32, i32* [[I:%.+]],
        <br>
        +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
        <br>
        +// CHECK-NEXT: sdiv i32 %{{.+}}, 1
        <br>
         // CHECK-NEXT: sext i32 %{{.+}} to i64
        <br>
        -// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64],
        [1 x
        <br>
        i64]* [[CNT:%.+]], i64 0, i64 0
        <br>
        +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]],
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64],
        [1 x
        <br>
        i64]* [[CNT]], i64 0, i64 0
        <br>
         // CHECK-NEXT: call void @__kmpc_doacross_post([[IDENT]], i32
        <br>
        [[GTID]], i64* [[TMP]])
        <br>
         #pragma omp ordered depend(source)
        <br>
             c[i] = c[i] + 1;
        <br>
             foo();
        <br>
         // CHECK: call void [[FOO]]
        <br>
        -// CHECK: load i32, i32* [[CNT]],
        <br>
        +// CHECK: load i32, i32* [[I]],
        <br>
         // CHECK-NEXT: sub nsw i32 %{{.+}}, 2
        <br>
        +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
        <br>
        +// CHECK-NEXT: sdiv i32 %{{.+}}, 1
        <br>
         // CHECK-NEXT: sext i32 %{{.+}} to i64
        <br>
        -// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64],
        [1 x
        <br>
        i64]* [[CNT:%.+]], i64 0, i64 0
        <br>
        +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]],
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64],
        [1 x
        <br>
        i64]* [[CNT]], i64 0, i64 0
        <br>
         // CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32
        <br>
        [[GTID]], i64* [[TMP]])
        <br>
         #pragma omp ordered depend(sink : i - 2)
        <br>
             d[i] = a[i - 2];
        <br>
        <br>
        Modified: cfe/trunk/test/OpenMP/ordered_doacross_codegen.cpp
        <br>
        URL:
        <br>
<a class="moz-txt-link-freetext" href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/ordered_doacross_codegen.cpp?rev=339603&r1=339602&r2=339603&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/ordered_doacross_codegen.cpp?rev=339603&r1=339602&r2=339603&view=diff</a>
        <br>
==============================================================================
        <br>
        --- cfe/trunk/test/OpenMP/ordered_doacross_codegen.cpp
        (original)
        <br>
        +++ cfe/trunk/test/OpenMP/ordered_doacross_codegen.cpp Mon Aug
        13 12:04:24 2018
        <br>
        @@ -19,17 +19,19 @@ void foo();
        <br>
         // CHECK-LABEL: @main()
        <br>
         int main() {
        <br>
           int i;
        <br>
        -// CHECK: [[DIMS:%.+]] = alloca [[KMP_DIM]],
        <br>
        +// CHECK: [[DIMS:%.+]] = alloca [1 x [[KMP_DIM]]],
        <br>
         // CHECK: [[GTID:%.+]] = call i32
        @__kmpc_global_thread_num([[IDENT:%.+]])
        <br>
         // CHECK: icmp
        <br>
         // CHECK-NEXT: br i1 %
        <br>
        -// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
        <br>
        +// CHECK: [[CAST:%.+]] = bitcast [1 x [[KMP_DIM]]]* [[DIMS]] to
        i8*
        <br>
         // CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 [[CAST]],
        i8 0,
        <br>
        i64 24, i1 false)
        <br>
        -// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]*
        [[DIMS]],
        <br>
        i32 0, i32 1
        <br>
        +// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x
        [[KMP_DIM]]], [1
        <br>
        x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0
        <br>
        +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]*
        [[DIM]],
        <br>
        i32 0, i32 1
        <br>
         // CHECK: store i64 %{{.+}}, i64* %
        <br>
        -// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]*
        [[DIMS]],
        <br>
        i32 0, i32 2
        <br>
        +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]*
        [[DIM]],
        <br>
        i32 0, i32 2
        <br>
         // CHECK: store i64 1, i64* %
        <br>
        -// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
        <br>
        +// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x
        [[KMP_DIM]]], [1
        <br>
        x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0
        <br>
        +// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIM]] to i8*
        <br>
         // CHECK: call void @__kmpc_doacross_init([[IDENT]], i32
        [[GTID]],
        <br>
        i32 1, i8* [[CAST]])
        <br>
         // CHECK: call void @__kmpc_for_static_init_4(
        <br>
         #pragma omp for ordered(1)
        <br>
        @@ -37,18 +39,26 @@ int main() {
        <br>
             a[i] = b[i] + 1;
        <br>
             foo();
        <br>
         // CHECK: invoke void [[FOO:.+]](
        <br>
        -// CHECK: load i32, i32* [[CNT:%.+]],
        <br>
        +// CHECK: load i32, i32* [[I:%.+]],
        <br>
        +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
        <br>
        +// CHECK-NEXT: sdiv i32 %{{.+}}, 1
        <br>
         // CHECK-NEXT: sext i32 %{{.+}} to i64
        <br>
        -// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64],
        [1 x
        <br>
        i64]* [[CNT:%.+]], i64 0, i64 0
        <br>
        +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]],
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64],
        [1 x
        <br>
        i64]* [[CNT]], i64 0, i64 0
        <br>
         // CHECK-NEXT: call void @__kmpc_doacross_post([[IDENT]], i32
        <br>
        [[GTID]], i64* [[TMP]])
        <br>
         #pragma omp ordered depend(source)
        <br>
             c[i] = c[i] + 1;
        <br>
             foo();
        <br>
         // CHECK: invoke void [[FOO]]
        <br>
        -// CHECK: load i32, i32* [[CNT]],
        <br>
        +// CHECK: load i32, i32* [[I]],
        <br>
         // CHECK-NEXT: sub nsw i32 %{{.+}}, 2
        <br>
        +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
        <br>
        +// CHECK-NEXT: sdiv i32 %{{.+}}, 1
        <br>
         // CHECK-NEXT: sext i32 %{{.+}} to i64
        <br>
        -// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64],
        [1 x
        <br>
        i64]* [[CNT:%.+]], i64 0, i64 0
        <br>
        +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]],
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64],
        [1 x
        <br>
        i64]* [[CNT]], i64 0, i64 0
        <br>
         // CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32
        <br>
        [[GTID]], i64* [[TMP]])
        <br>
         #pragma omp ordered depend(sink : i - 2)
        <br>
             d[i] = a[i - 2];
        <br>
        @@ -75,41 +85,84 @@ struct TestStruct {
        <br>
           T bar(T, T, T);
        <br>
           void baz(T, T);
        <br>
           TestStruct() {
        <br>
        -// CHECK: [[CNT:%.+]] = alloca i64,
        <br>
        -// CHECK: [[DIMS:%.+]] = alloca [[KMP_DIM]],
        <br>
        +// CHECK: [[DIMS:%.+]] = alloca [2 x [[KMP_DIM]]],
        <br>
         // CHECK: [[GTID:%.+]] = call i32
        @__kmpc_global_thread_num([[IDENT:%.+]])
        <br>
        -// CHECK: icmp
        <br>
        -// CHECK-NEXT: br i1 %
        <br>
        -// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
        <br>
        -// CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 [[CAST]],
        i8 0,
        <br>
        i64 24, i1 false)
        <br>
        -// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]*
        [[DIMS]],
        <br>
        i32 0, i32 1
        <br>
        +// CHECK: [[CAST:%.+]] = bitcast [2 x [[KMP_DIM]]]* [[DIMS]] to
        i8*
        <br>
        +// CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 [[CAST]],
        i8 0,
        <br>
        i64 48, i1 false)
        <br>
        +// CHECK: [[DIM:%.+]] = getelementptr inbounds [2 x
        [[KMP_DIM]]], [2
        <br>
        x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0
        <br>
        +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]*
        [[DIM]],
        <br>
        i32 0, i32 1
        <br>
        +// CHECK: store i64 10, i64* %
        <br>
        +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]*
        [[DIM]],
        <br>
        i32 0, i32 2
        <br>
        +// CHECK: store i64 1, i64* %
        <br>
        +// CHECK: [[DIM:%.+]] = getelementptr inbounds [2 x
        [[KMP_DIM]]], [2
        <br>
        x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 1
        <br>
        +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]*
        [[DIM]],
        <br>
        i32 0, i32 1
        <br>
         // CHECK: store i64 %{{.+}}, i64* %
        <br>
        -// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]*
        [[DIMS]],
        <br>
        i32 0, i32 2
        <br>
        +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]*
        [[DIM]],
        <br>
        i32 0, i32 2
        <br>
         // CHECK: store i64 1, i64* %
        <br>
        -// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
        <br>
        -// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32
        [[GTID]],
        <br>
        i32 1, i8* [[CAST]])
        <br>
        -// CHECK: call void @__kmpc_for_static_init_8(
        <br>
        +// CHECK: [[DIM:%.+]] = getelementptr inbounds [2 x
        [[KMP_DIM]]], [2
        <br>
        x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0
        <br>
        +// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIM]] to i8*
        <br>
        +// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32
        [[GTID]],
        <br>
        i32 2, i8* [[CAST]])
        <br>
        +// CHECK: call void @__kmpc_for_static_init_4(
        <br>
         #pragma omp for ordered(2)
        <br>
             for (T j = 0; j < M; j++)
        <br>
               for (i = 0; i < n; i += 2) {
        <br>
                 a[i][j] = foo(i, j);
        <br>
         // CHECK: invoke {{.+TestStruct.+foo}}
        <br>
        -// CHECK: load i64, i64* [[CNT]],
        <br>
        -// CHECK-NEXT: sub nsw i64 %{{.+}}, 1
        <br>
        +// CHECK: load i32*, i32** %
        <br>
        +// CHECK: load i32, i32* %
        <br>
        +// CHECK: load i32, i32* %
        <br>
        +// CHECK: load i32, i32* [[J:%.+]],
        <br>
        +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
        <br>
        +// CHECK-NEXT: sdiv i32 %{{.+}}, 1
        <br>
        +// CHECK-NEXT: sext i32 %{{.+}} to i64
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64],
        [2 x
        <br>
        i64]* [[CNT:%.+]], i64 0, i64 0
        <br>
         // CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
        <br>
        +// CHECK-NEXT: [[I:%.+]] = load i32*, i32** [[I_REF:%.+]],
        <br>
        +// CHECK-NEXT: load i32, i32* [[I]],
        <br>
        +// CHECK-NEXT: sub nsw i32 %{{.+}}, 2
        <br>
        +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
        <br>
        +// CHECK-NEXT: sdiv i32 %{{.+}}, 2
        <br>
        +// CHECK-NEXT: sext i32 %{{.+}} to i64
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64],
        [2 x
        <br>
        i64]* [[CNT]], i64 0, i64 1
        <br>
        +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]],
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64],
        [2 x
        <br>
        i64]* [[CNT]], i64 0, i64 0
        <br>
         // CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32
        <br>
        [[GTID]], i64* [[TMP]])
        <br>
        -// CHECK-NEXT: load i64, i64* [[CNT]],
        <br>
        -// CHECK-NEXT: load i32, i32* %
        <br>
        -// CHECK-NEXT: mul nsw i32 1, %
        <br>
        +// CHECK-NEXT: load i32, i32* [[J:%.+]],
        <br>
        +// CHECK-NEXT: sub nsw i32 %{{.+}}, 1
        <br>
        +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
        <br>
        +// CHECK-NEXT: sdiv i32 %{{.+}}, 1
        <br>
         // CHECK-NEXT: sext i32 %{{.+}} to i64
        <br>
        -// CHECK-NEXT: sub nsw i64 %
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64],
        [2 x
        <br>
        i64]* [[CNT:%.+]], i64 0, i64 0
        <br>
         // CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
        <br>
        +// CHECK-NEXT: [[I:%.+]] = load i32*, i32** [[I_REF]],
        <br>
        +// CHECK-NEXT: load i32, i32* [[I]],
        <br>
        +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
        <br>
        +// CHECK-NEXT: sdiv i32 %{{.+}}, 2
        <br>
        +// CHECK-NEXT: sext i32 %{{.+}} to i64
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64],
        [2 x
        <br>
        i64]* [[CNT]], i64 0, i64 1
        <br>
        +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]],
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64],
        [2 x
        <br>
        i64]* [[CNT]], i64 0, i64 0
        <br>
         // CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32
        <br>
        [[GTID]], i64* [[TMP]])
        <br>
         #pragma omp ordered depend(sink : j, i - 2) depend(sink : j -
        1, i)
        <br>
                 b[i][j] = bar(a[i][j], b[i - 1][j], b[i][j - 1]);
        <br>
         // CHECK: invoke {{.+TestStruct.+bar}}
        <br>
        -// CHECK: load i64, i64* [[CNT]],
        <br>
        +// CHECK: load i32*, i32** %
        <br>
        +// CHECK: load i32, i32* %
        <br>
        +// CHECK: load i32, i32* %
        <br>
        +// CHECK: load i32, i32* [[J]],
        <br>
        +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
        <br>
        +// CHECK-NEXT: sdiv i32 %{{.+}}, 1
        <br>
        +// CHECK-NEXT: sext i32 %{{.+}} to i64
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64],
        [2 x
        <br>
        i64]* [[CNT:%.+]], i64 0, i64 0
        <br>
         // CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
        <br>
        +// CHECK-NEXT: [[I:%.+]] = load i32*, i32** [[I_REF]],
        <br>
        +// CHECK-NEXT: load i32, i32* [[I]],
        <br>
        +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
        <br>
        +// CHECK-NEXT: sdiv i32 %{{.+}}, 2
        <br>
        +// CHECK-NEXT: sext i32 %{{.+}} to i64
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64],
        [2 x
        <br>
        i64]* [[CNT]], i64 0, i64 1
        <br>
        +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]],
        <br>
        +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64],
        [2 x
        <br>
        i64]* [[CNT]], i64 0, i64 0
        <br>
         // CHECK-NEXT: call void @__kmpc_doacross_post([[IDENT]], i32
        <br>
        [[GTID]], i64* [[TMP]])
        <br>
         #pragma omp ordered depend(source)
        <br>
                 baz(a[i][j], b[i][j]);
        <br>
        <br>
        Modified: cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp
        <br>
        URL:
        <br>
<a class="moz-txt-link-freetext" href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp?rev=339603&r1=339602&r2=339603&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp?rev=339603&r1=339602&r2=339603&view=diff</a>
        <br>
==============================================================================
        <br>
        --- cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp
        (original)
        <br>
        +++ cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp Mon
        Aug 13
        <br>
        12:04:24 2018
        <br>
        @@ -48,7 +48,7 @@ class S8 : public S7<S1> {
        <br>
        <br>
         public:
        <br>
           S8(int v) : S7<S1>(v){
        <br>
        -#pragma omp parallel for simd private(a) private(this->a)
        private(S7<S1>::a)
        <br>
        +#pragma omp parallel for simd private(a) private(this->a)
        private(S7 <S1>::a)
        <br>
             for (int k = 0; k < a.a; ++k)
        <br>
               ++this->a.a;
        <br>
           }
        <br>
        <br>
        <br>
        _______________________________________________
        <br>
        cfe-commits mailing list
        <br>
        <a class="moz-txt-link-abbreviated" href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>
        <br>
        <a class="moz-txt-link-freetext" href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a>
        <br>
      </blockquote>
      <br>
    </blockquote>
    <br>
  </body>
</html>