[llvm] r208615 - do not assert when delinearization fails

Sebastian Pop spop at codeaurora.org
Mon May 12 12:01:53 PDT 2014


Author: spop
Date: Mon May 12 14:01:53 2014
New Revision: 208615

URL: http://llvm.org/viewvc/llvm-project?rev=208615&view=rev
Log:
do not assert when delinearization fails

Added:
    llvm/trunk/test/Analysis/Delinearization/multidim_two_accesses_different_delinearization.ll
Modified:
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=208615&r1=208614&r2=208615&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon May 12 14:01:53 2014
@@ -7192,7 +7192,7 @@ findGCD(ScalarEvolution &SE, SmallVector
   return GCD;
 }
 
-static void findArrayDimensionsRec(ScalarEvolution &SE,
+static bool findArrayDimensionsRec(ScalarEvolution &SE,
                                    SmallVectorImpl<const SCEV *> &Terms,
                                    SmallVectorImpl<const SCEV *> &Sizes) {
   // The GCD of all Terms is the dimension of the innermost dimension.
@@ -7210,14 +7210,18 @@ static void findArrayDimensionsRec(Scala
     }
 
     Sizes.push_back(GCD);
-    return;
+    return true;
   }
 
   for (const SCEV *&Term : Terms) {
     // Normalize the terms before the next call to findArrayDimensionsRec.
     const SCEV *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;
   }
 
@@ -7228,8 +7232,11 @@ static void findArrayDimensionsRec(Scala
               Terms.end());
 
   if (Terms.size() > 0)
-    findArrayDimensionsRec(SE, Terms, Sizes);
+    if (!findArrayDimensionsRec(SE, Terms, Sizes))
+      return false;
+
   Sizes.push_back(GCD);
+  return true;
 }
 
 namespace {
@@ -7315,7 +7322,12 @@ void ScalarEvolution::findArrayDimension
     });
 
   ScalarEvolution &SE = *const_cast<ScalarEvolution *>(this);
-  findArrayDimensionsRec(SE, Terms, Sizes);
+  bool Res = findArrayDimensionsRec(SE, Terms, Sizes);
+
+  if (!Res) {
+    Sizes.clear();
+    return;
+  }
 
   DEBUG({
       dbgs() << "Sizes:\n";
@@ -7329,11 +7341,12 @@ void ScalarEvolution::findArrayDimension
 const SCEV *SCEVAddRecExpr::computeAccessFunctions(
     ScalarEvolution &SE, SmallVectorImpl<const SCEV *> &Subscripts,
     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;
+  if (Sizes.empty() || !this->isAffine())
+    return NULL;
 
+  const SCEV *Zero = SE.getConstant(this->getType(), 0);
   const SCEV *Res = this, *Remainder = Zero;
   int Last = Sizes.size() - 1;
   for (int i = Last; i >= 0; i--) {
@@ -7432,12 +7445,21 @@ SCEVAddRecExpr::delinearize(ScalarEvolut
   SmallVector<const SCEV *, 4> Terms;
   collectParametricTerms(SE, Terms);
 
+  if (Terms.empty())
+    return NULL;
+
   // Second step: find subscript sizes.
   SE.findArrayDimensions(Terms, Sizes);
 
+  if (Sizes.empty())
+    return NULL;
+
   // Third step: compute the access functions for each subscript.
   const SCEV *Remainder = computeAccessFunctions(SE, Subscripts, Sizes);
 
+  if (!Remainder || Subscripts.empty())
+    return NULL;
+
   DEBUG({
       dbgs() << "succeeded to delinearize " << *this << "\n";
       dbgs() << "ArrayDecl[UnknownSize]";

Added: llvm/trunk/test/Analysis/Delinearization/multidim_two_accesses_different_delinearization.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/Delinearization/multidim_two_accesses_different_delinearization.ll?rev=208615&view=auto
==============================================================================
--- llvm/trunk/test/Analysis/Delinearization/multidim_two_accesses_different_delinearization.ll (added)
+++ llvm/trunk/test/Analysis/Delinearization/multidim_two_accesses_different_delinearization.ll Mon May 12 14:01:53 2014
@@ -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
+}





More information about the llvm-commits mailing list