llvm.org GIT mirror llvm / 2f5f1c2
do not assert when delinearization fails git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208615 91177308-0d34-0410-b5e6-96231b3b80d8 Sebastian Pop 6 years ago
2 changed file(s) with 73 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
71917191 return GCD;
71927192 }
71937193
7194 static void findArrayDimensionsRec(ScalarEvolution &SE,
7194 static bool findArrayDimensionsRec(ScalarEvolution &SE,
71957195 SmallVectorImpl &Terms,
71967196 SmallVectorImpl &Sizes) {
71977197 // The GCD of all Terms is the dimension of the innermost dimension.
72097209 }
72107210
72117211 Sizes.push_back(GCD);
7212 return;
7212 return true;
72137213 }
72147214
72157215 for (const SCEV *&Term : Terms) {
72167216 // Normalize the terms before the next call to findArrayDimensionsRec.
72177217 const SCEV *Q, *R;
72187218 SCEVDivision::divide(SE, Term, GCD, &Q, &R);
7219 assert(R->isZero() && "GCD does not evenly divide one of the terms");
7219
7220 // Bail out when GCD does not evenly divide one of the terms.
7221 if (!R->isZero())
7222 return false;
7223
72207224 Term = Q;
72217225 }
72227226
72277231 Terms.end());
72287232
72297233 if (Terms.size() > 0)
7230 findArrayDimensionsRec(SE, Terms, Sizes);
7234 if (!findArrayDimensionsRec(SE, Terms, Sizes))
7235 return false;
7236
72317237 Sizes.push_back(GCD);
7238 return true;
72327239 }
72337240
72347241 namespace {
73147321 });
73157322
73167323 ScalarEvolution &SE = *const_cast(this);
7317 findArrayDimensionsRec(SE, Terms, Sizes);
7324 bool Res = findArrayDimensionsRec(SE, Terms, Sizes);
7325
7326 if (!Res) {
7327 Sizes.clear();
7328 return;
7329 }
73187330
73197331 DEBUG({
73207332 dbgs() << "Sizes:\n";
73287340 const SCEV *SCEVAddRecExpr::computeAccessFunctions(
73297341 ScalarEvolution &SE, SmallVectorImpl &Subscripts,
73307342 SmallVectorImpl &Sizes) const {
7343
73317344 // Early exit in case this SCEV is not an affine multivariate function.
7345 if (Sizes.empty() || !this->isAffine())
7346 return NULL;
7347
73327348 const SCEV *Zero = SE.getConstant(this->getType(), 0);
7333 if (!this->isAffine())
7334 return Zero;
7335
73367349 const SCEV *Res = this, *Remainder = Zero;
73377350 int Last = Sizes.size() - 1;
73387351 for (int i = Last; i >= 0; i--) {
74317444 SmallVector Terms;
74327445 collectParametricTerms(SE, Terms);
74337446
7447 if (Terms.empty())
7448 return NULL;
7449
74347450 // Second step: find subscript sizes.
74357451 SE.findArrayDimensions(Terms, Sizes);
74367452
7453 if (Sizes.empty())
7454 return NULL;
7455
74377456 // Third step: compute the access functions for each subscript.
74387457 const SCEV *Remainder = computeAccessFunctions(SE, Subscripts, Sizes);
7458
7459 if (!Remainder || Subscripts.empty())
7460 return NULL;
74397461
74407462 DEBUG({
74417463 dbgs() << "succeeded to delinearize " << *this << "\n";
0 ; RUN: opt -basicaa -da -analyze -da-delinearize < %s
1 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"
2 target triple = "x86_64-unknown-linux-gnu"
3
4 ; Derived from the following code:
5 ;
6 ; void foo(long n, long m, double *A) {
7 ; for (long i = 0; i < n; i++)
8 ; for (long j = 0; j < m; j++)
9 ; *(A + i * n + j) = 1.0;
10 ; *(A + j * m + i) = 2.0;
11 ; }
12
13 define void @foo(i64 %n, i64 %m, double* %A) {
14 entry:
15 br label %for.i
16
17 for.i:
18 %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
19 br label %for.j
20
21 for.j:
22 %j = phi i64 [ 0, %for.i ], [ %j.inc, %for.j ]
23 %tmp = mul nsw i64 %i, %m
24 %vlaarrayidx.sum = add i64 %j, %tmp
25 %arrayidx = getelementptr inbounds double* %A, i64 %vlaarrayidx.sum
26 store double 1.0, double* %arrayidx
27 %tmp1 = mul nsw i64 %j, %n
28 %vlaarrayidx.sum1 = add i64 %i, %tmp1
29 %arrayidx1 = getelementptr inbounds double* %A, i64 %vlaarrayidx.sum1
30 store double 1.0, double* %arrayidx1
31 %j.inc = add nsw i64 %j, 1
32 %j.exitcond = icmp eq i64 %j.inc, %m
33 br i1 %j.exitcond, label %for.i.inc, label %for.j
34
35 for.i.inc:
36 %i.inc = add nsw i64 %i, 1
37 %i.exitcond = icmp eq i64 %i.inc, %n
38 br i1 %i.exitcond, label %end, label %for.i
39
40 end:
41 ret void
42 }