From 2d8494a03060b3c1cd282b4d5fcafb4e9ba1346e Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Thu, 11 Aug 2011 23:38:09 +0000 Subject: [PATCH] A slew of unit tests for the recent LoopInfo::updateUnloop feature checked in at r137276 and r137341. llvm-svn: 137385 --- llvm/test/Transforms/LoopUnroll/unloop.ll | 429 ++++++++++++++++++++++ 1 file changed, 429 insertions(+) create mode 100644 llvm/test/Transforms/LoopUnroll/unloop.ll diff --git a/llvm/test/Transforms/LoopUnroll/unloop.ll b/llvm/test/Transforms/LoopUnroll/unloop.ll new file mode 100644 index 000000000000..4110809dfdc6 --- /dev/null +++ b/llvm/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 +}