mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-23 04:01:16 +00:00
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:
parent
d9673ebd34
commit
2f5f1c2ccb
@ -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]";
|
||||||
|
@ -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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user