diff options
Diffstat (limited to 'test/Transforms/LoopUnroll')
-rw-r--r-- | test/Transforms/LoopUnroll/2011-08-09-IVSimplify.ll | 2 | ||||
-rw-r--r-- | test/Transforms/LoopUnroll/2012-04-09-unroll-indirectbr.ll | 40 | ||||
-rw-r--r-- | test/Transforms/LoopUnroll/dg.exp | 3 | ||||
-rw-r--r-- | test/Transforms/LoopUnroll/lit.local.cfg | 1 | ||||
-rw-r--r-- | test/Transforms/LoopUnroll/partial-unroll-optsize.ll | 35 | ||||
-rw-r--r-- | test/Transforms/LoopUnroll/pr11361.ll | 42 | ||||
-rw-r--r-- | test/Transforms/LoopUnroll/runtime-loop.ll | 109 | ||||
-rw-r--r-- | test/Transforms/LoopUnroll/runtime-loop1.ll | 30 | ||||
-rw-r--r-- | test/Transforms/LoopUnroll/runtime-loop2.ll | 31 | ||||
-rw-r--r-- | test/Transforms/LoopUnroll/runtime-loop3.ll | 44 | ||||
-rw-r--r-- | test/Transforms/LoopUnroll/unloop.ll | 41 |
11 files changed, 374 insertions, 4 deletions
diff --git a/test/Transforms/LoopUnroll/2011-08-09-IVSimplify.ll b/test/Transforms/LoopUnroll/2011-08-09-IVSimplify.ll index 59551d5..a43a4ff 100644 --- a/test/Transforms/LoopUnroll/2011-08-09-IVSimplify.ll +++ b/test/Transforms/LoopUnroll/2011-08-09-IVSimplify.ll @@ -1,4 +1,4 @@ -; RUN: opt -S < %s -loop-unroll -unroll-count=4 -enable-iv-rewrite=false | FileCheck %s +; RUN: opt -S < %s -loop-unroll -unroll-count=4 | FileCheck %s ; ; Test induction variable simplify after loop unrolling. It should ; expose nice opportunities for GVN. diff --git a/test/Transforms/LoopUnroll/2012-04-09-unroll-indirectbr.ll b/test/Transforms/LoopUnroll/2012-04-09-unroll-indirectbr.ll new file mode 100644 index 0000000..8946a23 --- /dev/null +++ b/test/Transforms/LoopUnroll/2012-04-09-unroll-indirectbr.ll @@ -0,0 +1,40 @@ +; RUN: opt < %s -S -loop-unroll -simplifycfg | FileCheck %s +; PR12513: Loop unrolling breaks with indirect branches. +; If loop unrolling attempts to transform this loop, it replaces the +; indirectbr successors. SimplifyCFG then considers them to be unreachable. +declare void @subtract() nounwind uwtable + +; CHECK-NOT: unreachable +define i32 @main(i32 %argc, i8** nocapture %argv) nounwind uwtable { +entry: + %vals19 = alloca [5 x i32], align 16 + %x20 = alloca i32, align 4 + store i32 135, i32* %x20, align 4 + br label %for.body + +for.body: ; preds = ; %call2_termjoin, %call3_termjoin + %indvars.iv = phi i64 [ 0, %entry ], [ %joinphi15.in.in, %call2_termjoin ] + %a6 = call coldcc i8* @funca(i8* blockaddress(@main, %for.body_code), i8* +blockaddress(@main, %for.body_codeprime)) nounwind + indirectbr i8* %a6, [label %for.body_code, label %for.body_codeprime] + +for.body_code: ; preds = %for.body + call void @subtract() + br label %call2_termjoin + +call2_termjoin: ; preds = %for.body_codeprime, %for.body_code + %joinphi15.in.in = add i64 %indvars.iv, 1 + %exitcond = icmp eq i64 %joinphi15.in.in, 5 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %call2_termjoin + ret i32 0 + +for.body_codeprime: ; preds = %for.body + call void @subtract_v2(i64 %indvars.iv) + br label %call2_termjoin +} + +declare coldcc i8* @funca(i8*, i8*) readonly + +declare void @subtract_v2(i64) nounwind uwtable diff --git a/test/Transforms/LoopUnroll/dg.exp b/test/Transforms/LoopUnroll/dg.exp deleted file mode 100644 index f200589..0000000 --- a/test/Transforms/LoopUnroll/dg.exp +++ /dev/null @@ -1,3 +0,0 @@ -load_lib llvm.exp - -RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] diff --git a/test/Transforms/LoopUnroll/lit.local.cfg b/test/Transforms/LoopUnroll/lit.local.cfg new file mode 100644 index 0000000..19eebc0 --- /dev/null +++ b/test/Transforms/LoopUnroll/lit.local.cfg @@ -0,0 +1 @@ +config.suffixes = ['.ll', '.c', '.cpp'] diff --git a/test/Transforms/LoopUnroll/partial-unroll-optsize.ll b/test/Transforms/LoopUnroll/partial-unroll-optsize.ll new file mode 100644 index 0000000..3179d55e --- /dev/null +++ b/test/Transforms/LoopUnroll/partial-unroll-optsize.ll @@ -0,0 +1,35 @@ +; RUN: opt < %s -S -loop-unroll -unroll-allow-partial | FileCheck %s +; Loop size = 3, when the function has the optsize attribute, the +; OptSizeUnrollThreshold, i.e. 50, is used, hence the loop should be unrolled +; by 16 times because 3 * 16 < 50. +define void @unroll_opt_for_size() nounwind optsize { +entry: + br label %loop + +loop: + %iv = phi i32 [ 0, %entry ], [ %inc, %loop ] + %inc = add i32 %iv, 1 + %exitcnd = icmp uge i32 %inc, 1024 + br i1 %exitcnd, label %exit, label %loop + +exit: + ret void +} + +; CHECK: add +; CHECK-NEXT: add +; CHECK-NEXT: add +; CHECK-NEXT: add +; CHECK-NEXT: add +; CHECK-NEXT: add +; CHECK-NEXT: add +; CHECK-NEXT: add +; CHECK-NEXT: add +; CHECK-NEXT: add +; CHECK-NEXT: add +; CHECK-NEXT: add +; CHECK-NEXT: add +; CHECK-NEXT: add +; CHECK-NEXT: add +; CHECK-NEXT: add +; CHECK-NEXT: icmp diff --git a/test/Transforms/LoopUnroll/pr11361.ll b/test/Transforms/LoopUnroll/pr11361.ll new file mode 100644 index 0000000..7ce7f5f --- /dev/null +++ b/test/Transforms/LoopUnroll/pr11361.ll @@ -0,0 +1,42 @@ +; RUN: opt -loop-unroll -disable-output +; PR11361 + +; This tests for an iterator invalidation issue. + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @func_1() nounwind uwtable { +entry: + br label %for.cond8.preheader + +for.cond8.preheader: ; preds = %for.inc15, %entry + %l_1264.04 = phi i32 [ 0, %entry ], [ %add.i, %for.inc15 ] + %l_1330.0.03 = phi i80 [ undef, %entry ], [ %ins.lcssa, %for.inc15 ] + br label %for.body9 + +for.body9: ; preds = %for.body9, %for.cond8.preheader + %l_1330.0.12 = phi i80 [ %l_1330.0.03, %for.cond8.preheader ], [ %ins, %for.body9 ] + %storemerge1 = phi i32 [ 7, %for.cond8.preheader ], [ %sub, %for.body9 ] + %tmp = lshr i80 %l_1330.0.12, 8 + %tmp1 = trunc i80 %tmp to i8 + %inc12 = add i8 %tmp1, 1 + %tmp2 = zext i8 %inc12 to i80 + %tmp3 = shl nuw nsw i80 %tmp2, 8 + %mask = and i80 %l_1330.0.12, -65281 + %ins = or i80 %tmp3, %mask + %sub = add nsw i32 %storemerge1, -1 + %tobool = icmp eq i32 %sub, 0 + br i1 %tobool, label %for.inc15, label %for.body9 + +for.inc15: ; preds = %for.body9 + %ins.lcssa = phi i80 [ %ins, %for.body9 ] + %sext = shl i32 %l_1264.04, 24 + %conv.i = ashr exact i32 %sext, 24 + %add.i = add nsw i32 %conv.i, 1 + %cmp = icmp slt i32 %add.i, 3 + br i1 %cmp, label %for.cond8.preheader, label %for.end16 + +for.end16: ; preds = %for.inc15 + ret void +} diff --git a/test/Transforms/LoopUnroll/runtime-loop.ll b/test/Transforms/LoopUnroll/runtime-loop.ll new file mode 100644 index 0000000..d8bbea9 --- /dev/null +++ b/test/Transforms/LoopUnroll/runtime-loop.ll @@ -0,0 +1,109 @@ +; RUN: opt < %s -S -loop-unroll -unroll-runtime=true | FileCheck %s + +; Tests for unrolling loops with run-time trip counts + +; CHECK: unr.cmp{{.*}}: +; CHECK: for.body.unr{{.*}}: +; CHECK: for.body: +; CHECK: br i1 %exitcond.7, label %for.end.loopexit{{.*}}, label %for.body + +define i32 @test(i32* nocapture %a, i32 %n) nounwind uwtable readonly { +entry: + %cmp1 = icmp eq i32 %n, 0 + br i1 %cmp1, label %for.end, label %for.body + +for.body: ; preds = %for.body, %entry + %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] + %sum.02 = phi i32 [ %add, %for.body ], [ 0, %entry ] + %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv + %0 = load i32* %arrayidx, align 4 + %add = add nsw i32 %0, %sum.02 + %indvars.iv.next = add i64 %indvars.iv, 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp eq i32 %lftr.wideiv, %n + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + %sum.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.body ] + ret i32 %sum.0.lcssa +} + + +; Still try to completely unroll loops with compile-time trip counts +; even if the -unroll-runtime is specified + +; CHECK: for.body: +; CHECK-NOT: for.body.unr: + +define i32 @test1(i32* nocapture %a) nounwind uwtable readonly { +entry: + br label %for.body + +for.body: ; preds = %for.body, %entry + %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] + %sum.01 = phi i32 [ 0, %entry ], [ %add, %for.body ] + %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv + %0 = load i32* %arrayidx, align 4 + %add = add nsw i32 %0, %sum.01 + %indvars.iv.next = add i64 %indvars.iv, 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp eq i32 %lftr.wideiv, 5 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body + ret i32 %add +} + +; This is test 2007-05-09-UnknownTripCount.ll which can be unrolled now +; if the -unroll-runtime option is turned on + +; CHECK: bb72.2: + +define void @foo(i32 %trips) { +entry: + br label %cond_true.outer + +cond_true.outer: + %indvar1.ph = phi i32 [ 0, %entry ], [ %indvar.next2, %bb72 ] + br label %bb72 + +bb72: + %indvar.next2 = add i32 %indvar1.ph, 1 + %exitcond3 = icmp eq i32 %indvar.next2, %trips + br i1 %exitcond3, label %cond_true138, label %cond_true.outer + +cond_true138: + ret void +} + + +; Test run-time unrolling for a loop that counts down by -2. + +; CHECK: for.body.unr: +; CHECK: br i1 %cmp.7, label %for.cond.for.end_crit_edge{{.*}}, label %for.body + +define zeroext i16 @down(i16* nocapture %p, i32 %len) nounwind uwtable readonly { +entry: + %cmp2 = icmp eq i32 %len, 0 + br i1 %cmp2, label %for.end, label %for.body + +for.body: ; preds = %for.body, %entry + %p.addr.05 = phi i16* [ %incdec.ptr, %for.body ], [ %p, %entry ] + %len.addr.04 = phi i32 [ %sub, %for.body ], [ %len, %entry ] + %res.03 = phi i32 [ %add, %for.body ], [ 0, %entry ] + %incdec.ptr = getelementptr inbounds i16* %p.addr.05, i64 1 + %0 = load i16* %p.addr.05, align 2 + %conv = zext i16 %0 to i32 + %add = add i32 %conv, %res.03 + %sub = add nsw i32 %len.addr.04, -2 + %cmp = icmp eq i32 %sub, 0 + br i1 %cmp, label %for.cond.for.end_crit_edge, label %for.body + +for.cond.for.end_crit_edge: ; preds = %for.body + %phitmp = trunc i32 %add to i16 + br label %for.end + +for.end: ; preds = %for.cond.for.end_crit_edge, %entry + %res.0.lcssa = phi i16 [ %phitmp, %for.cond.for.end_crit_edge ], [ 0, %entry ] + ret i16 %res.0.lcssa +} diff --git a/test/Transforms/LoopUnroll/runtime-loop1.ll b/test/Transforms/LoopUnroll/runtime-loop1.ll new file mode 100644 index 0000000..ad99b8c --- /dev/null +++ b/test/Transforms/LoopUnroll/runtime-loop1.ll @@ -0,0 +1,30 @@ +; RUN: opt < %s -S -loop-unroll -unroll-runtime -unroll-count=4 | FileCheck %s + +; This tests that setting the unroll count works + +; CHECK: unr.cmp: +; CHECK: for.body.unr: +; CHECK: for.body: +; CHECK: br i1 %exitcond.3, label %for.end.loopexit{{.*}}, label %for.body +; CHECK-NOT: br i1 %exitcond.4, label %for.end.loopexit{{.*}}, label %for.body + +define i32 @test(i32* nocapture %a, i32 %n) nounwind uwtable readonly { +entry: + %cmp1 = icmp eq i32 %n, 0 + br i1 %cmp1, label %for.end, label %for.body + +for.body: ; preds = %for.body, %entry + %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] + %sum.02 = phi i32 [ %add, %for.body ], [ 0, %entry ] + %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv + %0 = load i32* %arrayidx, align 4 + %add = add nsw i32 %0, %sum.02 + %indvars.iv.next = add i64 %indvars.iv, 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp eq i32 %lftr.wideiv, %n + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + %sum.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.body ] + ret i32 %sum.0.lcssa +} diff --git a/test/Transforms/LoopUnroll/runtime-loop2.ll b/test/Transforms/LoopUnroll/runtime-loop2.ll new file mode 100644 index 0000000..cbc7af5 --- /dev/null +++ b/test/Transforms/LoopUnroll/runtime-loop2.ll @@ -0,0 +1,31 @@ +; RUN: opt < %s -S -loop-unroll -unroll-threshold=50 -unroll-runtime -unroll-count=8 | FileCheck %s + +; Choose a smaller, power-of-two, unroll count if the loop is too large. +; This test makes sure we're not unrolling 'odd' counts + +; CHECK: unr.cmp: +; CHECK: for.body.unr: +; CHECK: for.body: +; CHECK: br i1 %exitcond.3, label %for.end.loopexit{{.*}}, label %for.body +; CHECK-NOT: br i1 %exitcond.4, label %for.end.loopexit{{.*}}, label %for.body + +define i32 @test(i32* nocapture %a, i32 %n) nounwind uwtable readonly { +entry: + %cmp1 = icmp eq i32 %n, 0 + br i1 %cmp1, label %for.end, label %for.body + +for.body: ; preds = %for.body, %entry + %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] + %sum.02 = phi i32 [ %add, %for.body ], [ 0, %entry ] + %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv + %0 = load i32* %arrayidx, align 4 + %add = add nsw i32 %0, %sum.02 + %indvars.iv.next = add i64 %indvars.iv, 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp eq i32 %lftr.wideiv, %n + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + %sum.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.body ] + ret i32 %sum.0.lcssa +} diff --git a/test/Transforms/LoopUnroll/runtime-loop3.ll b/test/Transforms/LoopUnroll/runtime-loop3.ll new file mode 100644 index 0000000..55cf223 --- /dev/null +++ b/test/Transforms/LoopUnroll/runtime-loop3.ll @@ -0,0 +1,44 @@ +; RUN: opt < %s -disable-output -stats -loop-unroll -unroll-runtime -unroll-threshold=400 -info-output-file - | FileCheck %s --check-prefix=STATS + +; Test that nested loops can be unrolled. We need to increase threshold to do it + +; STATS: 2 loop-unroll - Number of loops unrolled (completely or otherwise) + +define i32 @nested(i32* nocapture %a, i32 %n, i32 %m) nounwind uwtable readonly { +entry: + %cmp11 = icmp sgt i32 %n, 0 + br i1 %cmp11, label %for.cond1.preheader.lr.ph, label %for.end7 + +for.cond1.preheader.lr.ph: ; preds = %entry + %cmp28 = icmp sgt i32 %m, 0 + br label %for.cond1.preheader + +for.cond1.preheader: ; preds = %for.inc5, %for.cond1.preheader.lr.ph + %indvars.iv16 = phi i64 [ 0, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next17, %for.inc5 ] + %sum.012 = phi i32 [ 0, %for.cond1.preheader.lr.ph ], [ %sum.1.lcssa, %for.inc5 ] + br i1 %cmp28, label %for.body3, label %for.inc5 + +for.body3: ; preds = %for.cond1.preheader, %for.body3 + %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3 ], [ 0, %for.cond1.preheader ] + %sum.19 = phi i32 [ %add4, %for.body3 ], [ %sum.012, %for.cond1.preheader ] + %0 = add nsw i64 %indvars.iv, %indvars.iv16 + %arrayidx = getelementptr inbounds i32* %a, i64 %0 + %1 = load i32* %arrayidx, align 4 + %add4 = add nsw i32 %1, %sum.19 + %indvars.iv.next = add i64 %indvars.iv, 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp eq i32 %lftr.wideiv, %m + br i1 %exitcond, label %for.inc5, label %for.body3 + +for.inc5: ; preds = %for.body3, %for.cond1.preheader + %sum.1.lcssa = phi i32 [ %sum.012, %for.cond1.preheader ], [ %add4, %for.body3 ] + %indvars.iv.next17 = add i64 %indvars.iv16, 1 + %lftr.wideiv18 = trunc i64 %indvars.iv.next17 to i32 + %exitcond19 = icmp eq i32 %lftr.wideiv18, %n + br i1 %exitcond19, label %for.end7, label %for.cond1.preheader + +for.end7: ; preds = %for.inc5, %entry + %sum.0.lcssa = phi i32 [ 0, %entry ], [ %sum.1.lcssa, %for.inc5 ] + ret i32 %sum.0.lcssa +} + diff --git a/test/Transforms/LoopUnroll/unloop.ll b/test/Transforms/LoopUnroll/unloop.ll index 217c8ce..5a9cacd 100644 --- a/test/Transforms/LoopUnroll/unloop.ll +++ b/test/Transforms/LoopUnroll/unloop.ll @@ -427,3 +427,44 @@ if.end2413: ; preds = %defchar return: ; preds = %sw.bb304 ret void } + +; PR11335: the most deeply nested block should be removed from the outer loop. +; CHECK: @removeSubloopBlocks2 +; CHECK: for.cond3: +; CHECK-NOT: br +; CHECK: ret void +define void @removeSubloopBlocks2() nounwind { +entry: + %tobool.i = icmp ne i32 undef, 0 + br label %lbl_616 + +lbl_616.loopexit: ; preds = %for.cond + br label %lbl_616 + +lbl_616: ; preds = %lbl_616.loopexit, %entry + br label %for.cond + +for.cond: ; preds = %for.cond3, %lbl_616 + br i1 false, label %for.cond1.preheader, label %lbl_616.loopexit + +for.cond1.preheader: ; preds = %for.cond + br label %for.cond1 + +for.cond1.loopexit: ; preds = %for.cond.i + br label %for.cond1 + +for.cond1: ; preds = %for.cond1.loopexit, %for.cond1.preheader + br i1 false, label %for.body2, label %for.cond3 + +for.body2: ; preds = %for.cond1 + br label %for.cond.i + +for.cond.i: ; preds = %for.cond.i, %for.body2 + br i1 %tobool.i, label %for.cond.i, label %for.cond1.loopexit + +for.cond3: ; preds = %for.cond1 + br i1 false, label %for.cond, label %if.end + +if.end: ; preds = %for.cond3 + ret void +} |