1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt -S -passes=inline %s | FileCheck %s
3 ; RUN: opt -S -passes='cgscc(inline)' %s | FileCheck %s
4 ; RUN: opt -S -passes='module-inline' %s | FileCheck %s
7 declare void @use.ptr(ptr) willreturn nounwind
8 declare void @use.val(i8) willreturn nounwind
11 declare ptr @llvm.ptrmask.p0.i64(ptr, i64)
15 define ptr @callee0123() {
16 ; CHECK-LABEL: define ptr @callee0123() {
17 ; CHECK-NEXT: [[R:%.*]] = call ptr @foo()
18 ; CHECK-NEXT: ret ptr [[R]]
24 define ptr @caller0() {
25 ; CHECK-LABEL: define ptr @caller0() {
26 ; CHECK-NEXT: [[R_I:%.*]] = call dereferenceable(16) ptr @foo()
27 ; CHECK-NEXT: ret ptr [[R_I]]
29 %r = call dereferenceable(16) ptr @callee0123()
33 define ptr @caller1() {
34 ; CHECK-LABEL: define ptr @caller1() {
35 ; CHECK-NEXT: [[R_I:%.*]] = call align 16 ptr @foo()
36 ; CHECK-NEXT: ret ptr [[R_I]]
38 %r = call align(16) ptr @callee0123()
42 define ptr @caller2() {
43 ; CHECK-LABEL: define ptr @caller2() {
44 ; CHECK-NEXT: [[R_I:%.*]] = call noundef ptr @foo()
45 ; CHECK-NEXT: ret ptr [[R_I]]
47 %r = call noundef ptr @callee0123()
51 define ptr @caller3() {
52 ; CHECK-LABEL: define ptr @caller3() {
53 ; CHECK-NEXT: [[R_I:%.*]] = call dereferenceable_or_null(32) ptr @foo()
54 ; CHECK-NEXT: ret ptr [[R_I]]
56 %r = call dereferenceable_or_null(32) ptr @callee0123()
60 define ptr @caller_0123_dornull() {
61 ; CHECK-LABEL: define ptr @caller_0123_dornull() {
62 ; CHECK-NEXT: [[R_I:%.*]] = call noundef align 32 dereferenceable_or_null(16) ptr @foo()
63 ; CHECK-NEXT: ret ptr [[R_I]]
65 %r = call noundef align(32) dereferenceable_or_null(16) ptr @callee0123()
69 define ptr @caller_0123_d() {
70 ; CHECK-LABEL: define ptr @caller_0123_d() {
71 ; CHECK-NEXT: [[R_I:%.*]] = call noundef align 32 dereferenceable(16) ptr @foo()
72 ; CHECK-NEXT: ret ptr [[R_I]]
74 %r = call noundef align(32) dereferenceable(16) ptr @callee0123()
78 define ptr @callee4() {
79 ; CHECK-LABEL: define ptr @callee4() {
80 ; CHECK-NEXT: [[R:%.*]] = call ptr @foo()
81 ; CHECK-NEXT: call void @bar()
82 ; CHECK-NEXT: ret ptr [[R]]
89 define ptr @caller4_fail() {
90 ; CHECK-LABEL: define ptr @caller4_fail() {
91 ; CHECK-NEXT: [[R_I:%.*]] = call ptr @foo()
92 ; CHECK-NEXT: call void @bar()
93 ; CHECK-NEXT: ret ptr [[R_I]]
95 %r = call noundef align(256) ptr @callee4()
99 define ptr @callee5() {
100 ; CHECK-LABEL: define ptr @callee5() {
101 ; CHECK-NEXT: [[R:%.*]] = call align 64 ptr @foo()
102 ; CHECK-NEXT: ret ptr [[R]]
104 %r = call align(64) ptr @foo()
108 define ptr @caller5_fail() {
109 ; CHECK-LABEL: define ptr @caller5_fail() {
110 ; CHECK-NEXT: [[R_I:%.*]] = call noundef align 64 ptr @foo()
111 ; CHECK-NEXT: ret ptr [[R_I]]
113 %r = call noundef align(32) ptr @callee5()
117 define ptr @caller5_okay() {
118 ; CHECK-LABEL: define ptr @caller5_okay() {
119 ; CHECK-NEXT: [[R_I:%.*]] = call noundef align 128 ptr @foo()
120 ; CHECK-NEXT: ret ptr [[R_I]]
122 %r = call noundef align(128) ptr @callee5()
126 define ptr @callee6() {
127 ; CHECK-LABEL: define ptr @callee6() {
128 ; CHECK-NEXT: [[R:%.*]] = call dereferenceable(16) ptr @foo()
129 ; CHECK-NEXT: ret ptr [[R]]
131 %r = call dereferenceable(16) ptr @foo()
135 define ptr @caller6_fail() {
136 ; CHECK-LABEL: define ptr @caller6_fail() {
137 ; CHECK-NEXT: [[R_I:%.*]] = call dereferenceable(16) ptr @foo()
138 ; CHECK-NEXT: ret ptr [[R_I]]
140 %r = call dereferenceable(8) ptr @callee6()
144 define ptr @caller6_okay() {
145 ; CHECK-LABEL: define ptr @caller6_okay() {
146 ; CHECK-NEXT: [[R_I:%.*]] = call dereferenceable(32) ptr @foo()
147 ; CHECK-NEXT: ret ptr [[R_I]]
149 %r = call dereferenceable(32) ptr @callee6()
153 define ptr @callee7() {
154 ; CHECK-LABEL: define ptr @callee7() {
155 ; CHECK-NEXT: [[R:%.*]] = call dereferenceable_or_null(16) ptr @foo()
156 ; CHECK-NEXT: ret ptr [[R]]
158 %r = call dereferenceable_or_null(16) ptr @foo()
162 define ptr @caller7_fail() {
163 ; CHECK-LABEL: define ptr @caller7_fail() {
164 ; CHECK-NEXT: [[R_I:%.*]] = call dereferenceable_or_null(16) ptr @foo()
165 ; CHECK-NEXT: ret ptr [[R_I]]
167 %r = call dereferenceable_or_null(8) ptr @callee7()
171 define ptr @caller7_okay() {
172 ; CHECK-LABEL: define ptr @caller7_okay() {
173 ; CHECK-NEXT: [[R_I:%.*]] = call dereferenceable_or_null(32) ptr @foo()
174 ; CHECK-NEXT: ret ptr [[R_I]]
176 %r = call dereferenceable_or_null(32) ptr @callee7()
180 define ptr @callee8() {
181 ; CHECK-LABEL: define ptr @callee8() {
182 ; CHECK-NEXT: [[R:%.*]] = call ptr @foo()
183 ; CHECK-NEXT: ret ptr [[R]]
189 define ptr @caller8_okay_use_after_poison_anyways() {
190 ; CHECK-LABEL: define ptr @caller8_okay_use_after_poison_anyways() {
191 ; CHECK-NEXT: [[R_I:%.*]] = call nonnull ptr @foo()
192 ; CHECK-NEXT: call void @use.ptr(ptr [[R_I]])
193 ; CHECK-NEXT: ret ptr [[R_I]]
195 %r = call nonnull ptr @callee8()
196 call void @use.ptr(ptr %r)
200 define ptr @callee9() {
201 ; CHECK-LABEL: define ptr @callee9() {
202 ; CHECK-NEXT: [[R:%.*]] = call noundef ptr @foo()
203 ; CHECK-NEXT: ret ptr [[R]]
205 %r = call noundef ptr @foo()
209 define ptr @caller9_fail_creates_ub() {
210 ; CHECK-LABEL: define ptr @caller9_fail_creates_ub() {
211 ; CHECK-NEXT: [[R_I:%.*]] = call noundef ptr @foo()
212 ; CHECK-NEXT: call void @use.ptr(ptr [[R_I]])
213 ; CHECK-NEXT: ret ptr [[R_I]]
215 %r = call nonnull ptr @callee9()
216 call void @use.ptr(ptr %r)
220 define ptr @caller9_okay_is_ub_anyways() {
221 ; CHECK-LABEL: define ptr @caller9_okay_is_ub_anyways() {
222 ; CHECK-NEXT: [[R_I:%.*]] = call noundef nonnull ptr @foo()
223 ; CHECK-NEXT: call void @use.ptr(ptr [[R_I]])
224 ; CHECK-NEXT: ret ptr [[R_I]]
226 %r = call noundef nonnull ptr @callee9()
227 call void @use.ptr(ptr %r)
231 define ptr @callee10() {
232 ; CHECK-LABEL: define ptr @callee10() {
233 ; CHECK-NEXT: [[R:%.*]] = call ptr @foo()
234 ; CHECK-NEXT: call void @use.ptr(ptr [[R]])
235 ; CHECK-NEXT: ret ptr [[R]]
238 call void @use.ptr(ptr %r)
242 define ptr @caller10_fail_maybe_poison() {
243 ; CHECK-LABEL: define ptr @caller10_fail_maybe_poison() {
244 ; CHECK-NEXT: [[R_I:%.*]] = call ptr @foo()
245 ; CHECK-NEXT: call void @use.ptr(ptr [[R_I]])
246 ; CHECK-NEXT: ret ptr [[R_I]]
248 %r = call nonnull ptr @callee10()
252 define ptr @caller10_okay_will_be_ub() {
253 ; CHECK-LABEL: define ptr @caller10_okay_will_be_ub() {
254 ; CHECK-NEXT: [[R_I:%.*]] = call noundef nonnull ptr @foo()
255 ; CHECK-NEXT: call void @use.ptr(ptr [[R_I]])
256 ; CHECK-NEXT: ret ptr [[R_I]]
258 %r = call noundef nonnull ptr @callee10()
262 define noundef ptr @caller10_okay_will_be_ub_todo() {
263 ; CHECK-LABEL: define noundef ptr @caller10_okay_will_be_ub_todo() {
264 ; CHECK-NEXT: [[R_I:%.*]] = call ptr @foo()
265 ; CHECK-NEXT: call void @use.ptr(ptr [[R_I]])
266 ; CHECK-NEXT: ret ptr [[R_I]]
268 %r = call nonnull ptr @callee10()
272 define ptr @callee11() {
273 ; CHECK-LABEL: define ptr @callee11() {
274 ; CHECK-NEXT: [[R:%.*]] = call ptr @foo()
275 ; CHECK-NEXT: [[COND:%.*]] = call i1 @val() #[[ATTR0:[0-9]+]]
276 ; CHECK-NEXT: br i1 [[COND]], label [[TRUE:%.*]], label [[FALSE:%.*]]
278 ; CHECK-NEXT: call void @baz() #[[ATTR0]]
279 ; CHECK-NEXT: ret ptr [[R]]
281 ; CHECK-NEXT: call void @bar() #[[ATTR0]]
282 ; CHECK-NEXT: [[COND2:%.*]] = call i1 @val()
283 ; CHECK-NEXT: ret ptr [[R]]
286 %cond = call i1 @val() nounwind willreturn
287 br i1 %cond, label %True, label %False
289 call void @baz() nounwind willreturn
292 call void @bar() nounwind willreturn
293 %cond2 = call i1 @val()
297 define ptr @caller11_todo() {
298 ; CHECK-LABEL: define ptr @caller11_todo() {
299 ; CHECK-NEXT: [[R_I:%.*]] = call ptr @foo()
300 ; CHECK-NEXT: [[COND_I:%.*]] = call i1 @val() #[[ATTR0]]
301 ; CHECK-NEXT: br i1 [[COND_I]], label [[TRUE_I:%.*]], label [[FALSE_I:%.*]]
303 ; CHECK-NEXT: call void @baz() #[[ATTR0]]
304 ; CHECK-NEXT: br label [[CALLEE11_EXIT:%.*]]
306 ; CHECK-NEXT: call void @bar() #[[ATTR0]]
307 ; CHECK-NEXT: [[COND2_I:%.*]] = call i1 @val()
308 ; CHECK-NEXT: br label [[CALLEE11_EXIT]]
309 ; CHECK: callee11.exit:
310 ; CHECK-NEXT: ret ptr [[R_I]]
312 %r = call nonnull ptr @callee11()
316 define ptr @callee12() {
317 ; CHECK-LABEL: define ptr @callee12() {
318 ; CHECK-NEXT: [[P:%.*]] = call ptr @foo()
319 ; CHECK-NEXT: [[COND:%.*]] = call i1 @val() #[[ATTR0]]
320 ; CHECK-NEXT: [[PP:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -4)
321 ; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], ptr [[P]], ptr [[PP]]
322 ; CHECK-NEXT: ret ptr [[R]]
325 %cond = call i1 @val() nounwind willreturn
326 %pp = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -4)
327 %r = select i1 %cond, ptr %p, ptr %pp
331 define ptr @caller12_todo() {
332 ; CHECK-LABEL: define ptr @caller12_todo() {
333 ; CHECK-NEXT: [[P_I:%.*]] = call ptr @foo()
334 ; CHECK-NEXT: [[COND_I:%.*]] = call i1 @val() #[[ATTR0]]
335 ; CHECK-NEXT: [[PP_I:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P_I]], i64 -4)
336 ; CHECK-NEXT: [[R_I:%.*]] = select i1 [[COND_I]], ptr [[P_I]], ptr [[PP_I]]
337 ; CHECK-NEXT: ret ptr [[R_I]]
339 %r = call nonnull ptr @callee12()
343 define i8 @callee13() {
344 ; CHECK-LABEL: define i8 @callee13() {
345 ; CHECK-NEXT: [[R:%.*]] = call i8 @val8()
346 ; CHECK-NEXT: ret i8 [[R]]
352 define i8 @caller13_okay_use_after_poison_anyways() {
353 ; CHECK-LABEL: define i8 @caller13_okay_use_after_poison_anyways() {
354 ; CHECK-NEXT: [[R_I:%.*]] = call range(i8 0, 10) i8 @val8()
355 ; CHECK-NEXT: call void @use.val(i8 [[R_I]])
356 ; CHECK-NEXT: ret i8 [[R_I]]
358 %r = call range(i8 0, 10) i8 @callee13()
359 call void @use.val(i8 %r)
363 define i8 @callee14() {
364 ; CHECK-LABEL: define i8 @callee14() {
365 ; CHECK-NEXT: [[R:%.*]] = call noundef i8 @val8()
366 ; CHECK-NEXT: ret i8 [[R]]
368 %r = call noundef i8 @val8()
372 define i8 @caller14_fail_creates_ub() {
373 ; CHECK-LABEL: define i8 @caller14_fail_creates_ub() {
374 ; CHECK-NEXT: [[R_I:%.*]] = call noundef i8 @val8()
375 ; CHECK-NEXT: call void @use.val(i8 [[R_I]])
376 ; CHECK-NEXT: ret i8 [[R_I]]
378 %r = call range(i8 0, 10) i8 @callee14()
379 call void @use.val(i8 %r)
383 define i8 @caller14_okay_is_ub_anyways() {
384 ; CHECK-LABEL: define i8 @caller14_okay_is_ub_anyways() {
385 ; CHECK-NEXT: [[R_I:%.*]] = call noundef range(i8 0, 10) i8 @val8()
386 ; CHECK-NEXT: call void @use.val(i8 [[R_I]])
387 ; CHECK-NEXT: ret i8 [[R_I]]
389 %r = call noundef range(i8 0, 10) i8 @callee14()
390 call void @use.val(i8 %r)
394 define i8 @callee15() {
395 ; CHECK-LABEL: define i8 @callee15() {
396 ; CHECK-NEXT: [[R:%.*]] = call range(i8 5, 10) i8 @val8()
397 ; CHECK-NEXT: ret i8 [[R]]
399 %r = call range(i8 5, 10) i8 @val8()
403 define i8 @caller15_okay_intersect_ranges() {
404 ; CHECK-LABEL: define i8 @caller15_okay_intersect_ranges() {
405 ; CHECK-NEXT: [[R_I:%.*]] = call range(i8 5, 7) i8 @val8()
406 ; CHECK-NEXT: call void @use.val(i8 [[R_I]])
407 ; CHECK-NEXT: ret i8 [[R_I]]
409 %r = call range(i8 0, 7) i8 @callee15()
410 call void @use.val(i8 %r)