[polly] r212198 - Derive run-time conditions for delinearization

Tobias Grosser tobias at grosser.es
Wed Jul 2 10:47:48 PDT 2014


Author: grosser
Date: Wed Jul  2 12:47:48 2014
New Revision: 212198

URL: http://llvm.org/viewvc/llvm-project?rev=212198&view=rev
Log:
Derive run-time conditions for delinearization

As our delinearization works optimistically, we need in some cases run-time
checks that verify our optimistic assumptions. A simple example is the
following code:

void foo(long n, long m, long o, double A[n][m][o]) {

  for (long i = 0; i < 100; i++)
    for (long j = 0; j < 150; j++)
      for (long k = 0; k < 200; k++)
        A[i][j][k] = 1.0;
}

After clang linearized the access to A and we delinearized it again to
A[i][j][k] we need to ensure that we do not access the delinearized array
out of bounds (this information is not available in LLVM-IR). Hence, we
need to verify the following constraints at run-time:

CHECK:   Assumed Context:
CHECK:   [o, m] -> {  : m >= 150 and o >= 200 }

Added:
    polly/trunk/test/Isl/Ast/simple-run-time-condition.ll
    polly/trunk/test/Isl/CodeGen/multidim_2d_parametric_array_static_loop_bounds.ll
      - copied, changed from r212186, polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll
    polly/trunk/test/Isl/CodeGen/run-time-condition-with-scev-parameters.ll
    polly/trunk/test/ScopInfo/multidim_2d_outer_larger_than_zero.ll
      - copied, changed from r212186, polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll
    polly/trunk/test/ScopInfo/multidim_2d_parametric_array_static_loop_bounds.ll
      - copied, changed from r212186, polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll
    polly/trunk/test/ScopInfo/multidim_3d_parametric_array_static_loop_bounds.ll
      - copied, changed from r212186, polly/trunk/test/ScopInfo/multidim_only_ivs_3d.ll
Modified:
    polly/trunk/include/polly/ScopInfo.h
    polly/trunk/lib/Analysis/ScopInfo.cpp
    polly/trunk/lib/CodeGen/IslAst.cpp
    polly/trunk/lib/CodeGen/IslCodeGeneration.cpp
    polly/trunk/test/ScopInfo/multidim_2d-diagonal-matrix.ll
    polly/trunk/test/ScopInfo/multidim_ivs_and_integer_offsets_3d.ll
    polly/trunk/test/ScopInfo/multidim_ivs_and_parameteric_offsets_3d.ll
    polly/trunk/test/ScopInfo/multidim_nested_start_integer.ll
    polly/trunk/test/ScopInfo/multidim_nested_start_share_parameter.ll
    polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll
    polly/trunk/test/ScopInfo/multidim_only_ivs_3d.ll
    polly/trunk/test/ScopInfo/multidim_only_ivs_3d_cast.ll
    polly/trunk/test/ScopInfo/multidim_only_ivs_3d_reverse.ll
    polly/trunk/test/ScopInfo/simple_loop_1.ll

Modified: polly/trunk/include/polly/ScopInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopInfo.h?rev=212198&r1=212197&r2=212198&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopInfo.h (original)
+++ polly/trunk/include/polly/ScopInfo.h Wed Jul  2 12:47:48 2014
@@ -140,6 +140,8 @@ private:
   /// Updated access relation read from JSCOP file.
   isl_map *newAccessRelation;
 
+  void assumeNoOutOfBound(const IRAccess &Access);
+
 public:
   // @brief Create a memory access from an access in LLVM-IR.
   //
@@ -177,6 +179,9 @@ public:
 
   isl_map *getAccessRelation() const;
 
+  /// @brief Return the space in which the access relation lives in.
+  __isl_give isl_space *getAccessRelationSpace() const;
+
   /// @brief Get an isl string representing this access function.
   std::string getAccessRelationStr() const;
 
@@ -541,6 +546,9 @@ class Scop {
   /// @brief Add the bounds of the parameters to the context.
   void addParameterBounds();
 
+  /// @brief Simplify the assumed context.
+  void simplifyAssumedContext();
+
   /// Build the Scop and Statement with precalculated scop information.
   void buildScop(TempScop &TempScop, const Region &CurRegion,
                  // Loops in Scop containing CurRegion
@@ -631,9 +639,27 @@ public:
   /// @return The assumed context of this Scop.
   __isl_give isl_set *getAssumedContext() const;
 
+  /// @brief Add assumptions to assumed context.
+  ///
+  /// The assumptions added will be assumed to hold during the execution of the
+  /// scop. However, as they are generally not statically provable, at code
+  /// generation time run-time checks will be generated that ensure the
+  /// assumptions hold.
+  ///
+  /// WARNING: We currently exploit in simplifyAssumedContext the knowledge
+  ///          that assumptions do not change the set of statement instances
+  ///          executed.
+  ///
+  /// @param Set A set describing relations between parameters that are assumed
+  ///            to hold.
+  void addAssumption(__isl_take isl_set *Set);
+
   /// @brief Get an isl string representing the context.
   std::string getContextStr() const;
 
+  /// @brief Get an isl string representing the assumed context.
+  std::string getAssumedContextStr() const;
+
   /// @name Statements Iterators
   ///
   /// These iterators iterate over all statements of this Scop.

Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=212198&r1=212197&r2=212198&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Wed Jul  2 12:47:48 2014
@@ -342,6 +342,10 @@ std::string MemoryAccess::getAccessRelat
   return stringFromIslObj(AccessRelation);
 }
 
+__isl_give isl_space *MemoryAccess::getAccessRelationSpace() const {
+  return isl_map_get_space(AccessRelation);
+}
+
 isl_map *MemoryAccess::getNewAccessRelation() const {
   return isl_map_copy(newAccessRelation);
 }
@@ -356,6 +360,66 @@ isl_basic_map *MemoryAccess::createBasic
       isl_basic_set_universe(Space));
 }
 
+// Formalize no out-of-bound access assumption
+//
+// When delinearizing array accesses we optimistically assume that the
+// delinearized accesses do not access out of bound locations (the subscript
+// expression of each array evaluates for each statement instance that is
+// executed to a value that is larger than zero and strictly smaller than the
+// size of the corresponding dimension). The only exception is the outermost
+// dimension for which we do not assume any upper bound.  At this point we
+// formalize this assumption to ensure that at code generation time the relevant
+// run-time checks can be generated.
+//
+// To find the set of constraints necessary to avoid out of bound accesses, we
+// first build the set of data locations that are not within array bounds. We
+// then apply the reverse access relation to obtain the set of iterations that
+// may contain invalid accesses and reduce this set of iterations to the ones
+// that are actually executed by intersecting them with the domain of the
+// statement. If we now project out all loop dimensions, we obtain a set of
+// parameters that may cause statement instances to be executed that may
+// possibly yield out of bound memory accesses. The complement of these
+// constraints is the set of constraints that needs to be assumed to ensure such
+// statement instances are never executed.
+void MemoryAccess::assumeNoOutOfBound(const IRAccess &Access) {
+  isl_space *Space = isl_space_range(getAccessRelationSpace());
+  isl_set *Outside = isl_set_empty(isl_space_copy(Space));
+  for (int i = 0, Size = Access.Subscripts.size(); i < Size; ++i) {
+    isl_local_space *LS = isl_local_space_from_space(isl_space_copy(Space));
+    isl_pw_aff *Var =
+        isl_pw_aff_var_on_domain(isl_local_space_copy(LS), isl_dim_set, i);
+    isl_pw_aff *Zero = isl_pw_aff_zero_on_domain(LS);
+
+    isl_set *DimOutside;
+
+    if (i == 0) {
+      DimOutside = isl_pw_aff_lt_set(Var, Zero);
+    } else {
+      DimOutside = isl_pw_aff_lt_set(isl_pw_aff_copy(Var), Zero);
+      isl_pw_aff *SizeE =
+          SCEVAffinator::getPwAff(Statement, Access.Sizes[i - 1]);
+
+      SizeE = isl_pw_aff_drop_dims(SizeE, isl_dim_in, 0,
+                                   Statement->getNumIterators());
+      SizeE = isl_pw_aff_add_dims(SizeE, isl_dim_in,
+                                  isl_space_dim(Space, isl_dim_set));
+      SizeE = isl_pw_aff_set_tuple_id(
+          SizeE, isl_dim_in, isl_space_get_tuple_id(Space, isl_dim_set));
+
+      DimOutside = isl_set_union(DimOutside, isl_pw_aff_le_set(SizeE, Var));
+    }
+
+    Outside = isl_set_union(Outside, DimOutside);
+  }
+
+  Outside = isl_set_apply(Outside, isl_map_reverse(getAccessRelation()));
+  Outside = isl_set_intersect(Outside, Statement->getDomain());
+  Outside = isl_set_params(Outside);
+  Outside = isl_set_complement(Outside);
+  Statement->getParent()->addAssumption(Outside);
+  isl_space_free(Space);
+}
+
 MemoryAccess::MemoryAccess(const IRAccess &Access, const Instruction *AccInst,
                            ScopStmt *Statement)
     : Statement(Statement), Inst(AccInst), newAccessRelation(nullptr) {
@@ -409,6 +473,7 @@ MemoryAccess::MemoryAccess(const IRAcces
   isl_space_free(Space);
   AccessRelation = isl_map_set_tuple_name(AccessRelation, isl_dim_out,
                                           getBaseName().c_str());
+  assumeNoOutOfBound(Access);
 }
 
 void MemoryAccess::realignParams() {
@@ -1051,6 +1116,39 @@ void Scop::realignParams() {
     Stmt->realignParams();
 }
 
+void Scop::simplifyAssumedContext() {
+  // The parameter constraints of the iteration domains give us a set of
+  // constraints that need to hold for all cases where at least a single
+  // statement iteration is executed in the whole scop. We now simplify the
+  // assumed context under the assumption that such constraints hold and at
+  // least a single statement iteration is executed. For cases where no
+  // statement instances are executed, the assumptions we have taken about
+  // the executed code do not matter and can be changed.
+  //
+  // WARNING: This only holds if the assumptions we have taken do not reduce
+  //          the set of statement instances that are executed. Otherwise we
+  //          may run into a case where the iteration domains suggest that
+  //          for a certain set of parameter constraints no code is executed,
+  //          but in the original program some computation would have been
+  //          performed. In such a case, modifying the run-time conditions and
+  //          possibly influencing the run-time check may cause certain scops
+  //          to not be executed.
+  //
+  // Example:
+  //
+  //   When delinearizing the following code:
+  //
+  //     for (long i = 0; i < 100; i++)
+  //       for (long j = 0; j < m; j++)
+  //         A[i+p][j] = 1.0;
+  //
+  //   we assume that the condition m <= 0 or (m >= 1 and p >= 0) holds as
+  //   otherwise we would access out of bound data. Now, knowing that code is
+  //   only executed for the case m >= 0, it is sufficient to assume p >= 0.
+  AssumedContext =
+      isl_set_gist_params(AssumedContext, isl_union_set_params(getDomains()));
+}
+
 Scop::Scop(TempScop &tempScop, LoopInfo &LI, ScalarEvolution &ScalarEvolution,
            isl_ctx *Context)
     : SE(&ScalarEvolution), R(tempScop.getMaxRegion()),
@@ -1069,6 +1167,7 @@ Scop::Scop(TempScop &tempScop, LoopInfo
 
   realignParams();
   addParameterBounds();
+  simplifyAssumedContext();
 
   assert(NestLoops.empty() && "NestLoops not empty at top level!");
 }
@@ -1083,6 +1182,9 @@ Scop::~Scop() {
 }
 
 std::string Scop::getContextStr() const { return stringFromIslObj(Context); }
+std::string Scop::getAssumedContextStr() const {
+  return stringFromIslObj(AssumedContext);
+}
 
 std::string Scop::getNameStr() const {
   std::string ExitName, EntryName;
@@ -1110,6 +1212,10 @@ __isl_give isl_set *Scop::getAssumedCont
   return isl_set_copy(AssumedContext);
 }
 
+void Scop::addAssumption(__isl_take isl_set *Set) {
+  AssumedContext = isl_set_intersect(AssumedContext, Set);
+}
+
 void Scop::printContext(raw_ostream &OS) const {
   OS << "Context:\n";
 
@@ -1120,6 +1226,14 @@ void Scop::printContext(raw_ostream &OS)
 
   OS.indent(4) << getContextStr() << "\n";
 
+  OS.indent(4) << "Assumed Context:\n";
+  if (!AssumedContext) {
+    OS.indent(4) << "n/a\n\n";
+    return;
+  }
+
+  OS.indent(4) << getAssumedContextStr() << "\n";
+
   for (const SCEV *Parameter : Parameters) {
     int Dim = ParameterIds.find(Parameter)->second;
     OS.indent(4) << "p" << Dim << ": " << *Parameter << "\n";

Modified: polly/trunk/lib/CodeGen/IslAst.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslAst.cpp?rev=212198&r1=212197&r2=212198&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslAst.cpp (original)
+++ polly/trunk/lib/CodeGen/IslAst.cpp Wed Jul  2 12:47:48 2014
@@ -341,7 +341,7 @@ void IslAst::buildRunCondition(__isl_kee
   PwZero = isl_pw_aff_intersect_domain(
       PwZero, isl_set_complement(S->getAssumedContext()));
 
-  isl_pw_aff *Cond = isl_pw_aff_union_max(PwZero, PwOne);
+  isl_pw_aff *Cond = isl_pw_aff_union_max(PwOne, PwZero);
 
   RunCondition = isl_ast_build_expr_from_pw_aff(Context, Cond);
 }

Modified: polly/trunk/lib/CodeGen/IslCodeGeneration.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslCodeGeneration.cpp?rev=212198&r1=212197&r2=212198&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslCodeGeneration.cpp (original)
+++ polly/trunk/lib/CodeGen/IslCodeGeneration.cpp Wed Jul  2 12:47:48 2014
@@ -1151,6 +1151,8 @@ public:
 
     IslNodeBuilder NodeBuilder(Builder, Annotator, this);
 
+    Builder.SetInsertPoint(StartBlock->getSinglePredecessor()->begin());
+    NodeBuilder.addParameters(S.getContext());
     // Build condition that evaluates at run-time if all assumptions taken
     // for the scop hold. If we detect some assumptions do not hold, the
     // original code is executed.
@@ -1160,8 +1162,8 @@ public:
     BasicBlock *PrevBB = StartBlock->getUniquePredecessor();
     BranchInst *Branch = dyn_cast<BranchInst>(PrevBB->getTerminator());
     Branch->setCondition(V);
+    Builder.SetInsertPoint(StartBlock->begin());
 
-    NodeBuilder.addParameters(S.getContext());
     NodeBuilder.create(Ast);
     return true;
   }

Added: polly/trunk/test/Isl/Ast/simple-run-time-condition.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/Ast/simple-run-time-condition.ll?rev=212198&view=auto
==============================================================================
--- polly/trunk/test/Isl/Ast/simple-run-time-condition.ll (added)
+++ polly/trunk/test/Isl/Ast/simple-run-time-condition.ll Wed Jul  2 12:47:48 2014
@@ -0,0 +1,94 @@
+; RUN: opt %loadPolly -polly-ast -analyze -polly-delinearize < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; void foo(long n, long m, int o, double A[n][m], long p, long q) {
+;
+; if (o >= 0)
+;   for (long i = 0; i < n; i++)
+;     for (long j = 0; j < m; j++)
+;         A[i+p][j+q] = 1.0;
+; else
+;   for (long i = 0; i < n; i++)
+;     for (long j = 0; j < m; j++)
+;         A[i+p][j+q-100] = 1.0;
+;
+
+; This test case is meant to verify that the run-time condition generated
+; for the delinearization is simplified such that conditions that would not
+; cause any code to be executed are not generated.
+
+; CHECK: if ((q == 100 && o <= 0 && p >= 0) || (q == 0 && o >= 1 && p >= 0) ? 1 : 0)
+
+; CHECK:     if (o >= 1) {
+; CHECK:       for (int c1 = 0; c1 < n; c1 += 1)
+; CHECK:         for (int c3 = 0; c3 < m; c3 += 1)
+; CHECK:           Stmt_for_j(c1, c3);
+; CHECK:     } else
+; CHECK:       for (int c1 = 0; c1 < n; c1 += 1)
+; CHECK:         for (int c3 = 0; c3 < m; c3 += 1)
+; CHECK:           Stmt_for_j_1(c1, c3);
+
+; CHECK: else
+; CHECK:     {  /* original code */ }
+
+define void @foo(i64 %n, i64 %m, i64 %o, double* %A, i64 %p, i64 %q) {
+entry:
+  br label %cond
+
+cond:
+  %cmp = icmp sgt i64 %o, 0
+  br i1 %cmp, label %for.i, label %for.i.1
+
+for.i:
+  %i = phi i64 [ 0, %cond ], [ %i.inc, %for.i.inc ]
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 0, %for.i ], [ %j.inc, %for.j.inc ]
+  %offset0 = add nsw i64 %i, %p
+  %subscript0 = mul i64 %offset0, %m
+  %offset1 = add nsw i64 %j, %q
+  %subscript1 = add i64 %offset1, %subscript0
+  %idx = getelementptr inbounds double* %A, i64 %subscript1
+  store double 1.0, double* %idx
+  br label %for.j.inc
+
+for.j.inc:
+  %j.inc = add nsw i64 %j, 1
+  %j.exitcond = icmp eq i64 %j.inc, %m
+  br i1 %j.exitcond, label %for.i.inc, label %for.j
+
+for.i.inc:
+  %i.inc = add nsw i64 %i, 1
+  %i.exitcond = icmp eq i64 %i.inc, %n
+  br i1 %i.exitcond, label %end, label %for.i
+
+for.i.1:
+  %i.1 = phi i64 [ 0, %cond ], [ %i.inc.1, %for.i.inc.1 ]
+  br label %for.j.1
+
+for.j.1:
+  %j.1 = phi i64 [ 0, %for.i.1 ], [ %j.inc.1, %for.j.inc.1 ]
+  %offset0.1 = add nsw i64 %i.1, %p
+  %subscript0.1 = mul i64 %offset0.1, %m
+  %offset1.1 = add nsw i64 %j.1, %q
+  %subscript1.1 = add i64 %offset1.1, %subscript0.1
+  %subscript1.2 = sub i64 %subscript1.1, 100
+  %idx.1 = getelementptr inbounds double* %A, i64 %subscript1.2
+  store double 1.0, double* %idx.1
+  br label %for.j.inc.1
+
+for.j.inc.1:
+  %j.inc.1 = add nsw i64 %j.1, 1
+  %j.exitcond.1 = icmp eq i64 %j.inc.1, %m
+  br i1 %j.exitcond.1, label %for.i.inc.1, label %for.j.1
+
+for.i.inc.1:
+  %i.inc.1 = add nsw i64 %i.1, 1
+  %i.exitcond.1 = icmp eq i64 %i.inc.1, %n
+  br i1 %i.exitcond.1, label %end, label %for.i.1
+
+end:
+  ret void
+}

Copied: polly/trunk/test/Isl/CodeGen/multidim_2d_parametric_array_static_loop_bounds.ll (from r212186, polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll)
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/multidim_2d_parametric_array_static_loop_bounds.ll?p2=polly/trunk/test/Isl/CodeGen/multidim_2d_parametric_array_static_loop_bounds.ll&p1=polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll&r1=212186&r2=212198&rev=212198&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll (original)
+++ polly/trunk/test/Isl/CodeGen/multidim_2d_parametric_array_static_loop_bounds.ll Wed Jul  2 12:47:48 2014
@@ -1,25 +1,20 @@
-; RUN: opt %loadPolly -polly-scops -analyze -polly-delinearize < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen-isl -S -polly-delinearize < %s | FileCheck %s
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
 ; Derived from the following code:
 ;
 ; void foo(long n, long m, double A[n][m]) {
-;   for (long i = 0; i < n; i++)
-;     for (long j = 0; j < m; j++)
+;   for (long i = 0; i < 100; i++)
+;     for (long j = 0; j < 150; j++)
 ;       A[i][j] = 1.0;
 ; }
 
-; CHECK: p0: %n
-; CHECK: p1: %m
-; CHECK-NOT: p3
-
-; CHECK: Domain
-; CHECK:   [n, m] -> { Stmt_for_j[i0, i1] : i0 >= 0 and i0 <= -1 + n and i1 >= 0 and i1 <= -1 + m };
-; CHECK: Scattering
-; CHECK:   [n, m] -> { Stmt_for_j[i0, i1] -> scattering[0, i0, 0, i1, 0] };
-; CHECK: MustWriteAccess
-; CHECK:   [n, m] -> { Stmt_for_j[i0, i1] -> MemRef_A[i0, i1] };
+; CHECK: polly.split_new_and_old:
+; CHECK: %0 = icmp sge i64 %m, 150
+; CHECK: %1 = select i1 %0, i64 1, i64 0
+; CHECK: %2 = icmp ne i64 0, %1
+; CHECK: br i1 %2, label %polly.start, label %for.i
 
 define void @foo(i64 %n, i64 %m, double* %A) {
 entry:
@@ -36,12 +31,12 @@ for.j:
   %arrayidx = getelementptr inbounds double* %A, i64 %vlaarrayidx.sum
   store double 1.0, double* %arrayidx
   %j.inc = add nsw i64 %j, 1
-  %j.exitcond = icmp eq i64 %j.inc, %m
+  %j.exitcond = icmp eq i64 %j.inc, 150
   br i1 %j.exitcond, label %for.i.inc, label %for.j
 
 for.i.inc:
   %i.inc = add nsw i64 %i, 1
-  %i.exitcond = icmp eq i64 %i.inc, %n
+  %i.exitcond = icmp eq i64 %i.inc, 100
   br i1 %i.exitcond, label %end, label %for.i
 
 end:

Added: polly/trunk/test/Isl/CodeGen/run-time-condition-with-scev-parameters.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/run-time-condition-with-scev-parameters.ll?rev=212198&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/run-time-condition-with-scev-parameters.ll (added)
+++ polly/trunk/test/Isl/CodeGen/run-time-condition-with-scev-parameters.ll Wed Jul  2 12:47:48 2014
@@ -0,0 +1,28 @@
+; RUN: opt %loadPolly -polly-codegen-isl -S -polly-delinearize < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen-isl -S -polly-delinearize -polly-codegen-scev < %s | FileCheck %s
+
+; CHECK: %1 = zext i32 %n to i64
+; CHECK: %2 = icmp sge i64 %1, 1
+; CHECK: %3 = select i1 %2, i64 1, i64 0
+; CHECK: %4 = icmp ne i64 0, %3
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @init_array(i32 %n, double* %data) {
+entry:
+  %0 = zext i32 %n to i64
+  br label %for.body4
+
+for.body4:                                        ; preds = %for.body4, %entry
+  %indvar1 = phi i64 [ %indvar.next2, %for.body4 ], [ 0, %entry ]
+  %.moved.to.for.body4 = mul i64 %0, %indvar1
+  %1 = add i64 %.moved.to.for.body4, 0
+  %arrayidx7 = getelementptr double* %data, i64 %1
+  store double undef, double* %arrayidx7, align 8
+  %indvar.next2 = add i64 %indvar1, 1
+  br i1 false, label %for.body4, label %for.end10
+
+for.end10:                                        ; preds = %for.body4
+  ret void
+}

Modified: polly/trunk/test/ScopInfo/multidim_2d-diagonal-matrix.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multidim_2d-diagonal-matrix.ll?rev=212198&r1=212197&r2=212198&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_2d-diagonal-matrix.ll (original)
+++ polly/trunk/test/ScopInfo/multidim_2d-diagonal-matrix.ll Wed Jul  2 12:47:48 2014
@@ -9,6 +9,10 @@ target triple = "x86_64-unknown-linux-gn
 ;     A[i][i] = 1.0;
 ; }
 
+
+; CHECK: Assumed Context:
+; CHECK:   [n] -> {  :  }
+
 ; CHECK: p0: %n
 ; CHECK-NOT: p1
 

Copied: polly/trunk/test/ScopInfo/multidim_2d_outer_larger_than_zero.ll (from r212186, polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll)
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multidim_2d_outer_larger_than_zero.ll?p2=polly/trunk/test/ScopInfo/multidim_2d_outer_larger_than_zero.ll&p1=polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll&r1=212186&r2=212198&rev=212198&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll (original)
+++ polly/trunk/test/ScopInfo/multidim_2d_outer_larger_than_zero.ll Wed Jul  2 12:47:48 2014
@@ -4,30 +4,34 @@ target triple = "x86_64-unknown-linux-gn
 
 ; Derived from the following code:
 ;
-; void foo(long n, long m, double A[n][m]) {
-;   for (long i = 0; i < n; i++)
+; void foo(long n, long m, long p, double A[n][m]) {
+;   for (long i = 0; i < 100; i++)
 ;     for (long j = 0; j < m; j++)
-;       A[i][j] = 1.0;
+;       A[i+p][j] = 1.0;
 ; }
 
-; CHECK: p0: %n
-; CHECK: p1: %m
-; CHECK-NOT: p3
-
-; CHECK: Domain
-; CHECK:   [n, m] -> { Stmt_for_j[i0, i1] : i0 >= 0 and i0 <= -1 + n and i1 >= 0 and i1 <= -1 + m };
-; CHECK: Scattering
-; CHECK:   [n, m] -> { Stmt_for_j[i0, i1] -> scattering[0, i0, 0, i1, 0] };
-; CHECK: MustWriteAccess
-; CHECK:   [n, m] -> { Stmt_for_j[i0, i1] -> MemRef_A[i0, i1] };
+; CHECK:  Assumed Context:
+; CHECK:  [m, p] -> {  : p >= 0 }
+; CHECK:  p0: %m
+; CHECK:  p1: %p
+; CHECK:  Statements {
+; CHECK:    Stmt_for_j
+; CHECK:          Domain :=
+; CHECK:              [m, p] -> { Stmt_for_j[i0, i1] : i0 >= 0 and i0 <= 99 and i1 >= 0 and i1 <= -1 + m };
+; CHECK:          Scattering :=
+; CHECK:              [m, p] -> { Stmt_for_j[i0, i1] -> scattering[0, i0, 0, i1, 0] };
+; CHECK:          MustWriteAccess := [Reduction Type: NONE]
+; CHECK:              [m, p] -> { Stmt_for_j[i0, i1] -> MemRef_A[p + i0, i1] };
+; CHECK:  }
 
-define void @foo(i64 %n, i64 %m, double* %A) {
+define void @foo(i64 %n, i64 %m, i64 %p, double* %A) {
 entry:
   br label %for.i
 
 for.i:
   %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
-  %tmp = mul nsw i64 %i, %m
+  %add = add nsw i64 %i, %p
+  %tmp = mul nsw i64 %add, %m
   br label %for.j
 
 for.j:
@@ -41,7 +45,7 @@ for.j:
 
 for.i.inc:
   %i.inc = add nsw i64 %i, 1
-  %i.exitcond = icmp eq i64 %i.inc, %n
+  %i.exitcond = icmp eq i64 %i.inc, 100
   br i1 %i.exitcond, label %end, label %for.i
 
 end:

Copied: polly/trunk/test/ScopInfo/multidim_2d_parametric_array_static_loop_bounds.ll (from r212186, polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll)
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multidim_2d_parametric_array_static_loop_bounds.ll?p2=polly/trunk/test/ScopInfo/multidim_2d_parametric_array_static_loop_bounds.ll&p1=polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll&r1=212186&r2=212198&rev=212198&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll (original)
+++ polly/trunk/test/ScopInfo/multidim_2d_parametric_array_static_loop_bounds.ll Wed Jul  2 12:47:48 2014
@@ -5,21 +5,21 @@ target triple = "x86_64-unknown-linux-gn
 ; Derived from the following code:
 ;
 ; void foo(long n, long m, double A[n][m]) {
-;   for (long i = 0; i < n; i++)
-;     for (long j = 0; j < m; j++)
+;   for (long i = 0; i < 100; i++)
+;     for (long j = 0; j < 150; j++)
 ;       A[i][j] = 1.0;
 ; }
-
-; CHECK: p0: %n
-; CHECK: p1: %m
-; CHECK-NOT: p3
-
-; CHECK: Domain
-; CHECK:   [n, m] -> { Stmt_for_j[i0, i1] : i0 >= 0 and i0 <= -1 + n and i1 >= 0 and i1 <= -1 + m };
-; CHECK: Scattering
-; CHECK:   [n, m] -> { Stmt_for_j[i0, i1] -> scattering[0, i0, 0, i1, 0] };
-; CHECK: MustWriteAccess
-; CHECK:   [n, m] -> { Stmt_for_j[i0, i1] -> MemRef_A[i0, i1] };
+; CHECK: Assumed Context:
+; CHECK: [m] -> {  : m >= 150 }
+; CHECK: p0: %m
+; CHECK: Statements {
+; CHECK:   Stmt_for_j
+; CHECK:         Domain :=
+; CHECK:             [m] -> { Stmt_for_j[i0, i1] : i0 >= 0 and i0 <= 99 and i1 >= 0 and i1 <= 149 };
+; CHECK:         Scattering :=
+; CHECK:             [m] -> { Stmt_for_j[i0, i1] -> scattering[0, i0, 0, i1, 0] };
+; CHECK:         MustWriteAccess := [Reduction Type: NONE]
+; CHECK:             [m] -> { Stmt_for_j[i0, i1] -> MemRef_A[i0, i1] };
 
 define void @foo(i64 %n, i64 %m, double* %A) {
 entry:
@@ -36,12 +36,12 @@ for.j:
   %arrayidx = getelementptr inbounds double* %A, i64 %vlaarrayidx.sum
   store double 1.0, double* %arrayidx
   %j.inc = add nsw i64 %j, 1
-  %j.exitcond = icmp eq i64 %j.inc, %m
+  %j.exitcond = icmp eq i64 %j.inc, 150
   br i1 %j.exitcond, label %for.i.inc, label %for.j
 
 for.i.inc:
   %i.inc = add nsw i64 %i, 1
-  %i.exitcond = icmp eq i64 %i.inc, %n
+  %i.exitcond = icmp eq i64 %i.inc, 100
   br i1 %i.exitcond, label %end, label %for.i
 
 end:

Copied: polly/trunk/test/ScopInfo/multidim_3d_parametric_array_static_loop_bounds.ll (from r212186, polly/trunk/test/ScopInfo/multidim_only_ivs_3d.ll)
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multidim_3d_parametric_array_static_loop_bounds.ll?p2=polly/trunk/test/ScopInfo/multidim_3d_parametric_array_static_loop_bounds.ll&p1=polly/trunk/test/ScopInfo/multidim_only_ivs_3d.ll&r1=212186&r2=212198&rev=212198&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_only_ivs_3d.ll (original)
+++ polly/trunk/test/ScopInfo/multidim_3d_parametric_array_static_loop_bounds.ll Wed Jul  2 12:47:48 2014
@@ -4,23 +4,24 @@ target triple = "x86_64-unknown-linux-gn
 
 ; void foo(long n, long m, long o, double A[n][m][o]) {
 ;
-;   for (long i = 0; i < n; i++)
-;     for (long j = 0; j < m; j++)
-;       for (long k = 0; k < o; k++)
+;   for (long i = 0; i < 100; i++)
+;     for (long j = 0; j < 150; j++)
+;       for (long k = 0; k < 200; k++)
 ;         A[i][j][k] = 1.0;
 ; }
 
-; CHECK: p0: %n
-; CHECK: p1: %m
-; CHECK: p2: %o
-; CHECK-NOT: p3
-;
-; CHECK: Domain
-; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] : i0 >= 0 and i0 <= -1 + n and i1 >= 0 and i1 <= -1 + m and i2 >= 0 and i2 <= -1 + o };
-; CHECK: Scattering
-; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] };
-; CHECK: WriteAccess
-; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] -> MemRef_A[i0, i1, i2] };
+; CHECK:   Assumed Context:
+; CHECK:   [m, o] -> {  : m >= 150 and o >= 200 }
+; CHECK:   p0: %m
+; CHECK:   p1: %o
+; CHECK:   Statements {
+; CHECK:     Stmt_for_k
+; CHECK:           Domain :=
+; CHECK:               [m, o] -> { Stmt_for_k[i0, i1, i2] : i0 >= 0 and i0 <= 99 and i1 >= 0 and i1 <= 149 and i2 >= 0 and i2 <= 199 };
+; CHECK:           Scattering :=
+; CHECK:               [m, o] -> { Stmt_for_k[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] };
+; CHECK:           MustWriteAccess := [Reduction Type: NONE]
+; CHECK:               [m, o] -> { Stmt_for_k[i0, i1, i2] -> MemRef_A[i0, i1, i2] };
 
 define void @foo(i64 %n, i64 %m, i64 %o, double* %A) {
 entry:
@@ -46,17 +47,17 @@ for.k:
 
 for.k.inc:
   %k.inc = add nsw i64 %k, 1
-  %k.exitcond = icmp eq i64 %k.inc, %o
+  %k.exitcond = icmp eq i64 %k.inc, 200
   br i1 %k.exitcond, label %for.j.inc, label %for.k
 
 for.j.inc:
   %j.inc = add nsw i64 %j, 1
-  %j.exitcond = icmp eq i64 %j.inc, %m
+  %j.exitcond = icmp eq i64 %j.inc, 150
   br i1 %j.exitcond, label %for.i.inc, label %for.j
 
 for.i.inc:
   %i.inc = add nsw i64 %i, 1
-  %i.exitcond = icmp eq i64 %i.inc, %n
+  %i.exitcond = icmp eq i64 %i.inc, 100
   br i1 %i.exitcond, label %end, label %for.i
 
 end:

Modified: polly/trunk/test/ScopInfo/multidim_ivs_and_integer_offsets_3d.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multidim_ivs_and_integer_offsets_3d.ll?rev=212198&r1=212197&r2=212198&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_ivs_and_integer_offsets_3d.ll (original)
+++ polly/trunk/test/ScopInfo/multidim_ivs_and_integer_offsets_3d.ll Wed Jul  2 12:47:48 2014
@@ -10,6 +10,9 @@ target triple = "x86_64-unknown-linux-gn
 ;         A[i+3][j-4][k+7] = 1.0;
 ; }
 
+; CHECK: Assumed Context:
+; CHECK: {  :  }
+
 ; CHECK: p0: %n
 ; CHECK: p1: %m
 ; CHECK: p2: %o

Modified: polly/trunk/test/ScopInfo/multidim_ivs_and_parameteric_offsets_3d.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multidim_ivs_and_parameteric_offsets_3d.ll?rev=212198&r1=212197&r2=212198&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_ivs_and_parameteric_offsets_3d.ll (original)
+++ polly/trunk/test/ScopInfo/multidim_ivs_and_parameteric_offsets_3d.ll Wed Jul  2 12:47:48 2014
@@ -13,6 +13,9 @@ target triple = "x86_64-unknown-linux-gn
 ; Access function:
 ;    {{{((8 * ((((%m * %p) + %q) * %o) + %r)) + %A),+,(8 * %m * %o)}<%for.i>,+,
 ;        (8 * %o)}<%for.j>,+,8}<%for.k>
+
+; CHECK: Assumed Context:
+; CHECK: [n, m, o, p, q, r] -> { : q = 0 and r = 0 and p >= 0 }
 ;
 ; CHECK: p0: %n
 ; CHECK: p1: %m

Modified: polly/trunk/test/ScopInfo/multidim_nested_start_integer.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multidim_nested_start_integer.ll?rev=212198&r1=212197&r2=212198&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_nested_start_integer.ll (original)
+++ polly/trunk/test/ScopInfo/multidim_nested_start_integer.ll Wed Jul  2 12:47:48 2014
@@ -9,6 +9,8 @@ target triple = "x86_64-unknown-linux-gn
 ;         A[i+3][j-4][k+7] = 1.0;
 ; }
 ;
+; CHECK: Assumed Context:
+; CHECK:   {  :  }
 ; CHECK: p0: %n
 ; CHECK: p1: %m
 ; CHECK: p2: %o

Modified: polly/trunk/test/ScopInfo/multidim_nested_start_share_parameter.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multidim_nested_start_share_parameter.ll?rev=212198&r1=212197&r2=212198&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_nested_start_share_parameter.ll (original)
+++ polly/trunk/test/ScopInfo/multidim_nested_start_share_parameter.ll Wed Jul  2 12:47:48 2014
@@ -12,6 +12,8 @@ target triple = "x86_64-unknown-linux-gn
 ;       }
 ; }
 ;
+; CHECK: Assumed Context:
+; CHECK:   {  :  }
 ; CHECK: p0: %n
 ; CHECK: p1: %m
 ; CHECK: p2: %o

Modified: polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll?rev=212198&r1=212197&r2=212198&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll (original)
+++ polly/trunk/test/ScopInfo/multidim_only_ivs_2d.ll Wed Jul  2 12:47:48 2014
@@ -10,6 +10,8 @@ target triple = "x86_64-unknown-linux-gn
 ;       A[i][j] = 1.0;
 ; }
 
+; CHECK: Assumed Context:
+; CHECK:   [n, m] -> {  :  }
 ; CHECK: p0: %n
 ; CHECK: p1: %m
 ; CHECK-NOT: p3

Modified: polly/trunk/test/ScopInfo/multidim_only_ivs_3d.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multidim_only_ivs_3d.ll?rev=212198&r1=212197&r2=212198&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_only_ivs_3d.ll (original)
+++ polly/trunk/test/ScopInfo/multidim_only_ivs_3d.ll Wed Jul  2 12:47:48 2014
@@ -10,6 +10,8 @@ target triple = "x86_64-unknown-linux-gn
 ;         A[i][j][k] = 1.0;
 ; }
 
+; CHECK: Assumed Context:
+; CHECK:   [n, m, o] -> {  :  }
 ; CHECK: p0: %n
 ; CHECK: p1: %m
 ; CHECK: p2: %o

Modified: polly/trunk/test/ScopInfo/multidim_only_ivs_3d_cast.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multidim_only_ivs_3d_cast.ll?rev=212198&r1=212197&r2=212198&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_only_ivs_3d_cast.ll (original)
+++ polly/trunk/test/ScopInfo/multidim_only_ivs_3d_cast.ll Wed Jul  2 12:47:48 2014
@@ -8,17 +8,25 @@
 ;         A[i][j][k] = 1.0;
 ; }
 
+; We currently fail to get the relation between the 32 and 64 bit versions of
+; m and o, such that we generate unnecessary run-time checks. This is not a
+; correctness issue, but could be improved.
+
+; CHECK: Assumed Context:
+; CHECK:  [n, m, o, p_3, p_4] -> { : p_4 >= o and p_3 >= m }
 ; CHECK: p0: %n
 ; CHECK: p1: %m
 ; CHECK: p2: %o
-; CHECK-NOT: p3
+; CHECK: p3: (zext i32 %m to i64)
+; CHECK: p4: (zext i32 %o to i64)
+; CHECK-NOT: p5
 
 ; CHECK: Domain
-; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] : i0 >= 0 and i0 <= -1 + n and i1 >= 0 and i1 <= -1 + m and i2 >= 0 and i2 <= -1 + o };
+; CHECK:   [n, m, o, p_3, p_4] -> { Stmt_for_k[i0, i1, i2] : i0 >= 0 and i0 <= -1 + n and i1 >= 0 and i1 <= -1 + m and i2 >= 0 and i2 <= -1 + o };
 ; CHECK: Scattering
-; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] };
+; CHECK:   [n, m, o, p_3, p_4] -> { Stmt_for_k[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] };
 ; CHECK: WriteAccess
-; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] -> MemRef_A[i0, i1, i2] };
+; CHECK:   [n, m, o, p_3, p_4] -> { Stmt_for_k[i0, i1, i2] -> MemRef_A[i0, i1, i2] };
 
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"

Modified: polly/trunk/test/ScopInfo/multidim_only_ivs_3d_reverse.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multidim_only_ivs_3d_reverse.ll?rev=212198&r1=212197&r2=212198&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_only_ivs_3d_reverse.ll (original)
+++ polly/trunk/test/ScopInfo/multidim_only_ivs_3d_reverse.ll Wed Jul  2 12:47:48 2014
@@ -10,22 +10,24 @@ target triple = "x86_64-unknown-linux-gn
 ; void foo(long n, long m, long o, double A[n][m][o]) {
 ;
 ;   for (long i = 0; i < n; i++)
-;     for (long j = 0; j < m; j++)
-;       for (long k = 0; k < o; k++)
-;         A[i][k][j] = 1.0;
+;     for (long k = 0; k < o; k++)
+;       for (long j = 0; j < m; j++)
+;         A[i][j][k] = 1.0;
 ; }
 
+; CHECK: Assumed Context:
+; CHECK:   {  :  }
 ; CHECK: p0: %n
-; CHECK: p1: %m
-; CHECK: p2: %o
+; CHECK: p1: %o
+; CHECK: p2: %m
 ; CHECK-NOT: p3
 ;
 ; CHECK: Domain
-; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] : i0 >= 0 and i0 <= -1 + n and i1 >= 0 and i1 <= -1 + m and i2 >= 0 and i2 <= -1 + o };
+; CHECK:  [n, o, m] -> { Stmt_for_j[i0, i1, i2] : i0 >= 0 and i0 <= -1 + n and i1 >= 0 and i1 <= -1 + o and i2 >= 0 and i2 <= -1 + m };
 ; CHECK: Scattering
-; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] };
+; CHECK:   [n, o, m] -> { Stmt_for_j[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] };
 ; CHECK: WriteAccess
-; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] -> MemRef_A[i0, i2, i1] };
+; CHECK:   [n, o, m] -> { Stmt_for_j[i0, i1, i2] -> MemRef_A[i0, i2, i1] };
 
 define void @foo(i64 %n, i64 %m, i64 %o, double* %A) {
 entry:
@@ -33,31 +35,31 @@ entry:
 
 for.i:
   %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
-  br label %for.j
-
-for.j:
-  %j = phi i64 [ 0, %for.i ], [ %j.inc, %for.j.inc ]
   br label %for.k
 
 for.k:
-  %k = phi i64 [ 0, %for.j ], [ %k.inc, %for.k.inc ]
+  %k = phi i64 [ 0, %for.i ], [ %k.inc, %for.k.inc ]
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 0, %for.k ], [ %j.inc, %for.j.inc ]
   %subscript0 = mul i64 %i, %m
-  %subscript1 = add i64 %k, %subscript0
+  %subscript1 = add i64 %j, %subscript0
   %subscript2 = mul i64 %subscript1, %o
-  %subscript = add i64 %subscript2, %j
+  %subscript = add i64 %subscript2, %k
   %idx = getelementptr inbounds double* %A, i64 %subscript
   store double 1.0, double* %idx
-  br label %for.k.inc
-
-for.k.inc:
-  %k.inc = add nsw i64 %k, 1
-  %k.exitcond = icmp eq i64 %k.inc, %o
-  br i1 %k.exitcond, label %for.j.inc, label %for.k
+  br label %for.j.inc
 
 for.j.inc:
   %j.inc = add nsw i64 %j, 1
   %j.exitcond = icmp eq i64 %j.inc, %m
-  br i1 %j.exitcond, label %for.i.inc, label %for.j
+  br i1 %j.exitcond, label %for.k.inc, label %for.j
+
+for.k.inc:
+  %k.inc = add nsw i64 %k, 1
+  %k.exitcond = icmp eq i64 %k.inc, %o
+  br i1 %k.exitcond, label %for.i.inc, label %for.k
 
 for.i.inc:
   %i.inc = add nsw i64 %i, 1

Modified: polly/trunk/test/ScopInfo/simple_loop_1.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/simple_loop_1.ll?rev=212198&r1=212197&r2=212198&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/simple_loop_1.ll (original)
+++ polly/trunk/test/ScopInfo/simple_loop_1.ll Wed Jul  2 12:47:48 2014
@@ -25,6 +25,9 @@ return:
   ret void
 }
 
+; CHECK: Assumed Context:
+; CHECK:   {  :  }
+
 ; CHECK:  Stmt_bb
 ; CHECK:        Domain :=
 ; CHECK:            [N] -> { Stmt_bb[i0] : i0 >= 0 and i0 <= -1 + N };





More information about the llvm-commits mailing list