[clang] [llvm] [openmp] [CLANG][OpenMP] Restore loop variable values after transformation directives (PR #214717)

Zahira Ammarguellat via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 10 10:59:09 PDT 2026


https://github.com/zahiraam updated https://github.com/llvm/llvm-project/pull/214717

>From c3f4946f9f13ce4ab30b94800dbb1c0a271dc629 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Fri, 7 Aug 2026 05:41:34 -0700
Subject: [PATCH 01/11] [OpenMP] Fix loop variable finalization for
 transformation directives

---
 clang/include/clang/AST/StmtOpenMP.h  |   67 +-
 clang/lib/AST/StmtOpenMP.cpp          |   48 +-
 clang/lib/CodeGen/CGStmtOpenMP.cpp    |   25 +
 clang/lib/Sema/SemaOpenMP.cpp         |  156 +-
 clang/test/OpenMP/fuse_codegen.cpp    |  158 ++
 clang/test/OpenMP/loop_transform_iv.c |  129 +
 clang/test/OpenMP/reverse_codegen.cpp | 3164 +++++++++++++------------
 clang/test/OpenMP/stripe_codegen.cpp  |   60 +
 clang/test/OpenMP/tile_codegen.cpp    |   60 +
 9 files changed, 2240 insertions(+), 1627 deletions(-)
 create mode 100644 clang/test/OpenMP/loop_transform_iv.c

diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h
index bd95080707e1e..b4c6573ef712b 100644
--- a/clang/include/clang/AST/StmtOpenMP.h
+++ b/clang/include/clang/AST/StmtOpenMP.h
@@ -5686,6 +5686,7 @@ class OMPTileDirective final
   enum {
     PreInitsOffset = 0,
     TransformedStmtOffset,
+    FinalsOffset,
   };
 
   explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc,
@@ -5702,6 +5703,8 @@ class OMPTileDirective final
     Data->getChildren()[TransformedStmtOffset] = S;
   }
 
+  void setFinals(Stmt *Finals) { Data->getChildren()[FinalsOffset] = Finals; }
+
 public:
   /// Create a new AST node representation for '#pragma omp tile'.
   ///
@@ -5715,11 +5718,11 @@ class OMPTileDirective final
   /// \param TransformedStmt The loop nest after tiling, or nullptr in
   ///                        dependent contexts.
   /// \param PreInits Helper preinits statements for the loop nest.
-  static OMPTileDirective *Create(const ASTContext &C, SourceLocation StartLoc,
-                                  SourceLocation EndLoc,
-                                  ArrayRef<OMPClause *> Clauses,
-                                  unsigned NumLoops, Stmt *AssociatedStmt,
-                                  Stmt *TransformedStmt, Stmt *PreInits);
+  /// \param Finals Loop variable finalization statements.
+  static OMPTileDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         ArrayRef<OMPClause *> Clauses, unsigned NumLoops, Stmt *AssociatedStmt,
+         Stmt *TransformedStmt, Stmt *PreInits, Stmt *Finals);
 
   /// Build an empty '#pragma omp tile' AST node for deserialization.
   ///
@@ -5747,6 +5750,9 @@ class OMPTileDirective final
   /// Return preinits statement.
   Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
 
+  /// Return finals statement (loop variable finalization).
+  Stmt *getFinals() const { return Data->getChildren()[FinalsOffset]; }
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == OMPTileDirectiveClass;
   }
@@ -5762,6 +5768,7 @@ class OMPStripeDirective final
   enum {
     PreInitsOffset = 0,
     TransformedStmtOffset,
+    FinalsOffset,
   };
 
   explicit OMPStripeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
@@ -5778,6 +5785,8 @@ class OMPStripeDirective final
     Data->getChildren()[TransformedStmtOffset] = S;
   }
 
+  void setFinals(Stmt *Finals) { Data->getChildren()[FinalsOffset] = Finals; }
+
 public:
   /// Create a new AST node representation for '#pragma omp stripe'.
   ///
@@ -5791,10 +5800,11 @@ class OMPStripeDirective final
   /// \param TransformedStmt The loop nest after striping, or nullptr in
   ///                        dependent contexts.
   /// \param PreInits Helper preinits statements for the loop nest.
+  /// \param Finals Loop variable finalization statements.
   static OMPStripeDirective *
   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
          ArrayRef<OMPClause *> Clauses, unsigned NumLoops, Stmt *AssociatedStmt,
-         Stmt *TransformedStmt, Stmt *PreInits);
+         Stmt *TransformedStmt, Stmt *PreInits, Stmt *Finals);
 
   /// Build an empty '#pragma omp stripe' AST node for deserialization.
   ///
@@ -5821,6 +5831,9 @@ class OMPStripeDirective final
   /// Return preinits statement.
   Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
 
+  /// Return finals statement (loop variable finalization).
+  Stmt *getFinals() const { return Data->getChildren()[FinalsOffset]; }
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == OMPStripeDirectiveClass;
   }
@@ -5917,6 +5930,7 @@ class OMPReverseDirective final
   enum {
     PreInitsOffset = 0,
     TransformedStmtOffset,
+    FinalsOffset,
   };
 
   explicit OMPReverseDirective(SourceLocation StartLoc, SourceLocation EndLoc,
@@ -5933,6 +5947,8 @@ class OMPReverseDirective final
     Data->getChildren()[TransformedStmtOffset] = S;
   }
 
+  void setFinals(Stmt *Finals) { Data->getChildren()[FinalsOffset] = Finals; }
+
 public:
   /// Create a new AST node representation for '#pragma omp reverse'.
   ///
@@ -5944,11 +5960,11 @@ class OMPReverseDirective final
   /// \param TransformedStmt The loop nest after tiling, or nullptr in
   ///                        dependent contexts.
   /// \param PreInits   Helper preinits statements for the loop nest.
-  static OMPReverseDirective *Create(const ASTContext &C,
-                                     SourceLocation StartLoc,
-                                     SourceLocation EndLoc,
-                                     Stmt *AssociatedStmt, unsigned NumLoops,
-                                     Stmt *TransformedStmt, Stmt *PreInits);
+  /// \param Finals     Loop variable finalization statements.
+  static OMPReverseDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         Stmt *AssociatedStmt, unsigned NumLoops, Stmt *TransformedStmt,
+         Stmt *PreInits, Stmt *Finals);
 
   /// Build an empty '#pragma omp reverse' AST node for deserialization.
   ///
@@ -5966,6 +5982,9 @@ class OMPReverseDirective final
   /// Return preinits statement.
   Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
 
+  /// Return finals statement.
+  Stmt *getFinals() const { return Data->getChildren()[FinalsOffset]; }
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == OMPReverseDirectiveClass;
   }
@@ -5988,6 +6007,7 @@ class OMPInterchangeDirective final
   enum {
     PreInitsOffset = 0,
     TransformedStmtOffset,
+    FinalsOffset,
   };
 
   explicit OMPInterchangeDirective(SourceLocation StartLoc,
@@ -6004,6 +6024,8 @@ class OMPInterchangeDirective final
     Data->getChildren()[TransformedStmtOffset] = S;
   }
 
+  void setFinals(Stmt *Finals) { Data->getChildren()[FinalsOffset] = Finals; }
+
 public:
   /// Create a new AST node representation for '#pragma omp interchange'.
   ///
@@ -6017,10 +6039,11 @@ class OMPInterchangeDirective final
   /// \param TransformedStmt The loop nest after tiling, or nullptr in
   ///                        dependent contexts.
   /// \param PreInits  Helper preinits statements for the loop nest.
+  /// \param Finals    Loop variable finalization statements.
   static OMPInterchangeDirective *
   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
          ArrayRef<OMPClause *> Clauses, unsigned NumLoops, Stmt *AssociatedStmt,
-         Stmt *TransformedStmt, Stmt *PreInits);
+         Stmt *TransformedStmt, Stmt *PreInits, Stmt *Finals);
 
   /// Build an empty '#pragma omp interchange' AST node for deserialization.
   ///
@@ -6039,6 +6062,9 @@ class OMPInterchangeDirective final
   /// Return preinits statement.
   Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
 
+  /// Return finals statement.
+  Stmt *getFinals() const { return Data->getChildren()[FinalsOffset]; }
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == OMPInterchangeDirectiveClass;
   }
@@ -6094,6 +6120,7 @@ class OMPFuseDirective final
   enum {
     PreInitsOffset = 0,
     TransformedStmtOffset,
+    FinalsOffset,
   };
 
   explicit OMPFuseDirective(SourceLocation StartLoc, SourceLocation EndLoc)
@@ -6108,6 +6135,8 @@ class OMPFuseDirective final
     Data->getChildren()[TransformedStmtOffset] = S;
   }
 
+  void setFinals(Stmt *Finals) { Data->getChildren()[FinalsOffset] = Finals; }
+
 public:
   /// Create a new AST node representation for #pragma omp fuse'
   ///
@@ -6123,10 +6152,13 @@ class OMPFuseDirective final
   /// \param TransformedStmt The loop nest after fusion, or nullptr in
   ///                        dependent
   /// \param PreInits Helper preinits statements for the loop nest
-  static OMPFuseDirective *
-  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
-         ArrayRef<OMPClause *> Clauses, unsigned NumGeneratedTopLevelLoops,
-         Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits);
+  /// \param Finals Loop variable finalization statements
+  static OMPFuseDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+                                  SourceLocation EndLoc,
+                                  ArrayRef<OMPClause *> Clauses,
+                                  unsigned NumGeneratedTopLevelLoops,
+                                  Stmt *AssociatedStmt, Stmt *TransformedStmt,
+                                  Stmt *PreInits, Stmt *Finals);
 
   /// Build an empty '#pragma omp fuse' AST node for deserialization
   ///
@@ -6145,6 +6177,9 @@ class OMPFuseDirective final
   /// Return preinits statement.
   Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
 
+  /// Return finals statement.
+  Stmt *getFinals() const { return Data->getChildren()[FinalsOffset]; }
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == OMPFuseDirectiveClass;
   }
diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp
index 44656266bcf08..0ca3349a23542 100644
--- a/clang/lib/AST/StmtOpenMP.cpp
+++ b/clang/lib/AST/StmtOpenMP.cpp
@@ -504,12 +504,12 @@ OMPTileDirective *
 OMPTileDirective::Create(const ASTContext &C, SourceLocation StartLoc,
                          SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses,
                          unsigned NumLoops, Stmt *AssociatedStmt,
-                         Stmt *TransformedStmt, Stmt *PreInits) {
+                         Stmt *TransformedStmt, Stmt *PreInits, Stmt *Finals) {
   OMPTileDirective *Dir = createDirective<OMPTileDirective>(
-      C, Clauses, AssociatedStmt, TransformedStmtOffset + 1, StartLoc, EndLoc,
-      NumLoops);
+      C, Clauses, AssociatedStmt, FinalsOffset + 1, StartLoc, EndLoc, NumLoops);
   Dir->setTransformedStmt(TransformedStmt);
   Dir->setPreInits(PreInits);
+  Dir->setFinals(Finals);
   return Dir;
 }
 
@@ -517,20 +517,19 @@ OMPTileDirective *OMPTileDirective::CreateEmpty(const ASTContext &C,
                                                 unsigned NumClauses,
                                                 unsigned NumLoops) {
   return createEmptyDirective<OMPTileDirective>(
-      C, NumClauses, /*HasAssociatedStmt=*/true, TransformedStmtOffset + 1,
+      C, NumClauses, /*HasAssociatedStmt=*/true, FinalsOffset + 1,
       SourceLocation(), SourceLocation(), NumLoops);
 }
 
-OMPStripeDirective *
-OMPStripeDirective::Create(const ASTContext &C, SourceLocation StartLoc,
-                           SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses,
-                           unsigned NumLoops, Stmt *AssociatedStmt,
-                           Stmt *TransformedStmt, Stmt *PreInits) {
+OMPStripeDirective *OMPStripeDirective::Create(
+    const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+    ArrayRef<OMPClause *> Clauses, unsigned NumLoops, Stmt *AssociatedStmt,
+    Stmt *TransformedStmt, Stmt *PreInits, Stmt *Finals) {
   OMPStripeDirective *Dir = createDirective<OMPStripeDirective>(
-      C, Clauses, AssociatedStmt, TransformedStmtOffset + 1, StartLoc, EndLoc,
-      NumLoops);
+      C, Clauses, AssociatedStmt, FinalsOffset + 1, StartLoc, EndLoc, NumLoops);
   Dir->setTransformedStmt(TransformedStmt);
   Dir->setPreInits(PreInits);
+  Dir->setFinals(Finals);
   return Dir;
 }
 
@@ -538,7 +537,7 @@ OMPStripeDirective *OMPStripeDirective::CreateEmpty(const ASTContext &C,
                                                     unsigned NumClauses,
                                                     unsigned NumLoops) {
   return createEmptyDirective<OMPStripeDirective>(
-      C, NumClauses, /*HasAssociatedStmt=*/true, TransformedStmtOffset + 1,
+      C, NumClauses, /*HasAssociatedStmt=*/true, FinalsOffset + 1,
       SourceLocation(), SourceLocation(), NumLoops);
 }
 
@@ -568,31 +567,31 @@ OMPReverseDirective *
 OMPReverseDirective::Create(const ASTContext &C, SourceLocation StartLoc,
                             SourceLocation EndLoc, Stmt *AssociatedStmt,
                             unsigned NumLoops, Stmt *TransformedStmt,
-                            Stmt *PreInits) {
+                            Stmt *PreInits, Stmt *Finals) {
   OMPReverseDirective *Dir = createDirective<OMPReverseDirective>(
-      C, {}, AssociatedStmt, TransformedStmtOffset + 1, StartLoc, EndLoc,
-      NumLoops);
+      C, {}, AssociatedStmt, FinalsOffset + 1, StartLoc, EndLoc, NumLoops);
   Dir->setTransformedStmt(TransformedStmt);
   Dir->setPreInits(PreInits);
+  Dir->setFinals(Finals);
   return Dir;
 }
 
 OMPReverseDirective *OMPReverseDirective::CreateEmpty(const ASTContext &C,
                                                       unsigned NumLoops) {
   return createEmptyDirective<OMPReverseDirective>(
-      C, /*NumClauses=*/0, /*HasAssociatedStmt=*/true,
-      TransformedStmtOffset + 1, SourceLocation(), SourceLocation(), NumLoops);
+      C, /*NumClauses=*/0, /*HasAssociatedStmt=*/true, FinalsOffset + 1,
+      SourceLocation(), SourceLocation(), NumLoops);
 }
 
 OMPInterchangeDirective *OMPInterchangeDirective::Create(
     const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
     ArrayRef<OMPClause *> Clauses, unsigned NumLoops, Stmt *AssociatedStmt,
-    Stmt *TransformedStmt, Stmt *PreInits) {
+    Stmt *TransformedStmt, Stmt *PreInits, Stmt *Finals) {
   OMPInterchangeDirective *Dir = createDirective<OMPInterchangeDirective>(
-      C, Clauses, AssociatedStmt, TransformedStmtOffset + 1, StartLoc, EndLoc,
-      NumLoops);
+      C, Clauses, AssociatedStmt, FinalsOffset + 1, StartLoc, EndLoc, NumLoops);
   Dir->setTransformedStmt(TransformedStmt);
   Dir->setPreInits(PreInits);
+  Dir->setFinals(Finals);
   return Dir;
 }
 
@@ -600,7 +599,7 @@ OMPInterchangeDirective *
 OMPInterchangeDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses,
                                      unsigned NumLoops) {
   return createEmptyDirective<OMPInterchangeDirective>(
-      C, NumClauses, /*HasAssociatedStmt=*/true, TransformedStmtOffset + 1,
+      C, NumClauses, /*HasAssociatedStmt=*/true, FinalsOffset + 1,
       SourceLocation(), SourceLocation(), NumLoops);
 }
 
@@ -628,12 +627,13 @@ OMPSplitDirective *OMPSplitDirective::CreateEmpty(const ASTContext &C,
 OMPFuseDirective *OMPFuseDirective::Create(
     const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
     ArrayRef<OMPClause *> Clauses, unsigned NumGeneratedTopLevelLoops,
-    Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits) {
+    Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits, Stmt *Finals) {
 
   OMPFuseDirective *Dir = createDirective<OMPFuseDirective>(
-      C, Clauses, AssociatedStmt, TransformedStmtOffset + 1, StartLoc, EndLoc);
+      C, Clauses, AssociatedStmt, FinalsOffset + 1, StartLoc, EndLoc);
   Dir->setTransformedStmt(TransformedStmt);
   Dir->setPreInits(PreInits);
+  Dir->setFinals(Finals);
   Dir->setNumGeneratedTopLevelLoops(NumGeneratedTopLevelLoops);
   return Dir;
 }
@@ -641,7 +641,7 @@ OMPFuseDirective *OMPFuseDirective::Create(
 OMPFuseDirective *OMPFuseDirective::CreateEmpty(const ASTContext &C,
                                                 unsigned NumClauses) {
   OMPFuseDirective *Dir = createEmptyDirective<OMPFuseDirective>(
-      C, NumClauses, /*HasAssociatedStmt=*/true, TransformedStmtOffset + 1,
+      C, NumClauses, /*HasAssociatedStmt=*/true, FinalsOffset + 1,
       SourceLocation(), SourceLocation());
   return Dir;
 }
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 7c3b30c6cedc0..5c7da3ebedce9 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -3224,18 +3224,33 @@ void CodeGenFunction::EmitOMPTileDirective(const OMPTileDirective &S) {
   // Emit the de-sugared statement.
   OMPTransformDirectiveScopeRAII TileScope(*this, &S);
   EmitStmt(S.getTransformedStmt());
+
+  // Emit loop variable finalization as required by OpenMP 6.0 spec to restore
+  // original loop variable values after the loop-transformation construct.
+  if (auto *Finals = S.getFinals())
+    EmitStmt(Finals);
 }
 
 void CodeGenFunction::EmitOMPStripeDirective(const OMPStripeDirective &S) {
   // Emit the de-sugared statement.
   OMPTransformDirectiveScopeRAII StripeScope(*this, &S);
   EmitStmt(S.getTransformedStmt());
+
+  // Emit loop variable finalization as required by OpenMP 6.0 spec to restore
+  // original loop variable values after the loop-transformation construct.
+  if (auto *Finals = S.getFinals())
+    EmitStmt(Finals);
 }
 
 void CodeGenFunction::EmitOMPReverseDirective(const OMPReverseDirective &S) {
   // Emit the de-sugared statement.
   OMPTransformDirectiveScopeRAII ReverseScope(*this, &S);
   EmitStmt(S.getTransformedStmt());
+
+  // Emit loop variable finalization as required by OpenMP 6.0 spec to restore
+  // original loop variable values after the loop-transformation construct.
+  if (auto *Finals = S.getFinals())
+    EmitStmt(Finals);
 }
 
 void CodeGenFunction::EmitOMPSplitDirective(const OMPSplitDirective &S) {
@@ -3249,12 +3264,22 @@ void CodeGenFunction::EmitOMPInterchangeDirective(
   // Emit the de-sugared statement.
   OMPTransformDirectiveScopeRAII InterchangeScope(*this, &S);
   EmitStmt(S.getTransformedStmt());
+
+  // Emit loop variable finalization as required by OpenMP 6.0 spec to restore
+  // original loop variable values after the loop-transformation construct.
+  if (auto *Finals = S.getFinals())
+    EmitStmt(Finals);
 }
 
 void CodeGenFunction::EmitOMPFuseDirective(const OMPFuseDirective &S) {
   // Emit the de-sugared statement
   OMPTransformDirectiveScopeRAII FuseScope(*this, &S);
   EmitStmt(S.getTransformedStmt());
+
+  // Emit loop variable finalization as required by OpenMP 6.0 spec to restore
+  // original loop variable values after the loop-transformation construct.
+  if (auto *Finals = S.getFinals())
+    EmitStmt(Finals);
 }
 
 void CodeGenFunction::EmitOMPUnrollDirective(const OMPUnrollDirective &S) {
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 2e4d9f2f82f0b..fe031b8376894 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -8087,6 +8087,8 @@ struct LoopIterationSpace final {
   /// check that the number of iterations for this particular counter must be
   /// finished.
   Expr *FinalCondition = nullptr;
+  /// True if this iteration space corresponds to a range-based for loop.
+  bool IsRangeFor = false;
 };
 
 /// Scan an AST subtree, checking that no decls in the CollapsedLoopVarDecls
@@ -9804,6 +9806,7 @@ static bool checkOpenMPIterationSpace(
   ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
   ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
       ISC.isStrictTestOp();
+  ResultIterSpaces[CurrentNestedLoopCount].IsRangeFor = (CXXFor != nullptr);
   std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
            ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
       ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
@@ -10122,6 +10125,24 @@ static Stmt *buildPreInits(ASTContext &Context, ArrayRef<Stmt *> PreInits) {
   return CompoundStmt::Create(Context, PreInits, FPOptionsOverride(), {}, {});
 }
 
+/// Helper to determine if a loop should skip finalization.
+/// Returns true for range-based for loops or loops with non-arithmetic counters.
+static bool shouldSkipLoopFinalization(Stmt *LoopStmt) {
+  if (isa<CXXForRangeStmt>(LoopStmt))
+    return true;
+
+  auto *For = dyn_cast<ForStmt>(LoopStmt);
+  if (!For)
+    return false;
+
+  auto *InitDecl = dyn_cast_or_null<DeclStmt>(For->getInit());
+  if (!InitDecl || !InitDecl->isSingleDecl())
+    return false;
+
+  auto *InitVar = dyn_cast<VarDecl>(InitDecl->getSingleDecl());
+  return InitVar && !InitVar->getType()->isArithmeticType();
+}
+
 /// Build postupdate expression for the given list of postupdates expressions.
 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
   Expr *PostUpdate = nullptr;
@@ -10825,16 +10846,37 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
       }
 
       // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
-      ExprResult Final =
-          buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
-                             IS.CounterInit, IS.NumIterations, IS.CounterStep,
-                             IS.Subtract, IS.IsNonRectangularLB, &Captures);
-      if (!Final.isUsable()) {
-        HasErrors = true;
-        break;
+      // For loop transformation directives with arithmetic counters, use
+      // (NumIters - 1) to get the value from the last iteration, not the loop
+      // exit value. For iterator-based loops (range-based for or explicit
+      // iterator loops), skip finalization entirely.
+      ExprResult Final;
+      bool IsIteratorLoop = IS.IsRangeFor ||
+                            !IS.CounterVar->getType()->isArithmeticType();
+      if (IsIteratorLoop && isOpenMPLoopTransformationDirective(DKind)) {
+        // Iterator-based loops in transformation directives don't need
+        // explicit finalization - the iterator is already at the end.
+        Final = nullptr;
+      } else {
+        Expr *FinalIterCount = IS.NumIterations;
+        if (isOpenMPLoopTransformationDirective(DKind)) {
+          ExprResult LastIter = SemaRef.BuildBinOp(
+              CurScope, UpdLoc, BO_Sub, IS.NumIterations,
+              SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
+          if (LastIter.isUsable()) {
+            FinalIterCount = LastIter.get();
+          }
+        }
+        Final = buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
+                                    IS.CounterInit, FinalIterCount, IS.CounterStep,
+                                    IS.Subtract, IS.IsNonRectangularLB, &Captures);
+        if (!Final.isUsable()) {
+          HasErrors = true;
+          break;
+        }
       }
 
-      if (!Update.isUsable() || !Final.isUsable()) {
+      if (!Update.isUsable()) {
         HasErrors = true;
         break;
       }
@@ -10843,7 +10885,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
       Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
       Built.Inits[Cnt] = Init.get();
       Built.Updates[Cnt] = Update.get();
-      Built.Finals[Cnt] = Final.get();
+      Built.Finals[Cnt] = Final.isUsable() ? Final.get() : nullptr;
       Built.DependentCounters[Cnt] = nullptr;
       Built.DependentInits[Cnt] = nullptr;
       // Transfer the body-guard condition: the loop condition for
@@ -15201,6 +15243,38 @@ static Expr *makeFloorIVRef(Sema &SemaRef, ArrayRef<VarDecl *> FloorIndVars,
                           OrigCntVar->getExprLoc());
 }
 
+/// Build loop variable finalization statement from HelperExprs.Finals.
+/// Returns a CompoundStmt containing all finalization statements, or nullptr
+/// if there are no finalization statements.
+/// Note: Loops with non-arithmetic loop variables (e.g., iterators) are skipped
+/// because finalization only applies to integer/floating-point counters.
+static Stmt *
+buildLoopFinalization(ASTContext &Context,
+                      ArrayRef<OMPLoopBasedDirective::HelperExprs> LoopHelpers,
+                      ArrayRef<Stmt *> LoopStmts = {}) {
+  bool ShouldFilter = !LoopStmts.empty();
+  assert((!ShouldFilter || LoopHelpers.size() == LoopStmts.size()) &&
+         "LoopHelpers and LoopStmts must have the same size");
+
+  SmallVector<Stmt *, 8> FinalizationStmts;
+
+  for (size_t I = 0; I < LoopHelpers.size(); ++I) {
+    // Filter iterator loops if LoopStmts provided
+    if (ShouldFilter && shouldSkipLoopFinalization(LoopStmts[I]))
+      continue;
+
+    for (auto *Final : LoopHelpers[I].Finals)
+      if (Final)
+        FinalizationStmts.push_back(Final);
+  }
+
+  return FinalizationStmts.empty()
+             ? nullptr
+             : CompoundStmt::Create(Context, FinalizationStmts,
+                                    FPOptionsOverride(), SourceLocation(),
+                                    SourceLocation());
+}
+
 StmtResult SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
                                                 Stmt *AStmt,
                                                 SourceLocation StartLoc,
@@ -15230,7 +15304,7 @@ StmtResult SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
   // Delay tiling to when template is completely instantiated.
   if (SemaRef.CurContext->isDependentContext())
     return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
-                                    NumLoops, AStmt, nullptr, nullptr);
+                                    NumLoops, AStmt, nullptr, nullptr, nullptr);
 
   assert(LoopHelpers.size() == NumLoops &&
          "Expecting loop iteration space dimensionality to match number of "
@@ -15553,7 +15627,9 @@ StmtResult SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
 
   return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
                                   AStmt, Inner,
-                                  buildPreInits(Context, PreInits));
+                                  buildPreInits(Context, PreInits),
+                                  buildLoopFinalization(Context, LoopHelpers,
+                                                        LoopStmts));
 }
 
 StmtResult SemaOpenMP::ActOnOpenMPStripeDirective(ArrayRef<OMPClause *> Clauses,
@@ -15587,7 +15663,8 @@ StmtResult SemaOpenMP::ActOnOpenMPStripeDirective(ArrayRef<OMPClause *> Clauses,
   // Delay striping to when template is completely instantiated.
   if (SemaRef.CurContext->isDependentContext())
     return OMPStripeDirective::Create(Context, StartLoc, EndLoc, Clauses,
-                                      NumLoops, AStmt, nullptr, nullptr);
+                                      NumLoops, AStmt, nullptr, nullptr,
+                                      nullptr);
 
   assert(LoopHelpers.size() == NumLoops &&
          "Expecting loop iteration space dimensionality to match number of "
@@ -15810,9 +15887,10 @@ StmtResult SemaOpenMP::ActOnOpenMPStripeDirective(ArrayRef<OMPClause *> Clauses,
                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
   }
 
-  return OMPStripeDirective::Create(Context, StartLoc, EndLoc, Clauses,
-                                    NumLoops, AStmt, Inner,
-                                    buildPreInits(Context, PreInits));
+  return OMPStripeDirective::Create(
+      Context, StartLoc, EndLoc, Clauses, NumLoops, AStmt, Inner,
+      buildPreInits(Context, PreInits),
+      buildLoopFinalization(Context, LoopHelpers, LoopStmts));
 }
 
 StmtResult SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
@@ -16119,7 +16197,7 @@ StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt,
   // instantiated.
   if (SemaRef.CurContext->isDependentContext())
     return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt,
-                                       NumLoops, nullptr, nullptr);
+                                       NumLoops, nullptr, nullptr, nullptr);
 
   assert(LoopHelpers.size() == NumLoops &&
          "Expecting a single-dimensional loop iteration space");
@@ -16278,9 +16356,10 @@ StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt,
       ForStmt(Context, Init.get(), Cond.get(), nullptr, Incr.get(),
               ReversedBody, LoopHelper.Init->getBeginLoc(),
               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
-  return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt, NumLoops,
-                                     ReversedFor,
-                                     buildPreInits(Context, PreInits));
+  return OMPReverseDirective::Create(
+      Context, StartLoc, EndLoc, AStmt, NumLoops, ReversedFor,
+      buildPreInits(Context, PreInits),
+      buildLoopFinalization(Context, LoopHelpers, {LoopStmt}));
 }
 
 /// Build the AST for \#pragma omp split counts(c1, c2, ...).
@@ -16539,7 +16618,8 @@ StmtResult SemaOpenMP::ActOnOpenMPInterchangeDirective(
   // Delay interchange to when template is completely instantiated.
   if (CurContext->isDependentContext())
     return OMPInterchangeDirective::Create(Context, StartLoc, EndLoc, Clauses,
-                                           NumLoops, AStmt, nullptr, nullptr);
+                                           NumLoops, AStmt, nullptr, nullptr,
+                                           nullptr);
 
   // An invalid expression in the permutation clause is set to nullptr in
   // ActOnOpenMPPermutationClause.
@@ -16592,7 +16672,8 @@ StmtResult SemaOpenMP::ActOnOpenMPInterchangeDirective(
         return Idx == Arg;
       }))
     return OMPInterchangeDirective::Create(Context, StartLoc, EndLoc, Clauses,
-                                           NumLoops, AStmt, AStmt, nullptr);
+                                           NumLoops, AStmt, AStmt, nullptr,
+                                           nullptr);
 
   // Find the affected loops.
   SmallVector<Stmt *> LoopStmts(NumLoops, nullptr);
@@ -16702,9 +16783,10 @@ StmtResult SemaOpenMP::ActOnOpenMPInterchangeDirective(
         SourceHelper.Inc->getEndLoc());
   }
 
-  return OMPInterchangeDirective::Create(Context, StartLoc, EndLoc, Clauses,
-                                         NumLoops, AStmt, Inner,
-                                         buildPreInits(Context, PreInits));
+  return OMPInterchangeDirective::Create(
+      Context, StartLoc, EndLoc, Clauses, NumLoops, AStmt, Inner,
+      buildPreInits(Context, PreInits),
+      buildLoopFinalization(Context, LoopHelpers, LoopStmts));
 }
 
 StmtResult SemaOpenMP::ActOnOpenMPFuseDirective(ArrayRef<OMPClause *> Clauses,
@@ -16727,7 +16809,8 @@ StmtResult SemaOpenMP::ActOnOpenMPFuseDirective(ArrayRef<OMPClause *> Clauses,
   // because a dependent context could prevent determining its true value
   if (CurrContext->isDependentContext())
     return OMPFuseDirective::Create(Context, StartLoc, EndLoc, Clauses,
-                                    /* NumLoops */ 1, AStmt, nullptr, nullptr);
+                                    /* NumLoops */ 1, AStmt, nullptr, nullptr,
+                                    nullptr);
 
   // Validate that the potential loop sequence is transformable for fusion
   // Also collect the HelperExprs, Loop Stmts, Inits, and Number of loops
@@ -16818,7 +16901,6 @@ StmtResult SemaOpenMP::ActOnOpenMPFuseDirective(ArrayRef<OMPClause *> Clauses,
   SmallVector<VarDecl *, 4> LBVarDecls;
   SmallVector<VarDecl *, 4> STVarDecls;
   SmallVector<VarDecl *, 4> NIVarDecls;
-  SmallVector<VarDecl *, 4> UBVarDecls;
   SmallVector<VarDecl *, 4> IVVarDecls;
 
   // Helper lambda to create variables for bounds, strides, and other
@@ -16901,8 +16983,6 @@ StmtResult SemaOpenMP::ActOnOpenMPFuseDirective(ArrayRef<OMPClause *> Clauses,
                       SeqAnalysis.Loops[I].TheForStmt,
                       SeqAnalysis.Loops[I].OriginalInits, PreInits);
     }
-    auto [UBVD, UBDStmt] =
-        CreateHelperVarAndStmt(SeqAnalysis.Loops[I].HelperExprs.UB, "ub", J);
     auto [LBVD, LBDStmt] =
         CreateHelperVarAndStmt(SeqAnalysis.Loops[I].HelperExprs.LB, "lb", J);
     auto [STVD, STDStmt] =
@@ -16915,7 +16995,6 @@ StmtResult SemaOpenMP::ActOnOpenMPFuseDirective(ArrayRef<OMPClause *> Clauses,
     assert(LBVD && STVD && NIVD && IVVD &&
            "OpenMP Fuse Helper variables creation failed");
 
-    UBVarDecls.push_back(UBVD);
     LBVarDecls.push_back(LBVD);
     STVarDecls.push_back(STVD);
     NIVarDecls.push_back(NIVD);
@@ -17133,6 +17212,18 @@ StmtResult SemaOpenMP::ActOnOpenMPFuseDirective(ArrayRef<OMPClause *> Clauses,
               FusedBody, InitStmt.get()->getBeginLoc(), SourceLocation(),
               IncrExpr.get()->getEndLoc());
 
+  // 8. Build finalization statements for fused loops.
+  // Collect HelperExprs from the fused loops.
+  SmallVector<OMPLoopBasedDirective::HelperExprs, 4> FusedLoopHelpers;
+  SmallVector<Stmt *, 4> FusedLoopStmts;
+  for (unsigned I = FirstVal - 1; I < LastVal; ++I) {
+    if (SeqAnalysis.Loops[I].isRegularLoop() &&
+        isa<ForStmt>(SeqAnalysis.Loops[I].TheForStmt)) {
+      FusedLoopHelpers.push_back(SeqAnalysis.Loops[I].HelperExprs);
+      FusedLoopStmts.push_back(SeqAnalysis.Loops[I].TheForStmt);
+    }
+  }
+
   //  In the case of looprange, the result of fuse won't simply
   //  be a single loop (ForStmt), but rather a loop sequence
   //  (CompoundStmt) of 3 parts: the pre-fusion loops, the fused loop
@@ -17180,9 +17271,10 @@ StmtResult SemaOpenMP::ActOnOpenMPFuseDirective(ArrayRef<OMPClause *> Clauses,
     FusionStmt = CompoundStmt::Create(Context, FinalLoops, FPOptionsOverride(),
                                       SourceLocation(), SourceLocation());
   }
-  return OMPFuseDirective::Create(Context, StartLoc, EndLoc, Clauses,
-                                  NumGeneratedTopLevelLoops, AStmt, FusionStmt,
-                                  buildPreInits(Context, PreInits));
+  return OMPFuseDirective::Create(
+      Context, StartLoc, EndLoc, Clauses, NumGeneratedTopLevelLoops, AStmt,
+      FusionStmt, buildPreInits(Context, PreInits),
+      buildLoopFinalization(Context, FusedLoopHelpers, FusedLoopStmts));
 }
 
 OMPClause *SemaOpenMP::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
diff --git a/clang/test/OpenMP/fuse_codegen.cpp b/clang/test/OpenMP/fuse_codegen.cpp
index df79562168588..d0eeb9fd58cac 100644
--- a/clang/test/OpenMP/fuse_codegen.cpp
+++ b/clang/test/OpenMP/fuse_codegen.cpp
@@ -244,6 +244,34 @@ extern "C" void foo5() {
 // CHECK1-NEXT:    store i32 [[INC]], ptr [[DOTOMP_FUSE_INDEX]], align 4
 // CHECK1-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]]
 // CHECK1:       [[FOR_END]]:
+// CHECK1-NEXT:    [[TMP44:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[TMP45:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK1-NEXT:    [[TMP46:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB28:%.*]] = sub i32 [[TMP45]], [[TMP46]]
+// CHECK1-NEXT:    [[SUB29:%.*]] = sub i32 [[SUB28]], 1
+// CHECK1-NEXT:    [[TMP47:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[ADD30:%.*]] = add i32 [[SUB29]], [[TMP47]]
+// CHECK1-NEXT:    [[TMP48:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[DIV31:%.*]] = udiv i32 [[ADD30]], [[TMP48]]
+// CHECK1-NEXT:    [[SUB32:%.*]] = sub i32 [[DIV31]], 1
+// CHECK1-NEXT:    [[TMP49:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[MUL33:%.*]] = mul i32 [[SUB32]], [[TMP49]]
+// CHECK1-NEXT:    [[ADD34:%.*]] = add i32 [[TMP44]], [[MUL33]]
+// CHECK1-NEXT:    store i32 [[ADD34]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[TMP50:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
+// CHECK1-NEXT:    [[TMP51:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_7]], align 4
+// CHECK1-NEXT:    [[TMP52:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
+// CHECK1-NEXT:    [[SUB35:%.*]] = sub i32 [[TMP51]], [[TMP52]]
+// CHECK1-NEXT:    [[SUB36:%.*]] = sub i32 [[SUB35]], 1
+// CHECK1-NEXT:    [[TMP53:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
+// CHECK1-NEXT:    [[ADD37:%.*]] = add i32 [[SUB36]], [[TMP53]]
+// CHECK1-NEXT:    [[TMP54:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
+// CHECK1-NEXT:    [[DIV38:%.*]] = udiv i32 [[ADD37]], [[TMP54]]
+// CHECK1-NEXT:    [[SUB39:%.*]] = sub i32 [[DIV38]], 1
+// CHECK1-NEXT:    [[TMP55:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
+// CHECK1-NEXT:    [[MUL40:%.*]] = mul i32 [[SUB39]], [[TMP55]]
+// CHECK1-NEXT:    [[ADD41:%.*]] = add i32 [[TMP50]], [[MUL40]]
+// CHECK1-NEXT:    store i32 [[ADD41]], ptr [[J]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -475,6 +503,48 @@ extern "C" void foo5() {
 // CHECK1-NEXT:    store i32 [[INC]], ptr [[DOTOMP_FUSE_INDEX]], align 4
 // CHECK1-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
 // CHECK1:       [[FOR_END]]:
+// CHECK1-NEXT:    [[TMP69:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[TMP70:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK1-NEXT:    [[TMP71:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB53:%.*]] = sub i32 [[TMP70]], [[TMP71]]
+// CHECK1-NEXT:    [[SUB54:%.*]] = sub i32 [[SUB53]], 1
+// CHECK1-NEXT:    [[TMP72:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[ADD55:%.*]] = add i32 [[SUB54]], [[TMP72]]
+// CHECK1-NEXT:    [[TMP73:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[DIV56:%.*]] = udiv i32 [[ADD55]], [[TMP73]]
+// CHECK1-NEXT:    [[SUB57:%.*]] = sub i32 [[DIV56]], 1
+// CHECK1-NEXT:    [[TMP74:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[MUL58:%.*]] = mul i32 [[SUB57]], [[TMP74]]
+// CHECK1-NEXT:    [[ADD59:%.*]] = add i32 [[TMP69]], [[MUL58]]
+// CHECK1-NEXT:    store i32 [[ADD59]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[TMP75:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
+// CHECK1-NEXT:    [[TMP76:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
+// CHECK1-NEXT:    [[TMP77:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_7]], align 4
+// CHECK1-NEXT:    [[SUB60:%.*]] = sub i32 [[TMP76]], [[TMP77]]
+// CHECK1-NEXT:    [[SUB61:%.*]] = sub i32 [[SUB60]], 1
+// CHECK1-NEXT:    [[TMP78:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
+// CHECK1-NEXT:    [[ADD62:%.*]] = add i32 [[SUB61]], [[TMP78]]
+// CHECK1-NEXT:    [[TMP79:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
+// CHECK1-NEXT:    [[DIV63:%.*]] = udiv i32 [[ADD62]], [[TMP79]]
+// CHECK1-NEXT:    [[SUB64:%.*]] = sub i32 [[DIV63]], 1
+// CHECK1-NEXT:    [[TMP80:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
+// CHECK1-NEXT:    [[MUL65:%.*]] = mul i32 [[SUB64]], [[TMP80]]
+// CHECK1-NEXT:    [[SUB66:%.*]] = sub i32 [[TMP75]], [[MUL65]]
+// CHECK1-NEXT:    store i32 [[SUB66]], ptr [[J]], align 4
+// CHECK1-NEXT:    [[TMP81:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_17]], align 4
+// CHECK1-NEXT:    [[TMP82:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_19]], align 4
+// CHECK1-NEXT:    [[TMP83:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_17]], align 4
+// CHECK1-NEXT:    [[SUB67:%.*]] = sub i32 [[TMP82]], [[TMP83]]
+// CHECK1-NEXT:    [[SUB68:%.*]] = sub i32 [[SUB67]], 1
+// CHECK1-NEXT:    [[TMP84:%.*]] = load i32, ptr [[DOTNEW_STEP21]], align 4
+// CHECK1-NEXT:    [[ADD69:%.*]] = add i32 [[SUB68]], [[TMP84]]
+// CHECK1-NEXT:    [[TMP85:%.*]] = load i32, ptr [[DOTNEW_STEP21]], align 4
+// CHECK1-NEXT:    [[DIV70:%.*]] = udiv i32 [[ADD69]], [[TMP85]]
+// CHECK1-NEXT:    [[SUB71:%.*]] = sub i32 [[DIV70]], 1
+// CHECK1-NEXT:    [[TMP86:%.*]] = load i32, ptr [[DOTNEW_STEP21]], align 4
+// CHECK1-NEXT:    [[MUL72:%.*]] = mul i32 [[SUB71]], [[TMP86]]
+// CHECK1-NEXT:    [[ADD73:%.*]] = add i32 [[TMP81]], [[MUL72]]
+// CHECK1-NEXT:    store i32 [[ADD73]], ptr [[K]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -922,6 +992,8 @@ extern "C" void foo5() {
 // CHECK1-NEXT:    store ptr [[INCDEC_PTR]], ptr [[__BEGIN2]], align 8
 // CHECK1-NEXT:    br label %[[FOR_COND19]]
 // CHECK1:       [[FOR_END23]]:
+// CHECK1-NEXT:    store i32 254, ptr [[J]], align 4
+// CHECK1-NEXT:    store i32 63, ptr [[K]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1193,6 +1265,13 @@ extern "C" void foo5() {
 // CHECK1-NEXT:    store ptr [[INCDEC_PTR]], ptr [[__BEGIN265]], align 8
 // CHECK1-NEXT:    br label %[[FOR_COND70]]
 // CHECK1:       [[FOR_END74]]:
+// CHECK1-NEXT:    [[TMP66:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB75:%.*]] = sub nsw i32 [[TMP66]], 0
+// CHECK1-NEXT:    [[DIV76:%.*]] = sdiv i32 [[SUB75]], 1
+// CHECK1-NEXT:    [[SUB77:%.*]] = sub nsw i32 [[DIV76]], 1
+// CHECK1-NEXT:    [[MUL78:%.*]] = mul nsw i32 [[SUB77]], 1
+// CHECK1-NEXT:    [[ADD79:%.*]] = add nsw i32 0, [[MUL78]]
+// CHECK1-NEXT:    store i32 [[ADD79]], ptr [[DOTOMP_FUSE_INDEX]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1356,6 +1435,34 @@ extern "C" void foo5() {
 // CHECK2-NEXT:    store i32 [[INC]], ptr [[DOTOMP_FUSE_INDEX]], align 4
 // CHECK2-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]]
 // CHECK2:       [[FOR_END]]:
+// CHECK2-NEXT:    [[TMP44:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[TMP45:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK2-NEXT:    [[TMP46:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB28:%.*]] = sub i32 [[TMP45]], [[TMP46]]
+// CHECK2-NEXT:    [[SUB29:%.*]] = sub i32 [[SUB28]], 1
+// CHECK2-NEXT:    [[TMP47:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[ADD30:%.*]] = add i32 [[SUB29]], [[TMP47]]
+// CHECK2-NEXT:    [[TMP48:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[DIV31:%.*]] = udiv i32 [[ADD30]], [[TMP48]]
+// CHECK2-NEXT:    [[SUB32:%.*]] = sub i32 [[DIV31]], 1
+// CHECK2-NEXT:    [[TMP49:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[MUL33:%.*]] = mul i32 [[SUB32]], [[TMP49]]
+// CHECK2-NEXT:    [[ADD34:%.*]] = add i32 [[TMP44]], [[MUL33]]
+// CHECK2-NEXT:    store i32 [[ADD34]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[TMP50:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
+// CHECK2-NEXT:    [[TMP51:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_7]], align 4
+// CHECK2-NEXT:    [[TMP52:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
+// CHECK2-NEXT:    [[SUB35:%.*]] = sub i32 [[TMP51]], [[TMP52]]
+// CHECK2-NEXT:    [[SUB36:%.*]] = sub i32 [[SUB35]], 1
+// CHECK2-NEXT:    [[TMP53:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
+// CHECK2-NEXT:    [[ADD37:%.*]] = add i32 [[SUB36]], [[TMP53]]
+// CHECK2-NEXT:    [[TMP54:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
+// CHECK2-NEXT:    [[DIV38:%.*]] = udiv i32 [[ADD37]], [[TMP54]]
+// CHECK2-NEXT:    [[SUB39:%.*]] = sub i32 [[DIV38]], 1
+// CHECK2-NEXT:    [[TMP55:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
+// CHECK2-NEXT:    [[MUL40:%.*]] = mul i32 [[SUB39]], [[TMP55]]
+// CHECK2-NEXT:    [[ADD41:%.*]] = add i32 [[TMP50]], [[MUL40]]
+// CHECK2-NEXT:    store i32 [[ADD41]], ptr [[J]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1803,6 +1910,8 @@ extern "C" void foo5() {
 // CHECK2-NEXT:    store ptr [[INCDEC_PTR]], ptr [[__BEGIN2]], align 8
 // CHECK2-NEXT:    br label %[[FOR_COND19]]
 // CHECK2:       [[FOR_END23]]:
+// CHECK2-NEXT:    store i32 254, ptr [[J]], align 4
+// CHECK2-NEXT:    store i32 63, ptr [[K]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2074,6 +2183,13 @@ extern "C" void foo5() {
 // CHECK2-NEXT:    store ptr [[INCDEC_PTR]], ptr [[__BEGIN265]], align 8
 // CHECK2-NEXT:    br label %[[FOR_COND70]]
 // CHECK2:       [[FOR_END74]]:
+// CHECK2-NEXT:    [[TMP66:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB75:%.*]] = sub nsw i32 [[TMP66]], 0
+// CHECK2-NEXT:    [[DIV76:%.*]] = sdiv i32 [[SUB75]], 1
+// CHECK2-NEXT:    [[SUB77:%.*]] = sub nsw i32 [[DIV76]], 1
+// CHECK2-NEXT:    [[MUL78:%.*]] = mul nsw i32 [[SUB77]], 1
+// CHECK2-NEXT:    [[ADD79:%.*]] = add nsw i32 0, [[MUL78]]
+// CHECK2-NEXT:    store i32 [[ADD79]], ptr [[DOTOMP_FUSE_INDEX]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2305,6 +2421,48 @@ extern "C" void foo5() {
 // CHECK2-NEXT:    store i32 [[INC]], ptr [[DOTOMP_FUSE_INDEX]], align 4
 // CHECK2-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP11:![0-9]+]]
 // CHECK2:       [[FOR_END]]:
+// CHECK2-NEXT:    [[TMP69:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[TMP70:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK2-NEXT:    [[TMP71:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB53:%.*]] = sub i32 [[TMP70]], [[TMP71]]
+// CHECK2-NEXT:    [[SUB54:%.*]] = sub i32 [[SUB53]], 1
+// CHECK2-NEXT:    [[TMP72:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[ADD55:%.*]] = add i32 [[SUB54]], [[TMP72]]
+// CHECK2-NEXT:    [[TMP73:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[DIV56:%.*]] = udiv i32 [[ADD55]], [[TMP73]]
+// CHECK2-NEXT:    [[SUB57:%.*]] = sub i32 [[DIV56]], 1
+// CHECK2-NEXT:    [[TMP74:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[MUL58:%.*]] = mul i32 [[SUB57]], [[TMP74]]
+// CHECK2-NEXT:    [[ADD59:%.*]] = add i32 [[TMP69]], [[MUL58]]
+// CHECK2-NEXT:    store i32 [[ADD59]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[TMP75:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
+// CHECK2-NEXT:    [[TMP76:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
+// CHECK2-NEXT:    [[TMP77:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_7]], align 4
+// CHECK2-NEXT:    [[SUB60:%.*]] = sub i32 [[TMP76]], [[TMP77]]
+// CHECK2-NEXT:    [[SUB61:%.*]] = sub i32 [[SUB60]], 1
+// CHECK2-NEXT:    [[TMP78:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
+// CHECK2-NEXT:    [[ADD62:%.*]] = add i32 [[SUB61]], [[TMP78]]
+// CHECK2-NEXT:    [[TMP79:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
+// CHECK2-NEXT:    [[DIV63:%.*]] = udiv i32 [[ADD62]], [[TMP79]]
+// CHECK2-NEXT:    [[SUB64:%.*]] = sub i32 [[DIV63]], 1
+// CHECK2-NEXT:    [[TMP80:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
+// CHECK2-NEXT:    [[MUL65:%.*]] = mul i32 [[SUB64]], [[TMP80]]
+// CHECK2-NEXT:    [[SUB66:%.*]] = sub i32 [[TMP75]], [[MUL65]]
+// CHECK2-NEXT:    store i32 [[SUB66]], ptr [[J]], align 4
+// CHECK2-NEXT:    [[TMP81:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_17]], align 4
+// CHECK2-NEXT:    [[TMP82:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_19]], align 4
+// CHECK2-NEXT:    [[TMP83:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_17]], align 4
+// CHECK2-NEXT:    [[SUB67:%.*]] = sub i32 [[TMP82]], [[TMP83]]
+// CHECK2-NEXT:    [[SUB68:%.*]] = sub i32 [[SUB67]], 1
+// CHECK2-NEXT:    [[TMP84:%.*]] = load i32, ptr [[DOTNEW_STEP21]], align 4
+// CHECK2-NEXT:    [[ADD69:%.*]] = add i32 [[SUB68]], [[TMP84]]
+// CHECK2-NEXT:    [[TMP85:%.*]] = load i32, ptr [[DOTNEW_STEP21]], align 4
+// CHECK2-NEXT:    [[DIV70:%.*]] = udiv i32 [[ADD69]], [[TMP85]]
+// CHECK2-NEXT:    [[SUB71:%.*]] = sub i32 [[DIV70]], 1
+// CHECK2-NEXT:    [[TMP86:%.*]] = load i32, ptr [[DOTNEW_STEP21]], align 4
+// CHECK2-NEXT:    [[MUL72:%.*]] = mul i32 [[SUB71]], [[TMP86]]
+// CHECK2-NEXT:    [[ADD73:%.*]] = add i32 [[TMP81]], [[MUL72]]
+// CHECK2-NEXT:    store i32 [[ADD73]], ptr [[K]], align 4
 // CHECK2-NEXT:    ret void
 //
 //.
diff --git a/clang/test/OpenMP/loop_transform_iv.c b/clang/test/OpenMP/loop_transform_iv.c
new file mode 100644
index 0000000000000..4ecaeecb9a174
--- /dev/null
+++ b/clang/test/OpenMP/loop_transform_iv.c
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -emit-llvm %s -o - | FileCheck %s
+// expected-no-diagnostics
+
+// Test that loop variables are correctly finalized after loop-transformation
+// constructs as required by OpenMP 6.0 spec (pg 371, lines 19-21).
+
+void test_tile(void) {
+  // CHECK-LABEL: define {{.*}} @test_tile
+  int i;
+  #pragma omp tile sizes(2)
+  for (i = 1; i <= 10; i++) {
+  }
+  // CHECK: store i32 10, ptr %i
+  // After loop: i should be 10 (last iteration value per OpenMP 6.0 spec)
+}
+
+void test_stripe(void) {
+  // CHECK-LABEL: define {{.*}} @test_stripe
+  int i;
+  #pragma omp stripe sizes(3)
+  for (i = 0; i < 10; i++) {
+  }
+  // CHECK: store i32 9, ptr %i
+  // After loop: i should be 9 (last iteration value per OpenMP 6.0 spec)
+}
+
+void test_tile_nested(void) {
+  // CHECK-LABEL: define {{.*}} @test_tile_nested
+  int i, j;
+  #pragma omp tile sizes(2, 3)
+  for (i = 0; i < 10; i++)
+    for (j = 0; j < 5; j++) {
+    }
+  // CHECK: store i32 9, ptr %i
+  // CHECK: store i32 4, ptr %j
+  // After loop: i should be 9, j should be 4 (last iteration values per OpenMP 6.0 spec)
+}
+
+void test_tile_stride(void) {
+  // CHECK-LABEL: define {{.*}} @test_tile_stride
+  int i;
+  #pragma omp tile sizes(4)
+  for (i = 5; i <= 15; i += 2) {
+  }
+  // CHECK: store i32 15, ptr %i
+  // After loop: i should be 15 (last iteration value per OpenMP 6.0 spec)
+}
+
+void test_tile_variable_bound(int n) {
+  // CHECK-LABEL: define {{.*}} @test_tile_variable_bound
+  int i;
+  #pragma omp tile sizes(3)
+  for (i = 0; i < n; i++) {
+  }
+  // CHECK: for.end14:
+  // CHECK-NEXT: %[[NUMITER:.*]] = load i32, ptr %.capture_expr.
+  // CHECK-NEXT: %[[SUB1:.*]] = sub nsw i32 %[[NUMITER]], 0
+  // CHECK-NEXT: %[[DIV:.*]] = sdiv i32 %[[SUB1]], 1
+  // CHECK-NEXT: %[[LASTITER:.*]] = sub nsw i32 %[[DIV]], 1
+  // CHECK-NEXT: %[[MUL:.*]] = mul nsw i32 %[[LASTITER]], 1
+  // CHECK-NEXT: %[[FINAL:.*]] = add nsw i32 0, %[[MUL]]
+  // CHECK-NEXT: store i32 %[[FINAL]], ptr %i
+  // After loop: i should equal n-1 (last iteration value per OpenMP 6.0 spec)
+}
+
+void test_reverse(void) {
+  // CHECK-LABEL: define {{.*}} @test_reverse
+  int i;
+  #pragma omp reverse
+  for (i = 0; i < 10; i++) {
+  }
+  // CHECK: store i32 9, ptr %i
+  // After loop: i should be 9 (last iteration value per OpenMP 6.0 spec)
+}
+
+void test_interchange(void) {
+  // CHECK-LABEL: define {{.*}} @test_interchange
+  int i, j;
+  #pragma omp interchange permutation(2, 1)
+  for (i = 0; i < 10; i++)
+    for (j = 0; j < 5; j++) {
+    }
+  // CHECK: store i32 9, ptr %i
+  // CHECK: store i32 4, ptr %j
+  // After loop: i should be 9, j should be 4 (last iteration values per OpenMP 6.0 spec)
+}
+
+void test_for_workshare(void) {
+  // CHECK-LABEL: define {{.*}} @test_for_workshare
+  int i;
+  #pragma omp for
+  for (i = 5; i <= 10; i += 2) {
+  }
+  // CHECK: omp.loop.exit:
+  // CHECK-NEXT: call void @__kmpc_for_static_fini
+  // CHECK-NEXT: call void @__kmpc_barrier
+  // CHECK-NEXT: ret void
+  // omp for worksharing doesn't finalize the loop variable after the loop
+}
+
+void test_for_lastprivate(void) {
+  // CHECK-LABEL: define {{.*}} @test_for_lastprivate
+  int i;
+  #pragma omp parallel
+  #pragma omp for lastprivate(i)
+  for (i = 5; i <= 10; i += 2) {
+  }
+  // CHECK: .omp.lastprivate.then:
+  // CHECK-NEXT: store i32 11, ptr %i{{.*}}, align 4
+  // CHECK-NEXT: %{{.*}} = load i32, ptr %i{{.*}}, align 4
+  // CHECK-NEXT: store i32 %{{.*}}, ptr %{{.*}}, align 4
+  // omp for with lastprivate DOES finalize the loop variable
+  // i = last_iteration_value + stride = 9 + 2 = 11
+}
+
+void test_tile_workshare(void) {
+  // CHECK-LABEL: define {{.*}} @test_tile_workshare
+  int i;
+  #pragma omp for
+  #pragma omp tile sizes(2)
+  for (i = 1; i <= 10; i++) {
+  }
+  // CHECK: omp.loop.exit:
+  // CHECK-NOT: store {{.*}}, ptr %i
+  // CHECK: call void @__kmpc_for_static_fini
+  // i is private to the `for` construct; its post-loop value is
+  // unspecified here (same as plain omp-for), so no restoring store
+  // is expected for i after omp.loop.exit.
+}
diff --git a/clang/test/OpenMP/reverse_codegen.cpp b/clang/test/OpenMP/reverse_codegen.cpp
index b4720d5d19d87..66febceaaea14 100644
--- a/clang/test/OpenMP/reverse_codegen.cpp
+++ b/clang/test/OpenMP/reverse_codegen.cpp
@@ -1,1555 +1,1609 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _
-
-// expected-no-diagnostics
-
-// Check code generation
-// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -std=c++20 -fclang-abi-compat=latest -fopenmp -fopenmp-version=60 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1
-
-// Check same results after serialization round-trip
-// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -std=c++20 -fclang-abi-compat=latest -fopenmp -fopenmp-version=60 -emit-pch -o %t %s
-// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -std=c++20 -fclang-abi-compat=latest -fopenmp -fopenmp-version=60 -include-pch %t -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK2
-
-#ifndef HEADER
-#define HEADER
-
-// placeholder for loop body code.
-extern "C" void body(...) {}
-
-
-struct S {
-  int i;
-  S() {
-#pragma omp reverse
-    for (i = 7; i < 17; i += 3)
-      body(i);
-  }
-} s;
-
-
-extern "C" void foo1(int start, int end, int step) {
-  int i;
-#pragma omp reverse
-  for (i = start; i < end; i += step)
-    body(i);
-}
-
-
-extern "C" void foo2() {
-#pragma omp for
-#pragma omp reverse
-    for (int i = 7; i < 17; i += 3)
-        body(i);
-}
-
-
-extern "C" void foo3() {
-#pragma omp for collapse(3)
-  for (int k = 7; k < 17; k += 3)
-#pragma omp reverse
-    for (int i = 7; i < 17; i += 3)
-      for (int j = 7; j < 17; j += 3)
-        body(k, i, j);
-}
-
-
-extern "C" void foo4() {
-#pragma omp parallel for
-#pragma omp reverse
-  for (int i = 7; i < 17; i += 3)
-    body(i);
-}
-
-
-template<typename T, T Step>
-void foo5(T start, T end) {
-#pragma omp reverse
-  for (T i = start; i < end; i += Step)
-    body(i);
-}
-
-extern "C" void tfoo5() {
-  foo5<int,3>(0, 42);
-}
-
-
-extern "C" void foo6() {
-  double arr[128];
-#pragma omp reverse
-  for (int c = 42; auto && v : arr)
-    body(v, c);
-}
-
-
-extern "C" void foo7() {
-  double A[128];
-
-#pragma omp for collapse(3)
-  for (int k = 7; k < 17; k += 3)
-#pragma omp reverse
-    for (int c = 42; auto && v : A)
-      for (int j = 7; j < 17; j += 3)
-        body(k, c, v, j);
-}
-
-#endif /* HEADER */
-
-
-// CHECK1-LABEL: define {{[^@]+}}@body
-// CHECK1-SAME: (...) #[[ATTR0:[0-9]+]] {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    ret void
-//
-//
-// CHECK1-LABEL: define {{[^@]+}}@__cxx_global_var_init
-// CHECK1-SAME: () #[[ATTR1:[0-9]+]] section ".text.startup" {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    call void @_ZN1SC1Ev(ptr noundef nonnull align 4 dereferenceable(4) @s)
-// CHECK1-NEXT:    ret void
-//
-//
-// CHECK1-LABEL: define {{[^@]+}}@_ZN1SC1Ev
-// CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
-// CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
-// CHECK1-NEXT:    call void @_ZN1SC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]])
-// CHECK1-NEXT:    ret void
-//
-//
-// CHECK1-LABEL: define {{[^@]+}}@_ZN1SC2Ev
-// CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[I2:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
-// CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
-// CHECK1-NEXT:    [[I:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0
-// CHECK1-NEXT:    store i32 7, ptr [[I]], align 4
-// CHECK1-NEXT:    [[I3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0
-// CHECK1-NEXT:    store ptr [[I3]], ptr [[I2]], align 8
-// CHECK1-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    br label [[FOR_COND:%.*]]
-// CHECK1:       for.cond:
-// CHECK1-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 4
-// CHECK1-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
-// CHECK1:       for.body:
-// CHECK1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    [[SUB:%.*]] = sub nsw i32 3, [[TMP1]]
-// CHECK1-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK1-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK1-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], 3
-// CHECK1-NEXT:    [[ADD:%.*]] = add nsw i32 7, [[MUL]]
-// CHECK1-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2:![0-9]+]], !align [[META3:![0-9]+]]
-// CHECK1-NEXT:    store i32 [[ADD]], ptr [[TMP3]], align 4
-// CHECK1-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
-// CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4
-// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP5]])
-// CHECK1-NEXT:    br label [[FOR_INC:%.*]]
-// CHECK1:       for.inc:
-// CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
-// CHECK1-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
-// CHECK1:       for.end:
-// CHECK1-NEXT:    ret void
-//
-//
-// CHECK1-LABEL: define {{[^@]+}}@foo1
-// CHECK1-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]], i32 noundef [[STEP:%.*]]) #[[ATTR0]] {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    [[START_ADDR:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[END_ADDR:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[STEP_ADDR:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTNEW_STEP:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    store i32 [[START]], ptr [[START_ADDR]], align 4
-// CHECK1-NEXT:    store i32 [[END]], ptr [[END_ADDR]], align 4
-// CHECK1-NEXT:    store i32 [[STEP]], ptr [[STEP_ADDR]], align 4
-// CHECK1-NEXT:    [[TMP0:%.*]] = load i32, ptr [[START_ADDR]], align 4
-// CHECK1-NEXT:    store i32 [[TMP0]], ptr [[I]], align 4
-// CHECK1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[START_ADDR]], align 4
-// CHECK1-NEXT:    store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4
-// CHECK1-NEXT:    [[TMP2:%.*]] = load i32, ptr [[END_ADDR]], align 4
-// CHECK1-NEXT:    store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
-// CHECK1-NEXT:    [[TMP3:%.*]] = load i32, ptr [[STEP_ADDR]], align 4
-// CHECK1-NEXT:    store i32 [[TMP3]], ptr [[DOTNEW_STEP]], align 4
-// CHECK1-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
-// CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
-// CHECK1-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], [[TMP5]]
-// CHECK1-NEXT:    [[SUB3:%.*]] = sub i32 [[SUB]], 1
-// CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK1-NEXT:    [[ADD:%.*]] = add i32 [[SUB3]], [[TMP6]]
-// CHECK1-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK1-NEXT:    [[DIV:%.*]] = udiv i32 [[ADD]], [[TMP7]]
-// CHECK1-NEXT:    [[SUB4:%.*]] = sub i32 [[DIV]], 1
-// CHECK1-NEXT:    store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4
-// CHECK1-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    br label [[FOR_COND:%.*]]
-// CHECK1:       for.cond:
-// CHECK1-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
-// CHECK1-NEXT:    [[ADD5:%.*]] = add i32 [[TMP9]], 1
-// CHECK1-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP8]], [[ADD5]]
-// CHECK1-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
-// CHECK1:       for.body:
-// CHECK1-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
-// CHECK1-NEXT:    [[ADD6:%.*]] = add i32 [[TMP10]], 1
-// CHECK1-NEXT:    [[SUB7:%.*]] = sub i32 [[ADD6]], 1
-// CHECK1-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    [[SUB8:%.*]] = sub i32 [[SUB7]], [[TMP11]]
-// CHECK1-NEXT:    store i32 [[SUB8]], ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK1-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
-// CHECK1-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK1-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK1-NEXT:    [[MUL:%.*]] = mul i32 [[TMP13]], [[TMP14]]
-// CHECK1-NEXT:    [[ADD9:%.*]] = add i32 [[TMP12]], [[MUL]]
-// CHECK1-NEXT:    store i32 [[ADD9]], ptr [[I]], align 4
-// CHECK1-NEXT:    [[TMP15:%.*]] = load i32, ptr [[I]], align 4
-// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP15]])
-// CHECK1-NEXT:    br label [[FOR_INC:%.*]]
-// CHECK1:       for.inc:
-// CHECK1-NEXT:    [[TMP16:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    [[INC:%.*]] = add i32 [[TMP16]], 1
-// CHECK1-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
-// CHECK1:       for.end:
-// CHECK1-NEXT:    ret void
-//
-//
-// CHECK1-LABEL: define {{[^@]+}}@foo2
-// CHECK1-SAME: () #[[ATTR0]] {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[TMP:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:[0-9]+]])
-// CHECK1-NEXT:    store i32 7, ptr [[I]], align 4
-// CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
-// CHECK1-NEXT:    store i32 3, ptr [[DOTOMP_UB]], align 4
-// CHECK1-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
-// CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
-// CHECK1-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
-// CHECK1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK1-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 3
-// CHECK1-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
-// CHECK1:       cond.true:
-// CHECK1-NEXT:    br label [[COND_END:%.*]]
-// CHECK1:       cond.false:
-// CHECK1-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK1-NEXT:    br label [[COND_END]]
-// CHECK1:       cond.end:
-// CHECK1-NEXT:    [[COND:%.*]] = phi i32 [ 3, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ]
-// CHECK1-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
-// CHECK1-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
-// CHECK1-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
-// CHECK1:       omp.inner.for.cond:
-// CHECK1-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK1-NEXT:    [[CMP1:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]]
-// CHECK1-NEXT:    br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
-// CHECK1:       omp.inner.for.body:
-// CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP6]], 1
-// CHECK1-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK1-NEXT:    store i32 [[ADD]], ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    [[SUB:%.*]] = sub nsw i32 3, [[TMP7]]
-// CHECK1-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK1-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK1-NEXT:    [[MUL2:%.*]] = mul nsw i32 [[TMP8]], 3
-// CHECK1-NEXT:    [[ADD3:%.*]] = add nsw i32 7, [[MUL2]]
-// CHECK1-NEXT:    store i32 [[ADD3]], ptr [[I]], align 4
-// CHECK1-NEXT:    [[TMP9:%.*]] = load i32, ptr [[I]], align 4
-// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP9]])
-// CHECK1-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
-// CHECK1:       omp.body.continue:
-// CHECK1-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
-// CHECK1:       omp.inner.for.inc:
-// CHECK1-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    [[ADD4:%.*]] = add nsw i32 [[TMP10]], 1
-// CHECK1-NEXT:    store i32 [[ADD4]], ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND]]
-// CHECK1:       omp.inner.for.end:
-// CHECK1-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
-// CHECK1:       omp.loop.exit:
-// CHECK1-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
-// CHECK1-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3:[0-9]+]], i32 [[TMP0]])
-// CHECK1-NEXT:    ret void
-//
-//
-// CHECK1-LABEL: define {{[^@]+}}@foo3
-// CHECK1-SAME: () #[[ATTR0]] {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[TMP:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[_TMP1:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[_TMP2:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[K:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[J:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
-// CHECK1-NEXT:    store i32 7, ptr [[I]], align 4
-// CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
-// CHECK1-NEXT:    store i32 63, ptr [[DOTOMP_UB]], align 4
-// CHECK1-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
-// CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
-// CHECK1-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
-// CHECK1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK1-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 63
-// CHECK1-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
-// CHECK1:       cond.true:
-// CHECK1-NEXT:    br label [[COND_END:%.*]]
-// CHECK1:       cond.false:
-// CHECK1-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK1-NEXT:    br label [[COND_END]]
-// CHECK1:       cond.end:
-// CHECK1-NEXT:    [[COND:%.*]] = phi i32 [ 63, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ]
-// CHECK1-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
-// CHECK1-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
-// CHECK1-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
-// CHECK1:       omp.inner.for.cond:
-// CHECK1-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK1-NEXT:    [[CMP3:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]]
-// CHECK1-NEXT:    br i1 [[CMP3]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
-// CHECK1:       omp.inner.for.body:
-// CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    [[DIV:%.*]] = sdiv i32 [[TMP6]], 16
-// CHECK1-NEXT:    [[MUL:%.*]] = mul nsw i32 [[DIV]], 3
-// CHECK1-NEXT:    [[ADD:%.*]] = add nsw i32 7, [[MUL]]
-// CHECK1-NEXT:    store i32 [[ADD]], ptr [[K]], align 4
-// CHECK1-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    [[DIV4:%.*]] = sdiv i32 [[TMP8]], 16
-// CHECK1-NEXT:    [[MUL5:%.*]] = mul nsw i32 [[DIV4]], 16
-// CHECK1-NEXT:    [[SUB:%.*]] = sub nsw i32 [[TMP7]], [[MUL5]]
-// CHECK1-NEXT:    [[DIV6:%.*]] = sdiv i32 [[SUB]], 4
-// CHECK1-NEXT:    [[MUL7:%.*]] = mul nsw i32 [[DIV6]], 1
-// CHECK1-NEXT:    [[ADD8:%.*]] = add nsw i32 0, [[MUL7]]
-// CHECK1-NEXT:    store i32 [[ADD8]], ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    [[DIV9:%.*]] = sdiv i32 [[TMP10]], 16
-// CHECK1-NEXT:    [[MUL10:%.*]] = mul nsw i32 [[DIV9]], 16
-// CHECK1-NEXT:    [[SUB11:%.*]] = sub nsw i32 [[TMP9]], [[MUL10]]
-// CHECK1-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    [[DIV12:%.*]] = sdiv i32 [[TMP12]], 16
-// CHECK1-NEXT:    [[MUL13:%.*]] = mul nsw i32 [[DIV12]], 16
-// CHECK1-NEXT:    [[SUB14:%.*]] = sub nsw i32 [[TMP11]], [[MUL13]]
-// CHECK1-NEXT:    [[DIV15:%.*]] = sdiv i32 [[SUB14]], 4
-// CHECK1-NEXT:    [[MUL16:%.*]] = mul nsw i32 [[DIV15]], 4
-// CHECK1-NEXT:    [[SUB17:%.*]] = sub nsw i32 [[SUB11]], [[MUL16]]
-// CHECK1-NEXT:    [[MUL18:%.*]] = mul nsw i32 [[SUB17]], 3
-// CHECK1-NEXT:    [[ADD19:%.*]] = add nsw i32 7, [[MUL18]]
-// CHECK1-NEXT:    store i32 [[ADD19]], ptr [[J]], align 4
-// CHECK1-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    [[SUB20:%.*]] = sub nsw i32 3, [[TMP13]]
-// CHECK1-NEXT:    store i32 [[SUB20]], ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK1-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK1-NEXT:    [[MUL21:%.*]] = mul nsw i32 [[TMP14]], 3
-// CHECK1-NEXT:    [[ADD22:%.*]] = add nsw i32 7, [[MUL21]]
-// CHECK1-NEXT:    store i32 [[ADD22]], ptr [[I]], align 4
-// CHECK1-NEXT:    [[TMP15:%.*]] = load i32, ptr [[K]], align 4
-// CHECK1-NEXT:    [[TMP16:%.*]] = load i32, ptr [[I]], align 4
-// CHECK1-NEXT:    [[TMP17:%.*]] = load i32, ptr [[J]], align 4
-// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP15]], i32 noundef [[TMP16]], i32 noundef [[TMP17]])
-// CHECK1-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
-// CHECK1:       omp.body.continue:
-// CHECK1-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
-// CHECK1:       omp.inner.for.inc:
-// CHECK1-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    [[ADD23:%.*]] = add nsw i32 [[TMP18]], 1
-// CHECK1-NEXT:    store i32 [[ADD23]], ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND]]
-// CHECK1:       omp.inner.for.end:
-// CHECK1-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
-// CHECK1:       omp.loop.exit:
-// CHECK1-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
-// CHECK1-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]])
-// CHECK1-NEXT:    ret void
-//
-//
-// CHECK1-LABEL: define {{[^@]+}}@foo4
-// CHECK1-SAME: () #[[ATTR0]] {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 0, ptr @foo4.omp_outlined)
-// CHECK1-NEXT:    ret void
-//
-//
-// CHECK1-LABEL: define {{[^@]+}}@foo4.omp_outlined
-// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR4:[0-9]+]] {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[TMP:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
-// CHECK1-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
-// CHECK1-NEXT:    store i32 7, ptr [[I]], align 4
-// CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
-// CHECK1-NEXT:    store i32 3, ptr [[DOTOMP_UB]], align 4
-// CHECK1-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
-// CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
-// CHECK1-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
-// CHECK1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4
-// CHECK1-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
-// CHECK1-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK1-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 3
-// CHECK1-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
-// CHECK1:       cond.true:
-// CHECK1-NEXT:    br label [[COND_END:%.*]]
-// CHECK1:       cond.false:
-// CHECK1-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK1-NEXT:    br label [[COND_END]]
-// CHECK1:       cond.end:
-// CHECK1-NEXT:    [[COND:%.*]] = phi i32 [ 3, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ]
-// CHECK1-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
-// CHECK1-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
-// CHECK1-NEXT:    store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
-// CHECK1:       omp.inner.for.cond:
-// CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK1-NEXT:    [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]]
-// CHECK1-NEXT:    br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
-// CHECK1:       omp.inner.for.body:
-// CHECK1-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1
-// CHECK1-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK1-NEXT:    store i32 [[ADD]], ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    [[SUB:%.*]] = sub nsw i32 3, [[TMP8]]
-// CHECK1-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK1-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK1-NEXT:    [[MUL2:%.*]] = mul nsw i32 [[TMP9]], 3
-// CHECK1-NEXT:    [[ADD3:%.*]] = add nsw i32 7, [[MUL2]]
-// CHECK1-NEXT:    store i32 [[ADD3]], ptr [[I]], align 4
-// CHECK1-NEXT:    [[TMP10:%.*]] = load i32, ptr [[I]], align 4
-// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP10]])
-// CHECK1-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
-// CHECK1:       omp.body.continue:
-// CHECK1-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
-// CHECK1:       omp.inner.for.inc:
-// CHECK1-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    [[ADD4:%.*]] = add nsw i32 [[TMP11]], 1
-// CHECK1-NEXT:    store i32 [[ADD4]], ptr [[DOTOMP_IV]], align 4
-// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND]]
-// CHECK1:       omp.inner.for.end:
-// CHECK1-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
-// CHECK1:       omp.loop.exit:
-// CHECK1-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]])
-// CHECK1-NEXT:    ret void
-//
-//
-// CHECK1-LABEL: define {{[^@]+}}@tfoo5
-// CHECK1-SAME: () #[[ATTR0]] {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    call void @_Z4foo5IiTnT_Li3EEvS0_S0_(i32 noundef 0, i32 noundef 42)
-// CHECK1-NEXT:    ret void
-//
-//
-// CHECK1-LABEL: define {{[^@]+}}@_Z4foo5IiTnT_Li3EEvS0_S0_
-// CHECK1-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]]) #[[ATTR0]] comdat {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    [[START_ADDR:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[END_ADDR:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    store i32 [[START]], ptr [[START_ADDR]], align 4
-// CHECK1-NEXT:    store i32 [[END]], ptr [[END_ADDR]], align 4
-// CHECK1-NEXT:    [[TMP0:%.*]] = load i32, ptr [[START_ADDR]], align 4
-// CHECK1-NEXT:    store i32 [[TMP0]], ptr [[I]], align 4
-// CHECK1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[START_ADDR]], align 4
-// CHECK1-NEXT:    store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4
-// CHECK1-NEXT:    [[TMP2:%.*]] = load i32, ptr [[END_ADDR]], align 4
-// CHECK1-NEXT:    store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
-// CHECK1-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
-// CHECK1-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
-// CHECK1-NEXT:    [[SUB:%.*]] = sub i32 [[TMP3]], [[TMP4]]
-// CHECK1-NEXT:    [[SUB3:%.*]] = sub i32 [[SUB]], 1
-// CHECK1-NEXT:    [[ADD:%.*]] = add i32 [[SUB3]], 3
-// CHECK1-NEXT:    [[DIV:%.*]] = udiv i32 [[ADD]], 3
-// CHECK1-NEXT:    [[SUB4:%.*]] = sub i32 [[DIV]], 1
-// CHECK1-NEXT:    store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4
-// CHECK1-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    br label [[FOR_COND:%.*]]
-// CHECK1:       for.cond:
-// CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
-// CHECK1-NEXT:    [[ADD5:%.*]] = add i32 [[TMP6]], 1
-// CHECK1-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP5]], [[ADD5]]
-// CHECK1-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
-// CHECK1:       for.body:
-// CHECK1-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
-// CHECK1-NEXT:    [[ADD6:%.*]] = add i32 [[TMP7]], 1
-// CHECK1-NEXT:    [[SUB7:%.*]] = sub i32 [[ADD6]], 1
-// CHECK1-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    [[SUB8:%.*]] = sub i32 [[SUB7]], [[TMP8]]
-// CHECK1-NEXT:    store i32 [[SUB8]], ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK1-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
-// CHECK1-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK1-NEXT:    [[MUL:%.*]] = mul i32 [[TMP10]], 3
-// CHECK1-NEXT:    [[ADD9:%.*]] = add i32 [[TMP9]], [[MUL]]
-// CHECK1-NEXT:    store i32 [[ADD9]], ptr [[I]], align 4
-// CHECK1-NEXT:    [[TMP11:%.*]] = load i32, ptr [[I]], align 4
-// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP11]])
-// CHECK1-NEXT:    br label [[FOR_INC:%.*]]
-// CHECK1:       for.inc:
-// CHECK1-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    [[INC:%.*]] = add i32 [[TMP12]], 1
-// CHECK1-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]]
-// CHECK1:       for.end:
-// CHECK1-NEXT:    ret void
-//
-//
-// CHECK1-LABEL: define {{[^@]+}}@foo6
-// CHECK1-SAME: () #[[ATTR0]] {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    [[ARR:%.*]] = alloca [128 x double], align 16
-// CHECK1-NEXT:    [[C:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[__RANGE2:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[__END2:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[__BEGIN2:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_3:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8
-// CHECK1-NEXT:    [[DOTFORWARD_IV___BEGIN2:%.*]] = alloca i64, align 8
-// CHECK1-NEXT:    [[DOTREVERSED_IV___BEGIN2:%.*]] = alloca i64, align 8
-// CHECK1-NEXT:    [[V:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    store i32 42, ptr [[C]], align 4
-// CHECK1-NEXT:    store ptr [[ARR]], ptr [[__RANGE2]], align 8
-// CHECK1-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[__RANGE2]], align 8, !nonnull [[META2]], !align [[META10:![0-9]+]]
-// CHECK1-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP0]], i64 0, i64 0
-// CHECK1-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128
-// CHECK1-NEXT:    store ptr [[ADD_PTR]], ptr [[__END2]], align 8
-// CHECK1-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[__RANGE2]], align 8, !nonnull [[META2]], !align [[META10]]
-// CHECK1-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0
-// CHECK1-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[__BEGIN2]], align 8
-// CHECK1-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[__RANGE2]], align 8, !nonnull [[META2]], !align [[META10]]
-// CHECK1-NEXT:    [[ARRAYDECAY2:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0
-// CHECK1-NEXT:    store ptr [[ARRAYDECAY2]], ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK1-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[__END2]], align 8
-// CHECK1-NEXT:    store ptr [[TMP3]], ptr [[DOTCAPTURE_EXPR_3]], align 8
-// CHECK1-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_3]], align 8
-// CHECK1-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK1-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP4]] to i64
-// CHECK1-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP5]] to i64
-// CHECK1-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
-// CHECK1-NEXT:    [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8
-// CHECK1-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1
-// CHECK1-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
-// CHECK1-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
-// CHECK1-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
-// CHECK1-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8
-// CHECK1-NEXT:    store i64 0, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
-// CHECK1-NEXT:    br label [[FOR_COND:%.*]]
-// CHECK1:       for.cond:
-// CHECK1-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
-// CHECK1-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
-// CHECK1-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP7]], 1
-// CHECK1-NEXT:    [[CMP:%.*]] = icmp slt i64 [[TMP6]], [[ADD6]]
-// CHECK1-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
-// CHECK1:       for.body:
-// CHECK1-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
-// CHECK1-NEXT:    [[ADD7:%.*]] = add nsw i64 [[TMP8]], 1
-// CHECK1-NEXT:    [[SUB8:%.*]] = sub nsw i64 [[ADD7]], 1
-// CHECK1-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
-// CHECK1-NEXT:    [[SUB9:%.*]] = sub nsw i64 [[SUB8]], [[TMP9]]
-// CHECK1-NEXT:    store i64 [[SUB9]], ptr [[DOTREVERSED_IV___BEGIN2]], align 8
-// CHECK1-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK1-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTREVERSED_IV___BEGIN2]], align 8
-// CHECK1-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP11]], 1
-// CHECK1-NEXT:    [[ADD_PTR10:%.*]] = getelementptr inbounds double, ptr [[TMP10]], i64 [[MUL]]
-// CHECK1-NEXT:    store ptr [[ADD_PTR10]], ptr [[__BEGIN2]], align 8
-// CHECK1-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[__BEGIN2]], align 8
-// CHECK1-NEXT:    store ptr [[TMP12]], ptr [[V]], align 8
-// CHECK1-NEXT:    [[TMP13:%.*]] = load ptr, ptr [[V]], align 8, !nonnull [[META2]], !align [[META10]]
-// CHECK1-NEXT:    [[TMP14:%.*]] = load double, ptr [[TMP13]], align 8
-// CHECK1-NEXT:    [[TMP15:%.*]] = load i32, ptr [[C]], align 4
-// CHECK1-NEXT:    call void (...) @body(double noundef [[TMP14]], i32 noundef [[TMP15]])
-// CHECK1-NEXT:    br label [[FOR_INC:%.*]]
-// CHECK1:       for.inc:
-// CHECK1-NEXT:    [[TMP16:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
-// CHECK1-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP16]], 1
-// CHECK1-NEXT:    store i64 [[INC]], ptr [[DOTFORWARD_IV___BEGIN2]], align 8
-// CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP11:![0-9]+]]
-// CHECK1:       for.end:
-// CHECK1-NEXT:    ret void
-//
-//
-// CHECK1-LABEL: define {{[^@]+}}@foo7
-// CHECK1-SAME: () #[[ATTR0]] {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    [[A:%.*]] = alloca [128 x double], align 16
-// CHECK1-NEXT:    [[DOTOMP_IV:%.*]] = alloca i64, align 8
-// CHECK1-NEXT:    [[TMP:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[_TMP1:%.*]] = alloca i64, align 8
-// CHECK1-NEXT:    [[_TMP2:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[C:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[__RANGE3:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[__END3:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[__BEGIN3:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_5:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_6:%.*]] = alloca i64, align 8
-// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_8:%.*]] = alloca i64, align 8
-// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_10:%.*]] = alloca i64, align 8
-// CHECK1-NEXT:    [[K:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTFORWARD_IV___BEGIN3:%.*]] = alloca i64, align 8
-// CHECK1-NEXT:    [[J:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTOMP_LB:%.*]] = alloca i64, align 8
-// CHECK1-NEXT:    [[DOTOMP_UB:%.*]] = alloca i64, align 8
-// CHECK1-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i64, align 8
-// CHECK1-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[K15:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTFORWARD_IV___BEGIN316:%.*]] = alloca i64, align 8
-// CHECK1-NEXT:    [[J17:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[DOTREVERSED_IV___BEGIN3:%.*]] = alloca i64, align 8
-// CHECK1-NEXT:    [[V:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
-// CHECK1-NEXT:    store i32 42, ptr [[C]], align 4
-// CHECK1-NEXT:    store ptr [[A]], ptr [[__RANGE3]], align 8
-// CHECK1-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[__RANGE3]], align 8, !nonnull [[META2]], !align [[META10]]
-// CHECK1-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0
-// CHECK1-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128
-// CHECK1-NEXT:    store ptr [[ADD_PTR]], ptr [[__END3]], align 8
-// CHECK1-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[__RANGE3]], align 8, !nonnull [[META2]], !align [[META10]]
-// CHECK1-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0
-// CHECK1-NEXT:    store ptr [[ARRAYDECAY3]], ptr [[__BEGIN3]], align 8
-// CHECK1-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[__RANGE3]], align 8, !nonnull [[META2]], !align [[META10]]
-// CHECK1-NEXT:    [[ARRAYDECAY4:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP3]], i64 0, i64 0
-// CHECK1-NEXT:    store ptr [[ARRAYDECAY4]], ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK1-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[__END3]], align 8
-// CHECK1-NEXT:    store ptr [[TMP4]], ptr [[DOTCAPTURE_EXPR_5]], align 8
-// CHECK1-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_5]], align 8
-// CHECK1-NEXT:    [[TMP6:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK1-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP5]] to i64
-// CHECK1-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP6]] to i64
-// CHECK1-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
-// CHECK1-NEXT:    [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8
-// CHECK1-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1
-// CHECK1-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
-// CHECK1-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
-// CHECK1-NEXT:    [[SUB7:%.*]] = sub nsw i64 [[DIV]], 1
-// CHECK1-NEXT:    store i64 [[SUB7]], ptr [[DOTCAPTURE_EXPR_6]], align 8
-// CHECK1-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_6]], align 8
-// CHECK1-NEXT:    [[ADD9:%.*]] = add nsw i64 [[TMP7]], 1
-// CHECK1-NEXT:    store i64 [[ADD9]], ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK1-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK1-NEXT:    [[SUB11:%.*]] = sub nsw i64 [[TMP8]], 0
-// CHECK1-NEXT:    [[DIV12:%.*]] = sdiv i64 [[SUB11]], 1
-// CHECK1-NEXT:    [[MUL:%.*]] = mul nsw i64 4, [[DIV12]]
-// CHECK1-NEXT:    [[MUL13:%.*]] = mul nsw i64 [[MUL]], 4
-// CHECK1-NEXT:    [[SUB14:%.*]] = sub nsw i64 [[MUL13]], 1
-// CHECK1-NEXT:    store i64 [[SUB14]], ptr [[DOTCAPTURE_EXPR_10]], align 8
-// CHECK1-NEXT:    store i32 7, ptr [[K]], align 4
-// CHECK1-NEXT:    store i64 0, ptr [[DOTFORWARD_IV___BEGIN3]], align 8
-// CHECK1-NEXT:    store i32 7, ptr [[J]], align 4
-// CHECK1-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK1-NEXT:    [[CMP:%.*]] = icmp slt i64 0, [[TMP9]]
-// CHECK1-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
-// CHECK1:       omp.precond.then:
-// CHECK1-NEXT:    store i64 0, ptr [[DOTOMP_LB]], align 8
-// CHECK1-NEXT:    [[TMP10:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8
-// CHECK1-NEXT:    store i64 [[TMP10]], ptr [[DOTOMP_UB]], align 8
-// CHECK1-NEXT:    store i64 1, ptr [[DOTOMP_STRIDE]], align 8
-// CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
-// CHECK1-NEXT:    call void @__kmpc_for_static_init_8(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1)
-// CHECK1-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8
-// CHECK1-NEXT:    [[TMP12:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8
-// CHECK1-NEXT:    [[CMP18:%.*]] = icmp sgt i64 [[TMP11]], [[TMP12]]
-// CHECK1-NEXT:    br i1 [[CMP18]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
-// CHECK1:       cond.true:
-// CHECK1-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8
-// CHECK1-NEXT:    br label [[COND_END:%.*]]
-// CHECK1:       cond.false:
-// CHECK1-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8
-// CHECK1-NEXT:    br label [[COND_END]]
-// CHECK1:       cond.end:
-// CHECK1-NEXT:    [[COND:%.*]] = phi i64 [ [[TMP13]], [[COND_TRUE]] ], [ [[TMP14]], [[COND_FALSE]] ]
-// CHECK1-NEXT:    store i64 [[COND]], ptr [[DOTOMP_UB]], align 8
-// CHECK1-NEXT:    [[TMP15:%.*]] = load i64, ptr [[DOTOMP_LB]], align 8
-// CHECK1-NEXT:    store i64 [[TMP15]], ptr [[DOTOMP_IV]], align 8
-// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
-// CHECK1:       omp.inner.for.cond:
-// CHECK1-NEXT:    [[TMP16:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK1-NEXT:    [[TMP17:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8
-// CHECK1-NEXT:    [[CMP19:%.*]] = icmp sle i64 [[TMP16]], [[TMP17]]
-// CHECK1-NEXT:    br i1 [[CMP19]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
-// CHECK1:       omp.inner.for.body:
-// CHECK1-NEXT:    [[TMP18:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK1-NEXT:    [[TMP19:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK1-NEXT:    [[SUB20:%.*]] = sub nsw i64 [[TMP19]], 0
-// CHECK1-NEXT:    [[DIV21:%.*]] = sdiv i64 [[SUB20]], 1
-// CHECK1-NEXT:    [[MUL22:%.*]] = mul nsw i64 1, [[DIV21]]
-// CHECK1-NEXT:    [[MUL23:%.*]] = mul nsw i64 [[MUL22]], 4
-// CHECK1-NEXT:    [[DIV24:%.*]] = sdiv i64 [[TMP18]], [[MUL23]]
-// CHECK1-NEXT:    [[MUL25:%.*]] = mul nsw i64 [[DIV24]], 3
-// CHECK1-NEXT:    [[ADD26:%.*]] = add nsw i64 7, [[MUL25]]
-// CHECK1-NEXT:    [[CONV:%.*]] = trunc i64 [[ADD26]] to i32
-// CHECK1-NEXT:    store i32 [[CONV]], ptr [[K15]], align 4
-// CHECK1-NEXT:    [[TMP20:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK1-NEXT:    [[TMP21:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK1-NEXT:    [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK1-NEXT:    [[SUB27:%.*]] = sub nsw i64 [[TMP22]], 0
-// CHECK1-NEXT:    [[DIV28:%.*]] = sdiv i64 [[SUB27]], 1
-// CHECK1-NEXT:    [[MUL29:%.*]] = mul nsw i64 1, [[DIV28]]
-// CHECK1-NEXT:    [[MUL30:%.*]] = mul nsw i64 [[MUL29]], 4
-// CHECK1-NEXT:    [[DIV31:%.*]] = sdiv i64 [[TMP21]], [[MUL30]]
-// CHECK1-NEXT:    [[TMP23:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK1-NEXT:    [[SUB32:%.*]] = sub nsw i64 [[TMP23]], 0
-// CHECK1-NEXT:    [[DIV33:%.*]] = sdiv i64 [[SUB32]], 1
-// CHECK1-NEXT:    [[MUL34:%.*]] = mul nsw i64 1, [[DIV33]]
-// CHECK1-NEXT:    [[MUL35:%.*]] = mul nsw i64 [[MUL34]], 4
-// CHECK1-NEXT:    [[MUL36:%.*]] = mul nsw i64 [[DIV31]], [[MUL35]]
-// CHECK1-NEXT:    [[SUB37:%.*]] = sub nsw i64 [[TMP20]], [[MUL36]]
-// CHECK1-NEXT:    [[DIV38:%.*]] = sdiv i64 [[SUB37]], 4
-// CHECK1-NEXT:    [[MUL39:%.*]] = mul nsw i64 [[DIV38]], 1
-// CHECK1-NEXT:    [[ADD40:%.*]] = add nsw i64 0, [[MUL39]]
-// CHECK1-NEXT:    store i64 [[ADD40]], ptr [[DOTFORWARD_IV___BEGIN316]], align 8
-// CHECK1-NEXT:    [[TMP24:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK1-NEXT:    [[TMP25:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK1-NEXT:    [[TMP26:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK1-NEXT:    [[SUB41:%.*]] = sub nsw i64 [[TMP26]], 0
-// CHECK1-NEXT:    [[DIV42:%.*]] = sdiv i64 [[SUB41]], 1
-// CHECK1-NEXT:    [[MUL43:%.*]] = mul nsw i64 1, [[DIV42]]
-// CHECK1-NEXT:    [[MUL44:%.*]] = mul nsw i64 [[MUL43]], 4
-// CHECK1-NEXT:    [[DIV45:%.*]] = sdiv i64 [[TMP25]], [[MUL44]]
-// CHECK1-NEXT:    [[TMP27:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK1-NEXT:    [[SUB46:%.*]] = sub nsw i64 [[TMP27]], 0
-// CHECK1-NEXT:    [[DIV47:%.*]] = sdiv i64 [[SUB46]], 1
-// CHECK1-NEXT:    [[MUL48:%.*]] = mul nsw i64 1, [[DIV47]]
-// CHECK1-NEXT:    [[MUL49:%.*]] = mul nsw i64 [[MUL48]], 4
-// CHECK1-NEXT:    [[MUL50:%.*]] = mul nsw i64 [[DIV45]], [[MUL49]]
-// CHECK1-NEXT:    [[SUB51:%.*]] = sub nsw i64 [[TMP24]], [[MUL50]]
-// CHECK1-NEXT:    [[TMP28:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK1-NEXT:    [[TMP29:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK1-NEXT:    [[TMP30:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK1-NEXT:    [[SUB52:%.*]] = sub nsw i64 [[TMP30]], 0
-// CHECK1-NEXT:    [[DIV53:%.*]] = sdiv i64 [[SUB52]], 1
-// CHECK1-NEXT:    [[MUL54:%.*]] = mul nsw i64 1, [[DIV53]]
-// CHECK1-NEXT:    [[MUL55:%.*]] = mul nsw i64 [[MUL54]], 4
-// CHECK1-NEXT:    [[DIV56:%.*]] = sdiv i64 [[TMP29]], [[MUL55]]
-// CHECK1-NEXT:    [[TMP31:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK1-NEXT:    [[SUB57:%.*]] = sub nsw i64 [[TMP31]], 0
-// CHECK1-NEXT:    [[DIV58:%.*]] = sdiv i64 [[SUB57]], 1
-// CHECK1-NEXT:    [[MUL59:%.*]] = mul nsw i64 1, [[DIV58]]
-// CHECK1-NEXT:    [[MUL60:%.*]] = mul nsw i64 [[MUL59]], 4
-// CHECK1-NEXT:    [[MUL61:%.*]] = mul nsw i64 [[DIV56]], [[MUL60]]
-// CHECK1-NEXT:    [[SUB62:%.*]] = sub nsw i64 [[TMP28]], [[MUL61]]
-// CHECK1-NEXT:    [[DIV63:%.*]] = sdiv i64 [[SUB62]], 4
-// CHECK1-NEXT:    [[MUL64:%.*]] = mul nsw i64 [[DIV63]], 4
-// CHECK1-NEXT:    [[SUB65:%.*]] = sub nsw i64 [[SUB51]], [[MUL64]]
-// CHECK1-NEXT:    [[MUL66:%.*]] = mul nsw i64 [[SUB65]], 3
-// CHECK1-NEXT:    [[ADD67:%.*]] = add nsw i64 7, [[MUL66]]
-// CHECK1-NEXT:    [[CONV68:%.*]] = trunc i64 [[ADD67]] to i32
-// CHECK1-NEXT:    store i32 [[CONV68]], ptr [[J17]], align 4
-// CHECK1-NEXT:    [[TMP32:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_6]], align 8
-// CHECK1-NEXT:    [[ADD69:%.*]] = add nsw i64 [[TMP32]], 1
-// CHECK1-NEXT:    [[SUB70:%.*]] = sub nsw i64 [[ADD69]], 1
-// CHECK1-NEXT:    [[TMP33:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN316]], align 8
-// CHECK1-NEXT:    [[SUB71:%.*]] = sub nsw i64 [[SUB70]], [[TMP33]]
-// CHECK1-NEXT:    store i64 [[SUB71]], ptr [[DOTREVERSED_IV___BEGIN3]], align 8
-// CHECK1-NEXT:    [[TMP34:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK1-NEXT:    [[TMP35:%.*]] = load i64, ptr [[DOTREVERSED_IV___BEGIN3]], align 8
-// CHECK1-NEXT:    [[MUL72:%.*]] = mul nsw i64 [[TMP35]], 1
-// CHECK1-NEXT:    [[ADD_PTR73:%.*]] = getelementptr inbounds double, ptr [[TMP34]], i64 [[MUL72]]
-// CHECK1-NEXT:    store ptr [[ADD_PTR73]], ptr [[__BEGIN3]], align 8
-// CHECK1-NEXT:    [[TMP36:%.*]] = load ptr, ptr [[__BEGIN3]], align 8
-// CHECK1-NEXT:    store ptr [[TMP36]], ptr [[V]], align 8
-// CHECK1-NEXT:    [[TMP37:%.*]] = load i32, ptr [[K15]], align 4
-// CHECK1-NEXT:    [[TMP38:%.*]] = load i32, ptr [[C]], align 4
-// CHECK1-NEXT:    [[TMP39:%.*]] = load ptr, ptr [[V]], align 8, !nonnull [[META2]], !align [[META10]]
-// CHECK1-NEXT:    [[TMP40:%.*]] = load double, ptr [[TMP39]], align 8
-// CHECK1-NEXT:    [[TMP41:%.*]] = load i32, ptr [[J17]], align 4
-// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP37]], i32 noundef [[TMP38]], double noundef [[TMP40]], i32 noundef [[TMP41]])
-// CHECK1-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
-// CHECK1:       omp.body.continue:
-// CHECK1-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
-// CHECK1:       omp.inner.for.inc:
-// CHECK1-NEXT:    [[TMP42:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK1-NEXT:    [[ADD74:%.*]] = add nsw i64 [[TMP42]], 1
-// CHECK1-NEXT:    store i64 [[ADD74]], ptr [[DOTOMP_IV]], align 8
-// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND]]
-// CHECK1:       omp.inner.for.end:
-// CHECK1-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
-// CHECK1:       omp.loop.exit:
-// CHECK1-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
-// CHECK1-NEXT:    br label [[OMP_PRECOND_END]]
-// CHECK1:       omp.precond.end:
-// CHECK1-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]])
-// CHECK1-NEXT:    ret void
-//
-//
-// CHECK1-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_reverse_codegen.cpp
-// CHECK1-SAME: () #[[ATTR1]] section ".text.startup" {
-// CHECK1-NEXT:  entry:
-// CHECK1-NEXT:    call void @__cxx_global_var_init()
-// CHECK1-NEXT:    ret void
-//
-//
-// CHECK2-LABEL: define {{[^@]+}}@__cxx_global_var_init
-// CHECK2-SAME: () #[[ATTR0:[0-9]+]] section ".text.startup" {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    call void @_ZN1SC1Ev(ptr noundef nonnull align 4 dereferenceable(4) @s)
-// CHECK2-NEXT:    ret void
-//
-//
-// CHECK2-LABEL: define {{[^@]+}}@_ZN1SC1Ev
-// CHECK2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
-// CHECK2-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
-// CHECK2-NEXT:    call void @_ZN1SC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]])
-// CHECK2-NEXT:    ret void
-//
-//
-// CHECK2-LABEL: define {{[^@]+}}@_ZN1SC2Ev
-// CHECK2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[I2:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
-// CHECK2-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
-// CHECK2-NEXT:    [[I:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0
-// CHECK2-NEXT:    store i32 7, ptr [[I]], align 4
-// CHECK2-NEXT:    [[I3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0
-// CHECK2-NEXT:    store ptr [[I3]], ptr [[I2]], align 8
-// CHECK2-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    br label [[FOR_COND:%.*]]
-// CHECK2:       for.cond:
-// CHECK2-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 4
-// CHECK2-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
-// CHECK2:       for.body:
-// CHECK2-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    [[SUB:%.*]] = sub nsw i32 3, [[TMP1]]
-// CHECK2-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK2-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK2-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], 3
-// CHECK2-NEXT:    [[ADD:%.*]] = add nsw i32 7, [[MUL]]
-// CHECK2-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2:![0-9]+]], !align [[META3:![0-9]+]]
-// CHECK2-NEXT:    store i32 [[ADD]], ptr [[TMP3]], align 4
-// CHECK2-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
-// CHECK2-NEXT:    [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4
-// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP5]])
-// CHECK2-NEXT:    br label [[FOR_INC:%.*]]
-// CHECK2:       for.inc:
-// CHECK2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
-// CHECK2-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
-// CHECK2:       for.end:
-// CHECK2-NEXT:    ret void
-//
-//
-// CHECK2-LABEL: define {{[^@]+}}@body
-// CHECK2-SAME: (...) #[[ATTR1]] {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    ret void
-//
-//
-// CHECK2-LABEL: define {{[^@]+}}@foo1
-// CHECK2-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]], i32 noundef [[STEP:%.*]]) #[[ATTR1]] {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    [[START_ADDR:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[END_ADDR:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[STEP_ADDR:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTNEW_STEP:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    store i32 [[START]], ptr [[START_ADDR]], align 4
-// CHECK2-NEXT:    store i32 [[END]], ptr [[END_ADDR]], align 4
-// CHECK2-NEXT:    store i32 [[STEP]], ptr [[STEP_ADDR]], align 4
-// CHECK2-NEXT:    [[TMP0:%.*]] = load i32, ptr [[START_ADDR]], align 4
-// CHECK2-NEXT:    store i32 [[TMP0]], ptr [[I]], align 4
-// CHECK2-NEXT:    [[TMP1:%.*]] = load i32, ptr [[START_ADDR]], align 4
-// CHECK2-NEXT:    store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4
-// CHECK2-NEXT:    [[TMP2:%.*]] = load i32, ptr [[END_ADDR]], align 4
-// CHECK2-NEXT:    store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
-// CHECK2-NEXT:    [[TMP3:%.*]] = load i32, ptr [[STEP_ADDR]], align 4
-// CHECK2-NEXT:    store i32 [[TMP3]], ptr [[DOTNEW_STEP]], align 4
-// CHECK2-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
-// CHECK2-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
-// CHECK2-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], [[TMP5]]
-// CHECK2-NEXT:    [[SUB3:%.*]] = sub i32 [[SUB]], 1
-// CHECK2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK2-NEXT:    [[ADD:%.*]] = add i32 [[SUB3]], [[TMP6]]
-// CHECK2-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK2-NEXT:    [[DIV:%.*]] = udiv i32 [[ADD]], [[TMP7]]
-// CHECK2-NEXT:    [[SUB4:%.*]] = sub i32 [[DIV]], 1
-// CHECK2-NEXT:    store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4
-// CHECK2-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    br label [[FOR_COND:%.*]]
-// CHECK2:       for.cond:
-// CHECK2-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
-// CHECK2-NEXT:    [[ADD5:%.*]] = add i32 [[TMP9]], 1
-// CHECK2-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP8]], [[ADD5]]
-// CHECK2-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
-// CHECK2:       for.body:
-// CHECK2-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
-// CHECK2-NEXT:    [[ADD6:%.*]] = add i32 [[TMP10]], 1
-// CHECK2-NEXT:    [[SUB7:%.*]] = sub i32 [[ADD6]], 1
-// CHECK2-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    [[SUB8:%.*]] = sub i32 [[SUB7]], [[TMP11]]
-// CHECK2-NEXT:    store i32 [[SUB8]], ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK2-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
-// CHECK2-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK2-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK2-NEXT:    [[MUL:%.*]] = mul i32 [[TMP13]], [[TMP14]]
-// CHECK2-NEXT:    [[ADD9:%.*]] = add i32 [[TMP12]], [[MUL]]
-// CHECK2-NEXT:    store i32 [[ADD9]], ptr [[I]], align 4
-// CHECK2-NEXT:    [[TMP15:%.*]] = load i32, ptr [[I]], align 4
-// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP15]])
-// CHECK2-NEXT:    br label [[FOR_INC:%.*]]
-// CHECK2:       for.inc:
-// CHECK2-NEXT:    [[TMP16:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    [[INC:%.*]] = add i32 [[TMP16]], 1
-// CHECK2-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
-// CHECK2:       for.end:
-// CHECK2-NEXT:    ret void
-//
-//
-// CHECK2-LABEL: define {{[^@]+}}@foo2
-// CHECK2-SAME: () #[[ATTR1]] {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[TMP:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:[0-9]+]])
-// CHECK2-NEXT:    store i32 7, ptr [[I]], align 4
-// CHECK2-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
-// CHECK2-NEXT:    store i32 3, ptr [[DOTOMP_UB]], align 4
-// CHECK2-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
-// CHECK2-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
-// CHECK2-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
-// CHECK2-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK2-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 3
-// CHECK2-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
-// CHECK2:       cond.true:
-// CHECK2-NEXT:    br label [[COND_END:%.*]]
-// CHECK2:       cond.false:
-// CHECK2-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK2-NEXT:    br label [[COND_END]]
-// CHECK2:       cond.end:
-// CHECK2-NEXT:    [[COND:%.*]] = phi i32 [ 3, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ]
-// CHECK2-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
-// CHECK2-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
-// CHECK2-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
-// CHECK2:       omp.inner.for.cond:
-// CHECK2-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK2-NEXT:    [[CMP1:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]]
-// CHECK2-NEXT:    br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
-// CHECK2:       omp.inner.for.body:
-// CHECK2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP6]], 1
-// CHECK2-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK2-NEXT:    store i32 [[ADD]], ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    [[SUB:%.*]] = sub nsw i32 3, [[TMP7]]
-// CHECK2-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK2-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK2-NEXT:    [[MUL2:%.*]] = mul nsw i32 [[TMP8]], 3
-// CHECK2-NEXT:    [[ADD3:%.*]] = add nsw i32 7, [[MUL2]]
-// CHECK2-NEXT:    store i32 [[ADD3]], ptr [[I]], align 4
-// CHECK2-NEXT:    [[TMP9:%.*]] = load i32, ptr [[I]], align 4
-// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP9]])
-// CHECK2-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
-// CHECK2:       omp.body.continue:
-// CHECK2-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
-// CHECK2:       omp.inner.for.inc:
-// CHECK2-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    [[ADD4:%.*]] = add nsw i32 [[TMP10]], 1
-// CHECK2-NEXT:    store i32 [[ADD4]], ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND]]
-// CHECK2:       omp.inner.for.end:
-// CHECK2-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
-// CHECK2:       omp.loop.exit:
-// CHECK2-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
-// CHECK2-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3:[0-9]+]], i32 [[TMP0]])
-// CHECK2-NEXT:    ret void
-//
-//
-// CHECK2-LABEL: define {{[^@]+}}@foo3
-// CHECK2-SAME: () #[[ATTR1]] {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[TMP:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[_TMP1:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[_TMP2:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[K:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[J:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
-// CHECK2-NEXT:    store i32 7, ptr [[I]], align 4
-// CHECK2-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
-// CHECK2-NEXT:    store i32 63, ptr [[DOTOMP_UB]], align 4
-// CHECK2-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
-// CHECK2-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
-// CHECK2-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
-// CHECK2-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK2-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 63
-// CHECK2-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
-// CHECK2:       cond.true:
-// CHECK2-NEXT:    br label [[COND_END:%.*]]
-// CHECK2:       cond.false:
-// CHECK2-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK2-NEXT:    br label [[COND_END]]
-// CHECK2:       cond.end:
-// CHECK2-NEXT:    [[COND:%.*]] = phi i32 [ 63, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ]
-// CHECK2-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
-// CHECK2-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
-// CHECK2-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
-// CHECK2:       omp.inner.for.cond:
-// CHECK2-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK2-NEXT:    [[CMP3:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]]
-// CHECK2-NEXT:    br i1 [[CMP3]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
-// CHECK2:       omp.inner.for.body:
-// CHECK2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    [[DIV:%.*]] = sdiv i32 [[TMP6]], 16
-// CHECK2-NEXT:    [[MUL:%.*]] = mul nsw i32 [[DIV]], 3
-// CHECK2-NEXT:    [[ADD:%.*]] = add nsw i32 7, [[MUL]]
-// CHECK2-NEXT:    store i32 [[ADD]], ptr [[K]], align 4
-// CHECK2-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    [[DIV4:%.*]] = sdiv i32 [[TMP8]], 16
-// CHECK2-NEXT:    [[MUL5:%.*]] = mul nsw i32 [[DIV4]], 16
-// CHECK2-NEXT:    [[SUB:%.*]] = sub nsw i32 [[TMP7]], [[MUL5]]
-// CHECK2-NEXT:    [[DIV6:%.*]] = sdiv i32 [[SUB]], 4
-// CHECK2-NEXT:    [[MUL7:%.*]] = mul nsw i32 [[DIV6]], 1
-// CHECK2-NEXT:    [[ADD8:%.*]] = add nsw i32 0, [[MUL7]]
-// CHECK2-NEXT:    store i32 [[ADD8]], ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    [[DIV9:%.*]] = sdiv i32 [[TMP10]], 16
-// CHECK2-NEXT:    [[MUL10:%.*]] = mul nsw i32 [[DIV9]], 16
-// CHECK2-NEXT:    [[SUB11:%.*]] = sub nsw i32 [[TMP9]], [[MUL10]]
-// CHECK2-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    [[DIV12:%.*]] = sdiv i32 [[TMP12]], 16
-// CHECK2-NEXT:    [[MUL13:%.*]] = mul nsw i32 [[DIV12]], 16
-// CHECK2-NEXT:    [[SUB14:%.*]] = sub nsw i32 [[TMP11]], [[MUL13]]
-// CHECK2-NEXT:    [[DIV15:%.*]] = sdiv i32 [[SUB14]], 4
-// CHECK2-NEXT:    [[MUL16:%.*]] = mul nsw i32 [[DIV15]], 4
-// CHECK2-NEXT:    [[SUB17:%.*]] = sub nsw i32 [[SUB11]], [[MUL16]]
-// CHECK2-NEXT:    [[MUL18:%.*]] = mul nsw i32 [[SUB17]], 3
-// CHECK2-NEXT:    [[ADD19:%.*]] = add nsw i32 7, [[MUL18]]
-// CHECK2-NEXT:    store i32 [[ADD19]], ptr [[J]], align 4
-// CHECK2-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    [[SUB20:%.*]] = sub nsw i32 3, [[TMP13]]
-// CHECK2-NEXT:    store i32 [[SUB20]], ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK2-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK2-NEXT:    [[MUL21:%.*]] = mul nsw i32 [[TMP14]], 3
-// CHECK2-NEXT:    [[ADD22:%.*]] = add nsw i32 7, [[MUL21]]
-// CHECK2-NEXT:    store i32 [[ADD22]], ptr [[I]], align 4
-// CHECK2-NEXT:    [[TMP15:%.*]] = load i32, ptr [[K]], align 4
-// CHECK2-NEXT:    [[TMP16:%.*]] = load i32, ptr [[I]], align 4
-// CHECK2-NEXT:    [[TMP17:%.*]] = load i32, ptr [[J]], align 4
-// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP15]], i32 noundef [[TMP16]], i32 noundef [[TMP17]])
-// CHECK2-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
-// CHECK2:       omp.body.continue:
-// CHECK2-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
-// CHECK2:       omp.inner.for.inc:
-// CHECK2-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    [[ADD23:%.*]] = add nsw i32 [[TMP18]], 1
-// CHECK2-NEXT:    store i32 [[ADD23]], ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND]]
-// CHECK2:       omp.inner.for.end:
-// CHECK2-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
-// CHECK2:       omp.loop.exit:
-// CHECK2-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
-// CHECK2-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]])
-// CHECK2-NEXT:    ret void
-//
-//
-// CHECK2-LABEL: define {{[^@]+}}@foo4
-// CHECK2-SAME: () #[[ATTR1]] {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 0, ptr @foo4.omp_outlined)
-// CHECK2-NEXT:    ret void
-//
-//
-// CHECK2-LABEL: define {{[^@]+}}@foo4.omp_outlined
-// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR4:[0-9]+]] {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[TMP:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
-// CHECK2-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
-// CHECK2-NEXT:    store i32 7, ptr [[I]], align 4
-// CHECK2-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
-// CHECK2-NEXT:    store i32 3, ptr [[DOTOMP_UB]], align 4
-// CHECK2-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
-// CHECK2-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
-// CHECK2-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
-// CHECK2-NEXT:    [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4
-// CHECK2-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
-// CHECK2-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK2-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 3
-// CHECK2-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
-// CHECK2:       cond.true:
-// CHECK2-NEXT:    br label [[COND_END:%.*]]
-// CHECK2:       cond.false:
-// CHECK2-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK2-NEXT:    br label [[COND_END]]
-// CHECK2:       cond.end:
-// CHECK2-NEXT:    [[COND:%.*]] = phi i32 [ 3, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ]
-// CHECK2-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
-// CHECK2-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
-// CHECK2-NEXT:    store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
-// CHECK2:       omp.inner.for.cond:
-// CHECK2-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
-// CHECK2-NEXT:    [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]]
-// CHECK2-NEXT:    br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
-// CHECK2:       omp.inner.for.body:
-// CHECK2-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1
-// CHECK2-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK2-NEXT:    store i32 [[ADD]], ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    [[SUB:%.*]] = sub nsw i32 3, [[TMP8]]
-// CHECK2-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK2-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK2-NEXT:    [[MUL2:%.*]] = mul nsw i32 [[TMP9]], 3
-// CHECK2-NEXT:    [[ADD3:%.*]] = add nsw i32 7, [[MUL2]]
-// CHECK2-NEXT:    store i32 [[ADD3]], ptr [[I]], align 4
-// CHECK2-NEXT:    [[TMP10:%.*]] = load i32, ptr [[I]], align 4
-// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP10]])
-// CHECK2-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
-// CHECK2:       omp.body.continue:
-// CHECK2-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
-// CHECK2:       omp.inner.for.inc:
-// CHECK2-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    [[ADD4:%.*]] = add nsw i32 [[TMP11]], 1
-// CHECK2-NEXT:    store i32 [[ADD4]], ptr [[DOTOMP_IV]], align 4
-// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND]]
-// CHECK2:       omp.inner.for.end:
-// CHECK2-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
-// CHECK2:       omp.loop.exit:
-// CHECK2-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]])
-// CHECK2-NEXT:    ret void
-//
-//
-// CHECK2-LABEL: define {{[^@]+}}@foo6
-// CHECK2-SAME: () #[[ATTR1]] {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    [[ARR:%.*]] = alloca [128 x double], align 16
-// CHECK2-NEXT:    [[C:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[__RANGE2:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[__END2:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[__BEGIN2:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_3:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8
-// CHECK2-NEXT:    [[DOTFORWARD_IV___BEGIN2:%.*]] = alloca i64, align 8
-// CHECK2-NEXT:    [[DOTREVERSED_IV___BEGIN2:%.*]] = alloca i64, align 8
-// CHECK2-NEXT:    [[V:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    store i32 42, ptr [[C]], align 4
-// CHECK2-NEXT:    store ptr [[ARR]], ptr [[__RANGE2]], align 8
-// CHECK2-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[__RANGE2]], align 8, !nonnull [[META2]], !align [[META9:![0-9]+]]
-// CHECK2-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP0]], i64 0, i64 0
-// CHECK2-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128
-// CHECK2-NEXT:    store ptr [[ADD_PTR]], ptr [[__END2]], align 8
-// CHECK2-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[__RANGE2]], align 8, !nonnull [[META2]], !align [[META9]]
-// CHECK2-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0
-// CHECK2-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[__BEGIN2]], align 8
-// CHECK2-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[__RANGE2]], align 8, !nonnull [[META2]], !align [[META9]]
-// CHECK2-NEXT:    [[ARRAYDECAY2:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0
-// CHECK2-NEXT:    store ptr [[ARRAYDECAY2]], ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK2-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[__END2]], align 8
-// CHECK2-NEXT:    store ptr [[TMP3]], ptr [[DOTCAPTURE_EXPR_3]], align 8
-// CHECK2-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_3]], align 8
-// CHECK2-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK2-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP4]] to i64
-// CHECK2-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP5]] to i64
-// CHECK2-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
-// CHECK2-NEXT:    [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8
-// CHECK2-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1
-// CHECK2-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
-// CHECK2-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
-// CHECK2-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
-// CHECK2-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8
-// CHECK2-NEXT:    store i64 0, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
-// CHECK2-NEXT:    br label [[FOR_COND:%.*]]
-// CHECK2:       for.cond:
-// CHECK2-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
-// CHECK2-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
-// CHECK2-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP7]], 1
-// CHECK2-NEXT:    [[CMP:%.*]] = icmp slt i64 [[TMP6]], [[ADD6]]
-// CHECK2-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
-// CHECK2:       for.body:
-// CHECK2-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
-// CHECK2-NEXT:    [[ADD7:%.*]] = add nsw i64 [[TMP8]], 1
-// CHECK2-NEXT:    [[SUB8:%.*]] = sub nsw i64 [[ADD7]], 1
-// CHECK2-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
-// CHECK2-NEXT:    [[SUB9:%.*]] = sub nsw i64 [[SUB8]], [[TMP9]]
-// CHECK2-NEXT:    store i64 [[SUB9]], ptr [[DOTREVERSED_IV___BEGIN2]], align 8
-// CHECK2-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK2-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTREVERSED_IV___BEGIN2]], align 8
-// CHECK2-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP11]], 1
-// CHECK2-NEXT:    [[ADD_PTR10:%.*]] = getelementptr inbounds double, ptr [[TMP10]], i64 [[MUL]]
-// CHECK2-NEXT:    store ptr [[ADD_PTR10]], ptr [[__BEGIN2]], align 8
-// CHECK2-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[__BEGIN2]], align 8
-// CHECK2-NEXT:    store ptr [[TMP12]], ptr [[V]], align 8
-// CHECK2-NEXT:    [[TMP13:%.*]] = load ptr, ptr [[V]], align 8, !nonnull [[META2]], !align [[META9]]
-// CHECK2-NEXT:    [[TMP14:%.*]] = load double, ptr [[TMP13]], align 8
-// CHECK2-NEXT:    [[TMP15:%.*]] = load i32, ptr [[C]], align 4
-// CHECK2-NEXT:    call void (...) @body(double noundef [[TMP14]], i32 noundef [[TMP15]])
-// CHECK2-NEXT:    br label [[FOR_INC:%.*]]
-// CHECK2:       for.inc:
-// CHECK2-NEXT:    [[TMP16:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
-// CHECK2-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP16]], 1
-// CHECK2-NEXT:    store i64 [[INC]], ptr [[DOTFORWARD_IV___BEGIN2]], align 8
-// CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP10:![0-9]+]]
-// CHECK2:       for.end:
-// CHECK2-NEXT:    ret void
-//
-//
-// CHECK2-LABEL: define {{[^@]+}}@foo7
-// CHECK2-SAME: () #[[ATTR1]] {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    [[A:%.*]] = alloca [128 x double], align 16
-// CHECK2-NEXT:    [[DOTOMP_IV:%.*]] = alloca i64, align 8
-// CHECK2-NEXT:    [[TMP:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[_TMP1:%.*]] = alloca i64, align 8
-// CHECK2-NEXT:    [[_TMP2:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[C:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[__RANGE3:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[__END3:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[__BEGIN3:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_5:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_6:%.*]] = alloca i64, align 8
-// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_8:%.*]] = alloca i64, align 8
-// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_10:%.*]] = alloca i64, align 8
-// CHECK2-NEXT:    [[K:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTFORWARD_IV___BEGIN3:%.*]] = alloca i64, align 8
-// CHECK2-NEXT:    [[J:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTOMP_LB:%.*]] = alloca i64, align 8
-// CHECK2-NEXT:    [[DOTOMP_UB:%.*]] = alloca i64, align 8
-// CHECK2-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i64, align 8
-// CHECK2-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[K15:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTFORWARD_IV___BEGIN316:%.*]] = alloca i64, align 8
-// CHECK2-NEXT:    [[J17:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTREVERSED_IV___BEGIN3:%.*]] = alloca i64, align 8
-// CHECK2-NEXT:    [[V:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
-// CHECK2-NEXT:    store i32 42, ptr [[C]], align 4
-// CHECK2-NEXT:    store ptr [[A]], ptr [[__RANGE3]], align 8
-// CHECK2-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[__RANGE3]], align 8, !nonnull [[META2]], !align [[META9]]
-// CHECK2-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0
-// CHECK2-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128
-// CHECK2-NEXT:    store ptr [[ADD_PTR]], ptr [[__END3]], align 8
-// CHECK2-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[__RANGE3]], align 8, !nonnull [[META2]], !align [[META9]]
-// CHECK2-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0
-// CHECK2-NEXT:    store ptr [[ARRAYDECAY3]], ptr [[__BEGIN3]], align 8
-// CHECK2-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[__RANGE3]], align 8, !nonnull [[META2]], !align [[META9]]
-// CHECK2-NEXT:    [[ARRAYDECAY4:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP3]], i64 0, i64 0
-// CHECK2-NEXT:    store ptr [[ARRAYDECAY4]], ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK2-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[__END3]], align 8
-// CHECK2-NEXT:    store ptr [[TMP4]], ptr [[DOTCAPTURE_EXPR_5]], align 8
-// CHECK2-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_5]], align 8
-// CHECK2-NEXT:    [[TMP6:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK2-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP5]] to i64
-// CHECK2-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP6]] to i64
-// CHECK2-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
-// CHECK2-NEXT:    [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8
-// CHECK2-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1
-// CHECK2-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
-// CHECK2-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
-// CHECK2-NEXT:    [[SUB7:%.*]] = sub nsw i64 [[DIV]], 1
-// CHECK2-NEXT:    store i64 [[SUB7]], ptr [[DOTCAPTURE_EXPR_6]], align 8
-// CHECK2-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_6]], align 8
-// CHECK2-NEXT:    [[ADD9:%.*]] = add nsw i64 [[TMP7]], 1
-// CHECK2-NEXT:    store i64 [[ADD9]], ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK2-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK2-NEXT:    [[SUB11:%.*]] = sub nsw i64 [[TMP8]], 0
-// CHECK2-NEXT:    [[DIV12:%.*]] = sdiv i64 [[SUB11]], 1
-// CHECK2-NEXT:    [[MUL:%.*]] = mul nsw i64 4, [[DIV12]]
-// CHECK2-NEXT:    [[MUL13:%.*]] = mul nsw i64 [[MUL]], 4
-// CHECK2-NEXT:    [[SUB14:%.*]] = sub nsw i64 [[MUL13]], 1
-// CHECK2-NEXT:    store i64 [[SUB14]], ptr [[DOTCAPTURE_EXPR_10]], align 8
-// CHECK2-NEXT:    store i32 7, ptr [[K]], align 4
-// CHECK2-NEXT:    store i64 0, ptr [[DOTFORWARD_IV___BEGIN3]], align 8
-// CHECK2-NEXT:    store i32 7, ptr [[J]], align 4
-// CHECK2-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK2-NEXT:    [[CMP:%.*]] = icmp slt i64 0, [[TMP9]]
-// CHECK2-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
-// CHECK2:       omp.precond.then:
-// CHECK2-NEXT:    store i64 0, ptr [[DOTOMP_LB]], align 8
-// CHECK2-NEXT:    [[TMP10:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8
-// CHECK2-NEXT:    store i64 [[TMP10]], ptr [[DOTOMP_UB]], align 8
-// CHECK2-NEXT:    store i64 1, ptr [[DOTOMP_STRIDE]], align 8
-// CHECK2-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
-// CHECK2-NEXT:    call void @__kmpc_for_static_init_8(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1)
-// CHECK2-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8
-// CHECK2-NEXT:    [[TMP12:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8
-// CHECK2-NEXT:    [[CMP18:%.*]] = icmp sgt i64 [[TMP11]], [[TMP12]]
-// CHECK2-NEXT:    br i1 [[CMP18]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
-// CHECK2:       cond.true:
-// CHECK2-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8
-// CHECK2-NEXT:    br label [[COND_END:%.*]]
-// CHECK2:       cond.false:
-// CHECK2-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8
-// CHECK2-NEXT:    br label [[COND_END]]
-// CHECK2:       cond.end:
-// CHECK2-NEXT:    [[COND:%.*]] = phi i64 [ [[TMP13]], [[COND_TRUE]] ], [ [[TMP14]], [[COND_FALSE]] ]
-// CHECK2-NEXT:    store i64 [[COND]], ptr [[DOTOMP_UB]], align 8
-// CHECK2-NEXT:    [[TMP15:%.*]] = load i64, ptr [[DOTOMP_LB]], align 8
-// CHECK2-NEXT:    store i64 [[TMP15]], ptr [[DOTOMP_IV]], align 8
-// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
-// CHECK2:       omp.inner.for.cond:
-// CHECK2-NEXT:    [[TMP16:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK2-NEXT:    [[TMP17:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8
-// CHECK2-NEXT:    [[CMP19:%.*]] = icmp sle i64 [[TMP16]], [[TMP17]]
-// CHECK2-NEXT:    br i1 [[CMP19]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
-// CHECK2:       omp.inner.for.body:
-// CHECK2-NEXT:    [[TMP18:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK2-NEXT:    [[TMP19:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK2-NEXT:    [[SUB20:%.*]] = sub nsw i64 [[TMP19]], 0
-// CHECK2-NEXT:    [[DIV21:%.*]] = sdiv i64 [[SUB20]], 1
-// CHECK2-NEXT:    [[MUL22:%.*]] = mul nsw i64 1, [[DIV21]]
-// CHECK2-NEXT:    [[MUL23:%.*]] = mul nsw i64 [[MUL22]], 4
-// CHECK2-NEXT:    [[DIV24:%.*]] = sdiv i64 [[TMP18]], [[MUL23]]
-// CHECK2-NEXT:    [[MUL25:%.*]] = mul nsw i64 [[DIV24]], 3
-// CHECK2-NEXT:    [[ADD26:%.*]] = add nsw i64 7, [[MUL25]]
-// CHECK2-NEXT:    [[CONV:%.*]] = trunc i64 [[ADD26]] to i32
-// CHECK2-NEXT:    store i32 [[CONV]], ptr [[K15]], align 4
-// CHECK2-NEXT:    [[TMP20:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK2-NEXT:    [[TMP21:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK2-NEXT:    [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK2-NEXT:    [[SUB27:%.*]] = sub nsw i64 [[TMP22]], 0
-// CHECK2-NEXT:    [[DIV28:%.*]] = sdiv i64 [[SUB27]], 1
-// CHECK2-NEXT:    [[MUL29:%.*]] = mul nsw i64 1, [[DIV28]]
-// CHECK2-NEXT:    [[MUL30:%.*]] = mul nsw i64 [[MUL29]], 4
-// CHECK2-NEXT:    [[DIV31:%.*]] = sdiv i64 [[TMP21]], [[MUL30]]
-// CHECK2-NEXT:    [[TMP23:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK2-NEXT:    [[SUB32:%.*]] = sub nsw i64 [[TMP23]], 0
-// CHECK2-NEXT:    [[DIV33:%.*]] = sdiv i64 [[SUB32]], 1
-// CHECK2-NEXT:    [[MUL34:%.*]] = mul nsw i64 1, [[DIV33]]
-// CHECK2-NEXT:    [[MUL35:%.*]] = mul nsw i64 [[MUL34]], 4
-// CHECK2-NEXT:    [[MUL36:%.*]] = mul nsw i64 [[DIV31]], [[MUL35]]
-// CHECK2-NEXT:    [[SUB37:%.*]] = sub nsw i64 [[TMP20]], [[MUL36]]
-// CHECK2-NEXT:    [[DIV38:%.*]] = sdiv i64 [[SUB37]], 4
-// CHECK2-NEXT:    [[MUL39:%.*]] = mul nsw i64 [[DIV38]], 1
-// CHECK2-NEXT:    [[ADD40:%.*]] = add nsw i64 0, [[MUL39]]
-// CHECK2-NEXT:    store i64 [[ADD40]], ptr [[DOTFORWARD_IV___BEGIN316]], align 8
-// CHECK2-NEXT:    [[TMP24:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK2-NEXT:    [[TMP25:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK2-NEXT:    [[TMP26:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK2-NEXT:    [[SUB41:%.*]] = sub nsw i64 [[TMP26]], 0
-// CHECK2-NEXT:    [[DIV42:%.*]] = sdiv i64 [[SUB41]], 1
-// CHECK2-NEXT:    [[MUL43:%.*]] = mul nsw i64 1, [[DIV42]]
-// CHECK2-NEXT:    [[MUL44:%.*]] = mul nsw i64 [[MUL43]], 4
-// CHECK2-NEXT:    [[DIV45:%.*]] = sdiv i64 [[TMP25]], [[MUL44]]
-// CHECK2-NEXT:    [[TMP27:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK2-NEXT:    [[SUB46:%.*]] = sub nsw i64 [[TMP27]], 0
-// CHECK2-NEXT:    [[DIV47:%.*]] = sdiv i64 [[SUB46]], 1
-// CHECK2-NEXT:    [[MUL48:%.*]] = mul nsw i64 1, [[DIV47]]
-// CHECK2-NEXT:    [[MUL49:%.*]] = mul nsw i64 [[MUL48]], 4
-// CHECK2-NEXT:    [[MUL50:%.*]] = mul nsw i64 [[DIV45]], [[MUL49]]
-// CHECK2-NEXT:    [[SUB51:%.*]] = sub nsw i64 [[TMP24]], [[MUL50]]
-// CHECK2-NEXT:    [[TMP28:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK2-NEXT:    [[TMP29:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK2-NEXT:    [[TMP30:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK2-NEXT:    [[SUB52:%.*]] = sub nsw i64 [[TMP30]], 0
-// CHECK2-NEXT:    [[DIV53:%.*]] = sdiv i64 [[SUB52]], 1
-// CHECK2-NEXT:    [[MUL54:%.*]] = mul nsw i64 1, [[DIV53]]
-// CHECK2-NEXT:    [[MUL55:%.*]] = mul nsw i64 [[MUL54]], 4
-// CHECK2-NEXT:    [[DIV56:%.*]] = sdiv i64 [[TMP29]], [[MUL55]]
-// CHECK2-NEXT:    [[TMP31:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK2-NEXT:    [[SUB57:%.*]] = sub nsw i64 [[TMP31]], 0
-// CHECK2-NEXT:    [[DIV58:%.*]] = sdiv i64 [[SUB57]], 1
-// CHECK2-NEXT:    [[MUL59:%.*]] = mul nsw i64 1, [[DIV58]]
-// CHECK2-NEXT:    [[MUL60:%.*]] = mul nsw i64 [[MUL59]], 4
-// CHECK2-NEXT:    [[MUL61:%.*]] = mul nsw i64 [[DIV56]], [[MUL60]]
-// CHECK2-NEXT:    [[SUB62:%.*]] = sub nsw i64 [[TMP28]], [[MUL61]]
-// CHECK2-NEXT:    [[DIV63:%.*]] = sdiv i64 [[SUB62]], 4
-// CHECK2-NEXT:    [[MUL64:%.*]] = mul nsw i64 [[DIV63]], 4
-// CHECK2-NEXT:    [[SUB65:%.*]] = sub nsw i64 [[SUB51]], [[MUL64]]
-// CHECK2-NEXT:    [[MUL66:%.*]] = mul nsw i64 [[SUB65]], 3
-// CHECK2-NEXT:    [[ADD67:%.*]] = add nsw i64 7, [[MUL66]]
-// CHECK2-NEXT:    [[CONV68:%.*]] = trunc i64 [[ADD67]] to i32
-// CHECK2-NEXT:    store i32 [[CONV68]], ptr [[J17]], align 4
-// CHECK2-NEXT:    [[TMP32:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_6]], align 8
-// CHECK2-NEXT:    [[ADD69:%.*]] = add nsw i64 [[TMP32]], 1
-// CHECK2-NEXT:    [[SUB70:%.*]] = sub nsw i64 [[ADD69]], 1
-// CHECK2-NEXT:    [[TMP33:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN316]], align 8
-// CHECK2-NEXT:    [[SUB71:%.*]] = sub nsw i64 [[SUB70]], [[TMP33]]
-// CHECK2-NEXT:    store i64 [[SUB71]], ptr [[DOTREVERSED_IV___BEGIN3]], align 8
-// CHECK2-NEXT:    [[TMP34:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK2-NEXT:    [[TMP35:%.*]] = load i64, ptr [[DOTREVERSED_IV___BEGIN3]], align 8
-// CHECK2-NEXT:    [[MUL72:%.*]] = mul nsw i64 [[TMP35]], 1
-// CHECK2-NEXT:    [[ADD_PTR73:%.*]] = getelementptr inbounds double, ptr [[TMP34]], i64 [[MUL72]]
-// CHECK2-NEXT:    store ptr [[ADD_PTR73]], ptr [[__BEGIN3]], align 8
-// CHECK2-NEXT:    [[TMP36:%.*]] = load ptr, ptr [[__BEGIN3]], align 8
-// CHECK2-NEXT:    store ptr [[TMP36]], ptr [[V]], align 8
-// CHECK2-NEXT:    [[TMP37:%.*]] = load i32, ptr [[K15]], align 4
-// CHECK2-NEXT:    [[TMP38:%.*]] = load i32, ptr [[C]], align 4
-// CHECK2-NEXT:    [[TMP39:%.*]] = load ptr, ptr [[V]], align 8, !nonnull [[META2]], !align [[META9]]
-// CHECK2-NEXT:    [[TMP40:%.*]] = load double, ptr [[TMP39]], align 8
-// CHECK2-NEXT:    [[TMP41:%.*]] = load i32, ptr [[J17]], align 4
-// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP37]], i32 noundef [[TMP38]], double noundef [[TMP40]], i32 noundef [[TMP41]])
-// CHECK2-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
-// CHECK2:       omp.body.continue:
-// CHECK2-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
-// CHECK2:       omp.inner.for.inc:
-// CHECK2-NEXT:    [[TMP42:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
-// CHECK2-NEXT:    [[ADD74:%.*]] = add nsw i64 [[TMP42]], 1
-// CHECK2-NEXT:    store i64 [[ADD74]], ptr [[DOTOMP_IV]], align 8
-// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND]]
-// CHECK2:       omp.inner.for.end:
-// CHECK2-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
-// CHECK2:       omp.loop.exit:
-// CHECK2-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
-// CHECK2-NEXT:    br label [[OMP_PRECOND_END]]
-// CHECK2:       omp.precond.end:
-// CHECK2-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]])
-// CHECK2-NEXT:    ret void
-//
-//
-// CHECK2-LABEL: define {{[^@]+}}@tfoo5
-// CHECK2-SAME: () #[[ATTR1]] {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    call void @_Z4foo5IiTnT_Li3EEvS0_S0_(i32 noundef 0, i32 noundef 42)
-// CHECK2-NEXT:    ret void
-//
-//
-// CHECK2-LABEL: define {{[^@]+}}@_Z4foo5IiTnT_Li3EEvS0_S0_
-// CHECK2-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]]) #[[ATTR1]] comdat {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    [[START_ADDR:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[END_ADDR:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    store i32 [[START]], ptr [[START_ADDR]], align 4
-// CHECK2-NEXT:    store i32 [[END]], ptr [[END_ADDR]], align 4
-// CHECK2-NEXT:    [[TMP0:%.*]] = load i32, ptr [[START_ADDR]], align 4
-// CHECK2-NEXT:    store i32 [[TMP0]], ptr [[I]], align 4
-// CHECK2-NEXT:    [[TMP1:%.*]] = load i32, ptr [[START_ADDR]], align 4
-// CHECK2-NEXT:    store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4
-// CHECK2-NEXT:    [[TMP2:%.*]] = load i32, ptr [[END_ADDR]], align 4
-// CHECK2-NEXT:    store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
-// CHECK2-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
-// CHECK2-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
-// CHECK2-NEXT:    [[SUB:%.*]] = sub i32 [[TMP3]], [[TMP4]]
-// CHECK2-NEXT:    [[SUB3:%.*]] = sub i32 [[SUB]], 1
-// CHECK2-NEXT:    [[ADD:%.*]] = add i32 [[SUB3]], 3
-// CHECK2-NEXT:    [[DIV:%.*]] = udiv i32 [[ADD]], 3
-// CHECK2-NEXT:    [[SUB4:%.*]] = sub i32 [[DIV]], 1
-// CHECK2-NEXT:    store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4
-// CHECK2-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    br label [[FOR_COND:%.*]]
-// CHECK2:       for.cond:
-// CHECK2-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
-// CHECK2-NEXT:    [[ADD5:%.*]] = add i32 [[TMP6]], 1
-// CHECK2-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP5]], [[ADD5]]
-// CHECK2-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
-// CHECK2:       for.body:
-// CHECK2-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
-// CHECK2-NEXT:    [[ADD6:%.*]] = add i32 [[TMP7]], 1
-// CHECK2-NEXT:    [[SUB7:%.*]] = sub i32 [[ADD6]], 1
-// CHECK2-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    [[SUB8:%.*]] = sub i32 [[SUB7]], [[TMP8]]
-// CHECK2-NEXT:    store i32 [[SUB8]], ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK2-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
-// CHECK2-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK2-NEXT:    [[MUL:%.*]] = mul i32 [[TMP10]], 3
-// CHECK2-NEXT:    [[ADD9:%.*]] = add i32 [[TMP9]], [[MUL]]
-// CHECK2-NEXT:    store i32 [[ADD9]], ptr [[I]], align 4
-// CHECK2-NEXT:    [[TMP11:%.*]] = load i32, ptr [[I]], align 4
-// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP11]])
-// CHECK2-NEXT:    br label [[FOR_INC:%.*]]
-// CHECK2:       for.inc:
-// CHECK2-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    [[INC:%.*]] = add i32 [[TMP12]], 1
-// CHECK2-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4
-// CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP11:![0-9]+]]
-// CHECK2:       for.end:
-// CHECK2-NEXT:    ret void
-//
-//
-// CHECK2-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_reverse_codegen.cpp
-// CHECK2-SAME: () #[[ATTR0]] section ".text.startup" {
-// CHECK2-NEXT:  entry:
-// CHECK2-NEXT:    call void @__cxx_global_var_init()
-// CHECK2-NEXT:    ret void
-//
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _
+
+// expected-no-diagnostics
+
+// Check code generation
+// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -std=c++20 -fclang-abi-compat=latest -fopenmp -fopenmp-version=60 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1
+
+// Check same results after serialization round-trip
+// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -std=c++20 -fclang-abi-compat=latest -fopenmp -fopenmp-version=60 -emit-pch -o %t %s
+// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -std=c++20 -fclang-abi-compat=latest -fopenmp -fopenmp-version=60 -include-pch %t -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK2
+
+#ifndef HEADER
+#define HEADER
+
+// placeholder for loop body code.
+extern "C" void body(...) {}
+
+
+struct S {
+  int i;
+  S() {
+#pragma omp reverse
+    for (i = 7; i < 17; i += 3)
+      body(i);
+  }
+} s;
+
+
+extern "C" void foo1(int start, int end, int step) {
+  int i;
+#pragma omp reverse
+  for (i = start; i < end; i += step)
+    body(i);
+}
+
+
+extern "C" void foo2() {
+#pragma omp for
+#pragma omp reverse
+    for (int i = 7; i < 17; i += 3)
+        body(i);
+}
+
+
+extern "C" void foo3() {
+#pragma omp for collapse(3)
+  for (int k = 7; k < 17; k += 3)
+#pragma omp reverse
+    for (int i = 7; i < 17; i += 3)
+      for (int j = 7; j < 17; j += 3)
+        body(k, i, j);
+}
+
+
+extern "C" void foo4() {
+#pragma omp parallel for
+#pragma omp reverse
+  for (int i = 7; i < 17; i += 3)
+    body(i);
+}
+
+
+template<typename T, T Step>
+void foo5(T start, T end) {
+#pragma omp reverse
+  for (T i = start; i < end; i += Step)
+    body(i);
+}
+
+extern "C" void tfoo5() {
+  foo5<int,3>(0, 42);
+}
+
+
+extern "C" void foo6() {
+  double arr[128];
+#pragma omp reverse
+  for (int c = 42; auto && v : arr)
+    body(v, c);
+}
+
+
+extern "C" void foo7() {
+  double A[128];
+
+#pragma omp for collapse(3)
+  for (int k = 7; k < 17; k += 3)
+#pragma omp reverse
+    for (int c = 42; auto && v : A)
+      for (int j = 7; j < 17; j += 3)
+        body(k, c, v, j);
+}
+
+#endif /* HEADER */
+
+
+// CHECK1-LABEL: define {{[^@]+}}@body
+// CHECK1-SAME: (...) #[[ATTR0:[0-9]+]] {
+// CHECK1-NEXT:  entry:
+// CHECK1-NEXT:    ret void
+//
+//
+// CHECK1-LABEL: define {{[^@]+}}@__cxx_global_var_init
+// CHECK1-SAME: () #[[ATTR1:[0-9]+]] section ".text.startup" {
+// CHECK1-NEXT:  entry:
+// CHECK1-NEXT:    call void @_ZN1SC1Ev(ptr noundef nonnull align 4 dereferenceable(4) @s)
+// CHECK1-NEXT:    ret void
+//
+//
+// CHECK1-LABEL: define {{[^@]+}}@_ZN1SC1Ev
+// CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 {
+// CHECK1-NEXT:  entry:
+// CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
+// CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
+// CHECK1-NEXT:    call void @_ZN1SC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]])
+// CHECK1-NEXT:    ret void
+//
+//
+// CHECK1-LABEL: define {{[^@]+}}@_ZN1SC2Ev
+// CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 {
+// CHECK1-NEXT:  entry:
+// CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[I2:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
+// CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
+// CHECK1-NEXT:    [[I:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0
+// CHECK1-NEXT:    store i32 7, ptr [[I]], align 4
+// CHECK1-NEXT:    [[I3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0
+// CHECK1-NEXT:    store ptr [[I3]], ptr [[I2]], align 8
+// CHECK1-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    br label [[FOR_COND:%.*]]
+// CHECK1:       for.cond:
+// CHECK1-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 4
+// CHECK1-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK1:       for.body:
+// CHECK1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    [[SUB:%.*]] = sub nsw i32 3, [[TMP1]]
+// CHECK1-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK1-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK1-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], 3
+// CHECK1-NEXT:    [[ADD:%.*]] = add nsw i32 7, [[MUL]]
+// CHECK1-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2:![0-9]+]], !align [[META3:![0-9]+]]
+// CHECK1-NEXT:    store i32 [[ADD]], ptr [[TMP3]], align 4
+// CHECK1-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4
+// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP5]])
+// CHECK1-NEXT:    br label [[FOR_INC:%.*]]
+// CHECK1:       for.inc:
+// CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
+// CHECK1-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
+// CHECK1:       for.end:
+// CHECK1-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK1-NEXT:    store i32 16, ptr [[TMP7]], align 4
+// CHECK1-NEXT:    ret void
+//
+//
+// CHECK1-LABEL: define {{[^@]+}}@foo1
+// CHECK1-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]], i32 noundef [[STEP:%.*]]) #[[ATTR0]] {
+// CHECK1-NEXT:  entry:
+// CHECK1-NEXT:    [[START_ADDR:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[END_ADDR:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[STEP_ADDR:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTNEW_STEP:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    store i32 [[START]], ptr [[START_ADDR]], align 4
+// CHECK1-NEXT:    store i32 [[END]], ptr [[END_ADDR]], align 4
+// CHECK1-NEXT:    store i32 [[STEP]], ptr [[STEP_ADDR]], align 4
+// CHECK1-NEXT:    [[TMP0:%.*]] = load i32, ptr [[START_ADDR]], align 4
+// CHECK1-NEXT:    store i32 [[TMP0]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[START_ADDR]], align 4
+// CHECK1-NEXT:    store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[TMP2:%.*]] = load i32, ptr [[END_ADDR]], align 4
+// CHECK1-NEXT:    store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK1-NEXT:    [[TMP3:%.*]] = load i32, ptr [[STEP_ADDR]], align 4
+// CHECK1-NEXT:    store i32 [[TMP3]], ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], [[TMP5]]
+// CHECK1-NEXT:    [[SUB3:%.*]] = sub i32 [[SUB]], 1
+// CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[ADD:%.*]] = add i32 [[SUB3]], [[TMP6]]
+// CHECK1-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[DIV:%.*]] = udiv i32 [[ADD]], [[TMP7]]
+// CHECK1-NEXT:    [[SUB4:%.*]] = sub i32 [[DIV]], 1
+// CHECK1-NEXT:    store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4
+// CHECK1-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    br label [[FOR_COND:%.*]]
+// CHECK1:       for.cond:
+// CHECK1-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
+// CHECK1-NEXT:    [[ADD5:%.*]] = add i32 [[TMP9]], 1
+// CHECK1-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP8]], [[ADD5]]
+// CHECK1-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK1:       for.body:
+// CHECK1-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
+// CHECK1-NEXT:    [[ADD6:%.*]] = add i32 [[TMP10]], 1
+// CHECK1-NEXT:    [[SUB7:%.*]] = sub i32 [[ADD6]], 1
+// CHECK1-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    [[SUB8:%.*]] = sub i32 [[SUB7]], [[TMP11]]
+// CHECK1-NEXT:    store i32 [[SUB8]], ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK1-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK1-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[MUL:%.*]] = mul i32 [[TMP13]], [[TMP14]]
+// CHECK1-NEXT:    [[ADD9:%.*]] = add i32 [[TMP12]], [[MUL]]
+// CHECK1-NEXT:    store i32 [[ADD9]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[TMP15:%.*]] = load i32, ptr [[I]], align 4
+// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP15]])
+// CHECK1-NEXT:    br label [[FOR_INC:%.*]]
+// CHECK1:       for.inc:
+// CHECK1-NEXT:    [[TMP16:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    [[INC:%.*]] = add i32 [[TMP16]], 1
+// CHECK1-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
+// CHECK1:       for.end:
+// CHECK1-NEXT:    [[TMP17:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK1-NEXT:    [[TMP19:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB10:%.*]] = sub i32 [[TMP18]], [[TMP19]]
+// CHECK1-NEXT:    [[SUB11:%.*]] = sub i32 [[SUB10]], 1
+// CHECK1-NEXT:    [[TMP20:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[ADD12:%.*]] = add i32 [[SUB11]], [[TMP20]]
+// CHECK1-NEXT:    [[TMP21:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[DIV13:%.*]] = udiv i32 [[ADD12]], [[TMP21]]
+// CHECK1-NEXT:    [[SUB14:%.*]] = sub i32 [[DIV13]], 1
+// CHECK1-NEXT:    [[TMP22:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[MUL15:%.*]] = mul i32 [[SUB14]], [[TMP22]]
+// CHECK1-NEXT:    [[ADD16:%.*]] = add i32 [[TMP17]], [[MUL15]]
+// CHECK1-NEXT:    store i32 [[ADD16]], ptr [[I]], align 4
+// CHECK1-NEXT:    ret void
+//
+//
+// CHECK1-LABEL: define {{[^@]+}}@foo2
+// CHECK1-SAME: () #[[ATTR0]] {
+// CHECK1-NEXT:  entry:
+// CHECK1-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:[0-9]+]])
+// CHECK1-NEXT:    store i32 7, ptr [[I]], align 4
+// CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
+// CHECK1-NEXT:    store i32 3, ptr [[DOTOMP_UB]], align 4
+// CHECK1-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
+// CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
+// CHECK1-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
+// CHECK1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK1-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 3
+// CHECK1-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// CHECK1:       cond.true:
+// CHECK1-NEXT:    br label [[COND_END:%.*]]
+// CHECK1:       cond.false:
+// CHECK1-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK1-NEXT:    br label [[COND_END]]
+// CHECK1:       cond.end:
+// CHECK1-NEXT:    [[COND:%.*]] = phi i32 [ 3, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ]
+// CHECK1-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
+// CHECK1-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
+// CHECK1-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// CHECK1:       omp.inner.for.cond:
+// CHECK1-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK1-NEXT:    [[CMP1:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]]
+// CHECK1-NEXT:    br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// CHECK1:       omp.inner.for.body:
+// CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP6]], 1
+// CHECK1-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
+// CHECK1-NEXT:    store i32 [[ADD]], ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    [[SUB:%.*]] = sub nsw i32 3, [[TMP7]]
+// CHECK1-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK1-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK1-NEXT:    [[MUL2:%.*]] = mul nsw i32 [[TMP8]], 3
+// CHECK1-NEXT:    [[ADD3:%.*]] = add nsw i32 7, [[MUL2]]
+// CHECK1-NEXT:    store i32 [[ADD3]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[TMP9:%.*]] = load i32, ptr [[I]], align 4
+// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP9]])
+// CHECK1-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// CHECK1:       omp.body.continue:
+// CHECK1-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// CHECK1:       omp.inner.for.inc:
+// CHECK1-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    [[ADD4:%.*]] = add nsw i32 [[TMP10]], 1
+// CHECK1-NEXT:    store i32 [[ADD4]], ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// CHECK1:       omp.inner.for.end:
+// CHECK1-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// CHECK1:       omp.loop.exit:
+// CHECK1-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
+// CHECK1-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3:[0-9]+]], i32 [[TMP0]])
+// CHECK1-NEXT:    ret void
+//
+//
+// CHECK1-LABEL: define {{[^@]+}}@foo3
+// CHECK1-SAME: () #[[ATTR0]] {
+// CHECK1-NEXT:  entry:
+// CHECK1-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[_TMP1:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[_TMP2:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[K:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[J:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
+// CHECK1-NEXT:    store i32 7, ptr [[I]], align 4
+// CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
+// CHECK1-NEXT:    store i32 63, ptr [[DOTOMP_UB]], align 4
+// CHECK1-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
+// CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
+// CHECK1-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
+// CHECK1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK1-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 63
+// CHECK1-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// CHECK1:       cond.true:
+// CHECK1-NEXT:    br label [[COND_END:%.*]]
+// CHECK1:       cond.false:
+// CHECK1-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK1-NEXT:    br label [[COND_END]]
+// CHECK1:       cond.end:
+// CHECK1-NEXT:    [[COND:%.*]] = phi i32 [ 63, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ]
+// CHECK1-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
+// CHECK1-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
+// CHECK1-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// CHECK1:       omp.inner.for.cond:
+// CHECK1-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK1-NEXT:    [[CMP3:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]]
+// CHECK1-NEXT:    br i1 [[CMP3]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// CHECK1:       omp.inner.for.body:
+// CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    [[DIV:%.*]] = sdiv i32 [[TMP6]], 16
+// CHECK1-NEXT:    [[MUL:%.*]] = mul nsw i32 [[DIV]], 3
+// CHECK1-NEXT:    [[ADD:%.*]] = add nsw i32 7, [[MUL]]
+// CHECK1-NEXT:    store i32 [[ADD]], ptr [[K]], align 4
+// CHECK1-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    [[DIV4:%.*]] = sdiv i32 [[TMP8]], 16
+// CHECK1-NEXT:    [[MUL5:%.*]] = mul nsw i32 [[DIV4]], 16
+// CHECK1-NEXT:    [[SUB:%.*]] = sub nsw i32 [[TMP7]], [[MUL5]]
+// CHECK1-NEXT:    [[DIV6:%.*]] = sdiv i32 [[SUB]], 4
+// CHECK1-NEXT:    [[MUL7:%.*]] = mul nsw i32 [[DIV6]], 1
+// CHECK1-NEXT:    [[ADD8:%.*]] = add nsw i32 0, [[MUL7]]
+// CHECK1-NEXT:    store i32 [[ADD8]], ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    [[DIV9:%.*]] = sdiv i32 [[TMP10]], 16
+// CHECK1-NEXT:    [[MUL10:%.*]] = mul nsw i32 [[DIV9]], 16
+// CHECK1-NEXT:    [[SUB11:%.*]] = sub nsw i32 [[TMP9]], [[MUL10]]
+// CHECK1-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    [[DIV12:%.*]] = sdiv i32 [[TMP12]], 16
+// CHECK1-NEXT:    [[MUL13:%.*]] = mul nsw i32 [[DIV12]], 16
+// CHECK1-NEXT:    [[SUB14:%.*]] = sub nsw i32 [[TMP11]], [[MUL13]]
+// CHECK1-NEXT:    [[DIV15:%.*]] = sdiv i32 [[SUB14]], 4
+// CHECK1-NEXT:    [[MUL16:%.*]] = mul nsw i32 [[DIV15]], 4
+// CHECK1-NEXT:    [[SUB17:%.*]] = sub nsw i32 [[SUB11]], [[MUL16]]
+// CHECK1-NEXT:    [[MUL18:%.*]] = mul nsw i32 [[SUB17]], 3
+// CHECK1-NEXT:    [[ADD19:%.*]] = add nsw i32 7, [[MUL18]]
+// CHECK1-NEXT:    store i32 [[ADD19]], ptr [[J]], align 4
+// CHECK1-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    [[SUB20:%.*]] = sub nsw i32 3, [[TMP13]]
+// CHECK1-NEXT:    store i32 [[SUB20]], ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK1-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK1-NEXT:    [[MUL21:%.*]] = mul nsw i32 [[TMP14]], 3
+// CHECK1-NEXT:    [[ADD22:%.*]] = add nsw i32 7, [[MUL21]]
+// CHECK1-NEXT:    store i32 [[ADD22]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[TMP15:%.*]] = load i32, ptr [[K]], align 4
+// CHECK1-NEXT:    [[TMP16:%.*]] = load i32, ptr [[I]], align 4
+// CHECK1-NEXT:    [[TMP17:%.*]] = load i32, ptr [[J]], align 4
+// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP15]], i32 noundef [[TMP16]], i32 noundef [[TMP17]])
+// CHECK1-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// CHECK1:       omp.body.continue:
+// CHECK1-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// CHECK1:       omp.inner.for.inc:
+// CHECK1-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    [[ADD23:%.*]] = add nsw i32 [[TMP18]], 1
+// CHECK1-NEXT:    store i32 [[ADD23]], ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// CHECK1:       omp.inner.for.end:
+// CHECK1-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// CHECK1:       omp.loop.exit:
+// CHECK1-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
+// CHECK1-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]])
+// CHECK1-NEXT:    ret void
+//
+//
+// CHECK1-LABEL: define {{[^@]+}}@foo4
+// CHECK1-SAME: () #[[ATTR0]] {
+// CHECK1-NEXT:  entry:
+// CHECK1-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 0, ptr @foo4.omp_outlined)
+// CHECK1-NEXT:    ret void
+//
+//
+// CHECK1-LABEL: define {{[^@]+}}@foo4.omp_outlined
+// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR4:[0-9]+]] {
+// CHECK1-NEXT:  entry:
+// CHECK1-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
+// CHECK1-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
+// CHECK1-NEXT:    store i32 7, ptr [[I]], align 4
+// CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
+// CHECK1-NEXT:    store i32 3, ptr [[DOTOMP_UB]], align 4
+// CHECK1-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
+// CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
+// CHECK1-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
+// CHECK1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4
+// CHECK1-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
+// CHECK1-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK1-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 3
+// CHECK1-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// CHECK1:       cond.true:
+// CHECK1-NEXT:    br label [[COND_END:%.*]]
+// CHECK1:       cond.false:
+// CHECK1-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK1-NEXT:    br label [[COND_END]]
+// CHECK1:       cond.end:
+// CHECK1-NEXT:    [[COND:%.*]] = phi i32 [ 3, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ]
+// CHECK1-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
+// CHECK1-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
+// CHECK1-NEXT:    store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// CHECK1:       omp.inner.for.cond:
+// CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK1-NEXT:    [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]]
+// CHECK1-NEXT:    br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// CHECK1:       omp.inner.for.body:
+// CHECK1-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1
+// CHECK1-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
+// CHECK1-NEXT:    store i32 [[ADD]], ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    [[SUB:%.*]] = sub nsw i32 3, [[TMP8]]
+// CHECK1-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK1-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK1-NEXT:    [[MUL2:%.*]] = mul nsw i32 [[TMP9]], 3
+// CHECK1-NEXT:    [[ADD3:%.*]] = add nsw i32 7, [[MUL2]]
+// CHECK1-NEXT:    store i32 [[ADD3]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[TMP10:%.*]] = load i32, ptr [[I]], align 4
+// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP10]])
+// CHECK1-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// CHECK1:       omp.body.continue:
+// CHECK1-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// CHECK1:       omp.inner.for.inc:
+// CHECK1-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    [[ADD4:%.*]] = add nsw i32 [[TMP11]], 1
+// CHECK1-NEXT:    store i32 [[ADD4]], ptr [[DOTOMP_IV]], align 4
+// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// CHECK1:       omp.inner.for.end:
+// CHECK1-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// CHECK1:       omp.loop.exit:
+// CHECK1-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]])
+// CHECK1-NEXT:    ret void
+//
+//
+// CHECK1-LABEL: define {{[^@]+}}@tfoo5
+// CHECK1-SAME: () #[[ATTR0]] {
+// CHECK1-NEXT:  entry:
+// CHECK1-NEXT:    call void @_Z4foo5IiTnT_Li3EEvS0_S0_(i32 noundef 0, i32 noundef 42)
+// CHECK1-NEXT:    ret void
+//
+//
+// CHECK1-LABEL: define {{[^@]+}}@_Z4foo5IiTnT_Li3EEvS0_S0_
+// CHECK1-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]]) #[[ATTR0]] comdat {
+// CHECK1-NEXT:  entry:
+// CHECK1-NEXT:    [[START_ADDR:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[END_ADDR:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    store i32 [[START]], ptr [[START_ADDR]], align 4
+// CHECK1-NEXT:    store i32 [[END]], ptr [[END_ADDR]], align 4
+// CHECK1-NEXT:    [[TMP0:%.*]] = load i32, ptr [[START_ADDR]], align 4
+// CHECK1-NEXT:    store i32 [[TMP0]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[START_ADDR]], align 4
+// CHECK1-NEXT:    store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[TMP2:%.*]] = load i32, ptr [[END_ADDR]], align 4
+// CHECK1-NEXT:    store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK1-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK1-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB:%.*]] = sub i32 [[TMP3]], [[TMP4]]
+// CHECK1-NEXT:    [[SUB3:%.*]] = sub i32 [[SUB]], 1
+// CHECK1-NEXT:    [[ADD:%.*]] = add i32 [[SUB3]], 3
+// CHECK1-NEXT:    [[DIV:%.*]] = udiv i32 [[ADD]], 3
+// CHECK1-NEXT:    [[SUB4:%.*]] = sub i32 [[DIV]], 1
+// CHECK1-NEXT:    store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4
+// CHECK1-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    br label [[FOR_COND:%.*]]
+// CHECK1:       for.cond:
+// CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
+// CHECK1-NEXT:    [[ADD5:%.*]] = add i32 [[TMP6]], 1
+// CHECK1-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP5]], [[ADD5]]
+// CHECK1-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK1:       for.body:
+// CHECK1-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
+// CHECK1-NEXT:    [[ADD6:%.*]] = add i32 [[TMP7]], 1
+// CHECK1-NEXT:    [[SUB7:%.*]] = sub i32 [[ADD6]], 1
+// CHECK1-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    [[SUB8:%.*]] = sub i32 [[SUB7]], [[TMP8]]
+// CHECK1-NEXT:    store i32 [[SUB8]], ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK1-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK1-NEXT:    [[MUL:%.*]] = mul i32 [[TMP10]], 3
+// CHECK1-NEXT:    [[ADD9:%.*]] = add i32 [[TMP9]], [[MUL]]
+// CHECK1-NEXT:    store i32 [[ADD9]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[TMP11:%.*]] = load i32, ptr [[I]], align 4
+// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP11]])
+// CHECK1-NEXT:    br label [[FOR_INC:%.*]]
+// CHECK1:       for.inc:
+// CHECK1-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    [[INC:%.*]] = add i32 [[TMP12]], 1
+// CHECK1-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]]
+// CHECK1:       for.end:
+// CHECK1-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK1-NEXT:    [[TMP15:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB10:%.*]] = sub i32 [[TMP14]], [[TMP15]]
+// CHECK1-NEXT:    [[SUB11:%.*]] = sub i32 [[SUB10]], 1
+// CHECK1-NEXT:    [[ADD12:%.*]] = add i32 [[SUB11]], 3
+// CHECK1-NEXT:    [[DIV13:%.*]] = udiv i32 [[ADD12]], 3
+// CHECK1-NEXT:    [[SUB14:%.*]] = sub i32 [[DIV13]], 1
+// CHECK1-NEXT:    [[MUL15:%.*]] = mul i32 [[SUB14]], 3
+// CHECK1-NEXT:    [[ADD16:%.*]] = add i32 [[TMP13]], [[MUL15]]
+// CHECK1-NEXT:    store i32 [[ADD16]], ptr [[I]], align 4
+// CHECK1-NEXT:    ret void
+//
+//
+// CHECK1-LABEL: define {{[^@]+}}@foo6
+// CHECK1-SAME: () #[[ATTR0]] {
+// CHECK1-NEXT:  entry:
+// CHECK1-NEXT:    [[ARR:%.*]] = alloca [128 x double], align 16
+// CHECK1-NEXT:    [[C:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[__RANGE2:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[__END2:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[__BEGIN2:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_3:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8
+// CHECK1-NEXT:    [[DOTFORWARD_IV___BEGIN2:%.*]] = alloca i64, align 8
+// CHECK1-NEXT:    [[DOTREVERSED_IV___BEGIN2:%.*]] = alloca i64, align 8
+// CHECK1-NEXT:    [[V:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    store i32 42, ptr [[C]], align 4
+// CHECK1-NEXT:    store ptr [[ARR]], ptr [[__RANGE2]], align 8
+// CHECK1-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[__RANGE2]], align 8, !nonnull [[META2]], !align [[META10:![0-9]+]]
+// CHECK1-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP0]], i64 0, i64 0
+// CHECK1-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128
+// CHECK1-NEXT:    store ptr [[ADD_PTR]], ptr [[__END2]], align 8
+// CHECK1-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[__RANGE2]], align 8, !nonnull [[META2]], !align [[META10]]
+// CHECK1-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0
+// CHECK1-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[__BEGIN2]], align 8
+// CHECK1-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[__RANGE2]], align 8, !nonnull [[META2]], !align [[META10]]
+// CHECK1-NEXT:    [[ARRAYDECAY2:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0
+// CHECK1-NEXT:    store ptr [[ARRAYDECAY2]], ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK1-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[__END2]], align 8
+// CHECK1-NEXT:    store ptr [[TMP3]], ptr [[DOTCAPTURE_EXPR_3]], align 8
+// CHECK1-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_3]], align 8
+// CHECK1-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK1-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP4]] to i64
+// CHECK1-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP5]] to i64
+// CHECK1-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
+// CHECK1-NEXT:    [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8
+// CHECK1-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1
+// CHECK1-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
+// CHECK1-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
+// CHECK1-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
+// CHECK1-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK1-NEXT:    store i64 0, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
+// CHECK1-NEXT:    br label [[FOR_COND:%.*]]
+// CHECK1:       for.cond:
+// CHECK1-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
+// CHECK1-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK1-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP7]], 1
+// CHECK1-NEXT:    [[CMP:%.*]] = icmp slt i64 [[TMP6]], [[ADD6]]
+// CHECK1-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK1:       for.body:
+// CHECK1-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK1-NEXT:    [[ADD7:%.*]] = add nsw i64 [[TMP8]], 1
+// CHECK1-NEXT:    [[SUB8:%.*]] = sub nsw i64 [[ADD7]], 1
+// CHECK1-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
+// CHECK1-NEXT:    [[SUB9:%.*]] = sub nsw i64 [[SUB8]], [[TMP9]]
+// CHECK1-NEXT:    store i64 [[SUB9]], ptr [[DOTREVERSED_IV___BEGIN2]], align 8
+// CHECK1-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK1-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTREVERSED_IV___BEGIN2]], align 8
+// CHECK1-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP11]], 1
+// CHECK1-NEXT:    [[ADD_PTR10:%.*]] = getelementptr inbounds double, ptr [[TMP10]], i64 [[MUL]]
+// CHECK1-NEXT:    store ptr [[ADD_PTR10]], ptr [[__BEGIN2]], align 8
+// CHECK1-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[__BEGIN2]], align 8
+// CHECK1-NEXT:    store ptr [[TMP12]], ptr [[V]], align 8
+// CHECK1-NEXT:    [[TMP13:%.*]] = load ptr, ptr [[V]], align 8, !nonnull [[META2]], !align [[META10]]
+// CHECK1-NEXT:    [[TMP14:%.*]] = load double, ptr [[TMP13]], align 8
+// CHECK1-NEXT:    [[TMP15:%.*]] = load i32, ptr [[C]], align 4
+// CHECK1-NEXT:    call void (...) @body(double noundef [[TMP14]], i32 noundef [[TMP15]])
+// CHECK1-NEXT:    br label [[FOR_INC:%.*]]
+// CHECK1:       for.inc:
+// CHECK1-NEXT:    [[TMP16:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
+// CHECK1-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP16]], 1
+// CHECK1-NEXT:    store i64 [[INC]], ptr [[DOTFORWARD_IV___BEGIN2]], align 8
+// CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP11:![0-9]+]]
+// CHECK1:       for.end:
+// CHECK1-NEXT:    ret void
+//
+//
+// CHECK1-LABEL: define {{[^@]+}}@foo7
+// CHECK1-SAME: () #[[ATTR0]] {
+// CHECK1-NEXT:  entry:
+// CHECK1-NEXT:    [[A:%.*]] = alloca [128 x double], align 16
+// CHECK1-NEXT:    [[DOTOMP_IV:%.*]] = alloca i64, align 8
+// CHECK1-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[_TMP1:%.*]] = alloca i64, align 8
+// CHECK1-NEXT:    [[_TMP2:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[C:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[__RANGE3:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[__END3:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[__BEGIN3:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_5:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_6:%.*]] = alloca i64, align 8
+// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_8:%.*]] = alloca i64, align 8
+// CHECK1-NEXT:    [[DOTCAPTURE_EXPR_10:%.*]] = alloca i64, align 8
+// CHECK1-NEXT:    [[K:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTFORWARD_IV___BEGIN3:%.*]] = alloca i64, align 8
+// CHECK1-NEXT:    [[J:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTOMP_LB:%.*]] = alloca i64, align 8
+// CHECK1-NEXT:    [[DOTOMP_UB:%.*]] = alloca i64, align 8
+// CHECK1-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i64, align 8
+// CHECK1-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[K15:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTFORWARD_IV___BEGIN316:%.*]] = alloca i64, align 8
+// CHECK1-NEXT:    [[J17:%.*]] = alloca i32, align 4
+// CHECK1-NEXT:    [[DOTREVERSED_IV___BEGIN3:%.*]] = alloca i64, align 8
+// CHECK1-NEXT:    [[V:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
+// CHECK1-NEXT:    store i32 42, ptr [[C]], align 4
+// CHECK1-NEXT:    store ptr [[A]], ptr [[__RANGE3]], align 8
+// CHECK1-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[__RANGE3]], align 8, !nonnull [[META2]], !align [[META10]]
+// CHECK1-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0
+// CHECK1-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128
+// CHECK1-NEXT:    store ptr [[ADD_PTR]], ptr [[__END3]], align 8
+// CHECK1-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[__RANGE3]], align 8, !nonnull [[META2]], !align [[META10]]
+// CHECK1-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0
+// CHECK1-NEXT:    store ptr [[ARRAYDECAY3]], ptr [[__BEGIN3]], align 8
+// CHECK1-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[__RANGE3]], align 8, !nonnull [[META2]], !align [[META10]]
+// CHECK1-NEXT:    [[ARRAYDECAY4:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP3]], i64 0, i64 0
+// CHECK1-NEXT:    store ptr [[ARRAYDECAY4]], ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK1-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[__END3]], align 8
+// CHECK1-NEXT:    store ptr [[TMP4]], ptr [[DOTCAPTURE_EXPR_5]], align 8
+// CHECK1-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_5]], align 8
+// CHECK1-NEXT:    [[TMP6:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK1-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP5]] to i64
+// CHECK1-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP6]] to i64
+// CHECK1-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
+// CHECK1-NEXT:    [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8
+// CHECK1-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1
+// CHECK1-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
+// CHECK1-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
+// CHECK1-NEXT:    [[SUB7:%.*]] = sub nsw i64 [[DIV]], 1
+// CHECK1-NEXT:    store i64 [[SUB7]], ptr [[DOTCAPTURE_EXPR_6]], align 8
+// CHECK1-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_6]], align 8
+// CHECK1-NEXT:    [[ADD9:%.*]] = add nsw i64 [[TMP7]], 1
+// CHECK1-NEXT:    store i64 [[ADD9]], ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK1-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK1-NEXT:    [[SUB11:%.*]] = sub nsw i64 [[TMP8]], 0
+// CHECK1-NEXT:    [[DIV12:%.*]] = sdiv i64 [[SUB11]], 1
+// CHECK1-NEXT:    [[MUL:%.*]] = mul nsw i64 4, [[DIV12]]
+// CHECK1-NEXT:    [[MUL13:%.*]] = mul nsw i64 [[MUL]], 4
+// CHECK1-NEXT:    [[SUB14:%.*]] = sub nsw i64 [[MUL13]], 1
+// CHECK1-NEXT:    store i64 [[SUB14]], ptr [[DOTCAPTURE_EXPR_10]], align 8
+// CHECK1-NEXT:    store i32 7, ptr [[K]], align 4
+// CHECK1-NEXT:    store i64 0, ptr [[DOTFORWARD_IV___BEGIN3]], align 8
+// CHECK1-NEXT:    store i32 7, ptr [[J]], align 4
+// CHECK1-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK1-NEXT:    [[CMP:%.*]] = icmp slt i64 0, [[TMP9]]
+// CHECK1-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// CHECK1:       omp.precond.then:
+// CHECK1-NEXT:    store i64 0, ptr [[DOTOMP_LB]], align 8
+// CHECK1-NEXT:    [[TMP10:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8
+// CHECK1-NEXT:    store i64 [[TMP10]], ptr [[DOTOMP_UB]], align 8
+// CHECK1-NEXT:    store i64 1, ptr [[DOTOMP_STRIDE]], align 8
+// CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
+// CHECK1-NEXT:    call void @__kmpc_for_static_init_8(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1)
+// CHECK1-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8
+// CHECK1-NEXT:    [[TMP12:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8
+// CHECK1-NEXT:    [[CMP18:%.*]] = icmp sgt i64 [[TMP11]], [[TMP12]]
+// CHECK1-NEXT:    br i1 [[CMP18]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// CHECK1:       cond.true:
+// CHECK1-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8
+// CHECK1-NEXT:    br label [[COND_END:%.*]]
+// CHECK1:       cond.false:
+// CHECK1-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8
+// CHECK1-NEXT:    br label [[COND_END]]
+// CHECK1:       cond.end:
+// CHECK1-NEXT:    [[COND:%.*]] = phi i64 [ [[TMP13]], [[COND_TRUE]] ], [ [[TMP14]], [[COND_FALSE]] ]
+// CHECK1-NEXT:    store i64 [[COND]], ptr [[DOTOMP_UB]], align 8
+// CHECK1-NEXT:    [[TMP15:%.*]] = load i64, ptr [[DOTOMP_LB]], align 8
+// CHECK1-NEXT:    store i64 [[TMP15]], ptr [[DOTOMP_IV]], align 8
+// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// CHECK1:       omp.inner.for.cond:
+// CHECK1-NEXT:    [[TMP16:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK1-NEXT:    [[TMP17:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8
+// CHECK1-NEXT:    [[CMP19:%.*]] = icmp sle i64 [[TMP16]], [[TMP17]]
+// CHECK1-NEXT:    br i1 [[CMP19]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// CHECK1:       omp.inner.for.body:
+// CHECK1-NEXT:    [[TMP18:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK1-NEXT:    [[TMP19:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK1-NEXT:    [[SUB20:%.*]] = sub nsw i64 [[TMP19]], 0
+// CHECK1-NEXT:    [[DIV21:%.*]] = sdiv i64 [[SUB20]], 1
+// CHECK1-NEXT:    [[MUL22:%.*]] = mul nsw i64 1, [[DIV21]]
+// CHECK1-NEXT:    [[MUL23:%.*]] = mul nsw i64 [[MUL22]], 4
+// CHECK1-NEXT:    [[DIV24:%.*]] = sdiv i64 [[TMP18]], [[MUL23]]
+// CHECK1-NEXT:    [[MUL25:%.*]] = mul nsw i64 [[DIV24]], 3
+// CHECK1-NEXT:    [[ADD26:%.*]] = add nsw i64 7, [[MUL25]]
+// CHECK1-NEXT:    [[CONV:%.*]] = trunc i64 [[ADD26]] to i32
+// CHECK1-NEXT:    store i32 [[CONV]], ptr [[K15]], align 4
+// CHECK1-NEXT:    [[TMP20:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK1-NEXT:    [[TMP21:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK1-NEXT:    [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK1-NEXT:    [[SUB27:%.*]] = sub nsw i64 [[TMP22]], 0
+// CHECK1-NEXT:    [[DIV28:%.*]] = sdiv i64 [[SUB27]], 1
+// CHECK1-NEXT:    [[MUL29:%.*]] = mul nsw i64 1, [[DIV28]]
+// CHECK1-NEXT:    [[MUL30:%.*]] = mul nsw i64 [[MUL29]], 4
+// CHECK1-NEXT:    [[DIV31:%.*]] = sdiv i64 [[TMP21]], [[MUL30]]
+// CHECK1-NEXT:    [[TMP23:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK1-NEXT:    [[SUB32:%.*]] = sub nsw i64 [[TMP23]], 0
+// CHECK1-NEXT:    [[DIV33:%.*]] = sdiv i64 [[SUB32]], 1
+// CHECK1-NEXT:    [[MUL34:%.*]] = mul nsw i64 1, [[DIV33]]
+// CHECK1-NEXT:    [[MUL35:%.*]] = mul nsw i64 [[MUL34]], 4
+// CHECK1-NEXT:    [[MUL36:%.*]] = mul nsw i64 [[DIV31]], [[MUL35]]
+// CHECK1-NEXT:    [[SUB37:%.*]] = sub nsw i64 [[TMP20]], [[MUL36]]
+// CHECK1-NEXT:    [[DIV38:%.*]] = sdiv i64 [[SUB37]], 4
+// CHECK1-NEXT:    [[MUL39:%.*]] = mul nsw i64 [[DIV38]], 1
+// CHECK1-NEXT:    [[ADD40:%.*]] = add nsw i64 0, [[MUL39]]
+// CHECK1-NEXT:    store i64 [[ADD40]], ptr [[DOTFORWARD_IV___BEGIN316]], align 8
+// CHECK1-NEXT:    [[TMP24:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK1-NEXT:    [[TMP25:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK1-NEXT:    [[TMP26:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK1-NEXT:    [[SUB41:%.*]] = sub nsw i64 [[TMP26]], 0
+// CHECK1-NEXT:    [[DIV42:%.*]] = sdiv i64 [[SUB41]], 1
+// CHECK1-NEXT:    [[MUL43:%.*]] = mul nsw i64 1, [[DIV42]]
+// CHECK1-NEXT:    [[MUL44:%.*]] = mul nsw i64 [[MUL43]], 4
+// CHECK1-NEXT:    [[DIV45:%.*]] = sdiv i64 [[TMP25]], [[MUL44]]
+// CHECK1-NEXT:    [[TMP27:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK1-NEXT:    [[SUB46:%.*]] = sub nsw i64 [[TMP27]], 0
+// CHECK1-NEXT:    [[DIV47:%.*]] = sdiv i64 [[SUB46]], 1
+// CHECK1-NEXT:    [[MUL48:%.*]] = mul nsw i64 1, [[DIV47]]
+// CHECK1-NEXT:    [[MUL49:%.*]] = mul nsw i64 [[MUL48]], 4
+// CHECK1-NEXT:    [[MUL50:%.*]] = mul nsw i64 [[DIV45]], [[MUL49]]
+// CHECK1-NEXT:    [[SUB51:%.*]] = sub nsw i64 [[TMP24]], [[MUL50]]
+// CHECK1-NEXT:    [[TMP28:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK1-NEXT:    [[TMP29:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK1-NEXT:    [[TMP30:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK1-NEXT:    [[SUB52:%.*]] = sub nsw i64 [[TMP30]], 0
+// CHECK1-NEXT:    [[DIV53:%.*]] = sdiv i64 [[SUB52]], 1
+// CHECK1-NEXT:    [[MUL54:%.*]] = mul nsw i64 1, [[DIV53]]
+// CHECK1-NEXT:    [[MUL55:%.*]] = mul nsw i64 [[MUL54]], 4
+// CHECK1-NEXT:    [[DIV56:%.*]] = sdiv i64 [[TMP29]], [[MUL55]]
+// CHECK1-NEXT:    [[TMP31:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK1-NEXT:    [[SUB57:%.*]] = sub nsw i64 [[TMP31]], 0
+// CHECK1-NEXT:    [[DIV58:%.*]] = sdiv i64 [[SUB57]], 1
+// CHECK1-NEXT:    [[MUL59:%.*]] = mul nsw i64 1, [[DIV58]]
+// CHECK1-NEXT:    [[MUL60:%.*]] = mul nsw i64 [[MUL59]], 4
+// CHECK1-NEXT:    [[MUL61:%.*]] = mul nsw i64 [[DIV56]], [[MUL60]]
+// CHECK1-NEXT:    [[SUB62:%.*]] = sub nsw i64 [[TMP28]], [[MUL61]]
+// CHECK1-NEXT:    [[DIV63:%.*]] = sdiv i64 [[SUB62]], 4
+// CHECK1-NEXT:    [[MUL64:%.*]] = mul nsw i64 [[DIV63]], 4
+// CHECK1-NEXT:    [[SUB65:%.*]] = sub nsw i64 [[SUB51]], [[MUL64]]
+// CHECK1-NEXT:    [[MUL66:%.*]] = mul nsw i64 [[SUB65]], 3
+// CHECK1-NEXT:    [[ADD67:%.*]] = add nsw i64 7, [[MUL66]]
+// CHECK1-NEXT:    [[CONV68:%.*]] = trunc i64 [[ADD67]] to i32
+// CHECK1-NEXT:    store i32 [[CONV68]], ptr [[J17]], align 4
+// CHECK1-NEXT:    [[TMP32:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_6]], align 8
+// CHECK1-NEXT:    [[ADD69:%.*]] = add nsw i64 [[TMP32]], 1
+// CHECK1-NEXT:    [[SUB70:%.*]] = sub nsw i64 [[ADD69]], 1
+// CHECK1-NEXT:    [[TMP33:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN316]], align 8
+// CHECK1-NEXT:    [[SUB71:%.*]] = sub nsw i64 [[SUB70]], [[TMP33]]
+// CHECK1-NEXT:    store i64 [[SUB71]], ptr [[DOTREVERSED_IV___BEGIN3]], align 8
+// CHECK1-NEXT:    [[TMP34:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK1-NEXT:    [[TMP35:%.*]] = load i64, ptr [[DOTREVERSED_IV___BEGIN3]], align 8
+// CHECK1-NEXT:    [[MUL72:%.*]] = mul nsw i64 [[TMP35]], 1
+// CHECK1-NEXT:    [[ADD_PTR73:%.*]] = getelementptr inbounds double, ptr [[TMP34]], i64 [[MUL72]]
+// CHECK1-NEXT:    store ptr [[ADD_PTR73]], ptr [[__BEGIN3]], align 8
+// CHECK1-NEXT:    [[TMP36:%.*]] = load ptr, ptr [[__BEGIN3]], align 8
+// CHECK1-NEXT:    store ptr [[TMP36]], ptr [[V]], align 8
+// CHECK1-NEXT:    [[TMP37:%.*]] = load i32, ptr [[K15]], align 4
+// CHECK1-NEXT:    [[TMP38:%.*]] = load i32, ptr [[C]], align 4
+// CHECK1-NEXT:    [[TMP39:%.*]] = load ptr, ptr [[V]], align 8, !nonnull [[META2]], !align [[META10]]
+// CHECK1-NEXT:    [[TMP40:%.*]] = load double, ptr [[TMP39]], align 8
+// CHECK1-NEXT:    [[TMP41:%.*]] = load i32, ptr [[J17]], align 4
+// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP37]], i32 noundef [[TMP38]], double noundef [[TMP40]], i32 noundef [[TMP41]])
+// CHECK1-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// CHECK1:       omp.body.continue:
+// CHECK1-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// CHECK1:       omp.inner.for.inc:
+// CHECK1-NEXT:    [[TMP42:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK1-NEXT:    [[ADD74:%.*]] = add nsw i64 [[TMP42]], 1
+// CHECK1-NEXT:    store i64 [[ADD74]], ptr [[DOTOMP_IV]], align 8
+// CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// CHECK1:       omp.inner.for.end:
+// CHECK1-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// CHECK1:       omp.loop.exit:
+// CHECK1-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
+// CHECK1-NEXT:    br label [[OMP_PRECOND_END]]
+// CHECK1:       omp.precond.end:
+// CHECK1-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]])
+// CHECK1-NEXT:    ret void
+//
+//
+// CHECK1-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_reverse_codegen.cpp
+// CHECK1-SAME: () #[[ATTR1]] section ".text.startup" {
+// CHECK1-NEXT:  entry:
+// CHECK1-NEXT:    call void @__cxx_global_var_init()
+// CHECK1-NEXT:    ret void
+//
+//
+// CHECK2-LABEL: define {{[^@]+}}@__cxx_global_var_init
+// CHECK2-SAME: () #[[ATTR0:[0-9]+]] section ".text.startup" {
+// CHECK2-NEXT:  entry:
+// CHECK2-NEXT:    call void @_ZN1SC1Ev(ptr noundef nonnull align 4 dereferenceable(4) @s)
+// CHECK2-NEXT:    ret void
+//
+//
+// CHECK2-LABEL: define {{[^@]+}}@_ZN1SC1Ev
+// CHECK2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 {
+// CHECK2-NEXT:  entry:
+// CHECK2-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
+// CHECK2-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
+// CHECK2-NEXT:    call void @_ZN1SC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]])
+// CHECK2-NEXT:    ret void
+//
+//
+// CHECK2-LABEL: define {{[^@]+}}@_ZN1SC2Ev
+// CHECK2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 {
+// CHECK2-NEXT:  entry:
+// CHECK2-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[I2:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
+// CHECK2-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
+// CHECK2-NEXT:    [[I:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0
+// CHECK2-NEXT:    store i32 7, ptr [[I]], align 4
+// CHECK2-NEXT:    [[I3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0
+// CHECK2-NEXT:    store ptr [[I3]], ptr [[I2]], align 8
+// CHECK2-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    br label [[FOR_COND:%.*]]
+// CHECK2:       for.cond:
+// CHECK2-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 4
+// CHECK2-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK2:       for.body:
+// CHECK2-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    [[SUB:%.*]] = sub nsw i32 3, [[TMP1]]
+// CHECK2-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK2-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK2-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], 3
+// CHECK2-NEXT:    [[ADD:%.*]] = add nsw i32 7, [[MUL]]
+// CHECK2-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2:![0-9]+]], !align [[META3:![0-9]+]]
+// CHECK2-NEXT:    store i32 [[ADD]], ptr [[TMP3]], align 4
+// CHECK2-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK2-NEXT:    [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4
+// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP5]])
+// CHECK2-NEXT:    br label [[FOR_INC:%.*]]
+// CHECK2:       for.inc:
+// CHECK2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
+// CHECK2-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
+// CHECK2:       for.end:
+// CHECK2-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK2-NEXT:    store i32 16, ptr [[TMP7]], align 4
+// CHECK2-NEXT:    ret void
+//
+//
+// CHECK2-LABEL: define {{[^@]+}}@body
+// CHECK2-SAME: (...) #[[ATTR1]] {
+// CHECK2-NEXT:  entry:
+// CHECK2-NEXT:    ret void
+//
+//
+// CHECK2-LABEL: define {{[^@]+}}@foo1
+// CHECK2-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]], i32 noundef [[STEP:%.*]]) #[[ATTR1]] {
+// CHECK2-NEXT:  entry:
+// CHECK2-NEXT:    [[START_ADDR:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[END_ADDR:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[STEP_ADDR:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTNEW_STEP:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    store i32 [[START]], ptr [[START_ADDR]], align 4
+// CHECK2-NEXT:    store i32 [[END]], ptr [[END_ADDR]], align 4
+// CHECK2-NEXT:    store i32 [[STEP]], ptr [[STEP_ADDR]], align 4
+// CHECK2-NEXT:    [[TMP0:%.*]] = load i32, ptr [[START_ADDR]], align 4
+// CHECK2-NEXT:    store i32 [[TMP0]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[TMP1:%.*]] = load i32, ptr [[START_ADDR]], align 4
+// CHECK2-NEXT:    store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[TMP2:%.*]] = load i32, ptr [[END_ADDR]], align 4
+// CHECK2-NEXT:    store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK2-NEXT:    [[TMP3:%.*]] = load i32, ptr [[STEP_ADDR]], align 4
+// CHECK2-NEXT:    store i32 [[TMP3]], ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK2-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB:%.*]] = sub i32 [[TMP4]], [[TMP5]]
+// CHECK2-NEXT:    [[SUB3:%.*]] = sub i32 [[SUB]], 1
+// CHECK2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[ADD:%.*]] = add i32 [[SUB3]], [[TMP6]]
+// CHECK2-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[DIV:%.*]] = udiv i32 [[ADD]], [[TMP7]]
+// CHECK2-NEXT:    [[SUB4:%.*]] = sub i32 [[DIV]], 1
+// CHECK2-NEXT:    store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4
+// CHECK2-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    br label [[FOR_COND:%.*]]
+// CHECK2:       for.cond:
+// CHECK2-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
+// CHECK2-NEXT:    [[ADD5:%.*]] = add i32 [[TMP9]], 1
+// CHECK2-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP8]], [[ADD5]]
+// CHECK2-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK2:       for.body:
+// CHECK2-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
+// CHECK2-NEXT:    [[ADD6:%.*]] = add i32 [[TMP10]], 1
+// CHECK2-NEXT:    [[SUB7:%.*]] = sub i32 [[ADD6]], 1
+// CHECK2-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    [[SUB8:%.*]] = sub i32 [[SUB7]], [[TMP11]]
+// CHECK2-NEXT:    store i32 [[SUB8]], ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK2-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK2-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[MUL:%.*]] = mul i32 [[TMP13]], [[TMP14]]
+// CHECK2-NEXT:    [[ADD9:%.*]] = add i32 [[TMP12]], [[MUL]]
+// CHECK2-NEXT:    store i32 [[ADD9]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[TMP15:%.*]] = load i32, ptr [[I]], align 4
+// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP15]])
+// CHECK2-NEXT:    br label [[FOR_INC:%.*]]
+// CHECK2:       for.inc:
+// CHECK2-NEXT:    [[TMP16:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    [[INC:%.*]] = add i32 [[TMP16]], 1
+// CHECK2-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
+// CHECK2:       for.end:
+// CHECK2-NEXT:    [[TMP17:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK2-NEXT:    [[TMP19:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB10:%.*]] = sub i32 [[TMP18]], [[TMP19]]
+// CHECK2-NEXT:    [[SUB11:%.*]] = sub i32 [[SUB10]], 1
+// CHECK2-NEXT:    [[TMP20:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[ADD12:%.*]] = add i32 [[SUB11]], [[TMP20]]
+// CHECK2-NEXT:    [[TMP21:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[DIV13:%.*]] = udiv i32 [[ADD12]], [[TMP21]]
+// CHECK2-NEXT:    [[SUB14:%.*]] = sub i32 [[DIV13]], 1
+// CHECK2-NEXT:    [[TMP22:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[MUL15:%.*]] = mul i32 [[SUB14]], [[TMP22]]
+// CHECK2-NEXT:    [[ADD16:%.*]] = add i32 [[TMP17]], [[MUL15]]
+// CHECK2-NEXT:    store i32 [[ADD16]], ptr [[I]], align 4
+// CHECK2-NEXT:    ret void
+//
+//
+// CHECK2-LABEL: define {{[^@]+}}@foo2
+// CHECK2-SAME: () #[[ATTR1]] {
+// CHECK2-NEXT:  entry:
+// CHECK2-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:[0-9]+]])
+// CHECK2-NEXT:    store i32 7, ptr [[I]], align 4
+// CHECK2-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
+// CHECK2-NEXT:    store i32 3, ptr [[DOTOMP_UB]], align 4
+// CHECK2-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
+// CHECK2-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
+// CHECK2-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
+// CHECK2-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK2-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 3
+// CHECK2-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// CHECK2:       cond.true:
+// CHECK2-NEXT:    br label [[COND_END:%.*]]
+// CHECK2:       cond.false:
+// CHECK2-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK2-NEXT:    br label [[COND_END]]
+// CHECK2:       cond.end:
+// CHECK2-NEXT:    [[COND:%.*]] = phi i32 [ 3, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ]
+// CHECK2-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
+// CHECK2-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
+// CHECK2-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// CHECK2:       omp.inner.for.cond:
+// CHECK2-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK2-NEXT:    [[CMP1:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]]
+// CHECK2-NEXT:    br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// CHECK2:       omp.inner.for.body:
+// CHECK2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP6]], 1
+// CHECK2-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
+// CHECK2-NEXT:    store i32 [[ADD]], ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    [[SUB:%.*]] = sub nsw i32 3, [[TMP7]]
+// CHECK2-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK2-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK2-NEXT:    [[MUL2:%.*]] = mul nsw i32 [[TMP8]], 3
+// CHECK2-NEXT:    [[ADD3:%.*]] = add nsw i32 7, [[MUL2]]
+// CHECK2-NEXT:    store i32 [[ADD3]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[TMP9:%.*]] = load i32, ptr [[I]], align 4
+// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP9]])
+// CHECK2-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// CHECK2:       omp.body.continue:
+// CHECK2-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// CHECK2:       omp.inner.for.inc:
+// CHECK2-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    [[ADD4:%.*]] = add nsw i32 [[TMP10]], 1
+// CHECK2-NEXT:    store i32 [[ADD4]], ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// CHECK2:       omp.inner.for.end:
+// CHECK2-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// CHECK2:       omp.loop.exit:
+// CHECK2-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
+// CHECK2-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3:[0-9]+]], i32 [[TMP0]])
+// CHECK2-NEXT:    ret void
+//
+//
+// CHECK2-LABEL: define {{[^@]+}}@foo3
+// CHECK2-SAME: () #[[ATTR1]] {
+// CHECK2-NEXT:  entry:
+// CHECK2-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[_TMP1:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[_TMP2:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[K:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[J:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
+// CHECK2-NEXT:    store i32 7, ptr [[I]], align 4
+// CHECK2-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
+// CHECK2-NEXT:    store i32 63, ptr [[DOTOMP_UB]], align 4
+// CHECK2-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
+// CHECK2-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
+// CHECK2-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
+// CHECK2-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK2-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 63
+// CHECK2-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// CHECK2:       cond.true:
+// CHECK2-NEXT:    br label [[COND_END:%.*]]
+// CHECK2:       cond.false:
+// CHECK2-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK2-NEXT:    br label [[COND_END]]
+// CHECK2:       cond.end:
+// CHECK2-NEXT:    [[COND:%.*]] = phi i32 [ 63, [[COND_TRUE]] ], [ [[TMP2]], [[COND_FALSE]] ]
+// CHECK2-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
+// CHECK2-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
+// CHECK2-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// CHECK2:       omp.inner.for.cond:
+// CHECK2-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK2-NEXT:    [[CMP3:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]]
+// CHECK2-NEXT:    br i1 [[CMP3]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// CHECK2:       omp.inner.for.body:
+// CHECK2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    [[DIV:%.*]] = sdiv i32 [[TMP6]], 16
+// CHECK2-NEXT:    [[MUL:%.*]] = mul nsw i32 [[DIV]], 3
+// CHECK2-NEXT:    [[ADD:%.*]] = add nsw i32 7, [[MUL]]
+// CHECK2-NEXT:    store i32 [[ADD]], ptr [[K]], align 4
+// CHECK2-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    [[DIV4:%.*]] = sdiv i32 [[TMP8]], 16
+// CHECK2-NEXT:    [[MUL5:%.*]] = mul nsw i32 [[DIV4]], 16
+// CHECK2-NEXT:    [[SUB:%.*]] = sub nsw i32 [[TMP7]], [[MUL5]]
+// CHECK2-NEXT:    [[DIV6:%.*]] = sdiv i32 [[SUB]], 4
+// CHECK2-NEXT:    [[MUL7:%.*]] = mul nsw i32 [[DIV6]], 1
+// CHECK2-NEXT:    [[ADD8:%.*]] = add nsw i32 0, [[MUL7]]
+// CHECK2-NEXT:    store i32 [[ADD8]], ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    [[DIV9:%.*]] = sdiv i32 [[TMP10]], 16
+// CHECK2-NEXT:    [[MUL10:%.*]] = mul nsw i32 [[DIV9]], 16
+// CHECK2-NEXT:    [[SUB11:%.*]] = sub nsw i32 [[TMP9]], [[MUL10]]
+// CHECK2-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    [[DIV12:%.*]] = sdiv i32 [[TMP12]], 16
+// CHECK2-NEXT:    [[MUL13:%.*]] = mul nsw i32 [[DIV12]], 16
+// CHECK2-NEXT:    [[SUB14:%.*]] = sub nsw i32 [[TMP11]], [[MUL13]]
+// CHECK2-NEXT:    [[DIV15:%.*]] = sdiv i32 [[SUB14]], 4
+// CHECK2-NEXT:    [[MUL16:%.*]] = mul nsw i32 [[DIV15]], 4
+// CHECK2-NEXT:    [[SUB17:%.*]] = sub nsw i32 [[SUB11]], [[MUL16]]
+// CHECK2-NEXT:    [[MUL18:%.*]] = mul nsw i32 [[SUB17]], 3
+// CHECK2-NEXT:    [[ADD19:%.*]] = add nsw i32 7, [[MUL18]]
+// CHECK2-NEXT:    store i32 [[ADD19]], ptr [[J]], align 4
+// CHECK2-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    [[SUB20:%.*]] = sub nsw i32 3, [[TMP13]]
+// CHECK2-NEXT:    store i32 [[SUB20]], ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK2-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK2-NEXT:    [[MUL21:%.*]] = mul nsw i32 [[TMP14]], 3
+// CHECK2-NEXT:    [[ADD22:%.*]] = add nsw i32 7, [[MUL21]]
+// CHECK2-NEXT:    store i32 [[ADD22]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[TMP15:%.*]] = load i32, ptr [[K]], align 4
+// CHECK2-NEXT:    [[TMP16:%.*]] = load i32, ptr [[I]], align 4
+// CHECK2-NEXT:    [[TMP17:%.*]] = load i32, ptr [[J]], align 4
+// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP15]], i32 noundef [[TMP16]], i32 noundef [[TMP17]])
+// CHECK2-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// CHECK2:       omp.body.continue:
+// CHECK2-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// CHECK2:       omp.inner.for.inc:
+// CHECK2-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    [[ADD23:%.*]] = add nsw i32 [[TMP18]], 1
+// CHECK2-NEXT:    store i32 [[ADD23]], ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// CHECK2:       omp.inner.for.end:
+// CHECK2-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// CHECK2:       omp.loop.exit:
+// CHECK2-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
+// CHECK2-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]])
+// CHECK2-NEXT:    ret void
+//
+//
+// CHECK2-LABEL: define {{[^@]+}}@foo4
+// CHECK2-SAME: () #[[ATTR1]] {
+// CHECK2-NEXT:  entry:
+// CHECK2-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 0, ptr @foo4.omp_outlined)
+// CHECK2-NEXT:    ret void
+//
+//
+// CHECK2-LABEL: define {{[^@]+}}@foo4.omp_outlined
+// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR4:[0-9]+]] {
+// CHECK2-NEXT:  entry:
+// CHECK2-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
+// CHECK2-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
+// CHECK2-NEXT:    store i32 7, ptr [[I]], align 4
+// CHECK2-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
+// CHECK2-NEXT:    store i32 3, ptr [[DOTOMP_UB]], align 4
+// CHECK2-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
+// CHECK2-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
+// CHECK2-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
+// CHECK2-NEXT:    [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4
+// CHECK2-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
+// CHECK2-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK2-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 3
+// CHECK2-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// CHECK2:       cond.true:
+// CHECK2-NEXT:    br label [[COND_END:%.*]]
+// CHECK2:       cond.false:
+// CHECK2-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK2-NEXT:    br label [[COND_END]]
+// CHECK2:       cond.end:
+// CHECK2-NEXT:    [[COND:%.*]] = phi i32 [ 3, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ]
+// CHECK2-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
+// CHECK2-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
+// CHECK2-NEXT:    store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// CHECK2:       omp.inner.for.cond:
+// CHECK2-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK2-NEXT:    [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]]
+// CHECK2-NEXT:    br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// CHECK2:       omp.inner.for.body:
+// CHECK2-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1
+// CHECK2-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
+// CHECK2-NEXT:    store i32 [[ADD]], ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    [[SUB:%.*]] = sub nsw i32 3, [[TMP8]]
+// CHECK2-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK2-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK2-NEXT:    [[MUL2:%.*]] = mul nsw i32 [[TMP9]], 3
+// CHECK2-NEXT:    [[ADD3:%.*]] = add nsw i32 7, [[MUL2]]
+// CHECK2-NEXT:    store i32 [[ADD3]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[TMP10:%.*]] = load i32, ptr [[I]], align 4
+// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP10]])
+// CHECK2-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// CHECK2:       omp.body.continue:
+// CHECK2-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// CHECK2:       omp.inner.for.inc:
+// CHECK2-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    [[ADD4:%.*]] = add nsw i32 [[TMP11]], 1
+// CHECK2-NEXT:    store i32 [[ADD4]], ptr [[DOTOMP_IV]], align 4
+// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// CHECK2:       omp.inner.for.end:
+// CHECK2-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// CHECK2:       omp.loop.exit:
+// CHECK2-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]])
+// CHECK2-NEXT:    ret void
+//
+//
+// CHECK2-LABEL: define {{[^@]+}}@foo6
+// CHECK2-SAME: () #[[ATTR1]] {
+// CHECK2-NEXT:  entry:
+// CHECK2-NEXT:    [[ARR:%.*]] = alloca [128 x double], align 16
+// CHECK2-NEXT:    [[C:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[__RANGE2:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[__END2:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[__BEGIN2:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_3:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8
+// CHECK2-NEXT:    [[DOTFORWARD_IV___BEGIN2:%.*]] = alloca i64, align 8
+// CHECK2-NEXT:    [[DOTREVERSED_IV___BEGIN2:%.*]] = alloca i64, align 8
+// CHECK2-NEXT:    [[V:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    store i32 42, ptr [[C]], align 4
+// CHECK2-NEXT:    store ptr [[ARR]], ptr [[__RANGE2]], align 8
+// CHECK2-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[__RANGE2]], align 8, !nonnull [[META2]], !align [[META9:![0-9]+]]
+// CHECK2-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP0]], i64 0, i64 0
+// CHECK2-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128
+// CHECK2-NEXT:    store ptr [[ADD_PTR]], ptr [[__END2]], align 8
+// CHECK2-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[__RANGE2]], align 8, !nonnull [[META2]], !align [[META9]]
+// CHECK2-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0
+// CHECK2-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[__BEGIN2]], align 8
+// CHECK2-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[__RANGE2]], align 8, !nonnull [[META2]], !align [[META9]]
+// CHECK2-NEXT:    [[ARRAYDECAY2:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0
+// CHECK2-NEXT:    store ptr [[ARRAYDECAY2]], ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK2-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[__END2]], align 8
+// CHECK2-NEXT:    store ptr [[TMP3]], ptr [[DOTCAPTURE_EXPR_3]], align 8
+// CHECK2-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_3]], align 8
+// CHECK2-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK2-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP4]] to i64
+// CHECK2-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP5]] to i64
+// CHECK2-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
+// CHECK2-NEXT:    [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8
+// CHECK2-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1
+// CHECK2-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
+// CHECK2-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
+// CHECK2-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
+// CHECK2-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK2-NEXT:    store i64 0, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
+// CHECK2-NEXT:    br label [[FOR_COND:%.*]]
+// CHECK2:       for.cond:
+// CHECK2-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
+// CHECK2-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK2-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP7]], 1
+// CHECK2-NEXT:    [[CMP:%.*]] = icmp slt i64 [[TMP6]], [[ADD6]]
+// CHECK2-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK2:       for.body:
+// CHECK2-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK2-NEXT:    [[ADD7:%.*]] = add nsw i64 [[TMP8]], 1
+// CHECK2-NEXT:    [[SUB8:%.*]] = sub nsw i64 [[ADD7]], 1
+// CHECK2-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
+// CHECK2-NEXT:    [[SUB9:%.*]] = sub nsw i64 [[SUB8]], [[TMP9]]
+// CHECK2-NEXT:    store i64 [[SUB9]], ptr [[DOTREVERSED_IV___BEGIN2]], align 8
+// CHECK2-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK2-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTREVERSED_IV___BEGIN2]], align 8
+// CHECK2-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP11]], 1
+// CHECK2-NEXT:    [[ADD_PTR10:%.*]] = getelementptr inbounds double, ptr [[TMP10]], i64 [[MUL]]
+// CHECK2-NEXT:    store ptr [[ADD_PTR10]], ptr [[__BEGIN2]], align 8
+// CHECK2-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[__BEGIN2]], align 8
+// CHECK2-NEXT:    store ptr [[TMP12]], ptr [[V]], align 8
+// CHECK2-NEXT:    [[TMP13:%.*]] = load ptr, ptr [[V]], align 8, !nonnull [[META2]], !align [[META9]]
+// CHECK2-NEXT:    [[TMP14:%.*]] = load double, ptr [[TMP13]], align 8
+// CHECK2-NEXT:    [[TMP15:%.*]] = load i32, ptr [[C]], align 4
+// CHECK2-NEXT:    call void (...) @body(double noundef [[TMP14]], i32 noundef [[TMP15]])
+// CHECK2-NEXT:    br label [[FOR_INC:%.*]]
+// CHECK2:       for.inc:
+// CHECK2-NEXT:    [[TMP16:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN2]], align 8
+// CHECK2-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP16]], 1
+// CHECK2-NEXT:    store i64 [[INC]], ptr [[DOTFORWARD_IV___BEGIN2]], align 8
+// CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP10:![0-9]+]]
+// CHECK2:       for.end:
+// CHECK2-NEXT:    ret void
+//
+//
+// CHECK2-LABEL: define {{[^@]+}}@foo7
+// CHECK2-SAME: () #[[ATTR1]] {
+// CHECK2-NEXT:  entry:
+// CHECK2-NEXT:    [[A:%.*]] = alloca [128 x double], align 16
+// CHECK2-NEXT:    [[DOTOMP_IV:%.*]] = alloca i64, align 8
+// CHECK2-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[_TMP1:%.*]] = alloca i64, align 8
+// CHECK2-NEXT:    [[_TMP2:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[C:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[__RANGE3:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[__END3:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[__BEGIN3:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_5:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_6:%.*]] = alloca i64, align 8
+// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_8:%.*]] = alloca i64, align 8
+// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_10:%.*]] = alloca i64, align 8
+// CHECK2-NEXT:    [[K:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTFORWARD_IV___BEGIN3:%.*]] = alloca i64, align 8
+// CHECK2-NEXT:    [[J:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTOMP_LB:%.*]] = alloca i64, align 8
+// CHECK2-NEXT:    [[DOTOMP_UB:%.*]] = alloca i64, align 8
+// CHECK2-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i64, align 8
+// CHECK2-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[K15:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTFORWARD_IV___BEGIN316:%.*]] = alloca i64, align 8
+// CHECK2-NEXT:    [[J17:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTREVERSED_IV___BEGIN3:%.*]] = alloca i64, align 8
+// CHECK2-NEXT:    [[V:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
+// CHECK2-NEXT:    store i32 42, ptr [[C]], align 4
+// CHECK2-NEXT:    store ptr [[A]], ptr [[__RANGE3]], align 8
+// CHECK2-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[__RANGE3]], align 8, !nonnull [[META2]], !align [[META9]]
+// CHECK2-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP1]], i64 0, i64 0
+// CHECK2-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 128
+// CHECK2-NEXT:    store ptr [[ADD_PTR]], ptr [[__END3]], align 8
+// CHECK2-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[__RANGE3]], align 8, !nonnull [[META2]], !align [[META9]]
+// CHECK2-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP2]], i64 0, i64 0
+// CHECK2-NEXT:    store ptr [[ARRAYDECAY3]], ptr [[__BEGIN3]], align 8
+// CHECK2-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[__RANGE3]], align 8, !nonnull [[META2]], !align [[META9]]
+// CHECK2-NEXT:    [[ARRAYDECAY4:%.*]] = getelementptr inbounds [128 x double], ptr [[TMP3]], i64 0, i64 0
+// CHECK2-NEXT:    store ptr [[ARRAYDECAY4]], ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK2-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[__END3]], align 8
+// CHECK2-NEXT:    store ptr [[TMP4]], ptr [[DOTCAPTURE_EXPR_5]], align 8
+// CHECK2-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_5]], align 8
+// CHECK2-NEXT:    [[TMP6:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK2-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP5]] to i64
+// CHECK2-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP6]] to i64
+// CHECK2-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
+// CHECK2-NEXT:    [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8
+// CHECK2-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1
+// CHECK2-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
+// CHECK2-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
+// CHECK2-NEXT:    [[SUB7:%.*]] = sub nsw i64 [[DIV]], 1
+// CHECK2-NEXT:    store i64 [[SUB7]], ptr [[DOTCAPTURE_EXPR_6]], align 8
+// CHECK2-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_6]], align 8
+// CHECK2-NEXT:    [[ADD9:%.*]] = add nsw i64 [[TMP7]], 1
+// CHECK2-NEXT:    store i64 [[ADD9]], ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK2-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK2-NEXT:    [[SUB11:%.*]] = sub nsw i64 [[TMP8]], 0
+// CHECK2-NEXT:    [[DIV12:%.*]] = sdiv i64 [[SUB11]], 1
+// CHECK2-NEXT:    [[MUL:%.*]] = mul nsw i64 4, [[DIV12]]
+// CHECK2-NEXT:    [[MUL13:%.*]] = mul nsw i64 [[MUL]], 4
+// CHECK2-NEXT:    [[SUB14:%.*]] = sub nsw i64 [[MUL13]], 1
+// CHECK2-NEXT:    store i64 [[SUB14]], ptr [[DOTCAPTURE_EXPR_10]], align 8
+// CHECK2-NEXT:    store i32 7, ptr [[K]], align 4
+// CHECK2-NEXT:    store i64 0, ptr [[DOTFORWARD_IV___BEGIN3]], align 8
+// CHECK2-NEXT:    store i32 7, ptr [[J]], align 4
+// CHECK2-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK2-NEXT:    [[CMP:%.*]] = icmp slt i64 0, [[TMP9]]
+// CHECK2-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
+// CHECK2:       omp.precond.then:
+// CHECK2-NEXT:    store i64 0, ptr [[DOTOMP_LB]], align 8
+// CHECK2-NEXT:    [[TMP10:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8
+// CHECK2-NEXT:    store i64 [[TMP10]], ptr [[DOTOMP_UB]], align 8
+// CHECK2-NEXT:    store i64 1, ptr [[DOTOMP_STRIDE]], align 8
+// CHECK2-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
+// CHECK2-NEXT:    call void @__kmpc_for_static_init_8(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1)
+// CHECK2-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8
+// CHECK2-NEXT:    [[TMP12:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8
+// CHECK2-NEXT:    [[CMP18:%.*]] = icmp sgt i64 [[TMP11]], [[TMP12]]
+// CHECK2-NEXT:    br i1 [[CMP18]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// CHECK2:       cond.true:
+// CHECK2-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_10]], align 8
+// CHECK2-NEXT:    br label [[COND_END:%.*]]
+// CHECK2:       cond.false:
+// CHECK2-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8
+// CHECK2-NEXT:    br label [[COND_END]]
+// CHECK2:       cond.end:
+// CHECK2-NEXT:    [[COND:%.*]] = phi i64 [ [[TMP13]], [[COND_TRUE]] ], [ [[TMP14]], [[COND_FALSE]] ]
+// CHECK2-NEXT:    store i64 [[COND]], ptr [[DOTOMP_UB]], align 8
+// CHECK2-NEXT:    [[TMP15:%.*]] = load i64, ptr [[DOTOMP_LB]], align 8
+// CHECK2-NEXT:    store i64 [[TMP15]], ptr [[DOTOMP_IV]], align 8
+// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
+// CHECK2:       omp.inner.for.cond:
+// CHECK2-NEXT:    [[TMP16:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK2-NEXT:    [[TMP17:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8
+// CHECK2-NEXT:    [[CMP19:%.*]] = icmp sle i64 [[TMP16]], [[TMP17]]
+// CHECK2-NEXT:    br i1 [[CMP19]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// CHECK2:       omp.inner.for.body:
+// CHECK2-NEXT:    [[TMP18:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK2-NEXT:    [[TMP19:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK2-NEXT:    [[SUB20:%.*]] = sub nsw i64 [[TMP19]], 0
+// CHECK2-NEXT:    [[DIV21:%.*]] = sdiv i64 [[SUB20]], 1
+// CHECK2-NEXT:    [[MUL22:%.*]] = mul nsw i64 1, [[DIV21]]
+// CHECK2-NEXT:    [[MUL23:%.*]] = mul nsw i64 [[MUL22]], 4
+// CHECK2-NEXT:    [[DIV24:%.*]] = sdiv i64 [[TMP18]], [[MUL23]]
+// CHECK2-NEXT:    [[MUL25:%.*]] = mul nsw i64 [[DIV24]], 3
+// CHECK2-NEXT:    [[ADD26:%.*]] = add nsw i64 7, [[MUL25]]
+// CHECK2-NEXT:    [[CONV:%.*]] = trunc i64 [[ADD26]] to i32
+// CHECK2-NEXT:    store i32 [[CONV]], ptr [[K15]], align 4
+// CHECK2-NEXT:    [[TMP20:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK2-NEXT:    [[TMP21:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK2-NEXT:    [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK2-NEXT:    [[SUB27:%.*]] = sub nsw i64 [[TMP22]], 0
+// CHECK2-NEXT:    [[DIV28:%.*]] = sdiv i64 [[SUB27]], 1
+// CHECK2-NEXT:    [[MUL29:%.*]] = mul nsw i64 1, [[DIV28]]
+// CHECK2-NEXT:    [[MUL30:%.*]] = mul nsw i64 [[MUL29]], 4
+// CHECK2-NEXT:    [[DIV31:%.*]] = sdiv i64 [[TMP21]], [[MUL30]]
+// CHECK2-NEXT:    [[TMP23:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK2-NEXT:    [[SUB32:%.*]] = sub nsw i64 [[TMP23]], 0
+// CHECK2-NEXT:    [[DIV33:%.*]] = sdiv i64 [[SUB32]], 1
+// CHECK2-NEXT:    [[MUL34:%.*]] = mul nsw i64 1, [[DIV33]]
+// CHECK2-NEXT:    [[MUL35:%.*]] = mul nsw i64 [[MUL34]], 4
+// CHECK2-NEXT:    [[MUL36:%.*]] = mul nsw i64 [[DIV31]], [[MUL35]]
+// CHECK2-NEXT:    [[SUB37:%.*]] = sub nsw i64 [[TMP20]], [[MUL36]]
+// CHECK2-NEXT:    [[DIV38:%.*]] = sdiv i64 [[SUB37]], 4
+// CHECK2-NEXT:    [[MUL39:%.*]] = mul nsw i64 [[DIV38]], 1
+// CHECK2-NEXT:    [[ADD40:%.*]] = add nsw i64 0, [[MUL39]]
+// CHECK2-NEXT:    store i64 [[ADD40]], ptr [[DOTFORWARD_IV___BEGIN316]], align 8
+// CHECK2-NEXT:    [[TMP24:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK2-NEXT:    [[TMP25:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK2-NEXT:    [[TMP26:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK2-NEXT:    [[SUB41:%.*]] = sub nsw i64 [[TMP26]], 0
+// CHECK2-NEXT:    [[DIV42:%.*]] = sdiv i64 [[SUB41]], 1
+// CHECK2-NEXT:    [[MUL43:%.*]] = mul nsw i64 1, [[DIV42]]
+// CHECK2-NEXT:    [[MUL44:%.*]] = mul nsw i64 [[MUL43]], 4
+// CHECK2-NEXT:    [[DIV45:%.*]] = sdiv i64 [[TMP25]], [[MUL44]]
+// CHECK2-NEXT:    [[TMP27:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK2-NEXT:    [[SUB46:%.*]] = sub nsw i64 [[TMP27]], 0
+// CHECK2-NEXT:    [[DIV47:%.*]] = sdiv i64 [[SUB46]], 1
+// CHECK2-NEXT:    [[MUL48:%.*]] = mul nsw i64 1, [[DIV47]]
+// CHECK2-NEXT:    [[MUL49:%.*]] = mul nsw i64 [[MUL48]], 4
+// CHECK2-NEXT:    [[MUL50:%.*]] = mul nsw i64 [[DIV45]], [[MUL49]]
+// CHECK2-NEXT:    [[SUB51:%.*]] = sub nsw i64 [[TMP24]], [[MUL50]]
+// CHECK2-NEXT:    [[TMP28:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK2-NEXT:    [[TMP29:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK2-NEXT:    [[TMP30:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK2-NEXT:    [[SUB52:%.*]] = sub nsw i64 [[TMP30]], 0
+// CHECK2-NEXT:    [[DIV53:%.*]] = sdiv i64 [[SUB52]], 1
+// CHECK2-NEXT:    [[MUL54:%.*]] = mul nsw i64 1, [[DIV53]]
+// CHECK2-NEXT:    [[MUL55:%.*]] = mul nsw i64 [[MUL54]], 4
+// CHECK2-NEXT:    [[DIV56:%.*]] = sdiv i64 [[TMP29]], [[MUL55]]
+// CHECK2-NEXT:    [[TMP31:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK2-NEXT:    [[SUB57:%.*]] = sub nsw i64 [[TMP31]], 0
+// CHECK2-NEXT:    [[DIV58:%.*]] = sdiv i64 [[SUB57]], 1
+// CHECK2-NEXT:    [[MUL59:%.*]] = mul nsw i64 1, [[DIV58]]
+// CHECK2-NEXT:    [[MUL60:%.*]] = mul nsw i64 [[MUL59]], 4
+// CHECK2-NEXT:    [[MUL61:%.*]] = mul nsw i64 [[DIV56]], [[MUL60]]
+// CHECK2-NEXT:    [[SUB62:%.*]] = sub nsw i64 [[TMP28]], [[MUL61]]
+// CHECK2-NEXT:    [[DIV63:%.*]] = sdiv i64 [[SUB62]], 4
+// CHECK2-NEXT:    [[MUL64:%.*]] = mul nsw i64 [[DIV63]], 4
+// CHECK2-NEXT:    [[SUB65:%.*]] = sub nsw i64 [[SUB51]], [[MUL64]]
+// CHECK2-NEXT:    [[MUL66:%.*]] = mul nsw i64 [[SUB65]], 3
+// CHECK2-NEXT:    [[ADD67:%.*]] = add nsw i64 7, [[MUL66]]
+// CHECK2-NEXT:    [[CONV68:%.*]] = trunc i64 [[ADD67]] to i32
+// CHECK2-NEXT:    store i32 [[CONV68]], ptr [[J17]], align 4
+// CHECK2-NEXT:    [[TMP32:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_6]], align 8
+// CHECK2-NEXT:    [[ADD69:%.*]] = add nsw i64 [[TMP32]], 1
+// CHECK2-NEXT:    [[SUB70:%.*]] = sub nsw i64 [[ADD69]], 1
+// CHECK2-NEXT:    [[TMP33:%.*]] = load i64, ptr [[DOTFORWARD_IV___BEGIN316]], align 8
+// CHECK2-NEXT:    [[SUB71:%.*]] = sub nsw i64 [[SUB70]], [[TMP33]]
+// CHECK2-NEXT:    store i64 [[SUB71]], ptr [[DOTREVERSED_IV___BEGIN3]], align 8
+// CHECK2-NEXT:    [[TMP34:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK2-NEXT:    [[TMP35:%.*]] = load i64, ptr [[DOTREVERSED_IV___BEGIN3]], align 8
+// CHECK2-NEXT:    [[MUL72:%.*]] = mul nsw i64 [[TMP35]], 1
+// CHECK2-NEXT:    [[ADD_PTR73:%.*]] = getelementptr inbounds double, ptr [[TMP34]], i64 [[MUL72]]
+// CHECK2-NEXT:    store ptr [[ADD_PTR73]], ptr [[__BEGIN3]], align 8
+// CHECK2-NEXT:    [[TMP36:%.*]] = load ptr, ptr [[__BEGIN3]], align 8
+// CHECK2-NEXT:    store ptr [[TMP36]], ptr [[V]], align 8
+// CHECK2-NEXT:    [[TMP37:%.*]] = load i32, ptr [[K15]], align 4
+// CHECK2-NEXT:    [[TMP38:%.*]] = load i32, ptr [[C]], align 4
+// CHECK2-NEXT:    [[TMP39:%.*]] = load ptr, ptr [[V]], align 8, !nonnull [[META2]], !align [[META9]]
+// CHECK2-NEXT:    [[TMP40:%.*]] = load double, ptr [[TMP39]], align 8
+// CHECK2-NEXT:    [[TMP41:%.*]] = load i32, ptr [[J17]], align 4
+// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP37]], i32 noundef [[TMP38]], double noundef [[TMP40]], i32 noundef [[TMP41]])
+// CHECK2-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
+// CHECK2:       omp.body.continue:
+// CHECK2-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
+// CHECK2:       omp.inner.for.inc:
+// CHECK2-NEXT:    [[TMP42:%.*]] = load i64, ptr [[DOTOMP_IV]], align 8
+// CHECK2-NEXT:    [[ADD74:%.*]] = add nsw i64 [[TMP42]], 1
+// CHECK2-NEXT:    store i64 [[ADD74]], ptr [[DOTOMP_IV]], align 8
+// CHECK2-NEXT:    br label [[OMP_INNER_FOR_COND]]
+// CHECK2:       omp.inner.for.end:
+// CHECK2-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
+// CHECK2:       omp.loop.exit:
+// CHECK2-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
+// CHECK2-NEXT:    br label [[OMP_PRECOND_END]]
+// CHECK2:       omp.precond.end:
+// CHECK2-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]])
+// CHECK2-NEXT:    ret void
+//
+//
+// CHECK2-LABEL: define {{[^@]+}}@tfoo5
+// CHECK2-SAME: () #[[ATTR1]] {
+// CHECK2-NEXT:  entry:
+// CHECK2-NEXT:    call void @_Z4foo5IiTnT_Li3EEvS0_S0_(i32 noundef 0, i32 noundef 42)
+// CHECK2-NEXT:    ret void
+//
+//
+// CHECK2-LABEL: define {{[^@]+}}@_Z4foo5IiTnT_Li3EEvS0_S0_
+// CHECK2-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]]) #[[ATTR1]] comdat {
+// CHECK2-NEXT:  entry:
+// CHECK2-NEXT:    [[START_ADDR:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[END_ADDR:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
+// CHECK2-NEXT:    store i32 [[START]], ptr [[START_ADDR]], align 4
+// CHECK2-NEXT:    store i32 [[END]], ptr [[END_ADDR]], align 4
+// CHECK2-NEXT:    [[TMP0:%.*]] = load i32, ptr [[START_ADDR]], align 4
+// CHECK2-NEXT:    store i32 [[TMP0]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[TMP1:%.*]] = load i32, ptr [[START_ADDR]], align 4
+// CHECK2-NEXT:    store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[TMP2:%.*]] = load i32, ptr [[END_ADDR]], align 4
+// CHECK2-NEXT:    store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK2-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK2-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB:%.*]] = sub i32 [[TMP3]], [[TMP4]]
+// CHECK2-NEXT:    [[SUB3:%.*]] = sub i32 [[SUB]], 1
+// CHECK2-NEXT:    [[ADD:%.*]] = add i32 [[SUB3]], 3
+// CHECK2-NEXT:    [[DIV:%.*]] = udiv i32 [[ADD]], 3
+// CHECK2-NEXT:    [[SUB4:%.*]] = sub i32 [[DIV]], 1
+// CHECK2-NEXT:    store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4
+// CHECK2-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    br label [[FOR_COND:%.*]]
+// CHECK2:       for.cond:
+// CHECK2-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
+// CHECK2-NEXT:    [[ADD5:%.*]] = add i32 [[TMP6]], 1
+// CHECK2-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP5]], [[ADD5]]
+// CHECK2-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK2:       for.body:
+// CHECK2-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4
+// CHECK2-NEXT:    [[ADD6:%.*]] = add i32 [[TMP7]], 1
+// CHECK2-NEXT:    [[SUB7:%.*]] = sub i32 [[ADD6]], 1
+// CHECK2-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    [[SUB8:%.*]] = sub i32 [[SUB7]], [[TMP8]]
+// CHECK2-NEXT:    store i32 [[SUB8]], ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK2-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK2-NEXT:    [[MUL:%.*]] = mul i32 [[TMP10]], 3
+// CHECK2-NEXT:    [[ADD9:%.*]] = add i32 [[TMP9]], [[MUL]]
+// CHECK2-NEXT:    store i32 [[ADD9]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[TMP11:%.*]] = load i32, ptr [[I]], align 4
+// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP11]])
+// CHECK2-NEXT:    br label [[FOR_INC:%.*]]
+// CHECK2:       for.inc:
+// CHECK2-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    [[INC:%.*]] = add i32 [[TMP12]], 1
+// CHECK2-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP11:![0-9]+]]
+// CHECK2:       for.end:
+// CHECK2-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK2-NEXT:    [[TMP15:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB10:%.*]] = sub i32 [[TMP14]], [[TMP15]]
+// CHECK2-NEXT:    [[SUB11:%.*]] = sub i32 [[SUB10]], 1
+// CHECK2-NEXT:    [[ADD12:%.*]] = add i32 [[SUB11]], 3
+// CHECK2-NEXT:    [[DIV13:%.*]] = udiv i32 [[ADD12]], 3
+// CHECK2-NEXT:    [[SUB14:%.*]] = sub i32 [[DIV13]], 1
+// CHECK2-NEXT:    [[MUL15:%.*]] = mul i32 [[SUB14]], 3
+// CHECK2-NEXT:    [[ADD16:%.*]] = add i32 [[TMP13]], [[MUL15]]
+// CHECK2-NEXT:    store i32 [[ADD16]], ptr [[I]], align 4
+// CHECK2-NEXT:    ret void
+//
+//
+// CHECK2-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_reverse_codegen.cpp
+// CHECK2-SAME: () #[[ATTR0]] section ".text.startup" {
+// CHECK2-NEXT:  entry:
+// CHECK2-NEXT:    call void @__cxx_global_var_init()
+// CHECK2-NEXT:    ret void
+//
diff --git a/clang/test/OpenMP/stripe_codegen.cpp b/clang/test/OpenMP/stripe_codegen.cpp
index 09ce673a5ce52..aefa0001e9a72 100644
--- a/clang/test/OpenMP/stripe_codegen.cpp
+++ b/clang/test/OpenMP/stripe_codegen.cpp
@@ -198,6 +198,8 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    store i32 [[ADD11]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
 // CHECK1:       for.end12:
+// CHECK1-NEXT:    [[TMP11:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK1-NEXT:    store i32 16, ptr [[TMP11]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -290,6 +292,20 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    store i32 [[ADD16]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP8:![0-9]+]]
 // CHECK1:       for.end17:
+// CHECK1-NEXT:    [[TMP22:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[TMP23:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK1-NEXT:    [[TMP24:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB18:%.*]] = sub i32 [[TMP23]], [[TMP24]]
+// CHECK1-NEXT:    [[SUB19:%.*]] = sub i32 [[SUB18]], 1
+// CHECK1-NEXT:    [[TMP25:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], [[TMP25]]
+// CHECK1-NEXT:    [[TMP26:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], [[TMP26]]
+// CHECK1-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
+// CHECK1-NEXT:    [[TMP27:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], [[TMP27]]
+// CHECK1-NEXT:    [[ADD24:%.*]] = add i32 [[TMP22]], [[MUL23]]
+// CHECK1-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -403,6 +419,8 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    store i32 [[ADD29]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP12:![0-9]+]]
 // CHECK1:       for.end30:
+// CHECK1-NEXT:    store i32 16, ptr [[I]], align 4
+// CHECK1-NEXT:    store i32 16, ptr [[J]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1101,6 +1119,17 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    store i32 [[ADD16]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP23:![0-9]+]]
 // CHECK1:       for.end17:
+// CHECK1-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[TMP19:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK1-NEXT:    [[TMP20:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB18:%.*]] = sub i32 [[TMP19]], [[TMP20]]
+// CHECK1-NEXT:    [[SUB19:%.*]] = sub i32 [[SUB18]], 1
+// CHECK1-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], 3
+// CHECK1-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], 3
+// CHECK1-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
+// CHECK1-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], 3
+// CHECK1-NEXT:    [[ADD24:%.*]] = add i32 [[TMP18]], [[MUL23]]
+// CHECK1-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1190,6 +1219,7 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    store i32 [[ADD23]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]]
 // CHECK1:       for.end24:
+// CHECK1-NEXT:    store i32 16, ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1476,6 +1506,8 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    store i32 [[ADD11]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
 // CHECK2:       for.end12:
+// CHECK2-NEXT:    [[TMP11:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK2-NEXT:    store i32 16, ptr [[TMP11]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1574,6 +1606,20 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    store i32 [[ADD16]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP8:![0-9]+]]
 // CHECK2:       for.end17:
+// CHECK2-NEXT:    [[TMP22:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[TMP23:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK2-NEXT:    [[TMP24:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB18:%.*]] = sub i32 [[TMP23]], [[TMP24]]
+// CHECK2-NEXT:    [[SUB19:%.*]] = sub i32 [[SUB18]], 1
+// CHECK2-NEXT:    [[TMP25:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], [[TMP25]]
+// CHECK2-NEXT:    [[TMP26:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], [[TMP26]]
+// CHECK2-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
+// CHECK2-NEXT:    [[TMP27:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], [[TMP27]]
+// CHECK2-NEXT:    [[ADD24:%.*]] = add i32 [[TMP22]], [[MUL23]]
+// CHECK2-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1787,6 +1833,8 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    store i32 [[ADD29]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]]
 // CHECK2:       for.end30:
+// CHECK2-NEXT:    store i32 16, ptr [[I]], align 4
+// CHECK2-NEXT:    store i32 16, ptr [[J]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2483,6 +2531,7 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    store i32 [[ADD23]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]]
 // CHECK2:       for.end24:
+// CHECK2-NEXT:    store i32 16, ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2671,6 +2720,17 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    store i32 [[ADD16]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP30:![0-9]+]]
 // CHECK2:       for.end17:
+// CHECK2-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[TMP19:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK2-NEXT:    [[TMP20:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB18:%.*]] = sub i32 [[TMP19]], [[TMP20]]
+// CHECK2-NEXT:    [[SUB19:%.*]] = sub i32 [[SUB18]], 1
+// CHECK2-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], 3
+// CHECK2-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], 3
+// CHECK2-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
+// CHECK2-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], 3
+// CHECK2-NEXT:    [[ADD24:%.*]] = add i32 [[TMP18]], [[MUL23]]
+// CHECK2-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
diff --git a/clang/test/OpenMP/tile_codegen.cpp b/clang/test/OpenMP/tile_codegen.cpp
index b208e5a4d5f40..b024964cf8356 100644
--- a/clang/test/OpenMP/tile_codegen.cpp
+++ b/clang/test/OpenMP/tile_codegen.cpp
@@ -193,6 +193,8 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    store i32 [[ADD11]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
 // CHECK1:       for.end12:
+// CHECK1-NEXT:    [[TMP11:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK1-NEXT:    store i32 16, ptr [[TMP11]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -285,6 +287,20 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    store i32 [[ADD16]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP8:![0-9]+]]
 // CHECK1:       for.end17:
+// CHECK1-NEXT:    [[TMP22:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[TMP23:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK1-NEXT:    [[TMP24:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB18:%.*]] = sub i32 [[TMP23]], [[TMP24]]
+// CHECK1-NEXT:    [[SUB19:%.*]] = sub i32 [[SUB18]], 1
+// CHECK1-NEXT:    [[TMP25:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], [[TMP25]]
+// CHECK1-NEXT:    [[TMP26:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], [[TMP26]]
+// CHECK1-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
+// CHECK1-NEXT:    [[TMP27:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK1-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], [[TMP27]]
+// CHECK1-NEXT:    [[ADD24:%.*]] = add i32 [[TMP22]], [[MUL23]]
+// CHECK1-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -398,6 +414,8 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    store i32 [[ADD29]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP12:![0-9]+]]
 // CHECK1:       for.end30:
+// CHECK1-NEXT:    store i32 16, ptr [[I]], align 4
+// CHECK1-NEXT:    store i32 16, ptr [[J]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -994,6 +1012,17 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    store i32 [[ADD16]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP23:![0-9]+]]
 // CHECK1:       for.end17:
+// CHECK1-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[TMP19:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK1-NEXT:    [[TMP20:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB18:%.*]] = sub i32 [[TMP19]], [[TMP20]]
+// CHECK1-NEXT:    [[SUB19:%.*]] = sub i32 [[SUB18]], 1
+// CHECK1-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], 3
+// CHECK1-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], 3
+// CHECK1-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
+// CHECK1-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], 3
+// CHECK1-NEXT:    [[ADD24:%.*]] = add i32 [[TMP18]], [[MUL23]]
+// CHECK1-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1083,6 +1112,7 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    store i32 [[ADD23]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]]
 // CHECK1:       for.end24:
+// CHECK1-NEXT:    store i32 16, ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1369,6 +1399,8 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    store i32 [[ADD11]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
 // CHECK2:       for.end12:
+// CHECK2-NEXT:    [[TMP11:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK2-NEXT:    store i32 16, ptr [[TMP11]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1467,6 +1499,20 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    store i32 [[ADD16]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP8:![0-9]+]]
 // CHECK2:       for.end17:
+// CHECK2-NEXT:    [[TMP22:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[TMP23:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK2-NEXT:    [[TMP24:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB18:%.*]] = sub i32 [[TMP23]], [[TMP24]]
+// CHECK2-NEXT:    [[SUB19:%.*]] = sub i32 [[SUB18]], 1
+// CHECK2-NEXT:    [[TMP25:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], [[TMP25]]
+// CHECK2-NEXT:    [[TMP26:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], [[TMP26]]
+// CHECK2-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
+// CHECK2-NEXT:    [[TMP27:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
+// CHECK2-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], [[TMP27]]
+// CHECK2-NEXT:    [[ADD24:%.*]] = add i32 [[TMP22]], [[MUL23]]
+// CHECK2-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1680,6 +1726,8 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    store i32 [[ADD29]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]]
 // CHECK2:       for.end30:
+// CHECK2-NEXT:    store i32 16, ptr [[I]], align 4
+// CHECK2-NEXT:    store i32 16, ptr [[J]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2274,6 +2322,7 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    store i32 [[ADD23]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]]
 // CHECK2:       for.end24:
+// CHECK2-NEXT:    store i32 16, ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2462,6 +2511,17 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    store i32 [[ADD16]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP30:![0-9]+]]
 // CHECK2:       for.end17:
+// CHECK2-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[TMP19:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK2-NEXT:    [[TMP20:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB18:%.*]] = sub i32 [[TMP19]], [[TMP20]]
+// CHECK2-NEXT:    [[SUB19:%.*]] = sub i32 [[SUB18]], 1
+// CHECK2-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], 3
+// CHECK2-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], 3
+// CHECK2-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
+// CHECK2-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], 3
+// CHECK2-NEXT:    [[ADD24:%.*]] = add i32 [[TMP18]], [[MUL23]]
+// CHECK2-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //

>From b41509df9e818494319120b1ca777dfdf4b008d3 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Fri, 7 Aug 2026 06:35:07 -0700
Subject: [PATCH 02/11] Fix format

---
 clang/lib/Sema/SemaOpenMP.cpp | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index fe031b8376894..0cbbe17a56abf 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -10126,7 +10126,8 @@ static Stmt *buildPreInits(ASTContext &Context, ArrayRef<Stmt *> PreInits) {
 }
 
 /// Helper to determine if a loop should skip finalization.
-/// Returns true for range-based for loops or loops with non-arithmetic counters.
+/// Returns true for range-based for loops or loops with non-arithmetic
+/// counters.
 static bool shouldSkipLoopFinalization(Stmt *LoopStmt) {
   if (isa<CXXForRangeStmt>(LoopStmt))
     return true;
@@ -10851,8 +10852,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
       // exit value. For iterator-based loops (range-based for or explicit
       // iterator loops), skip finalization entirely.
       ExprResult Final;
-      bool IsIteratorLoop = IS.IsRangeFor ||
-                            !IS.CounterVar->getType()->isArithmeticType();
+      bool IsIteratorLoop =
+          IS.IsRangeFor || !IS.CounterVar->getType()->isArithmeticType();
       if (IsIteratorLoop && isOpenMPLoopTransformationDirective(DKind)) {
         // Iterator-based loops in transformation directives don't need
         // explicit finalization - the iterator is already at the end.
@@ -10867,9 +10868,10 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
             FinalIterCount = LastIter.get();
           }
         }
-        Final = buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
-                                    IS.CounterInit, FinalIterCount, IS.CounterStep,
-                                    IS.Subtract, IS.IsNonRectangularLB, &Captures);
+        Final =
+            buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
+                               IS.CounterInit, FinalIterCount, IS.CounterStep,
+                               IS.Subtract, IS.IsNonRectangularLB, &Captures);
         if (!Final.isUsable()) {
           HasErrors = true;
           break;
@@ -15625,11 +15627,10 @@ StmtResult SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
   }
 
-  return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
-                                  AStmt, Inner,
-                                  buildPreInits(Context, PreInits),
-                                  buildLoopFinalization(Context, LoopHelpers,
-                                                        LoopStmts));
+  return OMPTileDirective::Create(
+      Context, StartLoc, EndLoc, Clauses, NumLoops, AStmt, Inner,
+      buildPreInits(Context, PreInits),
+      buildLoopFinalization(Context, LoopHelpers, LoopStmts));
 }
 
 StmtResult SemaOpenMP::ActOnOpenMPStripeDirective(ArrayRef<OMPClause *> Clauses,

>From b6e086c24613c8827ffe1074bd9413b0c40a9d0d Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Mon, 10 Aug 2026 09:52:44 -0700
Subject: [PATCH 03/11] Addressed review comments

---
 clang/lib/Sema/SemaOpenMP.cpp         |  40 ++------
 clang/test/OpenMP/fuse_codegen.cpp    | 140 ++++++++++++--------------
 clang/test/OpenMP/loop_transform_iv.c |  53 ++++++----
 clang/test/OpenMP/stripe_codegen.cpp  |  44 ++++----
 clang/test/OpenMP/tile_codegen.cpp    |  44 ++++----
 offload/test/offloading/target-tile.c |   8 +-
 6 files changed, 155 insertions(+), 174 deletions(-)

diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 0cbbe17a56abf..7739d1b859eb2 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -10859,19 +10859,10 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
         // explicit finalization - the iterator is already at the end.
         Final = nullptr;
       } else {
-        Expr *FinalIterCount = IS.NumIterations;
-        if (isOpenMPLoopTransformationDirective(DKind)) {
-          ExprResult LastIter = SemaRef.BuildBinOp(
-              CurScope, UpdLoc, BO_Sub, IS.NumIterations,
-              SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
-          if (LastIter.isUsable()) {
-            FinalIterCount = LastIter.get();
-          }
-        }
-        Final =
-            buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
-                               IS.CounterInit, FinalIterCount, IS.CounterStep,
-                               IS.Subtract, IS.IsNonRectangularLB, &Captures);
+        Final = buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
+                                   IS.CounterInit, IS.NumIterations,
+                                   IS.CounterStep, IS.Subtract,
+                                   IS.IsNonRectangularLB, &Captures);
         if (!Final.isUsable()) {
           HasErrors = true;
           break;
@@ -15252,19 +15243,10 @@ static Expr *makeFloorIVRef(Sema &SemaRef, ArrayRef<VarDecl *> FloorIndVars,
 /// because finalization only applies to integer/floating-point counters.
 static Stmt *
 buildLoopFinalization(ASTContext &Context,
-                      ArrayRef<OMPLoopBasedDirective::HelperExprs> LoopHelpers,
-                      ArrayRef<Stmt *> LoopStmts = {}) {
-  bool ShouldFilter = !LoopStmts.empty();
-  assert((!ShouldFilter || LoopHelpers.size() == LoopStmts.size()) &&
-         "LoopHelpers and LoopStmts must have the same size");
-
+                      ArrayRef<OMPLoopBasedDirective::HelperExprs> LoopHelpers) {
   SmallVector<Stmt *, 8> FinalizationStmts;
 
-  for (size_t I = 0; I < LoopHelpers.size(); ++I) {
-    // Filter iterator loops if LoopStmts provided
-    if (ShouldFilter && shouldSkipLoopFinalization(LoopStmts[I]))
-      continue;
-
+  for (size_t I : llvm::seq<size_t>(LoopHelpers.size())) {
     for (auto *Final : LoopHelpers[I].Finals)
       if (Final)
         FinalizationStmts.push_back(Final);
@@ -15630,7 +15612,7 @@ StmtResult SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
   return OMPTileDirective::Create(
       Context, StartLoc, EndLoc, Clauses, NumLoops, AStmt, Inner,
       buildPreInits(Context, PreInits),
-      buildLoopFinalization(Context, LoopHelpers, LoopStmts));
+      buildLoopFinalization(Context, LoopHelpers));
 }
 
 StmtResult SemaOpenMP::ActOnOpenMPStripeDirective(ArrayRef<OMPClause *> Clauses,
@@ -15891,7 +15873,7 @@ StmtResult SemaOpenMP::ActOnOpenMPStripeDirective(ArrayRef<OMPClause *> Clauses,
   return OMPStripeDirective::Create(
       Context, StartLoc, EndLoc, Clauses, NumLoops, AStmt, Inner,
       buildPreInits(Context, PreInits),
-      buildLoopFinalization(Context, LoopHelpers, LoopStmts));
+      buildLoopFinalization(Context, LoopHelpers));
 }
 
 StmtResult SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
@@ -16360,7 +16342,7 @@ StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt,
   return OMPReverseDirective::Create(
       Context, StartLoc, EndLoc, AStmt, NumLoops, ReversedFor,
       buildPreInits(Context, PreInits),
-      buildLoopFinalization(Context, LoopHelpers, {LoopStmt}));
+      buildLoopFinalization(Context, LoopHelpers));
 }
 
 /// Build the AST for \#pragma omp split counts(c1, c2, ...).
@@ -16787,7 +16769,7 @@ StmtResult SemaOpenMP::ActOnOpenMPInterchangeDirective(
   return OMPInterchangeDirective::Create(
       Context, StartLoc, EndLoc, Clauses, NumLoops, AStmt, Inner,
       buildPreInits(Context, PreInits),
-      buildLoopFinalization(Context, LoopHelpers, LoopStmts));
+      buildLoopFinalization(Context, LoopHelpers));
 }
 
 StmtResult SemaOpenMP::ActOnOpenMPFuseDirective(ArrayRef<OMPClause *> Clauses,
@@ -17275,7 +17257,7 @@ StmtResult SemaOpenMP::ActOnOpenMPFuseDirective(ArrayRef<OMPClause *> Clauses,
   return OMPFuseDirective::Create(
       Context, StartLoc, EndLoc, Clauses, NumGeneratedTopLevelLoops, AStmt,
       FusionStmt, buildPreInits(Context, PreInits),
-      buildLoopFinalization(Context, FusedLoopHelpers, FusedLoopStmts));
+      buildLoopFinalization(Context, FusedLoopHelpers));
 }
 
 OMPClause *SemaOpenMP::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
diff --git a/clang/test/OpenMP/fuse_codegen.cpp b/clang/test/OpenMP/fuse_codegen.cpp
index d0eeb9fd58cac..bd265e6117262 100644
--- a/clang/test/OpenMP/fuse_codegen.cpp
+++ b/clang/test/OpenMP/fuse_codegen.cpp
@@ -253,25 +253,23 @@ extern "C" void foo5() {
 // CHECK1-NEXT:    [[ADD30:%.*]] = add i32 [[SUB29]], [[TMP47]]
 // CHECK1-NEXT:    [[TMP48:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
 // CHECK1-NEXT:    [[DIV31:%.*]] = udiv i32 [[ADD30]], [[TMP48]]
-// CHECK1-NEXT:    [[SUB32:%.*]] = sub i32 [[DIV31]], 1
 // CHECK1-NEXT:    [[TMP49:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK1-NEXT:    [[MUL33:%.*]] = mul i32 [[SUB32]], [[TMP49]]
-// CHECK1-NEXT:    [[ADD34:%.*]] = add i32 [[TMP44]], [[MUL33]]
-// CHECK1-NEXT:    store i32 [[ADD34]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[MUL32:%.*]] = mul i32 [[DIV31]], [[TMP49]]
+// CHECK1-NEXT:    [[ADD33:%.*]] = add i32 [[TMP44]], [[MUL32]]
+// CHECK1-NEXT:    store i32 [[ADD33]], ptr [[I]], align 4
 // CHECK1-NEXT:    [[TMP50:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
 // CHECK1-NEXT:    [[TMP51:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_7]], align 4
 // CHECK1-NEXT:    [[TMP52:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
-// CHECK1-NEXT:    [[SUB35:%.*]] = sub i32 [[TMP51]], [[TMP52]]
-// CHECK1-NEXT:    [[SUB36:%.*]] = sub i32 [[SUB35]], 1
+// CHECK1-NEXT:    [[SUB34:%.*]] = sub i32 [[TMP51]], [[TMP52]]
+// CHECK1-NEXT:    [[SUB35:%.*]] = sub i32 [[SUB34]], 1
 // CHECK1-NEXT:    [[TMP53:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
-// CHECK1-NEXT:    [[ADD37:%.*]] = add i32 [[SUB36]], [[TMP53]]
+// CHECK1-NEXT:    [[ADD36:%.*]] = add i32 [[SUB35]], [[TMP53]]
 // CHECK1-NEXT:    [[TMP54:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
-// CHECK1-NEXT:    [[DIV38:%.*]] = udiv i32 [[ADD37]], [[TMP54]]
-// CHECK1-NEXT:    [[SUB39:%.*]] = sub i32 [[DIV38]], 1
+// CHECK1-NEXT:    [[DIV37:%.*]] = udiv i32 [[ADD36]], [[TMP54]]
 // CHECK1-NEXT:    [[TMP55:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
-// CHECK1-NEXT:    [[MUL40:%.*]] = mul i32 [[SUB39]], [[TMP55]]
-// CHECK1-NEXT:    [[ADD41:%.*]] = add i32 [[TMP50]], [[MUL40]]
-// CHECK1-NEXT:    store i32 [[ADD41]], ptr [[J]], align 4
+// CHECK1-NEXT:    [[MUL38:%.*]] = mul i32 [[DIV37]], [[TMP55]]
+// CHECK1-NEXT:    [[ADD39:%.*]] = add i32 [[TMP50]], [[MUL38]]
+// CHECK1-NEXT:    store i32 [[ADD39]], ptr [[J]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -512,39 +510,36 @@ extern "C" void foo5() {
 // CHECK1-NEXT:    [[ADD55:%.*]] = add i32 [[SUB54]], [[TMP72]]
 // CHECK1-NEXT:    [[TMP73:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
 // CHECK1-NEXT:    [[DIV56:%.*]] = udiv i32 [[ADD55]], [[TMP73]]
-// CHECK1-NEXT:    [[SUB57:%.*]] = sub i32 [[DIV56]], 1
 // CHECK1-NEXT:    [[TMP74:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK1-NEXT:    [[MUL58:%.*]] = mul i32 [[SUB57]], [[TMP74]]
-// CHECK1-NEXT:    [[ADD59:%.*]] = add i32 [[TMP69]], [[MUL58]]
-// CHECK1-NEXT:    store i32 [[ADD59]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[MUL57:%.*]] = mul i32 [[DIV56]], [[TMP74]]
+// CHECK1-NEXT:    [[ADD58:%.*]] = add i32 [[TMP69]], [[MUL57]]
+// CHECK1-NEXT:    store i32 [[ADD58]], ptr [[I]], align 4
 // CHECK1-NEXT:    [[TMP75:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
 // CHECK1-NEXT:    [[TMP76:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
 // CHECK1-NEXT:    [[TMP77:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_7]], align 4
-// CHECK1-NEXT:    [[SUB60:%.*]] = sub i32 [[TMP76]], [[TMP77]]
-// CHECK1-NEXT:    [[SUB61:%.*]] = sub i32 [[SUB60]], 1
+// CHECK1-NEXT:    [[SUB59:%.*]] = sub i32 [[TMP76]], [[TMP77]]
+// CHECK1-NEXT:    [[SUB60:%.*]] = sub i32 [[SUB59]], 1
 // CHECK1-NEXT:    [[TMP78:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
-// CHECK1-NEXT:    [[ADD62:%.*]] = add i32 [[SUB61]], [[TMP78]]
+// CHECK1-NEXT:    [[ADD61:%.*]] = add i32 [[SUB60]], [[TMP78]]
 // CHECK1-NEXT:    [[TMP79:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
-// CHECK1-NEXT:    [[DIV63:%.*]] = udiv i32 [[ADD62]], [[TMP79]]
-// CHECK1-NEXT:    [[SUB64:%.*]] = sub i32 [[DIV63]], 1
+// CHECK1-NEXT:    [[DIV62:%.*]] = udiv i32 [[ADD61]], [[TMP79]]
 // CHECK1-NEXT:    [[TMP80:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
-// CHECK1-NEXT:    [[MUL65:%.*]] = mul i32 [[SUB64]], [[TMP80]]
-// CHECK1-NEXT:    [[SUB66:%.*]] = sub i32 [[TMP75]], [[MUL65]]
-// CHECK1-NEXT:    store i32 [[SUB66]], ptr [[J]], align 4
+// CHECK1-NEXT:    [[MUL63:%.*]] = mul i32 [[DIV62]], [[TMP80]]
+// CHECK1-NEXT:    [[SUB64:%.*]] = sub i32 [[TMP75]], [[MUL63]]
+// CHECK1-NEXT:    store i32 [[SUB64]], ptr [[J]], align 4
 // CHECK1-NEXT:    [[TMP81:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_17]], align 4
 // CHECK1-NEXT:    [[TMP82:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_19]], align 4
 // CHECK1-NEXT:    [[TMP83:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_17]], align 4
-// CHECK1-NEXT:    [[SUB67:%.*]] = sub i32 [[TMP82]], [[TMP83]]
-// CHECK1-NEXT:    [[SUB68:%.*]] = sub i32 [[SUB67]], 1
+// CHECK1-NEXT:    [[SUB65:%.*]] = sub i32 [[TMP82]], [[TMP83]]
+// CHECK1-NEXT:    [[SUB66:%.*]] = sub i32 [[SUB65]], 1
 // CHECK1-NEXT:    [[TMP84:%.*]] = load i32, ptr [[DOTNEW_STEP21]], align 4
-// CHECK1-NEXT:    [[ADD69:%.*]] = add i32 [[SUB68]], [[TMP84]]
+// CHECK1-NEXT:    [[ADD67:%.*]] = add i32 [[SUB66]], [[TMP84]]
 // CHECK1-NEXT:    [[TMP85:%.*]] = load i32, ptr [[DOTNEW_STEP21]], align 4
-// CHECK1-NEXT:    [[DIV70:%.*]] = udiv i32 [[ADD69]], [[TMP85]]
-// CHECK1-NEXT:    [[SUB71:%.*]] = sub i32 [[DIV70]], 1
+// CHECK1-NEXT:    [[DIV68:%.*]] = udiv i32 [[ADD67]], [[TMP85]]
 // CHECK1-NEXT:    [[TMP86:%.*]] = load i32, ptr [[DOTNEW_STEP21]], align 4
-// CHECK1-NEXT:    [[MUL72:%.*]] = mul i32 [[SUB71]], [[TMP86]]
-// CHECK1-NEXT:    [[ADD73:%.*]] = add i32 [[TMP81]], [[MUL72]]
-// CHECK1-NEXT:    store i32 [[ADD73]], ptr [[K]], align 4
+// CHECK1-NEXT:    [[MUL69:%.*]] = mul i32 [[DIV68]], [[TMP86]]
+// CHECK1-NEXT:    [[ADD70:%.*]] = add i32 [[TMP81]], [[MUL69]]
+// CHECK1-NEXT:    store i32 [[ADD70]], ptr [[K]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -992,8 +987,8 @@ extern "C" void foo5() {
 // CHECK1-NEXT:    store ptr [[INCDEC_PTR]], ptr [[__BEGIN2]], align 8
 // CHECK1-NEXT:    br label %[[FOR_COND19]]
 // CHECK1:       [[FOR_END23]]:
-// CHECK1-NEXT:    store i32 254, ptr [[J]], align 4
-// CHECK1-NEXT:    store i32 63, ptr [[K]], align 4
+// CHECK1-NEXT:    store i32 256, ptr [[J]], align 4
+// CHECK1-NEXT:    store i32 64, ptr [[K]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1268,10 +1263,9 @@ extern "C" void foo5() {
 // CHECK1-NEXT:    [[TMP66:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
 // CHECK1-NEXT:    [[SUB75:%.*]] = sub nsw i32 [[TMP66]], 0
 // CHECK1-NEXT:    [[DIV76:%.*]] = sdiv i32 [[SUB75]], 1
-// CHECK1-NEXT:    [[SUB77:%.*]] = sub nsw i32 [[DIV76]], 1
-// CHECK1-NEXT:    [[MUL78:%.*]] = mul nsw i32 [[SUB77]], 1
-// CHECK1-NEXT:    [[ADD79:%.*]] = add nsw i32 0, [[MUL78]]
-// CHECK1-NEXT:    store i32 [[ADD79]], ptr [[DOTOMP_FUSE_INDEX]], align 4
+// CHECK1-NEXT:    [[MUL77:%.*]] = mul nsw i32 [[DIV76]], 1
+// CHECK1-NEXT:    [[ADD78:%.*]] = add nsw i32 0, [[MUL77]]
+// CHECK1-NEXT:    store i32 [[ADD78]], ptr [[DOTOMP_FUSE_INDEX]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1444,25 +1438,23 @@ extern "C" void foo5() {
 // CHECK2-NEXT:    [[ADD30:%.*]] = add i32 [[SUB29]], [[TMP47]]
 // CHECK2-NEXT:    [[TMP48:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
 // CHECK2-NEXT:    [[DIV31:%.*]] = udiv i32 [[ADD30]], [[TMP48]]
-// CHECK2-NEXT:    [[SUB32:%.*]] = sub i32 [[DIV31]], 1
 // CHECK2-NEXT:    [[TMP49:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK2-NEXT:    [[MUL33:%.*]] = mul i32 [[SUB32]], [[TMP49]]
-// CHECK2-NEXT:    [[ADD34:%.*]] = add i32 [[TMP44]], [[MUL33]]
-// CHECK2-NEXT:    store i32 [[ADD34]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[MUL32:%.*]] = mul i32 [[DIV31]], [[TMP49]]
+// CHECK2-NEXT:    [[ADD33:%.*]] = add i32 [[TMP44]], [[MUL32]]
+// CHECK2-NEXT:    store i32 [[ADD33]], ptr [[I]], align 4
 // CHECK2-NEXT:    [[TMP50:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
 // CHECK2-NEXT:    [[TMP51:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_7]], align 4
 // CHECK2-NEXT:    [[TMP52:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
-// CHECK2-NEXT:    [[SUB35:%.*]] = sub i32 [[TMP51]], [[TMP52]]
-// CHECK2-NEXT:    [[SUB36:%.*]] = sub i32 [[SUB35]], 1
+// CHECK2-NEXT:    [[SUB34:%.*]] = sub i32 [[TMP51]], [[TMP52]]
+// CHECK2-NEXT:    [[SUB35:%.*]] = sub i32 [[SUB34]], 1
 // CHECK2-NEXT:    [[TMP53:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
-// CHECK2-NEXT:    [[ADD37:%.*]] = add i32 [[SUB36]], [[TMP53]]
+// CHECK2-NEXT:    [[ADD36:%.*]] = add i32 [[SUB35]], [[TMP53]]
 // CHECK2-NEXT:    [[TMP54:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
-// CHECK2-NEXT:    [[DIV38:%.*]] = udiv i32 [[ADD37]], [[TMP54]]
-// CHECK2-NEXT:    [[SUB39:%.*]] = sub i32 [[DIV38]], 1
+// CHECK2-NEXT:    [[DIV37:%.*]] = udiv i32 [[ADD36]], [[TMP54]]
 // CHECK2-NEXT:    [[TMP55:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
-// CHECK2-NEXT:    [[MUL40:%.*]] = mul i32 [[SUB39]], [[TMP55]]
-// CHECK2-NEXT:    [[ADD41:%.*]] = add i32 [[TMP50]], [[MUL40]]
-// CHECK2-NEXT:    store i32 [[ADD41]], ptr [[J]], align 4
+// CHECK2-NEXT:    [[MUL38:%.*]] = mul i32 [[DIV37]], [[TMP55]]
+// CHECK2-NEXT:    [[ADD39:%.*]] = add i32 [[TMP50]], [[MUL38]]
+// CHECK2-NEXT:    store i32 [[ADD39]], ptr [[J]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1910,8 +1902,8 @@ extern "C" void foo5() {
 // CHECK2-NEXT:    store ptr [[INCDEC_PTR]], ptr [[__BEGIN2]], align 8
 // CHECK2-NEXT:    br label %[[FOR_COND19]]
 // CHECK2:       [[FOR_END23]]:
-// CHECK2-NEXT:    store i32 254, ptr [[J]], align 4
-// CHECK2-NEXT:    store i32 63, ptr [[K]], align 4
+// CHECK2-NEXT:    store i32 256, ptr [[J]], align 4
+// CHECK2-NEXT:    store i32 64, ptr [[K]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2186,10 +2178,9 @@ extern "C" void foo5() {
 // CHECK2-NEXT:    [[TMP66:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
 // CHECK2-NEXT:    [[SUB75:%.*]] = sub nsw i32 [[TMP66]], 0
 // CHECK2-NEXT:    [[DIV76:%.*]] = sdiv i32 [[SUB75]], 1
-// CHECK2-NEXT:    [[SUB77:%.*]] = sub nsw i32 [[DIV76]], 1
-// CHECK2-NEXT:    [[MUL78:%.*]] = mul nsw i32 [[SUB77]], 1
-// CHECK2-NEXT:    [[ADD79:%.*]] = add nsw i32 0, [[MUL78]]
-// CHECK2-NEXT:    store i32 [[ADD79]], ptr [[DOTOMP_FUSE_INDEX]], align 4
+// CHECK2-NEXT:    [[MUL77:%.*]] = mul nsw i32 [[DIV76]], 1
+// CHECK2-NEXT:    [[ADD78:%.*]] = add nsw i32 0, [[MUL77]]
+// CHECK2-NEXT:    store i32 [[ADD78]], ptr [[DOTOMP_FUSE_INDEX]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2430,39 +2421,36 @@ extern "C" void foo5() {
 // CHECK2-NEXT:    [[ADD55:%.*]] = add i32 [[SUB54]], [[TMP72]]
 // CHECK2-NEXT:    [[TMP73:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
 // CHECK2-NEXT:    [[DIV56:%.*]] = udiv i32 [[ADD55]], [[TMP73]]
-// CHECK2-NEXT:    [[SUB57:%.*]] = sub i32 [[DIV56]], 1
 // CHECK2-NEXT:    [[TMP74:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK2-NEXT:    [[MUL58:%.*]] = mul i32 [[SUB57]], [[TMP74]]
-// CHECK2-NEXT:    [[ADD59:%.*]] = add i32 [[TMP69]], [[MUL58]]
-// CHECK2-NEXT:    store i32 [[ADD59]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[MUL57:%.*]] = mul i32 [[DIV56]], [[TMP74]]
+// CHECK2-NEXT:    [[ADD58:%.*]] = add i32 [[TMP69]], [[MUL57]]
+// CHECK2-NEXT:    store i32 [[ADD58]], ptr [[I]], align 4
 // CHECK2-NEXT:    [[TMP75:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
 // CHECK2-NEXT:    [[TMP76:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_6]], align 4
 // CHECK2-NEXT:    [[TMP77:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_7]], align 4
-// CHECK2-NEXT:    [[SUB60:%.*]] = sub i32 [[TMP76]], [[TMP77]]
-// CHECK2-NEXT:    [[SUB61:%.*]] = sub i32 [[SUB60]], 1
+// CHECK2-NEXT:    [[SUB59:%.*]] = sub i32 [[TMP76]], [[TMP77]]
+// CHECK2-NEXT:    [[SUB60:%.*]] = sub i32 [[SUB59]], 1
 // CHECK2-NEXT:    [[TMP78:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
-// CHECK2-NEXT:    [[ADD62:%.*]] = add i32 [[SUB61]], [[TMP78]]
+// CHECK2-NEXT:    [[ADD61:%.*]] = add i32 [[SUB60]], [[TMP78]]
 // CHECK2-NEXT:    [[TMP79:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
-// CHECK2-NEXT:    [[DIV63:%.*]] = udiv i32 [[ADD62]], [[TMP79]]
-// CHECK2-NEXT:    [[SUB64:%.*]] = sub i32 [[DIV63]], 1
+// CHECK2-NEXT:    [[DIV62:%.*]] = udiv i32 [[ADD61]], [[TMP79]]
 // CHECK2-NEXT:    [[TMP80:%.*]] = load i32, ptr [[DOTNEW_STEP8]], align 4
-// CHECK2-NEXT:    [[MUL65:%.*]] = mul i32 [[SUB64]], [[TMP80]]
-// CHECK2-NEXT:    [[SUB66:%.*]] = sub i32 [[TMP75]], [[MUL65]]
-// CHECK2-NEXT:    store i32 [[SUB66]], ptr [[J]], align 4
+// CHECK2-NEXT:    [[MUL63:%.*]] = mul i32 [[DIV62]], [[TMP80]]
+// CHECK2-NEXT:    [[SUB64:%.*]] = sub i32 [[TMP75]], [[MUL63]]
+// CHECK2-NEXT:    store i32 [[SUB64]], ptr [[J]], align 4
 // CHECK2-NEXT:    [[TMP81:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_17]], align 4
 // CHECK2-NEXT:    [[TMP82:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_19]], align 4
 // CHECK2-NEXT:    [[TMP83:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_17]], align 4
-// CHECK2-NEXT:    [[SUB67:%.*]] = sub i32 [[TMP82]], [[TMP83]]
-// CHECK2-NEXT:    [[SUB68:%.*]] = sub i32 [[SUB67]], 1
+// CHECK2-NEXT:    [[SUB65:%.*]] = sub i32 [[TMP82]], [[TMP83]]
+// CHECK2-NEXT:    [[SUB66:%.*]] = sub i32 [[SUB65]], 1
 // CHECK2-NEXT:    [[TMP84:%.*]] = load i32, ptr [[DOTNEW_STEP21]], align 4
-// CHECK2-NEXT:    [[ADD69:%.*]] = add i32 [[SUB68]], [[TMP84]]
+// CHECK2-NEXT:    [[ADD67:%.*]] = add i32 [[SUB66]], [[TMP84]]
 // CHECK2-NEXT:    [[TMP85:%.*]] = load i32, ptr [[DOTNEW_STEP21]], align 4
-// CHECK2-NEXT:    [[DIV70:%.*]] = udiv i32 [[ADD69]], [[TMP85]]
-// CHECK2-NEXT:    [[SUB71:%.*]] = sub i32 [[DIV70]], 1
+// CHECK2-NEXT:    [[DIV68:%.*]] = udiv i32 [[ADD67]], [[TMP85]]
 // CHECK2-NEXT:    [[TMP86:%.*]] = load i32, ptr [[DOTNEW_STEP21]], align 4
-// CHECK2-NEXT:    [[MUL72:%.*]] = mul i32 [[SUB71]], [[TMP86]]
-// CHECK2-NEXT:    [[ADD73:%.*]] = add i32 [[TMP81]], [[MUL72]]
-// CHECK2-NEXT:    store i32 [[ADD73]], ptr [[K]], align 4
+// CHECK2-NEXT:    [[MUL69:%.*]] = mul i32 [[DIV68]], [[TMP86]]
+// CHECK2-NEXT:    [[ADD70:%.*]] = add i32 [[TMP81]], [[MUL69]]
+// CHECK2-NEXT:    store i32 [[ADD70]], ptr [[K]], align 4
 // CHECK2-NEXT:    ret void
 //
 //.
diff --git a/clang/test/OpenMP/loop_transform_iv.c b/clang/test/OpenMP/loop_transform_iv.c
index 4ecaeecb9a174..2f6105ed2927f 100644
--- a/clang/test/OpenMP/loop_transform_iv.c
+++ b/clang/test/OpenMP/loop_transform_iv.c
@@ -10,8 +10,8 @@ void test_tile(void) {
   #pragma omp tile sizes(2)
   for (i = 1; i <= 10; i++) {
   }
-  // CHECK: store i32 10, ptr %i
-  // After loop: i should be 10 (last iteration value per OpenMP 6.0 spec)
+  // CHECK: store i32 11, ptr %i
+  // After loop: i should be 11 (loop-exit value per OpenMP 6.0 spec)
 }
 
 void test_stripe(void) {
@@ -20,8 +20,8 @@ void test_stripe(void) {
   #pragma omp stripe sizes(3)
   for (i = 0; i < 10; i++) {
   }
-  // CHECK: store i32 9, ptr %i
-  // After loop: i should be 9 (last iteration value per OpenMP 6.0 spec)
+  // CHECK: store i32 10, ptr %i
+  // After loop: i should be 10 (loop-exit value per OpenMP 6.0 spec)
 }
 
 void test_tile_nested(void) {
@@ -31,9 +31,9 @@ void test_tile_nested(void) {
   for (i = 0; i < 10; i++)
     for (j = 0; j < 5; j++) {
     }
-  // CHECK: store i32 9, ptr %i
-  // CHECK: store i32 4, ptr %j
-  // After loop: i should be 9, j should be 4 (last iteration values per OpenMP 6.0 spec)
+  // CHECK: store i32 10, ptr %i
+  // CHECK: store i32 5, ptr %j
+  // After loop: i should be 10, j should be 5 (loop-exit values per OpenMP 6.0 spec)
 }
 
 void test_tile_stride(void) {
@@ -42,8 +42,8 @@ void test_tile_stride(void) {
   #pragma omp tile sizes(4)
   for (i = 5; i <= 15; i += 2) {
   }
-  // CHECK: store i32 15, ptr %i
-  // After loop: i should be 15 (last iteration value per OpenMP 6.0 spec)
+  // CHECK: store i32 17, ptr %i
+  // After loop: i should be 17 (loop-exit value per OpenMP 6.0 spec)
 }
 
 void test_tile_variable_bound(int n) {
@@ -56,11 +56,10 @@ void test_tile_variable_bound(int n) {
   // CHECK-NEXT: %[[NUMITER:.*]] = load i32, ptr %.capture_expr.
   // CHECK-NEXT: %[[SUB1:.*]] = sub nsw i32 %[[NUMITER]], 0
   // CHECK-NEXT: %[[DIV:.*]] = sdiv i32 %[[SUB1]], 1
-  // CHECK-NEXT: %[[LASTITER:.*]] = sub nsw i32 %[[DIV]], 1
-  // CHECK-NEXT: %[[MUL:.*]] = mul nsw i32 %[[LASTITER]], 1
+  // CHECK-NEXT: %[[MUL:.*]] = mul nsw i32 %[[DIV]], 1
   // CHECK-NEXT: %[[FINAL:.*]] = add nsw i32 0, %[[MUL]]
   // CHECK-NEXT: store i32 %[[FINAL]], ptr %i
-  // After loop: i should equal n-1 (last iteration value per OpenMP 6.0 spec)
+  // After loop: i should equal n (loop-exit value per OpenMP 6.0 spec)
 }
 
 void test_reverse(void) {
@@ -69,8 +68,8 @@ void test_reverse(void) {
   #pragma omp reverse
   for (i = 0; i < 10; i++) {
   }
-  // CHECK: store i32 9, ptr %i
-  // After loop: i should be 9 (last iteration value per OpenMP 6.0 spec)
+  // CHECK: store i32 10, ptr %i
+  // After loop: i should be 10 (loop-exit value per OpenMP 6.0 spec)
 }
 
 void test_interchange(void) {
@@ -80,9 +79,9 @@ void test_interchange(void) {
   for (i = 0; i < 10; i++)
     for (j = 0; j < 5; j++) {
     }
-  // CHECK: store i32 9, ptr %i
-  // CHECK: store i32 4, ptr %j
-  // After loop: i should be 9, j should be 4 (last iteration values per OpenMP 6.0 spec)
+  // CHECK: store i32 10, ptr %i
+  // CHECK: store i32 5, ptr %j
+  // After loop: i should be 10, j should be 5 (loop-exit values per OpenMP 6.0 spec)
 }
 
 void test_for_workshare(void) {
@@ -127,3 +126,23 @@ void test_tile_workshare(void) {
   // unspecified here (same as plain omp-for), so no restoring store
   // is expected for i after omp.loop.exit.
 }
+
+void test_tile_zero_tripcount(void) {
+  // CHECK-LABEL: define {{.*}} @test_tile_zero_tripcount
+  int i;
+  #pragma omp tile sizes(2)
+  for (i = 10; i < 5; i++) {
+  }
+  // CHECK: store i32 10, ptr %i
+  // Loop doesn't execute (tripcount = 0), i should remain at initial value 10.
+}
+
+void test_stripe_negative_step(void) {
+  // CHECK-LABEL: define {{.*}} @test_stripe_negative_step
+  int i;
+  #pragma omp stripe sizes(3)
+  for (i = 10; i > 0; i--) {
+  }
+  // CHECK: store i32 0, ptr %i
+  // Loop counts backward from 10 to 1, loop-exit value should be 0.
+}
diff --git a/clang/test/OpenMP/stripe_codegen.cpp b/clang/test/OpenMP/stripe_codegen.cpp
index aefa0001e9a72..7619e58d62a42 100644
--- a/clang/test/OpenMP/stripe_codegen.cpp
+++ b/clang/test/OpenMP/stripe_codegen.cpp
@@ -199,7 +199,7 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
 // CHECK1:       for.end12:
 // CHECK1-NEXT:    [[TMP11:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
-// CHECK1-NEXT:    store i32 16, ptr [[TMP11]], align 4
+// CHECK1-NEXT:    store i32 19, ptr [[TMP11]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -301,11 +301,10 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], [[TMP25]]
 // CHECK1-NEXT:    [[TMP26:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
 // CHECK1-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], [[TMP26]]
-// CHECK1-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
 // CHECK1-NEXT:    [[TMP27:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK1-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], [[TMP27]]
-// CHECK1-NEXT:    [[ADD24:%.*]] = add i32 [[TMP22]], [[MUL23]]
-// CHECK1-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[MUL22:%.*]] = mul i32 [[DIV21]], [[TMP27]]
+// CHECK1-NEXT:    [[ADD23:%.*]] = add i32 [[TMP22]], [[MUL22]]
+// CHECK1-NEXT:    store i32 [[ADD23]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -419,8 +418,8 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    store i32 [[ADD29]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP12:![0-9]+]]
 // CHECK1:       for.end30:
-// CHECK1-NEXT:    store i32 16, ptr [[I]], align 4
-// CHECK1-NEXT:    store i32 16, ptr [[J]], align 4
+// CHECK1-NEXT:    store i32 19, ptr [[I]], align 4
+// CHECK1-NEXT:    store i32 19, ptr [[J]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1126,10 +1125,9 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    [[SUB19:%.*]] = sub i32 [[SUB18]], 1
 // CHECK1-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], 3
 // CHECK1-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], 3
-// CHECK1-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
-// CHECK1-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], 3
-// CHECK1-NEXT:    [[ADD24:%.*]] = add i32 [[TMP18]], [[MUL23]]
-// CHECK1-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[MUL22:%.*]] = mul i32 [[DIV21]], 3
+// CHECK1-NEXT:    [[ADD23:%.*]] = add i32 [[TMP18]], [[MUL22]]
+// CHECK1-NEXT:    store i32 [[ADD23]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1219,7 +1217,7 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    store i32 [[ADD23]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]]
 // CHECK1:       for.end24:
-// CHECK1-NEXT:    store i32 16, ptr [[I]], align 4
+// CHECK1-NEXT:    store i32 19, ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1507,7 +1505,7 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
 // CHECK2:       for.end12:
 // CHECK2-NEXT:    [[TMP11:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
-// CHECK2-NEXT:    store i32 16, ptr [[TMP11]], align 4
+// CHECK2-NEXT:    store i32 19, ptr [[TMP11]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1615,11 +1613,10 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], [[TMP25]]
 // CHECK2-NEXT:    [[TMP26:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
 // CHECK2-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], [[TMP26]]
-// CHECK2-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
 // CHECK2-NEXT:    [[TMP27:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK2-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], [[TMP27]]
-// CHECK2-NEXT:    [[ADD24:%.*]] = add i32 [[TMP22]], [[MUL23]]
-// CHECK2-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[MUL22:%.*]] = mul i32 [[DIV21]], [[TMP27]]
+// CHECK2-NEXT:    [[ADD23:%.*]] = add i32 [[TMP22]], [[MUL22]]
+// CHECK2-NEXT:    store i32 [[ADD23]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1833,8 +1830,8 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    store i32 [[ADD29]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]]
 // CHECK2:       for.end30:
-// CHECK2-NEXT:    store i32 16, ptr [[I]], align 4
-// CHECK2-NEXT:    store i32 16, ptr [[J]], align 4
+// CHECK2-NEXT:    store i32 19, ptr [[I]], align 4
+// CHECK2-NEXT:    store i32 19, ptr [[J]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2531,7 +2528,7 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    store i32 [[ADD23]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]]
 // CHECK2:       for.end24:
-// CHECK2-NEXT:    store i32 16, ptr [[I]], align 4
+// CHECK2-NEXT:    store i32 19, ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2727,10 +2724,9 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    [[SUB19:%.*]] = sub i32 [[SUB18]], 1
 // CHECK2-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], 3
 // CHECK2-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], 3
-// CHECK2-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
-// CHECK2-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], 3
-// CHECK2-NEXT:    [[ADD24:%.*]] = add i32 [[TMP18]], [[MUL23]]
-// CHECK2-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[MUL22:%.*]] = mul i32 [[DIV21]], 3
+// CHECK2-NEXT:    [[ADD23:%.*]] = add i32 [[TMP18]], [[MUL22]]
+// CHECK2-NEXT:    store i32 [[ADD23]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
diff --git a/clang/test/OpenMP/tile_codegen.cpp b/clang/test/OpenMP/tile_codegen.cpp
index b024964cf8356..93e1c99e42b22 100644
--- a/clang/test/OpenMP/tile_codegen.cpp
+++ b/clang/test/OpenMP/tile_codegen.cpp
@@ -194,7 +194,7 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
 // CHECK1:       for.end12:
 // CHECK1-NEXT:    [[TMP11:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
-// CHECK1-NEXT:    store i32 16, ptr [[TMP11]], align 4
+// CHECK1-NEXT:    store i32 19, ptr [[TMP11]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -296,11 +296,10 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], [[TMP25]]
 // CHECK1-NEXT:    [[TMP26:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
 // CHECK1-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], [[TMP26]]
-// CHECK1-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
 // CHECK1-NEXT:    [[TMP27:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK1-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], [[TMP27]]
-// CHECK1-NEXT:    [[ADD24:%.*]] = add i32 [[TMP22]], [[MUL23]]
-// CHECK1-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[MUL22:%.*]] = mul i32 [[DIV21]], [[TMP27]]
+// CHECK1-NEXT:    [[ADD23:%.*]] = add i32 [[TMP22]], [[MUL22]]
+// CHECK1-NEXT:    store i32 [[ADD23]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -414,8 +413,8 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    store i32 [[ADD29]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP12:![0-9]+]]
 // CHECK1:       for.end30:
-// CHECK1-NEXT:    store i32 16, ptr [[I]], align 4
-// CHECK1-NEXT:    store i32 16, ptr [[J]], align 4
+// CHECK1-NEXT:    store i32 19, ptr [[I]], align 4
+// CHECK1-NEXT:    store i32 19, ptr [[J]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1019,10 +1018,9 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    [[SUB19:%.*]] = sub i32 [[SUB18]], 1
 // CHECK1-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], 3
 // CHECK1-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], 3
-// CHECK1-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
-// CHECK1-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], 3
-// CHECK1-NEXT:    [[ADD24:%.*]] = add i32 [[TMP18]], [[MUL23]]
-// CHECK1-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[MUL22:%.*]] = mul i32 [[DIV21]], 3
+// CHECK1-NEXT:    [[ADD23:%.*]] = add i32 [[TMP18]], [[MUL22]]
+// CHECK1-NEXT:    store i32 [[ADD23]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1112,7 +1110,7 @@ extern "C" void foo10(data_t data) {
 // CHECK1-NEXT:    store i32 [[ADD23]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]]
 // CHECK1:       for.end24:
-// CHECK1-NEXT:    store i32 16, ptr [[I]], align 4
+// CHECK1-NEXT:    store i32 19, ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1400,7 +1398,7 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
 // CHECK2:       for.end12:
 // CHECK2-NEXT:    [[TMP11:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
-// CHECK2-NEXT:    store i32 16, ptr [[TMP11]], align 4
+// CHECK2-NEXT:    store i32 19, ptr [[TMP11]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1508,11 +1506,10 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], [[TMP25]]
 // CHECK2-NEXT:    [[TMP26:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
 // CHECK2-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], [[TMP26]]
-// CHECK2-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
 // CHECK2-NEXT:    [[TMP27:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK2-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], [[TMP27]]
-// CHECK2-NEXT:    [[ADD24:%.*]] = add i32 [[TMP22]], [[MUL23]]
-// CHECK2-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[MUL22:%.*]] = mul i32 [[DIV21]], [[TMP27]]
+// CHECK2-NEXT:    [[ADD23:%.*]] = add i32 [[TMP22]], [[MUL22]]
+// CHECK2-NEXT:    store i32 [[ADD23]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1726,8 +1723,8 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    store i32 [[ADD29]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]]
 // CHECK2:       for.end30:
-// CHECK2-NEXT:    store i32 16, ptr [[I]], align 4
-// CHECK2-NEXT:    store i32 16, ptr [[J]], align 4
+// CHECK2-NEXT:    store i32 19, ptr [[I]], align 4
+// CHECK2-NEXT:    store i32 19, ptr [[J]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2322,7 +2319,7 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    store i32 [[ADD23]], ptr [[DOTFLOOR_0_IV_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]]
 // CHECK2:       for.end24:
-// CHECK2-NEXT:    store i32 16, ptr [[I]], align 4
+// CHECK2-NEXT:    store i32 19, ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -2518,10 +2515,9 @@ extern "C" void foo10(data_t data) {
 // CHECK2-NEXT:    [[SUB19:%.*]] = sub i32 [[SUB18]], 1
 // CHECK2-NEXT:    [[ADD20:%.*]] = add i32 [[SUB19]], 3
 // CHECK2-NEXT:    [[DIV21:%.*]] = udiv i32 [[ADD20]], 3
-// CHECK2-NEXT:    [[SUB22:%.*]] = sub i32 [[DIV21]], 1
-// CHECK2-NEXT:    [[MUL23:%.*]] = mul i32 [[SUB22]], 3
-// CHECK2-NEXT:    [[ADD24:%.*]] = add i32 [[TMP18]], [[MUL23]]
-// CHECK2-NEXT:    store i32 [[ADD24]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[MUL22:%.*]] = mul i32 [[DIV21]], 3
+// CHECK2-NEXT:    [[ADD23:%.*]] = add i32 [[TMP18]], [[MUL22]]
+// CHECK2-NEXT:    store i32 [[ADD23]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
diff --git a/offload/test/offloading/target-tile.c b/offload/test/offloading/target-tile.c
index 8460b43b6f9c7..5828083a6be3c 100644
--- a/offload/test/offloading/target-tile.c
+++ b/offload/test/offloading/target-tile.c
@@ -44,14 +44,14 @@ int main() {
       }
     }
   }
-  // Tiling leaves the loop variables with their values from the final iteration
-  // rather than with the usual +1.
-  expected = I_NTILES * I_NELEMS - 1;
+  // OpenMP 6.0 spec requires loop variables to have loop-exit values
+  // (the values they would have without the transformation directive).
+  expected = I_NTILES * I_NELEMS;
   if (i != expected) {
     printf("error: i = %d, expected %d\n", i, expected);
     return 1;
   }
-  expected = J_NTILES * J_NELEMS - 1;
+  expected = J_NTILES * J_NELEMS;
   if (j != expected) {
     printf("error: j = %d, expected %d\n", j, expected);
     return 1;

>From 5810ea15e1c5efb31dd9e9912b848a6f13100407 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Mon, 10 Aug 2026 12:28:00 -0700
Subject: [PATCH 04/11] Fix format and build error

---
 clang/lib/Sema/SemaOpenMP.cpp | 40 ++++++++++-------------------------
 1 file changed, 11 insertions(+), 29 deletions(-)

diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 7739d1b859eb2..cbd1606152914 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -10126,24 +10126,6 @@ static Stmt *buildPreInits(ASTContext &Context, ArrayRef<Stmt *> PreInits) {
 }
 
 /// Helper to determine if a loop should skip finalization.
-/// Returns true for range-based for loops or loops with non-arithmetic
-/// counters.
-static bool shouldSkipLoopFinalization(Stmt *LoopStmt) {
-  if (isa<CXXForRangeStmt>(LoopStmt))
-    return true;
-
-  auto *For = dyn_cast<ForStmt>(LoopStmt);
-  if (!For)
-    return false;
-
-  auto *InitDecl = dyn_cast_or_null<DeclStmt>(For->getInit());
-  if (!InitDecl || !InitDecl->isSingleDecl())
-    return false;
-
-  auto *InitVar = dyn_cast<VarDecl>(InitDecl->getSingleDecl());
-  return InitVar && !InitVar->getType()->isArithmeticType();
-}
-
 /// Build postupdate expression for the given list of postupdates expressions.
 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
   Expr *PostUpdate = nullptr;
@@ -10859,10 +10841,10 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
         // explicit finalization - the iterator is already at the end.
         Final = nullptr;
       } else {
-        Final = buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
-                                   IS.CounterInit, IS.NumIterations,
-                                   IS.CounterStep, IS.Subtract,
-                                   IS.IsNonRectangularLB, &Captures);
+        Final =
+            buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
+                               IS.CounterInit, IS.NumIterations, IS.CounterStep,
+                               IS.Subtract, IS.IsNonRectangularLB, &Captures);
         if (!Final.isUsable()) {
           HasErrors = true;
           break;
@@ -15241,9 +15223,9 @@ static Expr *makeFloorIVRef(Sema &SemaRef, ArrayRef<VarDecl *> FloorIndVars,
 /// if there are no finalization statements.
 /// Note: Loops with non-arithmetic loop variables (e.g., iterators) are skipped
 /// because finalization only applies to integer/floating-point counters.
-static Stmt *
-buildLoopFinalization(ASTContext &Context,
-                      ArrayRef<OMPLoopBasedDirective::HelperExprs> LoopHelpers) {
+static Stmt *buildLoopFinalization(
+    ASTContext &Context,
+    ArrayRef<OMPLoopBasedDirective::HelperExprs> LoopHelpers) {
   SmallVector<Stmt *, 8> FinalizationStmts;
 
   for (size_t I : llvm::seq<size_t>(LoopHelpers.size())) {
@@ -15609,10 +15591,10 @@ StmtResult SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
   }
 
-  return OMPTileDirective::Create(
-      Context, StartLoc, EndLoc, Clauses, NumLoops, AStmt, Inner,
-      buildPreInits(Context, PreInits),
-      buildLoopFinalization(Context, LoopHelpers));
+  return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
+                                  AStmt, Inner,
+                                  buildPreInits(Context, PreInits),
+                                  buildLoopFinalization(Context, LoopHelpers));
 }
 
 StmtResult SemaOpenMP::ActOnOpenMPStripeDirective(ArrayRef<OMPClause *> Clauses,

>From 700ec8997552ffa72f59a80f0af1776d068207d7 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Wed, 19 Aug 2026 13:42:04 -0700
Subject: [PATCH 05/11] Regenerate reverse_codegen.cpp test

---
 clang/test/OpenMP/reverse_codegen.cpp | 32 ++++++++++++---------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/clang/test/OpenMP/reverse_codegen.cpp b/clang/test/OpenMP/reverse_codegen.cpp
index 66febceaaea14..b12577d504803 100644
--- a/clang/test/OpenMP/reverse_codegen.cpp
+++ b/clang/test/OpenMP/reverse_codegen.cpp
@@ -156,7 +156,7 @@ extern "C" void foo7() {
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
 // CHECK1:       for.end:
 // CHECK1-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
-// CHECK1-NEXT:    store i32 16, ptr [[TMP7]], align 4
+// CHECK1-NEXT:    store i32 19, ptr [[TMP7]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -233,11 +233,10 @@ extern "C" void foo7() {
 // CHECK1-NEXT:    [[ADD12:%.*]] = add i32 [[SUB11]], [[TMP20]]
 // CHECK1-NEXT:    [[TMP21:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
 // CHECK1-NEXT:    [[DIV13:%.*]] = udiv i32 [[ADD12]], [[TMP21]]
-// CHECK1-NEXT:    [[SUB14:%.*]] = sub i32 [[DIV13]], 1
 // CHECK1-NEXT:    [[TMP22:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK1-NEXT:    [[MUL15:%.*]] = mul i32 [[SUB14]], [[TMP22]]
-// CHECK1-NEXT:    [[ADD16:%.*]] = add i32 [[TMP17]], [[MUL15]]
-// CHECK1-NEXT:    store i32 [[ADD16]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[MUL14:%.*]] = mul i32 [[DIV13]], [[TMP22]]
+// CHECK1-NEXT:    [[ADD15:%.*]] = add i32 [[TMP17]], [[MUL14]]
+// CHECK1-NEXT:    store i32 [[ADD15]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -558,10 +557,9 @@ extern "C" void foo7() {
 // CHECK1-NEXT:    [[SUB11:%.*]] = sub i32 [[SUB10]], 1
 // CHECK1-NEXT:    [[ADD12:%.*]] = add i32 [[SUB11]], 3
 // CHECK1-NEXT:    [[DIV13:%.*]] = udiv i32 [[ADD12]], 3
-// CHECK1-NEXT:    [[SUB14:%.*]] = sub i32 [[DIV13]], 1
-// CHECK1-NEXT:    [[MUL15:%.*]] = mul i32 [[SUB14]], 3
-// CHECK1-NEXT:    [[ADD16:%.*]] = add i32 [[TMP13]], [[MUL15]]
-// CHECK1-NEXT:    store i32 [[ADD16]], ptr [[I]], align 4
+// CHECK1-NEXT:    [[MUL14:%.*]] = mul i32 [[DIV13]], 3
+// CHECK1-NEXT:    [[ADD15:%.*]] = add i32 [[TMP13]], [[MUL14]]
+// CHECK1-NEXT:    store i32 [[ADD15]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -907,7 +905,7 @@ extern "C" void foo7() {
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
 // CHECK2:       for.end:
 // CHECK2-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
-// CHECK2-NEXT:    store i32 16, ptr [[TMP7]], align 4
+// CHECK2-NEXT:    store i32 19, ptr [[TMP7]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -990,11 +988,10 @@ extern "C" void foo7() {
 // CHECK2-NEXT:    [[ADD12:%.*]] = add i32 [[SUB11]], [[TMP20]]
 // CHECK2-NEXT:    [[TMP21:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
 // CHECK2-NEXT:    [[DIV13:%.*]] = udiv i32 [[ADD12]], [[TMP21]]
-// CHECK2-NEXT:    [[SUB14:%.*]] = sub i32 [[DIV13]], 1
 // CHECK2-NEXT:    [[TMP22:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4
-// CHECK2-NEXT:    [[MUL15:%.*]] = mul i32 [[SUB14]], [[TMP22]]
-// CHECK2-NEXT:    [[ADD16:%.*]] = add i32 [[TMP17]], [[MUL15]]
-// CHECK2-NEXT:    store i32 [[ADD16]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[MUL14:%.*]] = mul i32 [[DIV13]], [[TMP22]]
+// CHECK2-NEXT:    [[ADD15:%.*]] = add i32 [[TMP17]], [[MUL14]]
+// CHECK2-NEXT:    store i32 [[ADD15]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1594,10 +1591,9 @@ extern "C" void foo7() {
 // CHECK2-NEXT:    [[SUB11:%.*]] = sub i32 [[SUB10]], 1
 // CHECK2-NEXT:    [[ADD12:%.*]] = add i32 [[SUB11]], 3
 // CHECK2-NEXT:    [[DIV13:%.*]] = udiv i32 [[ADD12]], 3
-// CHECK2-NEXT:    [[SUB14:%.*]] = sub i32 [[DIV13]], 1
-// CHECK2-NEXT:    [[MUL15:%.*]] = mul i32 [[SUB14]], 3
-// CHECK2-NEXT:    [[ADD16:%.*]] = add i32 [[TMP13]], [[MUL15]]
-// CHECK2-NEXT:    store i32 [[ADD16]], ptr [[I]], align 4
+// CHECK2-NEXT:    [[MUL14:%.*]] = mul i32 [[DIV13]], 3
+// CHECK2-NEXT:    [[ADD15:%.*]] = add i32 [[TMP13]], [[MUL14]]
+// CHECK2-NEXT:    store i32 [[ADD15]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //

>From 76567d5e2d461622132ef755ba46452c0eb16043 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Fri, 21 Aug 2026 07:31:44 -0700
Subject: [PATCH 06/11] Addressed review comments

---
 clang/lib/Sema/SemaOpenMP.cpp         |   12 +-
 clang/test/OpenMP/loop_transform_iv.c | 1328 ++++++++++++++++++++++++-
 2 files changed, 1292 insertions(+), 48 deletions(-)

diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index cbd1606152914..a1cd89ced9af0 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -10125,7 +10125,6 @@ static Stmt *buildPreInits(ASTContext &Context, ArrayRef<Stmt *> PreInits) {
   return CompoundStmt::Create(Context, PreInits, FPOptionsOverride(), {}, {});
 }
 
-/// Helper to determine if a loop should skip finalization.
 /// Build postupdate expression for the given list of postupdates expressions.
 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
   Expr *PostUpdate = nullptr;
@@ -10829,13 +10828,12 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
       }
 
       // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
-      // For loop transformation directives with arithmetic counters, use
-      // (NumIters - 1) to get the value from the last iteration, not the loop
-      // exit value. For iterator-based loops (range-based for or explicit
-      // iterator loops), skip finalization entirely.
+      // For iterator-based loops (range-based for or explicit iterator loops)
+      // in loop transformation directives, skip finalization entirely.
       ExprResult Final;
       bool IsIteratorLoop =
-          IS.IsRangeFor || !IS.CounterVar->getType()->isArithmeticType();
+          IS.IsRangeFor || (!IS.CounterVar->getType()->isArithmeticType() &&
+                            !IS.CounterVar->getType()->isPointerType());
       if (IsIteratorLoop && isOpenMPLoopTransformationDirective(DKind)) {
         // Iterator-based loops in transformation directives don't need
         // explicit finalization - the iterator is already at the end.
@@ -17180,12 +17178,10 @@ StmtResult SemaOpenMP::ActOnOpenMPFuseDirective(ArrayRef<OMPClause *> Clauses,
   // 8. Build finalization statements for fused loops.
   // Collect HelperExprs from the fused loops.
   SmallVector<OMPLoopBasedDirective::HelperExprs, 4> FusedLoopHelpers;
-  SmallVector<Stmt *, 4> FusedLoopStmts;
   for (unsigned I = FirstVal - 1; I < LastVal; ++I) {
     if (SeqAnalysis.Loops[I].isRegularLoop() &&
         isa<ForStmt>(SeqAnalysis.Loops[I].TheForStmt)) {
       FusedLoopHelpers.push_back(SeqAnalysis.Loops[I].HelperExprs);
-      FusedLoopStmts.push_back(SeqAnalysis.Loops[I].TheForStmt);
     }
   }
 
diff --git a/clang/test/OpenMP/loop_transform_iv.c b/clang/test/OpenMP/loop_transform_iv.c
index 2f6105ed2927f..5da3650380f2e 100644
--- a/clang/test/OpenMP/loop_transform_iv.c
+++ b/clang/test/OpenMP/loop_transform_iv.c
@@ -1,3 +1,4 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ --version 5
 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -emit-llvm %s -o - | FileCheck %s
 // expected-no-diagnostics
 
@@ -5,144 +6,1391 @@
 // constructs as required by OpenMP 6.0 spec (pg 371, lines 19-21).
 
 void test_tile(void) {
-  // CHECK-LABEL: define {{.*}} @test_tile
   int i;
   #pragma omp tile sizes(2)
   for (i = 1; i <= 10; i++) {
   }
-  // CHECK: store i32 11, ptr %i
   // After loop: i should be 11 (loop-exit value per OpenMP 6.0 spec)
 }
 
 void test_stripe(void) {
-  // CHECK-LABEL: define {{.*}} @test_stripe
   int i;
   #pragma omp stripe sizes(3)
   for (i = 0; i < 10; i++) {
   }
-  // CHECK: store i32 10, ptr %i
   // After loop: i should be 10 (loop-exit value per OpenMP 6.0 spec)
 }
 
 void test_tile_nested(void) {
-  // CHECK-LABEL: define {{.*}} @test_tile_nested
   int i, j;
   #pragma omp tile sizes(2, 3)
   for (i = 0; i < 10; i++)
     for (j = 0; j < 5; j++) {
     }
-  // CHECK: store i32 10, ptr %i
-  // CHECK: store i32 5, ptr %j
   // After loop: i should be 10, j should be 5 (loop-exit values per OpenMP 6.0 spec)
 }
 
 void test_tile_stride(void) {
-  // CHECK-LABEL: define {{.*}} @test_tile_stride
   int i;
   #pragma omp tile sizes(4)
   for (i = 5; i <= 15; i += 2) {
   }
-  // CHECK: store i32 17, ptr %i
   // After loop: i should be 17 (loop-exit value per OpenMP 6.0 spec)
 }
 
 void test_tile_variable_bound(int n) {
-  // CHECK-LABEL: define {{.*}} @test_tile_variable_bound
   int i;
   #pragma omp tile sizes(3)
   for (i = 0; i < n; i++) {
   }
-  // CHECK: for.end14:
-  // CHECK-NEXT: %[[NUMITER:.*]] = load i32, ptr %.capture_expr.
-  // CHECK-NEXT: %[[SUB1:.*]] = sub nsw i32 %[[NUMITER]], 0
-  // CHECK-NEXT: %[[DIV:.*]] = sdiv i32 %[[SUB1]], 1
-  // CHECK-NEXT: %[[MUL:.*]] = mul nsw i32 %[[DIV]], 1
-  // CHECK-NEXT: %[[FINAL:.*]] = add nsw i32 0, %[[MUL]]
-  // CHECK-NEXT: store i32 %[[FINAL]], ptr %i
   // After loop: i should equal n (loop-exit value per OpenMP 6.0 spec)
 }
 
 void test_reverse(void) {
-  // CHECK-LABEL: define {{.*}} @test_reverse
   int i;
   #pragma omp reverse
   for (i = 0; i < 10; i++) {
   }
-  // CHECK: store i32 10, ptr %i
   // After loop: i should be 10 (loop-exit value per OpenMP 6.0 spec)
 }
 
 void test_interchange(void) {
-  // CHECK-LABEL: define {{.*}} @test_interchange
   int i, j;
   #pragma omp interchange permutation(2, 1)
   for (i = 0; i < 10; i++)
     for (j = 0; j < 5; j++) {
     }
-  // CHECK: store i32 10, ptr %i
-  // CHECK: store i32 5, ptr %j
   // After loop: i should be 10, j should be 5 (loop-exit values per OpenMP 6.0 spec)
 }
 
 void test_for_workshare(void) {
-  // CHECK-LABEL: define {{.*}} @test_for_workshare
   int i;
   #pragma omp for
   for (i = 5; i <= 10; i += 2) {
   }
-  // CHECK: omp.loop.exit:
-  // CHECK-NEXT: call void @__kmpc_for_static_fini
-  // CHECK-NEXT: call void @__kmpc_barrier
-  // CHECK-NEXT: ret void
   // omp for worksharing doesn't finalize the loop variable after the loop
 }
 
 void test_for_lastprivate(void) {
-  // CHECK-LABEL: define {{.*}} @test_for_lastprivate
   int i;
   #pragma omp parallel
   #pragma omp for lastprivate(i)
   for (i = 5; i <= 10; i += 2) {
   }
-  // CHECK: .omp.lastprivate.then:
-  // CHECK-NEXT: store i32 11, ptr %i{{.*}}, align 4
-  // CHECK-NEXT: %{{.*}} = load i32, ptr %i{{.*}}, align 4
-  // CHECK-NEXT: store i32 %{{.*}}, ptr %{{.*}}, align 4
   // omp for with lastprivate DOES finalize the loop variable
   // i = last_iteration_value + stride = 9 + 2 = 11
 }
 
 void test_tile_workshare(void) {
-  // CHECK-LABEL: define {{.*}} @test_tile_workshare
   int i;
   #pragma omp for
   #pragma omp tile sizes(2)
   for (i = 1; i <= 10; i++) {
   }
-  // CHECK: omp.loop.exit:
-  // CHECK-NOT: store {{.*}}, ptr %i
-  // CHECK: call void @__kmpc_for_static_fini
   // i is private to the `for` construct; its post-loop value is
   // unspecified here (same as plain omp-for), so no restoring store
   // is expected for i after omp.loop.exit.
 }
 
 void test_tile_zero_tripcount(void) {
-  // CHECK-LABEL: define {{.*}} @test_tile_zero_tripcount
   int i;
   #pragma omp tile sizes(2)
   for (i = 10; i < 5; i++) {
   }
-  // CHECK: store i32 10, ptr %i
   // Loop doesn't execute (tripcount = 0), i should remain at initial value 10.
 }
 
 void test_stripe_negative_step(void) {
-  // CHECK-LABEL: define {{.*}} @test_stripe_negative_step
   int i;
   #pragma omp stripe sizes(3)
   for (i = 10; i > 0; i--) {
   }
-  // CHECK: store i32 0, ptr %i
   // Loop counts backward from 10 to 1, loop-exit value should be 0.
 }
+
+void test_pointer_tile(void) {
+  int arr[20];
+  int *p;
+  #pragma omp tile sizes(5)
+  for (p = arr; p < arr + 20; p++) {
+    *p = 0;
+  }
+  // After loop: p should point to arr + 20 (loop-exit value)
+}
+
+void test_pointer_reverse(void) {
+  int arr[15];
+  int *q;
+  #pragma omp reverse
+  for (q = arr; q < arr + 15; q++) {
+    *q = 1;
+  }
+  // After loop: q should point to arr + 15 (loop-exit value)
+}
+
+void test_pointer_step(void) {
+  char buffer[30];
+  char *ptr;
+  #pragma omp tile sizes(4)
+  for (ptr = buffer; ptr < buffer + 30; ptr += 2) {
+    *ptr = 'x';
+  }
+  // After loop: ptr should point to buffer + 30 (loop-exit value)
+}
+
+void test_pointer_fuse(void) {
+  int arr1[10];
+  int arr2[15];
+  int *p;
+  int *q;
+  #pragma omp fuse looprange(1,2)
+  {
+    for (p = arr1; p < arr1 + 10; p++) {
+      *p = 0;
+    }
+    for (q = arr2; q < arr2 + 15; q++) {
+      *q = 1;
+    }
+  }
+  // After fuse: p should point to arr1 + 10, q should point to arr2 + 15
+}
+// CHECK-LABEL: define dso_local void @test_tile(
+// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 1, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND:.*]]
+// CHECK:       [[FOR_COND]]:
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
+// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END9:.*]]
+// CHECK:       [[FOR_BODY]]:
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND1:.*]]
+// CHECK:       [[FOR_COND1]]:
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 2
+// CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 10, [[ADD]]
+// CHECK-NEXT:    br i1 [[CMP2]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
+// CHECK:       [[COND_TRUE]]:
+// CHECK-NEXT:    br label %[[COND_END:.*]]
+// CHECK:       [[COND_FALSE]]:
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP4]], 2
+// CHECK-NEXT:    br label %[[COND_END]]
+// CHECK:       [[COND_END]]:
+// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 10, %[[COND_TRUE]] ], [ [[ADD3]], %[[COND_FALSE]] ]
+// CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP2]], [[COND]]
+// CHECK-NEXT:    br i1 [[CMP4]], label %[[FOR_BODY5:.*]], label %[[FOR_END:.*]]
+// CHECK:       [[FOR_BODY5]]:
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP5]], 1
+// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 1, [[MUL]]
+// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], align 4
+// CHECK-NEXT:    br label %[[FOR_INC:.*]]
+// CHECK:       [[FOR_INC]]:
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP2:![0-9]+]]
+// CHECK:       [[FOR_END]]:
+// CHECK-NEXT:    br label %[[FOR_INC7:.*]]
+// CHECK:       [[FOR_INC7]]:
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP7]], 2
+// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
+// CHECK:       [[FOR_END9]]:
+// CHECK-NEXT:    store i32 11, ptr [[I]], align 4
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define dso_local void @test_stripe(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTSTRIPE_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND:.*]]
+// CHECK:       [[FOR_COND]]:
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
+// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END9:.*]]
+// CHECK:       [[FOR_BODY]]:
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND1:.*]]
+// CHECK:       [[FOR_COND1]]:
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 3
+// CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 10, [[ADD]]
+// CHECK-NEXT:    br i1 [[CMP2]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
+// CHECK:       [[COND_TRUE]]:
+// CHECK-NEXT:    br label %[[COND_END:.*]]
+// CHECK:       [[COND_FALSE]]:
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP4]], 3
+// CHECK-NEXT:    br label %[[COND_END]]
+// CHECK:       [[COND_END]]:
+// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 10, %[[COND_TRUE]] ], [ [[ADD3]], %[[COND_FALSE]] ]
+// CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP2]], [[COND]]
+// CHECK-NEXT:    br i1 [[CMP4]], label %[[FOR_BODY5:.*]], label %[[FOR_END:.*]]
+// CHECK:       [[FOR_BODY5]]:
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP5]], 1
+// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 0, [[MUL]]
+// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], align 4
+// CHECK-NEXT:    br label %[[FOR_INC:.*]]
+// CHECK:       [[FOR_INC]]:
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP5:![0-9]+]]
+// CHECK:       [[FOR_END]]:
+// CHECK-NEXT:    br label %[[FOR_INC7:.*]]
+// CHECK:       [[FOR_INC7]]:
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP7]], 3
+// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
+// CHECK:       [[FOR_END9]]:
+// CHECK-NEXT:    store i32 10, ptr [[I]], align 4
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define dso_local void @test_tile_nested(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[J:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTFLOOR_1_IV_J:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTTILE_1_IV_J:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[J]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND:.*]]
+// CHECK:       [[FOR_COND]]:
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
+// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END30:.*]]
+// CHECK:       [[FOR_BODY]]:
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_1_IV_J]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND1:.*]]
+// CHECK:       [[FOR_COND1]]:
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], align 4
+// CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[TMP1]], 5
+// CHECK-NEXT:    br i1 [[CMP2]], label %[[FOR_BODY3:.*]], label %[[FOR_END27:.*]]
+// CHECK:       [[FOR_BODY3]]:
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[TMP2]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND4:.*]]
+// CHECK:       [[FOR_COND4]]:
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP4]], 2
+// CHECK-NEXT:    [[CMP5:%.*]] = icmp slt i32 10, [[ADD]]
+// CHECK-NEXT:    br i1 [[CMP5]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
+// CHECK:       [[COND_TRUE]]:
+// CHECK-NEXT:    br label %[[COND_END:.*]]
+// CHECK:       [[COND_FALSE]]:
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP5]], 2
+// CHECK-NEXT:    br label %[[COND_END]]
+// CHECK:       [[COND_END]]:
+// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 10, %[[COND_TRUE]] ], [ [[ADD6]], %[[COND_FALSE]] ]
+// CHECK-NEXT:    [[CMP7:%.*]] = icmp slt i32 [[TMP3]], [[COND]]
+// CHECK-NEXT:    br i1 [[CMP7]], label %[[FOR_BODY8:.*]], label %[[FOR_END24:.*]]
+// CHECK:       [[FOR_BODY8]]:
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP6]], 1
+// CHECK-NEXT:    [[ADD9:%.*]] = add nsw i32 0, [[MUL]]
+// CHECK-NEXT:    store i32 [[ADD9]], ptr [[I]], align 4
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], align 4
+// CHECK-NEXT:    store i32 [[TMP7]], ptr [[DOTTILE_1_IV_J]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND10:.*]]
+// CHECK:       [[FOR_COND10]]:
+// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTTILE_1_IV_J]], align 4
+// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], align 4
+// CHECK-NEXT:    [[ADD11:%.*]] = add nsw i32 [[TMP9]], 3
+// CHECK-NEXT:    [[CMP12:%.*]] = icmp slt i32 5, [[ADD11]]
+// CHECK-NEXT:    br i1 [[CMP12]], label %[[COND_TRUE13:.*]], label %[[COND_FALSE14:.*]]
+// CHECK:       [[COND_TRUE13]]:
+// CHECK-NEXT:    br label %[[COND_END16:.*]]
+// CHECK:       [[COND_FALSE14]]:
+// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], align 4
+// CHECK-NEXT:    [[ADD15:%.*]] = add nsw i32 [[TMP10]], 3
+// CHECK-NEXT:    br label %[[COND_END16]]
+// CHECK:       [[COND_END16]]:
+// CHECK-NEXT:    [[COND17:%.*]] = phi i32 [ 5, %[[COND_TRUE13]] ], [ [[ADD15]], %[[COND_FALSE14]] ]
+// CHECK-NEXT:    [[CMP18:%.*]] = icmp slt i32 [[TMP8]], [[COND17]]
+// CHECK-NEXT:    br i1 [[CMP18]], label %[[FOR_BODY19:.*]], label %[[FOR_END:.*]]
+// CHECK:       [[FOR_BODY19]]:
+// CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTTILE_1_IV_J]], align 4
+// CHECK-NEXT:    [[MUL20:%.*]] = mul nsw i32 [[TMP11]], 1
+// CHECK-NEXT:    [[ADD21:%.*]] = add nsw i32 0, [[MUL20]]
+// CHECK-NEXT:    store i32 [[ADD21]], ptr [[J]], align 4
+// CHECK-NEXT:    br label %[[FOR_INC:.*]]
+// CHECK:       [[FOR_INC]]:
+// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTTILE_1_IV_J]], align 4
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP12]], 1
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_1_IV_J]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND10]], !llvm.loop [[LOOP7:![0-9]+]]
+// CHECK:       [[FOR_END]]:
+// CHECK-NEXT:    br label %[[FOR_INC22:.*]]
+// CHECK:       [[FOR_INC22]]:
+// CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[INC23:%.*]] = add nsw i32 [[TMP13]], 1
+// CHECK-NEXT:    store i32 [[INC23]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND4]], !llvm.loop [[LOOP8:![0-9]+]]
+// CHECK:       [[FOR_END24]]:
+// CHECK-NEXT:    br label %[[FOR_INC25:.*]]
+// CHECK:       [[FOR_INC25]]:
+// CHECK-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], align 4
+// CHECK-NEXT:    [[ADD26:%.*]] = add nsw i32 [[TMP14]], 3
+// CHECK-NEXT:    store i32 [[ADD26]], ptr [[DOTFLOOR_1_IV_J]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP9:![0-9]+]]
+// CHECK:       [[FOR_END27]]:
+// CHECK-NEXT:    br label %[[FOR_INC28:.*]]
+// CHECK:       [[FOR_INC28]]:
+// CHECK-NEXT:    [[TMP15:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD29:%.*]] = add nsw i32 [[TMP15]], 2
+// CHECK-NEXT:    store i32 [[ADD29]], ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP10:![0-9]+]]
+// CHECK:       [[FOR_END30]]:
+// CHECK-NEXT:    store i32 10, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 5, ptr [[J]], align 4
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define dso_local void @test_tile_stride(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 5, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND:.*]]
+// CHECK:       [[FOR_COND]]:
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 6
+// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END9:.*]]
+// CHECK:       [[FOR_BODY]]:
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND1:.*]]
+// CHECK:       [[FOR_COND1]]:
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 4
+// CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 6, [[ADD]]
+// CHECK-NEXT:    br i1 [[CMP2]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
+// CHECK:       [[COND_TRUE]]:
+// CHECK-NEXT:    br label %[[COND_END:.*]]
+// CHECK:       [[COND_FALSE]]:
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP4]], 4
+// CHECK-NEXT:    br label %[[COND_END]]
+// CHECK:       [[COND_END]]:
+// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 6, %[[COND_TRUE]] ], [ [[ADD3]], %[[COND_FALSE]] ]
+// CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP2]], [[COND]]
+// CHECK-NEXT:    br i1 [[CMP4]], label %[[FOR_BODY5:.*]], label %[[FOR_END:.*]]
+// CHECK:       [[FOR_BODY5]]:
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP5]], 2
+// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 5, [[MUL]]
+// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], align 4
+// CHECK-NEXT:    br label %[[FOR_INC:.*]]
+// CHECK:       [[FOR_INC]]:
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP11:![0-9]+]]
+// CHECK:       [[FOR_END]]:
+// CHECK-NEXT:    br label %[[FOR_INC7:.*]]
+// CHECK:       [[FOR_INC7]]:
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP7]], 4
+// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP12:![0-9]+]]
+// CHECK:       [[FOR_END9]]:
+// CHECK-NEXT:    store i32 17, ptr [[I]], align 4
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define dso_local void @test_tile_variable_bound(
+// CHECK-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[N_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[N]], ptr [[N_ADDR]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[N_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[TMP0]], ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[TMP1]], 0
+// CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[SUB]], 1
+// CHECK-NEXT:    [[SUB2:%.*]] = sub nsw i32 [[DIV]], 1
+// CHECK-NEXT:    store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND:.*]]
+// CHECK:       [[FOR_COND]]:
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 1
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP2]], [[ADD]]
+// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END14:.*]]
+// CHECK:       [[FOR_BODY]]:
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[TMP4]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND3:.*]]
+// CHECK:       [[FOR_COND3]]:
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK-NEXT:    [[ADD4:%.*]] = add nsw i32 [[TMP6]], 1
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD5:%.*]] = add nsw i32 [[TMP7]], 3
+// CHECK-NEXT:    [[CMP6:%.*]] = icmp slt i32 [[ADD4]], [[ADD5]]
+// CHECK-NEXT:    br i1 [[CMP6]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
+// CHECK:       [[COND_TRUE]]:
+// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK-NEXT:    [[ADD7:%.*]] = add nsw i32 [[TMP8]], 1
+// CHECK-NEXT:    br label %[[COND_END:.*]]
+// CHECK:       [[COND_FALSE]]:
+// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP9]], 3
+// CHECK-NEXT:    br label %[[COND_END]]
+// CHECK:       [[COND_END]]:
+// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[ADD7]], %[[COND_TRUE]] ], [ [[ADD8]], %[[COND_FALSE]] ]
+// CHECK-NEXT:    [[CMP9:%.*]] = icmp slt i32 [[TMP5]], [[COND]]
+// CHECK-NEXT:    br i1 [[CMP9]], label %[[FOR_BODY10:.*]], label %[[FOR_END:.*]]
+// CHECK:       [[FOR_BODY10]]:
+// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1
+// CHECK-NEXT:    [[ADD11:%.*]] = add nsw i32 0, [[MUL]]
+// CHECK-NEXT:    store i32 [[ADD11]], ptr [[I]], align 4
+// CHECK-NEXT:    br label %[[FOR_INC:.*]]
+// CHECK:       [[FOR_INC]]:
+// CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP11]], 1
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND3]], !llvm.loop [[LOOP13:![0-9]+]]
+// CHECK:       [[FOR_END]]:
+// CHECK-NEXT:    br label %[[FOR_INC12:.*]]
+// CHECK:       [[FOR_INC12]]:
+// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD13:%.*]] = add nsw i32 [[TMP12]], 3
+// CHECK-NEXT:    store i32 [[ADD13]], ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP14:![0-9]+]]
+// CHECK:       [[FOR_END14]]:
+// CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK-NEXT:    [[SUB15:%.*]] = sub nsw i32 [[TMP13]], 0
+// CHECK-NEXT:    [[DIV16:%.*]] = sdiv i32 [[SUB15]], 1
+// CHECK-NEXT:    [[MUL17:%.*]] = mul nsw i32 [[DIV16]], 1
+// CHECK-NEXT:    [[ADD18:%.*]] = add nsw i32 0, [[MUL17]]
+// CHECK-NEXT:    store i32 [[ADD18]], ptr [[I]], align 4
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define dso_local void @test_reverse(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND:.*]]
+// CHECK:       [[FOR_COND]]:
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
+// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END:.*]]
+// CHECK:       [[FOR_BODY]]:
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 9, [[TMP1]]
+// CHECK-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], 1
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
+// CHECK-NEXT:    store i32 [[ADD]], ptr [[I]], align 4
+// CHECK-NEXT:    br label %[[FOR_INC:.*]]
+// CHECK:       [[FOR_INC]]:
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP3]], 1
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]]
+// CHECK:       [[FOR_END]]:
+// CHECK-NEXT:    store i32 10, ptr [[I]], align 4
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define dso_local void @test_interchange(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[J:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTPERMUTED_0_IV_J:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTPERMUTED_1_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[J]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTPERMUTED_0_IV_J]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND:.*]]
+// CHECK:       [[FOR_COND]]:
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 5
+// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END8:.*]]
+// CHECK:       [[FOR_BODY]]:
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP1]], 1
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
+// CHECK-NEXT:    store i32 [[ADD]], ptr [[J]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTPERMUTED_1_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND1:.*]]
+// CHECK:       [[FOR_COND1]]:
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4
+// CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[TMP2]], 10
+// CHECK-NEXT:    br i1 [[CMP2]], label %[[FOR_BODY3:.*]], label %[[FOR_END:.*]]
+// CHECK:       [[FOR_BODY3]]:
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4
+// CHECK-NEXT:    [[MUL4:%.*]] = mul nsw i32 [[TMP3]], 1
+// CHECK-NEXT:    [[ADD5:%.*]] = add nsw i32 0, [[MUL4]]
+// CHECK-NEXT:    store i32 [[ADD5]], ptr [[I]], align 4
+// CHECK-NEXT:    br label %[[FOR_INC:.*]]
+// CHECK:       [[FOR_INC]]:
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP4]], 1
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTPERMUTED_1_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP16:![0-9]+]]
+// CHECK:       [[FOR_END]]:
+// CHECK-NEXT:    br label %[[FOR_INC6:.*]]
+// CHECK:       [[FOR_INC6]]:
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4
+// CHECK-NEXT:    [[INC7:%.*]] = add nsw i32 [[TMP5]], 1
+// CHECK-NEXT:    store i32 [[INC7]], ptr [[DOTPERMUTED_0_IV_J]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP17:![0-9]+]]
+// CHECK:       [[FOR_END8]]:
+// CHECK-NEXT:    store i32 10, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 5, ptr [[J]], align 4
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define dso_local void @test_for_workshare(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[I1:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:[0-9]+]])
+// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
+// CHECK-NEXT:    store i32 2, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
+// CHECK-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 2
+// CHECK-NEXT:    br i1 [[CMP]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
+// CHECK:       [[COND_TRUE]]:
+// CHECK-NEXT:    br label %[[COND_END:.*]]
+// CHECK:       [[COND_FALSE]]:
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    br label %[[COND_END]]
+// CHECK:       [[COND_END]]:
+// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 2, %[[COND_TRUE]] ], [ [[TMP2]], %[[COND_FALSE]] ]
+// CHECK-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
+// CHECK-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND:.*]]
+// CHECK:       [[OMP_INNER_FOR_COND]]:
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]]
+// CHECK-NEXT:    br i1 [[CMP2]], label %[[OMP_INNER_FOR_BODY:.*]], label %[[OMP_INNER_FOR_END:.*]]
+// CHECK:       [[OMP_INNER_FOR_BODY]]:
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP6]], 2
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 5, [[MUL]]
+// CHECK-NEXT:    store i32 [[ADD]], ptr [[I1]], align 4
+// CHECK-NEXT:    br label %[[OMP_BODY_CONTINUE:.*]]
+// CHECK:       [[OMP_BODY_CONTINUE]]:
+// CHECK-NEXT:    br label %[[OMP_INNER_FOR_INC:.*]]
+// CHECK:       [[OMP_INNER_FOR_INC]]:
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP7]], 1
+// CHECK-NEXT:    store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND]]
+// CHECK:       [[OMP_INNER_FOR_END]]:
+// CHECK-NEXT:    br label %[[OMP_LOOP_EXIT:.*]]
+// CHECK:       [[OMP_LOOP_EXIT]]:
+// CHECK-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
+// CHECK-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3:[0-9]+]], i32 [[TMP0]])
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define dso_local void @test_for_lastprivate(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 1, ptr @test_for_lastprivate.omp_outlined, ptr [[I]])
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define internal void @test_for_lastprivate.omp_outlined(
+// CHECK-SAME: ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[I:%.*]]) #[[ATTR3:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[I_ADDR:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[I1:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[I2:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
+// CHECK-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
+// CHECK-NEXT:    store ptr [[I]], ptr [[I_ADDR]], align 8
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[I_ADDR]], align 8, !nonnull [[META18:![0-9]+]], !align [[META19:![0-9]+]]
+// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
+// CHECK-NEXT:    store i32 2, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 4
+// CHECK-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP2]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP3]], 2
+// CHECK-NEXT:    br i1 [[CMP]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
+// CHECK:       [[COND_TRUE]]:
+// CHECK-NEXT:    br label %[[COND_END:.*]]
+// CHECK:       [[COND_FALSE]]:
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    br label %[[COND_END]]
+// CHECK:       [[COND_END]]:
+// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 2, %[[COND_TRUE]] ], [ [[TMP4]], %[[COND_FALSE]] ]
+// CHECK-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
+// CHECK-NEXT:    store i32 [[TMP5]], ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND:.*]]
+// CHECK:       [[OMP_INNER_FOR_COND]]:
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[CMP3:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]]
+// CHECK-NEXT:    br i1 [[CMP3]], label %[[OMP_INNER_FOR_BODY:.*]], label %[[OMP_INNER_FOR_END:.*]]
+// CHECK:       [[OMP_INNER_FOR_BODY]]:
+// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP8]], 2
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 5, [[MUL]]
+// CHECK-NEXT:    store i32 [[ADD]], ptr [[I1]], align 4
+// CHECK-NEXT:    br label %[[OMP_BODY_CONTINUE:.*]]
+// CHECK:       [[OMP_BODY_CONTINUE]]:
+// CHECK-NEXT:    br label %[[OMP_INNER_FOR_INC:.*]]
+// CHECK:       [[OMP_INNER_FOR_INC]]:
+// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    [[ADD4:%.*]] = add nsw i32 [[TMP9]], 1
+// CHECK-NEXT:    store i32 [[ADD4]], ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND]]
+// CHECK:       [[OMP_INNER_FOR_END]]:
+// CHECK-NEXT:    br label %[[OMP_LOOP_EXIT:.*]]
+// CHECK:       [[OMP_LOOP_EXIT]]:
+// CHECK-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]])
+// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4
+// CHECK-NEXT:    [[TMP11:%.*]] = icmp ne i32 [[TMP10]], 0
+// CHECK-NEXT:    br i1 [[TMP11]], [[DOTOMP_LASTPRIVATE_THEN:label %.*]], [[DOTOMP_LASTPRIVATE_DONE:label %.*]]
+// CHECK:       [[_OMP_LASTPRIVATE_THEN:.*:]]
+// CHECK-NEXT:    store i32 11, ptr [[I1]], align 4
+// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[I1]], align 4
+// CHECK-NEXT:    store i32 [[TMP12]], ptr [[TMP0]], align 4
+// CHECK-NEXT:    br [[DOTOMP_LASTPRIVATE_DONE]]
+// CHECK:       [[_OMP_LASTPRIVATE_DONE:.*:]]
+// CHECK-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP2]])
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define dso_local void @test_tile_workshare(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[TMP:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
+// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
+// CHECK-NEXT:    store i32 4, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
+// CHECK-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 4
+// CHECK-NEXT:    br i1 [[CMP]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
+// CHECK:       [[COND_TRUE]]:
+// CHECK-NEXT:    br label %[[COND_END:.*]]
+// CHECK:       [[COND_FALSE]]:
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    br label %[[COND_END]]
+// CHECK:       [[COND_END]]:
+// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 4, %[[COND_TRUE]] ], [ [[TMP2]], %[[COND_FALSE]] ]
+// CHECK-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
+// CHECK-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND:.*]]
+// CHECK:       [[OMP_INNER_FOR_COND]]:
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[CMP1:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]]
+// CHECK-NEXT:    br i1 [[CMP1]], label %[[OMP_INNER_FOR_BODY:.*]], label %[[OMP_INNER_FOR_END:.*]]
+// CHECK:       [[OMP_INNER_FOR_BODY]]:
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP6]], 2
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
+// CHECK-NEXT:    store i32 [[ADD]], ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[TMP7]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND:.*]]
+// CHECK:       [[FOR_COND]]:
+// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD2:%.*]] = add nsw i32 [[TMP9]], 2
+// CHECK-NEXT:    [[CMP3:%.*]] = icmp slt i32 10, [[ADD2]]
+// CHECK-NEXT:    br i1 [[CMP3]], label %[[COND_TRUE4:.*]], label %[[COND_FALSE5:.*]]
+// CHECK:       [[COND_TRUE4]]:
+// CHECK-NEXT:    br label %[[COND_END7:.*]]
+// CHECK:       [[COND_FALSE5]]:
+// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP10]], 2
+// CHECK-NEXT:    br label %[[COND_END7]]
+// CHECK:       [[COND_END7]]:
+// CHECK-NEXT:    [[COND8:%.*]] = phi i32 [ 10, %[[COND_TRUE4]] ], [ [[ADD6]], %[[COND_FALSE5]] ]
+// CHECK-NEXT:    [[CMP9:%.*]] = icmp slt i32 [[TMP8]], [[COND8]]
+// CHECK-NEXT:    br i1 [[CMP9]], label %[[FOR_BODY:.*]], label %[[FOR_END:.*]]
+// CHECK:       [[FOR_BODY]]:
+// CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[MUL10:%.*]] = mul nsw i32 [[TMP11]], 1
+// CHECK-NEXT:    [[ADD11:%.*]] = add nsw i32 1, [[MUL10]]
+// CHECK-NEXT:    store i32 [[ADD11]], ptr [[I]], align 4
+// CHECK-NEXT:    br label %[[FOR_INC:.*]]
+// CHECK:       [[FOR_INC]]:
+// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP12]], 1
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP22:![0-9]+]]
+// CHECK:       [[FOR_END]]:
+// CHECK-NEXT:    br label %[[OMP_BODY_CONTINUE:.*]]
+// CHECK:       [[OMP_BODY_CONTINUE]]:
+// CHECK-NEXT:    br label %[[OMP_INNER_FOR_INC:.*]]
+// CHECK:       [[OMP_INNER_FOR_INC]]:
+// CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    [[ADD12:%.*]] = add nsw i32 [[TMP13]], 1
+// CHECK-NEXT:    store i32 [[ADD12]], ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND]]
+// CHECK:       [[OMP_INNER_FOR_END]]:
+// CHECK-NEXT:    br label %[[OMP_LOOP_EXIT:.*]]
+// CHECK:       [[OMP_LOOP_EXIT]]:
+// CHECK-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
+// CHECK-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]])
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define dso_local void @test_tile_zero_tripcount(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 10, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND:.*]]
+// CHECK:       [[FOR_COND]]:
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], -5
+// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END9:.*]]
+// CHECK:       [[FOR_BODY]]:
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND1:.*]]
+// CHECK:       [[FOR_COND1]]:
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 2
+// CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 -5, [[ADD]]
+// CHECK-NEXT:    br i1 [[CMP2]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
+// CHECK:       [[COND_TRUE]]:
+// CHECK-NEXT:    br label %[[COND_END:.*]]
+// CHECK:       [[COND_FALSE]]:
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP4]], 2
+// CHECK-NEXT:    br label %[[COND_END]]
+// CHECK:       [[COND_END]]:
+// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ -5, %[[COND_TRUE]] ], [ [[ADD3]], %[[COND_FALSE]] ]
+// CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP2]], [[COND]]
+// CHECK-NEXT:    br i1 [[CMP4]], label %[[FOR_BODY5:.*]], label %[[FOR_END:.*]]
+// CHECK:       [[FOR_BODY5]]:
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP5]], 1
+// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 10, [[MUL]]
+// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], align 4
+// CHECK-NEXT:    br label %[[FOR_INC:.*]]
+// CHECK:       [[FOR_INC]]:
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP23:![0-9]+]]
+// CHECK:       [[FOR_END]]:
+// CHECK-NEXT:    br label %[[FOR_INC7:.*]]
+// CHECK:       [[FOR_INC7]]:
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP7]], 2
+// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]]
+// CHECK:       [[FOR_END9]]:
+// CHECK-NEXT:    store i32 5, ptr [[I]], align 4
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define dso_local void @test_stripe_negative_step(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[DOTSTRIPE_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 10, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND:.*]]
+// CHECK:       [[FOR_COND]]:
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
+// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END8:.*]]
+// CHECK:       [[FOR_BODY]]:
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND1:.*]]
+// CHECK:       [[FOR_COND1]]:
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 3
+// CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 10, [[ADD]]
+// CHECK-NEXT:    br i1 [[CMP2]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
+// CHECK:       [[COND_TRUE]]:
+// CHECK-NEXT:    br label %[[COND_END:.*]]
+// CHECK:       [[COND_FALSE]]:
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP4]], 3
+// CHECK-NEXT:    br label %[[COND_END]]
+// CHECK:       [[COND_END]]:
+// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 10, %[[COND_TRUE]] ], [ [[ADD3]], %[[COND_FALSE]] ]
+// CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP2]], [[COND]]
+// CHECK-NEXT:    br i1 [[CMP4]], label %[[FOR_BODY5:.*]], label %[[FOR_END:.*]]
+// CHECK:       [[FOR_BODY5]]:
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP5]], 1
+// CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 10, [[MUL]]
+// CHECK-NEXT:    store i32 [[SUB]], ptr [[I]], align 4
+// CHECK-NEXT:    br label %[[FOR_INC:.*]]
+// CHECK:       [[FOR_INC]]:
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP25:![0-9]+]]
+// CHECK:       [[FOR_END]]:
+// CHECK-NEXT:    br label %[[FOR_INC6:.*]]
+// CHECK:       [[FOR_INC6]]:
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[ADD7:%.*]] = add nsw i32 [[TMP7]], 3
+// CHECK-NEXT:    store i32 [[ADD7]], ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]]
+// CHECK:       [[FOR_END8]]:
+// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define dso_local void @test_pointer_tile(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[ARR:%.*]] = alloca [20 x i32], align 16
+// CHECK-NEXT:    [[P:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_P:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTTILE_0_IV_P:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [20 x i32], ptr [[ARR]], i64 0, i64 0
+// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[P]], align 8
+// CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [20 x i32], ptr [[ARR]], i64 0, i64 0
+// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [20 x i32], ptr [[ARR]], i64 0, i64 0
+// CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY3]], i64 20
+// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], align 8
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
+// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP0]] to i64
+// CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP1]] to i64
+// CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
+// CHECK-NEXT:    [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 4
+// CHECK-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
+// CHECK-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
+// CHECK-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
+// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    store i64 0, ptr [[DOTFLOOR_0_IV_P]], align 8
+// CHECK-NEXT:    br label %[[FOR_COND:.*]]
+// CHECK:       [[FOR_COND]]:
+// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], align 8
+// CHECK-NEXT:    [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP3]], 1
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[TMP2]], [[ADD6]]
+// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END18:.*]]
+// CHECK:       [[FOR_BODY]]:
+// CHECK-NEXT:    [[TMP4:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], align 8
+// CHECK-NEXT:    store i64 [[TMP4]], ptr [[DOTTILE_0_IV_P]], align 8
+// CHECK-NEXT:    br label %[[FOR_COND7:.*]]
+// CHECK:       [[FOR_COND7]]:
+// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTTILE_0_IV_P]], align 8
+// CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[ADD8:%.*]] = add nsw i64 [[TMP6]], 1
+// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], align 8
+// CHECK-NEXT:    [[ADD9:%.*]] = add nsw i64 [[TMP7]], 5
+// CHECK-NEXT:    [[CMP10:%.*]] = icmp slt i64 [[ADD8]], [[ADD9]]
+// CHECK-NEXT:    br i1 [[CMP10]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
+// CHECK:       [[COND_TRUE]]:
+// CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[ADD11:%.*]] = add nsw i64 [[TMP8]], 1
+// CHECK-NEXT:    br label %[[COND_END:.*]]
+// CHECK:       [[COND_FALSE]]:
+// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], align 8
+// CHECK-NEXT:    [[ADD12:%.*]] = add nsw i64 [[TMP9]], 5
+// CHECK-NEXT:    br label %[[COND_END]]
+// CHECK:       [[COND_END]]:
+// CHECK-NEXT:    [[COND:%.*]] = phi i64 [ [[ADD11]], %[[COND_TRUE]] ], [ [[ADD12]], %[[COND_FALSE]] ]
+// CHECK-NEXT:    [[CMP13:%.*]] = icmp slt i64 [[TMP5]], [[COND]]
+// CHECK-NEXT:    br i1 [[CMP13]], label %[[FOR_BODY14:.*]], label %[[FOR_END:.*]]
+// CHECK:       [[FOR_BODY14]]:
+// CHECK-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTTILE_0_IV_P]], align 8
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP11]], 1
+// CHECK-NEXT:    [[ADD_PTR15:%.*]] = getelementptr inbounds i32, ptr [[TMP10]], i64 [[MUL]]
+// CHECK-NEXT:    store ptr [[ADD_PTR15]], ptr [[P]], align 8
+// CHECK-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[P]], align 8
+// CHECK-NEXT:    store i32 0, ptr [[TMP12]], align 4
+// CHECK-NEXT:    br label %[[FOR_INC:.*]]
+// CHECK:       [[FOR_INC]]:
+// CHECK-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTTILE_0_IV_P]], align 8
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP13]], 1
+// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTTILE_0_IV_P]], align 8
+// CHECK-NEXT:    br label %[[FOR_COND7]], !llvm.loop [[LOOP27:![0-9]+]]
+// CHECK:       [[FOR_END]]:
+// CHECK-NEXT:    br label %[[FOR_INC16:.*]]
+// CHECK:       [[FOR_INC16]]:
+// CHECK-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], align 8
+// CHECK-NEXT:    [[ADD17:%.*]] = add nsw i64 [[TMP14]], 5
+// CHECK-NEXT:    store i64 [[ADD17]], ptr [[DOTFLOOR_0_IV_P]], align 8
+// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP28:![0-9]+]]
+// CHECK:       [[FOR_END18]]:
+// CHECK-NEXT:    [[TMP15:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[TMP16:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
+// CHECK-NEXT:    [[TMP17:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[SUB_PTR_LHS_CAST19:%.*]] = ptrtoaddr ptr [[TMP16]] to i64
+// CHECK-NEXT:    [[SUB_PTR_RHS_CAST20:%.*]] = ptrtoaddr ptr [[TMP17]] to i64
+// CHECK-NEXT:    [[SUB_PTR_SUB21:%.*]] = sub i64 [[SUB_PTR_LHS_CAST19]], [[SUB_PTR_RHS_CAST20]]
+// CHECK-NEXT:    [[SUB_PTR_DIV22:%.*]] = sdiv exact i64 [[SUB_PTR_SUB21]], 4
+// CHECK-NEXT:    [[SUB23:%.*]] = sub nsw i64 [[SUB_PTR_DIV22]], 1
+// CHECK-NEXT:    [[ADD24:%.*]] = add nsw i64 [[SUB23]], 1
+// CHECK-NEXT:    [[DIV25:%.*]] = sdiv i64 [[ADD24]], 1
+// CHECK-NEXT:    [[MUL26:%.*]] = mul nsw i64 [[DIV25]], 1
+// CHECK-NEXT:    [[ADD_PTR27:%.*]] = getelementptr inbounds i32, ptr [[TMP15]], i64 [[MUL26]]
+// CHECK-NEXT:    store ptr [[ADD_PTR27]], ptr [[P]], align 8
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define dso_local void @test_pointer_reverse(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[ARR:%.*]] = alloca [15 x i32], align 16
+// CHECK-NEXT:    [[Q:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTFORWARD_IV_Q:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTREVERSED_IV_Q:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR]], i64 0, i64 0
+// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[Q]], align 8
+// CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR]], i64 0, i64 0
+// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR]], i64 0, i64 0
+// CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY3]], i64 15
+// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], align 8
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
+// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP0]] to i64
+// CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP1]] to i64
+// CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
+// CHECK-NEXT:    [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 4
+// CHECK-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
+// CHECK-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
+// CHECK-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
+// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    store i64 0, ptr [[DOTFORWARD_IV_Q]], align 8
+// CHECK-NEXT:    br label %[[FOR_COND:.*]]
+// CHECK:       [[FOR_COND]]:
+// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTFORWARD_IV_Q]], align 8
+// CHECK-NEXT:    [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP3]], 1
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[TMP2]], [[ADD6]]
+// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END:.*]]
+// CHECK:       [[FOR_BODY]]:
+// CHECK-NEXT:    [[TMP4:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[ADD7:%.*]] = add nsw i64 [[TMP4]], 1
+// CHECK-NEXT:    [[SUB8:%.*]] = sub nsw i64 [[ADD7]], 1
+// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTFORWARD_IV_Q]], align 8
+// CHECK-NEXT:    [[SUB9:%.*]] = sub nsw i64 [[SUB8]], [[TMP5]]
+// CHECK-NEXT:    store i64 [[SUB9]], ptr [[DOTREVERSED_IV_Q]], align 8
+// CHECK-NEXT:    [[TMP6:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTREVERSED_IV_Q]], align 8
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP7]], 1
+// CHECK-NEXT:    [[ADD_PTR10:%.*]] = getelementptr inbounds i32, ptr [[TMP6]], i64 [[MUL]]
+// CHECK-NEXT:    store ptr [[ADD_PTR10]], ptr [[Q]], align 8
+// CHECK-NEXT:    [[TMP8:%.*]] = load ptr, ptr [[Q]], align 8
+// CHECK-NEXT:    store i32 1, ptr [[TMP8]], align 4
+// CHECK-NEXT:    br label %[[FOR_INC:.*]]
+// CHECK:       [[FOR_INC]]:
+// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFORWARD_IV_Q]], align 8
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP9]], 1
+// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTFORWARD_IV_Q]], align 8
+// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP29:![0-9]+]]
+// CHECK:       [[FOR_END]]:
+// CHECK-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[TMP11:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
+// CHECK-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[SUB_PTR_LHS_CAST11:%.*]] = ptrtoaddr ptr [[TMP11]] to i64
+// CHECK-NEXT:    [[SUB_PTR_RHS_CAST12:%.*]] = ptrtoaddr ptr [[TMP12]] to i64
+// CHECK-NEXT:    [[SUB_PTR_SUB13:%.*]] = sub i64 [[SUB_PTR_LHS_CAST11]], [[SUB_PTR_RHS_CAST12]]
+// CHECK-NEXT:    [[SUB_PTR_DIV14:%.*]] = sdiv exact i64 [[SUB_PTR_SUB13]], 4
+// CHECK-NEXT:    [[SUB15:%.*]] = sub nsw i64 [[SUB_PTR_DIV14]], 1
+// CHECK-NEXT:    [[ADD16:%.*]] = add nsw i64 [[SUB15]], 1
+// CHECK-NEXT:    [[DIV17:%.*]] = sdiv i64 [[ADD16]], 1
+// CHECK-NEXT:    [[MUL18:%.*]] = mul nsw i64 [[DIV17]], 1
+// CHECK-NEXT:    [[ADD_PTR19:%.*]] = getelementptr inbounds i32, ptr [[TMP10]], i64 [[MUL18]]
+// CHECK-NEXT:    store ptr [[ADD_PTR19]], ptr [[Q]], align 8
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define dso_local void @test_pointer_step(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[BUFFER:%.*]] = alloca [30 x i8], align 16
+// CHECK-NEXT:    [[PTR:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_PTR:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTTILE_0_IV_PTR:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [30 x i8], ptr [[BUFFER]], i64 0, i64 0
+// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[PTR]], align 8
+// CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [30 x i8], ptr [[BUFFER]], i64 0, i64 0
+// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [30 x i8], ptr [[BUFFER]], i64 0, i64 0
+// CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[ARRAYDECAY3]], i64 30
+// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], align 8
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
+// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP0]] to i64
+// CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP1]] to i64
+// CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
+// CHECK-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_SUB]], 1
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 2
+// CHECK-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 2
+// CHECK-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
+// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    store i64 0, ptr [[DOTFLOOR_0_IV_PTR]], align 8
+// CHECK-NEXT:    br label %[[FOR_COND:.*]]
+// CHECK:       [[FOR_COND]]:
+// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], align 8
+// CHECK-NEXT:    [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP3]], 1
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[TMP2]], [[ADD6]]
+// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END18:.*]]
+// CHECK:       [[FOR_BODY]]:
+// CHECK-NEXT:    [[TMP4:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], align 8
+// CHECK-NEXT:    store i64 [[TMP4]], ptr [[DOTTILE_0_IV_PTR]], align 8
+// CHECK-NEXT:    br label %[[FOR_COND7:.*]]
+// CHECK:       [[FOR_COND7]]:
+// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTTILE_0_IV_PTR]], align 8
+// CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[ADD8:%.*]] = add nsw i64 [[TMP6]], 1
+// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], align 8
+// CHECK-NEXT:    [[ADD9:%.*]] = add nsw i64 [[TMP7]], 4
+// CHECK-NEXT:    [[CMP10:%.*]] = icmp slt i64 [[ADD8]], [[ADD9]]
+// CHECK-NEXT:    br i1 [[CMP10]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
+// CHECK:       [[COND_TRUE]]:
+// CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[ADD11:%.*]] = add nsw i64 [[TMP8]], 1
+// CHECK-NEXT:    br label %[[COND_END:.*]]
+// CHECK:       [[COND_FALSE]]:
+// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], align 8
+// CHECK-NEXT:    [[ADD12:%.*]] = add nsw i64 [[TMP9]], 4
+// CHECK-NEXT:    br label %[[COND_END]]
+// CHECK:       [[COND_END]]:
+// CHECK-NEXT:    [[COND:%.*]] = phi i64 [ [[ADD11]], %[[COND_TRUE]] ], [ [[ADD12]], %[[COND_FALSE]] ]
+// CHECK-NEXT:    [[CMP13:%.*]] = icmp slt i64 [[TMP5]], [[COND]]
+// CHECK-NEXT:    br i1 [[CMP13]], label %[[FOR_BODY14:.*]], label %[[FOR_END:.*]]
+// CHECK:       [[FOR_BODY14]]:
+// CHECK-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTTILE_0_IV_PTR]], align 8
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP11]], 2
+// CHECK-NEXT:    [[ADD_PTR15:%.*]] = getelementptr inbounds i8, ptr [[TMP10]], i64 [[MUL]]
+// CHECK-NEXT:    store ptr [[ADD_PTR15]], ptr [[PTR]], align 8
+// CHECK-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[PTR]], align 8
+// CHECK-NEXT:    store i8 120, ptr [[TMP12]], align 1
+// CHECK-NEXT:    br label %[[FOR_INC:.*]]
+// CHECK:       [[FOR_INC]]:
+// CHECK-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTTILE_0_IV_PTR]], align 8
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP13]], 1
+// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTTILE_0_IV_PTR]], align 8
+// CHECK-NEXT:    br label %[[FOR_COND7]], !llvm.loop [[LOOP30:![0-9]+]]
+// CHECK:       [[FOR_END]]:
+// CHECK-NEXT:    br label %[[FOR_INC16:.*]]
+// CHECK:       [[FOR_INC16]]:
+// CHECK-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], align 8
+// CHECK-NEXT:    [[ADD17:%.*]] = add nsw i64 [[TMP14]], 4
+// CHECK-NEXT:    store i64 [[ADD17]], ptr [[DOTFLOOR_0_IV_PTR]], align 8
+// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP31:![0-9]+]]
+// CHECK:       [[FOR_END18]]:
+// CHECK-NEXT:    [[TMP15:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[TMP16:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
+// CHECK-NEXT:    [[TMP17:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[SUB_PTR_LHS_CAST19:%.*]] = ptrtoaddr ptr [[TMP16]] to i64
+// CHECK-NEXT:    [[SUB_PTR_RHS_CAST20:%.*]] = ptrtoaddr ptr [[TMP17]] to i64
+// CHECK-NEXT:    [[SUB_PTR_SUB21:%.*]] = sub i64 [[SUB_PTR_LHS_CAST19]], [[SUB_PTR_RHS_CAST20]]
+// CHECK-NEXT:    [[SUB22:%.*]] = sub nsw i64 [[SUB_PTR_SUB21]], 1
+// CHECK-NEXT:    [[ADD23:%.*]] = add nsw i64 [[SUB22]], 2
+// CHECK-NEXT:    [[DIV24:%.*]] = sdiv i64 [[ADD23]], 2
+// CHECK-NEXT:    [[MUL25:%.*]] = mul nsw i64 [[DIV24]], 2
+// CHECK-NEXT:    [[ADD_PTR26:%.*]] = getelementptr inbounds i8, ptr [[TMP15]], i64 [[MUL25]]
+// CHECK-NEXT:    store ptr [[ADD_PTR26]], ptr [[PTR]], align 8
+// CHECK-NEXT:    ret void
+//
+//
+// CHECK-LABEL: define dso_local void @test_pointer_fuse(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[ARR1:%.*]] = alloca [10 x i32], align 16
+// CHECK-NEXT:    [[ARR2:%.*]] = alloca [15 x i32], align 16
+// CHECK-NEXT:    [[P:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[Q:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTOMP_LB0:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTOMP_ST0:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTOMP_NI0:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTOMP_IV0:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_8:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_10:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_13:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTOMP_LB1:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTOMP_ST1:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTOMP_NI1:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTOMP_IV1:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTOMP_TEMP_1:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTOMP_FUSE_MAX:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[DOTOMP_FUSE_INDEX:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARR1]], i64 0, i64 0
+// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[P]], align 8
+// CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARR1]], i64 0, i64 0
+// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARR1]], i64 0, i64 0
+// CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY3]], i64 10
+// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], align 8
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
+// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP0]] to i64
+// CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP1]] to i64
+// CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
+// CHECK-NEXT:    [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 4
+// CHECK-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
+// CHECK-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
+// CHECK-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
+// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    store i64 0, ptr [[DOTOMP_LB0]], align 8
+// CHECK-NEXT:    store i64 1, ptr [[DOTOMP_ST0]], align 8
+// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP2]], 1
+// CHECK-NEXT:    store i64 [[ADD6]], ptr [[DOTOMP_NI0]], align 8
+// CHECK-NEXT:    [[ARRAYDECAY7:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR2]], i64 0, i64 0
+// CHECK-NEXT:    store ptr [[ARRAYDECAY7]], ptr [[Q]], align 8
+// CHECK-NEXT:    [[ARRAYDECAY9:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR2]], i64 0, i64 0
+// CHECK-NEXT:    store ptr [[ARRAYDECAY9]], ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK-NEXT:    [[ARRAYDECAY11:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR2]], i64 0, i64 0
+// CHECK-NEXT:    [[ADD_PTR12:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY11]], i64 15
+// CHECK-NEXT:    store ptr [[ADD_PTR12]], ptr [[DOTCAPTURE_EXPR_10]], align 8
+// CHECK-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_10]], align 8
+// CHECK-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK-NEXT:    [[SUB_PTR_LHS_CAST14:%.*]] = ptrtoaddr ptr [[TMP3]] to i64
+// CHECK-NEXT:    [[SUB_PTR_RHS_CAST15:%.*]] = ptrtoaddr ptr [[TMP4]] to i64
+// CHECK-NEXT:    [[SUB_PTR_SUB16:%.*]] = sub i64 [[SUB_PTR_LHS_CAST14]], [[SUB_PTR_RHS_CAST15]]
+// CHECK-NEXT:    [[SUB_PTR_DIV17:%.*]] = sdiv exact i64 [[SUB_PTR_SUB16]], 4
+// CHECK-NEXT:    [[SUB18:%.*]] = sub nsw i64 [[SUB_PTR_DIV17]], 1
+// CHECK-NEXT:    [[ADD19:%.*]] = add nsw i64 [[SUB18]], 1
+// CHECK-NEXT:    [[DIV20:%.*]] = sdiv i64 [[ADD19]], 1
+// CHECK-NEXT:    [[SUB21:%.*]] = sub nsw i64 [[DIV20]], 1
+// CHECK-NEXT:    store i64 [[SUB21]], ptr [[DOTCAPTURE_EXPR_13]], align 8
+// CHECK-NEXT:    store i64 0, ptr [[DOTOMP_LB1]], align 8
+// CHECK-NEXT:    store i64 1, ptr [[DOTOMP_ST1]], align 8
+// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_13]], align 8
+// CHECK-NEXT:    [[ADD22:%.*]] = add nsw i64 [[TMP5]], 1
+// CHECK-NEXT:    store i64 [[ADD22]], ptr [[DOTOMP_NI1]], align 8
+// CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTOMP_NI0]], align 8
+// CHECK-NEXT:    store i64 [[TMP6]], ptr [[DOTOMP_TEMP_1]], align 8
+// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTOMP_TEMP_1]], align 8
+// CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTOMP_NI1]], align 8
+// CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i64 [[TMP7]], [[TMP8]]
+// CHECK-NEXT:    br i1 [[CMP]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
+// CHECK:       [[COND_TRUE]]:
+// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTOMP_TEMP_1]], align 8
+// CHECK-NEXT:    br label %[[COND_END:.*]]
+// CHECK:       [[COND_FALSE]]:
+// CHECK-NEXT:    [[TMP10:%.*]] = load i64, ptr [[DOTOMP_NI1]], align 8
+// CHECK-NEXT:    br label %[[COND_END]]
+// CHECK:       [[COND_END]]:
+// CHECK-NEXT:    [[COND:%.*]] = phi i64 [ [[TMP9]], %[[COND_TRUE]] ], [ [[TMP10]], %[[COND_FALSE]] ]
+// CHECK-NEXT:    store i64 [[COND]], ptr [[DOTOMP_FUSE_MAX]], align 8
+// CHECK-NEXT:    store i64 0, ptr [[DOTOMP_FUSE_INDEX]], align 8
+// CHECK-NEXT:    br label %[[FOR_COND:.*]]
+// CHECK:       [[FOR_COND]]:
+// CHECK-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], align 8
+// CHECK-NEXT:    [[TMP12:%.*]] = load i64, ptr [[DOTOMP_FUSE_MAX]], align 8
+// CHECK-NEXT:    [[CMP23:%.*]] = icmp slt i64 [[TMP11]], [[TMP12]]
+// CHECK-NEXT:    br i1 [[CMP23]], label %[[FOR_BODY:.*]], label %[[FOR_END:.*]]
+// CHECK:       [[FOR_BODY]]:
+// CHECK-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], align 8
+// CHECK-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTOMP_NI0]], align 8
+// CHECK-NEXT:    [[CMP24:%.*]] = icmp slt i64 [[TMP13]], [[TMP14]]
+// CHECK-NEXT:    br i1 [[CMP24]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
+// CHECK:       [[IF_THEN]]:
+// CHECK-NEXT:    [[TMP15:%.*]] = load i64, ptr [[DOTOMP_LB0]], align 8
+// CHECK-NEXT:    [[TMP16:%.*]] = load i64, ptr [[DOTOMP_ST0]], align 8
+// CHECK-NEXT:    [[TMP17:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], align 8
+// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP16]], [[TMP17]]
+// CHECK-NEXT:    [[ADD25:%.*]] = add nsw i64 [[TMP15]], [[MUL]]
+// CHECK-NEXT:    store i64 [[ADD25]], ptr [[DOTOMP_IV0]], align 8
+// CHECK-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[TMP19:%.*]] = load i64, ptr [[DOTOMP_IV0]], align 8
+// CHECK-NEXT:    [[MUL26:%.*]] = mul nsw i64 [[TMP19]], 1
+// CHECK-NEXT:    [[ADD_PTR27:%.*]] = getelementptr inbounds i32, ptr [[TMP18]], i64 [[MUL26]]
+// CHECK-NEXT:    store ptr [[ADD_PTR27]], ptr [[P]], align 8
+// CHECK-NEXT:    [[TMP20:%.*]] = load ptr, ptr [[P]], align 8
+// CHECK-NEXT:    store i32 0, ptr [[TMP20]], align 4
+// CHECK-NEXT:    br label %[[IF_END]]
+// CHECK:       [[IF_END]]:
+// CHECK-NEXT:    [[TMP21:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], align 8
+// CHECK-NEXT:    [[TMP22:%.*]] = load i64, ptr [[DOTOMP_NI1]], align 8
+// CHECK-NEXT:    [[CMP28:%.*]] = icmp slt i64 [[TMP21]], [[TMP22]]
+// CHECK-NEXT:    br i1 [[CMP28]], label %[[IF_THEN29:.*]], label %[[IF_END34:.*]]
+// CHECK:       [[IF_THEN29]]:
+// CHECK-NEXT:    [[TMP23:%.*]] = load i64, ptr [[DOTOMP_LB1]], align 8
+// CHECK-NEXT:    [[TMP24:%.*]] = load i64, ptr [[DOTOMP_ST1]], align 8
+// CHECK-NEXT:    [[TMP25:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], align 8
+// CHECK-NEXT:    [[MUL30:%.*]] = mul nsw i64 [[TMP24]], [[TMP25]]
+// CHECK-NEXT:    [[ADD31:%.*]] = add nsw i64 [[TMP23]], [[MUL30]]
+// CHECK-NEXT:    store i64 [[ADD31]], ptr [[DOTOMP_IV1]], align 8
+// CHECK-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK-NEXT:    [[TMP27:%.*]] = load i64, ptr [[DOTOMP_IV1]], align 8
+// CHECK-NEXT:    [[MUL32:%.*]] = mul nsw i64 [[TMP27]], 1
+// CHECK-NEXT:    [[ADD_PTR33:%.*]] = getelementptr inbounds i32, ptr [[TMP26]], i64 [[MUL32]]
+// CHECK-NEXT:    store ptr [[ADD_PTR33]], ptr [[Q]], align 8
+// CHECK-NEXT:    [[TMP28:%.*]] = load ptr, ptr [[Q]], align 8
+// CHECK-NEXT:    store i32 1, ptr [[TMP28]], align 4
+// CHECK-NEXT:    br label %[[IF_END34]]
+// CHECK:       [[IF_END34]]:
+// CHECK-NEXT:    br label %[[FOR_INC:.*]]
+// CHECK:       [[FOR_INC]]:
+// CHECK-NEXT:    [[TMP29:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], align 8
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP29]], 1
+// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTOMP_FUSE_INDEX]], align 8
+// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP32:![0-9]+]]
+// CHECK:       [[FOR_END]]:
+// CHECK-NEXT:    [[TMP30:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[TMP31:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
+// CHECK-NEXT:    [[TMP32:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[SUB_PTR_LHS_CAST35:%.*]] = ptrtoaddr ptr [[TMP31]] to i64
+// CHECK-NEXT:    [[SUB_PTR_RHS_CAST36:%.*]] = ptrtoaddr ptr [[TMP32]] to i64
+// CHECK-NEXT:    [[SUB_PTR_SUB37:%.*]] = sub i64 [[SUB_PTR_LHS_CAST35]], [[SUB_PTR_RHS_CAST36]]
+// CHECK-NEXT:    [[SUB_PTR_DIV38:%.*]] = sdiv exact i64 [[SUB_PTR_SUB37]], 4
+// CHECK-NEXT:    [[SUB39:%.*]] = sub nsw i64 [[SUB_PTR_DIV38]], 1
+// CHECK-NEXT:    [[ADD40:%.*]] = add nsw i64 [[SUB39]], 1
+// CHECK-NEXT:    [[DIV41:%.*]] = sdiv i64 [[ADD40]], 1
+// CHECK-NEXT:    [[MUL42:%.*]] = mul nsw i64 [[DIV41]], 1
+// CHECK-NEXT:    [[ADD_PTR43:%.*]] = getelementptr inbounds i32, ptr [[TMP30]], i64 [[MUL42]]
+// CHECK-NEXT:    store ptr [[ADD_PTR43]], ptr [[P]], align 8
+// CHECK-NEXT:    [[TMP33:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK-NEXT:    [[TMP34:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_10]], align 8
+// CHECK-NEXT:    [[TMP35:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK-NEXT:    [[SUB_PTR_LHS_CAST44:%.*]] = ptrtoaddr ptr [[TMP34]] to i64
+// CHECK-NEXT:    [[SUB_PTR_RHS_CAST45:%.*]] = ptrtoaddr ptr [[TMP35]] to i64
+// CHECK-NEXT:    [[SUB_PTR_SUB46:%.*]] = sub i64 [[SUB_PTR_LHS_CAST44]], [[SUB_PTR_RHS_CAST45]]
+// CHECK-NEXT:    [[SUB_PTR_DIV47:%.*]] = sdiv exact i64 [[SUB_PTR_SUB46]], 4
+// CHECK-NEXT:    [[SUB48:%.*]] = sub nsw i64 [[SUB_PTR_DIV47]], 1
+// CHECK-NEXT:    [[ADD49:%.*]] = add nsw i64 [[SUB48]], 1
+// CHECK-NEXT:    [[DIV50:%.*]] = sdiv i64 [[ADD49]], 1
+// CHECK-NEXT:    [[MUL51:%.*]] = mul nsw i64 [[DIV50]], 1
+// CHECK-NEXT:    [[ADD_PTR52:%.*]] = getelementptr inbounds i32, ptr [[TMP33]], i64 [[MUL51]]
+// CHECK-NEXT:    store ptr [[ADD_PTR52]], ptr [[Q]], align 8
+// CHECK-NEXT:    ret void
+//
+//.
+// CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[META3:![0-9]+]]}
+// CHECK: [[META3]] = !{!"llvm.loop.mustprogress"}
+// CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META3]]}
+// CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META3]]}
+// CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META3]]}
+// CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META3]]}
+// CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META3]]}
+// CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META3]]}
+// CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META3]]}
+// CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[META3]]}
+// CHECK: [[LOOP12]] = distinct !{[[LOOP12]], [[META3]]}
+// CHECK: [[LOOP13]] = distinct !{[[LOOP13]], [[META3]]}
+// CHECK: [[LOOP14]] = distinct !{[[LOOP14]], [[META3]]}
+// CHECK: [[LOOP15]] = distinct !{[[LOOP15]], [[META3]]}
+// CHECK: [[LOOP16]] = distinct !{[[LOOP16]], [[META3]]}
+// CHECK: [[LOOP17]] = distinct !{[[LOOP17]], [[META3]]}
+// CHECK: [[META18]] = !{}
+// CHECK: [[META19]] = !{i64 4}
+// CHECK: [[LOOP22]] = distinct !{[[LOOP22]], [[META3]]}
+// CHECK: [[LOOP23]] = distinct !{[[LOOP23]], [[META3]]}
+// CHECK: [[LOOP24]] = distinct !{[[LOOP24]], [[META3]]}
+// CHECK: [[LOOP25]] = distinct !{[[LOOP25]], [[META3]]}
+// CHECK: [[LOOP26]] = distinct !{[[LOOP26]], [[META3]]}
+// CHECK: [[LOOP27]] = distinct !{[[LOOP27]], [[META3]]}
+// CHECK: [[LOOP28]] = distinct !{[[LOOP28]], [[META3]]}
+// CHECK: [[LOOP29]] = distinct !{[[LOOP29]], [[META3]]}
+// CHECK: [[LOOP30]] = distinct !{[[LOOP30]], [[META3]]}
+// CHECK: [[LOOP31]] = distinct !{[[LOOP31]], [[META3]]}
+// CHECK: [[LOOP32]] = distinct !{[[LOOP32]], [[META3]]}
+//.

>From 7039e71497cdc23252016cca70c518160144eb1b Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Fri, 21 Aug 2026 09:26:38 -0700
Subject: [PATCH 07/11] Make the generated IR platform independent

---
 clang/test/OpenMP/loop_transform_iv.c | 936 +++++++++++++-------------
 1 file changed, 468 insertions(+), 468 deletions(-)

diff --git a/clang/test/OpenMP/loop_transform_iv.c b/clang/test/OpenMP/loop_transform_iv.c
index 5da3650380f2e..4eeb50a7fba5a 100644
--- a/clang/test/OpenMP/loop_transform_iv.c
+++ b/clang/test/OpenMP/loop_transform_iv.c
@@ -1,4 +1,4 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ --version 5
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" "align [0-9]+" --prefix-filecheck-ir-name _ --version 5
 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -emit-llvm %s -o - | FileCheck %s
 // expected-no-diagnostics
 
@@ -157,30 +157,30 @@ void test_pointer_fuse(void) {
 // CHECK-LABEL: define dso_local void @test_tile(
 // CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    store i32 1, ptr [[I]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    store i32 1, ptr [[I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND:.*]]
 // CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
 // CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END9:.*]]
 // CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
-// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND1:.*]]
 // CHECK:       [[FOR_COND1]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 2
 // CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 10, [[ADD]]
 // CHECK-NEXT:    br i1 [[CMP2]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
 // CHECK:       [[COND_TRUE]]:
 // CHECK-NEXT:    br label %[[COND_END:.*]]
 // CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP4]], 2
 // CHECK-NEXT:    br label %[[COND_END]]
 // CHECK:       [[COND_END]]:
@@ -188,55 +188,55 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP2]], [[COND]]
 // CHECK-NEXT:    br i1 [[CMP4]], label %[[FOR_BODY5:.*]], label %[[FOR_END:.*]]
 // CHECK:       [[FOR_BODY5]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP5]], 1
 // CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 1, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], align 4
+// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_INC:.*]]
 // CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP2:![0-9]+]]
 // CHECK:       [[FOR_END]]:
 // CHECK-NEXT:    br label %[[FOR_INC7:.*]]
 // CHECK:       [[FOR_INC7]]:
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP7]], 2
-// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
 // CHECK:       [[FOR_END9]]:
-// CHECK-NEXT:    store i32 11, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 11, ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    ret void
 //
 //
 // CHECK-LABEL: define dso_local void @test_stripe(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTSTRIPE_0_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTSTRIPE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND:.*]]
 // CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
 // CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END9:.*]]
 // CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
-// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND1:.*]]
 // CHECK:       [[FOR_COND1]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 3
 // CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 10, [[ADD]]
 // CHECK-NEXT:    br i1 [[CMP2]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
 // CHECK:       [[COND_TRUE]]:
 // CHECK-NEXT:    br label %[[COND_END:.*]]
 // CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP4]], 3
 // CHECK-NEXT:    br label %[[COND_END]]
 // CHECK:       [[COND_END]]:
@@ -244,66 +244,66 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP2]], [[COND]]
 // CHECK-NEXT:    br i1 [[CMP4]], label %[[FOR_BODY5:.*]], label %[[FOR_END:.*]]
 // CHECK:       [[FOR_BODY5]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP5]], 1
 // CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], align 4
+// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_INC:.*]]
 // CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP5:![0-9]+]]
 // CHECK:       [[FOR_END]]:
 // CHECK-NEXT:    br label %[[FOR_INC7:.*]]
 // CHECK:       [[FOR_INC7]]:
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP7]], 3
-// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
 // CHECK:       [[FOR_END9]]:
-// CHECK-NEXT:    store i32 10, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 10, ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    ret void
 //
 //
 // CHECK-LABEL: define dso_local void @test_tile_nested(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[J:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTFLOOR_1_IV_J:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTTILE_1_IV_J:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[J]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[J:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTFLOOR_1_IV_J:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTTILE_1_IV_J:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[J]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND:.*]]
 // CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
 // CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END30:.*]]
 // CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_1_IV_J]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_1_IV_J]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND1:.*]]
 // CHECK:       [[FOR_COND1]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[TMP1]], 5
 // CHECK-NEXT:    br i1 [[CMP2]], label %[[FOR_BODY3:.*]], label %[[FOR_END27:.*]]
 // CHECK:       [[FOR_BODY3]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
-// CHECK-NEXT:    store i32 [[TMP2]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 [[TMP2]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND4:.*]]
 // CHECK:       [[FOR_COND4]]:
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP4]], 2
 // CHECK-NEXT:    [[CMP5:%.*]] = icmp slt i32 10, [[ADD]]
 // CHECK-NEXT:    br i1 [[CMP5]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
 // CHECK:       [[COND_TRUE]]:
 // CHECK-NEXT:    br label %[[COND_END:.*]]
 // CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP5]], 2
 // CHECK-NEXT:    br label %[[COND_END]]
 // CHECK:       [[COND_END]]:
@@ -311,23 +311,23 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[CMP7:%.*]] = icmp slt i32 [[TMP3]], [[COND]]
 // CHECK-NEXT:    br i1 [[CMP7]], label %[[FOR_BODY8:.*]], label %[[FOR_END24:.*]]
 // CHECK:       [[FOR_BODY8]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP6]], 1
 // CHECK-NEXT:    [[ADD9:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD9]], ptr [[I]], align 4
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], align 4
-// CHECK-NEXT:    store i32 [[TMP7]], ptr [[DOTTILE_1_IV_J]], align 4
+// CHECK-NEXT:    store i32 [[ADD9]], ptr [[I]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 [[TMP7]], ptr [[DOTTILE_1_IV_J]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND10:.*]]
 // CHECK:       [[FOR_COND10]]:
-// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTTILE_1_IV_J]], align 4
-// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], align 4
+// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTTILE_1_IV_J]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD11:%.*]] = add nsw i32 [[TMP9]], 3
 // CHECK-NEXT:    [[CMP12:%.*]] = icmp slt i32 5, [[ADD11]]
 // CHECK-NEXT:    br i1 [[CMP12]], label %[[COND_TRUE13:.*]], label %[[COND_FALSE14:.*]]
 // CHECK:       [[COND_TRUE13]]:
 // CHECK-NEXT:    br label %[[COND_END16:.*]]
 // CHECK:       [[COND_FALSE14]]:
-// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], align 4
+// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD15:%.*]] = add nsw i32 [[TMP10]], 3
 // CHECK-NEXT:    br label %[[COND_END16]]
 // CHECK:       [[COND_END16]]:
@@ -335,70 +335,70 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[CMP18:%.*]] = icmp slt i32 [[TMP8]], [[COND17]]
 // CHECK-NEXT:    br i1 [[CMP18]], label %[[FOR_BODY19:.*]], label %[[FOR_END:.*]]
 // CHECK:       [[FOR_BODY19]]:
-// CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTTILE_1_IV_J]], align 4
+// CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTTILE_1_IV_J]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL20:%.*]] = mul nsw i32 [[TMP11]], 1
 // CHECK-NEXT:    [[ADD21:%.*]] = add nsw i32 0, [[MUL20]]
-// CHECK-NEXT:    store i32 [[ADD21]], ptr [[J]], align 4
+// CHECK-NEXT:    store i32 [[ADD21]], ptr [[J]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_INC:.*]]
 // CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTTILE_1_IV_J]], align 4
+// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTTILE_1_IV_J]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP12]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_1_IV_J]], align 4
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_1_IV_J]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND10]], !llvm.loop [[LOOP7:![0-9]+]]
 // CHECK:       [[FOR_END]]:
 // CHECK-NEXT:    br label %[[FOR_INC22:.*]]
 // CHECK:       [[FOR_INC22]]:
-// CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC23:%.*]] = add nsw i32 [[TMP13]], 1
-// CHECK-NEXT:    store i32 [[INC23]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[INC23]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND4]], !llvm.loop [[LOOP8:![0-9]+]]
 // CHECK:       [[FOR_END24]]:
 // CHECK-NEXT:    br label %[[FOR_INC25:.*]]
 // CHECK:       [[FOR_INC25]]:
-// CHECK-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], align 4
+// CHECK-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD26:%.*]] = add nsw i32 [[TMP14]], 3
-// CHECK-NEXT:    store i32 [[ADD26]], ptr [[DOTFLOOR_1_IV_J]], align 4
+// CHECK-NEXT:    store i32 [[ADD26]], ptr [[DOTFLOOR_1_IV_J]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP9:![0-9]+]]
 // CHECK:       [[FOR_END27]]:
 // CHECK-NEXT:    br label %[[FOR_INC28:.*]]
 // CHECK:       [[FOR_INC28]]:
-// CHECK-NEXT:    [[TMP15:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP15:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD29:%.*]] = add nsw i32 [[TMP15]], 2
-// CHECK-NEXT:    store i32 [[ADD29]], ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[ADD29]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP10:![0-9]+]]
 // CHECK:       [[FOR_END30]]:
-// CHECK-NEXT:    store i32 10, ptr [[I]], align 4
-// CHECK-NEXT:    store i32 5, ptr [[J]], align 4
+// CHECK-NEXT:    store i32 10, ptr [[I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 5, ptr [[J]], {{align [0-9]+}}
 // CHECK-NEXT:    ret void
 //
 //
 // CHECK-LABEL: define dso_local void @test_tile_stride(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    store i32 5, ptr [[I]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    store i32 5, ptr [[I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND:.*]]
 // CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 6
 // CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END9:.*]]
 // CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
-// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND1:.*]]
 // CHECK:       [[FOR_COND1]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 4
 // CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 6, [[ADD]]
 // CHECK-NEXT:    br i1 [[CMP2]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
 // CHECK:       [[COND_TRUE]]:
 // CHECK-NEXT:    br label %[[COND_END:.*]]
 // CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP4]], 4
 // CHECK-NEXT:    br label %[[COND_END]]
 // CHECK:       [[COND_END]]:
@@ -406,72 +406,72 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP2]], [[COND]]
 // CHECK-NEXT:    br i1 [[CMP4]], label %[[FOR_BODY5:.*]], label %[[FOR_END:.*]]
 // CHECK:       [[FOR_BODY5]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP5]], 2
 // CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 5, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], align 4
+// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_INC:.*]]
 // CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP11:![0-9]+]]
 // CHECK:       [[FOR_END]]:
 // CHECK-NEXT:    br label %[[FOR_INC7:.*]]
 // CHECK:       [[FOR_INC7]]:
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP7]], 4
-// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP12:![0-9]+]]
 // CHECK:       [[FOR_END9]]:
-// CHECK-NEXT:    store i32 17, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 17, ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    ret void
 //
 //
 // CHECK-LABEL: define dso_local void @test_tile_variable_bound(
 // CHECK-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[N_ADDR:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    store i32 [[N]], ptr [[N_ADDR]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[N_ADDR]], align 4
-// CHECK-NEXT:    store i32 [[TMP0]], ptr [[DOTCAPTURE_EXPR_]], align 4
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK-NEXT:    [[N_ADDR:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    store i32 [[N]], ptr [[N_ADDR]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[I]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[N_ADDR]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 [[TMP0]], ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
 // CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[TMP1]], 0
 // CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[SUB]], 1
 // CHECK-NEXT:    [[SUB2:%.*]] = sub nsw i32 [[DIV]], 1
-// CHECK-NEXT:    store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND:.*]]
 // CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 1
 // CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP2]], [[ADD]]
 // CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END14:.*]]
 // CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
-// CHECK-NEXT:    store i32 [[TMP4]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 [[TMP4]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND3:.*]]
 // CHECK:       [[FOR_COND3]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD4:%.*]] = add nsw i32 [[TMP6]], 1
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD5:%.*]] = add nsw i32 [[TMP7]], 3
 // CHECK-NEXT:    [[CMP6:%.*]] = icmp slt i32 [[ADD4]], [[ADD5]]
 // CHECK-NEXT:    br i1 [[CMP6]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
 // CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
+// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD7:%.*]] = add nsw i32 [[TMP8]], 1
 // CHECK-NEXT:    br label %[[COND_END:.*]]
 // CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP9]], 3
 // CHECK-NEXT:    br label %[[COND_END]]
 // CHECK:       [[COND_END]]:
@@ -479,163 +479,163 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[CMP9:%.*]] = icmp slt i32 [[TMP5]], [[COND]]
 // CHECK-NEXT:    br i1 [[CMP9]], label %[[FOR_BODY10:.*]], label %[[FOR_END:.*]]
 // CHECK:       [[FOR_BODY10]]:
-// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1
 // CHECK-NEXT:    [[ADD11:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD11]], ptr [[I]], align 4
+// CHECK-NEXT:    store i32 [[ADD11]], ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_INC:.*]]
 // CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP11]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND3]], !llvm.loop [[LOOP13:![0-9]+]]
 // CHECK:       [[FOR_END]]:
 // CHECK-NEXT:    br label %[[FOR_INC12:.*]]
 // CHECK:       [[FOR_INC12]]:
-// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD13:%.*]] = add nsw i32 [[TMP12]], 3
-// CHECK-NEXT:    store i32 [[ADD13]], ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[ADD13]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP14:![0-9]+]]
 // CHECK:       [[FOR_END14]]:
-// CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
 // CHECK-NEXT:    [[SUB15:%.*]] = sub nsw i32 [[TMP13]], 0
 // CHECK-NEXT:    [[DIV16:%.*]] = sdiv i32 [[SUB15]], 1
 // CHECK-NEXT:    [[MUL17:%.*]] = mul nsw i32 [[DIV16]], 1
 // CHECK-NEXT:    [[ADD18:%.*]] = add nsw i32 0, [[MUL17]]
-// CHECK-NEXT:    store i32 [[ADD18]], ptr [[I]], align 4
+// CHECK-NEXT:    store i32 [[ADD18]], ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    ret void
 //
 //
 // CHECK-LABEL: define dso_local void @test_reverse(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND:.*]]
 // CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
 // CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END:.*]]
 // CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 9, [[TMP1]]
-// CHECK-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], align 4
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], 1
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD]], ptr [[I]], align 4
+// CHECK-NEXT:    store i32 [[ADD]], ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_INC:.*]]
 // CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP3]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]]
 // CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    store i32 10, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 10, ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    ret void
 //
 //
 // CHECK-LABEL: define dso_local void @test_interchange(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[J:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTPERMUTED_0_IV_J:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTPERMUTED_1_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[J]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[DOTPERMUTED_0_IV_J]], align 4
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[J:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTPERMUTED_0_IV_J:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTPERMUTED_1_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[J]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[DOTPERMUTED_0_IV_J]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND:.*]]
 // CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 5
 // CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END8:.*]]
 // CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP1]], 1
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD]], ptr [[J]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[DOTPERMUTED_1_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[ADD]], ptr [[J]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[DOTPERMUTED_1_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND1:.*]]
 // CHECK:       [[FOR_COND1]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[TMP2]], 10
 // CHECK-NEXT:    br i1 [[CMP2]], label %[[FOR_BODY3:.*]], label %[[FOR_END:.*]]
 // CHECK:       [[FOR_BODY3]]:
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL4:%.*]] = mul nsw i32 [[TMP3]], 1
 // CHECK-NEXT:    [[ADD5:%.*]] = add nsw i32 0, [[MUL4]]
-// CHECK-NEXT:    store i32 [[ADD5]], ptr [[I]], align 4
+// CHECK-NEXT:    store i32 [[ADD5]], ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_INC:.*]]
 // CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], align 4
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP4]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTPERMUTED_1_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTPERMUTED_1_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP16:![0-9]+]]
 // CHECK:       [[FOR_END]]:
 // CHECK-NEXT:    br label %[[FOR_INC6:.*]]
 // CHECK:       [[FOR_INC6]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], align 4
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC7:%.*]] = add nsw i32 [[TMP5]], 1
-// CHECK-NEXT:    store i32 [[INC7]], ptr [[DOTPERMUTED_0_IV_J]], align 4
+// CHECK-NEXT:    store i32 [[INC7]], ptr [[DOTPERMUTED_0_IV_J]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP17:![0-9]+]]
 // CHECK:       [[FOR_END8]]:
-// CHECK-NEXT:    store i32 10, ptr [[I]], align 4
-// CHECK-NEXT:    store i32 5, ptr [[J]], align 4
+// CHECK-NEXT:    store i32 10, ptr [[I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 5, ptr [[J]], {{align [0-9]+}}
 // CHECK-NEXT:    ret void
 //
 //
 // CHECK-LABEL: define dso_local void @test_for_workshare(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[TMP:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[I1:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[I1:%.*]] = alloca i32, {{align [0-9]+}}
 // CHECK-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:[0-9]+]])
-// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
-// CHECK-NEXT:    store i32 2, ptr [[DOTOMP_UB]], align 4
-// CHECK-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_LB]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 2, ptr [[DOTOMP_UB]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], {{align [0-9]+}}
 // CHECK-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 2
 // CHECK-NEXT:    br i1 [[CMP]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
 // CHECK:       [[COND_TRUE]]:
 // CHECK-NEXT:    br label %[[COND_END:.*]]
 // CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[COND_END]]
 // CHECK:       [[COND_END]]:
 // CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 2, %[[COND_TRUE]] ], [ [[TMP2]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
-// CHECK-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND:.*]]
 // CHECK:       [[OMP_INNER_FOR_COND]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]]
 // CHECK-NEXT:    br i1 [[CMP2]], label %[[OMP_INNER_FOR_BODY:.*]], label %[[OMP_INNER_FOR_END:.*]]
 // CHECK:       [[OMP_INNER_FOR_BODY]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP6]], 2
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 5, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD]], ptr [[I1]], align 4
+// CHECK-NEXT:    store i32 [[ADD]], ptr [[I1]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[OMP_BODY_CONTINUE:.*]]
 // CHECK:       [[OMP_BODY_CONTINUE]]:
 // CHECK-NEXT:    br label %[[OMP_INNER_FOR_INC:.*]]
 // CHECK:       [[OMP_INNER_FOR_INC]]:
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP7]], 1
-// CHECK-NEXT:    store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    store i32 [[ADD3]], ptr [[DOTOMP_IV]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND]]
 // CHECK:       [[OMP_INNER_FOR_END]]:
 // CHECK-NEXT:    br label %[[OMP_LOOP_EXIT:.*]]
@@ -648,7 +648,7 @@ void test_pointer_fuse(void) {
 // CHECK-LABEL: define dso_local void @test_for_lastprivate(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
 // CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 1, ptr @test_for_lastprivate.omp_outlined, ptr [[I]])
 // CHECK-NEXT:    ret void
 //
@@ -656,71 +656,71 @@ void test_pointer_fuse(void) {
 // CHECK-LABEL: define internal void @test_for_lastprivate.omp_outlined(
 // CHECK-SAME: ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[I:%.*]]) #[[ATTR3:[0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[I_ADDR:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[TMP:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[I1:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[I2:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
-// CHECK-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
-// CHECK-NEXT:    store ptr [[I]], ptr [[I_ADDR]], align 8
-// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[I_ADDR]], align 8, !nonnull [[META18:![0-9]+]], !align [[META19:![0-9]+]]
-// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
-// CHECK-NEXT:    store i32 2, ptr [[DOTOMP_UB]], align 4
-// CHECK-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
-// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 4
+// CHECK-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[I_ADDR:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[I1:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[I2:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], {{align [0-9]+}}
+// CHECK-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], {{align [0-9]+}}
+// CHECK-NEXT:    store ptr [[I]], ptr [[I_ADDR]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[I_ADDR]], {{align [0-9]+}}, !nonnull [[META18:![0-9]+]], !align [[META19:![0-9]+]]
+// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_LB]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 2, ptr [[DOTOMP_UB]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[TMP1]], {{align [0-9]+}}
 // CHECK-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP2]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP3]], 2
 // CHECK-NEXT:    br i1 [[CMP]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
 // CHECK:       [[COND_TRUE]]:
 // CHECK-NEXT:    br label %[[COND_END:.*]]
 // CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[COND_END]]
 // CHECK:       [[COND_END]]:
 // CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 2, %[[COND_TRUE]] ], [ [[TMP4]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
-// CHECK-NEXT:    store i32 [[TMP5]], ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 [[TMP5]], ptr [[DOTOMP_IV]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND:.*]]
 // CHECK:       [[OMP_INNER_FOR_COND]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP3:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]]
 // CHECK-NEXT:    br i1 [[CMP3]], label %[[OMP_INNER_FOR_BODY:.*]], label %[[OMP_INNER_FOR_END:.*]]
 // CHECK:       [[OMP_INNER_FOR_BODY]]:
-// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP8]], 2
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 5, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD]], ptr [[I1]], align 4
+// CHECK-NEXT:    store i32 [[ADD]], ptr [[I1]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[OMP_BODY_CONTINUE:.*]]
 // CHECK:       [[OMP_BODY_CONTINUE]]:
 // CHECK-NEXT:    br label %[[OMP_INNER_FOR_INC:.*]]
 // CHECK:       [[OMP_INNER_FOR_INC]]:
-// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD4:%.*]] = add nsw i32 [[TMP9]], 1
-// CHECK-NEXT:    store i32 [[ADD4]], ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    store i32 [[ADD4]], ptr [[DOTOMP_IV]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND]]
 // CHECK:       [[OMP_INNER_FOR_END]]:
 // CHECK-NEXT:    br label %[[OMP_LOOP_EXIT:.*]]
 // CHECK:       [[OMP_LOOP_EXIT]]:
 // CHECK-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]])
-// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4
+// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], {{align [0-9]+}}
 // CHECK-NEXT:    [[TMP11:%.*]] = icmp ne i32 [[TMP10]], 0
 // CHECK-NEXT:    br i1 [[TMP11]], [[DOTOMP_LASTPRIVATE_THEN:label %.*]], [[DOTOMP_LASTPRIVATE_DONE:label %.*]]
 // CHECK:       [[_OMP_LASTPRIVATE_THEN:.*:]]
-// CHECK-NEXT:    store i32 11, ptr [[I1]], align 4
-// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[I1]], align 4
-// CHECK-NEXT:    store i32 [[TMP12]], ptr [[TMP0]], align 4
+// CHECK-NEXT:    store i32 11, ptr [[I1]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[I1]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 [[TMP12]], ptr [[TMP0]], {{align [0-9]+}}
 // CHECK-NEXT:    br [[DOTOMP_LASTPRIVATE_DONE]]
 // CHECK:       [[_OMP_LASTPRIVATE_DONE:.*:]]
 // CHECK-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP2]])
@@ -730,58 +730,58 @@ void test_pointer_fuse(void) {
 // CHECK-LABEL: define dso_local void @test_tile_workshare(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[TMP:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
 // CHECK-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
-// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_LB]], align 4
-// CHECK-NEXT:    store i32 4, ptr [[DOTOMP_UB]], align 4
-// CHECK-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_LB]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 4, ptr [[DOTOMP_UB]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], {{align [0-9]+}}
 // CHECK-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 4
 // CHECK-NEXT:    br i1 [[CMP]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
 // CHECK:       [[COND_TRUE]]:
 // CHECK-NEXT:    br label %[[COND_END:.*]]
 // CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[COND_END]]
 // CHECK:       [[COND_END]]:
 // CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 4, %[[COND_TRUE]] ], [ [[TMP2]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
-// CHECK-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND:.*]]
 // CHECK:       [[OMP_INNER_FOR_COND]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP1:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]]
 // CHECK-NEXT:    br i1 [[CMP1]], label %[[OMP_INNER_FOR_BODY:.*]], label %[[OMP_INNER_FOR_END:.*]]
 // CHECK:       [[OMP_INNER_FOR_BODY]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP6]], 2
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD]], ptr [[DOTFLOOR_0_IV_I]], align 4
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
-// CHECK-NEXT:    store i32 [[TMP7]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[ADD]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 [[TMP7]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND:.*]]
 // CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
-// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD2:%.*]] = add nsw i32 [[TMP9]], 2
 // CHECK-NEXT:    [[CMP3:%.*]] = icmp slt i32 10, [[ADD2]]
 // CHECK-NEXT:    br i1 [[CMP3]], label %[[COND_TRUE4:.*]], label %[[COND_FALSE5:.*]]
 // CHECK:       [[COND_TRUE4]]:
 // CHECK-NEXT:    br label %[[COND_END7:.*]]
 // CHECK:       [[COND_FALSE5]]:
-// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP10]], 2
 // CHECK-NEXT:    br label %[[COND_END7]]
 // CHECK:       [[COND_END7]]:
@@ -789,24 +789,24 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[CMP9:%.*]] = icmp slt i32 [[TMP8]], [[COND8]]
 // CHECK-NEXT:    br i1 [[CMP9]], label %[[FOR_BODY:.*]], label %[[FOR_END:.*]]
 // CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL10:%.*]] = mul nsw i32 [[TMP11]], 1
 // CHECK-NEXT:    [[ADD11:%.*]] = add nsw i32 1, [[MUL10]]
-// CHECK-NEXT:    store i32 [[ADD11]], ptr [[I]], align 4
+// CHECK-NEXT:    store i32 [[ADD11]], ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_INC:.*]]
 // CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP12]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP22:![0-9]+]]
 // CHECK:       [[FOR_END]]:
 // CHECK-NEXT:    br label %[[OMP_BODY_CONTINUE:.*]]
 // CHECK:       [[OMP_BODY_CONTINUE]]:
 // CHECK-NEXT:    br label %[[OMP_INNER_FOR_INC:.*]]
 // CHECK:       [[OMP_INNER_FOR_INC]]:
-// CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD12:%.*]] = add nsw i32 [[TMP13]], 1
-// CHECK-NEXT:    store i32 [[ADD12]], ptr [[DOTOMP_IV]], align 4
+// CHECK-NEXT:    store i32 [[ADD12]], ptr [[DOTOMP_IV]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND]]
 // CHECK:       [[OMP_INNER_FOR_END]]:
 // CHECK-NEXT:    br label %[[OMP_LOOP_EXIT:.*]]
@@ -819,30 +819,30 @@ void test_pointer_fuse(void) {
 // CHECK-LABEL: define dso_local void @test_tile_zero_tripcount(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    store i32 10, ptr [[I]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    store i32 10, ptr [[I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND:.*]]
 // CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], -5
 // CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END9:.*]]
 // CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
-// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND1:.*]]
 // CHECK:       [[FOR_COND1]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 2
 // CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 -5, [[ADD]]
 // CHECK-NEXT:    br i1 [[CMP2]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
 // CHECK:       [[COND_TRUE]]:
 // CHECK-NEXT:    br label %[[COND_END:.*]]
 // CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP4]], 2
 // CHECK-NEXT:    br label %[[COND_END]]
 // CHECK:       [[COND_END]]:
@@ -850,55 +850,55 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP2]], [[COND]]
 // CHECK-NEXT:    br i1 [[CMP4]], label %[[FOR_BODY5:.*]], label %[[FOR_END:.*]]
 // CHECK:       [[FOR_BODY5]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP5]], 1
 // CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 10, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], align 4
+// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_INC:.*]]
 // CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP23:![0-9]+]]
 // CHECK:       [[FOR_END]]:
 // CHECK-NEXT:    br label %[[FOR_INC7:.*]]
 // CHECK:       [[FOR_INC7]]:
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP7]], 2
-// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]]
 // CHECK:       [[FOR_END9]]:
-// CHECK-NEXT:    store i32 5, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 5, ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    ret void
 //
 //
 // CHECK-LABEL: define dso_local void @test_stripe_negative_step(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[DOTSTRIPE_0_IV_I:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    store i32 10, ptr [[I]], align 4
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTSTRIPE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
+// CHECK-NEXT:    store i32 10, ptr [[I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND:.*]]
 // CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
 // CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END8:.*]]
 // CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
-// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND1:.*]]
 // CHECK:       [[FOR_COND1]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 3
 // CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 10, [[ADD]]
 // CHECK-NEXT:    br i1 [[CMP2]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
 // CHECK:       [[COND_TRUE]]:
 // CHECK-NEXT:    br label %[[COND_END:.*]]
 // CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP4]], 3
 // CHECK-NEXT:    br label %[[COND_END]]
 // CHECK:       [[COND_END]]:
@@ -906,47 +906,47 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP2]], [[COND]]
 // CHECK-NEXT:    br i1 [[CMP4]], label %[[FOR_BODY5:.*]], label %[[FOR_END:.*]]
 // CHECK:       [[FOR_BODY5]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP5]], 1
 // CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 10, [[MUL]]
-// CHECK-NEXT:    store i32 [[SUB]], ptr [[I]], align 4
+// CHECK-NEXT:    store i32 [[SUB]], ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_INC:.*]]
 // CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTSTRIPE_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP25:![0-9]+]]
 // CHECK:       [[FOR_END]]:
 // CHECK-NEXT:    br label %[[FOR_INC6:.*]]
 // CHECK:       [[FOR_INC6]]:
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD7:%.*]] = add nsw i32 [[TMP7]], 3
-// CHECK-NEXT:    store i32 [[ADD7]], ptr [[DOTFLOOR_0_IV_I]], align 4
+// CHECK-NEXT:    store i32 [[ADD7]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]]
 // CHECK:       [[FOR_END8]]:
-// CHECK-NEXT:    store i32 0, ptr [[I]], align 4
+// CHECK-NEXT:    store i32 0, ptr [[I]], {{align [0-9]+}}
 // CHECK-NEXT:    ret void
 //
 //
 // CHECK-LABEL: define dso_local void @test_pointer_tile(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[ARR:%.*]] = alloca [20 x i32], align 16
-// CHECK-NEXT:    [[P:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_P:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTTILE_0_IV_P:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[ARR:%.*]] = alloca [20 x i32], {{align [0-9]+}}
+// CHECK-NEXT:    [[P:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_P:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTTILE_0_IV_P:%.*]] = alloca i64, {{align [0-9]+}}
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [20 x i32], ptr [[ARR]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[P]], align 8
+// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[P]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [20 x i32], ptr [[ARR]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [20 x i32], ptr [[ARR]], i64 0, i64 0
 // CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY3]], i64 20
-// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], align 8
-// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
-// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
 // CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP0]] to i64
 // CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP1]] to i64
 // CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
@@ -955,33 +955,33 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
 // CHECK-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
 // CHECK-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
-// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8
-// CHECK-NEXT:    store i64 0, ptr [[DOTFLOOR_0_IV_P]], align 8
+// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
+// CHECK-NEXT:    store i64 0, ptr [[DOTFLOOR_0_IV_P]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND:.*]]
 // CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], align 8
-// CHECK-NEXT:    [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP3]], 1
 // CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[TMP2]], [[ADD6]]
 // CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END18:.*]]
 // CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], align 8
-// CHECK-NEXT:    store i64 [[TMP4]], ptr [[DOTTILE_0_IV_P]], align 8
+// CHECK-NEXT:    [[TMP4:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], {{align [0-9]+}}
+// CHECK-NEXT:    store i64 [[TMP4]], ptr [[DOTTILE_0_IV_P]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND7:.*]]
 // CHECK:       [[FOR_COND7]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTTILE_0_IV_P]], align 8
-// CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTTILE_0_IV_P]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD8:%.*]] = add nsw i64 [[TMP6]], 1
-// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], align 8
+// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD9:%.*]] = add nsw i64 [[TMP7]], 5
 // CHECK-NEXT:    [[CMP10:%.*]] = icmp slt i64 [[ADD8]], [[ADD9]]
 // CHECK-NEXT:    br i1 [[CMP10]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
 // CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD11:%.*]] = add nsw i64 [[TMP8]], 1
 // CHECK-NEXT:    br label %[[COND_END:.*]]
 // CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], align 8
+// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD12:%.*]] = add nsw i64 [[TMP9]], 5
 // CHECK-NEXT:    br label %[[COND_END]]
 // CHECK:       [[COND_END]]:
@@ -989,30 +989,30 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[CMP13:%.*]] = icmp slt i64 [[TMP5]], [[COND]]
 // CHECK-NEXT:    br i1 [[CMP13]], label %[[FOR_BODY14:.*]], label %[[FOR_END:.*]]
 // CHECK:       [[FOR_BODY14]]:
-// CHECK-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTTILE_0_IV_P]], align 8
+// CHECK-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTTILE_0_IV_P]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP11]], 1
 // CHECK-NEXT:    [[ADD_PTR15:%.*]] = getelementptr inbounds i32, ptr [[TMP10]], i64 [[MUL]]
-// CHECK-NEXT:    store ptr [[ADD_PTR15]], ptr [[P]], align 8
-// CHECK-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[P]], align 8
-// CHECK-NEXT:    store i32 0, ptr [[TMP12]], align 4
+// CHECK-NEXT:    store ptr [[ADD_PTR15]], ptr [[P]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[P]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[TMP12]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_INC:.*]]
 // CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTTILE_0_IV_P]], align 8
+// CHECK-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTTILE_0_IV_P]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP13]], 1
-// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTTILE_0_IV_P]], align 8
+// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTTILE_0_IV_P]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND7]], !llvm.loop [[LOOP27:![0-9]+]]
 // CHECK:       [[FOR_END]]:
 // CHECK-NEXT:    br label %[[FOR_INC16:.*]]
 // CHECK:       [[FOR_INC16]]:
-// CHECK-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], align 8
+// CHECK-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD17:%.*]] = add nsw i64 [[TMP14]], 5
-// CHECK-NEXT:    store i64 [[ADD17]], ptr [[DOTFLOOR_0_IV_P]], align 8
+// CHECK-NEXT:    store i64 [[ADD17]], ptr [[DOTFLOOR_0_IV_P]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP28:![0-9]+]]
 // CHECK:       [[FOR_END18]]:
-// CHECK-NEXT:    [[TMP15:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK-NEXT:    [[TMP16:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
-// CHECK-NEXT:    [[TMP17:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[TMP15:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP16:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP17:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
 // CHECK-NEXT:    [[SUB_PTR_LHS_CAST19:%.*]] = ptrtoaddr ptr [[TMP16]] to i64
 // CHECK-NEXT:    [[SUB_PTR_RHS_CAST20:%.*]] = ptrtoaddr ptr [[TMP17]] to i64
 // CHECK-NEXT:    [[SUB_PTR_SUB21:%.*]] = sub i64 [[SUB_PTR_LHS_CAST19]], [[SUB_PTR_RHS_CAST20]]
@@ -1022,29 +1022,29 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[DIV25:%.*]] = sdiv i64 [[ADD24]], 1
 // CHECK-NEXT:    [[MUL26:%.*]] = mul nsw i64 [[DIV25]], 1
 // CHECK-NEXT:    [[ADD_PTR27:%.*]] = getelementptr inbounds i32, ptr [[TMP15]], i64 [[MUL26]]
-// CHECK-NEXT:    store ptr [[ADD_PTR27]], ptr [[P]], align 8
+// CHECK-NEXT:    store ptr [[ADD_PTR27]], ptr [[P]], {{align [0-9]+}}
 // CHECK-NEXT:    ret void
 //
 //
 // CHECK-LABEL: define dso_local void @test_pointer_reverse(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[ARR:%.*]] = alloca [15 x i32], align 16
-// CHECK-NEXT:    [[Q:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTFORWARD_IV_Q:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTREVERSED_IV_Q:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[ARR:%.*]] = alloca [15 x i32], {{align [0-9]+}}
+// CHECK-NEXT:    [[Q:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTFORWARD_IV_Q:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTREVERSED_IV_Q:%.*]] = alloca i64, {{align [0-9]+}}
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[Q]], align 8
+// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[Q]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR]], i64 0, i64 0
 // CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY3]], i64 15
-// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], align 8
-// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
-// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
 // CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP0]] to i64
 // CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP1]] to i64
 // CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
@@ -1053,39 +1053,39 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
 // CHECK-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
 // CHECK-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
-// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8
-// CHECK-NEXT:    store i64 0, ptr [[DOTFORWARD_IV_Q]], align 8
+// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
+// CHECK-NEXT:    store i64 0, ptr [[DOTFORWARD_IV_Q]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND:.*]]
 // CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTFORWARD_IV_Q]], align 8
-// CHECK-NEXT:    [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTFORWARD_IV_Q]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP3]], 1
 // CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[TMP2]], [[ADD6]]
 // CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END:.*]]
 // CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[TMP4:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD7:%.*]] = add nsw i64 [[TMP4]], 1
 // CHECK-NEXT:    [[SUB8:%.*]] = sub nsw i64 [[ADD7]], 1
-// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTFORWARD_IV_Q]], align 8
+// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTFORWARD_IV_Q]], {{align [0-9]+}}
 // CHECK-NEXT:    [[SUB9:%.*]] = sub nsw i64 [[SUB8]], [[TMP5]]
-// CHECK-NEXT:    store i64 [[SUB9]], ptr [[DOTREVERSED_IV_Q]], align 8
-// CHECK-NEXT:    [[TMP6:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTREVERSED_IV_Q]], align 8
+// CHECK-NEXT:    store i64 [[SUB9]], ptr [[DOTREVERSED_IV_Q]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP6:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTREVERSED_IV_Q]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP7]], 1
 // CHECK-NEXT:    [[ADD_PTR10:%.*]] = getelementptr inbounds i32, ptr [[TMP6]], i64 [[MUL]]
-// CHECK-NEXT:    store ptr [[ADD_PTR10]], ptr [[Q]], align 8
-// CHECK-NEXT:    [[TMP8:%.*]] = load ptr, ptr [[Q]], align 8
-// CHECK-NEXT:    store i32 1, ptr [[TMP8]], align 4
+// CHECK-NEXT:    store ptr [[ADD_PTR10]], ptr [[Q]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP8:%.*]] = load ptr, ptr [[Q]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 1, ptr [[TMP8]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_INC:.*]]
 // CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFORWARD_IV_Q]], align 8
+// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFORWARD_IV_Q]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP9]], 1
-// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTFORWARD_IV_Q]], align 8
+// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTFORWARD_IV_Q]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP29:![0-9]+]]
 // CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK-NEXT:    [[TMP11:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
-// CHECK-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP11:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
 // CHECK-NEXT:    [[SUB_PTR_LHS_CAST11:%.*]] = ptrtoaddr ptr [[TMP11]] to i64
 // CHECK-NEXT:    [[SUB_PTR_RHS_CAST12:%.*]] = ptrtoaddr ptr [[TMP12]] to i64
 // CHECK-NEXT:    [[SUB_PTR_SUB13:%.*]] = sub i64 [[SUB_PTR_LHS_CAST11]], [[SUB_PTR_RHS_CAST12]]
@@ -1095,29 +1095,29 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[DIV17:%.*]] = sdiv i64 [[ADD16]], 1
 // CHECK-NEXT:    [[MUL18:%.*]] = mul nsw i64 [[DIV17]], 1
 // CHECK-NEXT:    [[ADD_PTR19:%.*]] = getelementptr inbounds i32, ptr [[TMP10]], i64 [[MUL18]]
-// CHECK-NEXT:    store ptr [[ADD_PTR19]], ptr [[Q]], align 8
+// CHECK-NEXT:    store ptr [[ADD_PTR19]], ptr [[Q]], {{align [0-9]+}}
 // CHECK-NEXT:    ret void
 //
 //
 // CHECK-LABEL: define dso_local void @test_pointer_step(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[BUFFER:%.*]] = alloca [30 x i8], align 16
-// CHECK-NEXT:    [[PTR:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_PTR:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTTILE_0_IV_PTR:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[BUFFER:%.*]] = alloca [30 x i8], {{align [0-9]+}}
+// CHECK-NEXT:    [[PTR:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTFLOOR_0_IV_PTR:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTTILE_0_IV_PTR:%.*]] = alloca i64, {{align [0-9]+}}
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [30 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[PTR]], align 8
+// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[PTR]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [30 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [30 x i8], ptr [[BUFFER]], i64 0, i64 0
 // CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[ARRAYDECAY3]], i64 30
-// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], align 8
-// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
-// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
 // CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP0]] to i64
 // CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP1]] to i64
 // CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
@@ -1125,33 +1125,33 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 2
 // CHECK-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 2
 // CHECK-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
-// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8
-// CHECK-NEXT:    store i64 0, ptr [[DOTFLOOR_0_IV_PTR]], align 8
+// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
+// CHECK-NEXT:    store i64 0, ptr [[DOTFLOOR_0_IV_PTR]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND:.*]]
 // CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], align 8
-// CHECK-NEXT:    [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP3]], 1
 // CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[TMP2]], [[ADD6]]
 // CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END18:.*]]
 // CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], align 8
-// CHECK-NEXT:    store i64 [[TMP4]], ptr [[DOTTILE_0_IV_PTR]], align 8
+// CHECK-NEXT:    [[TMP4:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], {{align [0-9]+}}
+// CHECK-NEXT:    store i64 [[TMP4]], ptr [[DOTTILE_0_IV_PTR]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND7:.*]]
 // CHECK:       [[FOR_COND7]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTTILE_0_IV_PTR]], align 8
-// CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTTILE_0_IV_PTR]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD8:%.*]] = add nsw i64 [[TMP6]], 1
-// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], align 8
+// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD9:%.*]] = add nsw i64 [[TMP7]], 4
 // CHECK-NEXT:    [[CMP10:%.*]] = icmp slt i64 [[ADD8]], [[ADD9]]
 // CHECK-NEXT:    br i1 [[CMP10]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
 // CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD11:%.*]] = add nsw i64 [[TMP8]], 1
 // CHECK-NEXT:    br label %[[COND_END:.*]]
 // CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], align 8
+// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD12:%.*]] = add nsw i64 [[TMP9]], 4
 // CHECK-NEXT:    br label %[[COND_END]]
 // CHECK:       [[COND_END]]:
@@ -1159,30 +1159,30 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[CMP13:%.*]] = icmp slt i64 [[TMP5]], [[COND]]
 // CHECK-NEXT:    br i1 [[CMP13]], label %[[FOR_BODY14:.*]], label %[[FOR_END:.*]]
 // CHECK:       [[FOR_BODY14]]:
-// CHECK-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTTILE_0_IV_PTR]], align 8
+// CHECK-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTTILE_0_IV_PTR]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP11]], 2
 // CHECK-NEXT:    [[ADD_PTR15:%.*]] = getelementptr inbounds i8, ptr [[TMP10]], i64 [[MUL]]
-// CHECK-NEXT:    store ptr [[ADD_PTR15]], ptr [[PTR]], align 8
-// CHECK-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[PTR]], align 8
-// CHECK-NEXT:    store i8 120, ptr [[TMP12]], align 1
+// CHECK-NEXT:    store ptr [[ADD_PTR15]], ptr [[PTR]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[PTR]], {{align [0-9]+}}
+// CHECK-NEXT:    store i8 120, ptr [[TMP12]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_INC:.*]]
 // CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTTILE_0_IV_PTR]], align 8
+// CHECK-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTTILE_0_IV_PTR]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP13]], 1
-// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTTILE_0_IV_PTR]], align 8
+// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTTILE_0_IV_PTR]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND7]], !llvm.loop [[LOOP30:![0-9]+]]
 // CHECK:       [[FOR_END]]:
 // CHECK-NEXT:    br label %[[FOR_INC16:.*]]
 // CHECK:       [[FOR_INC16]]:
-// CHECK-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], align 8
+// CHECK-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD17:%.*]] = add nsw i64 [[TMP14]], 4
-// CHECK-NEXT:    store i64 [[ADD17]], ptr [[DOTFLOOR_0_IV_PTR]], align 8
+// CHECK-NEXT:    store i64 [[ADD17]], ptr [[DOTFLOOR_0_IV_PTR]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP31:![0-9]+]]
 // CHECK:       [[FOR_END18]]:
-// CHECK-NEXT:    [[TMP15:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK-NEXT:    [[TMP16:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
-// CHECK-NEXT:    [[TMP17:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[TMP15:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP16:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP17:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
 // CHECK-NEXT:    [[SUB_PTR_LHS_CAST19:%.*]] = ptrtoaddr ptr [[TMP16]] to i64
 // CHECK-NEXT:    [[SUB_PTR_RHS_CAST20:%.*]] = ptrtoaddr ptr [[TMP17]] to i64
 // CHECK-NEXT:    [[SUB_PTR_SUB21:%.*]] = sub i64 [[SUB_PTR_LHS_CAST19]], [[SUB_PTR_RHS_CAST20]]
@@ -1191,43 +1191,43 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[DIV24:%.*]] = sdiv i64 [[ADD23]], 2
 // CHECK-NEXT:    [[MUL25:%.*]] = mul nsw i64 [[DIV24]], 2
 // CHECK-NEXT:    [[ADD_PTR26:%.*]] = getelementptr inbounds i8, ptr [[TMP15]], i64 [[MUL25]]
-// CHECK-NEXT:    store ptr [[ADD_PTR26]], ptr [[PTR]], align 8
+// CHECK-NEXT:    store ptr [[ADD_PTR26]], ptr [[PTR]], {{align [0-9]+}}
 // CHECK-NEXT:    ret void
 //
 //
 // CHECK-LABEL: define dso_local void @test_pointer_fuse(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[ARR1:%.*]] = alloca [10 x i32], align 16
-// CHECK-NEXT:    [[ARR2:%.*]] = alloca [15 x i32], align 16
-// CHECK-NEXT:    [[P:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[Q:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTOMP_LB0:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTOMP_ST0:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTOMP_NI0:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTOMP_IV0:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_8:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_10:%.*]] = alloca ptr, align 8
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_13:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTOMP_LB1:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTOMP_ST1:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTOMP_NI1:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTOMP_IV1:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTOMP_TEMP_1:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTOMP_FUSE_MAX:%.*]] = alloca i64, align 8
-// CHECK-NEXT:    [[DOTOMP_FUSE_INDEX:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[ARR1:%.*]] = alloca [10 x i32], {{align [0-9]+}}
+// CHECK-NEXT:    [[ARR2:%.*]] = alloca [15 x i32], {{align [0-9]+}}
+// CHECK-NEXT:    [[P:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[Q:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_LB0:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_ST0:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_NI0:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_IV0:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_8:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_10:%.*]] = alloca ptr, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTCAPTURE_EXPR_13:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_LB1:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_ST1:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_NI1:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_IV1:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_TEMP_1:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_FUSE_MAX:%.*]] = alloca i64, {{align [0-9]+}}
+// CHECK-NEXT:    [[DOTOMP_FUSE_INDEX:%.*]] = alloca i64, {{align [0-9]+}}
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARR1]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[P]], align 8
+// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[P]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARR1]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARR1]], i64 0, i64 0
 // CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY3]], i64 10
-// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], align 8
-// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
-// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
 // CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP0]] to i64
 // CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP1]] to i64
 // CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
@@ -1236,21 +1236,21 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
 // CHECK-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
 // CHECK-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
-// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8
-// CHECK-NEXT:    store i64 0, ptr [[DOTOMP_LB0]], align 8
-// CHECK-NEXT:    store i64 1, ptr [[DOTOMP_ST0]], align 8
-// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8
+// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
+// CHECK-NEXT:    store i64 0, ptr [[DOTOMP_LB0]], {{align [0-9]+}}
+// CHECK-NEXT:    store i64 1, ptr [[DOTOMP_ST0]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP2]], 1
-// CHECK-NEXT:    store i64 [[ADD6]], ptr [[DOTOMP_NI0]], align 8
+// CHECK-NEXT:    store i64 [[ADD6]], ptr [[DOTOMP_NI0]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ARRAYDECAY7:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR2]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY7]], ptr [[Q]], align 8
+// CHECK-NEXT:    store ptr [[ARRAYDECAY7]], ptr [[Q]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ARRAYDECAY9:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR2]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY9]], ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK-NEXT:    store ptr [[ARRAYDECAY9]], ptr [[DOTCAPTURE_EXPR_8]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ARRAYDECAY11:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR2]], i64 0, i64 0
 // CHECK-NEXT:    [[ADD_PTR12:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY11]], i64 15
-// CHECK-NEXT:    store ptr [[ADD_PTR12]], ptr [[DOTCAPTURE_EXPR_10]], align 8
-// CHECK-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_10]], align 8
-// CHECK-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK-NEXT:    store ptr [[ADD_PTR12]], ptr [[DOTCAPTURE_EXPR_10]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_10]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], {{align [0-9]+}}
 // CHECK-NEXT:    [[SUB_PTR_LHS_CAST14:%.*]] = ptrtoaddr ptr [[TMP3]] to i64
 // CHECK-NEXT:    [[SUB_PTR_RHS_CAST15:%.*]] = ptrtoaddr ptr [[TMP4]] to i64
 // CHECK-NEXT:    [[SUB_PTR_SUB16:%.*]] = sub i64 [[SUB_PTR_LHS_CAST14]], [[SUB_PTR_RHS_CAST15]]
@@ -1259,85 +1259,85 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[ADD19:%.*]] = add nsw i64 [[SUB18]], 1
 // CHECK-NEXT:    [[DIV20:%.*]] = sdiv i64 [[ADD19]], 1
 // CHECK-NEXT:    [[SUB21:%.*]] = sub nsw i64 [[DIV20]], 1
-// CHECK-NEXT:    store i64 [[SUB21]], ptr [[DOTCAPTURE_EXPR_13]], align 8
-// CHECK-NEXT:    store i64 0, ptr [[DOTOMP_LB1]], align 8
-// CHECK-NEXT:    store i64 1, ptr [[DOTOMP_ST1]], align 8
-// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_13]], align 8
+// CHECK-NEXT:    store i64 [[SUB21]], ptr [[DOTCAPTURE_EXPR_13]], {{align [0-9]+}}
+// CHECK-NEXT:    store i64 0, ptr [[DOTOMP_LB1]], {{align [0-9]+}}
+// CHECK-NEXT:    store i64 1, ptr [[DOTOMP_ST1]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_13]], {{align [0-9]+}}
 // CHECK-NEXT:    [[ADD22:%.*]] = add nsw i64 [[TMP5]], 1
-// CHECK-NEXT:    store i64 [[ADD22]], ptr [[DOTOMP_NI1]], align 8
-// CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTOMP_NI0]], align 8
-// CHECK-NEXT:    store i64 [[TMP6]], ptr [[DOTOMP_TEMP_1]], align 8
-// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTOMP_TEMP_1]], align 8
-// CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTOMP_NI1]], align 8
+// CHECK-NEXT:    store i64 [[ADD22]], ptr [[DOTOMP_NI1]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTOMP_NI0]], {{align [0-9]+}}
+// CHECK-NEXT:    store i64 [[TMP6]], ptr [[DOTOMP_TEMP_1]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTOMP_TEMP_1]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTOMP_NI1]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i64 [[TMP7]], [[TMP8]]
 // CHECK-NEXT:    br i1 [[CMP]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
 // CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTOMP_TEMP_1]], align 8
+// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTOMP_TEMP_1]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[COND_END:.*]]
 // CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP10:%.*]] = load i64, ptr [[DOTOMP_NI1]], align 8
+// CHECK-NEXT:    [[TMP10:%.*]] = load i64, ptr [[DOTOMP_NI1]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[COND_END]]
 // CHECK:       [[COND_END]]:
 // CHECK-NEXT:    [[COND:%.*]] = phi i64 [ [[TMP9]], %[[COND_TRUE]] ], [ [[TMP10]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    store i64 [[COND]], ptr [[DOTOMP_FUSE_MAX]], align 8
-// CHECK-NEXT:    store i64 0, ptr [[DOTOMP_FUSE_INDEX]], align 8
+// CHECK-NEXT:    store i64 [[COND]], ptr [[DOTOMP_FUSE_MAX]], {{align [0-9]+}}
+// CHECK-NEXT:    store i64 0, ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND:.*]]
 // CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], align 8
-// CHECK-NEXT:    [[TMP12:%.*]] = load i64, ptr [[DOTOMP_FUSE_MAX]], align 8
+// CHECK-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP12:%.*]] = load i64, ptr [[DOTOMP_FUSE_MAX]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP23:%.*]] = icmp slt i64 [[TMP11]], [[TMP12]]
 // CHECK-NEXT:    br i1 [[CMP23]], label %[[FOR_BODY:.*]], label %[[FOR_END:.*]]
 // CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], align 8
-// CHECK-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTOMP_NI0]], align 8
+// CHECK-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTOMP_NI0]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP24:%.*]] = icmp slt i64 [[TMP13]], [[TMP14]]
 // CHECK-NEXT:    br i1 [[CMP24]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
 // CHECK:       [[IF_THEN]]:
-// CHECK-NEXT:    [[TMP15:%.*]] = load i64, ptr [[DOTOMP_LB0]], align 8
-// CHECK-NEXT:    [[TMP16:%.*]] = load i64, ptr [[DOTOMP_ST0]], align 8
-// CHECK-NEXT:    [[TMP17:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], align 8
+// CHECK-NEXT:    [[TMP15:%.*]] = load i64, ptr [[DOTOMP_LB0]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP16:%.*]] = load i64, ptr [[DOTOMP_ST0]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP17:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP16]], [[TMP17]]
 // CHECK-NEXT:    [[ADD25:%.*]] = add nsw i64 [[TMP15]], [[MUL]]
-// CHECK-NEXT:    store i64 [[ADD25]], ptr [[DOTOMP_IV0]], align 8
-// CHECK-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK-NEXT:    [[TMP19:%.*]] = load i64, ptr [[DOTOMP_IV0]], align 8
+// CHECK-NEXT:    store i64 [[ADD25]], ptr [[DOTOMP_IV0]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP19:%.*]] = load i64, ptr [[DOTOMP_IV0]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL26:%.*]] = mul nsw i64 [[TMP19]], 1
 // CHECK-NEXT:    [[ADD_PTR27:%.*]] = getelementptr inbounds i32, ptr [[TMP18]], i64 [[MUL26]]
-// CHECK-NEXT:    store ptr [[ADD_PTR27]], ptr [[P]], align 8
-// CHECK-NEXT:    [[TMP20:%.*]] = load ptr, ptr [[P]], align 8
-// CHECK-NEXT:    store i32 0, ptr [[TMP20]], align 4
+// CHECK-NEXT:    store ptr [[ADD_PTR27]], ptr [[P]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP20:%.*]] = load ptr, ptr [[P]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 0, ptr [[TMP20]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[IF_END]]
 // CHECK:       [[IF_END]]:
-// CHECK-NEXT:    [[TMP21:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], align 8
-// CHECK-NEXT:    [[TMP22:%.*]] = load i64, ptr [[DOTOMP_NI1]], align 8
+// CHECK-NEXT:    [[TMP21:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP22:%.*]] = load i64, ptr [[DOTOMP_NI1]], {{align [0-9]+}}
 // CHECK-NEXT:    [[CMP28:%.*]] = icmp slt i64 [[TMP21]], [[TMP22]]
 // CHECK-NEXT:    br i1 [[CMP28]], label %[[IF_THEN29:.*]], label %[[IF_END34:.*]]
 // CHECK:       [[IF_THEN29]]:
-// CHECK-NEXT:    [[TMP23:%.*]] = load i64, ptr [[DOTOMP_LB1]], align 8
-// CHECK-NEXT:    [[TMP24:%.*]] = load i64, ptr [[DOTOMP_ST1]], align 8
-// CHECK-NEXT:    [[TMP25:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], align 8
+// CHECK-NEXT:    [[TMP23:%.*]] = load i64, ptr [[DOTOMP_LB1]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP24:%.*]] = load i64, ptr [[DOTOMP_ST1]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP25:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL30:%.*]] = mul nsw i64 [[TMP24]], [[TMP25]]
 // CHECK-NEXT:    [[ADD31:%.*]] = add nsw i64 [[TMP23]], [[MUL30]]
-// CHECK-NEXT:    store i64 [[ADD31]], ptr [[DOTOMP_IV1]], align 8
-// CHECK-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK-NEXT:    [[TMP27:%.*]] = load i64, ptr [[DOTOMP_IV1]], align 8
+// CHECK-NEXT:    store i64 [[ADD31]], ptr [[DOTOMP_IV1]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP27:%.*]] = load i64, ptr [[DOTOMP_IV1]], {{align [0-9]+}}
 // CHECK-NEXT:    [[MUL32:%.*]] = mul nsw i64 [[TMP27]], 1
 // CHECK-NEXT:    [[ADD_PTR33:%.*]] = getelementptr inbounds i32, ptr [[TMP26]], i64 [[MUL32]]
-// CHECK-NEXT:    store ptr [[ADD_PTR33]], ptr [[Q]], align 8
-// CHECK-NEXT:    [[TMP28:%.*]] = load ptr, ptr [[Q]], align 8
-// CHECK-NEXT:    store i32 1, ptr [[TMP28]], align 4
+// CHECK-NEXT:    store ptr [[ADD_PTR33]], ptr [[Q]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP28:%.*]] = load ptr, ptr [[Q]], {{align [0-9]+}}
+// CHECK-NEXT:    store i32 1, ptr [[TMP28]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[IF_END34]]
 // CHECK:       [[IF_END34]]:
 // CHECK-NEXT:    br label %[[FOR_INC:.*]]
 // CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP29:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], align 8
+// CHECK-NEXT:    [[TMP29:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
 // CHECK-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP29]], 1
-// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTOMP_FUSE_INDEX]], align 8
+// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
 // CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP32:![0-9]+]]
 // CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    [[TMP30:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
-// CHECK-NEXT:    [[TMP31:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], align 8
-// CHECK-NEXT:    [[TMP32:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8
+// CHECK-NEXT:    [[TMP30:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP31:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP32:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
 // CHECK-NEXT:    [[SUB_PTR_LHS_CAST35:%.*]] = ptrtoaddr ptr [[TMP31]] to i64
 // CHECK-NEXT:    [[SUB_PTR_RHS_CAST36:%.*]] = ptrtoaddr ptr [[TMP32]] to i64
 // CHECK-NEXT:    [[SUB_PTR_SUB37:%.*]] = sub i64 [[SUB_PTR_LHS_CAST35]], [[SUB_PTR_RHS_CAST36]]
@@ -1347,10 +1347,10 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[DIV41:%.*]] = sdiv i64 [[ADD40]], 1
 // CHECK-NEXT:    [[MUL42:%.*]] = mul nsw i64 [[DIV41]], 1
 // CHECK-NEXT:    [[ADD_PTR43:%.*]] = getelementptr inbounds i32, ptr [[TMP30]], i64 [[MUL42]]
-// CHECK-NEXT:    store ptr [[ADD_PTR43]], ptr [[P]], align 8
-// CHECK-NEXT:    [[TMP33:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], align 8
-// CHECK-NEXT:    [[TMP34:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_10]], align 8
-// CHECK-NEXT:    [[TMP35:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], align 8
+// CHECK-NEXT:    store ptr [[ADD_PTR43]], ptr [[P]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP33:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP34:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_10]], {{align [0-9]+}}
+// CHECK-NEXT:    [[TMP35:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], {{align [0-9]+}}
 // CHECK-NEXT:    [[SUB_PTR_LHS_CAST44:%.*]] = ptrtoaddr ptr [[TMP34]] to i64
 // CHECK-NEXT:    [[SUB_PTR_RHS_CAST45:%.*]] = ptrtoaddr ptr [[TMP35]] to i64
 // CHECK-NEXT:    [[SUB_PTR_SUB46:%.*]] = sub i64 [[SUB_PTR_LHS_CAST44]], [[SUB_PTR_RHS_CAST45]]
@@ -1360,7 +1360,7 @@ void test_pointer_fuse(void) {
 // CHECK-NEXT:    [[DIV50:%.*]] = sdiv i64 [[ADD49]], 1
 // CHECK-NEXT:    [[MUL51:%.*]] = mul nsw i64 [[DIV50]], 1
 // CHECK-NEXT:    [[ADD_PTR52:%.*]] = getelementptr inbounds i32, ptr [[TMP33]], i64 [[MUL51]]
-// CHECK-NEXT:    store ptr [[ADD_PTR52]], ptr [[Q]], align 8
+// CHECK-NEXT:    store ptr [[ADD_PTR52]], ptr [[Q]], {{align [0-9]+}}
 // CHECK-NEXT:    ret void
 //
 //.

>From 4362820aaa05af1fcef39cdbc1ca7c8e11994c89 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Fri, 21 Aug 2026 12:07:13 -0700
Subject: [PATCH 08/11] Added target to test

---
 clang/test/OpenMP/loop_transform_iv.c | 1334 ++-----------------------
 1 file changed, 82 insertions(+), 1252 deletions(-)

diff --git a/clang/test/OpenMP/loop_transform_iv.c b/clang/test/OpenMP/loop_transform_iv.c
index 4eeb50a7fba5a..a61e6ce7cb2f9 100644
--- a/clang/test/OpenMP/loop_transform_iv.c
+++ b/clang/test/OpenMP/loop_transform_iv.c
@@ -1,144 +1,200 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" "align [0-9]+" --prefix-filecheck-ir-name _ --version 5
-// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s
 // expected-no-diagnostics
 
 // Test that loop variables are correctly finalized after loop-transformation
 // constructs as required by OpenMP 6.0 spec (pg 371, lines 19-21).
 
 void test_tile(void) {
+  // CHECK-LABEL: define {{.*}} @test_tile
   int i;
   #pragma omp tile sizes(2)
   for (i = 1; i <= 10; i++) {
   }
+  // CHECK: store i32 11, ptr %i
   // After loop: i should be 11 (loop-exit value per OpenMP 6.0 spec)
 }
 
 void test_stripe(void) {
+  // CHECK-LABEL: define {{.*}} @test_stripe
   int i;
   #pragma omp stripe sizes(3)
   for (i = 0; i < 10; i++) {
   }
+  // CHECK: store i32 10, ptr %i
   // After loop: i should be 10 (loop-exit value per OpenMP 6.0 spec)
 }
 
 void test_tile_nested(void) {
+  // CHECK-LABEL: define {{.*}} @test_tile_nested
   int i, j;
   #pragma omp tile sizes(2, 3)
   for (i = 0; i < 10; i++)
     for (j = 0; j < 5; j++) {
     }
+  // CHECK: store i32 10, ptr %i
+  // CHECK: store i32 5, ptr %j
   // After loop: i should be 10, j should be 5 (loop-exit values per OpenMP 6.0 spec)
 }
 
 void test_tile_stride(void) {
+  // CHECK-LABEL: define {{.*}} @test_tile_stride
   int i;
   #pragma omp tile sizes(4)
   for (i = 5; i <= 15; i += 2) {
   }
+  // CHECK: store i32 17, ptr %i
   // After loop: i should be 17 (loop-exit value per OpenMP 6.0 spec)
 }
 
 void test_tile_variable_bound(int n) {
+  // CHECK-LABEL: define {{.*}} @test_tile_variable_bound
   int i;
   #pragma omp tile sizes(3)
   for (i = 0; i < n; i++) {
   }
+  // CHECK: for.end14:
+  // CHECK: store i32 {{.*}}, ptr %i
   // After loop: i should equal n (loop-exit value per OpenMP 6.0 spec)
 }
 
 void test_reverse(void) {
+  // CHECK-LABEL: define {{.*}} @test_reverse
   int i;
   #pragma omp reverse
   for (i = 0; i < 10; i++) {
   }
+  // CHECK: store i32 10, ptr %i
   // After loop: i should be 10 (loop-exit value per OpenMP 6.0 spec)
 }
 
 void test_interchange(void) {
+  // CHECK-LABEL: define {{.*}} @test_interchange
   int i, j;
   #pragma omp interchange permutation(2, 1)
   for (i = 0; i < 10; i++)
     for (j = 0; j < 5; j++) {
     }
+  // CHECK: store i32 10, ptr %i
+  // CHECK: store i32 5, ptr %j
   // After loop: i should be 10, j should be 5 (loop-exit values per OpenMP 6.0 spec)
 }
 
 void test_for_workshare(void) {
+  // CHECK-LABEL: define {{.*}} @test_for_workshare
   int i;
   #pragma omp for
   for (i = 5; i <= 10; i += 2) {
   }
+  // CHECK: omp.loop.exit:
+  // CHECK-NEXT: call void @__kmpc_for_static_fini
+  // CHECK-NEXT: call void @__kmpc_barrier
+  // CHECK-NEXT: ret void
   // omp for worksharing doesn't finalize the loop variable after the loop
 }
 
-void test_for_lastprivate(void) {
-  int i;
-  #pragma omp parallel
-  #pragma omp for lastprivate(i)
-  for (i = 5; i <= 10; i += 2) {
-  }
-  // omp for with lastprivate DOES finalize the loop variable
-  // i = last_iteration_value + stride = 9 + 2 = 11
-}
-
 void test_tile_workshare(void) {
+  // CHECK-LABEL: define {{.*}} @test_tile_workshare
   int i;
   #pragma omp for
   #pragma omp tile sizes(2)
   for (i = 1; i <= 10; i++) {
   }
+  // CHECK: omp.loop.exit:
+  // CHECK-NOT: store {{.*}}, ptr %i
+  // CHECK: call void @__kmpc_for_static_fini
   // i is private to the `for` construct; its post-loop value is
   // unspecified here (same as plain omp-for), so no restoring store
   // is expected for i after omp.loop.exit.
 }
 
 void test_tile_zero_tripcount(void) {
+  // CHECK-LABEL: define {{.*}} @test_tile_zero_tripcount
   int i;
   #pragma omp tile sizes(2)
   for (i = 10; i < 5; i++) {
   }
+  // CHECK: store i32 10, ptr %i
   // Loop doesn't execute (tripcount = 0), i should remain at initial value 10.
 }
 
 void test_stripe_negative_step(void) {
+  // CHECK-LABEL: define {{.*}} @test_stripe_negative_step
   int i;
   #pragma omp stripe sizes(3)
   for (i = 10; i > 0; i--) {
   }
+  // CHECK: store i32 0, ptr %i
   // Loop counts backward from 10 to 1, loop-exit value should be 0.
 }
 
 void test_pointer_tile(void) {
+  // CHECK-LABEL: define {{.*}} @test_pointer_tile
   int arr[20];
   int *p;
   #pragma omp tile sizes(5)
   for (p = arr; p < arr + 20; p++) {
     *p = 0;
   }
+  // CHECK: for.end{{.*}}:
+  // CHECK: [[START:%.*]] = load ptr, ptr %.capture_expr.
+  // CHECK: [[END:%.*]] = load ptr, ptr %.capture_expr.{{[0-9]+}}
+  // CHECK: [[STARTDUP:%.*]] = load ptr, ptr %.capture_expr.
+  // CHECK: [[STARTCAST:%.*]] = ptrtoaddr ptr [[END]] to i64
+  // CHECK: [[ENDCAST:%.*]] = ptrtoaddr ptr [[STARTDUP]] to i64
+  // CHECK: [[DIFF:%.*]] = sub i64 [[STARTCAST]], [[ENDCAST]]
+  // CHECK: [[NUMELEM:%.*]] = sdiv exact i64 [[DIFF]], 4
+  // CHECK: [[SUB:%.*]] = sub nsw i64 [[NUMELEM]], 1
+  // CHECK: [[ADD:%.*]] = add nsw i64 [[SUB]], 1
+  // CHECK: [[DIV:%.*]] = sdiv i64 [[ADD]], 1
+  // CHECK: [[OFFSET:%.*]] = mul nsw i64 [[DIV]], 1
+  // CHECK: [[FINALPTR:%.*]] = getelementptr inbounds i32, ptr [[START]], i64 [[OFFSET]]
+  // CHECK: store ptr [[FINALPTR]], ptr %p
   // After loop: p should point to arr + 20 (loop-exit value)
 }
 
 void test_pointer_reverse(void) {
+  // CHECK-LABEL: define {{.*}} @test_pointer_reverse
   int arr[15];
   int *q;
   #pragma omp reverse
   for (q = arr; q < arr + 15; q++) {
     *q = 1;
   }
+  // CHECK: for.end{{.*}}:
+  // CHECK: load ptr, ptr %.capture_expr.
+  // CHECK: load ptr, ptr %.capture_expr.{{[0-9]+}}
+  // CHECK: ptrtoaddr ptr
+  // CHECK: ptrtoaddr ptr
+  // CHECK: sub i64
+  // CHECK: sdiv exact i64
+  // CHECK: mul nsw i64 {{.*}}, 1
+  // CHECK: [[FINALPTR:%.*]] = getelementptr inbounds i32, ptr {{.*}}, i64
+  // CHECK: store ptr [[FINALPTR]], ptr %q
   // After loop: q should point to arr + 15 (loop-exit value)
 }
 
 void test_pointer_step(void) {
+  // CHECK-LABEL: define {{.*}} @test_pointer_step
   char buffer[30];
   char *ptr;
   #pragma omp tile sizes(4)
   for (ptr = buffer; ptr < buffer + 30; ptr += 2) {
     *ptr = 'x';
   }
+  // CHECK: for.end{{.*}}:
+  // CHECK: load ptr, ptr %.capture_expr.
+  // CHECK: load ptr, ptr %.capture_expr.{{[0-9]+}}
+  // CHECK: ptrtoaddr ptr
+  // CHECK: ptrtoaddr ptr
+  // CHECK: sub i64
+  // CHECK: mul nsw i64 {{.*}}, 2
+  // CHECK: [[FINALPTR:%.*]] = getelementptr inbounds i8, ptr {{.*}}, i64
+  // CHECK: store ptr [[FINALPTR]], ptr %ptr
   // After loop: ptr should point to buffer + 30 (loop-exit value)
 }
 
 void test_pointer_fuse(void) {
+  // CHECK-LABEL: define {{.*}} @test_pointer_fuse
   int arr1[10];
   int arr2[15];
   int *p;
@@ -152,1245 +208,19 @@ void test_pointer_fuse(void) {
       *q = 1;
     }
   }
+  // CHECK: for.end{{.*}}:
+  // Finalization for p (first fused loop)
+  // CHECK: load ptr, ptr %.capture_expr.
+  // CHECK: ptrtoaddr ptr
+  // CHECK: ptrtoaddr ptr
+  // CHECK: sub i64
+  // CHECK: sdiv exact i64
+  // CHECK: mul nsw i64 {{.*}}, 1
+  // CHECK: [[P_FINAL:%.*]] = getelementptr inbounds i32, ptr {{.*}}, i64
+  // CHECK: store ptr [[P_FINAL]], ptr %p
+  // Finalization for q (second fused loop)
+  // CHECK: mul nsw i64 {{.*}}, 1
+  // CHECK: [[Q_FINAL:%.*]] = getelementptr inbounds i32, ptr {{.*}}, i64
+  // CHECK: store ptr [[Q_FINAL]], ptr %q
   // After fuse: p should point to arr1 + 10, q should point to arr2 + 15
 }
-// CHECK-LABEL: define dso_local void @test_tile(
-// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    store i32 1, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND:.*]]
-// CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
-// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END9:.*]]
-// CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND1:.*]]
-// CHECK:       [[FOR_COND1]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 2
-// CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 10, [[ADD]]
-// CHECK-NEXT:    br i1 [[CMP2]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
-// CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    br label %[[COND_END:.*]]
-// CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP4]], 2
-// CHECK-NEXT:    br label %[[COND_END]]
-// CHECK:       [[COND_END]]:
-// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 10, %[[COND_TRUE]] ], [ [[ADD3]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP2]], [[COND]]
-// CHECK-NEXT:    br i1 [[CMP4]], label %[[FOR_BODY5:.*]], label %[[FOR_END:.*]]
-// CHECK:       [[FOR_BODY5]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP5]], 1
-// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 1, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_INC:.*]]
-// CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP2:![0-9]+]]
-// CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    br label %[[FOR_INC7:.*]]
-// CHECK:       [[FOR_INC7]]:
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP7]], 2
-// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
-// CHECK:       [[FOR_END9]]:
-// CHECK-NEXT:    store i32 11, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define dso_local void @test_stripe(
-// CHECK-SAME: ) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTSTRIPE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND:.*]]
-// CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
-// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END9:.*]]
-// CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND1:.*]]
-// CHECK:       [[FOR_COND1]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 3
-// CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 10, [[ADD]]
-// CHECK-NEXT:    br i1 [[CMP2]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
-// CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    br label %[[COND_END:.*]]
-// CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP4]], 3
-// CHECK-NEXT:    br label %[[COND_END]]
-// CHECK:       [[COND_END]]:
-// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 10, %[[COND_TRUE]] ], [ [[ADD3]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP2]], [[COND]]
-// CHECK-NEXT:    br i1 [[CMP4]], label %[[FOR_BODY5:.*]], label %[[FOR_END:.*]]
-// CHECK:       [[FOR_BODY5]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP5]], 1
-// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_INC:.*]]
-// CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP5:![0-9]+]]
-// CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    br label %[[FOR_INC7:.*]]
-// CHECK:       [[FOR_INC7]]:
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP7]], 3
-// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
-// CHECK:       [[FOR_END9]]:
-// CHECK-NEXT:    store i32 10, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define dso_local void @test_tile_nested(
-// CHECK-SAME: ) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[J:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTFLOOR_1_IV_J:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTTILE_1_IV_J:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[J]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND:.*]]
-// CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
-// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END30:.*]]
-// CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_1_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND1:.*]]
-// CHECK:       [[FOR_COND1]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[TMP1]], 5
-// CHECK-NEXT:    br i1 [[CMP2]], label %[[FOR_BODY3:.*]], label %[[FOR_END27:.*]]
-// CHECK:       [[FOR_BODY3]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 [[TMP2]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND4:.*]]
-// CHECK:       [[FOR_COND4]]:
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP4]], 2
-// CHECK-NEXT:    [[CMP5:%.*]] = icmp slt i32 10, [[ADD]]
-// CHECK-NEXT:    br i1 [[CMP5]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
-// CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    br label %[[COND_END:.*]]
-// CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP5]], 2
-// CHECK-NEXT:    br label %[[COND_END]]
-// CHECK:       [[COND_END]]:
-// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 10, %[[COND_TRUE]] ], [ [[ADD6]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    [[CMP7:%.*]] = icmp slt i32 [[TMP3]], [[COND]]
-// CHECK-NEXT:    br i1 [[CMP7]], label %[[FOR_BODY8:.*]], label %[[FOR_END24:.*]]
-// CHECK:       [[FOR_BODY8]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP6]], 1
-// CHECK-NEXT:    [[ADD9:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD9]], ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 [[TMP7]], ptr [[DOTTILE_1_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND10:.*]]
-// CHECK:       [[FOR_COND10]]:
-// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTTILE_1_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD11:%.*]] = add nsw i32 [[TMP9]], 3
-// CHECK-NEXT:    [[CMP12:%.*]] = icmp slt i32 5, [[ADD11]]
-// CHECK-NEXT:    br i1 [[CMP12]], label %[[COND_TRUE13:.*]], label %[[COND_FALSE14:.*]]
-// CHECK:       [[COND_TRUE13]]:
-// CHECK-NEXT:    br label %[[COND_END16:.*]]
-// CHECK:       [[COND_FALSE14]]:
-// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD15:%.*]] = add nsw i32 [[TMP10]], 3
-// CHECK-NEXT:    br label %[[COND_END16]]
-// CHECK:       [[COND_END16]]:
-// CHECK-NEXT:    [[COND17:%.*]] = phi i32 [ 5, %[[COND_TRUE13]] ], [ [[ADD15]], %[[COND_FALSE14]] ]
-// CHECK-NEXT:    [[CMP18:%.*]] = icmp slt i32 [[TMP8]], [[COND17]]
-// CHECK-NEXT:    br i1 [[CMP18]], label %[[FOR_BODY19:.*]], label %[[FOR_END:.*]]
-// CHECK:       [[FOR_BODY19]]:
-// CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTTILE_1_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL20:%.*]] = mul nsw i32 [[TMP11]], 1
-// CHECK-NEXT:    [[ADD21:%.*]] = add nsw i32 0, [[MUL20]]
-// CHECK-NEXT:    store i32 [[ADD21]], ptr [[J]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_INC:.*]]
-// CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTTILE_1_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP12]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_1_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND10]], !llvm.loop [[LOOP7:![0-9]+]]
-// CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    br label %[[FOR_INC22:.*]]
-// CHECK:       [[FOR_INC22]]:
-// CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC23:%.*]] = add nsw i32 [[TMP13]], 1
-// CHECK-NEXT:    store i32 [[INC23]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND4]], !llvm.loop [[LOOP8:![0-9]+]]
-// CHECK:       [[FOR_END24]]:
-// CHECK-NEXT:    br label %[[FOR_INC25:.*]]
-// CHECK:       [[FOR_INC25]]:
-// CHECK-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD26:%.*]] = add nsw i32 [[TMP14]], 3
-// CHECK-NEXT:    store i32 [[ADD26]], ptr [[DOTFLOOR_1_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP9:![0-9]+]]
-// CHECK:       [[FOR_END27]]:
-// CHECK-NEXT:    br label %[[FOR_INC28:.*]]
-// CHECK:       [[FOR_INC28]]:
-// CHECK-NEXT:    [[TMP15:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD29:%.*]] = add nsw i32 [[TMP15]], 2
-// CHECK-NEXT:    store i32 [[ADD29]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP10:![0-9]+]]
-// CHECK:       [[FOR_END30]]:
-// CHECK-NEXT:    store i32 10, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 5, ptr [[J]], {{align [0-9]+}}
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define dso_local void @test_tile_stride(
-// CHECK-SAME: ) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    store i32 5, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND:.*]]
-// CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 6
-// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END9:.*]]
-// CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND1:.*]]
-// CHECK:       [[FOR_COND1]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 4
-// CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 6, [[ADD]]
-// CHECK-NEXT:    br i1 [[CMP2]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
-// CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    br label %[[COND_END:.*]]
-// CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP4]], 4
-// CHECK-NEXT:    br label %[[COND_END]]
-// CHECK:       [[COND_END]]:
-// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 6, %[[COND_TRUE]] ], [ [[ADD3]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP2]], [[COND]]
-// CHECK-NEXT:    br i1 [[CMP4]], label %[[FOR_BODY5:.*]], label %[[FOR_END:.*]]
-// CHECK:       [[FOR_BODY5]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP5]], 2
-// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 5, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_INC:.*]]
-// CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP11:![0-9]+]]
-// CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    br label %[[FOR_INC7:.*]]
-// CHECK:       [[FOR_INC7]]:
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP7]], 4
-// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP12:![0-9]+]]
-// CHECK:       [[FOR_END9]]:
-// CHECK-NEXT:    store i32 17, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define dso_local void @test_tile_variable_bound(
-// CHECK-SAME: i32 noundef [[N:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[N_ADDR:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    store i32 [[N]], ptr [[N_ADDR]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[N_ADDR]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 [[TMP0]], ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[TMP1]], 0
-// CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[SUB]], 1
-// CHECK-NEXT:    [[SUB2:%.*]] = sub nsw i32 [[DIV]], 1
-// CHECK-NEXT:    store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND:.*]]
-// CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 1
-// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP2]], [[ADD]]
-// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END14:.*]]
-// CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 [[TMP4]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND3:.*]]
-// CHECK:       [[FOR_COND3]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD4:%.*]] = add nsw i32 [[TMP6]], 1
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD5:%.*]] = add nsw i32 [[TMP7]], 3
-// CHECK-NEXT:    [[CMP6:%.*]] = icmp slt i32 [[ADD4]], [[ADD5]]
-// CHECK-NEXT:    br i1 [[CMP6]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
-// CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD7:%.*]] = add nsw i32 [[TMP8]], 1
-// CHECK-NEXT:    br label %[[COND_END:.*]]
-// CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP9]], 3
-// CHECK-NEXT:    br label %[[COND_END]]
-// CHECK:       [[COND_END]]:
-// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[ADD7]], %[[COND_TRUE]] ], [ [[ADD8]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    [[CMP9:%.*]] = icmp slt i32 [[TMP5]], [[COND]]
-// CHECK-NEXT:    br i1 [[CMP9]], label %[[FOR_BODY10:.*]], label %[[FOR_END:.*]]
-// CHECK:       [[FOR_BODY10]]:
-// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1
-// CHECK-NEXT:    [[ADD11:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD11]], ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_INC:.*]]
-// CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP11]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND3]], !llvm.loop [[LOOP13:![0-9]+]]
-// CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    br label %[[FOR_INC12:.*]]
-// CHECK:       [[FOR_INC12]]:
-// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD13:%.*]] = add nsw i32 [[TMP12]], 3
-// CHECK-NEXT:    store i32 [[ADD13]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP14:![0-9]+]]
-// CHECK:       [[FOR_END14]]:
-// CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[SUB15:%.*]] = sub nsw i32 [[TMP13]], 0
-// CHECK-NEXT:    [[DIV16:%.*]] = sdiv i32 [[SUB15]], 1
-// CHECK-NEXT:    [[MUL17:%.*]] = mul nsw i32 [[DIV16]], 1
-// CHECK-NEXT:    [[ADD18:%.*]] = add nsw i32 0, [[MUL17]]
-// CHECK-NEXT:    store i32 [[ADD18]], ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define dso_local void @test_reverse(
-// CHECK-SAME: ) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTFORWARD_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTREVERSED_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[DOTFORWARD_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND:.*]]
-// CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
-// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END:.*]]
-// CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 9, [[TMP1]]
-// CHECK-NEXT:    store i32 [[SUB]], ptr [[DOTREVERSED_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTREVERSED_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], 1
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD]], ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_INC:.*]]
-// CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFORWARD_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP3]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTFORWARD_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]]
-// CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    store i32 10, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define dso_local void @test_interchange(
-// CHECK-SAME: ) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[J:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTPERMUTED_0_IV_J:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTPERMUTED_1_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[J]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[DOTPERMUTED_0_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND:.*]]
-// CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 5
-// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END8:.*]]
-// CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP1]], 1
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD]], ptr [[J]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[DOTPERMUTED_1_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND1:.*]]
-// CHECK:       [[FOR_COND1]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[TMP2]], 10
-// CHECK-NEXT:    br i1 [[CMP2]], label %[[FOR_BODY3:.*]], label %[[FOR_END:.*]]
-// CHECK:       [[FOR_BODY3]]:
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL4:%.*]] = mul nsw i32 [[TMP3]], 1
-// CHECK-NEXT:    [[ADD5:%.*]] = add nsw i32 0, [[MUL4]]
-// CHECK-NEXT:    store i32 [[ADD5]], ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_INC:.*]]
-// CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTPERMUTED_1_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP4]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTPERMUTED_1_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP16:![0-9]+]]
-// CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    br label %[[FOR_INC6:.*]]
-// CHECK:       [[FOR_INC6]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTPERMUTED_0_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC7:%.*]] = add nsw i32 [[TMP5]], 1
-// CHECK-NEXT:    store i32 [[INC7]], ptr [[DOTPERMUTED_0_IV_J]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP17:![0-9]+]]
-// CHECK:       [[FOR_END8]]:
-// CHECK-NEXT:    store i32 10, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 5, ptr [[J]], {{align [0-9]+}}
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define dso_local void @test_for_workshare(
-// CHECK-SAME: ) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[I1:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:[0-9]+]])
-// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_LB]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 2, ptr [[DOTOMP_UB]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], {{align [0-9]+}}
-// CHECK-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 2
-// CHECK-NEXT:    br i1 [[CMP]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
-// CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    br label %[[COND_END:.*]]
-// CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[COND_END]]
-// CHECK:       [[COND_END]]:
-// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 2, %[[COND_TRUE]] ], [ [[TMP2]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND:.*]]
-// CHECK:       [[OMP_INNER_FOR_COND]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]]
-// CHECK-NEXT:    br i1 [[CMP2]], label %[[OMP_INNER_FOR_BODY:.*]], label %[[OMP_INNER_FOR_END:.*]]
-// CHECK:       [[OMP_INNER_FOR_BODY]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP6]], 2
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 5, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD]], ptr [[I1]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[OMP_BODY_CONTINUE:.*]]
-// CHECK:       [[OMP_BODY_CONTINUE]]:
-// CHECK-NEXT:    br label %[[OMP_INNER_FOR_INC:.*]]
-// CHECK:       [[OMP_INNER_FOR_INC]]:
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP7]], 1
-// CHECK-NEXT:    store i32 [[ADD3]], ptr [[DOTOMP_IV]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND]]
-// CHECK:       [[OMP_INNER_FOR_END]]:
-// CHECK-NEXT:    br label %[[OMP_LOOP_EXIT:.*]]
-// CHECK:       [[OMP_LOOP_EXIT]]:
-// CHECK-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
-// CHECK-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3:[0-9]+]], i32 [[TMP0]])
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define dso_local void @test_for_lastprivate(
-// CHECK-SAME: ) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 1, ptr @test_for_lastprivate.omp_outlined, ptr [[I]])
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define internal void @test_for_lastprivate.omp_outlined(
-// CHECK-SAME: ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[I:%.*]]) #[[ATTR3:[0-9]+]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[I_ADDR:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[I1:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[I2:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], {{align [0-9]+}}
-// CHECK-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], {{align [0-9]+}}
-// CHECK-NEXT:    store ptr [[I]], ptr [[I_ADDR]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[I_ADDR]], {{align [0-9]+}}, !nonnull [[META18:![0-9]+]], !align [[META19:![0-9]+]]
-// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_LB]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 2, ptr [[DOTOMP_UB]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[TMP1]], {{align [0-9]+}}
-// CHECK-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP2]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP3]], 2
-// CHECK-NEXT:    br i1 [[CMP]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
-// CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    br label %[[COND_END:.*]]
-// CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[COND_END]]
-// CHECK:       [[COND_END]]:
-// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 2, %[[COND_TRUE]] ], [ [[TMP4]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 [[TMP5]], ptr [[DOTOMP_IV]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND:.*]]
-// CHECK:       [[OMP_INNER_FOR_COND]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP3:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]]
-// CHECK-NEXT:    br i1 [[CMP3]], label %[[OMP_INNER_FOR_BODY:.*]], label %[[OMP_INNER_FOR_END:.*]]
-// CHECK:       [[OMP_INNER_FOR_BODY]]:
-// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP8]], 2
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 5, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD]], ptr [[I1]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[OMP_BODY_CONTINUE:.*]]
-// CHECK:       [[OMP_BODY_CONTINUE]]:
-// CHECK-NEXT:    br label %[[OMP_INNER_FOR_INC:.*]]
-// CHECK:       [[OMP_INNER_FOR_INC]]:
-// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD4:%.*]] = add nsw i32 [[TMP9]], 1
-// CHECK-NEXT:    store i32 [[ADD4]], ptr [[DOTOMP_IV]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND]]
-// CHECK:       [[OMP_INNER_FOR_END]]:
-// CHECK-NEXT:    br label %[[OMP_LOOP_EXIT:.*]]
-// CHECK:       [[OMP_LOOP_EXIT]]:
-// CHECK-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]])
-// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP11:%.*]] = icmp ne i32 [[TMP10]], 0
-// CHECK-NEXT:    br i1 [[TMP11]], [[DOTOMP_LASTPRIVATE_THEN:label %.*]], [[DOTOMP_LASTPRIVATE_DONE:label %.*]]
-// CHECK:       [[_OMP_LASTPRIVATE_THEN:.*:]]
-// CHECK-NEXT:    store i32 11, ptr [[I1]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[I1]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 [[TMP12]], ptr [[TMP0]], {{align [0-9]+}}
-// CHECK-NEXT:    br [[DOTOMP_LASTPRIVATE_DONE]]
-// CHECK:       [[_OMP_LASTPRIVATE_DONE:.*:]]
-// CHECK-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP2]])
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define dso_local void @test_tile_workshare(
-// CHECK-SAME: ) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_IV:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
-// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_LB]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 4, ptr [[DOTOMP_UB]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 1, ptr [[DOTOMP_STRIDE]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[DOTOMP_IS_LAST]], {{align [0-9]+}}
-// CHECK-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP0]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP1]], 4
-// CHECK-NEXT:    br i1 [[CMP]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
-// CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    br label %[[COND_END:.*]]
-// CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[COND_END]]
-// CHECK:       [[COND_END]]:
-// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 4, %[[COND_TRUE]] ], [ [[TMP2]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    store i32 [[COND]], ptr [[DOTOMP_UB]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_LB]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 [[TMP3]], ptr [[DOTOMP_IV]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND:.*]]
-// CHECK:       [[OMP_INNER_FOR_COND]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP1:%.*]] = icmp sle i32 [[TMP4]], [[TMP5]]
-// CHECK-NEXT:    br i1 [[CMP1]], label %[[OMP_INNER_FOR_BODY:.*]], label %[[OMP_INNER_FOR_END:.*]]
-// CHECK:       [[OMP_INNER_FOR_BODY]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP6]], 2
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 0, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 [[TMP7]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND:.*]]
-// CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD2:%.*]] = add nsw i32 [[TMP9]], 2
-// CHECK-NEXT:    [[CMP3:%.*]] = icmp slt i32 10, [[ADD2]]
-// CHECK-NEXT:    br i1 [[CMP3]], label %[[COND_TRUE4:.*]], label %[[COND_FALSE5:.*]]
-// CHECK:       [[COND_TRUE4]]:
-// CHECK-NEXT:    br label %[[COND_END7:.*]]
-// CHECK:       [[COND_FALSE5]]:
-// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP10]], 2
-// CHECK-NEXT:    br label %[[COND_END7]]
-// CHECK:       [[COND_END7]]:
-// CHECK-NEXT:    [[COND8:%.*]] = phi i32 [ 10, %[[COND_TRUE4]] ], [ [[ADD6]], %[[COND_FALSE5]] ]
-// CHECK-NEXT:    [[CMP9:%.*]] = icmp slt i32 [[TMP8]], [[COND8]]
-// CHECK-NEXT:    br i1 [[CMP9]], label %[[FOR_BODY:.*]], label %[[FOR_END:.*]]
-// CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL10:%.*]] = mul nsw i32 [[TMP11]], 1
-// CHECK-NEXT:    [[ADD11:%.*]] = add nsw i32 1, [[MUL10]]
-// CHECK-NEXT:    store i32 [[ADD11]], ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_INC:.*]]
-// CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP12]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP22:![0-9]+]]
-// CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    br label %[[OMP_BODY_CONTINUE:.*]]
-// CHECK:       [[OMP_BODY_CONTINUE]]:
-// CHECK-NEXT:    br label %[[OMP_INNER_FOR_INC:.*]]
-// CHECK:       [[OMP_INNER_FOR_INC]]:
-// CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD12:%.*]] = add nsw i32 [[TMP13]], 1
-// CHECK-NEXT:    store i32 [[ADD12]], ptr [[DOTOMP_IV]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[OMP_INNER_FOR_COND]]
-// CHECK:       [[OMP_INNER_FOR_END]]:
-// CHECK-NEXT:    br label %[[OMP_LOOP_EXIT:.*]]
-// CHECK:       [[OMP_LOOP_EXIT]]:
-// CHECK-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP0]])
-// CHECK-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[TMP0]])
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define dso_local void @test_tile_zero_tripcount(
-// CHECK-SAME: ) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTTILE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    store i32 10, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND:.*]]
-// CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], -5
-// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END9:.*]]
-// CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND1:.*]]
-// CHECK:       [[FOR_COND1]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 2
-// CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 -5, [[ADD]]
-// CHECK-NEXT:    br i1 [[CMP2]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
-// CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    br label %[[COND_END:.*]]
-// CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP4]], 2
-// CHECK-NEXT:    br label %[[COND_END]]
-// CHECK:       [[COND_END]]:
-// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ -5, %[[COND_TRUE]] ], [ [[ADD3]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP2]], [[COND]]
-// CHECK-NEXT:    br i1 [[CMP4]], label %[[FOR_BODY5:.*]], label %[[FOR_END:.*]]
-// CHECK:       [[FOR_BODY5]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP5]], 1
-// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 10, [[MUL]]
-// CHECK-NEXT:    store i32 [[ADD6]], ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_INC:.*]]
-// CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP23:![0-9]+]]
-// CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    br label %[[FOR_INC7:.*]]
-// CHECK:       [[FOR_INC7]]:
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP7]], 2
-// CHECK-NEXT:    store i32 [[ADD8]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]]
-// CHECK:       [[FOR_END9]]:
-// CHECK-NEXT:    store i32 5, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define dso_local void @test_stripe_negative_step(
-// CHECK-SAME: ) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTSTRIPE_0_IV_I:%.*]] = alloca i32, {{align [0-9]+}}
-// CHECK-NEXT:    store i32 10, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND:.*]]
-// CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
-// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END8:.*]]
-// CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 [[TMP1]], ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND1:.*]]
-// CHECK:       [[FOR_COND1]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 3
-// CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 10, [[ADD]]
-// CHECK-NEXT:    br i1 [[CMP2]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
-// CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    br label %[[COND_END:.*]]
-// CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP4]], 3
-// CHECK-NEXT:    br label %[[COND_END]]
-// CHECK:       [[COND_END]]:
-// CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 10, %[[COND_TRUE]] ], [ [[ADD3]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[TMP2]], [[COND]]
-// CHECK-NEXT:    br i1 [[CMP4]], label %[[FOR_BODY5:.*]], label %[[FOR_END:.*]]
-// CHECK:       [[FOR_BODY5]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP5]], 1
-// CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 10, [[MUL]]
-// CHECK-NEXT:    store i32 [[SUB]], ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_INC:.*]]
-// CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
-// CHECK-NEXT:    store i32 [[INC]], ptr [[DOTSTRIPE_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND1]], !llvm.loop [[LOOP25:![0-9]+]]
-// CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    br label %[[FOR_INC6:.*]]
-// CHECK:       [[FOR_INC6]]:
-// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD7:%.*]] = add nsw i32 [[TMP7]], 3
-// CHECK-NEXT:    store i32 [[ADD7]], ptr [[DOTFLOOR_0_IV_I]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]]
-// CHECK:       [[FOR_END8]]:
-// CHECK-NEXT:    store i32 0, ptr [[I]], {{align [0-9]+}}
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define dso_local void @test_pointer_tile(
-// CHECK-SAME: ) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[ARR:%.*]] = alloca [20 x i32], {{align [0-9]+}}
-// CHECK-NEXT:    [[P:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_P:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTTILE_0_IV_P:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [20 x i32], ptr [[ARR]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[P]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [20 x i32], ptr [[ARR]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [20 x i32], ptr [[ARR]], i64 0, i64 0
-// CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY3]], i64 20
-// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP0]] to i64
-// CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP1]] to i64
-// CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
-// CHECK-NEXT:    [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 4
-// CHECK-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
-// CHECK-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
-// CHECK-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
-// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
-// CHECK-NEXT:    store i64 0, ptr [[DOTFLOOR_0_IV_P]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND:.*]]
-// CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP3]], 1
-// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[TMP2]], [[ADD6]]
-// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END18:.*]]
-// CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], {{align [0-9]+}}
-// CHECK-NEXT:    store i64 [[TMP4]], ptr [[DOTTILE_0_IV_P]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND7:.*]]
-// CHECK:       [[FOR_COND7]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTTILE_0_IV_P]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD8:%.*]] = add nsw i64 [[TMP6]], 1
-// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD9:%.*]] = add nsw i64 [[TMP7]], 5
-// CHECK-NEXT:    [[CMP10:%.*]] = icmp slt i64 [[ADD8]], [[ADD9]]
-// CHECK-NEXT:    br i1 [[CMP10]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
-// CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD11:%.*]] = add nsw i64 [[TMP8]], 1
-// CHECK-NEXT:    br label %[[COND_END:.*]]
-// CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD12:%.*]] = add nsw i64 [[TMP9]], 5
-// CHECK-NEXT:    br label %[[COND_END]]
-// CHECK:       [[COND_END]]:
-// CHECK-NEXT:    [[COND:%.*]] = phi i64 [ [[ADD11]], %[[COND_TRUE]] ], [ [[ADD12]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    [[CMP13:%.*]] = icmp slt i64 [[TMP5]], [[COND]]
-// CHECK-NEXT:    br i1 [[CMP13]], label %[[FOR_BODY14:.*]], label %[[FOR_END:.*]]
-// CHECK:       [[FOR_BODY14]]:
-// CHECK-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTTILE_0_IV_P]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP11]], 1
-// CHECK-NEXT:    [[ADD_PTR15:%.*]] = getelementptr inbounds i32, ptr [[TMP10]], i64 [[MUL]]
-// CHECK-NEXT:    store ptr [[ADD_PTR15]], ptr [[P]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[P]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[TMP12]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_INC:.*]]
-// CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTTILE_0_IV_P]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP13]], 1
-// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTTILE_0_IV_P]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND7]], !llvm.loop [[LOOP27:![0-9]+]]
-// CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    br label %[[FOR_INC16:.*]]
-// CHECK:       [[FOR_INC16]]:
-// CHECK-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_P]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD17:%.*]] = add nsw i64 [[TMP14]], 5
-// CHECK-NEXT:    store i64 [[ADD17]], ptr [[DOTFLOOR_0_IV_P]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP28:![0-9]+]]
-// CHECK:       [[FOR_END18]]:
-// CHECK-NEXT:    [[TMP15:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP16:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP17:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[SUB_PTR_LHS_CAST19:%.*]] = ptrtoaddr ptr [[TMP16]] to i64
-// CHECK-NEXT:    [[SUB_PTR_RHS_CAST20:%.*]] = ptrtoaddr ptr [[TMP17]] to i64
-// CHECK-NEXT:    [[SUB_PTR_SUB21:%.*]] = sub i64 [[SUB_PTR_LHS_CAST19]], [[SUB_PTR_RHS_CAST20]]
-// CHECK-NEXT:    [[SUB_PTR_DIV22:%.*]] = sdiv exact i64 [[SUB_PTR_SUB21]], 4
-// CHECK-NEXT:    [[SUB23:%.*]] = sub nsw i64 [[SUB_PTR_DIV22]], 1
-// CHECK-NEXT:    [[ADD24:%.*]] = add nsw i64 [[SUB23]], 1
-// CHECK-NEXT:    [[DIV25:%.*]] = sdiv i64 [[ADD24]], 1
-// CHECK-NEXT:    [[MUL26:%.*]] = mul nsw i64 [[DIV25]], 1
-// CHECK-NEXT:    [[ADD_PTR27:%.*]] = getelementptr inbounds i32, ptr [[TMP15]], i64 [[MUL26]]
-// CHECK-NEXT:    store ptr [[ADD_PTR27]], ptr [[P]], {{align [0-9]+}}
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define dso_local void @test_pointer_reverse(
-// CHECK-SAME: ) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[ARR:%.*]] = alloca [15 x i32], {{align [0-9]+}}
-// CHECK-NEXT:    [[Q:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTFORWARD_IV_Q:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTREVERSED_IV_Q:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[Q]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR]], i64 0, i64 0
-// CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY3]], i64 15
-// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP0]] to i64
-// CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP1]] to i64
-// CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
-// CHECK-NEXT:    [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 4
-// CHECK-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
-// CHECK-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
-// CHECK-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
-// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
-// CHECK-NEXT:    store i64 0, ptr [[DOTFORWARD_IV_Q]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND:.*]]
-// CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTFORWARD_IV_Q]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP3]], 1
-// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[TMP2]], [[ADD6]]
-// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END:.*]]
-// CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD7:%.*]] = add nsw i64 [[TMP4]], 1
-// CHECK-NEXT:    [[SUB8:%.*]] = sub nsw i64 [[ADD7]], 1
-// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTFORWARD_IV_Q]], {{align [0-9]+}}
-// CHECK-NEXT:    [[SUB9:%.*]] = sub nsw i64 [[SUB8]], [[TMP5]]
-// CHECK-NEXT:    store i64 [[SUB9]], ptr [[DOTREVERSED_IV_Q]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP6:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTREVERSED_IV_Q]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP7]], 1
-// CHECK-NEXT:    [[ADD_PTR10:%.*]] = getelementptr inbounds i32, ptr [[TMP6]], i64 [[MUL]]
-// CHECK-NEXT:    store ptr [[ADD_PTR10]], ptr [[Q]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP8:%.*]] = load ptr, ptr [[Q]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 1, ptr [[TMP8]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_INC:.*]]
-// CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFORWARD_IV_Q]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP9]], 1
-// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTFORWARD_IV_Q]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP29:![0-9]+]]
-// CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP11:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[SUB_PTR_LHS_CAST11:%.*]] = ptrtoaddr ptr [[TMP11]] to i64
-// CHECK-NEXT:    [[SUB_PTR_RHS_CAST12:%.*]] = ptrtoaddr ptr [[TMP12]] to i64
-// CHECK-NEXT:    [[SUB_PTR_SUB13:%.*]] = sub i64 [[SUB_PTR_LHS_CAST11]], [[SUB_PTR_RHS_CAST12]]
-// CHECK-NEXT:    [[SUB_PTR_DIV14:%.*]] = sdiv exact i64 [[SUB_PTR_SUB13]], 4
-// CHECK-NEXT:    [[SUB15:%.*]] = sub nsw i64 [[SUB_PTR_DIV14]], 1
-// CHECK-NEXT:    [[ADD16:%.*]] = add nsw i64 [[SUB15]], 1
-// CHECK-NEXT:    [[DIV17:%.*]] = sdiv i64 [[ADD16]], 1
-// CHECK-NEXT:    [[MUL18:%.*]] = mul nsw i64 [[DIV17]], 1
-// CHECK-NEXT:    [[ADD_PTR19:%.*]] = getelementptr inbounds i32, ptr [[TMP10]], i64 [[MUL18]]
-// CHECK-NEXT:    store ptr [[ADD_PTR19]], ptr [[Q]], {{align [0-9]+}}
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define dso_local void @test_pointer_step(
-// CHECK-SAME: ) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[BUFFER:%.*]] = alloca [30 x i8], {{align [0-9]+}}
-// CHECK-NEXT:    [[PTR:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTFLOOR_0_IV_PTR:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTTILE_0_IV_PTR:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [30 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [30 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [30 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[ARRAYDECAY3]], i64 30
-// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP0]] to i64
-// CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP1]] to i64
-// CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
-// CHECK-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_SUB]], 1
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 2
-// CHECK-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 2
-// CHECK-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
-// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
-// CHECK-NEXT:    store i64 0, ptr [[DOTFLOOR_0_IV_PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND:.*]]
-// CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP3]], 1
-// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[TMP2]], [[ADD6]]
-// CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_END18:.*]]
-// CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP4:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    store i64 [[TMP4]], ptr [[DOTTILE_0_IV_PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND7:.*]]
-// CHECK:       [[FOR_COND7]]:
-// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTTILE_0_IV_PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD8:%.*]] = add nsw i64 [[TMP6]], 1
-// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD9:%.*]] = add nsw i64 [[TMP7]], 4
-// CHECK-NEXT:    [[CMP10:%.*]] = icmp slt i64 [[ADD8]], [[ADD9]]
-// CHECK-NEXT:    br i1 [[CMP10]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
-// CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD11:%.*]] = add nsw i64 [[TMP8]], 1
-// CHECK-NEXT:    br label %[[COND_END:.*]]
-// CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD12:%.*]] = add nsw i64 [[TMP9]], 4
-// CHECK-NEXT:    br label %[[COND_END]]
-// CHECK:       [[COND_END]]:
-// CHECK-NEXT:    [[COND:%.*]] = phi i64 [ [[ADD11]], %[[COND_TRUE]] ], [ [[ADD12]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    [[CMP13:%.*]] = icmp slt i64 [[TMP5]], [[COND]]
-// CHECK-NEXT:    br i1 [[CMP13]], label %[[FOR_BODY14:.*]], label %[[FOR_END:.*]]
-// CHECK:       [[FOR_BODY14]]:
-// CHECK-NEXT:    [[TMP10:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTTILE_0_IV_PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP11]], 2
-// CHECK-NEXT:    [[ADD_PTR15:%.*]] = getelementptr inbounds i8, ptr [[TMP10]], i64 [[MUL]]
-// CHECK-NEXT:    store ptr [[ADD_PTR15]], ptr [[PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP12:%.*]] = load ptr, ptr [[PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    store i8 120, ptr [[TMP12]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_INC:.*]]
-// CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTTILE_0_IV_PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP13]], 1
-// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTTILE_0_IV_PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND7]], !llvm.loop [[LOOP30:![0-9]+]]
-// CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    br label %[[FOR_INC16:.*]]
-// CHECK:       [[FOR_INC16]]:
-// CHECK-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTFLOOR_0_IV_PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD17:%.*]] = add nsw i64 [[TMP14]], 4
-// CHECK-NEXT:    store i64 [[ADD17]], ptr [[DOTFLOOR_0_IV_PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP31:![0-9]+]]
-// CHECK:       [[FOR_END18]]:
-// CHECK-NEXT:    [[TMP15:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP16:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP17:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[SUB_PTR_LHS_CAST19:%.*]] = ptrtoaddr ptr [[TMP16]] to i64
-// CHECK-NEXT:    [[SUB_PTR_RHS_CAST20:%.*]] = ptrtoaddr ptr [[TMP17]] to i64
-// CHECK-NEXT:    [[SUB_PTR_SUB21:%.*]] = sub i64 [[SUB_PTR_LHS_CAST19]], [[SUB_PTR_RHS_CAST20]]
-// CHECK-NEXT:    [[SUB22:%.*]] = sub nsw i64 [[SUB_PTR_SUB21]], 1
-// CHECK-NEXT:    [[ADD23:%.*]] = add nsw i64 [[SUB22]], 2
-// CHECK-NEXT:    [[DIV24:%.*]] = sdiv i64 [[ADD23]], 2
-// CHECK-NEXT:    [[MUL25:%.*]] = mul nsw i64 [[DIV24]], 2
-// CHECK-NEXT:    [[ADD_PTR26:%.*]] = getelementptr inbounds i8, ptr [[TMP15]], i64 [[MUL25]]
-// CHECK-NEXT:    store ptr [[ADD_PTR26]], ptr [[PTR]], {{align [0-9]+}}
-// CHECK-NEXT:    ret void
-//
-//
-// CHECK-LABEL: define dso_local void @test_pointer_fuse(
-// CHECK-SAME: ) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[ARR1:%.*]] = alloca [10 x i32], {{align [0-9]+}}
-// CHECK-NEXT:    [[ARR2:%.*]] = alloca [15 x i32], {{align [0-9]+}}
-// CHECK-NEXT:    [[P:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[Q:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_2:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_LB0:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_ST0:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_NI0:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_IV0:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_8:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_10:%.*]] = alloca ptr, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTCAPTURE_EXPR_13:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_LB1:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_ST1:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_NI1:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_IV1:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_TEMP_1:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_FUSE_MAX:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[DOTOMP_FUSE_INDEX:%.*]] = alloca i64, {{align [0-9]+}}
-// CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARR1]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[P]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARR1]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY1]], ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARR1]], i64 0, i64 0
-// CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY3]], i64 10
-// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoaddr ptr [[TMP0]] to i64
-// CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoaddr ptr [[TMP1]] to i64
-// CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
-// CHECK-NEXT:    [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 4
-// CHECK-NEXT:    [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1
-// CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SUB]], 1
-// CHECK-NEXT:    [[DIV:%.*]] = sdiv i64 [[ADD]], 1
-// CHECK-NEXT:    [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1
-// CHECK-NEXT:    store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
-// CHECK-NEXT:    store i64 0, ptr [[DOTOMP_LB0]], {{align [0-9]+}}
-// CHECK-NEXT:    store i64 1, ptr [[DOTOMP_ST0]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD6:%.*]] = add nsw i64 [[TMP2]], 1
-// CHECK-NEXT:    store i64 [[ADD6]], ptr [[DOTOMP_NI0]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ARRAYDECAY7:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR2]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY7]], ptr [[Q]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ARRAYDECAY9:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR2]], i64 0, i64 0
-// CHECK-NEXT:    store ptr [[ARRAYDECAY9]], ptr [[DOTCAPTURE_EXPR_8]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ARRAYDECAY11:%.*]] = getelementptr inbounds [15 x i32], ptr [[ARR2]], i64 0, i64 0
-// CHECK-NEXT:    [[ADD_PTR12:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY11]], i64 15
-// CHECK-NEXT:    store ptr [[ADD_PTR12]], ptr [[DOTCAPTURE_EXPR_10]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_10]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], {{align [0-9]+}}
-// CHECK-NEXT:    [[SUB_PTR_LHS_CAST14:%.*]] = ptrtoaddr ptr [[TMP3]] to i64
-// CHECK-NEXT:    [[SUB_PTR_RHS_CAST15:%.*]] = ptrtoaddr ptr [[TMP4]] to i64
-// CHECK-NEXT:    [[SUB_PTR_SUB16:%.*]] = sub i64 [[SUB_PTR_LHS_CAST14]], [[SUB_PTR_RHS_CAST15]]
-// CHECK-NEXT:    [[SUB_PTR_DIV17:%.*]] = sdiv exact i64 [[SUB_PTR_SUB16]], 4
-// CHECK-NEXT:    [[SUB18:%.*]] = sub nsw i64 [[SUB_PTR_DIV17]], 1
-// CHECK-NEXT:    [[ADD19:%.*]] = add nsw i64 [[SUB18]], 1
-// CHECK-NEXT:    [[DIV20:%.*]] = sdiv i64 [[ADD19]], 1
-// CHECK-NEXT:    [[SUB21:%.*]] = sub nsw i64 [[DIV20]], 1
-// CHECK-NEXT:    store i64 [[SUB21]], ptr [[DOTCAPTURE_EXPR_13]], {{align [0-9]+}}
-// CHECK-NEXT:    store i64 0, ptr [[DOTOMP_LB1]], {{align [0-9]+}}
-// CHECK-NEXT:    store i64 1, ptr [[DOTOMP_ST1]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP5:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_13]], {{align [0-9]+}}
-// CHECK-NEXT:    [[ADD22:%.*]] = add nsw i64 [[TMP5]], 1
-// CHECK-NEXT:    store i64 [[ADD22]], ptr [[DOTOMP_NI1]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[DOTOMP_NI0]], {{align [0-9]+}}
-// CHECK-NEXT:    store i64 [[TMP6]], ptr [[DOTOMP_TEMP_1]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[DOTOMP_TEMP_1]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[DOTOMP_NI1]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i64 [[TMP7]], [[TMP8]]
-// CHECK-NEXT:    br i1 [[CMP]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
-// CHECK:       [[COND_TRUE]]:
-// CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[DOTOMP_TEMP_1]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[COND_END:.*]]
-// CHECK:       [[COND_FALSE]]:
-// CHECK-NEXT:    [[TMP10:%.*]] = load i64, ptr [[DOTOMP_NI1]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[COND_END]]
-// CHECK:       [[COND_END]]:
-// CHECK-NEXT:    [[COND:%.*]] = phi i64 [ [[TMP9]], %[[COND_TRUE]] ], [ [[TMP10]], %[[COND_FALSE]] ]
-// CHECK-NEXT:    store i64 [[COND]], ptr [[DOTOMP_FUSE_MAX]], {{align [0-9]+}}
-// CHECK-NEXT:    store i64 0, ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND:.*]]
-// CHECK:       [[FOR_COND]]:
-// CHECK-NEXT:    [[TMP11:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP12:%.*]] = load i64, ptr [[DOTOMP_FUSE_MAX]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP23:%.*]] = icmp slt i64 [[TMP11]], [[TMP12]]
-// CHECK-NEXT:    br i1 [[CMP23]], label %[[FOR_BODY:.*]], label %[[FOR_END:.*]]
-// CHECK:       [[FOR_BODY]]:
-// CHECK-NEXT:    [[TMP13:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP14:%.*]] = load i64, ptr [[DOTOMP_NI0]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP24:%.*]] = icmp slt i64 [[TMP13]], [[TMP14]]
-// CHECK-NEXT:    br i1 [[CMP24]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
-// CHECK:       [[IF_THEN]]:
-// CHECK-NEXT:    [[TMP15:%.*]] = load i64, ptr [[DOTOMP_LB0]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP16:%.*]] = load i64, ptr [[DOTOMP_ST0]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP17:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL:%.*]] = mul nsw i64 [[TMP16]], [[TMP17]]
-// CHECK-NEXT:    [[ADD25:%.*]] = add nsw i64 [[TMP15]], [[MUL]]
-// CHECK-NEXT:    store i64 [[ADD25]], ptr [[DOTOMP_IV0]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP19:%.*]] = load i64, ptr [[DOTOMP_IV0]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL26:%.*]] = mul nsw i64 [[TMP19]], 1
-// CHECK-NEXT:    [[ADD_PTR27:%.*]] = getelementptr inbounds i32, ptr [[TMP18]], i64 [[MUL26]]
-// CHECK-NEXT:    store ptr [[ADD_PTR27]], ptr [[P]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP20:%.*]] = load ptr, ptr [[P]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 0, ptr [[TMP20]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[IF_END]]
-// CHECK:       [[IF_END]]:
-// CHECK-NEXT:    [[TMP21:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP22:%.*]] = load i64, ptr [[DOTOMP_NI1]], {{align [0-9]+}}
-// CHECK-NEXT:    [[CMP28:%.*]] = icmp slt i64 [[TMP21]], [[TMP22]]
-// CHECK-NEXT:    br i1 [[CMP28]], label %[[IF_THEN29:.*]], label %[[IF_END34:.*]]
-// CHECK:       [[IF_THEN29]]:
-// CHECK-NEXT:    [[TMP23:%.*]] = load i64, ptr [[DOTOMP_LB1]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP24:%.*]] = load i64, ptr [[DOTOMP_ST1]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP25:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL30:%.*]] = mul nsw i64 [[TMP24]], [[TMP25]]
-// CHECK-NEXT:    [[ADD31:%.*]] = add nsw i64 [[TMP23]], [[MUL30]]
-// CHECK-NEXT:    store i64 [[ADD31]], ptr [[DOTOMP_IV1]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP26:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP27:%.*]] = load i64, ptr [[DOTOMP_IV1]], {{align [0-9]+}}
-// CHECK-NEXT:    [[MUL32:%.*]] = mul nsw i64 [[TMP27]], 1
-// CHECK-NEXT:    [[ADD_PTR33:%.*]] = getelementptr inbounds i32, ptr [[TMP26]], i64 [[MUL32]]
-// CHECK-NEXT:    store ptr [[ADD_PTR33]], ptr [[Q]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP28:%.*]] = load ptr, ptr [[Q]], {{align [0-9]+}}
-// CHECK-NEXT:    store i32 1, ptr [[TMP28]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[IF_END34]]
-// CHECK:       [[IF_END34]]:
-// CHECK-NEXT:    br label %[[FOR_INC:.*]]
-// CHECK:       [[FOR_INC]]:
-// CHECK-NEXT:    [[TMP29:%.*]] = load i64, ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
-// CHECK-NEXT:    [[INC:%.*]] = add nsw i64 [[TMP29]], 1
-// CHECK-NEXT:    store i64 [[INC]], ptr [[DOTOMP_FUSE_INDEX]], {{align [0-9]+}}
-// CHECK-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP32:![0-9]+]]
-// CHECK:       [[FOR_END]]:
-// CHECK-NEXT:    [[TMP30:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP31:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_2]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP32:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], {{align [0-9]+}}
-// CHECK-NEXT:    [[SUB_PTR_LHS_CAST35:%.*]] = ptrtoaddr ptr [[TMP31]] to i64
-// CHECK-NEXT:    [[SUB_PTR_RHS_CAST36:%.*]] = ptrtoaddr ptr [[TMP32]] to i64
-// CHECK-NEXT:    [[SUB_PTR_SUB37:%.*]] = sub i64 [[SUB_PTR_LHS_CAST35]], [[SUB_PTR_RHS_CAST36]]
-// CHECK-NEXT:    [[SUB_PTR_DIV38:%.*]] = sdiv exact i64 [[SUB_PTR_SUB37]], 4
-// CHECK-NEXT:    [[SUB39:%.*]] = sub nsw i64 [[SUB_PTR_DIV38]], 1
-// CHECK-NEXT:    [[ADD40:%.*]] = add nsw i64 [[SUB39]], 1
-// CHECK-NEXT:    [[DIV41:%.*]] = sdiv i64 [[ADD40]], 1
-// CHECK-NEXT:    [[MUL42:%.*]] = mul nsw i64 [[DIV41]], 1
-// CHECK-NEXT:    [[ADD_PTR43:%.*]] = getelementptr inbounds i32, ptr [[TMP30]], i64 [[MUL42]]
-// CHECK-NEXT:    store ptr [[ADD_PTR43]], ptr [[P]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP33:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP34:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_10]], {{align [0-9]+}}
-// CHECK-NEXT:    [[TMP35:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_8]], {{align [0-9]+}}
-// CHECK-NEXT:    [[SUB_PTR_LHS_CAST44:%.*]] = ptrtoaddr ptr [[TMP34]] to i64
-// CHECK-NEXT:    [[SUB_PTR_RHS_CAST45:%.*]] = ptrtoaddr ptr [[TMP35]] to i64
-// CHECK-NEXT:    [[SUB_PTR_SUB46:%.*]] = sub i64 [[SUB_PTR_LHS_CAST44]], [[SUB_PTR_RHS_CAST45]]
-// CHECK-NEXT:    [[SUB_PTR_DIV47:%.*]] = sdiv exact i64 [[SUB_PTR_SUB46]], 4
-// CHECK-NEXT:    [[SUB48:%.*]] = sub nsw i64 [[SUB_PTR_DIV47]], 1
-// CHECK-NEXT:    [[ADD49:%.*]] = add nsw i64 [[SUB48]], 1
-// CHECK-NEXT:    [[DIV50:%.*]] = sdiv i64 [[ADD49]], 1
-// CHECK-NEXT:    [[MUL51:%.*]] = mul nsw i64 [[DIV50]], 1
-// CHECK-NEXT:    [[ADD_PTR52:%.*]] = getelementptr inbounds i32, ptr [[TMP33]], i64 [[MUL51]]
-// CHECK-NEXT:    store ptr [[ADD_PTR52]], ptr [[Q]], {{align [0-9]+}}
-// CHECK-NEXT:    ret void
-//
-//.
-// CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[META3:![0-9]+]]}
-// CHECK: [[META3]] = !{!"llvm.loop.mustprogress"}
-// CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META3]]}
-// CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META3]]}
-// CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META3]]}
-// CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META3]]}
-// CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META3]]}
-// CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META3]]}
-// CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META3]]}
-// CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[META3]]}
-// CHECK: [[LOOP12]] = distinct !{[[LOOP12]], [[META3]]}
-// CHECK: [[LOOP13]] = distinct !{[[LOOP13]], [[META3]]}
-// CHECK: [[LOOP14]] = distinct !{[[LOOP14]], [[META3]]}
-// CHECK: [[LOOP15]] = distinct !{[[LOOP15]], [[META3]]}
-// CHECK: [[LOOP16]] = distinct !{[[LOOP16]], [[META3]]}
-// CHECK: [[LOOP17]] = distinct !{[[LOOP17]], [[META3]]}
-// CHECK: [[META18]] = !{}
-// CHECK: [[META19]] = !{i64 4}
-// CHECK: [[LOOP22]] = distinct !{[[LOOP22]], [[META3]]}
-// CHECK: [[LOOP23]] = distinct !{[[LOOP23]], [[META3]]}
-// CHECK: [[LOOP24]] = distinct !{[[LOOP24]], [[META3]]}
-// CHECK: [[LOOP25]] = distinct !{[[LOOP25]], [[META3]]}
-// CHECK: [[LOOP26]] = distinct !{[[LOOP26]], [[META3]]}
-// CHECK: [[LOOP27]] = distinct !{[[LOOP27]], [[META3]]}
-// CHECK: [[LOOP28]] = distinct !{[[LOOP28]], [[META3]]}
-// CHECK: [[LOOP29]] = distinct !{[[LOOP29]], [[META3]]}
-// CHECK: [[LOOP30]] = distinct !{[[LOOP30]], [[META3]]}
-// CHECK: [[LOOP31]] = distinct !{[[LOOP31]], [[META3]]}
-// CHECK: [[LOOP32]] = distinct !{[[LOOP32]], [[META3]]}
-//.

>From e695f54d924e0385bf778180ad4bd30cbd9c37be Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Mon, 24 Aug 2026 14:13:15 -0700
Subject: [PATCH 09/11] Enable iterator finalization

---
 clang/lib/Sema/SemaOpenMP.cpp                 |  37 +++--
 .../OpenMP/loop_transform_iv_iterator.cpp     | 146 ++++++++++++++++++
 .../runtime/test/transform/fuse/iterfor.cpp   |  12 +-
 .../test/transform/interchange/iterfor.cpp    |  12 +-
 .../test/transform/reverse/iterfor.cpp        |   6 +-
 .../runtime/test/transform/tile/iterfor.cpp   |  10 +-
 .../test/transform/unroll/factor_iterfor.cpp  |   6 +-
 7 files changed, 210 insertions(+), 19 deletions(-)
 create mode 100644 clang/test/OpenMP/loop_transform_iv_iterator.cpp

diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index a1cd89ced9af0..a8f2d098dea81 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -4673,7 +4673,19 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
   QualType Ty = Init->getType();
   if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
     if (S.getLangOpts().CPlusPlus) {
-      Ty = C.getLValueReferenceType(Ty);
+      // For class types (iterators), capture by value to avoid dangling
+      // references to temporaries from expressions like vec.begin() or
+      // vec.end(). Use references for simple variable references
+      // (DeclRefExpr, MemberExpr) to maintain compatibility.
+      bool ShouldCaptureByValue = false;
+      if (CaptureExpr->getType()->isRecordType()) {
+        const Expr *InnerExpr = CaptureExpr->IgnoreParenImpCasts();
+        ShouldCaptureByValue =
+            !isa<DeclRefExpr>(InnerExpr) && !isa<MemberExpr>(InnerExpr);
+      }
+      if (!ShouldCaptureByValue) {
+        Ty = C.getLValueReferenceType(Ty);
+      }
     } else {
       Ty = C.getPointerType(Ty);
       ExprResult Res =
@@ -4709,7 +4721,12 @@ static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
 
 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref,
                                StringRef Name) {
-  CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
+  // For class types (like iterators), capture the object value directly
+  // without lvalue conversion to avoid dangling references to temporaries.
+  const bool IsClassType = CaptureExpr->getType()->isRecordType();
+  if (!IsClassType)
+    CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
+
   if (!Ref) {
     OMPCapturedExprDecl *CD = buildCaptureDecl(
         S, &S.getASTContext().Idents.get(Name), CaptureExpr,
@@ -4725,6 +4742,9 @@ static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref,
     if (!Res.isUsable())
       return ExprError();
   }
+  // For class types, return the object directly without lvalue conversion
+  if (IsClassType)
+    return Res;
   return S.DefaultLvalueConversion(Res.get());
 }
 
@@ -10828,15 +10848,12 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
       }
 
       // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
-      // For iterator-based loops (range-based for or explicit iterator loops)
-      // in loop transformation directives, skip finalization entirely.
+      // Range-based for loops manage their own iterators internally, so skip
+      // explicit finalization for them.
       ExprResult Final;
-      bool IsIteratorLoop =
-          IS.IsRangeFor || (!IS.CounterVar->getType()->isArithmeticType() &&
-                            !IS.CounterVar->getType()->isPointerType());
-      if (IsIteratorLoop && isOpenMPLoopTransformationDirective(DKind)) {
-        // Iterator-based loops in transformation directives don't need
-        // explicit finalization - the iterator is already at the end.
+      if (IS.IsRangeFor && isOpenMPLoopTransformationDirective(DKind)) {
+        // Range-based for loops have hidden iterators managed by
+        // compiler-generated machinery, no explicit finalization needed.
         Final = nullptr;
       } else {
         Final =
diff --git a/clang/test/OpenMP/loop_transform_iv_iterator.cpp b/clang/test/OpenMP/loop_transform_iv_iterator.cpp
new file mode 100644
index 0000000000000..c9d1444e88461
--- /dev/null
+++ b/clang/test/OpenMP/loop_transform_iv_iterator.cpp
@@ -0,0 +1,146 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -std=c++11 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// expected-no-diagnostics
+
+// Test that iterator loop variables are correctly finalized after loop-transformation
+// constructs as required by OpenMP 6.0 spec (pg 371, lines 19-21).
+
+// Simple iterator class for testing
+struct Iterator {
+  int *ptr;
+
+  Iterator(int *p) : ptr(p) {}
+
+  bool operator!=(const Iterator &other) const {
+    return ptr != other.ptr;
+  }
+
+  Iterator &operator++() {
+    ++ptr;
+    return *this;
+  }
+
+  int &operator*() {
+    return *ptr;
+  }
+
+  long operator-(const Iterator &other) const {
+    return ptr - other.ptr;
+  }
+
+  Iterator operator+(long n) const {
+    return Iterator(ptr + n);
+  }
+};
+
+struct Container {
+  int data[10];
+
+  Iterator begin() { return Iterator(data); }
+  Iterator end() { return Iterator(data + 10); }
+};
+
+void test_iterator_tile(void) {
+  // CHECK-LABEL: define {{.*}} @_Z{{.*}}test_iterator_tile
+  Container cont;
+  Iterator it = cont.begin();
+  #pragma omp tile sizes(3)
+  for (it = cont.begin(); it != cont.end(); ++it) {
+    *it = 42;
+  }
+  // CHECK: for.end{{.*}}:
+  // Iterator should be finalized to cont.end() (loop-exit value)
+  // CHECK: call {{.*}} @_ZNK8IteratormiERKS_
+  // CHECK: call {{.*}} @_ZNK8IteratorplEl
+  // CHECK: call void @llvm.memcpy{{.*}}(ptr align {{.*}} %it
+}
+
+void test_iterator_reverse(void) {
+  // CHECK-LABEL: define {{.*}} @_Z{{.*}}test_iterator_reverse
+  Container cont;
+  Iterator it = cont.begin();
+  #pragma omp reverse
+  for (it = cont.begin(); it != cont.end(); ++it) {
+    *it = 42;
+  }
+  // CHECK: for.end{{.*}}:
+  // Iterator should be finalized to cont.end() (loop-exit value)
+  // CHECK: call {{.*}} @_ZNK8IteratormiERKS_
+  // CHECK: call {{.*}} @_ZNK8IteratorplEl
+  // CHECK: call void @llvm.memcpy{{.*}}(ptr align {{.*}} %it
+}
+
+struct Container2 {
+  int data[5];
+
+  Iterator begin() { return Iterator(data); }
+  Iterator end() { return Iterator(data + 5); }
+};
+
+void test_iterator_interchange(void) {
+  // CHECK-LABEL: define {{.*}} @_Z{{.*}}test_iterator_interchange
+  Container cont1;
+  Container2 cont2;
+  Iterator i = cont1.begin();
+  Iterator j = cont2.begin();
+  #pragma omp interchange permutation(2, 1)
+  for (i = cont1.begin(); i != cont1.end(); ++i) {
+    for (j = cont2.begin(); j != cont2.end(); ++j) {
+      // noop
+    }
+  }
+  // CHECK: for.end{{.*}}:
+  // Both iterators should be finalized to their respective end() values
+  // CHECK: call {{.*}} @_ZNK8IteratormiERKS_
+  // CHECK: call {{.*}} @_ZNK8IteratorplEl
+  // CHECK: call void @llvm.memcpy{{.*}}(ptr align {{.*}} %i
+  // CHECK: call {{.*}} @_ZNK8IteratormiERKS_
+  // CHECK: call {{.*}} @_ZNK8IteratorplEl
+  // CHECK: call void @llvm.memcpy{{.*}}(ptr align {{.*}} %j
+}
+
+void test_iterator_fuse(void) {
+  // CHECK-LABEL: define {{.*}} @_Z{{.*}}test_iterator_fuse
+  Container cont1;
+  Container2 cont2;
+  Iterator p = cont1.begin();
+  Iterator q = cont2.begin();
+  #pragma omp fuse
+  {
+    for (p = cont1.begin(); p != cont1.end(); ++p) {
+      *p = 1;
+    }
+    for (q = cont2.begin(); q != cont2.end(); ++q) {
+      *q = 2;
+    }
+  }
+  // CHECK: for.end{{.*}}:
+  // Both iterators should be finalized to their respective end() values
+  // CHECK: call {{.*}} @_ZNK8IteratormiERKS_
+  // CHECK: call {{.*}} @_ZNK8IteratorplEl
+  // CHECK: call void @llvm.memcpy{{.*}}(ptr align {{.*}} %p
+  // CHECK: call {{.*}} @_ZNK8IteratormiERKS_
+  // CHECK: call {{.*}} @_ZNK8IteratorplEl
+  // CHECK: call void @llvm.memcpy{{.*}}(ptr align {{.*}} %q
+}
+
+void test_iterator_tile_nested(void) {
+  // CHECK-LABEL: define {{.*}} @_Z{{.*}}test_iterator_tile_nested
+  Container cont1;
+  Container2 cont2;
+  Iterator i = cont1.begin();
+  Iterator j = cont2.begin();
+  #pragma omp tile sizes(2, 3)
+  for (i = cont1.begin(); i != cont1.end(); ++i) {
+    for (j = cont2.begin(); j != cont2.end(); ++j) {
+      // noop
+    }
+  }
+  // CHECK: for.end{{.*}}:
+  // Both iterators should be finalized to their respective end() values
+  // CHECK: call {{.*}} @_ZNK8IteratormiERKS_
+  // CHECK: call {{.*}} @_ZNK8IteratorplEl
+  // CHECK: call void @llvm.memcpy{{.*}}(ptr align {{.*}} %i
+  // CHECK: call {{.*}} @_ZNK8IteratormiERKS_
+  // CHECK: call {{.*}} @_ZNK8IteratorplEl
+  // CHECK: call void @llvm.memcpy{{.*}}(ptr align {{.*}} %j
+}
diff --git a/openmp/runtime/test/transform/fuse/iterfor.cpp b/openmp/runtime/test/transform/fuse/iterfor.cpp
index 552484b2981c4..0c6733ba3dce3 100644
--- a/openmp/runtime/test/transform/fuse/iterfor.cpp
+++ b/openmp/runtime/test/transform/fuse/iterfor.cpp
@@ -183,12 +183,20 @@ int main() {
 // CHECK-NEXT: [D] iterator deref: 2
 // CHECK-NEXT: vv=2
 // CHECK-NEXT: [D] iterator dtor
+// CHECK-NEXT: [C] iterator distance: 3
+// CHECK-NEXT: [C] iterator advance: 0 += 3
+// CHECK-NEXT: [C] iterator move assign
+// CHECK-NEXT: [D] iterator distance: 3
+// CHECK-NEXT: [D] iterator advance: 0 += 3
+// CHECK-NEXT: [D] iterator move assign
+// CHECK-NEXT: [D] iterator dtor
+// CHECK-NEXT: [C] iterator dtor
+// CHECK-NEXT: [D] iterator dtor
 // CHECK-NEXT: [D] iterator dtor
 // CHECK-NEXT: [D] iterator dtor
 // CHECK-NEXT: [C] iterator dtor
 // CHECK-NEXT: [C] iterator dtor
-// CHECK-NEXT: done
-// CHECK-NEXT: [D] iterator dtor
 // CHECK-NEXT: [C] iterator dtor
+// CHECK-NEXT: done
 // CHECK-NEXT: [D] dtor
 // CHECK-NEXT: [C] dtor
diff --git a/openmp/runtime/test/transform/interchange/iterfor.cpp b/openmp/runtime/test/transform/interchange/iterfor.cpp
index 98a398fe8925e..ce22a1cad9fdd 100644
--- a/openmp/runtime/test/transform/interchange/iterfor.cpp
+++ b/openmp/runtime/test/transform/interchange/iterfor.cpp
@@ -213,12 +213,20 @@ int main() {
 // CHECK-NEXT: i=2 j=2
 // CHECK-NEXT: [A] iterator dtor
 // CHECK-NEXT: [B] iterator dtor
+// CHECK-NEXT: [A] iterator distance: 3
+// CHECK-NEXT: [A] iterator advance: 0 += 3
+// CHECK-NEXT: [A] iterator move assign
+// CHECK-NEXT: [B] iterator distance: 3
+// CHECK-NEXT: [B] iterator advance: 0 += 3
+// CHECK-NEXT: [B] iterator move assign
+// CHECK-NEXT: [B] iterator dtor
+// CHECK-NEXT: [A] iterator dtor
+// CHECK-NEXT: [B] iterator dtor
 // CHECK-NEXT: [B] iterator dtor
 // CHECK-NEXT: [B] iterator dtor
 // CHECK-NEXT: [A] iterator dtor
 // CHECK-NEXT: [A] iterator dtor
-// CHECK-NEXT: done
-// CHECK-NEXT: [B] iterator dtor
 // CHECK-NEXT: [A] iterator dtor
+// CHECK-NEXT: done
 // CHECK-NEXT: [B] dtor
 // CHECK-NEXT: [A] dtor
diff --git a/openmp/runtime/test/transform/reverse/iterfor.cpp b/openmp/runtime/test/transform/reverse/iterfor.cpp
index ba1086dbd76a5..f96f37721d5c5 100644
--- a/openmp/runtime/test/transform/reverse/iterfor.cpp
+++ b/openmp/runtime/test/transform/reverse/iterfor.cpp
@@ -157,8 +157,12 @@ int main() {
 // CHECK-NEXT: [range] iterator deref: 0
 // CHECK-NEXT: v=0
 // CHECK-NEXT: [range] iterator dtor
+// CHECK-NEXT: [range] iterator distance: 3
+// CHECK-NEXT: [range] iterator advance: 0 += 3
+// CHECK-NEXT: [range] iterator move assign
 // CHECK-NEXT: [range] iterator dtor
 // CHECK-NEXT: [range] iterator dtor
-// CHECK-NEXT: done
 // CHECK-NEXT: [range] iterator dtor
+// CHECK-NEXT: [range] iterator dtor
+// CHECK-NEXT: done
 // CHECK-NEXT: [range] dtor
diff --git a/openmp/runtime/test/transform/tile/iterfor.cpp b/openmp/runtime/test/transform/tile/iterfor.cpp
index 05b5677bf9c4f..b7cd003175e32 100644
--- a/openmp/runtime/test/transform/tile/iterfor.cpp
+++ b/openmp/runtime/test/transform/tile/iterfor.cpp
@@ -224,11 +224,19 @@ int main() {
 // CHECK-NEXT: i=2 j=2
 // CHECK-NEXT: [B] iterator dtor
 // CHECK-NEXT: [A] iterator dtor
+// CHECK-NEXT: [A] iterator distance: 3
+// CHECK-NEXT: [A] iterator advance: 0 += 3
+// CHECK-NEXT: [A] iterator move assign
+// CHECK-NEXT: [B] iterator distance: 3
+// CHECK-NEXT: [B] iterator advance: 0 += 3
+// CHECK-NEXT: [B] iterator move assign
+// CHECK-NEXT: [B] iterator dtor
+// CHECK-NEXT: [A] iterator dtor
+// CHECK-NEXT: [B] iterator dtor
 // CHECK-NEXT: [B] iterator dtor
 // CHECK-NEXT: [B] iterator dtor
 // CHECK-NEXT: [A] iterator dtor
 // CHECK-NEXT: [A] iterator dtor
-// CHECK-NEXT: [B] iterator dtor
 // CHECK-NEXT: [A] iterator dtor
 // CHECK-NEXT: [B] dtor
 // CHECK-NEXT: [A] dtor
diff --git a/openmp/runtime/test/transform/unroll/factor_iterfor.cpp b/openmp/runtime/test/transform/unroll/factor_iterfor.cpp
index 0298477110b25..2b0a988091bb0 100644
--- a/openmp/runtime/test/transform/unroll/factor_iterfor.cpp
+++ b/openmp/runtime/test/transform/unroll/factor_iterfor.cpp
@@ -145,22 +145,22 @@ int main() {
 // CHECK-NEXT: [range] begin()
 // CHECK-NEXT: [range] end()
 // CHECK-NEXT: [range] iterator 0 != 3
+// CHECK-NEXT: [range] iterator dtor
 // CHECK-NEXT: [range] iterator deref: 0
 // CHECK-NEXT: v=0
 // CHECK-NEXT: [range] iterator prefix ++
-// CHECK-NEXT: [range] iterator dtor
 // CHECK-NEXT: [range] end()
 // CHECK-NEXT: [range] iterator 1 != 3
+// CHECK-NEXT: [range] iterator dtor
 // CHECK-NEXT: [range] iterator deref: 1
 // CHECK-NEXT: v=1
 // CHECK-NEXT: [range] iterator prefix ++
-// CHECK-NEXT: [range] iterator dtor
 // CHECK-NEXT: [range] end()
 // CHECK-NEXT: [range] iterator 2 != 3
+// CHECK-NEXT: [range] iterator dtor
 // CHECK-NEXT: [range] iterator deref: 2
 // CHECK-NEXT: v=2
 // CHECK-NEXT: [range] iterator prefix ++
-// CHECK-NEXT: [range] iterator dtor
 // CHECK-NEXT: [range] end()
 // CHECK-NEXT: [range] iterator 3 != 3
 // CHECK-NEXT: [range] iterator dtor

>From f04fa4e46ed8d8c2649db707a155cb4a1ef5184a Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Tue, 25 Aug 2026 07:34:27 -0700
Subject: [PATCH 10/11] Added var finalization for split

---
 clang/include/clang/AST/StmtOpenMP.h          |  16 ++-
 clang/lib/AST/StmtOpenMP.cpp                  |   8 +-
 clang/lib/CodeGen/CGStmtOpenMP.cpp            |   5 +
 clang/lib/Sema/SemaOpenMP.cpp                 |  12 +-
 clang/test/OpenMP/loop_transform_iv.c         |  10 ++
 .../OpenMP/loop_transform_iv_iterator.cpp     |  15 +++
 clang/test/OpenMP/split_codegen.cpp           | 106 ++++++++++++++++++
 clang/test/OpenMP/split_counts_verify.c       |   1 +
 8 files changed, 160 insertions(+), 13 deletions(-)

diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h
index b4c6573ef712b..6fcaa8f4a87e5 100644
--- a/clang/include/clang/AST/StmtOpenMP.h
+++ b/clang/include/clang/AST/StmtOpenMP.h
@@ -6206,6 +6206,7 @@ class OMPSplitDirective final
   enum {
     PreInitsOffset = 0,
     TransformedStmtOffset,
+    FinalsOffset,
   };
 
   explicit OMPSplitDirective(SourceLocation StartLoc, SourceLocation EndLoc,
@@ -6222,6 +6223,8 @@ class OMPSplitDirective final
     Data->getChildren()[TransformedStmtOffset] = S;
   }
 
+  void setFinals(Stmt *Finals) { Data->getChildren()[FinalsOffset] = Finals; }
+
 public:
   /// Create a new AST node representation for '#pragma omp split'.
   ///
@@ -6235,11 +6238,11 @@ class OMPSplitDirective final
   /// \param TransformedStmt The loop nest after splitting, or nullptr in
   ///                        dependent contexts.
   /// \param PreInits   Helper preinits statements for the loop nest.
-  static OMPSplitDirective *Create(const ASTContext &C, SourceLocation StartLoc,
-                                   SourceLocation EndLoc,
-                                   ArrayRef<OMPClause *> Clauses,
-                                   unsigned NumLoops, Stmt *AssociatedStmt,
-                                   Stmt *TransformedStmt, Stmt *PreInits);
+  /// \param Finals     Loop variable finalization statements.
+  static OMPSplitDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         ArrayRef<OMPClause *> Clauses, unsigned NumLoops, Stmt *AssociatedStmt,
+         Stmt *TransformedStmt, Stmt *PreInits, Stmt *Finals);
 
   /// Build an empty '#pragma omp split' AST node for deserialization.
   ///
@@ -6258,6 +6261,9 @@ class OMPSplitDirective final
   /// Return preinits statement.
   Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
 
+  /// Return finals statement (loop variable finalization).
+  Stmt *getFinals() const { return Data->getChildren()[FinalsOffset]; }
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == OMPSplitDirectiveClass;
   }
diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp
index 0ca3349a23542..ce1a7ec27a119 100644
--- a/clang/lib/AST/StmtOpenMP.cpp
+++ b/clang/lib/AST/StmtOpenMP.cpp
@@ -607,12 +607,12 @@ OMPSplitDirective *
 OMPSplitDirective::Create(const ASTContext &C, SourceLocation StartLoc,
                           SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses,
                           unsigned NumLoops, Stmt *AssociatedStmt,
-                          Stmt *TransformedStmt, Stmt *PreInits) {
+                          Stmt *TransformedStmt, Stmt *PreInits, Stmt *Finals) {
   OMPSplitDirective *Dir = createDirective<OMPSplitDirective>(
-      C, Clauses, AssociatedStmt, TransformedStmtOffset + 1, StartLoc, EndLoc,
-      NumLoops);
+      C, Clauses, AssociatedStmt, FinalsOffset + 1, StartLoc, EndLoc, NumLoops);
   Dir->setTransformedStmt(TransformedStmt);
   Dir->setPreInits(PreInits);
+  Dir->setFinals(Finals);
   return Dir;
 }
 
@@ -620,7 +620,7 @@ OMPSplitDirective *OMPSplitDirective::CreateEmpty(const ASTContext &C,
                                                   unsigned NumClauses,
                                                   unsigned NumLoops) {
   return createEmptyDirective<OMPSplitDirective>(
-      C, NumClauses, /*HasAssociatedStmt=*/true, TransformedStmtOffset + 1,
+      C, NumClauses, /*HasAssociatedStmt=*/true, FinalsOffset + 1,
       SourceLocation(), SourceLocation(), NumLoops);
 }
 
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 5c7da3ebedce9..fdf6e0cd1c76c 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -3257,6 +3257,11 @@ void CodeGenFunction::EmitOMPSplitDirective(const OMPSplitDirective &S) {
   // Emit the de-sugared statement (the split loops).
   OMPTransformDirectiveScopeRAII SplitScope(*this, &S);
   EmitStmt(S.getTransformedStmt());
+
+  // Emit loop variable finalization as required by OpenMP 6.0 spec to restore
+  // original loop variable values after the loop-transformation construct.
+  if (auto *Finals = S.getFinals())
+    EmitStmt(Finals);
 }
 
 void CodeGenFunction::EmitOMPInterchangeDirective(
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index a8f2d098dea81..d8a653d36adc5 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -16376,7 +16376,8 @@ StmtResult SemaOpenMP::ActOnOpenMPSplitDirective(ArrayRef<OMPClause *> Clauses,
   // instantiated.
   if (SemaRef.CurContext->isDependentContext())
     return OMPSplitDirective::Create(Context, StartLoc, EndLoc, Clauses,
-                                     NumLoops, AStmt, nullptr, nullptr);
+                                     NumLoops, AStmt, nullptr, nullptr,
+                                     nullptr);
 
   assert(LoopHelpers.size() == NumLoops &&
          "Expecting a single-dimensional loop iteration space");
@@ -16419,12 +16420,14 @@ StmtResult SemaOpenMP::ActOnOpenMPSplitDirective(ArrayRef<OMPClause *> Clauses,
     Expr *CountExpr = Refs[I];
     if (!CountExpr)
       return OMPSplitDirective::Create(Context, StartLoc, EndLoc, Clauses,
-                                       NumLoops, AStmt, nullptr, nullptr);
+                                       NumLoops, AStmt, nullptr, nullptr,
+                                       nullptr);
     std::optional<llvm::APSInt> OptVal =
         CountExpr->getIntegerConstantExpr(Context);
     if (!OptVal || OptVal->isNegative())
       return OMPSplitDirective::Create(Context, StartLoc, EndLoc, Clauses,
-                                       NumLoops, AStmt, nullptr, nullptr);
+                                       NumLoops, AStmt, nullptr, nullptr,
+                                       nullptr);
     CountValues[I] = OptVal->getZExtValue();
   }
 
@@ -16568,7 +16571,8 @@ StmtResult SemaOpenMP::ActOnOpenMPSplitDirective(ArrayRef<OMPClause *> Clauses,
 
   return OMPSplitDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
                                    AStmt, SplitStmt,
-                                   buildPreInits(Context, PreInits));
+                                   buildPreInits(Context, PreInits),
+                                   buildLoopFinalization(Context, LoopHelpers));
 }
 
 StmtResult SemaOpenMP::ActOnOpenMPInterchangeDirective(
diff --git a/clang/test/OpenMP/loop_transform_iv.c b/clang/test/OpenMP/loop_transform_iv.c
index a61e6ce7cb2f9..d591d299cd617 100644
--- a/clang/test/OpenMP/loop_transform_iv.c
+++ b/clang/test/OpenMP/loop_transform_iv.c
@@ -224,3 +224,13 @@ void test_pointer_fuse(void) {
   // CHECK: store ptr [[Q_FINAL]], ptr %q
   // After fuse: p should point to arr1 + 10, q should point to arr2 + 15
 }
+
+void test_split(void) {
+  // CHECK-LABEL: define {{.*}} @test_split
+  int i;
+  #pragma omp split counts(5, omp_fill)
+  for (i = 0; i < 20; i++) {
+  }
+  // CHECK: store i32 20, ptr %i
+  // After loop: i should be 20 (loop-exit value per OpenMP 6.0 spec)
+}
diff --git a/clang/test/OpenMP/loop_transform_iv_iterator.cpp b/clang/test/OpenMP/loop_transform_iv_iterator.cpp
index c9d1444e88461..7bde83e80c0bd 100644
--- a/clang/test/OpenMP/loop_transform_iv_iterator.cpp
+++ b/clang/test/OpenMP/loop_transform_iv_iterator.cpp
@@ -144,3 +144,18 @@ void test_iterator_tile_nested(void) {
   // CHECK: call {{.*}} @_ZNK8IteratorplEl
   // CHECK: call void @llvm.memcpy{{.*}}(ptr align {{.*}} %j
 }
+
+void test_iterator_split(void) {
+  // CHECK-LABEL: define {{.*}} @_Z{{.*}}test_iterator_split
+  Container cont;
+  Iterator it = cont.begin();
+  #pragma omp split counts(3, omp_fill)
+  for (it = cont.begin(); it != cont.end(); ++it) {
+    *it = 42;
+  }
+  // CHECK: for.end{{.*}}:
+  // Iterator should be finalized to cont.end() (loop-exit value)
+  // CHECK: call {{.*}} @_ZNK8IteratormiERKS_
+  // CHECK: call {{.*}} @_ZNK8IteratorplEl
+  // CHECK: call void @llvm.memcpy{{.*}}(ptr align {{.*}} %it
+}
diff --git a/clang/test/OpenMP/split_codegen.cpp b/clang/test/OpenMP/split_codegen.cpp
index 8855f24639d08..ae0059abb78ff 100644
--- a/clang/test/OpenMP/split_codegen.cpp
+++ b/clang/test/OpenMP/split_codegen.cpp
@@ -173,6 +173,8 @@ void split_range_for() {
 // CHECK1-NEXT:    store i32 [[INC10]], ptr [[DOTSPLIT_IV_1_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND4]], !llvm.loop [[LOOP6:![0-9]+]]
 // CHECK1:       for.end11:
+// CHECK1-NEXT:    [[TMP14:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK1-NEXT:    store i32 20, ptr [[TMP14]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -228,6 +230,7 @@ void split_range_for() {
 // CHECK1-NEXT:    store i32 [[INC7]], ptr [[DOTSPLIT_IV_1_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND1]], !llvm.loop [[LOOP8:![0-9]+]]
 // CHECK1:       for.end8:
+// CHECK1-NEXT:    store i32 10, ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -296,6 +299,12 @@ void split_range_for() {
 // CHECK1-NEXT:    store i32 [[INC10]], ptr [[DOTSPLIT_IV_1_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND3]], !llvm.loop [[LOOP10:![0-9]+]]
 // CHECK1:       for.end11:
+// CHECK1-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB12:%.*]] = sub nsw i32 [[TMP13]], 0
+// CHECK1-NEXT:    [[DIV13:%.*]] = sdiv i32 [[SUB12]], 1
+// CHECK1-NEXT:    [[MUL14:%.*]] = mul nsw i32 [[DIV13]], 1
+// CHECK1-NEXT:    [[ADD15:%.*]] = add nsw i32 0, [[MUL14]]
+// CHECK1-NEXT:    store i32 [[ADD15]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -393,6 +402,12 @@ void split_range_for() {
 // CHECK1-NEXT:    store i32 [[INC22]], ptr [[DOTSPLIT_IV_2_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND15]], !llvm.loop [[LOOP13:![0-9]+]]
 // CHECK1:       for.end23:
+// CHECK1-NEXT:    [[TMP20:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB24:%.*]] = sub nsw i32 [[TMP20]], 0
+// CHECK1-NEXT:    [[DIV25:%.*]] = sdiv i32 [[SUB24]], 1
+// CHECK1-NEXT:    [[MUL26:%.*]] = mul nsw i32 [[DIV25]], 1
+// CHECK1-NEXT:    [[ADD27:%.*]] = add nsw i32 0, [[MUL26]]
+// CHECK1-NEXT:    store i32 [[ADD27]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -467,6 +482,12 @@ void split_range_for() {
 // CHECK1-NEXT:    store i32 [[INC14]], ptr [[DOTSPLIT_IV_1_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND7]], !llvm.loop [[LOOP15:![0-9]+]]
 // CHECK1:       for.end15:
+// CHECK1-NEXT:    [[TMP15:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB16:%.*]] = sub nsw i32 [[TMP15]], 0
+// CHECK1-NEXT:    [[DIV17:%.*]] = sdiv i32 [[SUB16]], 1
+// CHECK1-NEXT:    [[MUL18:%.*]] = mul nsw i32 [[DIV17]], 1
+// CHECK1-NEXT:    [[ADD19:%.*]] = add nsw i32 0, [[MUL18]]
+// CHECK1-NEXT:    store i32 [[ADD19]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -512,6 +533,12 @@ void split_range_for() {
 // CHECK1-NEXT:    store i32 [[INC]], ptr [[DOTSPLIT_IV_0_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP16:![0-9]+]]
 // CHECK1:       for.end:
+// CHECK1-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB4:%.*]] = sub nsw i32 [[TMP8]], 0
+// CHECK1-NEXT:    [[DIV5:%.*]] = sdiv i32 [[SUB4]], 1
+// CHECK1-NEXT:    [[MUL6:%.*]] = mul nsw i32 [[DIV5]], 1
+// CHECK1-NEXT:    [[ADD7:%.*]] = add nsw i32 0, [[MUL6]]
+// CHECK1-NEXT:    store i32 [[ADD7]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -609,6 +636,12 @@ void split_range_for() {
 // CHECK1-NEXT:    store i32 [[INC22]], ptr [[DOTSPLIT_IV_2_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND15]], !llvm.loop [[LOOP19:![0-9]+]]
 // CHECK1:       for.end23:
+// CHECK1-NEXT:    [[TMP20:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB24:%.*]] = sub i32 [[TMP20]], -2
+// CHECK1-NEXT:    [[DIV25:%.*]] = udiv i32 [[SUB24]], 1
+// CHECK1-NEXT:    [[MUL26:%.*]] = mul i32 [[DIV25]], 1
+// CHECK1-NEXT:    [[ADD27:%.*]] = add i32 -1, [[MUL26]]
+// CHECK1-NEXT:    store i32 [[ADD27]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -664,6 +697,7 @@ void split_range_for() {
 // CHECK1-NEXT:    store i32 [[INC7]], ptr [[DOTSPLIT_IV_1_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND1]], !llvm.loop [[LOOP21:![0-9]+]]
 // CHECK1:       for.end8:
+// CHECK1-NEXT:    store i32 10, ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -755,6 +789,12 @@ void split_range_for() {
 // CHECK1-NEXT:    store i32 [[INC18]], ptr [[DOTSPLIT_IV_2_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND11]], !llvm.loop [[LOOP24:![0-9]+]]
 // CHECK1:       for.end19:
+// CHECK1-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB20:%.*]] = sub nsw i32 [[TMP18]], 0
+// CHECK1-NEXT:    [[DIV21:%.*]] = sdiv i32 [[SUB20]], 1
+// CHECK1-NEXT:    [[MUL22:%.*]] = mul nsw i32 [[DIV21]], 1
+// CHECK1-NEXT:    [[ADD23:%.*]] = add nsw i32 0, [[MUL22]]
+// CHECK1-NEXT:    store i32 [[ADD23]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -823,6 +863,12 @@ void split_range_for() {
 // CHECK1-NEXT:    store i32 [[INC10]], ptr [[DOTSPLIT_IV_1_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND3]], !llvm.loop [[LOOP26:![0-9]+]]
 // CHECK1:       for.end11:
+// CHECK1-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB12:%.*]] = sub i32 [[TMP13]], -1
+// CHECK1-NEXT:    [[DIV13:%.*]] = udiv i32 [[SUB12]], 2
+// CHECK1-NEXT:    [[MUL14:%.*]] = mul i32 [[DIV13]], 2
+// CHECK1-NEXT:    [[ADD15:%.*]] = add i32 0, [[MUL14]]
+// CHECK1-NEXT:    store i32 [[ADD15]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -900,6 +946,13 @@ void split_range_for() {
 // CHECK1-NEXT:    store i32 [[INC14]], ptr [[DOTSPLIT_IV_1_I]], align 4
 // CHECK1-NEXT:    br label [[FOR_COND7]], !llvm.loop [[LOOP28:![0-9]+]]
 // CHECK1:       for.end15:
+// CHECK1-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[TMP19:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB16:%.*]] = sub nsw i32 [[TMP19]], 0
+// CHECK1-NEXT:    [[DIV17:%.*]] = sdiv i32 [[SUB16]], 1
+// CHECK1-NEXT:    [[MUL18:%.*]] = mul nsw i32 [[DIV17]], 1
+// CHECK1-NEXT:    [[SUB19:%.*]] = sub nsw i32 [[TMP18]], [[MUL18]]
+// CHECK1-NEXT:    store i32 [[SUB19]], ptr [[I]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1085,6 +1138,8 @@ void split_range_for() {
 // CHECK2-NEXT:    store i32 [[INC10]], ptr [[DOTSPLIT_IV_1_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND4]], !llvm.loop [[LOOP6:![0-9]+]]
 // CHECK2:       for.end11:
+// CHECK2-NEXT:    [[TMP14:%.*]] = load ptr, ptr [[I2]], align 8, !nonnull [[META2]], !align [[META3]]
+// CHECK2-NEXT:    store i32 20, ptr [[TMP14]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1264,6 +1319,13 @@ void split_range_for() {
 // CHECK2-NEXT:    store i32 [[INC14]], ptr [[DOTSPLIT_IV_1_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND7]], !llvm.loop [[LOOP10:![0-9]+]]
 // CHECK2:       for.end15:
+// CHECK2-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[TMP19:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB16:%.*]] = sub nsw i32 [[TMP19]], 0
+// CHECK2-NEXT:    [[DIV17:%.*]] = sdiv i32 [[SUB16]], 1
+// CHECK2-NEXT:    [[MUL18:%.*]] = mul nsw i32 [[DIV17]], 1
+// CHECK2-NEXT:    [[SUB19:%.*]] = sub nsw i32 [[TMP18]], [[MUL18]]
+// CHECK2-NEXT:    store i32 [[SUB19]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1338,6 +1400,12 @@ void split_range_for() {
 // CHECK2-NEXT:    store i32 [[INC14]], ptr [[DOTSPLIT_IV_1_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND7]], !llvm.loop [[LOOP12:![0-9]+]]
 // CHECK2:       for.end15:
+// CHECK2-NEXT:    [[TMP15:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB16:%.*]] = sub nsw i32 [[TMP15]], 0
+// CHECK2-NEXT:    [[DIV17:%.*]] = sdiv i32 [[SUB16]], 1
+// CHECK2-NEXT:    [[MUL18:%.*]] = mul nsw i32 [[DIV17]], 1
+// CHECK2-NEXT:    [[ADD19:%.*]] = add nsw i32 0, [[MUL18]]
+// CHECK2-NEXT:    store i32 [[ADD19]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1435,6 +1503,12 @@ void split_range_for() {
 // CHECK2-NEXT:    store i32 [[INC22]], ptr [[DOTSPLIT_IV_2_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND15]], !llvm.loop [[LOOP15:![0-9]+]]
 // CHECK2:       for.end23:
+// CHECK2-NEXT:    [[TMP20:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB24:%.*]] = sub nsw i32 [[TMP20]], 0
+// CHECK2-NEXT:    [[DIV25:%.*]] = sdiv i32 [[SUB24]], 1
+// CHECK2-NEXT:    [[MUL26:%.*]] = mul nsw i32 [[DIV25]], 1
+// CHECK2-NEXT:    [[ADD27:%.*]] = add nsw i32 0, [[MUL26]]
+// CHECK2-NEXT:    store i32 [[ADD27]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1532,6 +1606,12 @@ void split_range_for() {
 // CHECK2-NEXT:    store i32 [[INC22]], ptr [[DOTSPLIT_IV_2_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND15]], !llvm.loop [[LOOP18:![0-9]+]]
 // CHECK2:       for.end23:
+// CHECK2-NEXT:    [[TMP20:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB24:%.*]] = sub i32 [[TMP20]], -2
+// CHECK2-NEXT:    [[DIV25:%.*]] = udiv i32 [[SUB24]], 1
+// CHECK2-NEXT:    [[MUL26:%.*]] = mul i32 [[DIV25]], 1
+// CHECK2-NEXT:    [[ADD27:%.*]] = add i32 -1, [[MUL26]]
+// CHECK2-NEXT:    store i32 [[ADD27]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1577,6 +1657,12 @@ void split_range_for() {
 // CHECK2-NEXT:    store i32 [[INC]], ptr [[DOTSPLIT_IV_0_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP19:![0-9]+]]
 // CHECK2:       for.end:
+// CHECK2-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB4:%.*]] = sub nsw i32 [[TMP8]], 0
+// CHECK2-NEXT:    [[DIV5:%.*]] = sdiv i32 [[SUB4]], 1
+// CHECK2-NEXT:    [[MUL6:%.*]] = mul nsw i32 [[DIV5]], 1
+// CHECK2-NEXT:    [[ADD7:%.*]] = add nsw i32 0, [[MUL6]]
+// CHECK2-NEXT:    store i32 [[ADD7]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1645,6 +1731,12 @@ void split_range_for() {
 // CHECK2-NEXT:    store i32 [[INC10]], ptr [[DOTSPLIT_IV_1_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND3]], !llvm.loop [[LOOP21:![0-9]+]]
 // CHECK2:       for.end11:
+// CHECK2-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB12:%.*]] = sub i32 [[TMP13]], -1
+// CHECK2-NEXT:    [[DIV13:%.*]] = udiv i32 [[SUB12]], 2
+// CHECK2-NEXT:    [[MUL14:%.*]] = mul i32 [[DIV13]], 2
+// CHECK2-NEXT:    [[ADD15:%.*]] = add i32 0, [[MUL14]]
+// CHECK2-NEXT:    store i32 [[ADD15]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1736,6 +1828,12 @@ void split_range_for() {
 // CHECK2-NEXT:    store i32 [[INC18]], ptr [[DOTSPLIT_IV_2_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND11]], !llvm.loop [[LOOP24:![0-9]+]]
 // CHECK2:       for.end19:
+// CHECK2-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB20:%.*]] = sub nsw i32 [[TMP18]], 0
+// CHECK2-NEXT:    [[DIV21:%.*]] = sdiv i32 [[SUB20]], 1
+// CHECK2-NEXT:    [[MUL22:%.*]] = mul nsw i32 [[DIV21]], 1
+// CHECK2-NEXT:    [[ADD23:%.*]] = add nsw i32 0, [[MUL22]]
+// CHECK2-NEXT:    store i32 [[ADD23]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1791,6 +1889,7 @@ void split_range_for() {
 // CHECK2-NEXT:    store i32 [[INC7]], ptr [[DOTSPLIT_IV_1_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND1]], !llvm.loop [[LOOP26:![0-9]+]]
 // CHECK2:       for.end8:
+// CHECK2-NEXT:    store i32 10, ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1859,6 +1958,12 @@ void split_range_for() {
 // CHECK2-NEXT:    store i32 [[INC10]], ptr [[DOTSPLIT_IV_1_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND3]], !llvm.loop [[LOOP28:![0-9]+]]
 // CHECK2:       for.end11:
+// CHECK2-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB12:%.*]] = sub nsw i32 [[TMP13]], 0
+// CHECK2-NEXT:    [[DIV13:%.*]] = sdiv i32 [[SUB12]], 1
+// CHECK2-NEXT:    [[MUL14:%.*]] = mul nsw i32 [[DIV13]], 1
+// CHECK2-NEXT:    [[ADD15:%.*]] = add nsw i32 0, [[MUL14]]
+// CHECK2-NEXT:    store i32 [[ADD15]], ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1914,6 +2019,7 @@ void split_range_for() {
 // CHECK2-NEXT:    store i32 [[INC7]], ptr [[DOTSPLIT_IV_1_I]], align 4
 // CHECK2-NEXT:    br label [[FOR_COND1]], !llvm.loop [[LOOP30:![0-9]+]]
 // CHECK2:       for.end8:
+// CHECK2-NEXT:    store i32 10, ptr [[I]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
diff --git a/clang/test/OpenMP/split_counts_verify.c b/clang/test/OpenMP/split_counts_verify.c
index 7fec1561d8380..00721dcf17765 100644
--- a/clang/test/OpenMP/split_counts_verify.c
+++ b/clang/test/OpenMP/split_counts_verify.c
@@ -109,6 +109,7 @@ int main(void) {
 // IR-NEXT:    store i32 [[INC18]], ptr [[DOTSPLIT_IV_2_I]], align 4
 // IR-NEXT:    br label %[[FOR_COND11]], !llvm.loop [[LOOP5:![0-9]+]]
 // IR:       [[FOR_END19]]:
+// IR-NEXT:    store i32 10, ptr [[I]], align 4
 // IR-NEXT:    [[TMP18:%.*]] = load i32, ptr [[SUM]], align 4
 // IR-NEXT:    [[CMP20:%.*]] = icmp eq i32 [[TMP18]], 45
 // IR-NEXT:    [[TMP19:%.*]] = zext i1 [[CMP20]] to i64

>From 27062b41ce59332180303f0001020d12fd981769 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Wed, 9 Sep 2026 13:55:51 -0700
Subject: [PATCH 11/11] Added fix for tests to pass

---
 clang/include/clang/AST/StmtOpenMP.h      |  42 +++++-
 clang/include/clang/Sema/SemaOpenMP.h     |   5 +
 clang/lib/AST/StmtOpenMP.cpp              |  45 +++++-
 clang/lib/CodeGen/CGStmtOpenMP.cpp        |  29 +++-
 clang/lib/Sema/SemaOpenMP.cpp             |  38 ++++-
 clang/lib/Serialization/ASTReaderStmt.cpp |   1 +
 clang/lib/Serialization/ASTWriterStmt.cpp |   1 +
 clang/test/OpenMP/fuse_codegen.cpp        | 164 ++++++++++++----------
 8 files changed, 228 insertions(+), 97 deletions(-)

diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h
index 6fcaa8f4a87e5..23fb1fde91a56 100644
--- a/clang/include/clang/AST/StmtOpenMP.h
+++ b/clang/include/clang/AST/StmtOpenMP.h
@@ -1037,6 +1037,10 @@ class OMPLoopTransformationDirective {
   /// Return preinits statement.
   Stmt *getPreInits() const;
 
+  /// Return loop variable finalization statement, or nullptr if the concrete
+  /// transformation does not produce one (e.g. unroll).
+  Stmt *getFinals() const;
+
   static bool classof(const Stmt *T) {
     return isa<OMPCanonicalLoopNestTransformationDirective,
                OMPCanonicalLoopSequenceTransformationDirective>(T);
@@ -1070,6 +1074,10 @@ class OMPCanonicalLoopNestTransformationDirective
   /// Return preinits statement.
   Stmt *getPreInits() const;
 
+  /// Return loop variable finalization statement, or nullptr if the concrete
+  /// transformation does not produce one (e.g. unroll).
+  Stmt *getFinals() const;
+
   static bool classof(const Stmt *T) {
     Stmt::StmtClass C = T->getStmtClass();
     return C == OMPTileDirectiveClass || C == OMPUnrollDirectiveClass ||
@@ -5909,6 +5917,9 @@ class OMPUnrollDirective final
   /// Return the pre-init statements.
   Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
 
+  /// Unroll does not model loop variable finalization; always returns nullptr.
+  Stmt *getFinals() const { return nullptr; }
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == OMPUnrollDirectiveClass;
   }
@@ -6095,6 +6106,10 @@ class OMPCanonicalLoopSequenceTransformationDirective
   /// Return preinits statement.
   Stmt *getPreInits() const;
 
+  /// Return loop variable finalization statement, or nullptr if the concrete
+  /// transformation does not produce one.
+  Stmt *getFinals() const;
+
   static bool classof(const Stmt *T) {
     Stmt::StmtClass C = T->getStmtClass();
     return C == OMPFuseDirectiveClass;
@@ -6123,6 +6138,13 @@ class OMPFuseDirective final
     FinalsOffset,
   };
 
+  /// Position of the fused loop within the CompoundStmt TransformedStmt for
+  /// looprange fuse (i.e., the index of the FusedForStmt among the children of
+  /// the CompoundStmt). Codegen uses this to emit Finals immediately after the
+  /// fused loop, before any post-fusion loops. Ignored (0) when the
+  /// TransformedStmt is a single ForStmt (no looprange or full range).
+  unsigned FusedLoopIdx = 0;
+
   explicit OMPFuseDirective(SourceLocation StartLoc, SourceLocation EndLoc)
       : OMPCanonicalLoopSequenceTransformationDirective(
             OMPFuseDirectiveClass, llvm::omp::OMPD_fuse, StartLoc, EndLoc) {}
@@ -6137,6 +6159,8 @@ class OMPFuseDirective final
 
   void setFinals(Stmt *Finals) { Data->getChildren()[FinalsOffset] = Finals; }
 
+  void setFusedLoopIdx(unsigned Idx) { FusedLoopIdx = Idx; }
+
 public:
   /// Create a new AST node representation for #pragma omp fuse'
   ///
@@ -6153,12 +6177,14 @@ class OMPFuseDirective final
   ///                        dependent
   /// \param PreInits Helper preinits statements for the loop nest
   /// \param Finals Loop variable finalization statements
-  static OMPFuseDirective *Create(const ASTContext &C, SourceLocation StartLoc,
-                                  SourceLocation EndLoc,
-                                  ArrayRef<OMPClause *> Clauses,
-                                  unsigned NumGeneratedTopLevelLoops,
-                                  Stmt *AssociatedStmt, Stmt *TransformedStmt,
-                                  Stmt *PreInits, Stmt *Finals);
+  /// \param FusedLoopIdx Position of the fused loop within the compound
+  ///                     TransformedStmt (0-based). 0 when TransformedStmt is
+  ///                     a single ForStmt.
+  static OMPFuseDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         ArrayRef<OMPClause *> Clauses, unsigned NumGeneratedTopLevelLoops,
+         Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits,
+         Stmt *Finals, unsigned FusedLoopIdx = 0);
 
   /// Build an empty '#pragma omp fuse' AST node for deserialization
   ///
@@ -6180,6 +6206,10 @@ class OMPFuseDirective final
   /// Return finals statement.
   Stmt *getFinals() const { return Data->getChildren()[FinalsOffset]; }
 
+  /// Return position of the fused loop within the CompoundStmt
+  /// TransformedStmt.
+  unsigned getFusedLoopIdx() const { return FusedLoopIdx; }
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == OMPFuseDirectiveClass;
   }
diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h
index a5f357c15f5c4..006a3543ea826 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -1595,6 +1595,11 @@ class SemaOpenMP : public SemaBase {
     SmallVector<LoopAnalysis, 2> Loops;
     /// Additional code required before entering the transformed loop sequence.
     SmallVector<Stmt *> LoopSequencePreInits;
+    /// Finalization statements collected from inner loop transformations
+    /// encountered while analyzing this sequence. The enclosing directive
+    /// must execute these to restore loop variables to their loop-exit values
+    /// so that downstream code observes correct values.
+    SmallVector<Stmt *, 2> InnerFinals;
 
     // Convenience function used when building the LoopSequenceAnalysis.
     static bool isLoopSequenceDerivation(Stmt *S) {
diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp
index ce1a7ec27a119..1e38194a5e67a 100644
--- a/clang/lib/AST/StmtOpenMP.cpp
+++ b/clang/lib/AST/StmtOpenMP.cpp
@@ -438,6 +438,14 @@ Stmt *OMPLoopTransformationDirective::getPreInits() const {
   llvm_unreachable("unexpected object type");
 }
 
+Stmt *OMPLoopTransformationDirective::getFinals() const {
+  if (auto *D = dyn_cast<OMPCanonicalLoopNestTransformationDirective>(S))
+    return D->getFinals();
+  if (auto *D = dyn_cast<OMPCanonicalLoopSequenceTransformationDirective>(S))
+    return D->getFinals();
+  llvm_unreachable("unexpected object type");
+}
+
 Stmt *OMPCanonicalLoopNestTransformationDirective::getTransformedStmt() const {
   switch (getStmtClass()) {
 #define STMT(CLASS, PARENT)
@@ -464,6 +472,19 @@ Stmt *OMPCanonicalLoopNestTransformationDirective::getPreInits() const {
   }
 }
 
+Stmt *OMPCanonicalLoopNestTransformationDirective::getFinals() const {
+  switch (getStmtClass()) {
+#define STMT(CLASS, PARENT)
+#define ABSTRACT_STMT(CLASS)
+#define OMPCANONICALLOOPNESTTRANSFORMATIONDIRECTIVE(CLASS, PARENT)             \
+  case Stmt::CLASS##Class:                                                     \
+    return static_cast<const CLASS *>(this)->getFinals();
+#include "clang/AST/StmtNodes.inc"
+  default:
+    llvm_unreachable("Not a loop transformation for canonical loop nests");
+  }
+}
+
 Stmt *
 OMPCanonicalLoopSequenceTransformationDirective::getTransformedStmt() const {
   switch (getStmtClass()) {
@@ -491,6 +512,19 @@ Stmt *OMPCanonicalLoopSequenceTransformationDirective::getPreInits() const {
   }
 }
 
+Stmt *OMPCanonicalLoopSequenceTransformationDirective::getFinals() const {
+  switch (getStmtClass()) {
+#define STMT(CLASS, PARENT)
+#define ABSTRACT_STMT(CLASS)
+#define OMPCANONICALLOOPSEQUENCETRANSFORMATIONDIRECTIVE(CLASS, PARENT)         \
+  case Stmt::CLASS##Class:                                                     \
+    return static_cast<const CLASS *>(this)->getFinals();
+#include "clang/AST/StmtNodes.inc"
+  default:
+    llvm_unreachable("Not a loop transformation for canonical loop sequences");
+  }
+}
+
 OMPForDirective *OMPForDirective::CreateEmpty(const ASTContext &C,
                                               unsigned NumClauses,
                                               unsigned CollapsedNum,
@@ -624,16 +658,19 @@ OMPSplitDirective *OMPSplitDirective::CreateEmpty(const ASTContext &C,
       SourceLocation(), SourceLocation(), NumLoops);
 }
 
-OMPFuseDirective *OMPFuseDirective::Create(
-    const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
-    ArrayRef<OMPClause *> Clauses, unsigned NumGeneratedTopLevelLoops,
-    Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits, Stmt *Finals) {
+OMPFuseDirective *
+OMPFuseDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+                         SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses,
+                         unsigned NumGeneratedTopLevelLoops,
+                         Stmt *AssociatedStmt, Stmt *TransformedStmt,
+                         Stmt *PreInits, Stmt *Finals, unsigned FusedLoopIdx) {
 
   OMPFuseDirective *Dir = createDirective<OMPFuseDirective>(
       C, Clauses, AssociatedStmt, FinalsOffset + 1, StartLoc, EndLoc);
   Dir->setTransformedStmt(TransformedStmt);
   Dir->setPreInits(PreInits);
   Dir->setFinals(Finals);
+  Dir->setFusedLoopIdx(FusedLoopIdx);
   Dir->setNumGeneratedTopLevelLoops(NumGeneratedTopLevelLoops);
   return Dir;
 }
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index fdf6e0cd1c76c..c557fca1de4fe 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -3279,11 +3279,32 @@ void CodeGenFunction::EmitOMPInterchangeDirective(
 void CodeGenFunction::EmitOMPFuseDirective(const OMPFuseDirective &S) {
   // Emit the de-sugared statement
   OMPTransformDirectiveScopeRAII FuseScope(*this, &S);
-  EmitStmt(S.getTransformedStmt());
 
-  // Emit loop variable finalization as required by OpenMP 6.0 spec to restore
-  // original loop variable values after the loop-transformation construct.
-  if (auto *Finals = S.getFinals())
+  const Stmt *Transformed = S.getTransformedStmt();
+  const Stmt *Finals = S.getFinals();
+
+  // For fuse with a looprange clause, the transformed statement is a
+  // CompoundStmt containing [pre_fusion_loops..., fused_loop,
+  // post_fusion_loops...]. Emit Finals immediately after the fused loop, so
+  // post-fusion loops (and any code after the construct) observe the
+  // finalized loop-exit values.
+  const auto *CS = Finals ? dyn_cast<CompoundStmt>(Transformed) : nullptr;
+  if (CS) {
+    unsigned FusedIdx = S.getFusedLoopIdx();
+    unsigned Idx = 0;
+    for (const Stmt *Child : CS->body()) {
+      EmitStmt(Child);
+      if (Idx == FusedIdx)
+        EmitStmt(Finals);
+      ++Idx;
+    }
+    return;
+  }
+
+  // Non-looprange case: single ForStmt. Emit it and then the finalization
+  // (OpenMP 6.0) that restores loop variables to their loop-exit values.
+  EmitStmt(Transformed);
+  if (Finals)
     EmitStmt(Finals);
 }
 
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index d8a653d36adc5..954467ac91c3b 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -15023,6 +15023,11 @@ bool SemaOpenMP::analyzeLoopSequence(Stmt *LoopSeqStmt,
     Stmt *TransformedStmt = LoopTransform->getTransformedStmt();
     unsigned NumGeneratedTopLevelLoops =
         LoopTransform->getNumGeneratedTopLevelLoops();
+    // Propagate this transformation's Finals (if any) to the enclosing
+    // directive. The enclosing directive will emit them so they execute at
+    // the right point (right after the transformed loops complete).
+    if (Stmt *InnerFinal = LoopTransform->getFinals())
+      SeqAnalysis.InnerFinals.push_back(InnerFinal);
     // Handle the case where transformed statement is not available due to
     // dependent contexts
     if (!TransformedStmt) {
@@ -17206,6 +17211,24 @@ StmtResult SemaOpenMP::ActOnOpenMPFuseDirective(ArrayRef<OMPClause *> Clauses,
     }
   }
 
+  // Build Finals for this fuse and combine with any Finals propagated from
+  // inner loop transformations. This ensures nested transformations'
+  // finalizations are not lost.
+  Stmt *OwnFinals = buildLoopFinalization(Context, FusedLoopHelpers);
+  SmallVector<Stmt *, 4> AllFinalsStmts;
+  for (Stmt *InnerFinal : SeqAnalysis.InnerFinals)
+    if (InnerFinal)
+      AllFinalsStmts.push_back(InnerFinal);
+  if (OwnFinals)
+    AllFinalsStmts.push_back(OwnFinals);
+  Stmt *CombinedFinals = nullptr;
+  if (AllFinalsStmts.size() == 1)
+    CombinedFinals = AllFinalsStmts.front();
+  else if (!AllFinalsStmts.empty())
+    CombinedFinals =
+        CompoundStmt::Create(Context, AllFinalsStmts, FPOptionsOverride(),
+                             SourceLocation(), SourceLocation());
+
   //  In the case of looprange, the result of fuse won't simply
   //  be a single loop (ForStmt), but rather a loop sequence
   //  (CompoundStmt) of 3 parts: the pre-fusion loops, the fused loop
@@ -17216,6 +17239,7 @@ StmtResult SemaOpenMP::ActOnOpenMPFuseDirective(ArrayRef<OMPClause *> Clauses,
   //  treatment is skipped)
 
   Stmt *FusionStmt = FusedForStmt;
+  unsigned FusedLoopIdx = 0;
   if (LRC && CountVal != SeqAnalysis.LoopSeqSize) {
     SmallVector<Stmt *, 4> FinalLoops;
 
@@ -17249,14 +17273,18 @@ StmtResult SemaOpenMP::ActOnOpenMPFuseDirective(ArrayRef<OMPClause *> Clauses,
       FinalLoops.push_back(SeqAnalysis.Loops[I].TheForStmt);
     }
 
-    FinalLoops.insert(FinalLoops.begin() + (FirstVal - 1), FusedForStmt);
+    // Insert the fused loop and record its position. Codegen uses this index
+    // to know where to emit Finals (right after the fused loop, before any
+    // post-fusion loops so that post-fusion code observes finalized values).
+    FusedLoopIdx = FirstVal - 1;
+    FinalLoops.insert(FinalLoops.begin() + FusedLoopIdx, FusedForStmt);
     FusionStmt = CompoundStmt::Create(Context, FinalLoops, FPOptionsOverride(),
                                       SourceLocation(), SourceLocation());
   }
-  return OMPFuseDirective::Create(
-      Context, StartLoc, EndLoc, Clauses, NumGeneratedTopLevelLoops, AStmt,
-      FusionStmt, buildPreInits(Context, PreInits),
-      buildLoopFinalization(Context, FusedLoopHelpers));
+  return OMPFuseDirective::Create(Context, StartLoc, EndLoc, Clauses,
+                                  NumGeneratedTopLevelLoops, AStmt, FusionStmt,
+                                  buildPreInits(Context, PreInits),
+                                  CombinedFinals, FusedLoopIdx);
 }
 
 OMPClause *SemaOpenMP::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 92c555dc427b3..fdf2eebdb5b3d 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -2582,6 +2582,7 @@ void ASTStmtReader::VisitOMPSplitDirective(OMPSplitDirective *D) {
 
 void ASTStmtReader::VisitOMPFuseDirective(OMPFuseDirective *D) {
   VisitOMPCanonicalLoopSequenceTransformationDirective(D);
+  D->setFusedLoopIdx(Record.readInt());
 }
 
 void ASTStmtReader::VisitOMPForDirective(OMPForDirective *D) {
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 513c832c38ffd..6e732f724da31 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -2661,6 +2661,7 @@ void ASTStmtWriter::VisitOMPCanonicalLoopSequenceTransformationDirective(
 
 void ASTStmtWriter::VisitOMPFuseDirective(OMPFuseDirective *D) {
   VisitOMPCanonicalLoopSequenceTransformationDirective(D);
+  Record.writeUInt32(D->getFusedLoopIdx());
   Code = serialization::STMT_OMP_FUSE_DIRECTIVE;
 }
 
diff --git a/clang/test/OpenMP/fuse_codegen.cpp b/clang/test/OpenMP/fuse_codegen.cpp
index bd265e6117262..afce4ed30c44c 100644
--- a/clang/test/OpenMP/fuse_codegen.cpp
+++ b/clang/test/OpenMP/fuse_codegen.cpp
@@ -840,6 +840,8 @@ extern "C" void foo5() {
 // CHECK1-NEXT:    store i64 [[INC]], ptr [[DOTOMP_FUSE_INDEX52]], align 8
 // CHECK1-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP7:![0-9]+]]
 // CHECK1:       [[FOR_END]]:
+// CHECK1-NEXT:    store i32 128, ptr [[I]], align 4
+// CHECK1-NEXT:    store i32 256, ptr [[J]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -958,6 +960,8 @@ extern "C" void foo5() {
 // CHECK1-NEXT:    store i32 [[INC16]], ptr [[DOTOMP_FUSE_INDEX]], align 4
 // CHECK1-NEXT:    br label %[[FOR_COND2]], !llvm.loop [[LOOP9:![0-9]+]]
 // CHECK1:       [[FOR_END17]]:
+// CHECK1-NEXT:    store i32 256, ptr [[J]], align 4
+// CHECK1-NEXT:    store i32 64, ptr [[K]], align 4
 // CHECK1-NEXT:    store i32 42, ptr [[C]], align 4
 // CHECK1-NEXT:    store ptr [[ARR]], ptr [[__RANGE2]], align 8
 // CHECK1-NEXT:    [[TMP25:%.*]] = load ptr, ptr [[__RANGE2]], align 8, !nonnull [[META5]], !align [[META6]]
@@ -987,8 +991,6 @@ extern "C" void foo5() {
 // CHECK1-NEXT:    store ptr [[INCDEC_PTR]], ptr [[__BEGIN2]], align 8
 // CHECK1-NEXT:    br label %[[FOR_COND19]]
 // CHECK1:       [[FOR_END23]]:
-// CHECK1-NEXT:    store i32 256, ptr [[J]], align 4
-// CHECK1-NEXT:    store i32 64, ptr [[K]], align 4
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1032,9 +1034,9 @@ extern "C" void foo5() {
 // CHECK1-NEXT:    [[DOTOMP_FUSE_INDEX29:%.*]] = alloca i64, align 8
 // CHECK1-NEXT:    [[V:%.*]] = alloca ptr, align 8
 // CHECK1-NEXT:    [[CC:%.*]] = alloca i32, align 4
-// CHECK1-NEXT:    [[__RANGE264:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[__BEGIN265:%.*]] = alloca ptr, align 8
-// CHECK1-NEXT:    [[__END267:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[__RANGE268:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[__BEGIN269:%.*]] = alloca ptr, align 8
+// CHECK1-NEXT:    [[__END271:%.*]] = alloca ptr, align 8
 // CHECK1-NEXT:    [[VV:%.*]] = alloca ptr, align 8
 // CHECK1-NEXT:    store i32 0, ptr [[J]], align 4
 // CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_LB0]], align 4
@@ -1231,41 +1233,43 @@ extern "C" void foo5() {
 // CHECK1-NEXT:    store i64 [[INC62]], ptr [[DOTOMP_FUSE_INDEX29]], align 8
 // CHECK1-NEXT:    br label %[[FOR_COND30]], !llvm.loop [[LOOP11:![0-9]+]]
 // CHECK1:       [[FOR_END63]]:
+// CHECK1-NEXT:    store i32 256, ptr [[J]], align 4
+// CHECK1-NEXT:    store i32 512, ptr [[K]], align 4
+// CHECK1-NEXT:    [[TMP57:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK1-NEXT:    [[SUB64:%.*]] = sub nsw i32 [[TMP57]], 0
+// CHECK1-NEXT:    [[DIV65:%.*]] = sdiv i32 [[SUB64]], 1
+// CHECK1-NEXT:    [[MUL66:%.*]] = mul nsw i32 [[DIV65]], 1
+// CHECK1-NEXT:    [[ADD67:%.*]] = add nsw i32 0, [[MUL66]]
+// CHECK1-NEXT:    store i32 [[ADD67]], ptr [[DOTOMP_FUSE_INDEX]], align 4
 // CHECK1-NEXT:    store i32 37, ptr [[CC]], align 4
-// CHECK1-NEXT:    store ptr [[ARR]], ptr [[__RANGE264]], align 8
-// CHECK1-NEXT:    [[TMP57:%.*]] = load ptr, ptr [[__RANGE264]], align 8, !nonnull [[META5]], !align [[META6]]
-// CHECK1-NEXT:    [[ARRAYDECAY66:%.*]] = getelementptr inbounds [256 x double], ptr [[TMP57]], i64 0, i64 0
-// CHECK1-NEXT:    store ptr [[ARRAYDECAY66]], ptr [[__BEGIN265]], align 8
-// CHECK1-NEXT:    [[TMP58:%.*]] = load ptr, ptr [[__RANGE264]], align 8, !nonnull [[META5]], !align [[META6]]
-// CHECK1-NEXT:    [[ARRAYDECAY68:%.*]] = getelementptr inbounds [256 x double], ptr [[TMP58]], i64 0, i64 0
-// CHECK1-NEXT:    [[ADD_PTR69:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY68]], i64 256
-// CHECK1-NEXT:    store ptr [[ADD_PTR69]], ptr [[__END267]], align 8
-// CHECK1-NEXT:    br label %[[FOR_COND70:.*]]
-// CHECK1:       [[FOR_COND70]]:
-// CHECK1-NEXT:    [[TMP59:%.*]] = load ptr, ptr [[__BEGIN265]], align 8
-// CHECK1-NEXT:    [[TMP60:%.*]] = load ptr, ptr [[__END267]], align 8
-// CHECK1-NEXT:    [[CMP71:%.*]] = icmp ne ptr [[TMP59]], [[TMP60]]
-// CHECK1-NEXT:    br i1 [[CMP71]], label %[[FOR_BODY72:.*]], label %[[FOR_END74:.*]]
-// CHECK1:       [[FOR_BODY72]]:
-// CHECK1-NEXT:    [[TMP61:%.*]] = load ptr, ptr [[__BEGIN265]], align 8
-// CHECK1-NEXT:    store ptr [[TMP61]], ptr [[VV]], align 8
-// CHECK1-NEXT:    [[TMP62:%.*]] = load i32, ptr [[CC]], align 4
-// CHECK1-NEXT:    [[TMP63:%.*]] = load ptr, ptr [[VV]], align 8, !nonnull [[META5]], !align [[META6]]
-// CHECK1-NEXT:    [[TMP64:%.*]] = load double, ptr [[TMP63]], align 8
-// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP62]], double noundef [[TMP64]])
-// CHECK1-NEXT:    br label %[[FOR_INC73:.*]]
-// CHECK1:       [[FOR_INC73]]:
-// CHECK1-NEXT:    [[TMP65:%.*]] = load ptr, ptr [[__BEGIN265]], align 8
-// CHECK1-NEXT:    [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP65]], i32 1
-// CHECK1-NEXT:    store ptr [[INCDEC_PTR]], ptr [[__BEGIN265]], align 8
-// CHECK1-NEXT:    br label %[[FOR_COND70]]
-// CHECK1:       [[FOR_END74]]:
-// CHECK1-NEXT:    [[TMP66:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
-// CHECK1-NEXT:    [[SUB75:%.*]] = sub nsw i32 [[TMP66]], 0
-// CHECK1-NEXT:    [[DIV76:%.*]] = sdiv i32 [[SUB75]], 1
-// CHECK1-NEXT:    [[MUL77:%.*]] = mul nsw i32 [[DIV76]], 1
-// CHECK1-NEXT:    [[ADD78:%.*]] = add nsw i32 0, [[MUL77]]
-// CHECK1-NEXT:    store i32 [[ADD78]], ptr [[DOTOMP_FUSE_INDEX]], align 4
+// CHECK1-NEXT:    store ptr [[ARR]], ptr [[__RANGE268]], align 8
+// CHECK1-NEXT:    [[TMP58:%.*]] = load ptr, ptr [[__RANGE268]], align 8, !nonnull [[META5]], !align [[META6]]
+// CHECK1-NEXT:    [[ARRAYDECAY70:%.*]] = getelementptr inbounds [256 x double], ptr [[TMP58]], i64 0, i64 0
+// CHECK1-NEXT:    store ptr [[ARRAYDECAY70]], ptr [[__BEGIN269]], align 8
+// CHECK1-NEXT:    [[TMP59:%.*]] = load ptr, ptr [[__RANGE268]], align 8, !nonnull [[META5]], !align [[META6]]
+// CHECK1-NEXT:    [[ARRAYDECAY72:%.*]] = getelementptr inbounds [256 x double], ptr [[TMP59]], i64 0, i64 0
+// CHECK1-NEXT:    [[ADD_PTR73:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY72]], i64 256
+// CHECK1-NEXT:    store ptr [[ADD_PTR73]], ptr [[__END271]], align 8
+// CHECK1-NEXT:    br label %[[FOR_COND74:.*]]
+// CHECK1:       [[FOR_COND74]]:
+// CHECK1-NEXT:    [[TMP60:%.*]] = load ptr, ptr [[__BEGIN269]], align 8
+// CHECK1-NEXT:    [[TMP61:%.*]] = load ptr, ptr [[__END271]], align 8
+// CHECK1-NEXT:    [[CMP75:%.*]] = icmp ne ptr [[TMP60]], [[TMP61]]
+// CHECK1-NEXT:    br i1 [[CMP75]], label %[[FOR_BODY76:.*]], label %[[FOR_END78:.*]]
+// CHECK1:       [[FOR_BODY76]]:
+// CHECK1-NEXT:    [[TMP62:%.*]] = load ptr, ptr [[__BEGIN269]], align 8
+// CHECK1-NEXT:    store ptr [[TMP62]], ptr [[VV]], align 8
+// CHECK1-NEXT:    [[TMP63:%.*]] = load i32, ptr [[CC]], align 4
+// CHECK1-NEXT:    [[TMP64:%.*]] = load ptr, ptr [[VV]], align 8, !nonnull [[META5]], !align [[META6]]
+// CHECK1-NEXT:    [[TMP65:%.*]] = load double, ptr [[TMP64]], align 8
+// CHECK1-NEXT:    call void (...) @body(i32 noundef [[TMP63]], double noundef [[TMP65]])
+// CHECK1-NEXT:    br label %[[FOR_INC77:.*]]
+// CHECK1:       [[FOR_INC77]]:
+// CHECK1-NEXT:    [[TMP66:%.*]] = load ptr, ptr [[__BEGIN269]], align 8
+// CHECK1-NEXT:    [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP66]], i32 1
+// CHECK1-NEXT:    store ptr [[INCDEC_PTR]], ptr [[__BEGIN269]], align 8
+// CHECK1-NEXT:    br label %[[FOR_COND74]]
+// CHECK1:       [[FOR_END78]]:
 // CHECK1-NEXT:    ret void
 //
 //
@@ -1755,6 +1759,8 @@ extern "C" void foo5() {
 // CHECK2-NEXT:    store i64 [[INC]], ptr [[DOTOMP_FUSE_INDEX52]], align 8
 // CHECK2-NEXT:    br label %[[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
 // CHECK2:       [[FOR_END]]:
+// CHECK2-NEXT:    store i32 128, ptr [[I]], align 4
+// CHECK2-NEXT:    store i32 256, ptr [[J]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1873,6 +1879,8 @@ extern "C" void foo5() {
 // CHECK2-NEXT:    store i32 [[INC16]], ptr [[DOTOMP_FUSE_INDEX]], align 4
 // CHECK2-NEXT:    br label %[[FOR_COND2]], !llvm.loop [[LOOP8:![0-9]+]]
 // CHECK2:       [[FOR_END17]]:
+// CHECK2-NEXT:    store i32 256, ptr [[J]], align 4
+// CHECK2-NEXT:    store i32 64, ptr [[K]], align 4
 // CHECK2-NEXT:    store i32 42, ptr [[C]], align 4
 // CHECK2-NEXT:    store ptr [[ARR]], ptr [[__RANGE2]], align 8
 // CHECK2-NEXT:    [[TMP25:%.*]] = load ptr, ptr [[__RANGE2]], align 8, !nonnull [[META4]], !align [[META5]]
@@ -1902,8 +1910,6 @@ extern "C" void foo5() {
 // CHECK2-NEXT:    store ptr [[INCDEC_PTR]], ptr [[__BEGIN2]], align 8
 // CHECK2-NEXT:    br label %[[FOR_COND19]]
 // CHECK2:       [[FOR_END23]]:
-// CHECK2-NEXT:    store i32 256, ptr [[J]], align 4
-// CHECK2-NEXT:    store i32 64, ptr [[K]], align 4
 // CHECK2-NEXT:    ret void
 //
 //
@@ -1947,9 +1953,9 @@ extern "C" void foo5() {
 // CHECK2-NEXT:    [[DOTOMP_FUSE_INDEX29:%.*]] = alloca i64, align 8
 // CHECK2-NEXT:    [[V:%.*]] = alloca ptr, align 8
 // CHECK2-NEXT:    [[CC:%.*]] = alloca i32, align 4
-// CHECK2-NEXT:    [[__RANGE264:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[__BEGIN265:%.*]] = alloca ptr, align 8
-// CHECK2-NEXT:    [[__END267:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[__RANGE268:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[__BEGIN269:%.*]] = alloca ptr, align 8
+// CHECK2-NEXT:    [[__END271:%.*]] = alloca ptr, align 8
 // CHECK2-NEXT:    [[VV:%.*]] = alloca ptr, align 8
 // CHECK2-NEXT:    store i32 0, ptr [[J]], align 4
 // CHECK2-NEXT:    store i32 0, ptr [[DOTOMP_LB0]], align 4
@@ -2146,41 +2152,43 @@ extern "C" void foo5() {
 // CHECK2-NEXT:    store i64 [[INC62]], ptr [[DOTOMP_FUSE_INDEX29]], align 8
 // CHECK2-NEXT:    br label %[[FOR_COND30]], !llvm.loop [[LOOP10:![0-9]+]]
 // CHECK2:       [[FOR_END63]]:
+// CHECK2-NEXT:    store i32 256, ptr [[J]], align 4
+// CHECK2-NEXT:    store i32 512, ptr [[K]], align 4
+// CHECK2-NEXT:    [[TMP57:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
+// CHECK2-NEXT:    [[SUB64:%.*]] = sub nsw i32 [[TMP57]], 0
+// CHECK2-NEXT:    [[DIV65:%.*]] = sdiv i32 [[SUB64]], 1
+// CHECK2-NEXT:    [[MUL66:%.*]] = mul nsw i32 [[DIV65]], 1
+// CHECK2-NEXT:    [[ADD67:%.*]] = add nsw i32 0, [[MUL66]]
+// CHECK2-NEXT:    store i32 [[ADD67]], ptr [[DOTOMP_FUSE_INDEX]], align 4
 // CHECK2-NEXT:    store i32 37, ptr [[CC]], align 4
-// CHECK2-NEXT:    store ptr [[ARR]], ptr [[__RANGE264]], align 8
-// CHECK2-NEXT:    [[TMP57:%.*]] = load ptr, ptr [[__RANGE264]], align 8, !nonnull [[META4]], !align [[META5]]
-// CHECK2-NEXT:    [[ARRAYDECAY66:%.*]] = getelementptr inbounds [256 x double], ptr [[TMP57]], i64 0, i64 0
-// CHECK2-NEXT:    store ptr [[ARRAYDECAY66]], ptr [[__BEGIN265]], align 8
-// CHECK2-NEXT:    [[TMP58:%.*]] = load ptr, ptr [[__RANGE264]], align 8, !nonnull [[META4]], !align [[META5]]
-// CHECK2-NEXT:    [[ARRAYDECAY68:%.*]] = getelementptr inbounds [256 x double], ptr [[TMP58]], i64 0, i64 0
-// CHECK2-NEXT:    [[ADD_PTR69:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY68]], i64 256
-// CHECK2-NEXT:    store ptr [[ADD_PTR69]], ptr [[__END267]], align 8
-// CHECK2-NEXT:    br label %[[FOR_COND70:.*]]
-// CHECK2:       [[FOR_COND70]]:
-// CHECK2-NEXT:    [[TMP59:%.*]] = load ptr, ptr [[__BEGIN265]], align 8
-// CHECK2-NEXT:    [[TMP60:%.*]] = load ptr, ptr [[__END267]], align 8
-// CHECK2-NEXT:    [[CMP71:%.*]] = icmp ne ptr [[TMP59]], [[TMP60]]
-// CHECK2-NEXT:    br i1 [[CMP71]], label %[[FOR_BODY72:.*]], label %[[FOR_END74:.*]]
-// CHECK2:       [[FOR_BODY72]]:
-// CHECK2-NEXT:    [[TMP61:%.*]] = load ptr, ptr [[__BEGIN265]], align 8
-// CHECK2-NEXT:    store ptr [[TMP61]], ptr [[VV]], align 8
-// CHECK2-NEXT:    [[TMP62:%.*]] = load i32, ptr [[CC]], align 4
-// CHECK2-NEXT:    [[TMP63:%.*]] = load ptr, ptr [[VV]], align 8, !nonnull [[META4]], !align [[META5]]
-// CHECK2-NEXT:    [[TMP64:%.*]] = load double, ptr [[TMP63]], align 8
-// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP62]], double noundef [[TMP64]])
-// CHECK2-NEXT:    br label %[[FOR_INC73:.*]]
-// CHECK2:       [[FOR_INC73]]:
-// CHECK2-NEXT:    [[TMP65:%.*]] = load ptr, ptr [[__BEGIN265]], align 8
-// CHECK2-NEXT:    [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP65]], i32 1
-// CHECK2-NEXT:    store ptr [[INCDEC_PTR]], ptr [[__BEGIN265]], align 8
-// CHECK2-NEXT:    br label %[[FOR_COND70]]
-// CHECK2:       [[FOR_END74]]:
-// CHECK2-NEXT:    [[TMP66:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
-// CHECK2-NEXT:    [[SUB75:%.*]] = sub nsw i32 [[TMP66]], 0
-// CHECK2-NEXT:    [[DIV76:%.*]] = sdiv i32 [[SUB75]], 1
-// CHECK2-NEXT:    [[MUL77:%.*]] = mul nsw i32 [[DIV76]], 1
-// CHECK2-NEXT:    [[ADD78:%.*]] = add nsw i32 0, [[MUL77]]
-// CHECK2-NEXT:    store i32 [[ADD78]], ptr [[DOTOMP_FUSE_INDEX]], align 4
+// CHECK2-NEXT:    store ptr [[ARR]], ptr [[__RANGE268]], align 8
+// CHECK2-NEXT:    [[TMP58:%.*]] = load ptr, ptr [[__RANGE268]], align 8, !nonnull [[META4]], !align [[META5]]
+// CHECK2-NEXT:    [[ARRAYDECAY70:%.*]] = getelementptr inbounds [256 x double], ptr [[TMP58]], i64 0, i64 0
+// CHECK2-NEXT:    store ptr [[ARRAYDECAY70]], ptr [[__BEGIN269]], align 8
+// CHECK2-NEXT:    [[TMP59:%.*]] = load ptr, ptr [[__RANGE268]], align 8, !nonnull [[META4]], !align [[META5]]
+// CHECK2-NEXT:    [[ARRAYDECAY72:%.*]] = getelementptr inbounds [256 x double], ptr [[TMP59]], i64 0, i64 0
+// CHECK2-NEXT:    [[ADD_PTR73:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY72]], i64 256
+// CHECK2-NEXT:    store ptr [[ADD_PTR73]], ptr [[__END271]], align 8
+// CHECK2-NEXT:    br label %[[FOR_COND74:.*]]
+// CHECK2:       [[FOR_COND74]]:
+// CHECK2-NEXT:    [[TMP60:%.*]] = load ptr, ptr [[__BEGIN269]], align 8
+// CHECK2-NEXT:    [[TMP61:%.*]] = load ptr, ptr [[__END271]], align 8
+// CHECK2-NEXT:    [[CMP75:%.*]] = icmp ne ptr [[TMP60]], [[TMP61]]
+// CHECK2-NEXT:    br i1 [[CMP75]], label %[[FOR_BODY76:.*]], label %[[FOR_END78:.*]]
+// CHECK2:       [[FOR_BODY76]]:
+// CHECK2-NEXT:    [[TMP62:%.*]] = load ptr, ptr [[__BEGIN269]], align 8
+// CHECK2-NEXT:    store ptr [[TMP62]], ptr [[VV]], align 8
+// CHECK2-NEXT:    [[TMP63:%.*]] = load i32, ptr [[CC]], align 4
+// CHECK2-NEXT:    [[TMP64:%.*]] = load ptr, ptr [[VV]], align 8, !nonnull [[META4]], !align [[META5]]
+// CHECK2-NEXT:    [[TMP65:%.*]] = load double, ptr [[TMP64]], align 8
+// CHECK2-NEXT:    call void (...) @body(i32 noundef [[TMP63]], double noundef [[TMP65]])
+// CHECK2-NEXT:    br label %[[FOR_INC77:.*]]
+// CHECK2:       [[FOR_INC77]]:
+// CHECK2-NEXT:    [[TMP66:%.*]] = load ptr, ptr [[__BEGIN269]], align 8
+// CHECK2-NEXT:    [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw double, ptr [[TMP66]], i32 1
+// CHECK2-NEXT:    store ptr [[INCDEC_PTR]], ptr [[__BEGIN269]], align 8
+// CHECK2-NEXT:    br label %[[FOR_COND74]]
+// CHECK2:       [[FOR_END78]]:
 // CHECK2-NEXT:    ret void
 //
 //



More information about the cfe-commits mailing list