llvm/test/Transforms/Inline/inline_cleanup.ll
Chandler Carruth 919b2376dc [PM] Turn on the new PM's inliner in addition to the current one for
most of the inliner test cases.

The inliner involves a bunch of interesting code and tends to be where
most of the issues I've seen experimenting with the new PM lie. All of
these test cases pass, but I'd like to keep some more thorough coverage
here so doing a fairly blanket enabling.

There are a handful of interesting tests I've not enabled yet because
they're focused on the always inliner, or on functionality that doesn't
(yet) exist in the inliner.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290592 91177308-0d34-0410-b5e6-96231b3b80d8
2016-12-27 07:18:43 +00:00

215 lines
4.7 KiB
LLVM

; Test that the inliner doesn't leave around dead allocas, and that it folds
; uncond branches away after it is done specializing.
; RUN: opt < %s -inline -S | FileCheck %s
; RUN: opt < %s -passes='cgscc(inline)' -S | FileCheck %s
@A = weak global i32 0 ; <i32*> [#uses=1]
@B = weak global i32 0 ; <i32*> [#uses=1]
@C = weak global i32 0 ; <i32*> [#uses=1]
define internal fastcc void @foo(i32 %X) {
entry:
%ALL = alloca i32, align 4 ; <i32*> [#uses=1]
%tmp1 = and i32 %X, 1 ; <i32> [#uses=1]
%tmp1.upgrd.1 = icmp eq i32 %tmp1, 0 ; <i1> [#uses=1]
br i1 %tmp1.upgrd.1, label %cond_next, label %cond_true
cond_true: ; preds = %entry
store i32 1, i32* @A
br label %cond_next
cond_next: ; preds = %cond_true, %entry
%tmp4 = and i32 %X, 2 ; <i32> [#uses=1]
%tmp4.upgrd.2 = icmp eq i32 %tmp4, 0 ; <i1> [#uses=1]
br i1 %tmp4.upgrd.2, label %cond_next7, label %cond_true5
cond_true5: ; preds = %cond_next
store i32 1, i32* @B
br label %cond_next7
cond_next7: ; preds = %cond_true5, %cond_next
%tmp10 = and i32 %X, 4 ; <i32> [#uses=1]
%tmp10.upgrd.3 = icmp eq i32 %tmp10, 0 ; <i1> [#uses=1]
br i1 %tmp10.upgrd.3, label %cond_next13, label %cond_true11
cond_true11: ; preds = %cond_next7
store i32 1, i32* @C
br label %cond_next13
cond_next13: ; preds = %cond_true11, %cond_next7
%tmp16 = and i32 %X, 8 ; <i32> [#uses=1]
%tmp16.upgrd.4 = icmp eq i32 %tmp16, 0 ; <i1> [#uses=1]
br i1 %tmp16.upgrd.4, label %UnifiedReturnBlock, label %cond_true17
cond_true17: ; preds = %cond_next13
call void @ext( i32* %ALL )
ret void
UnifiedReturnBlock: ; preds = %cond_next13
ret void
}
declare void @ext(i32*)
define void @test() {
; CHECK-LABEL: @test(
; CHECK-NOT: ret
;
; FIXME: This should be a CHECK-NOT, but currently we have a bug that causes us
; to not nuke unused allocas.
; CHECK: alloca
; CHECK-NOT: ret
;
; No branches should survive the inliner's cleanup.
; CHECK-NOT: br
; CHECK: ret void
entry:
tail call fastcc void @foo( i32 1 )
tail call fastcc void @foo( i32 2 )
tail call fastcc void @foo( i32 3 )
tail call fastcc void @foo( i32 8 )
ret void
}
declare void @f(i32 %x)
define void @inner2(i32 %x, i32 %y, i32 %z, i1 %b) {
entry:
%cmp1 = icmp ne i32 %x, 0
br i1 %cmp1, label %then1, label %end1
then1:
call void @f(i32 %x)
br label %end1
end1:
%x2 = and i32 %x, %z
%cmp2 = icmp sgt i32 %x2, 1
br i1 %cmp2, label %then2, label %end2
then2:
call void @f(i32 %x2)
br label %end2
end2:
%y2 = or i32 %y, %z
%cmp3 = icmp sgt i32 %y2, 0
br i1 %cmp3, label %then3, label %end3
then3:
call void @f(i32 %y2)
br label %end3
end3:
br i1 %b, label %end3.1, label %end3.2
end3.1:
%x3.1 = or i32 %x, 10
br label %end3.3
end3.2:
%x3.2 = or i32 %x, 10
br label %end3.3
end3.3:
%x3.3 = phi i32 [ %x3.1, %end3.1 ], [ %x3.2, %end3.2 ]
%cmp4 = icmp slt i32 %x3.3, 1
br i1 %cmp4, label %then4, label %end4
then4:
call void @f(i32 %x3.3)
br label %end4
end4:
ret void
}
define void @outer2(i32 %z, i1 %b) {
; Ensure that after inlining, none of the blocks with a call to @f actually
; make it through inlining.
; CHECK-LABEL: define void @outer2(
; CHECK-NOT: call
; CHECK: ret void
entry:
call void @inner2(i32 0, i32 -1, i32 %z, i1 %b)
ret void
}
define void @PR12470_inner(i16 signext %p1) nounwind uwtable {
entry:
br i1 undef, label %cond.true, label %cond.false
cond.true:
br label %cond.end
cond.false:
%conv = sext i16 %p1 to i32
br label %cond.end
cond.end:
%cond = phi i32 [ undef, %cond.true ], [ 0, %cond.false ]
%tobool = icmp eq i32 %cond, 0
br i1 %tobool, label %if.end5, label %if.then
if.then:
ret void
if.end5:
ret void
}
define void @PR12470_outer() {
; This previously crashed during inliner cleanup and folding inner return
; instructions. Check that we don't crash and we produce a function with a single
; return instruction due to merging the returns of the inlined function.
; CHECK-LABEL: define void @PR12470_outer(
; CHECK-NOT: call
; CHECK: ret void
; CHECK-NOT: ret void
; CHECK: }
entry:
call void @PR12470_inner(i16 signext 1)
ret void
}
define void @crasher_inner() nounwind uwtable {
entry:
br i1 false, label %for.end28, label %for.body6
for.body6:
br i1 undef, label %for.body6, label %for.cond12.for.inc26_crit_edge
for.cond12.for.inc26_crit_edge:
br label %for.body6.1
for.end28:
ret void
for.body6.1:
br i1 undef, label %for.body6.1, label %for.cond12.for.inc26_crit_edge.1
for.cond12.for.inc26_crit_edge.1:
br label %for.body6.2
for.body6.2:
br i1 undef, label %for.body6.2, label %for.cond12.for.inc26_crit_edge.2
for.cond12.for.inc26_crit_edge.2:
br label %for.end28
}
define void @crasher_outer() {
; CHECK-LABEL: @crasher_outer(
; CHECK-NOT: call
; CHECK: ret void
; CHECK-NOT: ret
; CHECK: }
entry:
tail call void @crasher_inner()
ret void
}