forked from OSchip/llvm-project
A slew of unit tests for the recent LoopInfo::updateUnloop feature
checked in at r137276 and r137341. llvm-svn: 137385
This commit is contained in:
parent
2b6860f0a1
commit
2d8494a030
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue