Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@ -0,0 +1,75 @@
; RUN: opt < %s -loop-extract -disable-output
define void @solve() {
entry:
br label %loopentry.0
loopentry.0: ; preds = %endif.0, %entry
br i1 false, label %no_exit.0, label %loopexit.0
no_exit.0: ; preds = %loopentry.0
br i1 false, label %then.0, label %endif.0
then.0: ; preds = %no_exit.0
br i1 false, label %shortcirc_done, label %shortcirc_next
shortcirc_next: ; preds = %then.0
br label %shortcirc_done
shortcirc_done: ; preds = %shortcirc_next, %then.0
br i1 false, label %then.1, label %endif.1
then.1: ; preds = %shortcirc_done
br i1 false, label %cond_true, label %cond_false
cond_true: ; preds = %then.1
br label %cond_continue
cond_false: ; preds = %then.1
br label %cond_continue
cond_continue: ; preds = %cond_false, %cond_true
br label %return
after_ret.0: ; No predecessors!
br label %endif.1
endif.1: ; preds = %after_ret.0, %shortcirc_done
br label %endif.0
endif.0: ; preds = %endif.1, %no_exit.0
br label %loopentry.0
loopexit.0: ; preds = %loopentry.0
br i1 false, label %then.2, label %endif.2
then.2: ; preds = %loopexit.0
br i1 false, label %then.3, label %endif.3
then.3: ; preds = %then.2
br label %return
after_ret.1: ; No predecessors!
br label %endif.3
endif.3: ; preds = %after_ret.1, %then.2
br label %endif.2
endif.2: ; preds = %endif.3, %loopexit.0
br label %loopentry.1
loopentry.1: ; preds = %no_exit.1, %endif.2
br i1 false, label %no_exit.1, label %loopexit.1
no_exit.1: ; preds = %loopentry.1
br label %loopentry.1
loopexit.1: ; preds = %loopentry.1
br label %return
after_ret.2: ; No predecessors!
br label %return
return: ; preds = %after_ret.2, %loopexit.1, %then.3, %cond_continue
ret void
}

View File

@ -0,0 +1,33 @@
; RUN: opt < %s -loop-extract -disable-output
; This testcase is failing the loop extractor because not all exit blocks
; are dominated by all of the live-outs.
define i32 @ab(i32 %alpha, i32 %beta) {
entry:
br label %loopentry.1.preheader
loopentry.1.preheader: ; preds = %entry
br label %loopentry.1
loopentry.1: ; preds = %no_exit.1, %loopentry.1.preheader
br i1 false, label %no_exit.1, label %loopexit.0.loopexit1
no_exit.1: ; preds = %loopentry.1
%tmp.53 = load i32, i32* null ; <i32> [#uses=1]
br i1 false, label %shortcirc_next.2, label %loopentry.1
shortcirc_next.2: ; preds = %no_exit.1
%tmp.563 = call i32 @wins( i32 0, i32 %tmp.53, i32 3 ) ; <i32> [#uses=0]
ret i32 0
loopexit.0.loopexit1: ; preds = %loopentry.1
br label %loopexit.0
loopexit.0: ; preds = %loopexit.0.loopexit1
ret i32 0
}
declare i32 @wins(i32, i32, i32)
declare i16 @ab_code()

View File

@ -0,0 +1,28 @@
; RUN: opt < %s -loop-extract-single -disable-output
define void @ab() {
entry:
br label %codeReplTail
then.1: ; preds = %codeReplTail
br label %loopentry.1
loopentry.1: ; preds = %no_exit.1, %then.1
br i1 false, label %no_exit.1, label %loopexit.0.loopexit1
no_exit.1: ; preds = %loopentry.1
br label %loopentry.1
loopexit.0.loopexit: ; preds = %codeReplTail
ret void
loopexit.0.loopexit1: ; preds = %loopentry.1
ret void
codeReplTail: ; preds = %codeReplTail, %entry
switch i16 0, label %codeReplTail [
i16 0, label %loopexit.0.loopexit
i16 1, label %then.1
]
}

View File

@ -0,0 +1,47 @@
; RUN: opt < %s -loop-extract -disable-output
define void @sendMTFValues() {
entry:
br i1 false, label %then.1, label %endif.1
then.1: ; preds = %entry
br i1 false, label %loopentry.6.preheader, label %else.0
endif.1: ; preds = %entry
ret void
else.0: ; preds = %then.1
ret void
loopentry.6.preheader: ; preds = %then.1
br i1 false, label %endif.7.preheader, label %loopexit.9
endif.7.preheader: ; preds = %loopentry.6.preheader
%tmp.183 = add i32 0, -1 ; <i32> [#uses=1]
br label %endif.7
endif.7: ; preds = %loopexit.15, %endif.7.preheader
br i1 false, label %loopentry.10, label %loopentry.12
loopentry.10: ; preds = %endif.7
br label %loopentry.12
loopentry.12: ; preds = %loopentry.10, %endif.7
%ge.2.1 = phi i32 [ 0, %loopentry.10 ], [ %tmp.183, %endif.7 ] ; <i32> [#uses=0]
br i1 false, label %loopexit.14, label %no_exit.11
no_exit.11: ; preds = %loopentry.12
ret void
loopexit.14: ; preds = %loopentry.12
br i1 false, label %loopexit.15, label %no_exit.14
no_exit.14: ; preds = %loopexit.14
ret void
loopexit.15: ; preds = %loopexit.14
br i1 false, label %endif.7, label %loopexit.9
loopexit.9: ; preds = %loopexit.15, %loopentry.6.preheader
ret void
}

View File

@ -0,0 +1,23 @@
; RUN: opt < %s -loop-extract -disable-output
define void @maketree() {
entry:
br i1 false, label %no_exit.1, label %loopexit.0
no_exit.1: ; preds = %endif, %expandbox.entry, %entry
br i1 false, label %endif, label %expandbox.entry
expandbox.entry: ; preds = %no_exit.1
br i1 false, label %loopexit.1, label %no_exit.1
endif: ; preds = %no_exit.1
br i1 false, label %loopexit.1, label %no_exit.1
loopexit.1: ; preds = %endif, %expandbox.entry
%ic.i.0.0.4 = phi i32 [ 0, %expandbox.entry ], [ 0, %endif ] ; <i32> [#uses=0]
ret void
loopexit.0: ; preds = %entry
ret void
}

View File

@ -0,0 +1,198 @@
; RUN: opt < %s -loop-extract -disable-output
declare i32 @_IO_getc()
declare void @__errno_location()
define void @yylex() personality i32 (...)* @__gcc_personality_v0 {
entry:
switch i32 0, label %label.126 [
i32 0, label %return
i32 61, label %combine
i32 33, label %combine
i32 94, label %combine
i32 37, label %combine
i32 47, label %combine
i32 42, label %combine
i32 62, label %combine
i32 60, label %combine
i32 58, label %combine
i32 124, label %combine
i32 38, label %combine
i32 45, label %combine
i32 43, label %combine
i32 34, label %string_constant
i32 39, label %char_constant
i32 46, label %loopexit.2
i32 57, label %loopexit.2
i32 56, label %loopexit.2
i32 55, label %loopexit.2
i32 54, label %loopexit.2
i32 53, label %loopexit.2
i32 52, label %loopexit.2
i32 51, label %loopexit.2
i32 50, label %loopexit.2
i32 49, label %loopexit.2
i32 48, label %loopexit.2
i32 95, label %letter
i32 122, label %letter
i32 121, label %letter
i32 120, label %letter
i32 119, label %letter
i32 118, label %letter
i32 117, label %letter
i32 116, label %letter
i32 115, label %letter
i32 114, label %letter
i32 113, label %letter
i32 112, label %letter
i32 111, label %letter
i32 110, label %letter
i32 109, label %letter
i32 108, label %letter
i32 107, label %letter
i32 106, label %letter
i32 105, label %letter
i32 104, label %letter
i32 103, label %letter
i32 102, label %letter
i32 101, label %letter
i32 100, label %letter
i32 99, label %letter
i32 98, label %letter
i32 97, label %letter
i32 90, label %letter
i32 89, label %letter
i32 88, label %letter
i32 87, label %letter
i32 86, label %letter
i32 85, label %letter
i32 84, label %letter
i32 83, label %letter
i32 82, label %letter
i32 81, label %letter
i32 80, label %letter
i32 79, label %letter
i32 78, label %letter
i32 77, label %letter
i32 75, label %letter
i32 74, label %letter
i32 73, label %letter
i32 72, label %letter
i32 71, label %letter
i32 70, label %letter
i32 69, label %letter
i32 68, label %letter
i32 67, label %letter
i32 66, label %letter
i32 65, label %letter
i32 64, label %label.13
i32 76, label %label.12
i32 36, label %label.11
i32 -1, label %label.10
]
label.10: ; preds = %entry
ret void
label.11: ; preds = %entry
ret void
label.12: ; preds = %entry
ret void
label.13: ; preds = %entry
ret void
letter: ; preds = %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry
ret void
loopexit.2: ; preds = %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry
switch i32 0, label %shortcirc_next.14 [
i32 48, label %then.20
i32 46, label %endif.38
]
then.20: ; preds = %loopexit.2
switch i32 0, label %else.4 [
i32 120, label %then.21
i32 88, label %then.21
]
then.21: ; preds = %then.20, %then.20
ret void
else.4: ; preds = %then.20
ret void
shortcirc_next.14: ; preds = %loopexit.2
ret void
endif.38: ; preds = %loopexit.2
br i1 false, label %then.40, label %then.39
then.39: ; preds = %endif.38
ret void
then.40: ; preds = %endif.38
invoke void @__errno_location( )
to label %switchexit.2 unwind label %LongJmpBlkPre
loopentry.6: ; preds = %endif.52
switch i32 0, label %switchexit.2 [
i32 73, label %label.82
i32 105, label %label.82
i32 76, label %label.80
i32 108, label %label.80
i32 70, label %label.78
i32 102, label %label.78
]
label.78: ; preds = %loopentry.6, %loopentry.6
ret void
label.80: ; preds = %loopentry.6, %loopentry.6
ret void
label.82: ; preds = %loopentry.6, %loopentry.6
%c.0.15.5 = phi i32 [ %tmp.79417, %loopentry.6 ], [ %tmp.79417, %loopentry.6 ] ; <i32> [#uses=0]
ret void
switchexit.2: ; preds = %loopentry.6, %then.40
br i1 false, label %endif.51, label %loopexit.6
endif.51: ; preds = %switchexit.2
br i1 false, label %endif.52, label %then.52
then.52: ; preds = %endif.51
ret void
endif.52: ; preds = %endif.51
%tmp.79417 = invoke i32 @_IO_getc( )
to label %loopentry.6 unwind label %LongJmpBlkPre ; <i32> [#uses=2]
loopexit.6: ; preds = %switchexit.2
ret void
char_constant: ; preds = %entry
ret void
string_constant: ; preds = %entry
ret void
combine: ; preds = %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry
ret void
label.126: ; preds = %entry
ret void
return: ; preds = %entry
ret void
LongJmpBlkPre: ; preds = %endif.52, %then.40
%exn = landingpad { i8*, i32 }
catch i8* null
ret void
}
declare i32 @__gcc_personality_v0(...)

View File

@ -0,0 +1,26 @@
; RUN: opt < %s -extract-blocks -disable-output
define void @test1() {
no_exit.0.i:
br i1 false, label %yylex.entry, label %yylex.entry
yylex.entry: ; preds = %no_exit.0.i, %no_exit.0.i
%tmp.1027 = phi i32 [ 0, %no_exit.0.i ], [ 0, %no_exit.0.i ] ; <i32> [#uses=0]
ret void
}
define void @test2() {
no_exit.0.i:
switch i32 0, label %yylex.entry [
i32 0, label %yylex.entry
i32 1, label %foo
]
yylex.entry: ; preds = %no_exit.0.i, %no_exit.0.i
%tmp.1027 = phi i32 [ 0, %no_exit.0.i ], [ 0, %no_exit.0.i ] ; <i32> [#uses=0]
ret void
foo: ; preds = %no_exit.0.i
ret void
}

View File

@ -0,0 +1,18 @@
; RUN: opt < %s -extract-blocks -disable-output
define i32 @foo() personality i32 (...)* @__gcc_personality_v0 {
br label %EB
EB: ; preds = %0
%V = invoke i32 @foo( )
to label %Cont unwind label %Unw ; <i32> [#uses=1]
Cont: ; preds = %EB
ret i32 %V
Unw: ; preds = %EB
%exn = landingpad { i8*, i32 }
catch i8* null
resume { i8*, i32 } %exn
}
declare i32 @__gcc_personality_v0(...)

View File

@ -0,0 +1,36 @@
; RUN: opt < %s -loop-extract -S | FileCheck %s
@label = common local_unnamed_addr global i8* null
; CHECK: define
; no outlined function
; CHECK-NOT: define
define i32 @sterix(i32 %n) {
entry:
%tobool = icmp ne i32 %n, 0
; this blockaddress references a basic block that goes in the extracted loop
%cond = select i1 %tobool, i8* blockaddress(@sterix, %for.cond), i8* blockaddress(@sterix, %exit)
store i8* %cond, i8** @label
%cmp5 = icmp sgt i32 %n, 0
br i1 %cmp5, label %for.body, label %exit
for.cond:
%mul = shl nsw i32 %s.06, 1
%exitcond = icmp eq i32 %inc, %n
br i1 %exitcond, label %exit.loopexit, label %for.body
for.body:
%i.07 = phi i32 [ %inc, %for.cond ], [ 0, %entry ]
%s.06 = phi i32 [ %mul, %for.cond ], [ 1, %entry ]
%inc = add nuw nsw i32 %i.07, 1
br label %for.cond
exit.loopexit:
%phitmp = icmp ne i32 %s.06, 2
%phitmp8 = zext i1 %phitmp to i32
br label %exit
exit:
%s.1 = phi i32 [ 1, %entry ], [ %phitmp8, %exit.loopexit ]
ret i32 %s.1
}

View File

@ -0,0 +1,50 @@
; RUN: opt < %s -loop-extract -S | FileCheck %s
@choum.addr = internal unnamed_addr constant [3 x i8*] [i8* blockaddress(@choum, %bb10), i8* blockaddress(@choum, %bb14), i8* blockaddress(@choum, %bb18)]
; CHECK: define
; no outlined function
; CHECK-NOT: define
define void @choum(i32 %arg, i32* nocapture %arg1, i32 %arg2) {
bb:
%tmp = icmp sgt i32 %arg, 0
br i1 %tmp, label %bb3, label %bb24
bb3: ; preds = %bb
%tmp4 = sext i32 %arg2 to i64
%tmp5 = getelementptr inbounds [3 x i8*], [3 x i8*]* @choum.addr, i64 0, i64 %tmp4
%tmp6 = load i8*, i8** %tmp5
%tmp7 = zext i32 %arg to i64
br label %bb8
bb8: ; preds = %bb18, %bb3
%tmp9 = phi i64 [ 0, %bb3 ], [ %tmp22, %bb18 ]
indirectbr i8* %tmp6, [label %bb10, label %bb14, label %bb18]
bb10: ; preds = %bb8
%tmp11 = getelementptr inbounds i32, i32* %arg1, i64 %tmp9
%tmp12 = load i32, i32* %tmp11
%tmp13 = add nsw i32 %tmp12, 1
store i32 %tmp13, i32* %tmp11
br label %bb14
bb14: ; preds = %bb10, %bb8
%tmp15 = getelementptr inbounds i32, i32* %arg1, i64 %tmp9
%tmp16 = load i32, i32* %tmp15
%tmp17 = shl nsw i32 %tmp16, 1
store i32 %tmp17, i32* %tmp15
br label %bb18
bb18: ; preds = %bb14, %bb8
%tmp19 = getelementptr inbounds i32, i32* %arg1, i64 %tmp9
%tmp20 = load i32, i32* %tmp19
%tmp21 = add nsw i32 %tmp20, -3
store i32 %tmp21, i32* %tmp19
%tmp22 = add nuw nsw i64 %tmp9, 1
%tmp23 = icmp eq i64 %tmp22, %tmp7
br i1 %tmp23, label %bb24, label %bb8
bb24: ; preds = %bb18, %bb
ret void
}

View File

@ -0,0 +1,33 @@
; RUN: opt < %s -partial-inliner -skip-partial-inlining-cost-analysis -S | FileCheck %s
; This test checks to make sure that the CodeExtractor
; properly sets the entry count for the function that is
; extracted based on the root block being extracted and also
; takes into consideration if the block has edges coming from
; a block that is also being extracted.
define i32 @inlinedFunc(i1 %cond) !prof !1 {
entry:
br i1 %cond, label %if.then, label %return, !prof !2
if.then:
br i1 %cond, label %if.then, label %return, !prof !3
return: ; preds = %entry
ret i32 0
}
define internal i32 @dummyCaller(i1 %cond) !prof !1 {
entry:
%val = call i32 @inlinedFunc(i1 %cond)
ret i32 %val
}
; CHECK: @inlinedFunc.1_if.then(i1 %cond) !prof [[COUNT1:![0-9]+]]
!llvm.module.flags = !{!0}
; CHECK: [[COUNT1]] = !{!"function_entry_count", i64 250}
!0 = !{i32 1, !"MaxFunctionCount", i32 1000}
!1 = !{!"function_entry_count", i64 1000}
!2 = !{!"branch_weights", i32 250, i32 750}
!3 = !{!"branch_weights", i32 125, i32 125}

View File

@ -0,0 +1,34 @@
; RUN: opt < %s -partial-inliner -max-num-inline-blocks=2 -skip-partial-inlining-cost-analysis -S | FileCheck %s
; This test checks to make sure that CodeExtractor updates
; the exit branch probabilities for multiple exit blocks.
define i32 @inlinedFunc(i1 %cond) !prof !1 {
entry:
br i1 %cond, label %if.then, label %return, !prof !2
if.then:
br i1 %cond, label %return, label %return.2, !prof !3
return.2:
ret i32 10
return: ; preds = %entry
ret i32 0
}
define internal i32 @dummyCaller(i1 %cond) !prof !1 {
entry:
%val = call i32 @inlinedFunc(i1 %cond)
ret i32 %val
; CHECK-LABEL: @dummyCaller
; CHECK: call
; CHECK-NEXT: br i1 {{.*}}return.i{{.*}}return.2{{.*}}!prof [[COUNT1:![0-9]+]]
}
!llvm.module.flags = !{!0}
!0 = !{i32 1, !"MaxFunctionCount", i32 10000}
!1 = !{!"function_entry_count", i64 10000}
!2 = !{!"branch_weights", i32 5, i32 5}
!3 = !{!"branch_weights", i32 4, i32 1}
; CHECK: [[COUNT1]] = !{!"branch_weights", i32 31, i32 8}

View File

@ -0,0 +1,68 @@
; RUN: opt < %s -partial-inliner -skip-partial-inlining-cost-analysis -S | FileCheck %s
; RUN: opt < %s -passes=partial-inliner -skip-partial-inlining-cost-analysis -S | FileCheck %s
%"class.base" = type { %"struct.base"* }
%"struct.base" = type opaque
@g = external local_unnamed_addr global i32, align 4
; Function Attrs: nounwind uwtable
define i32 @callee_sinkable_bitcast(i32 %arg) local_unnamed_addr #0 {
; CHECK-LABEL:define{{.*}}@callee_sinkable_bitcast.{{[0-9]}}
; CHECK: alloca
; CHECK-NEXT: bitcast
; CHECK: call void @llvm.lifetime
bb:
%tmp = alloca %"class.base", align 4
%tmp1 = bitcast %"class.base"* %tmp to i8*
%tmp2 = load i32, i32* @g, align 4, !tbaa !2
%tmp3 = add nsw i32 %tmp2, 1
%tmp4 = icmp slt i32 %arg, 0
br i1 %tmp4, label %bb6, label %bb5
bb5: ; preds = %bb
call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %tmp1) #2
%tmp11 = bitcast %"class.base"* %tmp to i32*
store i32 %tmp3, i32* %tmp11, align 4, !tbaa !2
store i32 %tmp3, i32* @g, align 4, !tbaa !2
call void @bar(i32* nonnull %tmp11) #2
call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %tmp1) #2
br label %bb6
bb6: ; preds = %bb5, %bb
%tmp7 = phi i32 [ 1, %bb5 ], [ 0, %bb ]
ret i32 %tmp7
}
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
declare void @bar(i32*) local_unnamed_addr #2
declare void @bar2(i32*, i32*) local_unnamed_addr #1
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
; Function Attrs: nounwind uwtable
define i32 @caller(i32 %arg) local_unnamed_addr #0 {
bb:
%tmp = tail call i32 @callee_sinkable_bitcast(i32 %arg)
ret i32 %tmp
}
attributes #0 = { nounwind uwtable}
attributes #1 = { argmemonly nounwind }
attributes #2 = { nounwind }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 5.0.0 (trunk 303574)"}
!2 = !{!3, !3, i64 0}
!3 = !{!"int", !4, i64 0}
!4 = !{!"omnipotent char", !5, i64 0}
!5 = !{!"Simple C/C++ TBAA"}

View File

@ -0,0 +1,65 @@
; RUN: opt < %s -partial-inliner -skip-partial-inlining-cost-analysis -S | FileCheck %s
; RUN: opt < %s -passes=partial-inliner -skip-partial-inlining-cost-analysis -S | FileCheck %s
%"class.base" = type { %"struct.base"* }
%"struct.base" = type opaque
@g = external local_unnamed_addr global i32, align 4
define i32 @callee_no_bitcast(i32 %arg) local_unnamed_addr #0 {
; CHECK-LABEL:define{{.*}}@callee_no_bitcast.{{[0-9]}}
; CHECK: alloca
; CHECK: call void @llvm.lifetime
bb:
%tmp = alloca i8, align 4
%tmp2 = load i32, i32* @g, align 4, !tbaa !2
%tmp3 = add nsw i32 %tmp2, 1
%tmp4 = icmp slt i32 %arg, 0
br i1 %tmp4, label %bb6, label %bb5
bb5: ; preds = %bb
call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %tmp) #2
store i32 %tmp3, i32* @g, align 4, !tbaa !2
%tmp11 = bitcast i8 * %tmp to i32*
call void @bar(i32* nonnull %tmp11) #2
call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %tmp) #2
br label %bb6
bb6: ; preds = %bb5, %bb
%tmp7 = phi i32 [ 1, %bb5 ], [ 0, %bb ]
ret i32 %tmp7
}
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
declare void @bar(i32*) local_unnamed_addr #2
declare void @bar2(i32*, i32*) local_unnamed_addr #1
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
; Function Attrs: nounwind uwtable
define i32 @caller(i32 %arg) local_unnamed_addr #0 {
bb:
%tmp = tail call i32 @callee_no_bitcast(i32 %arg)
ret i32 %tmp
}
attributes #0 = { nounwind uwtable}
attributes #1 = { argmemonly nounwind }
attributes #2 = { nounwind }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 5.0.0 (trunk 303574)"}
!2 = !{!3, !3, i64 0}
!3 = !{!"int", !4, i64 0}
!4 = !{!"omnipotent char", !5, i64 0}
!5 = !{!"Simple C/C++ TBAA"}

View File

@ -0,0 +1,67 @@
; RUN: opt < %s -partial-inliner -skip-partial-inlining-cost-analysis -S | FileCheck %s
; RUN: opt < %s -passes=partial-inliner -skip-partial-inlining-cost-analysis -S | FileCheck %s
%"class.base" = type { %"struct.base"* }
%"struct.base" = type opaque
@g = external local_unnamed_addr global i32, align 4
define i32 @callee_unknown_use1(i32 %arg) local_unnamed_addr #0 {
; CHECK-LABEL:define{{.*}}@callee_unknown_use1.{{[0-9]}}
; CHECK-NOT: alloca
; CHECK: call void @llvm.lifetime
bb:
%tmp = alloca i8, align 4
%tmp2 = load i32, i32* @g, align 4, !tbaa !2
%tmp3 = add nsw i32 %tmp2, 1
%tmp4 = icmp slt i32 %arg, 0
br i1 %tmp4, label %bb6, label %bb5
bb5: ; preds = %bb
call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %tmp) #2
store i32 %tmp3, i32* @g, align 4, !tbaa !2
%tmp11 = bitcast i8* %tmp to i32*
call void @bar(i32* nonnull %tmp11) #2
call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %tmp) #2
br label %bb6
bb6: ; preds = %bb5, %bb
%tmp7 = phi i32 [ 1, %bb5 ], [ 0, %bb ]
%tmp1 = bitcast i8* %tmp to i32*
ret i32 %tmp7
}
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
declare void @bar(i32*) local_unnamed_addr #2
declare void @bar2(i32*, i32*) local_unnamed_addr #1
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
; Function Attrs: nounwind uwtable
define i32 @caller(i32 %arg) local_unnamed_addr #0 {
bb:
%tmp = tail call i32 @callee_unknown_use1(i32 %arg)
ret i32 %tmp
}
attributes #0 = { nounwind uwtable}
attributes #1 = { argmemonly nounwind }
attributes #2 = { nounwind }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 5.0.0 (trunk 303574)"}
!2 = !{!3, !3, i64 0}
!3 = !{!"int", !4, i64 0}
!4 = !{!"omnipotent char", !5, i64 0}
!5 = !{!"Simple C/C++ TBAA"}

View File

@ -0,0 +1,67 @@
; RUN: opt < %s -partial-inliner -skip-partial-inlining-cost-analysis -S | FileCheck %s
; RUN: opt < %s -passes=partial-inliner -skip-partial-inlining-cost-analysis -S | FileCheck %s
%"class.base" = type { %"struct.base"* }
%"struct.base" = type opaque
@g = external local_unnamed_addr global i32, align 4
define i32 @callee_unknown_use2(i32 %arg) local_unnamed_addr #0 {
; CHECK-LABEL:define{{.*}}@callee_unknown_use2.{{[0-9]}}
; CHECK-NOT: alloca
; CHECK: call void @llvm.lifetime
bb:
%tmp = alloca i32, align 4
%tmp1 = bitcast i32* %tmp to i8*
%tmp2 = load i32, i32* @g, align 4, !tbaa !2
%tmp3 = add nsw i32 %tmp2, 1
%tmp4 = icmp slt i32 %arg, 0
br i1 %tmp4, label %bb6, label %bb5
bb5: ; preds = %bb
call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %tmp1) #2
store i32 %tmp3, i32* %tmp, align 4, !tbaa !2
store i32 %tmp3, i32* @g, align 4, !tbaa !2
call void @bar(i32* nonnull %tmp) #2
call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %tmp1) #2
br label %bb6
bb6: ; preds = %bb5, %bb
%tmp7 = phi i32 [ 1, %bb5 ], [ 0, %bb ]
%tmp10 = bitcast i8* %tmp1 to i32*
ret i32 %tmp7
}
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
declare void @bar(i32*) local_unnamed_addr #2
declare void @bar2(i32*, i32*) local_unnamed_addr #1
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
; Function Attrs: nounwind uwtable
define i32 @caller(i32 %arg) local_unnamed_addr #0 {
bb:
%tmp = tail call i32 @callee_unknown_use2(i32 %arg)
ret i32 %tmp
}
attributes #0 = { nounwind uwtable}
attributes #1 = { argmemonly nounwind }
attributes #2 = { nounwind }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 5.0.0 (trunk 303574)"}
!2 = !{!3, !3, i64 0}
!3 = !{!"int", !4, i64 0}
!4 = !{!"omnipotent char", !5, i64 0}
!5 = !{!"Simple C/C++ TBAA"}

View File

@ -0,0 +1,56 @@
; RUN: opt < %s -partial-inliner -S | FileCheck %s
; RUN: opt < %s -passes=partial-inliner -S | FileCheck %s
; RUN: opt < %s -partial-inliner -skip-partial-inlining-cost-analysis -max-num-inline-blocks=2 -S | FileCheck --check-prefix=LIMIT %s
; RUN: opt < %s -passes=partial-inliner -skip-partial-inlining-cost-analysis -max-num-inline-blocks=2 -S | FileCheck --check-prefix=LIMIT %s
; Function Attrs: nounwind uwtable
define i32 @bar(i32 %arg) local_unnamed_addr #0 {
bb:
%tmp = icmp slt i32 %arg, 0
br i1 %tmp, label %bb1, label %bb5
bb1: ; preds = %bb
%tmp2 = tail call i32 (...) @channels() #2
%tmp3 = icmp slt i32 %tmp2, %arg
br i1 %tmp3, label %bb4, label %bb5
bb4: ; preds = %bb1
tail call void (...) @foo() #2
tail call void (...) @foo() #2
tail call void (...) @foo() #2
tail call void (...) @foo() #2
tail call void (...) @foo() #2
tail call void (...) @foo() #2
tail call void (...) @foo() #2
tail call void (...) @foo() #2
tail call void (...) @foo() #2
br label %bb5
bb5: ; preds = %bb4, %bb1, %bb
%tmp6 = phi i32 [ 0, %bb4 ], [ 1, %bb1 ], [ 1, %bb ]
ret i32 %tmp6
}
declare i32 @channels(...) local_unnamed_addr #1
declare void @foo(...) local_unnamed_addr #1
; Function Attrs: nounwind uwtable
define i32 @dummy_caller(i32 %arg) local_unnamed_addr #0 {
bb:
; CHECK-LABEL: @dummy_caller
; CHECK: br i1
; CHECK: br i1
; CHECK: call void @bar.1_
; LIMIT-LABEL: @dummy_caller
; LIMIT: br i1
; LIMIT-NOT: br
; LIMIT: call void @bar.1_
%tmp = tail call i32 @bar(i32 %arg)
ret i32 %tmp
}
attributes #0 = { nounwind }
attributes #1 = { nounwind }
attributes #2 = { nounwind }

View File

@ -0,0 +1,63 @@
; RUN: opt < %s -partial-inliner -S | FileCheck %s
; RUN: opt < %s -passes=partial-inliner -S | FileCheck %s
; RUN: opt < %s -partial-inliner -max-num-inline-blocks=3 -S | FileCheck --check-prefix=LIMIT %s
; RUN: opt < %s -passes=partial-inliner -max-num-inline-blocks=3 -S | FileCheck --check-prefix=LIMIT %s
; Function Attrs: nounwind uwtable
define i32 @bar(i32 %arg) local_unnamed_addr #0 {
bb:
%tmp = icmp slt i32 %arg, 0
br i1 %tmp, label %bb1, label %bb4
bb1: ; preds = %bb
%tmp2 = tail call i32 (...) @n() #2
%tmp3 = icmp slt i32 %tmp2, %arg
br i1 %tmp3, label %bb7, label %bb4
bb4: ; preds = %bb1, %bb
%tmp5 = tail call i32 (...) @m() #2
%tmp6 = icmp slt i32 %tmp5, %arg
br i1 %tmp6, label %bb7, label %bb8
bb7: ; preds = %bb4, %bb1
tail call void (...) @foo() #2
tail call void (...) @foo() #2
tail call void (...) @foo() #2
tail call void (...) @foo() #2
tail call void (...) @foo() #2
tail call void (...) @foo() #2
tail call void (...) @foo() #2
tail call void (...) @foo() #2
tail call void (...) @foo() #2
br label %bb8
bb8: ; preds = %bb7, %bb4
%tmp9 = phi i32 [ 0, %bb7 ], [ 1, %bb4 ]
ret i32 %tmp9
}
declare i32 @n(...) local_unnamed_addr #1
declare i32 @m(...) local_unnamed_addr #1
declare void @foo(...) local_unnamed_addr #1
; Function Attrs: nounwind uwtable
define i32 @dummy_caller(i32 %arg) local_unnamed_addr #0 {
bb:
; CHECK-LABEL: @dummy_caller
; CHECK: br i1
; CHECK: br i1
; CHECK: br i1
; CHECK: call void @bar.1_
; LIMIT-LABEL: @dummy_caller
; LIMIT-NOT: br i1
; LIMIT: call i32 @bar
%tmp = tail call i32 @bar(i32 %arg)
ret i32 %tmp
}
attributes #0 = { nounwind }
attributes #1 = { nounwind }
attributes #2 = { nounwind }

View File

@ -0,0 +1,56 @@
; RUN: opt < %s -partial-inliner -S | FileCheck %s
; RUN: opt < %s -passes=partial-inliner -S | FileCheck %s
; Function Attrs: nounwind
declare void @foo(...) local_unnamed_addr #0
; Function Attrs: noinline
define i32 @caller(i32 (i32)* nocapture %arg, i32 (i32)* nocapture %arg1, i32 %arg2) local_unnamed_addr #1 {
bb:
%tmp = tail call i32 %arg(i32 %arg2) #0
%tmp3 = tail call i32 %arg1(i32 %arg2) #0
%tmp4 = add nsw i32 %tmp3, %tmp
ret i32 %tmp4
}
; Function Attrs: nounwind
define i32 @bar(i32 %arg) #0 {
bb:
%tmp = icmp slt i32 %arg, 0
br i1 %tmp, label %bb1, label %bb2
bb1: ; preds = %bb
tail call void (...) @foo() #0
tail call void (...) @foo() #0
tail call void (...) @foo() #0
tail call void (...) @foo() #0
tail call void (...) @foo() #0
tail call void (...) @foo() #0
tail call void (...) @foo() #0
tail call void (...) @foo() #0
tail call void (...) @foo() #0
br label %bb2
bb2: ; preds = %bb1, %bb
%tmp3 = phi i32 [ 0, %bb1 ], [ 1, %bb ]
ret i32 %tmp3
}
; Function Attrs: nounwind
define i32 @dummy_caller(i32 %arg) local_unnamed_addr #0 {
bb:
; CHECK-LABEL: @dummy_caller
; check that caller is not wrongly inlined by partial inliner
; CHECK: call i32 @caller
; CHECK-NOT: call .* @bar
%tmp = tail call i32 @caller(i32 (i32)* nonnull @bar, i32 (i32)* nonnull @bar, i32 %arg)
ret i32 %tmp
}
attributes #0 = { nounwind }
attributes #1 = { noinline }
!llvm.ident = !{!0}
!0 = !{!"clang version 5.0.0 (trunk 300897) (llvm/trunk 300947)"}

View File

@ -0,0 +1,104 @@
; RUN: opt < %s -S -partial-inliner -skip-partial-inlining-cost-analysis=true | FileCheck %s
; CHECK-LABEL: @callee
; CHECK: %mul = mul nsw i32 %v, 10, !dbg ![[DBG1:[0-9]+]]
define i32 @callee(i32 %v) !dbg !16 {
entry:
%cmp = icmp sgt i32 %v, 2000
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
%mul = mul nsw i32 %v, 10, !dbg !17
br label %if.then2
if.then2:
%sub = sub i32 %v, 10, !dbg !23
br label %if.end
if.end: ; preds = %if.then, %entry
%v2 = phi i32 [ %v, %entry ], [ %mul, %if.then2 ]
%add = add nsw i32 %v2, 200
ret i32 %add
}
; CHECK-LABEL: @caller
; CHECK: codeRepl.i:
; CHECK-NEXT: call void @callee.2_if.then(i32 %v, i32* %mul.loc.i), !dbg ![[DBG2:[0-9]+]]
define i32 @caller(i32 %v) !dbg !8 {
entry:
%call = call i32 @callee(i32 %v), !dbg !14
ret i32 %call
}
; CHECK-LABEL: @callee2
; CHECK: %sub = sub i32 %v, 10, !dbg ![[DBG3:[0-9]+]]
define i32 @callee2(i32 %v) !dbg !18 {
entry:
%cmp = icmp sgt i32 %v, 2000
br i1 %cmp, label %if.then, label %if.end
if.then:
br label %if.then2
if.then2:
%sub = sub i32 %v, 10, !dbg !20
br label %if.end
if.end:
%v2 = phi i32 [ %v, %entry ], [ %sub, %if.then2 ]
%add = add nsw i32 %v2, 200
ret i32 %add
}
; CHECK-LABEL: @caller2
; CHECK: codeRepl.i:
; CHECK-NEXT: call void @callee2.1_if.then(i32 %v, i32* %sub.loc.i), !dbg ![[DBG4:[0-9]+]]
define i32 @caller2(i32 %v) !dbg !21 {
entry:
%call = call i32 @callee2(i32 %v), !dbg !22
ret i32 %call
}
; CHECK-LABEL: define internal void @callee2.1_if.then
; CHECK: br label %if.then, !dbg ![[DBG5:[0-9]+]]
; CHECK-LABEL: define internal void @callee.2_if.then
; CHECK: br label %if.then, !dbg ![[DBG6:[0-9]+]]
; CHECK: ![[DBG1]] = !DILocation(line: 10, column: 7,
; CHECK: ![[DBG2]] = !DILocation(line: 10, column: 7,
; CHECK: ![[DBG3]] = !DILocation(line: 110, column: 17,
; CHECK: ![[DBG4]] = !DILocation(line: 110, column: 17,
; CHECK: ![[DBG5]] = !DILocation(line: 110, column: 17,
; CHECK: ![[DBG6]] = !DILocation(line: 10, column: 7,
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5, !6}
!llvm.ident = !{!7}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0 (trunk 177881)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "test.c", directory: "/tmp")
!2 = !{}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{i32 1, !"min_enum_size", i32 4}
!7 = !{!"clang version 6.0.0"}
!8 = distinct !DISubprogram(name: "caller", scope: !1, file: !1, line: 3, type: !9, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12)
!9 = !DISubroutineType(types: !10)
!10 = !{!11, !11}
!11 = !DIBasicType(name: "int", size: 19, encoding: DW_ATE_signed)
!12 = !{!13}
!13 = !DILocalVariable(name: "v", arg: 1, scope: !8, file: !1, line: 3, type: !11)
!14 = !DILocation(line: 5, column: 10, scope: !8)
!15 = distinct !DILexicalBlock(scope: !16, file: !1, line: 9, column: 7)
!16 = distinct !DISubprogram(name: "callee", scope: !1, file: !1, line: 8, type: !9, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12)
!17 = !DILocation(line: 10, column: 7, scope: !15)
!18 = distinct !DISubprogram(name: "callee2", scope: !1, file: !1, line: 8, type: !9, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12)
!19 = distinct !DILexicalBlock(scope: !18, file: !1, line: 100, column: 1)
!20 = !DILocation(line: 110, column: 17, scope: !19)
!21 = distinct !DISubprogram(name: "caller2", scope: !1, file: !1, line: 8, type: !9, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12)
!22 = !DILocation(line: 110, column: 17, scope: !21)
!23 = !DILocation(line: 15, column: 7, scope: !15)

Some files were not shown because too many files have changed in this diff Show More