[PATCH] Fix for bug in indvars/ SCEV generating infinite loop (pr18886)

Dinesh Dwivedi dinesh.d at samsung.com
Tue May 20 04:19:05 PDT 2014


Hi atrick, hfinkel,

Condition like SCEV{-1,+,2} != 0 will always true and ScalarEvolution::HowFarToZero was
not generating correct exit limit for such exit conditions. Indvars pass was using these to
eliminate those exit conditions resulting in infinite loop.

This patch fixes PR18886, PR19799 and similar bugs.

http://reviews.llvm.org/D3837

Files:
  lib/Analysis/ScalarEvolution.cpp
  test/Transforms/IndVarSimplify/pr18886.ll
  test/Transforms/IndVarSimplify/pr19799.ll

Index: lib/Analysis/ScalarEvolution.cpp
===================================================================
--- lib/Analysis/ScalarEvolution.cpp
+++ lib/Analysis/ScalarEvolution.cpp
@@ -5741,8 +5741,14 @@
   // computed by this udiv could be smaller than the number of well-defined
   // iterations.
   if (!IsSubExpr && AddRec->getNoWrapFlags(SCEV::FlagNW)) {
+    // if start and step, both constant and start % step != 0, loop will never
+    // terminate by this condition.
+    if (isa<SCEVConstant>(Start) &&
+        GetMinTrailingZeros(Start) < GetMinTrailingZeros(Step))
+      return getCouldNotCompute();
+
     const SCEV *Exact =
-      getUDivExpr(Distance, CountDown ? getNegativeSCEV(Step) : Step);
+        getUDivExpr(Distance, CountDown ? getNegativeSCEV(Step) : Step);
     return ExitLimit(Exact, Exact, /*MustExit=*/false);
   }
 
Index: test/Transforms/IndVarSimplify/pr18886.ll
===================================================================
--- /dev/null
+++ test/Transforms/IndVarSimplify/pr18886.ll
@@ -0,0 +1,27 @@
+; RUN: opt -indvars -S < %s | FileCheck %s
+
+; CHECK-LABEL: @main(
+; CHECK-NOT: br i1 false, label %return, label %for.cond
+; CHECK-NOT: br i1 true, label %for.body, label %return
+
+ at a = global i64 0, align 8
+define i32 @main() {
+entry:
+  store i64 -21, i64* @a, align 8
+  br label %for.body
+
+for.body:
+  %storemerge1 = phi i64 [ -21, %entry ], [ %add, %for.cond ]
+  %tobool = icmp eq i64 %storemerge1, 0
+  %add = add nsw i64 %storemerge1, 8
+  br i1 %tobool, label %return, label %for.cond
+
+for.cond:
+  store i64 %add, i64* @a, align 8
+  %cmp = icmp slt i64 %add, 9
+  br i1 %cmp, label %for.body, label %return
+
+return:
+  %retval.0 = phi i32 [ 1, %for.body ], [ 0, %for.cond ]
+  ret i32 %retval.0
+}
Index: test/Transforms/IndVarSimplify/pr19799.ll
===================================================================
--- /dev/null
+++ test/Transforms/IndVarSimplify/pr19799.ll
@@ -0,0 +1,27 @@
+; RUN: opt -indvars -S < %s | FileCheck %s
+
+; CHECK-LABEL: @bar(
+; CHECK-NOT: br i1 true, label %for.body, label %return
+; CHECK-NOT: br i1 false, label %return, label %for.cond
+
+ at a = global i32 0, align 8
+define i32 @bar() {
+entry:
+  store i32 -1, i32* @a, align 4
+  br label %for.body
+
+for.cond:
+  store i32 %add.i, i32* @a, align 4
+  %cmp = icmp slt i32 %storemerge1, 0
+  br i1 %cmp, label %for.body, label %return
+
+for.body:
+  %storemerge1 = phi i32 [ -1, %entry ], [ %add.i, %for.cond ]
+  %tobool = icmp eq i32 %storemerge1, 0
+  %add.i = add nsw i32 %storemerge1, 2
+  br i1 %tobool, label %return, label %for.cond
+
+return:
+  %retval.0 = phi i32 [ 0, %for.body ], [ 1, %for.cond ]
+  ret i32 %retval.0
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3837.9606.patch
Type: text/x-patch
Size: 2699 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140520/adcfbc74/attachment.bin>


More information about the llvm-commits mailing list