summaryrefslogtreecommitdiff
path: root/test/Transforms/IndVarSimplify
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-12-30 11:46:15 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-12-30 11:46:15 +0000
commitdd58ef019b700900793a1eb48b52123db01b654e (patch)
treefcfbb4df56a744f4ddc6122c50521dd3f1c5e196 /test/Transforms/IndVarSimplify
parent2fe5752e3a7c345cdb59e869278d36af33c13fa4 (diff)
Notes
Diffstat (limited to 'test/Transforms/IndVarSimplify')
-rw-r--r--test/Transforms/IndVarSimplify/bec-cmp.ll47
-rw-r--r--test/Transforms/IndVarSimplify/const_phi.ll33
-rw-r--r--test/Transforms/IndVarSimplify/eliminate-comparison.ll348
-rw-r--r--test/Transforms/IndVarSimplify/iv-widen.ll30
-rw-r--r--test/Transforms/IndVarSimplify/loop-invariant-conditions.ll279
-rw-r--r--test/Transforms/IndVarSimplify/pr24356.ll63
-rw-r--r--test/Transforms/IndVarSimplify/pr24783.ll30
-rw-r--r--test/Transforms/IndVarSimplify/pr24804.ll25
-rw-r--r--test/Transforms/IndVarSimplify/pr24952.ll27
-rw-r--r--test/Transforms/IndVarSimplify/pr24956.ll37
-rw-r--r--test/Transforms/IndVarSimplify/pr25047.ll49
-rw-r--r--test/Transforms/IndVarSimplify/pr25051.ll44
-rw-r--r--test/Transforms/IndVarSimplify/pr25060.ll37
-rw-r--r--test/Transforms/IndVarSimplify/pr25360.ll33
-rw-r--r--test/Transforms/IndVarSimplify/pr25421.ll30
-rw-r--r--test/Transforms/IndVarSimplify/pr25578.ll45
-rw-r--r--test/Transforms/IndVarSimplify/tripcount_infinite.ll15
-rw-r--r--test/Transforms/IndVarSimplify/widen-loop-comp.ll160
-rw-r--r--test/Transforms/IndVarSimplify/zext-nuw.ll49
19 files changed, 1375 insertions, 6 deletions
diff --git a/test/Transforms/IndVarSimplify/bec-cmp.ll b/test/Transforms/IndVarSimplify/bec-cmp.ll
new file mode 100644
index 000000000000..06a7d5ebe4dc
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/bec-cmp.ll
@@ -0,0 +1,47 @@
+; RUN: opt -S -indvars < %s | FileCheck %s
+target datalayout = "E-m:e-i64:64-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+; Function Attrs: nounwind
+define void @foo(i32* nocapture %a, i32* nocapture readonly %b, i32 signext %n) #0 {
+entry:
+
+; CHECK-LABEL: @foo
+
+ %cmp.10 = icmp sgt i32 %n, 0
+ br i1 %cmp.10, label %for.body.lr.ph, label %for.cond.cleanup
+
+for.body.lr.ph: ; preds = %entry
+ br label %for.body
+
+for.cond.for.cond.cleanup_crit_edge: ; preds = %for.inc
+ br label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.cond.for.cond.cleanup_crit_edge, %entry
+ ret void
+
+for.body: ; preds = %for.body.lr.ph, %for.inc
+ %i.011 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]
+ %cmp1 = icmp sgt i32 %i.011, %n
+ br i1 %cmp1, label %if.then, label %for.inc
+
+; CHECK-NOT: br i1 %cmp1, label %if.then, label %for.inc
+; CHECK: br i1 false, label %if.then, label %for.inc
+
+if.then: ; preds = %for.body
+ %idxprom = sext i32 %i.011 to i64
+ %arrayidx = getelementptr inbounds i32, i32* %b, i64 %idxprom
+ %0 = load i32, i32* %arrayidx, align 4
+ %add = add nsw i32 %0, 1
+ %arrayidx3 = getelementptr inbounds i32, i32* %a, i64 %idxprom
+ store i32 %add, i32* %arrayidx3, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body, %if.then
+ %inc = add nsw i32 %i.011, 1
+ %cmp = icmp slt i32 %inc, %n
+ br i1 %cmp, label %for.body, label %for.cond.for.cond.cleanup_crit_edge
+}
+
+attributes #0 = { nounwind }
+
diff --git a/test/Transforms/IndVarSimplify/const_phi.ll b/test/Transforms/IndVarSimplify/const_phi.ll
new file mode 100644
index 000000000000..33dc5514d3cc
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/const_phi.ll
@@ -0,0 +1,33 @@
+; RUN: opt < %s -indvars -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+; PR25372
+; We can compute the expression of %phi0 and that is a SCEV
+; constant. However, instcombine can't deduce this, so we can
+; potentially end up trying to handle a constant when replacing
+; congruent IVs.
+
+; CHECK-LABEL: crash
+define void @crash() {
+entry:
+ br i1 false, label %not_taken, label %pre
+
+not_taken:
+ br label %pre
+
+pre:
+; %phi0.pre and %phi1.pre are evaluated by SCEV to constant 0.
+ %phi0.pre = phi i32 [ 0, %entry ], [ 2, %not_taken ]
+ %phi1.pre = phi i32 [ 0, %entry ], [ 1, %not_taken ]
+ br label %loop
+
+loop:
+; %phi0 and %phi1 are evaluated by SCEV to constant 0.
+ %phi0 = phi i32 [ 0, %loop ], [ %phi0.pre, %pre ]
+ %phi1 = phi i32 [ 0, %loop ], [ %phi1.pre, %pre ]
+ br i1 undef, label %exit, label %loop
+
+exit:
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/eliminate-comparison.ll b/test/Transforms/IndVarSimplify/eliminate-comparison.ll
index 4d14b3681c5d..612f01e3cade 100644
--- a/test/Transforms/IndVarSimplify/eliminate-comparison.ll
+++ b/test/Transforms/IndVarSimplify/eliminate-comparison.ll
@@ -209,3 +209,351 @@ assert77: ; preds = %noassert68
unrolledend: ; preds = %forcond38
ret i32 0
}
+
+declare void @side_effect()
+
+define void @func_13(i32* %len.ptr) {
+; CHECK-LABEL: @func_13(
+ entry:
+ %len = load i32, i32* %len.ptr, !range !0
+ %len.sub.1 = add i32 %len, -1
+ %len.is.zero = icmp eq i32 %len, 0
+ br i1 %len.is.zero, label %leave, label %loop
+
+ loop:
+; CHECK: loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
+ call void @side_effect()
+ %iv.inc = add i32 %iv, 1
+ %iv.cmp = icmp ult i32 %iv, %len
+ br i1 %iv.cmp, label %be, label %leave
+; CHECK: br i1 true, label %be, label %leave
+
+ be:
+ call void @side_effect()
+ %be.cond = icmp ult i32 %iv, %len.sub.1
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret void
+}
+
+define void @func_14(i32* %len.ptr) {
+; CHECK-LABEL: @func_14(
+ entry:
+ %len = load i32, i32* %len.ptr, !range !0
+ %len.sub.1 = add i32 %len, -1
+ %len.is.zero = icmp eq i32 %len, 0
+ %len.is.int_min = icmp eq i32 %len, 2147483648
+ %no.entry = or i1 %len.is.zero, %len.is.int_min
+ br i1 %no.entry, label %leave, label %loop
+
+ loop:
+; CHECK: loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
+ call void @side_effect()
+ %iv.inc = add i32 %iv, 1
+ %iv.cmp = icmp slt i32 %iv, %len
+ br i1 %iv.cmp, label %be, label %leave
+; CHECK: br i1 true, label %be, label %leave
+
+ be:
+ call void @side_effect()
+ %be.cond = icmp slt i32 %iv, %len.sub.1
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret void
+}
+
+define void @func_15(i32* %len.ptr) {
+; CHECK-LABEL: @func_15(
+ entry:
+ %len = load i32, i32* %len.ptr, !range !0
+ %len.add.1 = add i32 %len, 1
+ %len.add.1.is.zero = icmp eq i32 %len.add.1, 0
+ br i1 %len.add.1.is.zero, label %leave, label %loop
+
+ loop:
+; CHECK: loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
+ call void @side_effect()
+ %iv.inc = add i32 %iv, 1
+ %iv.cmp = icmp ult i32 %iv, %len.add.1
+ br i1 %iv.cmp, label %be, label %leave
+; CHECK: br i1 true, label %be, label %leave
+
+ be:
+ call void @side_effect()
+ %be.cond = icmp ult i32 %iv, %len
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret void
+}
+
+define void @func_16(i32* %len.ptr) {
+; CHECK-LABEL: @func_16(
+ entry:
+ %len = load i32, i32* %len.ptr, !range !0
+ %len.add.5 = add i32 %len, 5
+ %entry.cond.0 = icmp slt i32 %len, 2147483643
+ %entry.cond.1 = icmp slt i32 4, %len.add.5
+ %entry.cond = and i1 %entry.cond.0, %entry.cond.1
+ br i1 %entry.cond, label %loop, label %leave
+
+ loop:
+; CHECK: loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
+ call void @side_effect()
+ %iv.inc = add i32 %iv, 1
+ %iv.add.4 = add i32 %iv, 4
+ %iv.cmp = icmp slt i32 %iv.add.4, %len.add.5
+ br i1 %iv.cmp, label %be, label %leave
+; CHECK: br i1 true, label %be, label %leave
+
+ be:
+ call void @side_effect()
+ %be.cond = icmp slt i32 %iv, %len
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret void
+}
+
+define void @func_17(i32* %len.ptr) {
+; CHECK-LABEL: @func_17(
+ entry:
+ %len = load i32, i32* %len.ptr
+ %len.add.5 = add i32 %len, -5
+ %entry.cond.0 = icmp slt i32 %len, 2147483653 ;; 2147483653 == INT_MIN - (-5)
+ %entry.cond.1 = icmp slt i32 -6, %len.add.5
+ %entry.cond = and i1 %entry.cond.0, %entry.cond.1
+ br i1 %entry.cond, label %loop, label %leave
+
+ loop:
+; CHECK: loop:
+ %iv.2 = phi i32 [ 0, %entry ], [ %iv.2.inc, %be ]
+ %iv = phi i32 [ -6, %entry ], [ %iv.inc, %be ]
+ call void @side_effect()
+ %iv.inc = add i32 %iv, 1
+ %iv.2.inc = add i32 %iv.2, 1
+ %iv.cmp = icmp slt i32 %iv, %len.add.5
+
+; Deduces {-5,+,1} s< (-5 + %len) from {0,+,1} < %len
+; since %len s< INT_MIN - (-5) from the entry condition
+
+; CHECK: br i1 true, label %be, label %leave
+ br i1 %iv.cmp, label %be, label %leave
+
+ be:
+; CHECK: be:
+ call void @side_effect()
+ %be.cond = icmp slt i32 %iv.2, %len
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret void
+}
+
+define i1 @func_18(i16* %tmp20, i32* %len.addr) {
+; CHECK-LABEL: @func_18(
+entry:
+ %len = load i32, i32* %len.addr, !range !0
+ %tmp18 = icmp eq i32 %len, 0
+ br i1 %tmp18, label %bb2, label %bb0.preheader
+
+bb0.preheader:
+ br label %bb0
+
+bb0:
+; CHECK: bb0:
+ %var_0.in = phi i32 [ %var_0, %bb1 ], [ %len, %bb0.preheader ]
+ %var_1 = phi i32 [ %tmp30, %bb1 ], [ 0, %bb0.preheader ]
+ %var_0 = add nsw i32 %var_0.in, -1
+ %tmp23 = icmp ult i32 %var_1, %len
+; CHECK: br i1 true, label %stay, label %bb2.loopexit
+ br i1 %tmp23, label %stay, label %bb2
+
+stay:
+; CHECK: stay:
+ %tmp25 = getelementptr inbounds i16, i16* %tmp20, i32 %var_1
+ %tmp26 = load i16, i16* %tmp25
+ %tmp29 = icmp eq i16 %tmp26, 0
+ br i1 %tmp29, label %bb1, label %bb2
+
+bb1:
+ %tmp30 = add i32 %var_1, 1
+ %tmp31 = icmp eq i32 %var_0, 0
+ br i1 %tmp31, label %bb3, label %bb0
+
+bb2:
+ ret i1 false
+
+bb3:
+ ret i1 true
+}
+
+define void @func_19(i32* %length.ptr) {
+; CHECK-LABEL: @func_19(
+ entry:
+ %length = load i32, i32* %length.ptr, !range !0
+ %length.is.nonzero = icmp ne i32 %length, 0
+ br i1 %length.is.nonzero, label %loop, label %leave
+
+ loop:
+; CHECK: loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
+ %iv.inc = add i32 %iv, 1
+ %range.check = icmp ult i32 %iv, %length
+ br i1 %range.check, label %be, label %leave
+; CHECK: br i1 true, label %be, label %leave.loopexit
+; CHECK: be:
+
+ be:
+ call void @side_effect()
+ %be.cond = icmp slt i32 %iv.inc, %length
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret void
+}
+
+define void @func_20(i32* %length.ptr) {
+; Like @func_19, but %length is no longer provably positive, so
+; %range.check cannot be proved to be always true.
+
+; CHECK-LABEL: @func_20(
+ entry:
+ %length = load i32, i32* %length.ptr
+ %length.is.nonzero = icmp ne i32 %length, 0
+ br i1 %length.is.nonzero, label %loop, label %leave
+
+ loop:
+; CHECK: loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
+ %iv.inc = add i32 %iv, 1
+ %range.check = icmp ult i32 %iv, %length
+ br i1 %range.check, label %be, label %leave
+; CHECK: br i1 %range.check, label %be, label %leave.loopexit
+; CHECK: be:
+
+ be:
+ call void @side_effect()
+ %be.cond = icmp slt i32 %iv.inc, %length
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret void
+}
+
+define void @func_21(i32* %length.ptr) {
+; CHECK-LABEL: @func_21(
+
+; This checks that the backedge condition, (I + 1) < Length - 1 implies
+; (I + 1) < Length
+ entry:
+ %length = load i32, i32* %length.ptr, !range !0
+ %lim = sub i32 %length, 1
+ %entry.cond = icmp sgt i32 %length, 1
+ br i1 %entry.cond, label %loop, label %leave
+
+ loop:
+; CHECK: loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
+ %iv.inc = add i32 %iv, 1
+ %range.check = icmp slt i32 %iv, %length
+ br i1 %range.check, label %be, label %leave
+; CHECK: br i1 true, label %be, label %leave.loopexit
+; CHECK: be:
+
+ be:
+ call void @side_effect()
+ %be.cond = icmp slt i32 %iv.inc, %lim
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret void
+}
+
+define void @func_22(i32* %length.ptr) {
+; CHECK-LABEL: @func_22(
+
+; This checks that the backedge condition, (I + 1) < Length - 1 implies
+; (I + 1) < Length
+ entry:
+ %length = load i32, i32* %length.ptr, !range !0
+ %lim = sub i32 %length, 1
+ %entry.cond = icmp sgt i32 %length, 1
+ br i1 %entry.cond, label %loop, label %leave
+
+ loop:
+; CHECK: loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
+ %iv.inc = add i32 %iv, 1
+ %range.check = icmp sle i32 %iv, %length
+ br i1 %range.check, label %be, label %leave
+; CHECK: br i1 true, label %be, label %leave.loopexit
+; CHECK: be:
+
+ be:
+ call void @side_effect()
+ %be.cond = icmp sle i32 %iv.inc, %lim
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret void
+}
+
+define void @func_23(i32* %length.ptr) {
+; CHECK-LABEL: @func_23(
+ entry:
+ %length = load i32, i32* %length.ptr, !range !0
+ %entry.cond = icmp ult i32 4, %length
+ br i1 %entry.cond, label %loop, label %leave
+
+ loop:
+; CHECK: loop:
+ %iv = phi i32 [ 4, %entry ], [ %iv.inc, %be ]
+ %iv.inc = add i32 %iv, 1
+ %range.check = icmp slt i32 %iv, %length
+ br i1 %range.check, label %be, label %leave
+; CHECK: br i1 true, label %be, label %leave.loopexit
+; CHECK: be:
+
+ be:
+ call void @side_effect()
+ %be.cond = icmp slt i32 %iv.inc, %length
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret void
+}
+
+define void @func_24(i32* %init.ptr) {
+; CHECK-LABEL: @func_24(
+ entry:
+ %init = load i32, i32* %init.ptr, !range !0
+ %entry.cond = icmp ugt i32 %init, 4
+ br i1 %entry.cond, label %loop, label %leave
+
+ loop:
+; CHECK: loop:
+ %iv = phi i32 [ %init, %entry ], [ %iv.dec, %be ]
+ %iv.dec = add i32 %iv, -1
+ %range.check = icmp sgt i32 %iv, 4
+ br i1 %range.check, label %be, label %leave
+; CHECK: br i1 true, label %be, label %leave.loopexit
+; CHECK: be:
+
+ be:
+ call void @side_effect()
+ %be.cond = icmp sgt i32 %iv.dec, 4
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret void
+}
+
+
+!0 = !{i32 0, i32 2147483647}
diff --git a/test/Transforms/IndVarSimplify/iv-widen.ll b/test/Transforms/IndVarSimplify/iv-widen.ll
index 464b03ce5595..ccf9fa0aa0ac 100644
--- a/test/Transforms/IndVarSimplify/iv-widen.ll
+++ b/test/Transforms/IndVarSimplify/iv-widen.ll
@@ -6,7 +6,7 @@ target datalayout = "n8:16:32:64"
target triple = "x86_64-apple-darwin"
-; CHECK-LABEL: @sloop
+; CHECK-LABEL: @loop_0
; CHECK-LABEL: B18:
; Only one phi now.
; CHECK: phi
@@ -16,7 +16,7 @@ target triple = "x86_64-apple-darwin"
; One trunc for the dummy() call.
; CHECK-LABEL: exit24:
; CHECK: trunc i64 {{.*}}lcssa.wide to i32
-define void @sloop(i32* %a) {
+define void @loop_0(i32* %a) {
Prologue:
br i1 undef, label %B18, label %B6
@@ -41,4 +41,30 @@ exit24: ; preds = %B18
unreachable
}
+define void @loop_1(i32 %lim) {
+; CHECK-LABEL: @loop_1(
+ entry:
+ %entry.cond = icmp ne i32 %lim, 0
+ br i1 %entry.cond, label %loop, label %leave
+
+ loop:
+; CHECK: loop:
+; CHECK: %indvars.iv = phi i64 [ 1, %loop.preheader ], [ %indvars.iv.next, %loop ]
+; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+; CHECK: [[IV_INC:%[^ ]+]] = add nsw i64 %indvars.iv, -1
+; CHECK: call void @dummy.i64(i64 [[IV_INC]])
+
+ %iv = phi i32 [ 1, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add i32 %iv, 1
+ %iv.inc.sub = add i32 %iv, -1
+ %iv.inc.sub.zext = zext i32 %iv.inc.sub to i64
+ call void @dummy.i64(i64 %iv.inc.sub.zext)
+ %be.cond = icmp ult i32 %iv.inc, %lim
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret void
+}
+
declare void @dummy(i32)
+declare void @dummy.i64(i64)
diff --git a/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll b/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll
new file mode 100644
index 000000000000..eee321da2395
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll
@@ -0,0 +1,279 @@
+; RUN: opt -S -indvars %s | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @test1(i64 %start) {
+; CHECK-LABEL: @test1
+entry:
+ br label %loop
+
+loop:
+ %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
+ %indvars.iv.next = add nsw i64 %indvars.iv, 1
+; CHECK: %cmp1 = icmp slt i64 %start, -1
+ %cmp1 = icmp slt i64 %indvars.iv, -1
+ br i1 %cmp1, label %for.end, label %loop
+
+for.end: ; preds = %if.end, %entry
+ ret void
+}
+
+define void @test2(i64 %start) {
+; CHECK-LABEL: @test2
+entry:
+ br label %loop
+
+loop:
+ %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
+ %indvars.iv.next = add nsw i64 %indvars.iv, 1
+; CHECK: %cmp1 = icmp sle i64 %start, -1
+ %cmp1 = icmp sle i64 %indvars.iv, -1
+ br i1 %cmp1, label %for.end, label %loop
+
+for.end: ; preds = %if.end, %entry
+ ret void
+}
+
+; As long as the test dominates the backedge, we're good
+define void @test3(i64 %start) {
+; CHECK-LABEL: @test3
+entry:
+ br label %loop
+
+loop:
+ %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
+ %indvars.iv.next = add nsw i64 %indvars.iv, 1
+ %cmp = icmp eq i64 %indvars.iv.next, 25
+ br i1 %cmp, label %backedge, label %for.end
+
+backedge:
+ ; prevent flattening, needed to make sure we're testing what we intend
+ call void @foo()
+; CHECK: %cmp1 = icmp slt i64 %start, -1
+ %cmp1 = icmp slt i64 %indvars.iv, -1
+ br i1 %cmp1, label %for.end, label %loop
+
+for.end: ; preds = %if.end, %entry
+ ret void
+}
+
+define void @test4(i64 %start) {
+; CHECK-LABEL: @test4
+entry:
+ br label %loop
+
+loop:
+ %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
+ %indvars.iv.next = add nsw i64 %indvars.iv, 1
+ %cmp = icmp eq i64 %indvars.iv.next, 25
+ br i1 %cmp, label %backedge, label %for.end
+
+backedge:
+ ; prevent flattening, needed to make sure we're testing what we intend
+ call void @foo()
+; CHECK: %cmp1 = icmp sgt i64 %start, -1
+ %cmp1 = icmp sgt i64 %indvars.iv, -1
+ br i1 %cmp1, label %loop, label %for.end
+
+for.end: ; preds = %if.end, %entry
+ ret void
+}
+
+define void @test5(i64 %start) {
+; CHECK-LABEL: @test5
+entry:
+ br label %loop
+
+loop:
+ %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
+ %indvars.iv.next = add nuw i64 %indvars.iv, 1
+ %cmp = icmp eq i64 %indvars.iv.next, 25
+ br i1 %cmp, label %backedge, label %for.end
+
+backedge:
+ ; prevent flattening, needed to make sure we're testing what we intend
+ call void @foo()
+; CHECK: %cmp1 = icmp ugt i64 %start, 100
+ %cmp1 = icmp ugt i64 %indvars.iv, 100
+ br i1 %cmp1, label %loop, label %for.end
+
+for.end: ; preds = %if.end, %entry
+ ret void
+}
+
+define void @test6(i64 %start) {
+; CHECK-LABEL: @test6
+entry:
+ br label %loop
+
+loop:
+ %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
+ %indvars.iv.next = add nuw i64 %indvars.iv, 1
+ %cmp = icmp eq i64 %indvars.iv.next, 25
+ br i1 %cmp, label %backedge, label %for.end
+
+backedge:
+ ; prevent flattening, needed to make sure we're testing what we intend
+ call void @foo()
+; CHECK: %cmp1 = icmp ult i64 %start, 100
+ %cmp1 = icmp ult i64 %indvars.iv, 100
+ br i1 %cmp1, label %for.end, label %loop
+
+for.end: ; preds = %if.end, %entry
+ ret void
+}
+
+define void @test7(i64 %start, i64* %inc_ptr) {
+; CHECK-LABEL: @test7
+entry:
+ %inc = load i64, i64* %inc_ptr, !range !0
+ %ok = icmp sge i64 %inc, 0
+ br i1 %ok, label %loop, label %for.end
+
+loop:
+ %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
+ %indvars.iv.next = add nsw i64 %indvars.iv, %inc
+; CHECK: %cmp1 = icmp slt i64 %start, -1
+ %cmp1 = icmp slt i64 %indvars.iv, -1
+ br i1 %cmp1, label %for.end, label %loop
+
+for.end: ; preds = %if.end, %entry
+ ret void
+}
+
+!0 = !{i64 0, i64 100}
+
+; Negative test - we can't show that the internal branch executes, so we can't
+; fold the test to a loop invariant one.
+define void @test1_neg(i64 %start) {
+; CHECK-LABEL: @test1_neg
+entry:
+ br label %loop
+
+loop:
+ %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
+ %indvars.iv.next = add nsw i64 %indvars.iv, 1
+ %cmp = icmp eq i64 %indvars.iv.next, 25
+ br i1 %cmp, label %backedge, label %skip
+skip:
+ ; prevent flattening, needed to make sure we're testing what we intend
+ call void @foo()
+; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
+ %cmp1 = icmp slt i64 %indvars.iv, -1
+ br i1 %cmp1, label %for.end, label %backedge
+backedge:
+ ; prevent flattening, needed to make sure we're testing what we intend
+ call void @foo()
+ br label %loop
+
+for.end: ; preds = %if.end, %entry
+ ret void
+}
+
+; Slightly subtle version of @test4 where the icmp dominates the backedge,
+; but the exit branch doesn't.
+define void @test2_neg(i64 %start) {
+; CHECK-LABEL: @test2_neg
+entry:
+ br label %loop
+
+loop:
+ %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
+ %indvars.iv.next = add nsw i64 %indvars.iv, 1
+ %cmp = icmp eq i64 %indvars.iv.next, 25
+; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
+ %cmp1 = icmp slt i64 %indvars.iv, -1
+ br i1 %cmp, label %backedge, label %skip
+skip:
+ ; prevent flattening, needed to make sure we're testing what we intend
+ call void @foo()
+ br i1 %cmp1, label %for.end, label %backedge
+backedge:
+ ; prevent flattening, needed to make sure we're testing what we intend
+ call void @foo()
+ br label %loop
+
+for.end: ; preds = %if.end, %entry
+ ret void
+}
+
+; The branch has to exit the loop if the condition is true
+define void @test3_neg(i64 %start) {
+; CHECK-LABEL: @test3_neg
+entry:
+ br label %loop
+
+loop:
+ %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
+ %indvars.iv.next = add nsw i64 %indvars.iv, 1
+; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
+ %cmp1 = icmp slt i64 %indvars.iv, -1
+ br i1 %cmp1, label %loop, label %for.end
+
+for.end: ; preds = %if.end, %entry
+ ret void
+}
+
+define void @test4_neg(i64 %start) {
+; CHECK-LABEL: @test4_neg
+entry:
+ br label %loop
+
+loop:
+ %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
+ %indvars.iv.next = add nsw i64 %indvars.iv, 1
+ %cmp = icmp eq i64 %indvars.iv.next, 25
+ br i1 %cmp, label %backedge, label %for.end
+
+backedge:
+ ; prevent flattening, needed to make sure we're testing what we intend
+ call void @foo()
+; CHECK: %cmp1 = icmp sgt i64 %indvars.iv, -1
+ %cmp1 = icmp sgt i64 %indvars.iv, -1
+
+; %cmp1 can be made loop invariant only if the branch below goes to
+; %the header when %cmp1 is true.
+ br i1 %cmp1, label %for.end, label %loop
+
+for.end: ; preds = %if.end, %entry
+ ret void
+}
+
+define void @test5_neg(i64 %start, i64 %inc) {
+; CHECK-LABEL: @test5_neg
+entry:
+ br label %loop
+
+loop:
+ %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
+ %indvars.iv.next = add nsw i64 %indvars.iv, %inc
+; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
+ %cmp1 = icmp slt i64 %indvars.iv, -1
+ br i1 %cmp1, label %for.end, label %loop
+
+for.end: ; preds = %if.end, %entry
+ ret void
+}
+
+define void @test8(i64 %start, i64* %inc_ptr) {
+; CHECK-LABEL: @test8
+entry:
+ %inc = load i64, i64* %inc_ptr, !range !1
+ %ok = icmp sge i64 %inc, 0
+ br i1 %ok, label %loop, label %for.end
+
+loop:
+ %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
+ %indvars.iv.next = add nsw i64 %indvars.iv, %inc
+; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
+ %cmp1 = icmp slt i64 %indvars.iv, -1
+ br i1 %cmp1, label %for.end, label %loop
+
+for.end: ; preds = %if.end, %entry
+ ret void
+}
+
+!1 = !{i64 -1, i64 100}
+
+
+declare void @foo()
diff --git a/test/Transforms/IndVarSimplify/pr24356.ll b/test/Transforms/IndVarSimplify/pr24356.ll
new file mode 100644
index 000000000000..eac4204c0e16
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/pr24356.ll
@@ -0,0 +1,63 @@
+; RUN: opt -S -indvars < %s | FileCheck %s
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.10.0"
+
+@a = common global i32 0, align 4
+
+; Function Attrs: nounwind ssp uwtable
+define void @fn1() {
+; CHECK-LABEL: @fn1(
+bb:
+ br label %bb4.preheader
+
+bb4.preheader: ; preds = %bb, %bb16
+; CHECK-LABEL: bb4.preheader:
+ %b.03 = phi i8 [ 0, %bb ], [ %tmp17, %bb16 ]
+; CHECK: %tmp9 = icmp ugt i8 %b.03, 1
+; CHECK-NOT: %tmp9 = icmp ugt i8 0, 1
+
+ %tmp9 = icmp ugt i8 %b.03, 1
+ br i1 %tmp9, label %bb4.preheader.bb18.loopexit.split_crit_edge, label %bb4.preheader.bb4.preheader.split_crit_edge
+
+bb4.preheader.bb4.preheader.split_crit_edge: ; preds = %bb4.preheader
+ br label %bb4.preheader.split
+
+bb4.preheader.bb18.loopexit.split_crit_edge: ; preds = %bb4.preheader
+ store i32 0, i32* @a, align 4
+ br label %bb18.loopexit.split
+
+bb4.preheader.split: ; preds = %bb4.preheader.bb4.preheader.split_crit_edge
+ br label %bb7
+
+bb4: ; preds = %bb7
+ %tmp6 = icmp slt i32 %storemerge2, 0
+ br i1 %tmp6, label %bb7, label %bb16
+
+bb7: ; preds = %bb4.preheader.split, %bb4
+ %storemerge2 = phi i32 [ 0, %bb4.preheader.split ], [ %tmp14, %bb4 ]
+ %tmp14 = add nsw i32 %storemerge2, 1
+ br i1 false, label %bb18.loopexit, label %bb4
+
+bb16: ; preds = %bb4
+ %tmp14.lcssa5 = phi i32 [ %tmp14, %bb4 ]
+ %tmp17 = add i8 %b.03, -1
+ %tmp2 = icmp eq i8 %tmp17, -2
+ br i1 %tmp2, label %bb18.loopexit1, label %bb4.preheader
+
+bb18.loopexit: ; preds = %bb7
+ br label %bb18.loopexit.split
+
+bb18.loopexit.split: ; preds = %bb4.preheader.bb18.loopexit.split_crit_edge, %bb18.loopexit
+ br label %bb18
+
+bb18.loopexit1: ; preds = %bb16
+ %tmp14.lcssa5.lcssa = phi i32 [ %tmp14.lcssa5, %bb16 ]
+ store i32 %tmp14.lcssa5.lcssa, i32* @a, align 4
+ br label %bb18
+
+bb18: ; preds = %bb18.loopexit1, %bb18.loopexit.split
+ ret void
+}
+
+declare void @abort()
diff --git a/test/Transforms/IndVarSimplify/pr24783.ll b/test/Transforms/IndVarSimplify/pr24783.ll
new file mode 100644
index 000000000000..637cb1e196c5
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/pr24783.ll
@@ -0,0 +1,30 @@
+; RUN: opt -S -indvars < %s | FileCheck %s
+
+target datalayout = "E-m:e-i64:64-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+define void @f(i32* %end.s, i8** %loc, i32 %p) {
+; CHECK-LABEL: @f(
+entry:
+; CHECK: [[P_SEXT:%[0-9a-z]+]] = sext i32 %p to i64
+; CHECK: [[END:%[0-9a-z]+]] = getelementptr i32, i32* %end.s, i64 [[P_SEXT]]
+
+ %end = getelementptr inbounds i32, i32* %end.s, i32 %p
+ %init = bitcast i32* %end.s to i8*
+ br label %while.body.i
+
+while.body.i:
+ %ptr = phi i8* [ %ptr.inc, %while.body.i ], [ %init, %entry ]
+ %ptr.inc = getelementptr inbounds i8, i8* %ptr, i8 1
+ %ptr.inc.cast = bitcast i8* %ptr.inc to i32*
+ %cmp.i = icmp eq i32* %ptr.inc.cast, %end
+ br i1 %cmp.i, label %loop.exit, label %while.body.i
+
+loop.exit:
+; CHECK: loop.exit:
+; CHECK: [[END_BCASTED:%[a-z0-9]+]] = bitcast i32* %scevgep to i8*
+; CHECK: store i8* [[END_BCASTED]], i8** %loc
+ %ptr.inc.lcssa = phi i8* [ %ptr.inc, %while.body.i ]
+ store i8* %ptr.inc.lcssa, i8** %loc
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/pr24804.ll b/test/Transforms/IndVarSimplify/pr24804.ll
new file mode 100644
index 000000000000..6f89481853ad
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/pr24804.ll
@@ -0,0 +1,25 @@
+; RUN: opt -indvars -loop-idiom -loop-deletion -S < %s | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Checking for a crash
+
+define void @f(i32* %a) {
+; CHECK-LABEL: @f(
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %for.cond, %entry
+ %iv = phi i32 [ 0, %entry ], [ %add, %for.inc ], [ %iv, %for.cond ]
+ %add = add nsw i32 %iv, 1
+ %idxprom = sext i32 %add to i64
+ %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
+ br i1 undef, label %for.cond, label %for.inc
+
+for.inc: ; preds = %for.cond
+ br i1 undef, label %for.cond, label %for.end
+
+for.end: ; preds = %for.inc
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/pr24952.ll b/test/Transforms/IndVarSimplify/pr24952.ll
new file mode 100644
index 000000000000..c430cae98f58
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/pr24952.ll
@@ -0,0 +1,27 @@
+; RUN: opt -indvars -S < %s | FileCheck %s
+
+declare void @use(i1)
+
+define void @f() {
+; CHECK-LABEL: @f(
+ entry:
+ %x = alloca i32
+ %y = alloca i32
+ br label %loop
+
+ loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add i32 %iv, 1
+
+ %x.gep = getelementptr i32, i32* %x, i32 %iv
+ %eql = icmp eq i32* %x.gep, %y
+; CHECK-NOT: @use(i1 true)
+ call void @use(i1 %eql)
+
+ ; %be.cond deliberately 'false' -- we want want the trip count to be 0.
+ %be.cond = icmp ult i32 %iv, 0
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/pr24956.ll b/test/Transforms/IndVarSimplify/pr24956.ll
new file mode 100644
index 000000000000..58688912cc37
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/pr24956.ll
@@ -0,0 +1,37 @@
+; RUN: opt -S -indvars < %s | FileCheck %s
+
+; Check that this test does not crash.
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.10.0"
+
+define void @re_update_line(i8* %new) {
+; CHECK: @re_update_line(
+entry:
+ %incdec.ptr6 = getelementptr inbounds i8, i8* %new, i64 1
+ br label %for.cond.11.preheader
+
+for.cond.11.preheader: ; preds = %for.inc.26, %entry
+ %n.154 = phi i8* [ %new, %entry ], [ %incdec.ptr27, %for.inc.26 ]
+ %cmp12.52 = icmp ult i8* %n.154, %incdec.ptr6
+ br i1 %cmp12.52, label %land.rhs.16.lr.ph, label %for.inc.26
+
+land.rhs.16.lr.ph: ; preds = %for.cond.11.preheader
+ br label %land.rhs.16
+
+for.cond.11: ; preds = %land.rhs.16
+ %incdec.ptr24 = getelementptr inbounds i8, i8* %p.053, i64 1
+ %cmp12 = icmp ult i8* %p.053, %new
+ br i1 %cmp12, label %land.rhs.16, label %for.inc.26
+
+land.rhs.16: ; preds = %for.cond.11, %land.rhs.16.lr.ph
+ %p.053 = phi i8* [ %n.154, %land.rhs.16.lr.ph ], [ %incdec.ptr24, %for.cond.11 ]
+ br i1 undef, label %for.cond.11, label %for.inc.26
+
+for.inc.26: ; preds = %land.rhs.16, %for.cond.11, %for.cond.11.preheader
+ %incdec.ptr27 = getelementptr inbounds i8, i8* %n.154, i64 1
+ br i1 false, label %for.cond.11.preheader, label %for.end.28
+
+for.end.28: ; preds = %for.inc.26
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/pr25047.ll b/test/Transforms/IndVarSimplify/pr25047.ll
new file mode 100644
index 000000000000..dc39a78c7eb9
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/pr25047.ll
@@ -0,0 +1,49 @@
+; RUN: opt -indvars -S < %s | FileCheck %s
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+define void @fn1(i1 %c0, i1 %c1) {
+; CHECK-LABEL: @fn1(
+entry:
+ br i1 %c0, label %for.end.34, label %for.cond.1thread-pre-split
+
+for.cond.loopexit: ; preds = %for.end.29, %for.end.7
+ %f.lcssa = phi i32 [ %f.1, %for.end.29 ], [ %f.1, %for.end.7 ]
+ br i1 %c1, label %for.end.34, label %for.cond.1thread-pre-split
+
+for.cond.1thread-pre-split: ; preds = %for.cond.loopexit, %entry
+ %f.047 = phi i32 [ %f.lcssa, %for.cond.loopexit ], [ 0, %entry ]
+ br label %for.cond.1
+
+for.cond.1: ; preds = %for.cond.1, %for.cond.1thread-pre-split
+ br i1 %c1, label %for.cond.4, label %for.cond.1
+
+for.cond.4: ; preds = %for.end.29, %for.cond.1
+ %f.1 = phi i32 [ 0, %for.end.29 ], [ %f.047, %for.cond.1 ]
+ br label %for.cond.5
+
+for.cond.5: ; preds = %for.cond.5, %for.cond.4
+ %h.0 = phi i32 [ 0, %for.cond.4 ], [ %inc, %for.cond.5 ]
+ %cmp = icmp slt i32 %h.0, 1
+ %inc = add nsw i32 %h.0, 1
+ br i1 %cmp, label %for.cond.5, label %for.end.7
+
+for.end.7: ; preds = %for.cond.5
+ %g.lcssa = phi i32 [ %h.0, %for.cond.5 ]
+ %tobool10 = icmp eq i32 %g.lcssa, 0
+ br i1 %tobool10, label %for.end.8, label %for.cond.loopexit
+
+for.end.8: ; preds = %for.end.7
+ br i1 %c1, label %for.cond.19, label %for.end.29
+
+for.cond.19: ; preds = %for.cond.19, %for.end.8
+ br label %for.cond.19
+
+for.end.29: ; preds = %for.end.8
+ %tobool30 = icmp eq i32 %f.1, 0
+ br i1 %tobool30, label %for.cond.4, label %for.cond.loopexit
+
+for.end.34: ; preds = %for.cond.loopexit, %entry
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/pr25051.ll b/test/Transforms/IndVarSimplify/pr25051.ll
new file mode 100644
index 000000000000..a02d539a66dd
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/pr25051.ll
@@ -0,0 +1,44 @@
+; RUN: opt -S -indvars < %s | FileCheck %s
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+define i32 @somefunc(double* %arr) {
+; CHECK-LABEL: @somefunc(
+entry:
+ br label %for.cond.1.preheader
+
+for.cond.1.preheader: ; preds = %for.inc.9, %entry
+ %index3.013 = phi i32 [ 0, %entry ], [ %index3.1.lcssa, %for.inc.9 ]
+ %index.012 = phi i32 [ 0, %entry ], [ %inc10, %for.inc.9 ]
+ %cmp2.9 = icmp sgt i32 %index.012, 0
+ br i1 %cmp2.9, label %for.body.3.lr.ph, label %for.inc.9
+
+for.body.3.lr.ph: ; preds = %for.cond.1.preheader
+ %idxprom5 = sext i32 %index.012 to i64
+ br label %for.body.3
+
+for.body.3: ; preds = %for.body.3, %for.body.3.lr.ph
+ %index3.111 = phi i32 [ %index3.013, %for.body.3.lr.ph ], [ %inc, %for.body.3 ]
+ %index2.010 = phi i32 [ 0, %for.body.3.lr.ph ], [ %inc8, %for.body.3 ]
+ %inc = add nsw i32 %index3.111, 1
+ %idxprom = sext i32 %index3.111 to i64
+ %arrayidx = getelementptr inbounds double, double* %arr, i64 %idxprom
+ %idxprom4 = sext i32 %index2.010 to i64
+ %inc8 = add nsw i32 %index2.010, 1
+ %cmp2 = icmp slt i32 %inc8, %index.012
+ br i1 %cmp2, label %for.body.3, label %for.inc.9.loopexit
+
+for.inc.9.loopexit: ; preds = %for.body.3
+ %inc.lcssa = phi i32 [ %inc, %for.body.3 ]
+ br label %for.inc.9
+
+for.inc.9: ; preds = %for.inc.9.loopexit, %for.cond.1.preheader
+ %index3.1.lcssa = phi i32 [ %index3.013, %for.cond.1.preheader ], [ %inc.lcssa, %for.inc.9.loopexit ]
+ %inc10 = add nsw i32 %index.012, 1
+ %cmp = icmp slt i32 %inc10, 10
+ br i1 %cmp, label %for.cond.1.preheader, label %for.end.11
+
+for.end.11: ; preds = %for.inc.9
+ ret i32 1
+}
diff --git a/test/Transforms/IndVarSimplify/pr25060.ll b/test/Transforms/IndVarSimplify/pr25060.ll
new file mode 100644
index 000000000000..25863fff2d36
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/pr25060.ll
@@ -0,0 +1,37 @@
+; RUN: opt -S -indvars < %s | FileCheck %s
+
+define i16 @fn1() {
+; CHECK-LABEL: @fn1(
+entry:
+ br label %bb1
+
+bb1:
+ %i = phi i16 [ 0, %entry ], [ 1, %bb1 ]
+ %storemerge = phi i16 [ %storemerge2, %bb1 ], [ 0, %entry ]
+ %storemerge2 = phi i16 [ 10, %entry ], [ 200, %bb1 ]
+ %tmp10 = icmp eq i16 %i, 1
+ br i1 %tmp10, label %bb5, label %bb1
+
+bb5:
+ %storemerge.lcssa = phi i16 [ %storemerge, %bb1 ]
+; CHECK: ret i16 10
+ ret i16 %storemerge.lcssa
+}
+
+define i16 @fn2() {
+; CHECK-LABEL: @fn2(
+entry:
+ br label %bb1
+
+bb1:
+ %canary = phi i16 [ 0, %entry ], [ %canary.inc, %bb1 ]
+ %i = phi i16 [ 0, %entry ], [ %storemerge, %bb1 ]
+ %storemerge = phi i16 [ 0, %bb1 ], [ 10, %entry ]
+ %canary.inc = add i16 %canary, 1
+ %_tmp10 = icmp eq i16 %i, 10
+ br i1 %_tmp10, label %bb5, label %bb1
+
+bb5:
+; CHECK: ret i16 1
+ ret i16 %canary
+}
diff --git a/test/Transforms/IndVarSimplify/pr25360.ll b/test/Transforms/IndVarSimplify/pr25360.ll
new file mode 100644
index 000000000000..9f6df7051ea8
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/pr25360.ll
@@ -0,0 +1,33 @@
+; RUN: opt -indvars -S < %s | FileCheck %s
+
+
+; Ensure that does not crash
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f() {
+; CHECK-LABEL: @f(
+entry:
+ br label %for.end
+
+for.condt: ; preds = %for.end
+ br i1 true, label %for.cond.0, label %for.end
+
+for.end: ; preds = %for.body.3
+ %inc = select i1 undef, i32 2, i32 1
+ br i1 false, label %for.condt, label %for.cond.0
+
+for.cond.0: ; preds = %for.end, %for.condt
+ %init = phi i32 [ 0, %for.condt ], [ %inc, %for.end ]
+ br i1 true, label %for.end.13, label %for.body.9
+
+for.body.9: ; preds = %for.body.9, %for.cond.0
+ %p1.addr.22 = phi i32 [ %inc10, %for.body.9 ], [ %init, %for.cond.0 ]
+ %inc10 = add i32 %p1.addr.22, 1
+ br i1 true, label %for.end.13, label %for.body.9
+
+for.end.13: ; preds = %for.cond.7.for.end.13_crit_edge, %for.cond.0
+ %p1.addr.2.lcssa = phi i32 [ %inc10, %for.body.9 ], [ %init, %for.cond.0 ]
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/pr25421.ll b/test/Transforms/IndVarSimplify/pr25421.ll
new file mode 100644
index 000000000000..efb71f9c3039
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/pr25421.ll
@@ -0,0 +1,30 @@
+; RUN: opt -S -indvars < %s | FileCheck %s
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+declare void @use(i1)
+
+define void @f(i32 %x) {
+; CHECK-LABEL: @f(
+ entry:
+ %conv = sext i32 %x to i64
+ %sub = add i64 %conv, -1
+ %ec = icmp sgt i32 %x, 0
+ br i1 %ec, label %loop, label %leave
+
+ loop:
+; CHECK: loop:
+ %iv = phi i64 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add i64 %iv, 1
+ %cmp = icmp slt i64 %iv, %sub
+ call void @use(i1 %cmp)
+; CHECK: call void @use(i1 %cmp)
+; CHECK-NOT: call void @use(i1 true)
+
+ %be.cond = icmp slt i64 %iv.inc, %conv
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/pr25578.ll b/test/Transforms/IndVarSimplify/pr25578.ll
new file mode 100644
index 000000000000..bc648b517bbe
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/pr25578.ll
@@ -0,0 +1,45 @@
+; RUN: opt < %s -indvars -S | FileCheck %s
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+
+; CHECK-LABEL: @foo
+define void @foo() {
+entry:
+ br label %L1_header
+
+L1_header:
+ br label %L2_header
+
+; CHECK: L2_header:
+; CHECK: %[[INDVAR:.*]] = phi i64
+; CHECK: %[[TRUNC:.*]] = trunc i64 %[[INDVAR]] to i32
+L2_header:
+ %i = phi i32 [ 0, %L1_header ], [ %i_next, %L2_latch ]
+ %i_prom = sext i32 %i to i64
+ br label %L3_header
+
+L3_header:
+ br i1 undef, label %L3_latch, label %L2_exiting_1
+
+L3_latch:
+ br i1 undef, label %L3_header, label %L2_exiting_2
+
+L2_exiting_1:
+ br i1 undef, label %L2_latch, label %L1_latch
+
+L2_exiting_2:
+ br i1 undef, label %L2_latch, label %L1_latch
+
+L2_latch:
+ %i_next = add nsw i32 %i, 1
+ br label %L2_header
+
+L1_latch:
+; CHECK: L1_latch:
+; CHECK: %i_lcssa = phi i32 [ %[[TRUNC]], %L2_exiting_1 ], [ %[[TRUNC]], %L2_exiting_2 ]
+
+ %i_lcssa = phi i32 [ %i, %L2_exiting_1 ], [ %i, %L2_exiting_2 ]
+ br i1 undef, label %exit, label %L1_header
+
+exit:
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/tripcount_infinite.ll b/test/Transforms/IndVarSimplify/tripcount_infinite.ll
index 0495b50c3e48..658598d3b7e4 100644
--- a/test/Transforms/IndVarSimplify/tripcount_infinite.ll
+++ b/test/Transforms/IndVarSimplify/tripcount_infinite.ll
@@ -1,38 +1,45 @@
; These tests have an infinite trip count. We obviously shouldn't remove the
; loops! :)
;
-; RUN: opt < %s -indvars -adce -simplifycfg -S | grep icmp | wc -l > %t2
-; RUN: llvm-as < %s | llvm-dis | grep icmp | wc -l > %t1
-; RUN: diff %t1 %t2
+; RUN: opt < %s -indvars -adce -simplifycfg -S | FileCheck %s
;; test for (i = 1; i != 100; i += 2)
define i32 @infinite_linear() {
+; CHECK-LABEL: @infinite_linear(
entry:
br label %loop
loop: ; preds = %loop, %entry
+; CHECK-LABEL: loop:
%i = phi i32 [ 1, %entry ], [ %i.next, %loop ] ; <i32> [#uses=3]
%i.next = add i32 %i, 2 ; <i32> [#uses=1]
%c = icmp ne i32 %i, 100 ; <i1> [#uses=1]
+; CHECK: icmp
+; CHECK: br
br i1 %c, label %loop, label %loopexit
loopexit: ; preds = %loop
+; CHECK-LABEL: loopexit:
ret i32 %i
}
;; test for (i = 1; i*i != 63; ++i)
define i32 @infinite_quadratic() {
+; CHECK-LABEL: @infinite_quadratic(
entry:
br label %loop
loop: ; preds = %loop, %entry
+; CHECK-LABEL: loop:
%i = phi i32 [ 1, %entry ], [ %i.next, %loop ] ; <i32> [#uses=4]
%isquare = mul i32 %i, %i ; <i32> [#uses=1]
%i.next = add i32 %i, 1 ; <i32> [#uses=1]
%c = icmp ne i32 %isquare, 63 ; <i1> [#uses=1]
+; CHECK: icmp
+; CHECK: br
br i1 %c, label %loop, label %loopexit
loopexit: ; preds = %loop
+; CHECK-LABEL: loopexit:
ret i32 %i
}
-
diff --git a/test/Transforms/IndVarSimplify/widen-loop-comp.ll b/test/Transforms/IndVarSimplify/widen-loop-comp.ll
index eb81ceb700b0..b87cd0550192 100644
--- a/test/Transforms/IndVarSimplify/widen-loop-comp.ll
+++ b/test/Transforms/IndVarSimplify/widen-loop-comp.ll
@@ -193,3 +193,163 @@ for.body:
for.end:
ret i32 %sum.0
}
+
+define i32 @test6(i32* %a, i32 %b) {
+; CHECK-LABEL: @test6(
+; CHECK: [[B_SEXT:%[a-z0-9]+]] = sext i32 %b to i64
+; CHECK: for.cond:
+; CHECK: icmp sle i64 %indvars.iv, [[B_SEXT]]
+
+entry:
+ br label %for.cond
+
+for.cond:
+ %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+ %cmp = icmp sle i32 %i.0, %b
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body:
+ %idxprom = zext i32 %i.0 to i64
+ %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
+ %0 = load i32, i32* %arrayidx, align 4
+ %add = add nsw i32 %sum.0, %0
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end:
+ ret i32 %sum.0
+}
+
+define i32 @test7(i32* %a, i32 %b) {
+; CHECK-LABEL: @test7(
+; CHECK: [[B_ZEXT:%[a-z0-9]+]] = zext i32 %b to i64
+; CHECK: [[B_SEXT:%[a-z0-9]+]] = sext i32 %b to i64
+; CHECK: for.cond:
+; CHECK: icmp ule i64 %indvars.iv, [[B_ZEXT]]
+; CHECK: for.body:
+; CHECK: icmp sle i64 %indvars.iv, [[B_SEXT]]
+
+entry:
+ br label %for.cond
+
+for.cond:
+ %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+ %cmp = icmp ule i32 %i.0, %b
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body:
+ %idxprom = sext i32 %i.0 to i64
+ %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
+ %0 = load i32, i32* %arrayidx, align 4
+ %add = add nsw i32 %sum.0, %0
+ %inc = add nsw i32 %i.0, 1
+ %cmp2 = icmp sle i32 %i.0, %b
+ br i1 %cmp2, label %for.cond, label %for.end
+
+for.end:
+ ret i32 %sum.0
+}
+
+define i32 @test8(i32* %a, i32 %b, i32 %init) {
+; CHECK-LABEL: @test8(
+; CHECK: [[INIT_SEXT:%[a-z0-9]+]] = sext i32 %init to i64
+; CHECK: [[B_ZEXT:%[a-z0-9]+]] = zext i32 %b to i64
+; CHECK: for.cond:
+; Note: %indvars.iv is the sign extension of %i.0
+; CHECK: %indvars.iv = phi i64 [ [[INIT_SEXT]], %for.cond.preheader ], [ %indvars.iv.next, %for.body ]
+; CHECK: icmp ule i64 %indvars.iv, [[B_ZEXT]]
+
+entry:
+ %e = icmp sgt i32 %init, 0
+ br i1 %e, label %for.cond, label %leave
+
+for.cond:
+ %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
+ %i.0 = phi i32 [ %init, %entry ], [ %inc, %for.body ]
+ %cmp = icmp ule i32 %i.0, %b
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body:
+ %idxprom = sext i32 %i.0 to i64
+ %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
+ %0 = load i32, i32* %arrayidx, align 4
+ %add = add nsw i32 %sum.0, %0
+ %inc = add nsw i32 %i.0, 1
+ %cmp2 = icmp slt i32 0, %inc
+ br i1 %cmp2, label %for.cond, label %for.end
+
+for.end:
+ ret i32 %sum.0
+
+leave:
+ ret i32 0
+}
+
+define i32 @test9(i32* %a, i32 %b, i32 %init) {
+; CHECK-LABEL: @test9(
+; CHECK: [[INIT_ZEXT:%[a-z0-9]+]] = zext i32 %init to i64
+; CHECK: [[B_SEXT:%[a-z0-9]+]] = sext i32 %b to i64
+; CHECK: for.cond:
+; Note: %indvars.iv is the zero extension of %i.0
+; CHECK: %indvars.iv = phi i64 [ [[INIT_ZEXT]], %for.cond.preheader ], [ %indvars.iv.next, %for.body ]
+; CHECK: icmp slt i64 %indvars.iv, [[B_SEXT]]
+
+entry:
+ %e = icmp sgt i32 %init, 0
+ br i1 %e, label %for.cond, label %leave
+
+for.cond:
+ %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
+ %i.0 = phi i32 [ %init, %entry ], [ %inc, %for.body ]
+ %cmp = icmp slt i32 %i.0, %b
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body:
+ %idxprom = zext i32 %i.0 to i64
+ %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
+ %0 = load i32, i32* %arrayidx, align 4
+ %add = add nsw i32 %sum.0, %0
+ %inc = add nsw i32 %i.0, 1
+ %cmp2 = icmp slt i32 0, %inc
+ br i1 %cmp2, label %for.cond, label %for.end
+
+for.end:
+ ret i32 %sum.0
+
+leave:
+ ret i32 0
+}
+
+declare void @consume.i64(i64)
+declare void @consume.i1(i1)
+
+define i32 @test10(i32 %v) {
+; CHECK-LABEL: @test10(
+ entry:
+; CHECK-NOT: zext
+ br label %loop
+
+ loop:
+; CHECK: loop:
+; CHECK: %indvars.iv = phi i64 [ %indvars.iv.next, %loop ], [ 0, %entry ]
+; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+; CHECK: [[MUL:%[a-z0-9]+]] = mul nsw i64 %indvars.iv, -1
+; CHECK: [[MUL_TRUNC:%[a-z0-9]+]] = trunc i64 [[MUL]] to i32
+; CHECK: [[CMP:%[a-z0-9]+]] = icmp eq i32 [[MUL_TRUNC]], %v
+; CHECK: call void @consume.i1(i1 [[CMP]])
+
+ %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
+ %i.inc = add i32 %i, 1
+ %iv = mul i32 %i, -1
+ %cmp = icmp eq i32 %iv, %v
+ call void @consume.i1(i1 %cmp)
+ %be.cond = icmp slt i32 %i.inc, 11
+ %ext = sext i32 %iv to i64
+ call void @consume.i64(i64 %ext)
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret i32 22
+}
diff --git a/test/Transforms/IndVarSimplify/zext-nuw.ll b/test/Transforms/IndVarSimplify/zext-nuw.ll
new file mode 100644
index 000000000000..13138de6a507
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/zext-nuw.ll
@@ -0,0 +1,49 @@
+; RUN: opt -indvars -S %s | FileCheck %s
+
+%struct.A = type { i8 }
+
+@c = global %struct.A* null
+@d = global i32 4
+
+define void @_Z3fn1v() {
+ %x2 = load i32, i32* @d
+ %x3 = icmp slt i32 %x2, 1
+ %x4 = select i1 %x3, i32 1, i32 %x2
+ %x5 = load %struct.A*, %struct.A** @c
+ %j.sroa.0.0..sroa_idx = getelementptr %struct.A, %struct.A* %x5, i64 0, i32 0
+ %j.sroa.0.0.copyload = load i8, i8* %j.sroa.0.0..sroa_idx
+ br label %.preheader4.lr.ph
+
+.preheader4.lr.ph: ; preds = %0
+ ; CHECK-NOT: add i64 {{.*}}, 4294967296
+ br label %.preheader4
+
+.preheader4: ; preds = %x22, %.preheader4.lr.ph
+ %k.09 = phi i8* [ undef, %.preheader4.lr.ph ], [ %x25, %x22 ]
+ %x8 = icmp ult i32 0, 4
+ br i1 %x8, label %.preheader.lr.ph, label %x22
+
+.preheader.lr.ph: ; preds = %.preheader4
+ br label %.preheader
+
+.preheader: ; preds = %x17, %.preheader.lr.ph
+ %k.17 = phi i8* [ %k.09, %.preheader.lr.ph ], [ %x19, %x17 ]
+ %v.06 = phi i32 [ 0, %.preheader.lr.ph ], [ %x20, %x17 ]
+ br label %x17
+
+x17: ; preds = %.preheader
+ %x18 = sext i8 %j.sroa.0.0.copyload to i64
+ %x19 = getelementptr i8, i8* %k.17, i64 %x18
+ %x20 = add i32 %v.06, 1
+ %x21 = icmp ult i32 %x20, %x4
+ br i1 %x21, label %.preheader, label %._crit_edge.8
+
+._crit_edge.8: ; preds = %x17
+ %split = phi i8* [ %x19, %x17 ]
+ br label %x22
+
+x22: ; preds = %._crit_edge.8, %.preheader4
+ %k.1.lcssa = phi i8* [ %split, %._crit_edge.8 ], [ %k.09, %.preheader4 ]
+ %x25 = getelementptr i8, i8* %k.1.lcssa
+ br label %.preheader4
+}