• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt -S -always-inline < %s | FileCheck %s
2
3declare void @f()
4declare i32 @g()
5declare fastcc i32 @g.fastcc()
6
7define i32 @callee_0() alwaysinline {
8 entry:
9  call void @f()
10  ret i32 2
11}
12
13define i32 @caller_0() {
14; CHECK-LABEL: @caller_0(
15 entry:
16; CHECK: entry:
17; CHECK-NEXT: call void @f()
18; CHECK-NEXT: ret i32 2
19  %x = call i32 @callee_0() [ "deopt"(i32 5) ]
20  ret i32 %x
21}
22
23define i32 @callee_1() alwaysinline {
24 entry:
25  call void @f() [ "deopt"() ]
26  call void @f() [ "deopt"(i32 0, i32 1) ]
27  call void @f() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
28  ret i32 2
29}
30
31define i32 @caller_1() {
32; CHECK-LABEL: @caller_1(
33 entry:
34; CHECK: entry:
35; CHECK-NEXT:  call void @f() [ "deopt"(i32 5) ]
36; CHECK-NEXT:  call void @f() [ "deopt"(i32 5, i32 0, i32 1) ]
37; CHECK-NEXT:  call void @f() [ "deopt"(i32 5, i32 0, i32 1), "foo"(double 0.000000e+00) ]
38; CHECK-NEXT:  ret i32 2
39
40  %x = call i32 @callee_1() [ "deopt"(i32 5) ]
41  ret i32 %x
42}
43
44define i32 @callee_2() alwaysinline {
45 entry:
46  %v = call i32 @g() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
47  ret i32 %v
48}
49
50define i32 @caller_2(i32 %val) {
51; CHECK-LABEL: @caller_2(
52 entry:
53; CHECK: entry:
54; CHECK-NEXT:   [[RVAL:%[^ ]+]] = call i32 @g() [ "deopt"(i32 %val, i32 0, i32 1), "foo"(double 0.000000e+00) ]
55; CHECK-NEXT:   ret i32 [[RVAL]]
56  %x = call i32 @callee_2() [ "deopt"(i32 %val) ]
57  ret i32 %x
58}
59
60define i32 @callee_3() alwaysinline {
61 entry:
62  %v = call i32 @g() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
63  ret i32 %v
64}
65
66define i32 @caller_3() personality i8 3 {
67; CHECK-LABEL: @caller_3(
68 entry:
69  %x = invoke i32 @callee_3() [ "deopt"(i32 7) ] to label %normal unwind label %unwind
70; CHECK: invoke i32 @g() [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ]
71
72 normal:
73  ret i32 %x
74
75 unwind:
76  %cleanup = landingpad i8 cleanup
77  ret i32 101
78}
79
80define i32 @callee_4() alwaysinline personality i8 3 {
81 entry:
82  %v = invoke i32 @g() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ] to label %normal unwind label %unwind
83
84 normal:
85  ret i32 %v
86
87 unwind:
88  %cleanup = landingpad i8 cleanup
89  ret i32 100
90}
91
92define i32 @caller_4() {
93; CHECK-LABEL: @caller_4(
94 entry:
95; CHECK: invoke i32 @g() [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ]
96  %x = call i32 @callee_4() [ "deopt"(i32 7) ]
97  ret i32 %x
98}
99
100define i32 @callee_5() alwaysinline personality i8 3 {
101 entry:
102  %v = invoke fastcc i32 @g.fastcc() #0 [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ] to label %normal unwind label %unwind
103
104 normal:
105  ret i32 %v
106
107 unwind:
108  %cleanup = landingpad i8 cleanup
109  ret i32 100
110}
111
112define i32 @caller_5() {
113; CHECK-LABEL: @caller_5(
114 entry:
115; CHECK:  invoke fastcc i32 @g.fastcc() #[[FOO_BAR_ATTR_IDX:[0-9]+]] [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ]
116  %x = call i32 @callee_5() [ "deopt"(i32 7) ]
117  ret i32 %x
118}
119
120define i32 @callee_6() alwaysinline personality i8 3 {
121 entry:
122  %v = call fastcc i32 @g.fastcc() #0 [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
123  ret i32 %v
124}
125
126define i32 @caller_6() {
127; CHECK-LABEL: @caller_6(
128 entry:
129; CHECK: call fastcc i32 @g.fastcc() #[[FOO_BAR_ATTR_IDX]] [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ]
130  %x = call i32 @callee_6() [ "deopt"(i32 7) ]
131  ret i32 %x
132}
133
134define i32 @callee_7(i1 %val) alwaysinline personality i8 3 {
135; We want something that PruningFunctionCloner is not smart enough to
136; recognize, but can be recognized by recursivelySimplifyInstruction.
137
138 entry:
139  br i1 %val, label %check, label %precheck
140
141 precheck:
142  br label %check
143
144 check:
145  %p = phi i1 [ %val, %entry ], [ true, %precheck ]
146  br i1 %p, label %do.not, label %do
147
148 do.not:
149  ret i32 0
150
151 do:
152  %v = call fastcc i32 @g.fastcc() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
153  ret i32 %v
154}
155
156define i32 @caller_7() {
157; CHECK-LABEL: @caller_7(
158 entry:
159; CHECK-NOT: call fastcc i32 @g.fastcc()
160; CHECK: ret i32 0
161  %x = call i32 @callee_7(i1 true) [ "deopt"(i32 7) ]
162  ret i32 %x
163}
164
165define i32 @callee_8(i1 %val) alwaysinline personality i8 3 {
166; We want something that PruningFunctionCloner is not smart enough to
167; recognize, but can be recognized by recursivelySimplifyInstruction.
168
169 entry:
170  br i1 %val, label %check, label %precheck
171
172 precheck:
173  br label %check
174
175 check:
176  %p = phi i1 [ %val, %entry ], [ true, %precheck ]
177  br i1 %p, label %do.not, label %do
178
179 do.not:
180  ret i32 0
181
182 do:
183  %phi = phi i32 [ 0, %check ], [ %v, %do ]
184  %v = call fastcc i32 @g.fastcc() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
185  %ic = icmp eq i32 %v, 42
186  br i1 %ic, label %do, label %done
187
188 done:
189  ret i32 %phi
190}
191
192define i32 @caller_8() {
193; CHECK-LABEL: @caller_8(
194 entry:
195; CHECK-NOT: call fastcc i32 @g.fastcc()
196; CHECK: ret i32 0
197  %x = call i32 @callee_8(i1 true) [ "deopt"(i32 7) ]
198  ret i32 %x
199}
200
201attributes #0 = { "foo"="bar" }
202
203; CHECK: attributes #[[FOO_BAR_ATTR_IDX]] = { "foo"="bar" }
204