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