1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
; RUN: opt -S -passes=inline %s | FileCheck %s
; RUN: opt -S -passes='cgscc(inline)' %s | FileCheck %s
; RUN: opt -S -passes='module-inline' %s | FileCheck %s
declare void @foo()
declare void @bar()
define void @callee(ptr %arg) {
; CHECK-LABEL: define void @callee
; CHECK-SAME: (ptr [[ARG:%.*]]) {
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[ARG]], null
; CHECK-NEXT: br i1 [[CMP]], label [[EXPENSIVE:%.*]], label [[DONE:%.*]]
; CHECK: expensive:
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: ret void
; CHECK: done:
; CHECK-NEXT: call void @bar()
; CHECK-NEXT: ret void
;
%cmp = icmp eq ptr %arg, null
br i1 %cmp, label %expensive, label %done
; This block is designed to be too expensive to inline. We can only inline
; callee if this block is known to be dead.
expensive:
call void @foo()
call void @foo()
call void @foo()
call void @foo()
call void @foo()
call void @foo()
call void @foo()
call void @foo()
call void @foo()
call void @foo()
ret void
done:
call void @bar()
ret void
}
; Positive test - arg is known non null
define void @caller(ptr nonnull %arg) {
; CHECK-LABEL: define void @caller
; CHECK-SAME: (ptr nonnull [[ARG:%.*]]) {
; CHECK-NEXT: call void @bar()
; CHECK-NEXT: ret void
;
call void @callee(ptr nonnull %arg)
ret void
}
; Negative test - arg is not known to be non null
define void @caller2(ptr %arg) {
; CHECK-LABEL: define void @caller2
; CHECK-SAME: (ptr [[ARG:%.*]]) {
; CHECK-NEXT: call void @callee(ptr [[ARG]])
; CHECK-NEXT: ret void
;
call void @callee(ptr %arg)
ret void
}
define void @caller3(ptr %arg) {
; CHECK-LABEL: define void @caller3
; CHECK-SAME: (ptr [[ARG:%.*]]) {
; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq ptr [[ARG]], null
; CHECK-NEXT: br i1 [[CMP_I]], label [[EXPENSIVE_I:%.*]], label [[DONE_I:%.*]]
; CHECK: expensive.i:
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: br label [[CALLEE_EXIT:%.*]]
; CHECK: done.i:
; CHECK-NEXT: call void @bar()
; CHECK-NEXT: br label [[CALLEE_EXIT]]
; CHECK: callee.exit:
; CHECK-NEXT: ret void
;
call void @callee(ptr nonnull %arg)
ret void
}
define void @caller4(ptr dereferenceable(8) %arg) {
; CHECK-LABEL: define void @caller4
; CHECK-SAME: (ptr dereferenceable(8) [[ARG:%.*]]) {
; CHECK-NEXT: call void @callee(ptr dereferenceable(8) [[ARG]])
; CHECK-NEXT: ret void
;
call void @callee(ptr dereferenceable(8) %arg)
ret void
}
define void @caller5(ptr dereferenceable(8) %arg) {
; CHECK-LABEL: define void @caller5
; CHECK-SAME: (ptr dereferenceable(8) [[ARG:%.*]]) {
; CHECK-NEXT: call void @callee(ptr [[ARG]])
; CHECK-NEXT: ret void
;
call void @callee(ptr %arg)
ret void
}
define void @caller6(ptr %arg) {
; CHECK-LABEL: define void @caller6
; CHECK-SAME: (ptr [[ARG:%.*]]) {
; CHECK-NEXT: call void @callee(ptr dereferenceable(8) [[ARG]])
; CHECK-NEXT: ret void
;
call void @callee(ptr dereferenceable(8) %arg)
ret void
}
|