diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
| commit | dd58ef019b700900793a1eb48b52123db01b654e (patch) | |
| tree | fcfbb4df56a744f4ddc6122c50521dd3f1c5e196 /test/Transforms/IndVarSimplify | |
| parent | 2fe5752e3a7c345cdb59e869278d36af33c13fa4 (diff) | |
Notes
Diffstat (limited to 'test/Transforms/IndVarSimplify')
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 +} |
