do not assert when delinearization fails

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208615 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sebastian Pop 2014-05-12 19:01:53 +00:00
parent d9673ebd34
commit 2f5f1c2ccb
2 changed files with 74 additions and 9 deletions

View File

@ -7192,7 +7192,7 @@ findGCD(ScalarEvolution &SE, SmallVectorImpl<const SCEV *> &Terms) {
return GCD; return GCD;
} }
static void findArrayDimensionsRec(ScalarEvolution &SE, static bool findArrayDimensionsRec(ScalarEvolution &SE,
SmallVectorImpl<const SCEV *> &Terms, SmallVectorImpl<const SCEV *> &Terms,
SmallVectorImpl<const SCEV *> &Sizes) { SmallVectorImpl<const SCEV *> &Sizes) {
// The GCD of all Terms is the dimension of the innermost dimension. // The GCD of all Terms is the dimension of the innermost dimension.
@ -7210,14 +7210,18 @@ static void findArrayDimensionsRec(ScalarEvolution &SE,
} }
Sizes.push_back(GCD); Sizes.push_back(GCD);
return; return true;
} }
for (const SCEV *&Term : Terms) { for (const SCEV *&Term : Terms) {
// Normalize the terms before the next call to findArrayDimensionsRec. // Normalize the terms before the next call to findArrayDimensionsRec.
const SCEV *Q, *R; const SCEV *Q, *R;
SCEVDivision::divide(SE, Term, GCD, &Q, &R); SCEVDivision::divide(SE, Term, GCD, &Q, &R);
assert(R->isZero() && "GCD does not evenly divide one of the terms");
// Bail out when GCD does not evenly divide one of the terms.
if (!R->isZero())
return false;
Term = Q; Term = Q;
} }
@ -7228,8 +7232,11 @@ static void findArrayDimensionsRec(ScalarEvolution &SE,
Terms.end()); Terms.end());
if (Terms.size() > 0) if (Terms.size() > 0)
findArrayDimensionsRec(SE, Terms, Sizes); if (!findArrayDimensionsRec(SE, Terms, Sizes))
return false;
Sizes.push_back(GCD); Sizes.push_back(GCD);
return true;
} }
namespace { namespace {
@ -7315,7 +7322,12 @@ void ScalarEvolution::findArrayDimensions(
}); });
ScalarEvolution &SE = *const_cast<ScalarEvolution *>(this); ScalarEvolution &SE = *const_cast<ScalarEvolution *>(this);
findArrayDimensionsRec(SE, Terms, Sizes); bool Res = findArrayDimensionsRec(SE, Terms, Sizes);
if (!Res) {
Sizes.clear();
return;
}
DEBUG({ DEBUG({
dbgs() << "Sizes:\n"; dbgs() << "Sizes:\n";
@ -7329,11 +7341,12 @@ void ScalarEvolution::findArrayDimensions(
const SCEV *SCEVAddRecExpr::computeAccessFunctions( const SCEV *SCEVAddRecExpr::computeAccessFunctions(
ScalarEvolution &SE, SmallVectorImpl<const SCEV *> &Subscripts, ScalarEvolution &SE, SmallVectorImpl<const SCEV *> &Subscripts,
SmallVectorImpl<const SCEV *> &Sizes) const { SmallVectorImpl<const SCEV *> &Sizes) const {
// Early exit in case this SCEV is not an affine multivariate function.
const SCEV *Zero = SE.getConstant(this->getType(), 0);
if (!this->isAffine())
return Zero;
// Early exit in case this SCEV is not an affine multivariate function.
if (Sizes.empty() || !this->isAffine())
return NULL;
const SCEV *Zero = SE.getConstant(this->getType(), 0);
const SCEV *Res = this, *Remainder = Zero; const SCEV *Res = this, *Remainder = Zero;
int Last = Sizes.size() - 1; int Last = Sizes.size() - 1;
for (int i = Last; i >= 0; i--) { for (int i = Last; i >= 0; i--) {
@ -7432,12 +7445,21 @@ SCEVAddRecExpr::delinearize(ScalarEvolution &SE,
SmallVector<const SCEV *, 4> Terms; SmallVector<const SCEV *, 4> Terms;
collectParametricTerms(SE, Terms); collectParametricTerms(SE, Terms);
if (Terms.empty())
return NULL;
// Second step: find subscript sizes. // Second step: find subscript sizes.
SE.findArrayDimensions(Terms, Sizes); SE.findArrayDimensions(Terms, Sizes);
if (Sizes.empty())
return NULL;
// Third step: compute the access functions for each subscript. // Third step: compute the access functions for each subscript.
const SCEV *Remainder = computeAccessFunctions(SE, Subscripts, Sizes); const SCEV *Remainder = computeAccessFunctions(SE, Subscripts, Sizes);
if (!Remainder || Subscripts.empty())
return NULL;
DEBUG({ DEBUG({
dbgs() << "succeeded to delinearize " << *this << "\n"; dbgs() << "succeeded to delinearize " << *this << "\n";
dbgs() << "ArrayDecl[UnknownSize]"; dbgs() << "ArrayDecl[UnknownSize]";

View File

@ -0,0 +1,43 @@
; RUN: opt -basicaa -da -analyze -da-delinearize < %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) {
; for (long i = 0; i < n; i++)
; for (long j = 0; j < m; j++)
; *(A + i * n + j) = 1.0;
; *(A + j * m + i) = 2.0;
; }
define void @foo(i64 %n, i64 %m, double* %A) {
entry:
br label %for.i
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 ]
%tmp = mul nsw i64 %i, %m
%vlaarrayidx.sum = add i64 %j, %tmp
%arrayidx = getelementptr inbounds double* %A, i64 %vlaarrayidx.sum
store double 1.0, double* %arrayidx
%tmp1 = mul nsw i64 %j, %n
%vlaarrayidx.sum1 = add i64 %i, %tmp1
%arrayidx1 = getelementptr inbounds double* %A, i64 %vlaarrayidx.sum1
store double 1.0, double* %arrayidx1
%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
end:
ret void
}