[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