xref: /llvm-project/llvm/test/Transforms/Inline/access-attributes-prop.ll (revision 69a798a996e0cd9d521db38167cadf841d629d38)
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
5
6declare void @bar1(ptr %p)
7declare void @bar2(ptr %p, ptr %p2)
8declare void @bar3(ptr writable %p)
9declare void @bar4(ptr byval([4 x i32]) %p)
10define dso_local void @foo1_rdonly(ptr readonly %p) {
11; CHECK-LABEL: define {{[^@]+}}@foo1_rdonly
12; CHECK-SAME: (ptr readonly [[P:%.*]]) {
13; CHECK-NEXT:    call void @bar1(ptr [[P]])
14; CHECK-NEXT:    ret void
15;
16  call void @bar1(ptr %p)
17  ret void
18}
19
20define dso_local void @foo1(ptr %p) {
21; CHECK-LABEL: define {{[^@]+}}@foo1
22; CHECK-SAME: (ptr [[P:%.*]]) {
23; CHECK-NEXT:    call void @bar1(ptr [[P]])
24; CHECK-NEXT:    ret void
25;
26  call void @bar1(ptr %p)
27  ret void
28}
29
30define dso_local void @foo1_writable(ptr %p) {
31; CHECK-LABEL: define {{[^@]+}}@foo1_writable
32; CHECK-SAME: (ptr [[P:%.*]]) {
33; CHECK-NEXT:    call void @bar1(ptr writable [[P]])
34; CHECK-NEXT:    ret void
35;
36  call void @bar1(ptr writable %p)
37  ret void
38}
39
40define dso_local void @foo3_writable(ptr %p) {
41; CHECK-LABEL: define {{[^@]+}}@foo3_writable
42; CHECK-SAME: (ptr [[P:%.*]]) {
43; CHECK-NEXT:    call void @bar3(ptr [[P]])
44; CHECK-NEXT:    ret void
45;
46  call void @bar3(ptr %p)
47  ret void
48}
49
50define dso_local void @foo1_bar_aligned64_deref512(ptr %p) {
51; CHECK-LABEL: define {{[^@]+}}@foo1_bar_aligned64_deref512
52; CHECK-SAME: (ptr [[P:%.*]]) {
53; CHECK-NEXT:    call void @bar1(ptr align 64 dereferenceable(512) [[P]])
54; CHECK-NEXT:    ret void
55;
56  call void @bar1(ptr align 64 dereferenceable(512) %p)
57  ret void
58}
59
60define dso_local void @foo1_bar_aligned512_deref_or_null512(ptr %p) {
61; CHECK-LABEL: define {{[^@]+}}@foo1_bar_aligned512_deref_or_null512
62; CHECK-SAME: (ptr [[P:%.*]]) {
63; CHECK-NEXT:    call void @bar1(ptr align 512 dereferenceable_or_null(512) [[P]])
64; CHECK-NEXT:    ret void
65;
66  call void @bar1(ptr align 512 dereferenceable_or_null(512) %p)
67  ret void
68}
69
70define dso_local void @foo2(ptr %p, ptr %p2) {
71; CHECK-LABEL: define {{[^@]+}}@foo2
72; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
73; CHECK-NEXT:    call void @bar2(ptr [[P]], ptr [[P]])
74; CHECK-NEXT:    ret void
75;
76  call void @bar2(ptr %p, ptr %p)
77  ret void
78}
79
80define dso_local void @foo2_2(ptr %p, ptr %p2) {
81; CHECK-LABEL: define {{[^@]+}}@foo2_2
82; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
83; CHECK-NEXT:    call void @bar2(ptr [[P2]], ptr [[P2]])
84; CHECK-NEXT:    ret void
85;
86  call void @bar2(ptr %p2, ptr %p2)
87  ret void
88}
89
90define dso_local void @foo2_3(ptr %p, ptr readnone %p2) {
91; CHECK-LABEL: define {{[^@]+}}@foo2_3
92; CHECK-SAME: (ptr [[P:%.*]], ptr readnone [[P2:%.*]]) {
93; CHECK-NEXT:    call void @bar2(ptr [[P]], ptr [[P2]])
94; CHECK-NEXT:    ret void
95;
96  call void @bar2(ptr %p, ptr %p2)
97  ret void
98}
99
100define dso_local void @buz1_wronly(ptr %p) writeonly {
101; CHECK: Function Attrs: memory(write)
102; CHECK-LABEL: define {{[^@]+}}@buz1_wronly
103; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {
104; CHECK-NEXT:    call void @bar1(ptr [[P]])
105; CHECK-NEXT:    ret void
106;
107  call void @bar1(ptr %p)
108  ret void
109}
110
111define dso_local void @buz1(ptr %p) {
112; CHECK-LABEL: define {{[^@]+}}@buz1
113; CHECK-SAME: (ptr [[P:%.*]]) {
114; CHECK-NEXT:    call void @bar1(ptr [[P]])
115; CHECK-NEXT:    ret void
116;
117  call void @bar1(ptr %p)
118  ret void
119}
120
121define dso_local void @buz1_wronly_fail_alloca(ptr %p) writeonly {
122; CHECK: Function Attrs: memory(write)
123; CHECK-LABEL: define {{[^@]+}}@buz1_wronly_fail_alloca
124; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR0]] {
125; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
126; CHECK-NEXT:    call void @bar2(ptr [[P]], ptr [[A]])
127; CHECK-NEXT:    ret void
128;
129  %a = alloca i32, align 4
130  call void @bar2(ptr %p, ptr %a)
131  ret void
132}
133
134define dso_local void @buz1_fail_alloca(ptr %p) {
135; CHECK-LABEL: define {{[^@]+}}@buz1_fail_alloca
136; CHECK-SAME: (ptr [[P:%.*]]) {
137; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
138; CHECK-NEXT:    call void @bar2(ptr [[P]], ptr [[A]])
139; CHECK-NEXT:    ret void
140;
141  %a = alloca i32, align 4
142  call void @bar2(ptr %p, ptr %a)
143  ret void
144}
145
146define dso_local void @buz1_wronly_partially_okay_alloca(ptr %p) writeonly {
147; CHECK: Function Attrs: memory(write)
148; CHECK-LABEL: define {{[^@]+}}@buz1_wronly_partially_okay_alloca
149; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR0]] {
150; CHECK-NEXT:    call void @bar1(ptr [[P]])
151; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
152; CHECK-NEXT:    call void @bar2(ptr [[P]], ptr [[A]])
153; CHECK-NEXT:    ret void
154;
155  call void @bar1(ptr %p)
156  %a = alloca i32, align 4
157  call void @bar2(ptr %p, ptr %a)
158  ret void
159}
160
161define dso_local void @buz1_partially_okay_alloca(ptr %p) {
162; CHECK-LABEL: define {{[^@]+}}@buz1_partially_okay_alloca
163; CHECK-SAME: (ptr [[P:%.*]]) {
164; CHECK-NEXT:    call void @bar1(ptr [[P]])
165; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
166; CHECK-NEXT:    call void @bar2(ptr [[P]], ptr [[A]])
167; CHECK-NEXT:    ret void
168;
169  call void @bar1(ptr %p)
170  %a = alloca i32, align 4
171  call void @bar2(ptr %p, ptr %a)
172  ret void
173}
174
175define dso_local void @foo2_through_obj(ptr %p, ptr %p2) {
176; CHECK-LABEL: define {{[^@]+}}@foo2_through_obj
177; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
178; CHECK-NEXT:    [[PP:%.*]] = getelementptr i8, ptr [[P]], i64 9
179; CHECK-NEXT:    [[P2P:%.*]] = getelementptr i8, ptr [[P2]], i64 123
180; CHECK-NEXT:    call void @bar2(ptr [[P2P]], ptr [[PP]])
181; CHECK-NEXT:    ret void
182;
183  %pp = getelementptr i8, ptr %p, i64 9
184  %p2p = getelementptr i8, ptr %p2, i64 123
185  call void @bar2(ptr %p2p, ptr %pp)
186  ret void
187}
188
189define dso_local void @foo_byval_readonly(ptr readonly %p) {
190; CHECK-LABEL: define {{[^@]+}}@foo_byval_readonly
191; CHECK-SAME: (ptr readonly [[P:%.*]]) {
192; CHECK-NEXT:    call void @bar4(ptr byval([4 x i32]) [[P]])
193; CHECK-NEXT:    ret void
194;
195  call void @bar4(ptr byval([4 x i32]) %p)
196  ret void
197}
198
199define void @prop_param_func_decl(ptr %p) {
200; CHECK-LABEL: define {{[^@]+}}@prop_param_func_decl
201; CHECK-SAME: (ptr [[P:%.*]]) {
202; CHECK-NEXT:    call void @bar1(ptr readonly [[P]])
203; CHECK-NEXT:    ret void
204;
205  call void @foo1_rdonly(ptr %p)
206  ret void
207}
208
209define void @prop_param_callbase_def(ptr %p) {
210; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def
211; CHECK-SAME: (ptr [[P:%.*]]) {
212; CHECK-NEXT:    call void @bar1(ptr readonly [[P]])
213; CHECK-NEXT:    call void @bar1(ptr [[P]])
214; CHECK-NEXT:    ret void
215;
216  call void @foo1(ptr readonly %p)
217  call void @bar1(ptr %p)
218  ret void
219}
220
221define void @prop_param_callbase_def_2x(ptr %p, ptr %p2) {
222; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_2x
223; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
224; CHECK-NEXT:    call void @bar2(ptr readonly [[P]], ptr readonly [[P]])
225; CHECK-NEXT:    ret void
226;
227  call void @foo2(ptr readonly %p, ptr %p)
228  ret void
229}
230
231define void @prop_param_callbase_def_2x_2(ptr %p, ptr %p2) {
232; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_2x_2
233; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
234; CHECK-NEXT:    [[PP_I:%.*]] = getelementptr i8, ptr [[P]], i64 9
235; CHECK-NEXT:    [[P2P_I:%.*]] = getelementptr i8, ptr [[P2]], i64 123
236; CHECK-NEXT:    call void @bar2(ptr [[P2P_I]], ptr readonly [[PP_I]])
237; CHECK-NEXT:    ret void
238;
239  call void @foo2_through_obj(ptr readonly %p, ptr writeonly %p2)
240  ret void
241}
242
243define void @prop_param_callbase_def_2x_incompat(ptr %p, ptr %p2) {
244; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_2x_incompat
245; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
246; CHECK-NEXT:    [[PP_I:%.*]] = getelementptr i8, ptr [[P]], i64 9
247; CHECK-NEXT:    [[P2P_I:%.*]] = getelementptr i8, ptr [[P]], i64 123
248; CHECK-NEXT:    call void @bar2(ptr readonly [[P2P_I]], ptr readnone [[PP_I]])
249; CHECK-NEXT:    ret void
250;
251  call void @foo2_through_obj(ptr readnone %p, ptr readonly %p)
252  ret void
253}
254
255define void @prop_param_callbase_def_2x_incompat_2(ptr %p, ptr %p2) {
256; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_2x_incompat_2
257; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
258; CHECK-NEXT:    call void @bar2(ptr readonly [[P]], ptr readonly [[P]])
259; CHECK-NEXT:    ret void
260;
261  call void @foo2(ptr readonly %p, ptr readnone %p)
262  ret void
263}
264
265define void @prop_param_callbase_def_2x_incompat_3(ptr %p, ptr %p2) {
266; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_2x_incompat_3
267; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
268; CHECK-NEXT:    call void @bar2(ptr readnone [[P]], ptr readnone [[P]])
269; CHECK-NEXT:    ret void
270;
271  call void @foo2_2(ptr readonly %p, ptr readnone %p)
272  ret void
273}
274
275define void @prop_param_callbase_def_1x_partial(ptr %p, ptr %p2) {
276; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_1x_partial
277; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
278; CHECK-NEXT:    call void @bar2(ptr readonly [[P]], ptr readonly [[P]])
279; CHECK-NEXT:    ret void
280;
281  call void @foo2(ptr readonly %p, ptr %p)
282  ret void
283}
284
285define void @prop_param_callbase_def_1x_partial_2(ptr %p, ptr %p2) {
286; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_1x_partial_2
287; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
288; CHECK-NEXT:    call void @bar2(ptr [[P]], ptr [[P]])
289; CHECK-NEXT:    ret void
290;
291  call void @foo2_2(ptr readonly %p, ptr %p)
292  ret void
293}
294
295define void @prop_param_callbase_def_1x_partial_3(ptr %p, ptr %p2) {
296; CHECK-LABEL: define {{[^@]+}}@prop_param_callbase_def_1x_partial_3
297; CHECK-SAME: (ptr [[P:%.*]], ptr [[P2:%.*]]) {
298; CHECK-NEXT:    call void @bar2(ptr readonly [[P]], ptr readnone [[P]])
299; CHECK-NEXT:    ret void
300;
301  call void @foo2_3(ptr readonly %p, ptr %p)
302  ret void
303}
304
305define void @prop_deref(ptr %p) {
306; CHECK-LABEL: define {{[^@]+}}@prop_deref
307; CHECK-SAME: (ptr [[P:%.*]]) {
308; CHECK-NEXT:    call void @bar1(ptr dereferenceable(16) [[P]])
309; CHECK-NEXT:    ret void
310;
311  call void @foo1(ptr dereferenceable(16) %p)
312  ret void
313}
314
315define void @prop_deref_or_null(ptr %p) {
316; CHECK-LABEL: define {{[^@]+}}@prop_deref_or_null
317; CHECK-SAME: (ptr [[P:%.*]]) {
318; CHECK-NEXT:    call void @bar1(ptr dereferenceable_or_null(256) [[P]])
319; CHECK-NEXT:    ret void
320;
321  call void @foo1(ptr dereferenceable_or_null(256) %p)
322  ret void
323}
324
325define void @prop_param_nonnull_and_align(ptr %p) {
326; CHECK-LABEL: define {{[^@]+}}@prop_param_nonnull_and_align
327; CHECK-SAME: (ptr [[P:%.*]]) {
328; CHECK-NEXT:    call void @bar1(ptr nonnull align 32 [[P]])
329; CHECK-NEXT:    ret void
330;
331  call void @foo1(ptr nonnull align 32 %p)
332  ret void
333}
334
335define void @prop_param_nofree_and_align(ptr %p) {
336; CHECK-LABEL: define {{[^@]+}}@prop_param_nofree_and_align
337; CHECK-SAME: (ptr [[P:%.*]]) {
338; CHECK-NEXT:    call void @bar1(ptr align 32 [[P]])
339; CHECK-NEXT:    ret void
340;
341  call void @foo1(ptr nofree align 32 %p)
342  ret void
343}
344
345define void @prop_param_deref_align_no_update(ptr %p) {
346; CHECK-LABEL: define {{[^@]+}}@prop_param_deref_align_no_update
347; CHECK-SAME: (ptr [[P:%.*]]) {
348; CHECK-NEXT:    call void @bar1(ptr align 64 dereferenceable(512) [[P]])
349; CHECK-NEXT:    ret void
350;
351  call void @foo1_bar_aligned64_deref512(ptr align 4 dereferenceable(64) %p)
352  ret void
353}
354
355define void @prop_param_deref_align_update(ptr %p) {
356; CHECK-LABEL: define {{[^@]+}}@prop_param_deref_align_update
357; CHECK-SAME: (ptr [[P:%.*]]) {
358; CHECK-NEXT:    call void @bar1(ptr align 128 dereferenceable(1024) [[P]])
359; CHECK-NEXT:    ret void
360;
361  call void @foo1_bar_aligned64_deref512(ptr align 128 dereferenceable(1024) %p)
362  ret void
363}
364
365define void @prop_param_deref_or_null_update(ptr %p) {
366; CHECK-LABEL: define {{[^@]+}}@prop_param_deref_or_null_update
367; CHECK-SAME: (ptr [[P:%.*]]) {
368; CHECK-NEXT:    call void @bar1(ptr align 512 dereferenceable_or_null(1024) [[P]])
369; CHECK-NEXT:    ret void
370;
371  call void @foo1_bar_aligned512_deref_or_null512(ptr dereferenceable_or_null(1024) %p)
372  ret void
373}
374
375define void @prop_param_deref_or_null_no_update(ptr %p) {
376; CHECK-LABEL: define {{[^@]+}}@prop_param_deref_or_null_no_update
377; CHECK-SAME: (ptr [[P:%.*]]) {
378; CHECK-NEXT:    call void @bar1(ptr align 512 dereferenceable_or_null(512) [[P]])
379; CHECK-NEXT:    ret void
380;
381  call void @foo1_bar_aligned512_deref_or_null512(ptr dereferenceable_or_null(32) %p)
382  ret void
383}
384
385define void @prop_fn_decl(ptr %p) {
386; CHECK-LABEL: define {{[^@]+}}@prop_fn_decl
387; CHECK-SAME: (ptr [[P:%.*]]) {
388; CHECK-NEXT:    call void @bar1(ptr [[P]])
389; CHECK-NEXT:    call void @bar1(ptr [[P]])
390; CHECK-NEXT:    ret void
391;
392  call void @buz1_wronly(ptr %p)
393  call void @bar1(ptr %p)
394  ret void
395}
396
397define void @prop_cb_def_wr(ptr %p) {
398; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_wr
399; CHECK-SAME: (ptr [[P:%.*]]) {
400; CHECK-NEXT:    call void @bar1(ptr [[P]])
401; CHECK-NEXT:    call void @bar1(ptr [[P]])
402; CHECK-NEXT:    ret void
403;
404  call void @buz1(ptr %p) writeonly
405  call void @bar1(ptr %p)
406  ret void
407}
408
409define void @prop_fn_decl_fail_alloca(ptr %p) {
410; CHECK-LABEL: define {{[^@]+}}@prop_fn_decl_fail_alloca
411; CHECK-SAME: (ptr [[P:%.*]]) {
412; CHECK-NEXT:    [[A_I:%.*]] = alloca i32, align 4
413; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[A_I]])
414; CHECK-NEXT:    call void @bar2(ptr [[P]], ptr [[A_I]])
415; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[A_I]])
416; CHECK-NEXT:    call void @bar1(ptr [[P]])
417; CHECK-NEXT:    ret void
418;
419  call void @buz1_wronly_fail_alloca(ptr %p)
420  call void @bar1(ptr %p)
421  ret void
422}
423
424define void @prop_cb_def_wr_fail_alloca(ptr %p) {
425; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_wr_fail_alloca
426; CHECK-SAME: (ptr [[P:%.*]]) {
427; CHECK-NEXT:    [[A_I:%.*]] = alloca i32, align 4
428; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[A_I]])
429; CHECK-NEXT:    call void @bar2(ptr [[P]], ptr [[A_I]])
430; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[A_I]])
431; CHECK-NEXT:    call void @bar1(ptr [[P]])
432; CHECK-NEXT:    ret void
433;
434  call void @buz1_fail_alloca(ptr %p) writeonly
435  call void @bar1(ptr %p)
436  ret void
437}
438
439define void @prop_fn_decl_partially_okay_alloca(ptr %p) {
440; CHECK-LABEL: define {{[^@]+}}@prop_fn_decl_partially_okay_alloca
441; CHECK-SAME: (ptr [[P:%.*]]) {
442; CHECK-NEXT:    [[A_I:%.*]] = alloca i32, align 4
443; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[A_I]])
444; CHECK-NEXT:    call void @bar1(ptr [[P]])
445; CHECK-NEXT:    call void @bar2(ptr [[P]], ptr [[A_I]])
446; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[A_I]])
447; CHECK-NEXT:    call void @bar1(ptr [[P]])
448; CHECK-NEXT:    ret void
449;
450  call void @buz1_wronly_partially_okay_alloca(ptr %p)
451  call void @bar1(ptr %p)
452  ret void
453}
454
455define void @prop_cb_def_wr_partially_okay_alloca(ptr %p) {
456; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_wr_partially_okay_alloca
457; CHECK-SAME: (ptr [[P:%.*]]) {
458; CHECK-NEXT:    [[A_I:%.*]] = alloca i32, align 4
459; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[A_I]])
460; CHECK-NEXT:    call void @bar1(ptr [[P]])
461; CHECK-NEXT:    call void @bar2(ptr [[P]], ptr [[A_I]])
462; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[A_I]])
463; CHECK-NEXT:    call void @bar1(ptr [[P]])
464; CHECK-NEXT:    ret void
465;
466  call void @buz1_partially_okay_alloca(ptr %p) writeonly
467  call void @bar1(ptr %p)
468  ret void
469}
470
471define void @prop_cb_def_readonly(ptr %p) {
472; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_readonly
473; CHECK-SAME: (ptr [[P:%.*]]) {
474; CHECK-NEXT:    call void @bar1(ptr [[P]])
475; CHECK-NEXT:    ret void
476;
477  call void @foo1(ptr %p) readonly
478  ret void
479}
480
481define void @prop_cb_def_readnone(ptr %p) {
482; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_readnone
483; CHECK-SAME: (ptr [[P:%.*]]) {
484; CHECK-NEXT:    call void @bar1(ptr [[P]])
485; CHECK-NEXT:    ret void
486;
487  call void @foo1(ptr %p) readnone
488  ret void
489}
490
491define void @prop_cb_def_argmem_readonly_fail(ptr %p) {
492; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_argmem_readonly_fail
493; CHECK-SAME: (ptr [[P:%.*]]) {
494; CHECK-NEXT:    call void @bar1(ptr [[P]])
495; CHECK-NEXT:    ret void
496;
497  call void @foo1(ptr %p) memory(argmem:read)
498  ret void
499}
500
501define void @prop_cb_def_inaccessible_none(ptr %p) {
502; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_inaccessible_none
503; CHECK-SAME: (ptr [[P:%.*]]) {
504; CHECK-NEXT:    call void @bar1(ptr [[P]])
505; CHECK-NEXT:    ret void
506;
507  call void @foo1(ptr %p) memory(inaccessiblemem:none)
508  ret void
509}
510
511define void @prop_cb_def_inaccessible_none_argmem_none(ptr %p) {
512; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_inaccessible_none_argmem_none
513; CHECK-SAME: (ptr [[P:%.*]]) {
514; CHECK-NEXT:    call void @bar1(ptr [[P]])
515; CHECK-NEXT:    ret void
516;
517  call void @foo1(ptr %p) memory(inaccessiblemem:none, argmem:none)
518  ret void
519}
520
521define void @prop_cb_def_willreturn(ptr %p) {
522; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_willreturn
523; CHECK-SAME: (ptr [[P:%.*]]) {
524; CHECK-NEXT:    call void @bar1(ptr [[P]])
525; CHECK-NEXT:    ret void
526;
527  call void @foo1(ptr %p) willreturn
528  ret void
529}
530
531define void @prop_cb_def_mustprogress(ptr %p) {
532; CHECK-LABEL: define {{[^@]+}}@prop_cb_def_mustprogress
533; CHECK-SAME: (ptr [[P:%.*]]) {
534; CHECK-NEXT:    call void @bar1(ptr [[P]])
535; CHECK-NEXT:    ret void
536;
537  call void @foo1(ptr %p) mustprogress
538  ret void
539}
540
541define void @prop_no_conflict_writable(ptr %p) {
542; CHECK-LABEL: define {{[^@]+}}@prop_no_conflict_writable
543; CHECK-SAME: (ptr [[P:%.*]]) {
544; CHECK-NEXT:    call void @bar1(ptr readonly [[P]])
545; CHECK-NEXT:    ret void
546;
547  call void @foo1_writable(ptr readonly %p)
548  ret void
549}
550
551define void @prop_no_conflict_writable2(ptr %p) {
552; CHECK-LABEL: define {{[^@]+}}@prop_no_conflict_writable2
553; CHECK-SAME: (ptr [[P:%.*]]) {
554; CHECK-NEXT:    call void @bar3(ptr readnone [[P]])
555; CHECK-NEXT:    ret void
556;
557  call void @foo3_writable(ptr readnone %p)
558  ret void
559}
560
561define void @prop_byval_readonly(ptr %p) {
562; CHECK-LABEL: define {{[^@]+}}@prop_byval_readonly
563; CHECK-SAME: (ptr [[P:%.*]]) {
564; CHECK-NEXT:    call void @bar4(ptr byval([4 x i32]) [[P]])
565; CHECK-NEXT:    ret void
566;
567  call void @foo_byval_readonly(ptr %p)
568  ret void
569}
570
571define ptr @caller_bad_param_prop(ptr %p1, ptr %p2, i64 %x) {
572; CHECK-LABEL: define {{[^@]+}}@caller_bad_param_prop
573; CHECK-SAME: (ptr [[P1:%.*]], ptr [[P2:%.*]], i64 [[X:%.*]]) {
574; CHECK-NEXT:    [[TMP1:%.*]] = call ptr [[P1]](i64 [[X]], ptr [[P2]])
575; CHECK-NEXT:    ret ptr [[TMP1]]
576;
577  %1 = call ptr %p1(i64 %x, ptr %p2)
578  %2 = call ptr @callee_bad_param_prop(ptr %1)
579  ret ptr %2
580}
581
582define ptr @callee_bad_param_prop(ptr readonly %x) {
583; CHECK-LABEL: define {{[^@]+}}@callee_bad_param_prop
584; CHECK-SAME: (ptr readonly [[X:%.*]]) {
585; CHECK-NEXT:    [[R:%.*]] = tail call ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 -1)
586; CHECK-NEXT:    ret ptr [[R]]
587;
588  %r = tail call ptr @llvm.ptrmask(ptr %x, i64 -1)
589  ret ptr %r
590}
591
592define dso_local void @foo_byval_readonly2(ptr readonly %p) {
593; CHECK-LABEL: define {{[^@]+}}@foo_byval_readonly2
594; CHECK-SAME: (ptr readonly [[P:%.*]]) {
595; CHECK-NEXT:    call void @bar4(ptr [[P]])
596; CHECK-NEXT:    ret void
597;
598  call void @bar4(ptr %p)
599  ret void
600}
601
602define void @prop_byval_readonly2(ptr %p) {
603; CHECK-LABEL: define {{[^@]+}}@prop_byval_readonly2
604; CHECK-SAME: (ptr [[P:%.*]]) {
605; CHECK-NEXT:    call void @bar4(ptr [[P]])
606; CHECK-NEXT:    ret void
607;
608  call void @foo_byval_readonly2(ptr %p)
609  ret void
610}
611
612declare void @bar5(i32)
613
614define dso_local void @foo4_range_0_10(i32 %v) {
615; CHECK-LABEL: define {{[^@]+}}@foo4_range_0_10
616; CHECK-SAME: (i32 [[V:%.*]]) {
617; CHECK-NEXT:    call void @bar5(i32 range(i32 0, 10) [[V]])
618; CHECK-NEXT:    ret void
619;
620  call void @bar5(i32 range(i32 0, 10) %v)
621  ret void
622}
623
624define dso_local void @foo4_range_10_40(i32 %v) {
625; CHECK-LABEL: define {{[^@]+}}@foo4_range_10_40
626; CHECK-SAME: (i32 [[V:%.*]]) {
627; CHECK-NEXT:    call void @bar5(i32 range(i32 10, 40) [[V]])
628; CHECK-NEXT:    ret void
629;
630  call void @bar5(i32 range(i32 10, 40) %v)
631  ret void
632}
633
634define dso_local void @foo4_2_range_0_10(i32 range(i32 0, 10) %v) {
635; CHECK-LABEL: define {{[^@]+}}@foo4_2_range_0_10
636; CHECK-SAME: (i32 range(i32 0, 10) [[V:%.*]]) {
637; CHECK-NEXT:    call void @bar5(i32 [[V]])
638; CHECK-NEXT:    ret void
639;
640  call void @bar5(i32 %v)
641  ret void
642}
643
644define dso_local void @foo4(i32 %v) {
645; CHECK-LABEL: define {{[^@]+}}@foo4
646; CHECK-SAME: (i32 [[V:%.*]]) {
647; CHECK-NEXT:    call void @bar5(i32 [[V]])
648; CHECK-NEXT:    ret void
649;
650  call void @bar5(i32 %v)
651  ret void
652}
653
654define void @prop_range_empty_intersect(i32 %v) {
655; CHECK-LABEL: define {{[^@]+}}@prop_range_empty_intersect
656; CHECK-SAME: (i32 [[V:%.*]]) {
657; CHECK-NEXT:    call void @bar5(i32 range(i32 0, 0) [[V]])
658; CHECK-NEXT:    ret void
659;
660  call void @foo4_range_0_10(i32 range(i32 11, 50) %v)
661  ret void
662}
663
664define void @prop_range_empty(i32 %v) {
665; CHECK-LABEL: define {{[^@]+}}@prop_range_empty
666; CHECK-SAME: (i32 [[V:%.*]]) {
667; CHECK-NEXT:    call void @bar5(i32 range(i32 1, 0) [[V]])
668; CHECK-NEXT:    ret void
669;
670  call void @foo4(i32 range(i32 1, 0) %v)
671  ret void
672}
673
674define void @prop_range_empty_with_intersect(i32 %v) {
675; CHECK-LABEL: define {{[^@]+}}@prop_range_empty_with_intersect
676; CHECK-SAME: (i32 [[V:%.*]]) {
677; CHECK-NEXT:    call void @bar5(i32 range(i32 1, 10) [[V]])
678; CHECK-NEXT:    ret void
679;
680  call void @foo4_range_0_10(i32 range(i32 1, 0) %v)
681  ret void
682}
683
684define void @prop_range_intersect1(i32 %v) {
685; CHECK-LABEL: define {{[^@]+}}@prop_range_intersect1
686; CHECK-SAME: (i32 [[V:%.*]]) {
687; CHECK-NEXT:    call void @bar5(i32 range(i32 0, 9) [[V]])
688; CHECK-NEXT:    ret void
689;
690  call void @foo4_range_0_10(i32 range(i32 0, 9) %v)
691  ret void
692}
693
694define void @prop_range_intersect2(i32 %v) {
695; CHECK-LABEL: define {{[^@]+}}@prop_range_intersect2
696; CHECK-SAME: (i32 [[V:%.*]]) {
697; CHECK-NEXT:    call void @bar5(i32 range(i32 1, 9) [[V]])
698; CHECK-NEXT:    ret void
699;
700  call void @foo4_range_0_10(i32 range(i32 1, 9) %v)
701  ret void
702}
703
704define void @prop_range_intersect3(i32 %v) {
705; CHECK-LABEL: define {{[^@]+}}@prop_range_intersect3
706; CHECK-SAME: (i32 [[V:%.*]]) {
707; CHECK-NEXT:    call void @bar5(i32 range(i32 0, 11) [[V]])
708; CHECK-NEXT:    ret void
709;
710  call void @foo4_2_range_0_10(i32 range(i32 0, 11) %v)
711  ret void
712}
713
714define void @prop_range_intersect4(i32 %v) {
715; CHECK-LABEL: define {{[^@]+}}@prop_range_intersect4
716; CHECK-SAME: (i32 [[V:%.*]]) {
717; CHECK-NEXT:    call void @bar5(i32 range(i32 0, 5) [[V]])
718; CHECK-NEXT:    ret void
719;
720  call void @foo4_range_0_10(i32 range(i32 40, 5) %v)
721  ret void
722}
723
724define void @prop_range_intersect5(i32 %v) {
725; CHECK-LABEL: define {{[^@]+}}@prop_range_intersect5
726; CHECK-SAME: (i32 [[V:%.*]]) {
727; CHECK-NEXT:    call void @bar5(i32 range(i32 10, 40) [[V]])
728; CHECK-NEXT:    ret void
729;
730  call void @foo4_range_10_40(i32 range(i32 30, 20) %v)
731  ret void
732}
733
734define void @prop_range_keep(i32 %v) {
735; CHECK-LABEL: define {{[^@]+}}@prop_range_keep
736; CHECK-SAME: (i32 [[V:%.*]]) {
737; CHECK-NEXT:    call void @bar5(i32 range(i32 10, 40) [[V]])
738; CHECK-NEXT:    ret void
739;
740  call void @foo4_range_10_40(i32 %v)
741  ret void
742}
743
744define void @prop_range_direct(i32 %v) {
745; CHECK-LABEL: define {{[^@]+}}@prop_range_direct
746; CHECK-SAME: (i32 [[V:%.*]]) {
747; CHECK-NEXT:    call void @bar5(i32 range(i32 1, 11) [[V]])
748; CHECK-NEXT:    ret void
749;
750  call void @foo4(i32 range(i32 1, 11) %v)
751  ret void
752}
753