summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorMax Kazantsev <max.kazantsev@azul.com>2017-12-08 12:19:45 +0000
committerMax Kazantsev <max.kazantsev@azul.com>2017-12-08 12:19:45 +0000
commit9c08b7a0539ea98e6119ca1038a65c081e17d364 (patch)
tree73f18dc5a4ba648ef0ef86685aa0c737c6368c4a /llvm
parentf4bd295576d6ea3fa1dc69f5ec88e45c9e369fc1 (diff)
downloadbcm5719-llvm-9c08b7a0539ea98e6119ca1038a65c081e17d364.tar.gz
bcm5719-llvm-9c08b7a0539ea98e6119ca1038a65c081e17d364.zip
[SCEV] Fix predicate usage in computeExitLimitFromICmp
In this method, we invoke `SimplifyICmpOperands` which takes the `Cond` predicate by reference and may change it along with `LHS` and `RHS` SCEVs. But then we invoke `computeShiftCompareExitLimit` with Values from which the SCEVs have been derived, these Values have not been modified while `Cond` could be. One of possible outcomes of this is that we may falsely prove that an infinite loop ends within some finite number of iterations. In this patch, we save the original `Cond` and pass it along with original operands. This logic may be removed in future once `computeShiftCompareExitLimit` works with SCEVs instead of value operands. Reviewed By: sanjoy Differential Revision: https://reviews.llvm.org/D40953 llvm-svn: 320142
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp3
-rw-r--r--llvm/test/Analysis/ScalarEvolution/shift-op.ll19
2 files changed, 21 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 9bc8f2dc83d..8001d99603a 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -7074,6 +7074,7 @@ ScalarEvolution::computeExitLimitFromICmp(const Loop *L,
Cond = ExitCond->getPredicate();
else
Cond = ExitCond->getInversePredicate();
+ const ICmpInst::Predicate OriginalCond = Cond;
// Handle common loops like: for (X = "string"; *X; ++X)
if (LoadInst *LI = dyn_cast<LoadInst>(ExitCond->getOperand(0)))
@@ -7157,7 +7158,7 @@ ScalarEvolution::computeExitLimitFromICmp(const Loop *L,
return ExhaustiveCount;
return computeShiftCompareExitLimit(ExitCond->getOperand(0),
- ExitCond->getOperand(1), L, Cond);
+ ExitCond->getOperand(1), L, OriginalCond);
}
ScalarEvolution::ExitLimit
diff --git a/llvm/test/Analysis/ScalarEvolution/shift-op.ll b/llvm/test/Analysis/ScalarEvolution/shift-op.ll
index fe832d56768..ae13b2879df 100644
--- a/llvm/test/Analysis/ScalarEvolution/shift-op.ll
+++ b/llvm/test/Analysis/ScalarEvolution/shift-op.ll
@@ -160,5 +160,24 @@ define void @test8(i32 %init) {
ret void
}
+define void @test9() {
+; CHECK-LABEL: Determining loop execution counts for: @test9
+; CHECK: Loop %loop: Unpredictable max backedge-taken count.
+
+; This is an infinite loop, make sure that it recognized as such.
+
+entry:
+ br label %loop
+
+leave:
+ ret void
+
+loop:
+ %iv = phi i32 [ -20, %entry ], [ %iv.shift, %loop ]
+ %iv.shift = ashr i32 %iv, 1
+ %exit.cond = icmp sgt i32 %iv, -1
+ br i1 %exit.cond, label %leave, label %loop
+}
+
!0 = !{i32 0, i32 50000}
!1 = !{i32 -5000, i32 -1}
OpenPOWER on IntegriCloud