[llvm-commits] [llvm] r73862 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Analysis/ScalarEvolution.cpp test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll test/Analysis/ScalarEvolution/trip-count3.ll test/Transforms/IndVarSimplify/loop_evaluate_6.ll

Dan Gohman gohman at apple.com
Sun Jun 21 16:46:39 PDT 2009


Author: djg
Date: Sun Jun 21 18:46:38 2009
New Revision: 73862

URL: http://llvm.org/viewvc/llvm-project?rev=73862&view=rev
Log:
Fix ScalarEvolution's backedge-taken count computations to check for
overflow when computing a integer division to round up.

Thanks to Nick Lewycky for noticing this!

Modified:
    llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp
    llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll
    llvm/trunk/test/Analysis/ScalarEvolution/trip-count3.ll
    llvm/trunk/test/Transforms/IndVarSimplify/loop_evaluate_6.ll

Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=73862&r1=73861&r2=73862&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)
+++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Sun Jun 21 18:46:38 2009
@@ -332,6 +332,13 @@
                                           const SCEVHandle &SymName,
                                           const SCEVHandle &NewVal);
 
+    /// getBECount - Subtract the end and start values and divide by the step,
+    /// rounding up, to get the number of times the backedge is executed. Return
+    /// CouldNotCompute if an intermediate computation overflows.
+    SCEVHandle getBECount(const SCEVHandle &Start,
+                          const SCEVHandle &End,
+                          const SCEVHandle &Step);
+
     /// getBackedgeTakenInfo - Return the BackedgeTakenInfo for the given
     /// loop, lazily computing new values if the loop hasn't been analyzed
     /// yet.

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=73862&r1=73861&r2=73862&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Sun Jun 21 18:46:38 2009
@@ -3788,6 +3788,33 @@
   return false;
 }
 
+/// getBECount - Subtract the end and start values and divide by the step,
+/// rounding up, to get the number of times the backedge is executed. Return
+/// CouldNotCompute if an intermediate computation overflows.
+SCEVHandle ScalarEvolution::getBECount(const SCEVHandle &Start,
+                                       const SCEVHandle &End,
+                                       const SCEVHandle &Step) {
+  const Type *Ty = Start->getType();
+  SCEVHandle NegOne = getIntegerSCEV(-1, Ty);
+  SCEVHandle Diff = getMinusSCEV(End, Start);
+  SCEVHandle RoundUp = getAddExpr(Step, NegOne);
+
+  // Add an adjustment to the difference between End and Start so that
+  // the division will effectively round up.
+  SCEVHandle Add = getAddExpr(Diff, RoundUp);
+
+  // Check Add for unsigned overflow.
+  // TODO: More sophisticated things could be done here.
+  const Type *WideTy = IntegerType::get(getTypeSizeInBits(Ty) + 1);
+  SCEVHandle OperandExtendedAdd =
+    getAddExpr(getZeroExtendExpr(Diff, WideTy),
+               getZeroExtendExpr(RoundUp, WideTy));
+  if (getZeroExtendExpr(Add, WideTy) != OperandExtendedAdd)
+    return CouldNotCompute;
+
+  return getUDivExpr(Add, Step);
+}
+
 /// HowManyLessThans - Return the number of times a backedge containing the
 /// specified less-than comparison will execute.  If not computable, return
 /// CouldNotCompute.
@@ -3869,16 +3896,11 @@
 
     // Finally, we subtract these two values and divide, rounding up, to get
     // the number of times the backedge is executed.
-    SCEVHandle BECount = getUDivExpr(getAddExpr(getMinusSCEV(End, Start),
-                                                getAddExpr(Step, NegOne)),
-                                     Step);
+    SCEVHandle BECount = getBECount(Start, End, Step);
 
     // The maximum backedge count is similar, except using the minimum start
     // value and the maximum end value.
-    SCEVHandle MaxBECount = getUDivExpr(getAddExpr(getMinusSCEV(MaxEnd,
-                                                                MinStart),
-                                                   getAddExpr(Step, NegOne)),
-                                        Step);
+    SCEVHandle MaxBECount = getBECount(MinStart, MaxEnd, Step);;
 
     return BackedgeTakenInfo(BECount, MaxBECount);
   }

Modified: llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll?rev=73862&r1=73861&r2=73862&view=diff

==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll (original)
+++ llvm/trunk/test/Analysis/ScalarEvolution/2008-11-18-Stride1.ll Sun Jun 21 18:46:38 2009
@@ -1,4 +1,9 @@
-; RUN: llvm-as < %s | opt -analyze -scalar-evolution -disable-output |& grep {/u 3}
+; RUN: llvm-as < %s | opt -analyze -scalar-evolution -disable-output \
+; RUN:  | grep {Loop bb: Unpredictable backedge-taken count\\.}
+
+; ScalarEvolution can't compute a trip count because it doesn't know if
+; dividing by the stride will have a remainder. This could theoretically
+; be teaching it how to use a more elaborate trip count computation.
 
 define i32 @f(i32 %x) nounwind readnone {
 entry:

Modified: llvm/trunk/test/Analysis/ScalarEvolution/trip-count3.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/trip-count3.ll?rev=73862&r1=73861&r2=73862&view=diff

==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/trip-count3.ll (original)
+++ llvm/trunk/test/Analysis/ScalarEvolution/trip-count3.ll Sun Jun 21 18:46:38 2009
@@ -1,5 +1,9 @@
 ; RUN: llvm-as < %s | opt -scalar-evolution -analyze -disable-output \
-; RUN:  | grep {backedge-taken count is ((64 + (-64 smax (-1 + (-1 \\* %0))) + %0) /u 64)}
+; RUN:  | grep {Loop bb3\\.i: Unpredictable backedge-taken count\\.}
+
+; ScalarEvolution can't compute a trip count because it doesn't know if
+; dividing by the stride will have a remainder. This could theoretically
+; be teaching it how to use a more elaborate trip count computation.
 
 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"
 target triple = "x86_64-unknown-linux-gnu"

Modified: llvm/trunk/test/Transforms/IndVarSimplify/loop_evaluate_6.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/loop_evaluate_6.ll?rev=73862&r1=73861&r2=73862&view=diff

==============================================================================
--- llvm/trunk/test/Transforms/IndVarSimplify/loop_evaluate_6.ll (original)
+++ llvm/trunk/test/Transforms/IndVarSimplify/loop_evaluate_6.ll Sun Jun 21 18:46:38 2009
@@ -1,7 +1,9 @@
 ; RUN: llvm-as < %s | opt -indvars -loop-deletion | llvm-dis | grep phi | count 1
+; XFAIL: *
 
-; Indvars should be able to evaluate this loop, allowing loop deletion
-; to delete it.
+; Indvars can't evaluate this loop, because ScalarEvolution can't compute
+; an exact trip count, because it doesn't know if dividing by the stride will
+; have a remainder. It could be done with more aggressive VRP though.
 
 define i32 @test(i32 %x_offs) nounwind readnone {
 entry:





More information about the llvm-commits mailing list