1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes
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
6 declare void @bar1(ptr %p)
7 declare void @bar2(ptr %p, ptr %p2)
9 define dso_local void @foo1_rdonly(ptr readonly %p) {
10 ; CHECK-LABEL: define {{[^@]+}}@foo1_rdonly
11 ; CHECK-SAME: (ptr readonly [[P:%.*]]) {
12 ; CHECK-NEXT: call void @bar1(ptr [[P]])
13 ; CHECK-NEXT: ret void
15 call void @bar1(ptr %p)
19 define dso_local void @foo1(ptr %p) {
20 ; CHECK-LABEL: define {{[^@]+}}@foo1
21 ; CHECK-SAME: (ptr [[P:%.*]]) {
22 ; CHECK-NEXT: call void @bar1(ptr [[P]])
23 ; CHECK-NEXT: ret void
25 call void @bar1(ptr %p)
29 define dso_local void @foo1_bar_aligned64_deref512(ptr %p) {
30 ; CHECK-LABEL: define {{[^@]+}}@foo1_bar_aligned64_deref512
31 ; CHECK-SAME: (ptr [[P:%.*]]) {
32 ; CHECK-NEXT: call void @bar1(ptr align 64 dereferenceable(512) [[P]])
33 ; CHECK-NEXT: ret void
35 call void @bar1(ptr align 64 dereferenceable(512) %p)
39 define dso_local void @foo1_bar_aligned512_deref_or_null512(ptr %p) {
40 ; CHECK-LABEL: define {{[^@]+}}@foo1_bar_aligned512_deref_or_null512
41 ; CHECK-SAME: (ptr [[P:%.*]]) {
42 ; CHECK-NEXT: call void @bar1(ptr align 512 dereferenceable_or_null(512) [[P]])
43 ; CHECK-NEXT: ret void
45 call void @bar1(ptr align 512 dereferenceable_or_null(512) %p)
49 define dso_local void @foo2(ptr %p, ptr %p2) {
50 ; CHECK-LABEL: define {{[^@]+}}@foo2
51 ; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
52 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[P]])
53 ; CHECK-NEXT: ret void
55 call void @bar2(ptr %p, ptr %p)
59 define dso_local void @foo2_2(ptr %p, ptr %p2) {
60 ; CHECK-LABEL: define {{[^@]+}}@foo2_2
61 ; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
62 ; CHECK-NEXT: call void @bar2(ptr [[P2]], ptr [[P2]])
63 ; CHECK-NEXT: ret void
65 call void @bar2(ptr %p2, ptr %p2)
69 define dso_local void @foo2_3(ptr %p, ptr readnone %p2) {
70 ; CHECK-LABEL: define {{[^@]+}}@foo2_3
71 ; CHECK-SAME: (ptr [[P:%.*]], ptr readnone [[P2:%.*]]) {
72 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[P2]])
73 ; CHECK-NEXT: ret void
75 call void @bar2(ptr %p, ptr %p2)
79 define dso_local void @buz1_wronly(ptr %p) writeonly {
80 ; CHECK: Function Attrs: memory(write)
81 ; CHECK-LABEL: define {{[^@]+}}@buz1_wronly
82 ; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {
83 ; CHECK-NEXT: call void @bar1(ptr [[P]])
84 ; CHECK-NEXT: ret void
86 call void @bar1(ptr %p)
90 define dso_local void @buz1(ptr %p) {
91 ; CHECK-LABEL: define {{[^@]+}}@buz1
92 ; CHECK-SAME: (ptr [[P:%.*]]) {
93 ; CHECK-NEXT: call void @bar1(ptr [[P]])
94 ; CHECK-NEXT: ret void
96 call void @bar1(ptr %p)
100 define dso_local void @buz1_wronly_fail_alloca(ptr %p) writeonly {
101 ; CHECK: Function Attrs: memory(write)
102 ; CHECK-LABEL: define {{[^@]+}}@buz1_wronly_fail_alloca
103 ; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR0]] {
104 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
105 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[A]])
106 ; CHECK-NEXT: ret void
108 %a = alloca i32, align 4
109 call void @bar2(ptr %p, ptr %a)
113 define dso_local void @buz1_fail_alloca(ptr %p) {
114 ; CHECK-LABEL: define {{[^@]+}}@buz1_fail_alloca
115 ; CHECK-SAME: (ptr [[P:%.*]]) {
116 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
117 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[A]])
118 ; CHECK-NEXT: ret void
120 %a = alloca i32, align 4
121 call void @bar2(ptr %p, ptr %a)
125 define dso_local void @buz1_wronly_partially_okay_alloca(ptr %p) writeonly {
126 ; CHECK: Function Attrs: memory(write)
127 ; CHECK-LABEL: define {{[^@]+}}@buz1_wronly_partially_okay_alloca
128 ; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR0]] {
129 ; CHECK-NEXT: call void @bar1(ptr [[P]])
130 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
131 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[A]])
132 ; CHECK-NEXT: ret void
134 call void @bar1(ptr %p)
135 %a = alloca i32, align 4
136 call void @bar2(ptr %p, ptr %a)
140 define dso_local void @buz1_partially_okay_alloca(ptr %p) {
141 ; CHECK-LABEL: define {{[^@]+}}@buz1_partially_okay_alloca
142 ; CHECK-SAME: (ptr [[P:%.*]]) {
143 ; CHECK-NEXT: call void @bar1(ptr [[P]])
144 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
145 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[A]])
146 ; CHECK-NEXT: ret void
148 call void @bar1(ptr %p)
149 %a = alloca i32, align 4
150 call void @bar2(ptr %p, ptr %a)
154 define dso_local void @foo2_through_obj(ptr %p, ptr %p2) {
155 ; CHECK-LABEL: define {{[^@]+}}@foo2_through_obj
156 ; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
157 ; CHECK-NEXT: [[PP:%.*]] = getelementptr i8, ptr [[P]], i64 9
158 ; CHECK-NEXT: [[P2P:%.*]] = getelementptr i8, ptr [[P2]], i64 123
159 ; CHECK-NEXT: call void @bar2(ptr [[P2P]], ptr [[PP]])
160 ; CHECK-NEXT: ret void
162 %pp = getelementptr i8, ptr %p, i64 9
163 %p2p = getelementptr i8, ptr %p2, i64 123
164 call void @bar2(ptr %p2p, ptr %pp)
168 define void @prop_param_func_decl(ptr %p) {
169 ; CHECK-LABEL: define {{[^@]+}}@prop_param_func_decl
170 ; CHECK-SAME: (ptr [[P:%.*]]) {
171 ; CHECK-NEXT: call void @bar1(ptr [[P]])
172 ; CHECK-NEXT: ret void
174 call void @foo1_rdonly(ptr %p)
178 define void @prop_param_callbase_def(ptr %p) {
179 ; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def
180 ; CHECK-SAME: (ptr [[P:%.*]]) {
181 ; CHECK-NEXT: call void @bar1(ptr [[P]])
182 ; CHECK-NEXT: call void @bar1(ptr [[P]])
183 ; CHECK-NEXT: ret void
185 call void @foo1(ptr readonly %p)
186 call void @bar1(ptr %p)
190 define void @prop_param_callbase_def_2x(ptr %p, ptr %p2) {
191 ; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_2x
192 ; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
193 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[P]])
194 ; CHECK-NEXT: ret void
196 call void @foo2(ptr readonly %p, ptr %p)
200 define void @prop_param_callbase_def_2x_2(ptr %p, ptr %p2) {
201 ; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_2x_2
202 ; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
203 ; CHECK-NEXT: [[PP_I:%.*]] = getelementptr i8, ptr [[P]], i64 9
204 ; CHECK-NEXT: [[P2P_I:%.*]] = getelementptr i8, ptr [[P2]], i64 123
205 ; CHECK-NEXT: call void @bar2(ptr [[P2P_I]], ptr [[PP_I]])
206 ; CHECK-NEXT: ret void
208 call void @foo2_through_obj(ptr readonly %p, ptr writeonly %p2)
212 define void @prop_param_callbase_def_2x_incompat(ptr %p, ptr %p2) {
213 ; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_2x_incompat
214 ; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
215 ; CHECK-NEXT: [[PP_I:%.*]] = getelementptr i8, ptr [[P]], i64 9
216 ; CHECK-NEXT: [[P2P_I:%.*]] = getelementptr i8, ptr [[P]], i64 123
217 ; CHECK-NEXT: call void @bar2(ptr [[P2P_I]], ptr [[PP_I]])
218 ; CHECK-NEXT: ret void
220 call void @foo2_through_obj(ptr readnone %p, ptr readonly %p)
224 define void @prop_param_callbase_def_2x_incompat_2(ptr %p, ptr %p2) {
225 ; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_2x_incompat_2
226 ; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
227 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[P]])
228 ; CHECK-NEXT: ret void
230 call void @foo2(ptr readonly %p, ptr readnone %p)
234 define void @prop_param_callbase_def_2x_incompat_3(ptr %p, ptr %p2) {
235 ; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_2x_incompat_3
236 ; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
237 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[P]])
238 ; CHECK-NEXT: ret void
240 call void @foo2_2(ptr readonly %p, ptr readnone %p)
244 define void @prop_param_callbase_def_1x_partial(ptr %p, ptr %p2) {
245 ; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_1x_partial
246 ; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
247 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[P]])
248 ; CHECK-NEXT: ret void
250 call void @foo2(ptr readonly %p, ptr %p)
254 define void @prop_param_callbase_def_1x_partial_2(ptr %p, ptr %p2) {
255 ; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_1x_partial_2
256 ; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
257 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[P]])
258 ; CHECK-NEXT: ret void
260 call void @foo2_2(ptr readonly %p, ptr %p)
264 define void @prop_param_callbase_def_1x_partial_3(ptr %p, ptr %p2) {
265 ; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_1x_partial_3
266 ; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
267 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[P]])
268 ; CHECK-NEXT: ret void
270 call void @foo2_3(ptr readonly %p, ptr %p)
274 define void @prop_deref(ptr %p) {
275 ; CHECK-LABEL: define {{[^@]+}}@prop_deref
276 ; CHECK-SAME: (ptr [[P:%.*]]) {
277 ; CHECK-NEXT: call void @bar1(ptr [[P]])
278 ; CHECK-NEXT: ret void
280 call void @foo1(ptr dereferenceable(16) %p)
284 define void @prop_deref_or_null(ptr %p) {
285 ; CHECK-LABEL: define {{[^@]+}}@prop_deref_or_null
286 ; CHECK-SAME: (ptr [[P:%.*]]) {
287 ; CHECK-NEXT: call void @bar1(ptr [[P]])
288 ; CHECK-NEXT: ret void
290 call void @foo1(ptr dereferenceable_or_null(256) %p)
294 define void @prop_param_nonnull_and_align(ptr %p) {
295 ; CHECK-LABEL: define {{[^@]+}}@prop_param_nonnull_and_align
296 ; CHECK-SAME: (ptr [[P:%.*]]) {
297 ; CHECK-NEXT: call void @bar1(ptr [[P]])
298 ; CHECK-NEXT: ret void
300 call void @foo1(ptr nonnull align 32 %p)
304 define void @prop_param_deref_align_no_update(ptr %p) {
305 ; CHECK-LABEL: define {{[^@]+}}@prop_param_deref_align_no_update
306 ; CHECK-SAME: (ptr [[P:%.*]]) {
307 ; CHECK-NEXT: call void @bar1(ptr align 64 dereferenceable(512) [[P]])
308 ; CHECK-NEXT: ret void
310 call void @foo1_bar_aligned64_deref512(ptr align 4 dereferenceable(64) %p)
314 define void @prop_param_deref_align_update(ptr %p) {
315 ; CHECK-LABEL: define {{[^@]+}}@prop_param_deref_align_update
316 ; CHECK-SAME: (ptr [[P:%.*]]) {
317 ; CHECK-NEXT: call void @bar1(ptr align 64 dereferenceable(512) [[P]])
318 ; CHECK-NEXT: ret void
320 call void @foo1_bar_aligned64_deref512(ptr align 128 dereferenceable(1024) %p)
324 define void @prop_param_deref_or_null_update(ptr %p) {
325 ; CHECK-LABEL: define {{[^@]+}}@prop_param_deref_or_null_update
326 ; CHECK-SAME: (ptr [[P:%.*]]) {
327 ; CHECK-NEXT: call void @bar1(ptr align 512 dereferenceable_or_null(512) [[P]])
328 ; CHECK-NEXT: ret void
330 call void @foo1_bar_aligned512_deref_or_null512(ptr dereferenceable_or_null(1024) %p)
334 define void @prop_param_deref_or_null_no_update(ptr %p) {
335 ; CHECK-LABEL: define {{[^@]+}}@prop_param_deref_or_null_no_update
336 ; CHECK-SAME: (ptr [[P:%.*]]) {
337 ; CHECK-NEXT: call void @bar1(ptr align 512 dereferenceable_or_null(512) [[P]])
338 ; CHECK-NEXT: ret void
340 call void @foo1_bar_aligned512_deref_or_null512(ptr dereferenceable_or_null(32) %p)
344 define void @prop_fn_decl(ptr %p) {
345 ; CHECK-LABEL: define {{[^@]+}}@prop_fn_decl
346 ; CHECK-SAME: (ptr [[P:%.*]]) {
347 ; CHECK-NEXT: call void @bar1(ptr [[P]])
348 ; CHECK-NEXT: call void @bar1(ptr [[P]])
349 ; CHECK-NEXT: ret void
351 call void @buz1_wronly(ptr %p)
352 call void @bar1(ptr %p)
356 define void @prop_cb_def_wr(ptr %p) {
357 ; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_wr
358 ; CHECK-SAME: (ptr [[P:%.*]]) {
359 ; CHECK-NEXT: call void @bar1(ptr [[P]])
360 ; CHECK-NEXT: call void @bar1(ptr [[P]])
361 ; CHECK-NEXT: ret void
363 call void @buz1(ptr %p) writeonly
364 call void @bar1(ptr %p)
368 define void @prop_fn_decl_fail_alloca(ptr %p) {
369 ; CHECK-LABEL: define {{[^@]+}}@prop_fn_decl_fail_alloca
370 ; CHECK-SAME: (ptr [[P:%.*]]) {
371 ; CHECK-NEXT: [[A_I:%.*]] = alloca i32, align 4
372 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[A_I]])
373 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[A_I]])
374 ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[A_I]])
375 ; CHECK-NEXT: call void @bar1(ptr [[P]])
376 ; CHECK-NEXT: ret void
378 call void @buz1_wronly_fail_alloca(ptr %p)
379 call void @bar1(ptr %p)
383 define void @prop_cb_def_wr_fail_alloca(ptr %p) {
384 ; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_wr_fail_alloca
385 ; CHECK-SAME: (ptr [[P:%.*]]) {
386 ; CHECK-NEXT: [[A_I:%.*]] = alloca i32, align 4
387 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[A_I]])
388 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[A_I]])
389 ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[A_I]])
390 ; CHECK-NEXT: call void @bar1(ptr [[P]])
391 ; CHECK-NEXT: ret void
393 call void @buz1_fail_alloca(ptr %p) writeonly
394 call void @bar1(ptr %p)
398 define void @prop_fn_decl_partially_okay_alloca(ptr %p) {
399 ; CHECK-LABEL: define {{[^@]+}}@prop_fn_decl_partially_okay_alloca
400 ; CHECK-SAME: (ptr [[P:%.*]]) {
401 ; CHECK-NEXT: [[A_I:%.*]] = alloca i32, align 4
402 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[A_I]])
403 ; CHECK-NEXT: call void @bar1(ptr [[P]])
404 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[A_I]])
405 ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[A_I]])
406 ; CHECK-NEXT: call void @bar1(ptr [[P]])
407 ; CHECK-NEXT: ret void
409 call void @buz1_wronly_partially_okay_alloca(ptr %p)
410 call void @bar1(ptr %p)
414 define void @prop_cb_def_wr_partially_okay_alloca(ptr %p) {
415 ; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_wr_partially_okay_alloca
416 ; CHECK-SAME: (ptr [[P:%.*]]) {
417 ; CHECK-NEXT: [[A_I:%.*]] = alloca i32, align 4
418 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[A_I]])
419 ; CHECK-NEXT: call void @bar1(ptr [[P]])
420 ; CHECK-NEXT: call void @bar2(ptr [[P]], ptr [[A_I]])
421 ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[A_I]])
422 ; CHECK-NEXT: call void @bar1(ptr [[P]])
423 ; CHECK-NEXT: ret void
425 call void @buz1_partially_okay_alloca(ptr %p) writeonly
426 call void @bar1(ptr %p)
430 define void @prop_cb_def_readonly(ptr %p) {
431 ; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_readonly
432 ; CHECK-SAME: (ptr [[P:%.*]]) {
433 ; CHECK-NEXT: call void @bar1(ptr [[P]])
434 ; CHECK-NEXT: ret void
436 call void @foo1(ptr %p) readonly
440 define void @prop_cb_def_readnone(ptr %p) {
441 ; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_readnone
442 ; CHECK-SAME: (ptr [[P:%.*]]) {
443 ; CHECK-NEXT: call void @bar1(ptr [[P]])
444 ; CHECK-NEXT: ret void
446 call void @foo1(ptr %p) readnone
450 define void @prop_cb_def_argmem_readonly_fail(ptr %p) {
451 ; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_argmem_readonly_fail
452 ; CHECK-SAME: (ptr [[P:%.*]]) {
453 ; CHECK-NEXT: call void @bar1(ptr [[P]])
454 ; CHECK-NEXT: ret void
456 call void @foo1(ptr %p) memory(argmem:read)
460 define void @prop_cb_def_inaccessible_none(ptr %p) {
461 ; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_inaccessible_none
462 ; CHECK-SAME: (ptr [[P:%.*]]) {
463 ; CHECK-NEXT: call void @bar1(ptr [[P]])
464 ; CHECK-NEXT: ret void
466 call void @foo1(ptr %p) memory(inaccessiblemem:none)
470 define void @prop_cb_def_inaccessible_none_argmem_none(ptr %p) {
471 ; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_inaccessible_none_argmem_none
472 ; CHECK-SAME: (ptr [[P:%.*]]) {
473 ; CHECK-NEXT: call void @bar1(ptr [[P]])
474 ; CHECK-NEXT: ret void
476 call void @foo1(ptr %p) memory(inaccessiblemem:none, argmem:none)
480 define void @prop_cb_def_willreturn(ptr %p) {
481 ; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_willreturn
482 ; CHECK-SAME: (ptr [[P:%.*]]) {
483 ; CHECK-NEXT: call void @bar1(ptr [[P]])
484 ; CHECK-NEXT: ret void
486 call void @foo1(ptr %p) willreturn
490 define void @prop_cb_def_mustprogress(ptr %p) {
491 ; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_mustprogress
492 ; CHECK-SAME: (ptr [[P:%.*]]) {
493 ; CHECK-NEXT: call void @bar1(ptr [[P]])
494 ; CHECK-NEXT: ret void
496 call void @foo1(ptr %p) mustprogress