llvm.org GIT mirror llvm / 96068f9
[SCEV] Fix PR26207 In some cases, the max backedge taken count can be more conservative than the exact backedge taken count (for instance, because ScalarEvolution::getRange is not control-flow sensitive whereas computeExitLimitFromICmp can be). In these cases, computeExitLimitFromCond (specifically the bit that deals with `and` and `or` instructions) can create an ExitLimit instance with a `SCEVCouldNotCompute` max backedge count expression, but a computable exact backedge count expression. This violates an implicit SCEV assumption: a computable exact BE count should imply a computable max BE count. This change - Makes the above implicit invariant explicit by adding an assert to ExitLimit's constructor - Changes `computeExitLimitFromCond` to be more robust around conservative max backedge counts git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@258184 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjoy Das 4 years ago
3 changed file(s) with 33 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
411411
412412 /*implicit*/ ExitLimit(const SCEV *E) : Exact(E), Max(E) {}
413413
414 ExitLimit(const SCEV *E, const SCEV *M) : Exact(E), Max(M) {}
414 ExitLimit(const SCEV *E, const SCEV *M) : Exact(E), Max(M) {
415 assert((isa(Exact) ||
416 !isa(Max)) &&
417 "Exact is not allowed to be less precise than Max");
418 }
415419
416420 /// Test whether this ExitLimit contains any computed information, or
417421 /// whether it's all SCEVCouldNotCompute values.
53665366 BECount = EL0.Exact;
53675367 }
53685368
5369 // There are cases (e.g. PR26207) where computeExitLimitFromCond is able
5370 // to be more aggressive when computing BECount than when computing
5371 // MaxBECount. In these cases it is possible for EL0.Exact and EL1.Exact
5372 // to match, but for EL0.Max and EL1.Max to not.
5373 if (isa(MaxBECount) &&
5374 !isa(BECount))
5375 MaxBECount = BECount;
5376
53695377 return ExitLimit(BECount, MaxBECount);
53705378 }
53715379 if (BO->getOpcode() == Instruction::Or) {
0 ; RUN: opt -S -indvars < %s | FileCheck %s
1
2 target triple = "x86_64-unknown-linux-gnu"
3
4 define void @main(i16 %in) {
5 ; CHECK-LABEL: @main(
6 br label %bb2
7
8 bb2: ; preds = %bb1.i, %bb2, %0
9 %_tmp44.i = icmp slt i16 %in, 2
10 br i1 %_tmp44.i, label %bb1.i, label %bb2
11
12 bb1.i: ; preds = %bb1.i, %bb2
13 %_tmp25.i = phi i16 [ %in, %bb2 ], [ %_tmp6.i, %bb1.i ]
14 %_tmp6.i = add nsw i16 %_tmp25.i, 1
15 %_tmp10.i = icmp sge i16 %_tmp6.i, 2
16 %exitcond.i = icmp eq i16 %_tmp6.i, 2
17 %or.cond = and i1 %_tmp10.i, %exitcond.i
18 br i1 %or.cond, label %bb2, label %bb1.i
19 }