summaryrefslogtreecommitdiffstats
path: root/test/Transforms
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2011-08-11 23:38:09 +0000
committerAndrew Trick <atrick@apple.com>2011-08-11 23:38:09 +0000
commit30039de2e9aeffdfe4ee784ff44ebb3648e69f94 (patch)
tree22e9bb004cb69b71586a55382fa563de63d34a37 /test/Transforms
parentb1831c66403315a1d84593b7c198ddbd43a574cf (diff)
downloadexternal_llvm-30039de2e9aeffdfe4ee784ff44ebb3648e69f94.zip
external_llvm-30039de2e9aeffdfe4ee784ff44ebb3648e69f94.tar.gz
external_llvm-30039de2e9aeffdfe4ee784ff44ebb3648e69f94.tar.bz2
A slew of unit tests for the recent LoopInfo::updateUnloop feature
checked in at r137276 and r137341. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137385 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms')
-rw-r--r--test/Transforms/LoopUnroll/unloop.ll429
1 files changed, 429 insertions, 0 deletions
diff --git a/test/Transforms/LoopUnroll/unloop.ll b/test/Transforms/LoopUnroll/unloop.ll
new file mode 100644
index 0000000..4110809
--- /dev/null
+++ b/test/Transforms/LoopUnroll/unloop.ll
@@ -0,0 +1,429 @@
+; RUN: opt < %s -S -loop-unroll -verify-loop-info -unroll-scev | FileCheck %s
+;
+; Unit tests for LoopInfo::updateUnloop.
+
+declare i1 @check() nounwind
+
+; Ensure that tail->inner is removed and rely on verify-loopinfo to
+; check soundness.
+;
+; CHECK: @skiplevelexit
+; CHECK: tail:
+; CHECK-NOT: br
+; CHECK: ret void
+define void @skiplevelexit() nounwind {
+entry:
+ br label %outer
+
+outer:
+ br label %inner
+
+inner:
+ %iv = phi i32 [ 0, %outer ], [ %inc, %tail ]
+ %inc = add i32 %iv, 1
+ %wbucond = call zeroext i1 @check()
+ br i1 %wbucond, label %outer.backedge, label %tail
+
+tail:
+ br i1 false, label %inner, label %exit
+
+outer.backedge:
+ br label %outer
+
+exit:
+ ret void
+}
+
+; Remove the middle loop of a triply nested loop tree.
+; Ensure that only the middle loop is removed and rely on verify-loopinfo to
+; check soundness.
+;
+; CHECK: @unloopNested
+; Outer loop control.
+; CHECK: while.body:
+; CHECK: br i1 %cmp3, label %if.then, label %if.end
+; Inner loop control.
+; CHECK: while.end14.i:
+; CHECK: br i1 %call15.i, label %if.end.i, label %exit
+; Middle loop control should no longer reach %while.cond.
+; Now it is the outer loop backedge.
+; CHECK: exit:
+; CHECK: br label %while.cond.outer
+define void @unloopNested() {
+entry:
+ br label %while.cond.outer
+
+while.cond.outer:
+ br label %while.cond
+
+while.cond:
+ %cmp = call zeroext i1 @check()
+ br i1 %cmp, label %while.body, label %while.end
+
+while.body:
+ %cmp3 = call zeroext i1 @check()
+ br i1 %cmp3, label %if.then, label %if.end
+
+if.then:
+ br label %return
+
+if.end:
+ %cmp.i48 = call zeroext i1 @check()
+ br i1 %cmp.i48, label %if.then.i, label %if.else20.i
+
+if.then.i:
+ %cmp8.i = call zeroext i1 @check()
+ br i1 %cmp8.i, label %merge, label %if.else.i
+
+if.else.i:
+ br label %merge
+
+if.else20.i:
+ %cmp25.i = call zeroext i1 @check()
+ br i1 %cmp25.i, label %merge, label %if.else28.i
+
+if.else28.i:
+ br label %merge
+
+merge:
+ br label %while.cond2.i
+
+while.cond2.i:
+ %cmp.i = call zeroext i1 @check()
+ br i1 %cmp.i, label %while.cond2.backedge.i, label %while.end.i
+
+while.cond2.backedge.i:
+ br label %while.cond2.i
+
+while.end.i:
+ %cmp1114.i = call zeroext i1 @check()
+ br i1 %cmp1114.i, label %while.body12.lr.ph.i, label %while.end14.i
+
+while.body12.lr.ph.i:
+ br label %while.end14.i
+
+while.end14.i:
+ %call15.i = call zeroext i1 @check()
+ br i1 %call15.i, label %if.end.i, label %exit
+
+if.end.i:
+ br label %while.cond2.backedge.i
+
+exit:
+ br i1 false, label %while.cond, label %if.else
+
+if.else:
+ br label %while.cond.outer
+
+while.end:
+ br label %return
+
+return:
+ ret void
+}
+
+; Remove the middle loop of a deeply nested loop tree.
+; Ensure that only the middle loop is removed and rely on verify-loopinfo to
+; check soundness.
+;
+; CHECK: @unloopDeepNested
+; Inner-inner loop control.
+; CHECK: while.cond.us.i:
+; CHECK: br i1 %cmp.us.i, label %next_data.exit, label %while.body.us.i
+; CHECK: if.then.us.i:
+; CHECK: br label %while.cond.us.i
+; Inner loop tail.
+; CHECK: if.else.i:
+; CHECK: br label %while.cond.outer.i
+; Middle loop control (removed).
+; CHECK: valid_data.exit:
+; CHECK-NOT: br
+; CHECK: %cmp = call zeroext i1 @check()
+; Outer loop control.
+; CHECK: copy_data.exit:
+; CHECK: br i1 %cmp38, label %if.then39, label %while.cond.outer
+; Outer-outer loop tail.
+; CHECK: while.cond.outer.outer.backedge:
+; CHECK: br label %while.cond.outer.outer
+define void @unloopDeepNested() nounwind {
+for.cond8.preheader.i:
+ %cmp113.i = call zeroext i1 @check()
+ br i1 %cmp113.i, label %make_data.exit, label %for.body13.lr.ph.i
+
+for.body13.lr.ph.i:
+ br label %make_data.exit
+
+make_data.exit:
+ br label %while.cond.outer.outer
+
+while.cond.outer.outer:
+ br label %while.cond.outer
+
+while.cond.outer:
+ br label %while.cond
+
+while.cond:
+ br label %while.cond.outer.i
+
+while.cond.outer.i:
+ %tmp192.ph.i = call zeroext i1 @check()
+ br i1 %tmp192.ph.i, label %while.cond.outer.split.us.i, label %while.body.loopexit
+
+while.cond.outer.split.us.i:
+ br label %while.cond.us.i
+
+while.cond.us.i:
+ %cmp.us.i = call zeroext i1 @check()
+ br i1 %cmp.us.i, label %next_data.exit, label %while.body.us.i
+
+while.body.us.i:
+ %cmp7.us.i = call zeroext i1 @check()
+ br i1 %cmp7.us.i, label %if.then.us.i, label %if.else.i
+
+if.then.us.i:
+ br label %while.cond.us.i
+
+if.else.i:
+ br label %while.cond.outer.i
+
+next_data.exit:
+ %tmp192.ph.i.lcssa28 = call zeroext i1 @check()
+ br i1 %tmp192.ph.i.lcssa28, label %while.end, label %while.body
+
+while.body.loopexit:
+ br label %while.body
+
+while.body:
+ br label %while.cond.i
+
+while.cond.i:
+ %cmp.i = call zeroext i1 @check()
+ br i1 %cmp.i, label %valid_data.exit, label %while.body.i
+
+while.body.i:
+ %cmp7.i = call zeroext i1 @check()
+ br i1 %cmp7.i, label %valid_data.exit, label %if.end.i
+
+if.end.i:
+ br label %while.cond.i
+
+valid_data.exit:
+ br i1 true, label %if.then, label %while.cond
+
+if.then:
+ %cmp = call zeroext i1 @check()
+ br i1 %cmp, label %if.then12, label %if.end
+
+if.then12:
+ br label %if.end
+
+if.end:
+ %tobool3.i = call zeroext i1 @check()
+ br i1 %tobool3.i, label %copy_data.exit, label %while.body.lr.ph.i
+
+while.body.lr.ph.i:
+ br label %copy_data.exit
+
+copy_data.exit:
+ %cmp38 = call zeroext i1 @check()
+ br i1 %cmp38, label %if.then39, label %while.cond.outer
+
+if.then39:
+ %cmp5.i = call zeroext i1 @check()
+ br i1 %cmp5.i, label %while.cond.outer.outer.backedge, label %for.cond8.preheader.i8.thread
+
+for.cond8.preheader.i8.thread:
+ br label %while.cond.outer.outer.backedge
+
+while.cond.outer.outer.backedge:
+ br label %while.cond.outer.outer
+
+while.end:
+ ret void
+}
+
+; Remove a nested loop with irreducible control flow.
+; Ensure that only the middle loop is removed and rely on verify-loopinfo to
+; check soundness.
+;
+; CHECK: @unloopIrreducible
+; Irreducible loop.
+; CHECK: for.inc117:
+; CHECK: br label %for.cond103t
+; Nested loop (removed).
+; CHECK: for.inc159:
+; CHECK: br label %for.inc163
+define void @unloopIrreducible() nounwind {
+
+entry:
+ br label %for.body
+
+for.body:
+ %cmp2113 = call zeroext i1 @check()
+ br i1 %cmp2113, label %for.body22.lr.ph, label %for.inc163
+
+for.body22.lr.ph:
+ br label %for.body22
+
+for.body22:
+ br label %for.body33
+
+for.body33:
+ br label %for.end
+
+for.end:
+ %cmp424 = call zeroext i1 @check()
+ br i1 %cmp424, label %for.body43.lr.ph, label %for.end93
+
+for.body43.lr.ph:
+ br label %for.end93
+
+for.end93:
+ %cmp96 = call zeroext i1 @check()
+ br i1 %cmp96, label %if.then97, label %for.cond103
+
+if.then97:
+ br label %for.cond103t
+
+for.cond103t:
+ br label %for.cond103
+
+for.cond103:
+ %cmp105 = call zeroext i1 @check()
+ br i1 %cmp105, label %for.body106, label %for.end120
+
+for.body106:
+ %cmp108 = call zeroext i1 @check()
+ br i1 %cmp108, label %if.then109, label %for.inc117
+
+if.then109:
+ br label %for.inc117
+
+for.inc117:
+ br label %for.cond103t
+
+for.end120:
+ br label %for.inc159
+
+for.inc159:
+ br i1 false, label %for.body22, label %for.cond15.for.inc163_crit_edge
+
+for.cond15.for.inc163_crit_edge:
+ br label %for.inc163
+
+for.inc163:
+ %cmp12 = call zeroext i1 @check()
+ br i1 %cmp12, label %for.body, label %for.end166
+
+for.end166:
+ ret void
+
+}
+
+; Remove a loop whose exit branches into a sibling loop.
+; Ensure that only the loop is removed and rely on verify-loopinfo to
+; check soundness.
+;
+; CHECK: @unloopCriticalEdge
+; CHECK: while.cond.outer.i.loopexit.split:
+; CHECK: br label %while.body
+; CHECK: while.body:
+; CHECK: br label %for.end78
+define void @unloopCriticalEdge() nounwind {
+entry:
+ br label %for.cond31
+
+for.cond31:
+ br i1 undef, label %for.body35, label %for.end94
+
+for.body35:
+ br label %while.cond.i.preheader
+
+while.cond.i.preheader:
+ br i1 undef, label %while.cond.i.preheader.split, label %while.cond.outer.i.loopexit.split
+
+while.cond.i.preheader.split:
+ br label %while.cond.i
+
+while.cond.i:
+ br i1 true, label %while.cond.i, label %while.cond.outer.i.loopexit
+
+while.cond.outer.i.loopexit:
+ br label %while.cond.outer.i.loopexit.split
+
+while.cond.outer.i.loopexit.split:
+ br i1 false, label %while.cond.i.preheader, label %Func2.exit
+
+Func2.exit:
+ br label %while.body
+
+while.body:
+ br i1 false, label %while.body, label %while.end
+
+while.end:
+ br label %for.end78
+
+for.end78:
+ br i1 undef, label %Proc2.exit, label %for.cond.i.preheader
+
+for.cond.i.preheader:
+ br label %for.cond.i
+
+for.cond.i:
+ br label %for.cond.i
+
+Proc2.exit:
+ br label %for.cond31
+
+for.end94:
+ ret void
+}
+
+; Test UnloopUpdater::removeBlocksFromAncestors.
+;
+; Check that the loop backedge is removed from the middle loop 1699,
+; but not the inner loop 1676.
+; CHECK: while.body1694:
+; CHECK: br label %while.cond1676
+; CHECK: while.end1699:
+; CHECK: br label %sw.default1711
+define void @removeSubloopBlocks() nounwind {
+entry:
+ br label %tryagain.outer
+
+tryagain.outer: ; preds = %sw.bb304, %entry
+ br label %tryagain
+
+tryagain: ; preds = %while.end1699, %tryagain.outer
+ br i1 undef, label %sw.bb1669, label %sw.bb304
+
+sw.bb304: ; preds = %tryagain
+ br i1 undef, label %return, label %tryagain.outer
+
+sw.bb1669: ; preds = %tryagain
+ br i1 undef, label %sw.default1711, label %while.cond1676
+
+while.cond1676: ; preds = %while.body1694, %sw.bb1669
+ br i1 undef, label %while.end1699, label %while.body1694
+
+while.body1694: ; preds = %while.cond1676
+ br label %while.cond1676
+
+while.end1699: ; preds = %while.cond1676
+ br i1 false, label %tryagain, label %sw.default1711
+
+sw.default1711: ; preds = %while.end1699, %sw.bb1669, %tryagain
+ br label %defchar
+
+defchar: ; preds = %sw.default1711, %sw.bb376
+ br i1 undef, label %if.end2413, label %if.then2368
+
+if.then2368: ; preds = %defchar
+ unreachable
+
+if.end2413: ; preds = %defchar
+ unreachable
+
+return: ; preds = %sw.bb304
+ ret void
+}