Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / Attributor / undefined_behavior.ll
blob4ca6ab2c734350f3e1b90fbb1996f3f75336ce09
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-annotate-decl-cs  -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
5 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7 ; Test cases specifically designed for the "undefined behavior" abstract function attribute.
8 ; We want to verify that whenever undefined behavior is assumed, the code becomes unreachable.
9 ; We use FIXME's to indicate problems and missing attributes.
11 ; -- Load tests --
13 define void @load_wholly_unreachable() {
14 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
15 ; CHECK-LABEL: define {{[^@]+}}@load_wholly_unreachable
16 ; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
17 ; CHECK-NEXT:    unreachable
19   %a = load i32, ptr null
20   ret void
23 define void @loads_wholly_unreachable() {
24 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
25 ; CHECK-LABEL: define {{[^@]+}}@loads_wholly_unreachable
26 ; CHECK-SAME: () #[[ATTR0]] {
27 ; CHECK-NEXT:    unreachable
29   %a = load i32, ptr null
30   %b = load i32, ptr null
31   ret void
35 define void @load_single_bb_unreachable(i1 %cond) {
36 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
37 ; CHECK-LABEL: define {{[^@]+}}@load_single_bb_unreachable
38 ; CHECK-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR0]] {
39 ; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
40 ; CHECK:       t:
41 ; CHECK-NEXT:    unreachable
42 ; CHECK:       e:
43 ; CHECK-NEXT:    ret void
45   br i1 %cond, label %t, label %e
47   %b = load i32, ptr null
48   br label %e
50   ret void
53 ; Note that while the load is removed (because it's unused), the block
54 ; is not changed to unreachable
55 define void @load_null_pointer_is_defined() null_pointer_is_valid {
56 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none)
57 ; CHECK-LABEL: define {{[^@]+}}@load_null_pointer_is_defined
58 ; CHECK-SAME: () #[[ATTR1:[0-9]+]] {
59 ; CHECK-NEXT:    ret void
61   %a = load i32, ptr null
62   ret void
65 define internal ptr @ret_null() {
66 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
67 ; CGSCC-LABEL: define {{[^@]+}}@ret_null
68 ; CGSCC-SAME: () #[[ATTR0]] {
69 ; CGSCC-NEXT:    ret ptr null
71   ret ptr null
74 define void @load_null_propagated() {
75 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
76 ; TUNIT-LABEL: define {{[^@]+}}@load_null_propagated
77 ; TUNIT-SAME: () #[[ATTR0]] {
78 ; TUNIT-NEXT:    unreachable
80 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
81 ; CGSCC-LABEL: define {{[^@]+}}@load_null_propagated
82 ; CGSCC-SAME: () #[[ATTR2:[0-9]+]] {
83 ; CGSCC-NEXT:    ret void
85   %ptr = call ptr @ret_null()
86   %a = load i32, ptr %ptr
87   ret void
90 ; -- Store tests --
92 define void @store_wholly_unreachable() {
93 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
94 ; CHECK-LABEL: define {{[^@]+}}@store_wholly_unreachable
95 ; CHECK-SAME: () #[[ATTR0]] {
96 ; CHECK-NEXT:    unreachable
98   store i32 5, ptr null
99   ret void
102 define void @store_wholly_unreachable_volatile() {
103 ; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
104 ; TUNIT-LABEL: define {{[^@]+}}@store_wholly_unreachable_volatile
105 ; TUNIT-SAME: () #[[ATTR2:[0-9]+]] {
106 ; TUNIT-NEXT:    store volatile i32 5, ptr null, align 4294967296
107 ; TUNIT-NEXT:    ret void
109 ; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
110 ; CGSCC-LABEL: define {{[^@]+}}@store_wholly_unreachable_volatile
111 ; CGSCC-SAME: () #[[ATTR3:[0-9]+]] {
112 ; CGSCC-NEXT:    store volatile i32 5, ptr null, align 4294967296
113 ; CGSCC-NEXT:    ret void
115   store volatile i32 5, ptr null
116   ret void
119 define void @store_single_bb_unreachable(i1 %cond) {
120 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
121 ; CHECK-LABEL: define {{[^@]+}}@store_single_bb_unreachable
122 ; CHECK-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR0]] {
123 ; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
124 ; CHECK:       t:
125 ; CHECK-NEXT:    unreachable
126 ; CHECK:       e:
127 ; CHECK-NEXT:    ret void
129   br i1 %cond, label %t, label %e
131   store i32 5, ptr null
132   br label %e
134   ret void
137 define void @store_null_pointer_is_defined() null_pointer_is_valid {
138 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(write)
139 ; TUNIT-LABEL: define {{[^@]+}}@store_null_pointer_is_defined
140 ; TUNIT-SAME: () #[[ATTR3:[0-9]+]] {
141 ; TUNIT-NEXT:    store i32 5, ptr null, align 4294967296
142 ; TUNIT-NEXT:    ret void
144 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(write)
145 ; CGSCC-LABEL: define {{[^@]+}}@store_null_pointer_is_defined
146 ; CGSCC-SAME: () #[[ATTR4:[0-9]+]] {
147 ; CGSCC-NEXT:    store i32 5, ptr null, align 4294967296
148 ; CGSCC-NEXT:    ret void
150   store i32 5, ptr null
151   ret void
154 define void @store_null_propagated() {
155 ; ATTRIBUTOR-LABEL: @store_null_propagated(
156 ; ATTRIBUTOR-NEXT:    unreachable
158 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
159 ; TUNIT-LABEL: define {{[^@]+}}@store_null_propagated
160 ; TUNIT-SAME: () #[[ATTR0]] {
161 ; TUNIT-NEXT:    unreachable
163 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write)
164 ; CGSCC-LABEL: define {{[^@]+}}@store_null_propagated
165 ; CGSCC-SAME: () #[[ATTR5:[0-9]+]] {
166 ; CGSCC-NEXT:    [[PTR:%.*]] = call noalias align 4294967296 ptr @ret_null() #[[ATTR10:[0-9]+]]
167 ; CGSCC-NEXT:    ret void
169   %ptr = call ptr @ret_null()
170   store i32 5, ptr %ptr
171   ret void
174 ; -- AtomicRMW tests --
176 define void @atomicrmw_wholly_unreachable() {
177 ; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
178 ; TUNIT-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable
179 ; TUNIT-SAME: () #[[ATTR2]] {
180 ; TUNIT-NEXT:    unreachable
182 ; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
183 ; CGSCC-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable
184 ; CGSCC-SAME: () #[[ATTR3]] {
185 ; CGSCC-NEXT:    unreachable
187   %a = atomicrmw add ptr null, i32 1 acquire
188   ret void
191 define void @atomicrmw_single_bb_unreachable(i1 %cond) {
192 ; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
193 ; TUNIT-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable
194 ; TUNIT-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR2]] {
195 ; TUNIT-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
196 ; TUNIT:       t:
197 ; TUNIT-NEXT:    unreachable
198 ; TUNIT:       e:
199 ; TUNIT-NEXT:    ret void
201 ; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
202 ; CGSCC-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable
203 ; CGSCC-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR3]] {
204 ; CGSCC-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
205 ; CGSCC:       t:
206 ; CGSCC-NEXT:    unreachable
207 ; CGSCC:       e:
208 ; CGSCC-NEXT:    ret void
210   br i1 %cond, label %t, label %e
212   %a = atomicrmw add ptr null, i32 1 acquire
213   br label %e
215   ret void
218 define void @atomicrmw_null_pointer_is_defined() null_pointer_is_valid {
219 ; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind null_pointer_is_valid willreturn
220 ; TUNIT-LABEL: define {{[^@]+}}@atomicrmw_null_pointer_is_defined
221 ; TUNIT-SAME: () #[[ATTR4:[0-9]+]] {
222 ; TUNIT-NEXT:    [[A:%.*]] = atomicrmw add ptr null, i32 1 acquire, align 4
223 ; TUNIT-NEXT:    ret void
225 ; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind null_pointer_is_valid willreturn
226 ; CGSCC-LABEL: define {{[^@]+}}@atomicrmw_null_pointer_is_defined
227 ; CGSCC-SAME: () #[[ATTR6:[0-9]+]] {
228 ; CGSCC-NEXT:    [[A:%.*]] = atomicrmw add ptr null, i32 1 acquire, align 4
229 ; CGSCC-NEXT:    ret void
231   %a = atomicrmw add ptr null, i32 1 acquire
232   ret void
235 define void @atomicrmw_null_propagated() {
236 ; ATTRIBUTOR-LABEL: @atomicrmw_null_propagated(
237 ; ATTRIBUTOR-NEXT:    unreachable
239 ; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
240 ; TUNIT-LABEL: define {{[^@]+}}@atomicrmw_null_propagated
241 ; TUNIT-SAME: () #[[ATTR2]] {
242 ; TUNIT-NEXT:    unreachable
244 ; CGSCC: Function Attrs: mustprogress nofree nounwind willreturn
245 ; CGSCC-LABEL: define {{[^@]+}}@atomicrmw_null_propagated
246 ; CGSCC-SAME: () #[[ATTR7:[0-9]+]] {
247 ; CGSCC-NEXT:    [[PTR:%.*]] = call noalias ptr @ret_null() #[[ATTR11:[0-9]+]]
248 ; CGSCC-NEXT:    [[A:%.*]] = atomicrmw add ptr [[PTR]], i32 1 acquire, align 4
249 ; CGSCC-NEXT:    ret void
251   %ptr = call ptr @ret_null()
252   %a = atomicrmw add ptr %ptr, i32 1 acquire
253   ret void
256 ; -- AtomicCmpXchg tests --
258 define void @atomiccmpxchg_wholly_unreachable() {
259 ; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
260 ; TUNIT-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable
261 ; TUNIT-SAME: () #[[ATTR2]] {
262 ; TUNIT-NEXT:    unreachable
264 ; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
265 ; CGSCC-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable
266 ; CGSCC-SAME: () #[[ATTR3]] {
267 ; CGSCC-NEXT:    unreachable
269   %a = cmpxchg ptr null, i32 2, i32 3 acq_rel monotonic
270   ret void
273 define void @atomiccmpxchg_single_bb_unreachable(i1 %cond) {
274 ; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
275 ; TUNIT-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable
276 ; TUNIT-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR2]] {
277 ; TUNIT-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
278 ; TUNIT:       t:
279 ; TUNIT-NEXT:    unreachable
280 ; TUNIT:       e:
281 ; TUNIT-NEXT:    ret void
283 ; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
284 ; CGSCC-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable
285 ; CGSCC-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR3]] {
286 ; CGSCC-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
287 ; CGSCC:       t:
288 ; CGSCC-NEXT:    unreachable
289 ; CGSCC:       e:
290 ; CGSCC-NEXT:    ret void
292   br i1 %cond, label %t, label %e
294   %a = cmpxchg ptr null, i32 2, i32 3 acq_rel monotonic
295   br label %e
297   ret void
300 define void @atomiccmpxchg_null_pointer_is_defined() null_pointer_is_valid {
301 ; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind null_pointer_is_valid willreturn
302 ; TUNIT-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined
303 ; TUNIT-SAME: () #[[ATTR4]] {
304 ; TUNIT-NEXT:    [[A:%.*]] = cmpxchg ptr null, i32 2, i32 3 acq_rel monotonic, align 4
305 ; TUNIT-NEXT:    ret void
307 ; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind null_pointer_is_valid willreturn
308 ; CGSCC-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined
309 ; CGSCC-SAME: () #[[ATTR6]] {
310 ; CGSCC-NEXT:    [[A:%.*]] = cmpxchg ptr null, i32 2, i32 3 acq_rel monotonic, align 4
311 ; CGSCC-NEXT:    ret void
313   %a = cmpxchg ptr null, i32 2, i32 3 acq_rel monotonic
314   ret void
317 define void @atomiccmpxchg_null_propagated() {
318 ; ATTRIBUTOR-LABEL: @atomiccmpxchg_null_propagated(
319 ; ATTRIBUTOR-NEXT:    unreachable
321 ; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
322 ; TUNIT-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated
323 ; TUNIT-SAME: () #[[ATTR2]] {
324 ; TUNIT-NEXT:    unreachable
326 ; CGSCC: Function Attrs: mustprogress nofree nounwind willreturn
327 ; CGSCC-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated
328 ; CGSCC-SAME: () #[[ATTR7]] {
329 ; CGSCC-NEXT:    [[PTR:%.*]] = call noalias ptr @ret_null() #[[ATTR11]]
330 ; CGSCC-NEXT:    [[A:%.*]] = cmpxchg ptr [[PTR]], i32 2, i32 3 acq_rel monotonic, align 4
331 ; CGSCC-NEXT:    ret void
333   %ptr = call ptr @ret_null()
334   %a = cmpxchg ptr %ptr, i32 2, i32 3 acq_rel monotonic
335   ret void
338 ; -- Conditional branching tests --
340 ; Note: The unreachable on %t and %e is _not_ from AAUndefinedBehavior
342 define i32 @cond_br_on_undef() {
343 ; TUNIT: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(none)
344 ; TUNIT-LABEL: define {{[^@]+}}@cond_br_on_undef
345 ; TUNIT-SAME: () #[[ATTR5:[0-9]+]] {
346 ; TUNIT-NEXT:    unreachable
347 ; TUNIT:       t:
348 ; TUNIT-NEXT:    unreachable
349 ; TUNIT:       e:
350 ; TUNIT-NEXT:    unreachable
352 ; CGSCC: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(none)
353 ; CGSCC-LABEL: define {{[^@]+}}@cond_br_on_undef
354 ; CGSCC-SAME: () #[[ATTR8:[0-9]+]] {
355 ; CGSCC-NEXT:    unreachable
356 ; CGSCC:       t:
357 ; CGSCC-NEXT:    unreachable
358 ; CGSCC:       e:
359 ; CGSCC-NEXT:    unreachable
361   br i1 undef, label %t, label %e
363   ret i32 1
365   ret i32 2
368 ; More complicated branching
369   ; Valid branch - verify that this is not converted
370   ; to unreachable.
371 define void @cond_br_on_undef2(i1 %cond) {
372 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
373 ; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef2
374 ; CHECK-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR0]] {
375 ; CHECK-NEXT:    br i1 [[COND]], label [[T1:%.*]], label [[E1:%.*]]
376 ; CHECK:       t1:
377 ; CHECK-NEXT:    unreachable
378 ; CHECK:       t2:
379 ; CHECK-NEXT:    unreachable
380 ; CHECK:       e2:
381 ; CHECK-NEXT:    unreachable
382 ; CHECK:       e1:
383 ; CHECK-NEXT:    ret void
385   br i1 %cond, label %t1, label %e1
387   br i1 undef, label %t2, label %e2
389   ret void
391   ret void
393   ret void
396 define i1 @ret_undef() {
397 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
398 ; CHECK-LABEL: define {{[^@]+}}@ret_undef
399 ; CHECK-SAME: () #[[ATTR0]] {
400 ; CHECK-NEXT:    ret i1 undef
402   ret i1 undef
405 define void @cond_br_on_undef_interproc() {
406 ; TUNIT: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(none)
407 ; TUNIT-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc
408 ; TUNIT-SAME: () #[[ATTR5]] {
409 ; TUNIT-NEXT:    unreachable
410 ; TUNIT:       t:
411 ; TUNIT-NEXT:    unreachable
412 ; TUNIT:       e:
413 ; TUNIT-NEXT:    unreachable
415 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
416 ; CGSCC-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc
417 ; CGSCC-SAME: () #[[ATTR2]] {
418 ; CGSCC-NEXT:    [[COND:%.*]] = call i1 @ret_undef() #[[ATTR10]]
419 ; CGSCC-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
420 ; CGSCC:       t:
421 ; CGSCC-NEXT:    ret void
422 ; CGSCC:       e:
423 ; CGSCC-NEXT:    ret void
425   %cond = call i1 @ret_undef()
426   br i1 %cond, label %t, label %e
428   ret void
430   ret void
433 define i1 @ret_undef2() {
434 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
435 ; CHECK-LABEL: define {{[^@]+}}@ret_undef2
436 ; CHECK-SAME: () #[[ATTR0]] {
437 ; CHECK-NEXT:    br i1 true, label [[T:%.*]], label [[E:%.*]]
438 ; CHECK:       t:
439 ; CHECK-NEXT:    ret i1 undef
440 ; CHECK:       e:
441 ; CHECK-NEXT:    unreachable
443   br i1 true, label %t, label %e
445   ret i1 undef
447   ret i1 undef
450 ; More complicated interproc deduction of undef
451 define void @cond_br_on_undef_interproc2() {
452 ; TUNIT: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(none)
453 ; TUNIT-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2
454 ; TUNIT-SAME: () #[[ATTR5]] {
455 ; TUNIT-NEXT:    unreachable
456 ; TUNIT:       t:
457 ; TUNIT-NEXT:    unreachable
458 ; TUNIT:       e:
459 ; TUNIT-NEXT:    unreachable
461 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
462 ; CGSCC-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2
463 ; CGSCC-SAME: () #[[ATTR2]] {
464 ; CGSCC-NEXT:    [[COND:%.*]] = call i1 @ret_undef2() #[[ATTR10]]
465 ; CGSCC-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
466 ; CGSCC:       t:
467 ; CGSCC-NEXT:    ret void
468 ; CGSCC:       e:
469 ; CGSCC-NEXT:    ret void
471   %cond = call i1 @ret_undef2()
472   br i1 %cond, label %t, label %e
474   ret void
476   ret void
479 ; Branch on undef that depends on propagation of
480 ; undef of a previous instruction.
481 define i32 @cond_br_on_undef3() {
482 ; TUNIT: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(none)
483 ; TUNIT-LABEL: define {{[^@]+}}@cond_br_on_undef3
484 ; TUNIT-SAME: () #[[ATTR5]] {
485 ; TUNIT-NEXT:    unreachable
486 ; TUNIT:       t:
487 ; TUNIT-NEXT:    unreachable
488 ; TUNIT:       e:
489 ; TUNIT-NEXT:    unreachable
491 ; CGSCC: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(none)
492 ; CGSCC-LABEL: define {{[^@]+}}@cond_br_on_undef3
493 ; CGSCC-SAME: () #[[ATTR8]] {
494 ; CGSCC-NEXT:    unreachable
495 ; CGSCC:       t:
496 ; CGSCC-NEXT:    unreachable
497 ; CGSCC:       e:
498 ; CGSCC-NEXT:    unreachable
500   %cond = icmp ne i32 1, undef
501   br i1 %cond, label %t, label %e
503   ret i32 1
505   ret i32 2
508 ; Branch on undef because of uninitialized value.
509 ; FIXME: Currently it doesn't propagate the undef.
510 define i32 @cond_br_on_undef_uninit() {
511 ; TUNIT: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(none)
512 ; TUNIT-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit
513 ; TUNIT-SAME: () #[[ATTR5]] {
514 ; TUNIT-NEXT:    unreachable
515 ; TUNIT:       t:
516 ; TUNIT-NEXT:    unreachable
517 ; TUNIT:       e:
518 ; TUNIT-NEXT:    unreachable
520 ; CGSCC: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(none)
521 ; CGSCC-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit
522 ; CGSCC-SAME: () #[[ATTR8]] {
523 ; CGSCC-NEXT:    unreachable
524 ; CGSCC:       t:
525 ; CGSCC-NEXT:    unreachable
526 ; CGSCC:       e:
527 ; CGSCC-NEXT:    unreachable
529   %alloc = alloca i1
530   %cond = load i1, ptr %alloc
531   br i1 %cond, label %t, label %e
533   ret i32 1
535   ret i32 2
538 ; Note that the `load` has UB (so it will be changed to unreachable)
539 ; and the branch is a terminator that can be constant-folded.
540 ; We want to test that doing both won't cause a segfault.
541 ; MODULE-NOT: @callee(
542 define internal i32 @callee(i1 %C, ptr %A) {
544 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
545 ; CGSCC-LABEL: define {{[^@]+}}@callee
546 ; CGSCC-SAME: () #[[ATTR0]] {
547 ; CGSCC-NEXT:  entry:
548 ; CGSCC-NEXT:    unreachable
549 ; CGSCC:       T:
550 ; CGSCC-NEXT:    unreachable
551 ; CGSCC:       F:
552 ; CGSCC-NEXT:    ret i32 1
554 entry:
555   %A.0 = load i32, ptr null
556   br i1 %C, label %T, label %F
559   ret i32 %A.0
562   ret i32 1
565 define i32 @foo() {
566 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
567 ; TUNIT-LABEL: define {{[^@]+}}@foo
568 ; TUNIT-SAME: () #[[ATTR0]] {
569 ; TUNIT-NEXT:    ret i32 1
571 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
572 ; CGSCC-LABEL: define {{[^@]+}}@foo
573 ; CGSCC-SAME: () #[[ATTR2]] {
574 ; CGSCC-NEXT:    [[X:%.*]] = call noundef i32 @callee() #[[ATTR10]]
575 ; CGSCC-NEXT:    ret i32 [[X]]
577   %X = call i32 @callee(i1 false, ptr null)
578   ret i32 %X
581 ; Tests for nonnull noundef attribute violation.
583 ; Tests for argument position
585 define void @arg_nonnull_1(ptr nonnull %a) {
586 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
587 ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_1
588 ; TUNIT-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] {
589 ; TUNIT-NEXT:    store i32 0, ptr [[A]], align 4
590 ; TUNIT-NEXT:    ret void
592 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
593 ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_1
594 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR9:[0-9]+]] {
595 ; CGSCC-NEXT:    store i32 0, ptr [[A]], align 4
596 ; CGSCC-NEXT:    ret void
598   store i32 0, ptr %a
599   ret void
602 define void @arg_nonnull_1_noundef_1(ptr nonnull noundef %a) {
603 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
604 ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_1_noundef_1
605 ; TUNIT-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6]] {
606 ; TUNIT-NEXT:    store i32 0, ptr [[A]], align 4
607 ; TUNIT-NEXT:    ret void
609 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
610 ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_1_noundef_1
611 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR9]] {
612 ; CGSCC-NEXT:    store i32 0, ptr [[A]], align 4
613 ; CGSCC-NEXT:    ret void
615   store i32 0, ptr %a
616   ret void
619 define void @arg_nonnull_12(ptr nonnull %a, ptr nonnull %b, ptr %c) {
620 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
621 ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_12
622 ; TUNIT-SAME: (ptr nocapture nofree nonnull writeonly [[A:%.*]], ptr nocapture nofree nonnull writeonly [[B:%.*]], ptr nofree writeonly [[C:%.*]]) #[[ATTR6]] {
623 ; TUNIT-NEXT:    [[D:%.*]] = icmp eq ptr [[C]], null
624 ; TUNIT-NEXT:    br i1 [[D]], label [[T:%.*]], label [[F:%.*]]
625 ; TUNIT:       t:
626 ; TUNIT-NEXT:    store i32 0, ptr [[A]], align 4
627 ; TUNIT-NEXT:    br label [[RET:%.*]]
628 ; TUNIT:       f:
629 ; TUNIT-NEXT:    store i32 1, ptr [[B]], align 4
630 ; TUNIT-NEXT:    br label [[RET]]
631 ; TUNIT:       ret:
632 ; TUNIT-NEXT:    ret void
634 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
635 ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_12
636 ; CGSCC-SAME: (ptr nocapture nofree nonnull writeonly [[A:%.*]], ptr nocapture nofree nonnull writeonly [[B:%.*]], ptr nofree writeonly [[C:%.*]]) #[[ATTR9]] {
637 ; CGSCC-NEXT:    [[D:%.*]] = icmp eq ptr [[C]], null
638 ; CGSCC-NEXT:    br i1 [[D]], label [[T:%.*]], label [[F:%.*]]
639 ; CGSCC:       t:
640 ; CGSCC-NEXT:    store i32 0, ptr [[A]], align 4
641 ; CGSCC-NEXT:    br label [[RET:%.*]]
642 ; CGSCC:       f:
643 ; CGSCC-NEXT:    store i32 1, ptr [[B]], align 4
644 ; CGSCC-NEXT:    br label [[RET]]
645 ; CGSCC:       ret:
646 ; CGSCC-NEXT:    ret void
648   %d = icmp eq ptr %c, null
649   br i1 %d, label %t, label %f
651   store i32 0, ptr %a
652   br label %ret
654   store i32 1, ptr %b
655   br label %ret
656 ret:
657   ret void
660 define void @arg_nonnull_12_noundef_2(ptr nonnull %a, ptr noundef nonnull %b, ptr %c) {
661 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
662 ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_12_noundef_2
663 ; TUNIT-SAME: (ptr nocapture nofree nonnull writeonly [[A:%.*]], ptr nocapture nofree noundef nonnull writeonly [[B:%.*]], ptr nofree writeonly [[C:%.*]]) #[[ATTR6]] {
664 ; TUNIT-NEXT:    [[D:%.*]] = icmp eq ptr [[C]], null
665 ; TUNIT-NEXT:    br i1 [[D]], label [[T:%.*]], label [[F:%.*]]
666 ; TUNIT:       t:
667 ; TUNIT-NEXT:    store i32 0, ptr [[A]], align 4
668 ; TUNIT-NEXT:    br label [[RET:%.*]]
669 ; TUNIT:       f:
670 ; TUNIT-NEXT:    store i32 1, ptr [[B]], align 4
671 ; TUNIT-NEXT:    br label [[RET]]
672 ; TUNIT:       ret:
673 ; TUNIT-NEXT:    ret void
675 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
676 ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_12_noundef_2
677 ; CGSCC-SAME: (ptr nocapture nofree nonnull writeonly [[A:%.*]], ptr nocapture nofree noundef nonnull writeonly [[B:%.*]], ptr nofree writeonly [[C:%.*]]) #[[ATTR9]] {
678 ; CGSCC-NEXT:    [[D:%.*]] = icmp eq ptr [[C]], null
679 ; CGSCC-NEXT:    br i1 [[D]], label [[T:%.*]], label [[F:%.*]]
680 ; CGSCC:       t:
681 ; CGSCC-NEXT:    store i32 0, ptr [[A]], align 4
682 ; CGSCC-NEXT:    br label [[RET:%.*]]
683 ; CGSCC:       f:
684 ; CGSCC-NEXT:    store i32 1, ptr [[B]], align 4
685 ; CGSCC-NEXT:    br label [[RET]]
686 ; CGSCC:       ret:
687 ; CGSCC-NEXT:    ret void
689   %d = icmp eq ptr %c, null
690   br i1 %d, label %t, label %f
692   store i32 0, ptr %a
693   br label %ret
695   store i32 1, ptr %b
696   br label %ret
697 ret:
698   ret void
701 ; Pass null directly to argument with nonnull attribute
702 define void @arg_nonnull_violation1_1() {
703 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
704 ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_violation1_1
705 ; TUNIT-SAME: () #[[ATTR0]] {
706 ; TUNIT-NEXT:    unreachable
708 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
709 ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_violation1_1
710 ; CGSCC-SAME: () #[[ATTR2]] {
711 ; CGSCC-NEXT:    unreachable
713   call void @arg_nonnull_1(ptr null)
714   ret void
717 define void @arg_nonnull_violation1_2() {
718 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
719 ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_violation1_2
720 ; TUNIT-SAME: () #[[ATTR0]] {
721 ; TUNIT-NEXT:    unreachable
723 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
724 ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_violation1_2
725 ; CGSCC-SAME: () #[[ATTR2]] {
726 ; CGSCC-NEXT:    unreachable
728   call void @arg_nonnull_1_noundef_1(ptr null)
729   ret void
732 ; A case that depends on value simplification
733 define void @arg_nonnull_violation2_1(i1 %c) {
734 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
735 ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_violation2_1
736 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
737 ; TUNIT-NEXT:    unreachable
739 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
740 ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_violation2_1
741 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
742 ; CGSCC-NEXT:    unreachable
744   %mustnull = select i1 %c, ptr null, ptr null
745   call void @arg_nonnull_1(ptr %mustnull)
746   ret void
749 define void @arg_nonnull_violation2_2(i1 %c) {
750 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
751 ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_violation2_2
752 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
753 ; TUNIT-NEXT:    unreachable
755 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
756 ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_violation2_2
757 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
758 ; CGSCC-NEXT:    unreachable
760   %mustnull = select i1 %c, ptr null, ptr null
761   call void @arg_nonnull_1_noundef_1(ptr %mustnull)
762   ret void
765 ; Cases for single and multiple violation at a callsite
766 define void @arg_nonnull_violation3_1(i1 %c) {
767 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
768 ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_violation3_1
769 ; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR0]] {
770 ; TUNIT-NEXT:    [[PTR:%.*]] = alloca i32, align 4
771 ; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
772 ; TUNIT:       t:
773 ; TUNIT-NEXT:    call void @arg_nonnull_12(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR7:[0-9]+]]
774 ; TUNIT-NEXT:    call void @arg_nonnull_12(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nofree noundef writeonly align 4294967296 null) #[[ATTR7]]
775 ; TUNIT-NEXT:    unreachable
776 ; TUNIT:       f:
777 ; TUNIT-NEXT:    unreachable
778 ; TUNIT:       ret:
779 ; TUNIT-NEXT:    ret void
781 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
782 ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_violation3_1
783 ; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR2]] {
784 ; CGSCC-NEXT:    [[PTR:%.*]] = alloca i32, align 4
785 ; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
786 ; CGSCC:       t:
787 ; CGSCC-NEXT:    call void @arg_nonnull_12(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR12:[0-9]+]]
788 ; CGSCC-NEXT:    call void @arg_nonnull_12(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nofree noundef writeonly align 4294967296 null) #[[ATTR12]]
789 ; CGSCC-NEXT:    unreachable
790 ; CGSCC:       f:
791 ; CGSCC-NEXT:    unreachable
792 ; CGSCC:       ret:
793 ; CGSCC-NEXT:    ret void
795   %ptr = alloca i32
796   br i1 %c, label %t, label %f
798   call void @arg_nonnull_12(ptr %ptr, ptr %ptr, ptr %ptr)
799   call void @arg_nonnull_12(ptr %ptr, ptr %ptr, ptr null)
800   call void @arg_nonnull_12(ptr %ptr, ptr null, ptr %ptr)
801   call void @arg_nonnull_12(ptr %ptr, ptr null, ptr null)
802   br label %ret
804   call void @arg_nonnull_12(ptr null, ptr %ptr, ptr %ptr)
805   call void @arg_nonnull_12(ptr null, ptr %ptr, ptr null)
806   call void @arg_nonnull_12(ptr null, ptr null, ptr %ptr)
807   call void @arg_nonnull_12(ptr null, ptr null, ptr null)
808   br label %ret
809 ret:
810   ret void
813 define void @arg_nonnull_violation3_2(i1 %c) {
814 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
815 ; TUNIT-LABEL: define {{[^@]+}}@arg_nonnull_violation3_2
816 ; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR0]] {
817 ; TUNIT-NEXT:    [[PTR:%.*]] = alloca i32, align 4
818 ; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
819 ; TUNIT:       t:
820 ; TUNIT-NEXT:    call void @arg_nonnull_12_noundef_2(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR7]]
821 ; TUNIT-NEXT:    call void @arg_nonnull_12_noundef_2(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nofree noundef writeonly align 4294967296 null) #[[ATTR7]]
822 ; TUNIT-NEXT:    unreachable
823 ; TUNIT:       f:
824 ; TUNIT-NEXT:    unreachable
825 ; TUNIT:       ret:
826 ; TUNIT-NEXT:    ret void
828 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
829 ; CGSCC-LABEL: define {{[^@]+}}@arg_nonnull_violation3_2
830 ; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR2]] {
831 ; CGSCC-NEXT:    [[PTR:%.*]] = alloca i32, align 4
832 ; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
833 ; CGSCC:       t:
834 ; CGSCC-NEXT:    call void @arg_nonnull_12_noundef_2(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR12]]
835 ; CGSCC-NEXT:    call void @arg_nonnull_12_noundef_2(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], ptr nofree noundef writeonly align 4294967296 null) #[[ATTR12]]
836 ; CGSCC-NEXT:    unreachable
837 ; CGSCC:       f:
838 ; CGSCC-NEXT:    unreachable
839 ; CGSCC:       ret:
840 ; CGSCC-NEXT:    ret void
842   %ptr = alloca i32
843   br i1 %c, label %t, label %f
845   call void @arg_nonnull_12_noundef_2(ptr %ptr, ptr %ptr, ptr %ptr)
846   call void @arg_nonnull_12_noundef_2(ptr %ptr, ptr %ptr, ptr null)
847   call void @arg_nonnull_12_noundef_2(ptr %ptr, ptr null, ptr %ptr)
848   call void @arg_nonnull_12_noundef_2(ptr %ptr, ptr null, ptr null)
849   br label %ret
851   call void @arg_nonnull_12_noundef_2(ptr null, ptr %ptr, ptr %ptr)
852   call void @arg_nonnull_12_noundef_2(ptr null, ptr %ptr, ptr null)
853   call void @arg_nonnull_12_noundef_2(ptr null, ptr null, ptr %ptr)
854   call void @arg_nonnull_12_noundef_2(ptr null, ptr null, ptr null)
855   br label %ret
856 ret:
857   ret void
860 ; Tests for returned position
862 define nonnull ptr @returned_nonnnull(i32 %c) {
863 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
864 ; CHECK-LABEL: define {{[^@]+}}@returned_nonnnull
865 ; CHECK-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] {
866 ; CHECK-NEXT:    switch i32 [[C]], label [[ONDEFAULT:%.*]] [
867 ; CHECK-NEXT:      i32 0, label [[ONZERO:%.*]]
868 ; CHECK-NEXT:      i32 1, label [[ONONE:%.*]]
869 ; CHECK-NEXT:    ]
870 ; CHECK:       onzero:
871 ; CHECK-NEXT:    [[PTR:%.*]] = alloca i32, align 4
872 ; CHECK-NEXT:    ret ptr [[PTR]]
873 ; CHECK:       onone:
874 ; CHECK-NEXT:    ret ptr null
875 ; CHECK:       ondefault:
876 ; CHECK-NEXT:    ret ptr undef
878   switch i32 %c, label %ondefault [ i32 0, label %onzero
879   i32 1, label %onone ]
880 onzero:
881   %ptr = alloca i32
882   ret ptr %ptr
883 onone:
884   ret ptr null
885 ondefault:
886   ret ptr undef
889 define noundef ptr @returned_noundef(i32 %c) {
890 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
891 ; CHECK-LABEL: define {{[^@]+}}@returned_noundef
892 ; CHECK-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] {
893 ; CHECK-NEXT:    switch i32 [[C]], label [[ONDEFAULT:%.*]] [
894 ; CHECK-NEXT:      i32 0, label [[ONZERO:%.*]]
895 ; CHECK-NEXT:      i32 1, label [[ONONE:%.*]]
896 ; CHECK-NEXT:    ]
897 ; CHECK:       onzero:
898 ; CHECK-NEXT:    [[PTR:%.*]] = alloca i32, align 4
899 ; CHECK-NEXT:    ret ptr [[PTR]]
900 ; CHECK:       onone:
901 ; CHECK-NEXT:    ret ptr null
902 ; CHECK:       ondefault:
903 ; CHECK-NEXT:    unreachable
905   switch i32 %c, label %ondefault [ i32 0, label %onzero
906   i32 1, label %onone ]
907 onzero:
908   %ptr = alloca i32
909   ret ptr %ptr
910 onone:
911   ret ptr null
912 ondefault:
913   ret ptr undef
916 define nonnull noundef ptr @returned_nonnnull_noundef(i32 %c) {
917 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
918 ; CHECK-LABEL: define {{[^@]+}}@returned_nonnnull_noundef
919 ; CHECK-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] {
920 ; CHECK-NEXT:    switch i32 [[C]], label [[ONDEFAULT:%.*]] [
921 ; CHECK-NEXT:      i32 0, label [[ONZERO:%.*]]
922 ; CHECK-NEXT:      i32 1, label [[ONONE:%.*]]
923 ; CHECK-NEXT:    ]
924 ; CHECK:       onzero:
925 ; CHECK-NEXT:    [[PTR:%.*]] = alloca i32, align 4
926 ; CHECK-NEXT:    ret ptr [[PTR]]
927 ; CHECK:       onone:
928 ; CHECK-NEXT:    unreachable
929 ; CHECK:       ondefault:
930 ; CHECK-NEXT:    unreachable
932   switch i32 %c, label %ondefault [ i32 0, label %onzero
933   i32 1, label %onone ]
934 onzero:
935   %ptr = alloca i32
936   ret ptr %ptr
937 onone:
938   ret ptr null
939 ondefault:
940   ret ptr undef
943 define noundef i32 @returned_nonnnull_noundef_int() {
944 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
945 ; CHECK-LABEL: define {{[^@]+}}@returned_nonnnull_noundef_int
946 ; CHECK-SAME: () #[[ATTR0]] {
947 ; CHECK-NEXT:    ret i32 0
949   ret i32 0
952 declare void @callee_int_arg(i32)
954 define void @callsite_noundef_1() {
955 ; CHECK-LABEL: define {{[^@]+}}@callsite_noundef_1() {
956 ; CHECK-NEXT:    call void @callee_int_arg(i32 noundef 0)
957 ; CHECK-NEXT:    ret void
959   call void @callee_int_arg(i32 noundef 0)
960   ret void
963 declare void @callee_ptr_arg(ptr)
965 define void @callsite_noundef_2() {
966 ; CHECK-LABEL: define {{[^@]+}}@callsite_noundef_2() {
967 ; CHECK-NEXT:    unreachable
969   call void @callee_ptr_arg(ptr noundef undef)
970   ret void
973 define i32 @argument_noundef1(i32 noundef %c) {
974 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
975 ; CHECK-LABEL: define {{[^@]+}}@argument_noundef1
976 ; CHECK-SAME: (i32 noundef returned [[C:%.*]]) #[[ATTR0]] {
977 ; CHECK-NEXT:    ret i32 [[C]]
979   ret i32 %c
982 define i32 @violate_noundef_nonpointer() {
983 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
984 ; TUNIT-LABEL: define {{[^@]+}}@violate_noundef_nonpointer
985 ; TUNIT-SAME: () #[[ATTR0]] {
986 ; TUNIT-NEXT:    ret i32 undef
988 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
989 ; CGSCC-LABEL: define {{[^@]+}}@violate_noundef_nonpointer
990 ; CGSCC-SAME: () #[[ATTR2]] {
991 ; CGSCC-NEXT:    unreachable
993   %ret = call i32 @argument_noundef1(i32 undef)
994   ret i32 %ret
997 define ptr @argument_noundef2(ptr noundef %c) {
998 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
999 ; CHECK-LABEL: define {{[^@]+}}@argument_noundef2
1000 ; CHECK-SAME: (ptr nofree noundef readnone returned "no-capture-maybe-returned" [[C:%.*]]) #[[ATTR0]] {
1001 ; CHECK-NEXT:    ret ptr [[C]]
1003   ret ptr %c
1006 define ptr @violate_noundef_pointer() {
1007 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1008 ; TUNIT-LABEL: define {{[^@]+}}@violate_noundef_pointer
1009 ; TUNIT-SAME: () #[[ATTR0]] {
1010 ; TUNIT-NEXT:    ret ptr undef
1012 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1013 ; CGSCC-LABEL: define {{[^@]+}}@violate_noundef_pointer
1014 ; CGSCC-SAME: () #[[ATTR2]] {
1015 ; CGSCC-NEXT:    ret ptr undef
1017   %ret = call ptr @argument_noundef2(ptr undef)
1018   ret ptr %ret
1021 define internal noundef i32 @assumed_undef_is_ok(i1 %c, i32 %arg) {
1022 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1023 ; CGSCC-LABEL: define {{[^@]+}}@assumed_undef_is_ok
1024 ; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR2]] {
1025 ; CGSCC-NEXT:    br i1 [[C]], label [[REC:%.*]], label [[RET:%.*]]
1026 ; CGSCC:       rec:
1027 ; CGSCC-NEXT:    br label [[RET]]
1028 ; CGSCC:       ret:
1029 ; CGSCC-NEXT:    ret i32 0
1031   %stack = alloca i32
1032   store i32 %arg, ptr %stack
1033   br i1 %c, label %rec, label %ret
1034 rec:
1035   %call = call i32 @assumed_undef_is_ok(i1 false, i32 0)
1036   store i32 %call, ptr %stack
1037   br label %ret
1038 ret:
1039   %l = load i32, ptr %stack
1040   ret i32 %l
1043 define noundef i32 @assumed_undef_is_ok_caller(i1 %c) {
1044 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1045 ; TUNIT-LABEL: define {{[^@]+}}@assumed_undef_is_ok_caller
1046 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
1047 ; TUNIT-NEXT:    ret i32 0
1049 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1050 ; CGSCC-LABEL: define {{[^@]+}}@assumed_undef_is_ok_caller
1051 ; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR2]] {
1052 ; CGSCC-NEXT:    [[CALL:%.*]] = call i32 @assumed_undef_is_ok(i1 noundef [[C]]) #[[ATTR10]]
1053 ; CGSCC-NEXT:    ret i32 [[CALL]]
1055   %call = call i32 @assumed_undef_is_ok(i1 %c, i32 undef)
1056   ret i32 %call
1060 ; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
1061 ; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none) }
1062 ; TUNIT: attributes #[[ATTR2]] = { mustprogress nofree norecurse nounwind willreturn memory(none) }
1063 ; TUNIT: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(write) }
1064 ; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree norecurse nounwind null_pointer_is_valid willreturn }
1065 ; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(none) }
1066 ; TUNIT: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
1067 ; TUNIT: attributes #[[ATTR7]] = { nofree nosync nounwind willreturn memory(write) }
1069 ; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
1070 ; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none) }
1071 ; CGSCC: attributes #[[ATTR2]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
1072 ; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree norecurse nounwind willreturn memory(none) }
1073 ; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(write) }
1074 ; CGSCC: attributes #[[ATTR5]] = { mustprogress nofree nosync nounwind willreturn memory(write) }
1075 ; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree norecurse nounwind null_pointer_is_valid willreturn }
1076 ; CGSCC: attributes #[[ATTR7]] = { mustprogress nofree nounwind willreturn }
1077 ; CGSCC: attributes #[[ATTR8]] = { mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(none) }
1078 ; CGSCC: attributes #[[ATTR9]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
1079 ; CGSCC: attributes #[[ATTR10]] = { nofree nosync willreturn }
1080 ; CGSCC: attributes #[[ATTR11]] = { nofree willreturn }
1081 ; CGSCC: attributes #[[ATTR12]] = { nofree nounwind willreturn memory(write) }