[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