Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / Inline / ret_attr_align_and_noundef.ll
blobf4cebf1fcb5da0c8469320959153beede6b0ffa1
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
6 declare ptr @foo()
7 declare void @use.ptr(ptr) willreturn nounwind
8 declare void @use.val(i8) willreturn nounwind
9 declare void @bar()
10 declare void @baz()
11 declare ptr @llvm.ptrmask.p0.i64(ptr, i64)
12 declare i1 @val()
13 declare i8 @val8()
15 define ptr @callee0123() {
16 ; CHECK-LABEL: define ptr @callee0123() {
17 ; CHECK-NEXT:    [[R:%.*]] = call ptr @foo()
18 ; CHECK-NEXT:    ret ptr [[R]]
20   %r = call ptr @foo()
21   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()
30   ret ptr %r
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()
39   ret ptr %r
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()
48   ret ptr %r
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()
57   ret ptr %r
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()
66   ret ptr %r
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()
75   ret ptr %r
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]]
84   %r = call ptr @foo()
85   call void @bar()
86   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()
96   ret ptr %r
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()
105   ret ptr %r
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()
114   ret ptr %r
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()
123   ret ptr %r
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()
132   ret ptr %r
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()
141   ret ptr %r
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()
150   ret ptr %r
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()
159   ret ptr %r
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()
168   ret ptr %r
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()
177   ret ptr %r
180 define ptr @callee8() {
181 ; CHECK-LABEL: define ptr @callee8() {
182 ; CHECK-NEXT:    [[R:%.*]] = call ptr @foo()
183 ; CHECK-NEXT:    ret ptr [[R]]
185   %r = call ptr @foo()
186   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)
197   ret 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()
206   ret ptr %r
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)
217   ret 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)
228   ret 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]]
237   %r = call ptr @foo()
238   call void @use.ptr(ptr %r)
239   ret 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()
249   ret ptr %r
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()
259   ret ptr %r
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()
269   ret ptr %r
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:%.*]]
277 ; CHECK:       True:
278 ; CHECK-NEXT:    call void @baz() #[[ATTR0]]
279 ; CHECK-NEXT:    ret ptr [[R]]
280 ; CHECK:       False:
281 ; CHECK-NEXT:    call void @bar() #[[ATTR0]]
282 ; CHECK-NEXT:    [[COND2:%.*]] = call i1 @val()
283 ; CHECK-NEXT:    ret ptr [[R]]
285   %r = call ptr @foo()
286   %cond = call i1 @val() nounwind willreturn
287   br i1 %cond, label %True, label %False
288 True:
289   call void @baz() nounwind willreturn
290   ret ptr %r
291 False:
292   call void @bar() nounwind willreturn
293   %cond2 = call i1 @val()
294   ret ptr %r
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:%.*]]
302 ; CHECK:       True.i:
303 ; CHECK-NEXT:    call void @baz() #[[ATTR0]]
304 ; CHECK-NEXT:    br label [[CALLEE11_EXIT:%.*]]
305 ; CHECK:       False.i:
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()
313   ret ptr %r
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]]
324   %p = call ptr @foo()
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
328   ret ptr %r
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()
340   ret ptr %r
343 define i8 @callee13() {
344 ; CHECK-LABEL: define i8 @callee13() {
345 ; CHECK-NEXT:    [[R:%.*]] = call i8 @val8()
346 ; CHECK-NEXT:    ret i8 [[R]]
348   %r = call i8 @val8()
349   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)
360   ret 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()
369   ret i8 %r
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)
380   ret 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)
391   ret 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()
400   ret i8 %r
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)
411   ret i8 %r