llvm.org GIT mirror llvm / 51f53b7
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! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73862 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 11 years ago
5 changed file(s) with 51 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
331331 const SCEVHandle &SymName,
332332 const SCEVHandle &NewVal);
333333
334 /// getBECount - Subtract the end and start values and divide by the step,
335 /// rounding up, to get the number of times the backedge is executed. Return
336 /// CouldNotCompute if an intermediate computation overflows.
337 SCEVHandle getBECount(const SCEVHandle &Start,
338 const SCEVHandle &End,
339 const SCEVHandle &Step);
340
334341 /// getBackedgeTakenInfo - Return the BackedgeTakenInfo for the given
335342 /// loop, lazily computing new values if the loop hasn't been analyzed
336343 /// yet.
37873787 return false;
37883788 }
37893789
3790 /// getBECount - Subtract the end and start values and divide by the step,
3791 /// rounding up, to get the number of times the backedge is executed. Return
3792 /// CouldNotCompute if an intermediate computation overflows.
3793 SCEVHandle ScalarEvolution::getBECount(const SCEVHandle &Start,
3794 const SCEVHandle &End,
3795 const SCEVHandle &Step) {
3796 const Type *Ty = Start->getType();
3797 SCEVHandle NegOne = getIntegerSCEV(-1, Ty);
3798 SCEVHandle Diff = getMinusSCEV(End, Start);
3799 SCEVHandle RoundUp = getAddExpr(Step, NegOne);
3800
3801 // Add an adjustment to the difference between End and Start so that
3802 // the division will effectively round up.
3803 SCEVHandle Add = getAddExpr(Diff, RoundUp);
3804
3805 // Check Add for unsigned overflow.
3806 // TODO: More sophisticated things could be done here.
3807 const Type *WideTy = IntegerType::get(getTypeSizeInBits(Ty) + 1);
3808 SCEVHandle OperandExtendedAdd =
3809 getAddExpr(getZeroExtendExpr(Diff, WideTy),
3810 getZeroExtendExpr(RoundUp, WideTy));
3811 if (getZeroExtendExpr(Add, WideTy) != OperandExtendedAdd)
3812 return CouldNotCompute;
3813
3814 return getUDivExpr(Add, Step);
3815 }
3816
37903817 /// HowManyLessThans - Return the number of times a backedge containing the
37913818 /// specified less-than comparison will execute. If not computable, return
37923819 /// CouldNotCompute.
38683895
38693896 // Finally, we subtract these two values and divide, rounding up, to get
38703897 // the number of times the backedge is executed.
3871 SCEVHandle BECount = getUDivExpr(getAddExpr(getMinusSCEV(End, Start),
3872 getAddExpr(Step, NegOne)),
3873 Step);
3898 SCEVHandle BECount = getBECount(Start, End, Step);
38743899
38753900 // The maximum backedge count is similar, except using the minimum start
38763901 // value and the maximum end value.
3877 SCEVHandle MaxBECount = getUDivExpr(getAddExpr(getMinusSCEV(MaxEnd,
3878 MinStart),
3879 getAddExpr(Step, NegOne)),
3880 Step);
3902 SCEVHandle MaxBECount = getBECount(MinStart, MaxEnd, Step);;
38813903
38823904 return BackedgeTakenInfo(BECount, MaxBECount);
38833905 }
None ; RUN: llvm-as < %s | opt -analyze -scalar-evolution -disable-output |& grep {/u 3}
0 ; RUN: llvm-as < %s | opt -analyze -scalar-evolution -disable-output \
1 ; RUN: | grep {Loop bb: Unpredictable backedge-taken count\\.}
2
3 ; ScalarEvolution can't compute a trip count because it doesn't know if
4 ; dividing by the stride will have a remainder. This could theoretically
5 ; be teaching it how to use a more elaborate trip count computation.
16
27 define i32 @f(i32 %x) nounwind readnone {
38 entry:
0 ; RUN: llvm-as < %s | opt -scalar-evolution -analyze -disable-output \
1 ; RUN: | grep {backedge-taken count is ((64 + (-64 smax (-1 + (-1 \\* %0))) + %0) /u 64)}
1 ; RUN: | grep {Loop bb3\\.i: Unpredictable backedge-taken count\\.}
2
3 ; ScalarEvolution can't compute a trip count because it doesn't know if
4 ; dividing by the stride will have a remainder. This could theoretically
5 ; be teaching it how to use a more elaborate trip count computation.
26
37 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"
48 target triple = "x86_64-unknown-linux-gnu"
0 ; RUN: llvm-as < %s | opt -indvars -loop-deletion | llvm-dis | grep phi | count 1
1 ; XFAIL: *
12
2 ; Indvars should be able to evaluate this loop, allowing loop deletion
3 ; to delete it.
3 ; Indvars can't evaluate this loop, because ScalarEvolution can't compute
4 ; an exact trip count, because it doesn't know if dividing by the stride will
5 ; have a remainder. It could be done with more aggressive VRP though.
46
57 define i32 @test(i32 %x_offs) nounwind readnone {
68 entry: