[PATCH] D40953: [SCEV] Fix predicate usage in computeExitLimitFromICmp

Max Kazantsev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 7 06:34:32 PST 2017


mkazantsev created this revision.

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.


https://reviews.llvm.org/D40953

Files:
  lib/Analysis/ScalarEvolution.cpp
  test/Analysis/ScalarEvolution/shift-op.ll


Index: test/Analysis/ScalarEvolution/shift-op.ll
===================================================================
--- test/Analysis/ScalarEvolution/shift-op.ll
+++ test/Analysis/ScalarEvolution/shift-op.ll
@@ -160,5 +160,24 @@
   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}
Index: lib/Analysis/ScalarEvolution.cpp
===================================================================
--- lib/Analysis/ScalarEvolution.cpp
+++ lib/Analysis/ScalarEvolution.cpp
@@ -7058,6 +7058,7 @@
     Cond = ExitCond->getPredicate();
   else
     Cond = ExitCond->getInversePredicate();
+  ICmpInst::Predicate OriginalCond = Cond;
 
   // Handle common loops like: for (X = "string"; *X; ++X)
   if (LoadInst *LI = dyn_cast<LoadInst>(ExitCond->getOperand(0)))
@@ -7141,7 +7142,7 @@
     return ExhaustiveCount;
 
   return computeShiftCompareExitLimit(ExitCond->getOperand(0),
-                                      ExitCond->getOperand(1), L, Cond);
+                                      ExitCond->getOperand(1), L, OriginalCond);
 }
 
 ScalarEvolution::ExitLimit


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D40953.125943.patch
Type: text/x-patch
Size: 1525 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171207/454ae0d7/attachment.bin>


More information about the llvm-commits mailing list