1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -functionattrs -enable-nonnull-arg-prop %s | FileCheck %s --check-prefixes=BOTH,FNATTR,OLD
3; RUN: opt -S -passes=function-attrs -enable-nonnull-arg-prop %s | FileCheck %s --check-prefixes=BOTH,FNATTR,OLD
4; RUN: opt -attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=BOTH,OLD,ATTRIBUTOR,ATTRIBUTOR_OPM
5; RUN: opt -passes=attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=BOTH,ATTRIBUTOR,ATTRIBUTOR_NPM
6
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8
9declare nonnull i8* @ret_nonnull()
10
11; Return a pointer trivially nonnull (call return attribute)
12define i8* @test1() {
13; BOTH: define nonnull i8* @test1
14  %ret = call i8* @ret_nonnull()
15  ret i8* %ret
16}
17
18; Return a pointer trivially nonnull (argument attribute)
19define i8* @test2(i8* nonnull %p) {
20; BOTH: define nonnull i8* @test2
21  ret i8* %p
22}
23
24; Given an SCC where one of the functions can not be marked nonnull,
25; can we still mark the other one which is trivially nonnull
26define i8* @scc_binder(i1 %c) {
27; FNATTR: define i8* @scc_binder
28; ATTRIBUTOR: define noalias i8* @scc_binder
29  br i1 %c, label %rec, label %end
30rec:
31  call i8* @test3(i1 %c)
32  br label %end
33end:
34  ret i8* null
35}
36
37define i8* @test3(i1 %c) {
38; BOTH: define nonnull i8* @test3
39  call i8* @scc_binder(i1 %c)
40  %ret = call i8* @ret_nonnull()
41  ret i8* %ret
42}
43
44; Given a mutual recursive set of functions, we can mark them
45; nonnull if neither can ever return null.  (In this case, they
46; just never return period.)
47define i8* @test4_helper() {
48; FNATTR: define noalias nonnull i8* @test4_helper
49; ATTRIBUTOR: define noalias nonnull align 536870912 dereferenceable(4294967295) i8* @test4_helper
50  %ret = call i8* @test4()
51  ret i8* %ret
52}
53
54define i8* @test4() {
55; FNATTR: define noalias nonnull i8* @test4
56; ATTRIBUTOR: define noalias nonnull align 536870912 dereferenceable(4294967295) i8* @test4
57  %ret = call i8* @test4_helper()
58  ret i8* %ret
59}
60
61; Given a mutual recursive set of functions which *can* return null
62; make sure we haven't marked them as nonnull.
63define i8* @test5_helper(i1 %c) {
64; FNATTR: define noalias i8* @test5_helper
65; ATTRIBUTOR: define noalias i8* @test5_helper
66  br i1 %c, label %rec, label %end
67rec:
68  %ret = call i8* @test5(i1 %c)
69  br label %end
70end:
71  ret i8* null
72}
73
74define i8* @test5(i1 %c) {
75; FNATTR: define noalias i8* @test5
76; ATTRIBUTOR: define noalias i8* @test5
77  %ret = call i8* @test5_helper(i1 %c)
78  ret i8* %ret
79}
80
81; Local analysis, but going through a self recursive phi
82; ATTRIBUTOR: Function Attrs: noreturn
83; ATTRIBUTOR: define noalias nonnull align 536870912 dereferenceable(4294967295) i8* @test6a()
84define i8* @test6a() {
85entry:
86  %ret = call i8* @ret_nonnull()
87  br label %loop
88loop:
89  %phi = phi i8* [%ret, %entry], [%phi, %loop]
90  br i1 undef, label %loop, label %exit
91exit:
92  ret i8* %phi
93}
94
95; ATTRIBUTOR: define nonnull i8* @test6b(i1 %c)
96define i8* @test6b(i1 %c) {
97entry:
98  %ret = call i8* @ret_nonnull()
99  br label %loop
100loop:
101  %phi = phi i8* [%ret, %entry], [%phi, %loop]
102  br i1 %c, label %loop, label %exit
103exit:
104  ret i8* %phi
105}
106
107; BOTH: define i8* @test7
108define i8* @test7(i8* %a) {
109  %b = getelementptr inbounds i8, i8* %a, i64 0
110  ret i8* %b
111}
112
113; BOTH: define nonnull i8* @test8
114define i8* @test8(i8* %a) {
115  %b = getelementptr inbounds i8, i8* %a, i64 1
116  ret i8* %b
117}
118
119; BOTH: define i8* @test9
120define i8* @test9(i8* %a, i64 %n) {
121  %b = getelementptr inbounds i8, i8* %a, i64 %n
122  ret i8* %b
123}
124
125declare void @llvm.assume(i1)
126; FNATTR: define i8* @test10
127; FIXME: missing nonnull
128; ATTRIBUTOR: define i8* @test10
129define i8* @test10(i8* %a, i64 %n) {
130  %cmp = icmp ne i64 %n, 0
131  call void @llvm.assume(i1 %cmp)
132  %b = getelementptr inbounds i8, i8* %a, i64 %n
133  ret i8* %b
134}
135
136; TEST 11
137; char* test11(char *p) {
138;   return p? p: nonnull();
139; }
140; FNATTR: define i8* @test11
141; FIXME: missing nonnull
142; ATTRIBUTOR: define i8* @test11
143define i8* @test11(i8*) local_unnamed_addr {
144  %2 = icmp eq i8* %0, null
145  br i1 %2, label %3, label %5
146
147; <label>:3:                                      ; preds = %1
148  %4 = tail call i8* @ret_nonnull()
149  br label %5
150
151; <label>:5:                                      ; preds = %3, %1
152  %6 = phi i8* [ %4, %3 ], [ %0, %1 ]
153  ret i8* %6
154}
155
156; TEST 12
157; Simple CallSite Test
158declare void @test12_helper(i8*)
159define void @test12(i8* nonnull %a) {
160; ATTRIBUTOR: define void @test12(i8* nonnull %a)
161; ATTRIBUTOR-NEXT: tail call void @test12_helper(i8* nonnull %a)
162  tail call void @test12_helper(i8* %a)
163  ret void
164}
165
166; TEST 13
167; Simple Argument Tests
168declare i8* @unknown()
169define void @test13_helper() {
170  %nonnullptr = tail call i8* @ret_nonnull()
171  %maybenullptr = tail call i8* @unknown()
172  tail call void @test13(i8* %nonnullptr, i8* %nonnullptr, i8* %maybenullptr)
173  tail call void @test13(i8* %nonnullptr, i8* %maybenullptr, i8* %nonnullptr)
174  ret void
175}
176define internal void @test13(i8* %a, i8* %b, i8* %c) {
177; ATTRIBUTOR: define internal void @test13(i8* nocapture nonnull readnone %a, i8* nocapture readnone %b, i8* nocapture readnone %c)
178  ret void
179}
180
181declare nonnull i8* @nonnull()
182
183; TEST 14
184; Complex propagation
185; Argument of f1, f2, f3 can be marked with nonnull.
186
187; * Argument
188; 1. In f1:bb6, %arg can be marked with nonnull because of the comparison in bb1
189; 2. Because f2 is internal function, f2(i32* %arg) -> @f2(i32* nonnull %arg)
190; 3. In f1:bb4 %tmp5 is nonnull and f3 is internal function.
191;    Then, f3(i32* %arg) -> @f3(i32* nonnull %arg)
192; 4. We get nonnull in whole f1 call sites so f1(i32* %arg) -> @f1(i32* nonnull %arg)
193
194
195define internal i32* @f1(i32* %arg) {
196; FIXME: missing nonnull It should be nonnull @f1(i32* nonnull readonly %arg)
197; ATTRIBUTOR: define internal nonnull i32* @f1(i32* readonly %arg)
198
199bb:
200  %tmp = icmp eq i32* %arg, null
201  br i1 %tmp, label %bb9, label %bb1
202
203bb1:                                              ; preds = %bb
204  %tmp2 = load i32, i32* %arg, align 4
205  %tmp3 = icmp eq i32 %tmp2, 0
206  br i1 %tmp3, label %bb6, label %bb4
207
208bb4:                                              ; preds = %bb1
209  %tmp5 = getelementptr inbounds i32, i32* %arg, i64 1
210; ATTRIBUTOR: %tmp5b = tail call nonnull i32* @f3(i32* nonnull %tmp5)
211  %tmp5b = tail call i32* @f3(i32* %tmp5)
212  %tmp5c = getelementptr inbounds i32, i32* %tmp5b, i64 -1
213  br label %bb9
214
215bb6:                                              ; preds = %bb1
216; FIXME: missing nonnull. It should be @f2(i32* nonnull %arg)
217; ATTRIBUTOR: %tmp7 = tail call nonnull i32* @f2(i32* %arg)
218  %tmp7 = tail call i32* @f2(i32* %arg)
219  ret i32* %tmp7
220
221bb9:                                              ; preds = %bb4, %bb
222  %tmp10 = phi i32* [ %tmp5c, %bb4 ], [ inttoptr (i64 4 to i32*), %bb ]
223  ret i32* %tmp10
224}
225
226define internal i32* @f2(i32* %arg) {
227; FIXME: missing nonnull. It should be nonnull @f2(i32* nonnull %arg)
228; ATTRIBUTOR: define internal nonnull i32* @f2(i32* readonly %arg)
229bb:
230
231; FIXME: missing nonnull. It should be @f1(i32* nonnull readonly %arg)
232; ATTRIBUTOR:   %tmp = tail call nonnull i32* @f1(i32* %arg)
233  %tmp = tail call i32* @f1(i32* %arg)
234  ret i32* %tmp
235}
236
237define dso_local noalias i32* @f3(i32* %arg) {
238; FIXME: missing nonnull. It should be nonnull @f3(i32* nonnull readonly %arg)
239; ATTRIBUTOR: define dso_local noalias nonnull i32* @f3(i32* readonly %arg)
240bb:
241; FIXME: missing nonnull. It should be @f1(i32* nonnull readonly %arg)
242; ATTRIBUTOR:   %tmp = call nonnull i32* @f1(i32* %arg)
243  %tmp = call i32* @f1(i32* %arg)
244  ret i32* %tmp
245}
246
247; TEST 15
248define void @f15(i8* %arg) {
249; ATTRIBUTOR:   tail call void @use1(i8* nonnull dereferenceable(4) %arg)
250
251  tail call void @use1(i8* dereferenceable(4) %arg)
252  ret void
253}
254
255declare void @fun0() #1
256declare void @fun1(i8*) #1
257declare void @fun2(i8*, i8*) #1
258declare void @fun3(i8*, i8*, i8*) #1
259; TEST 16 simple path test
260; if(..)
261;   fun2(nonnull %a, nonnull %b)
262; else
263;   fun2(nonnull %a, %b)
264; We can say that %a is nonnull but %b is not.
265define void @f16(i8* %a, i8 * %b, i8 %c) {
266; FIXME: missing nonnull on %a
267; ATTRIBUTOR: define void @f16(i8* %a, i8* %b, i8 %c)
268  %cmp = icmp eq i8 %c, 0
269  br i1 %cmp, label %if.then, label %if.else
270if.then:
271  tail call void @fun2(i8* nonnull %a, i8* nonnull %b)
272  ret void
273if.else:
274  tail call void @fun2(i8* nonnull %a, i8* %b)
275  ret void
276}
277; TEST 17 explore child BB test
278; if(..)
279;    ... (willreturn & nounwind)
280; else
281;    ... (willreturn & nounwind)
282; fun1(nonnull %a)
283; We can say that %a is nonnull
284define void @f17(i8* %a, i8 %c) {
285; ATTRIBUTOR: define void @f17(i8* nonnull %a, i8 %c)
286  %cmp = icmp eq i8 %c, 0
287  br i1 %cmp, label %if.then, label %if.else
288if.then:
289  tail call void @fun0()
290  br label %cont
291if.else:
292  tail call void @fun0()
293  br label %cont
294cont:
295  tail call void @fun1(i8* nonnull %a)
296  ret void
297}
298; TEST 18 More complex test
299; if(..)
300;    ... (willreturn & nounwind)
301; else
302;    ... (willreturn & nounwind)
303; if(..)
304;    ... (willreturn & nounwind)
305; else
306;    ... (willreturn & nounwind)
307; fun1(nonnull %a)
308
309define void @f18(i8* %a, i8* %b, i8 %c) {
310; ATTRIBUTOR: define void @f18(i8* nonnull %a, i8* %b, i8 %c)
311  %cmp1 = icmp eq i8 %c, 0
312  br i1 %cmp1, label %if.then, label %if.else
313if.then:
314  tail call void @fun0()
315  br label %cont
316if.else:
317  tail call void @fun0()
318  br label %cont
319cont:
320  %cmp2 = icmp eq i8 %c, 1
321  br i1 %cmp2, label %cont.then, label %cont.else
322cont.then:
323  tail call void @fun1(i8* nonnull %b)
324  br label %cont2
325cont.else:
326  tail call void @fun0()
327  br label %cont2
328cont2:
329  tail call void @fun1(i8* nonnull %a)
330  ret void
331}
332
333; TEST 19: Loop
334
335define void @f19(i8* %a, i8* %b, i8 %c) {
336; FIXME: missing nonnull on %b
337; ATTRIBUTOR: define void @f19(i8* %a, i8* %b, i8 %c)
338  br label %loop.header
339loop.header:
340  %cmp2 = icmp eq i8 %c, 0
341  br i1 %cmp2, label %loop.body, label %loop.exit
342loop.body:
343  tail call void @fun1(i8* nonnull %b)
344  tail call void @fun1(i8* nonnull %a)
345  br label %loop.header
346loop.exit:
347  tail call void @fun1(i8* nonnull %b)
348  ret void
349}
350
351; Test propagation of nonnull callsite args back to caller.
352
353declare void @use1(i8* %x)
354declare void @use2(i8* %x, i8* %y);
355declare void @use3(i8* %x, i8* %y, i8* %z);
356
357declare void @use1nonnull(i8* nonnull %x);
358declare void @use2nonnull(i8* nonnull %x, i8* nonnull %y);
359declare void @use3nonnull(i8* nonnull %x, i8* nonnull %y, i8* nonnull %z);
360
361declare i8 @use1safecall(i8* %x) readonly nounwind ; readonly+nounwind guarantees that execution continues to successor
362
363; Can't extend non-null to parent for any argument because the 2nd call is not guaranteed to execute.
364
365define void @parent1(i8* %a, i8* %b, i8* %c) {
366; BOTH-LABEL: @parent1(i8* %a, i8* %b, i8* %c)
367; BOTH-NEXT:    call void @use3(i8* %c, i8* %a, i8* %b)
368; FNATTR-NEXT:    call void @use3nonnull(i8* %b, i8* %c, i8* %a)
369; ATTRIBUTOR-NEXT:    call void @use3nonnull(i8* nonnull %b, i8* nonnull %c, i8* nonnull %a)
370; BOTH-NEXT:    ret void
371  call void @use3(i8* %c, i8* %a, i8* %b)
372  call void @use3nonnull(i8* %b, i8* %c, i8* %a)
373  ret void
374}
375
376; Extend non-null to parent for all arguments.
377
378define void @parent2(i8* %a, i8* %b, i8* %c) {
379; FNATTR-LABEL: @parent2(i8* nonnull %a, i8* nonnull %b, i8* nonnull %c)
380; FNATTR-NEXT:    call void @use3nonnull(i8* %b, i8* %c, i8* %a)
381; FNATTR-NEXT:    call void @use3(i8* %c, i8* %a, i8* %b)
382
383; ATTRIBUTOR-LABEL: @parent2(i8* nonnull %a, i8* nonnull %b, i8* nonnull %c)
384; ATTRIBUTOR-NEXT:    call void @use3nonnull(i8* nonnull %b, i8* nonnull %c, i8* nonnull %a)
385; ATTRIBUTOR-NEXT:    call void @use3(i8* nonnull %c, i8* nonnull %a, i8* nonnull %b)
386
387; BOTH-NEXT:    ret void
388  call void @use3nonnull(i8* %b, i8* %c, i8* %a)
389  call void @use3(i8* %c, i8* %a, i8* %b)
390  ret void
391}
392
393; Extend non-null to parent for 1st argument.
394
395define void @parent3(i8* %a, i8* %b, i8* %c) {
396; FNATTR-LABEL: @parent3(i8* nonnull %a, i8* %b, i8* %c)
397; FNATTR-NEXT:    call void @use1nonnull(i8* %a)
398; FNATTR-NEXT:    call void @use3(i8* %c, i8* %b, i8* %a)
399
400; ATTRIBUTOR-LABEL: @parent3(i8* nonnull %a, i8* %b, i8* %c)
401; ATTRIBUTOR-NEXT:    call void @use1nonnull(i8* nonnull %a)
402; ATTRIBUTOR-NEXT:    call void @use3(i8* %c, i8* %b, i8* nonnull %a)
403
404; BOTH-NEXT:  ret void
405
406  call void @use1nonnull(i8* %a)
407  call void @use3(i8* %c, i8* %b, i8* %a)
408  ret void
409}
410
411; Extend non-null to parent for last 2 arguments.
412
413define void @parent4(i8* %a, i8* %b, i8* %c) {
414; CHECK-LABEL: @parent4(i8* %a, i8* nonnull %b, i8* nonnull %c)
415; CHECK-NEXT:    call void @use2nonnull(i8* %c, i8* %b)
416; CHECK-NEXT:    call void @use2(i8* %a, i8* %c)
417; CHECK-NEXT:    call void @use1(i8* %b)
418
419; ATTRIBUTOR-LABEL: @parent4(i8* %a, i8* nonnull %b, i8* nonnull %c)
420; ATTRIBUTOR-NEXT:    call void @use2nonnull(i8* nonnull %c, i8* nonnull %b)
421; ATTRIBUTOR-NEXT:    call void @use2(i8* %a, i8* nonnull %c)
422; ATTRIBUTOR-NEXT:    call void @use1(i8* nonnull %b)
423
424; BOTH: ret void
425
426  call void @use2nonnull(i8* %c, i8* %b)
427  call void @use2(i8* %a, i8* %c)
428  call void @use1(i8* %b)
429  ret void
430}
431
432; The callsite must execute in order for the attribute to transfer to the parent.
433; It appears benign to extend non-null to the parent in this case, but we can't do that
434; because it would incorrectly propagate the wrong information to its callers.
435
436define void @parent5(i8* %a, i1 %a_is_notnull) {
437; BOTH: @parent5(i8* %a, i1 %a_is_notnull)
438; BOTH-NEXT:    br i1 %a_is_notnull, label %t, label %f
439; BOTH:       t:
440; FNATTR-NEXT:    call void @use1nonnull(i8* %a)
441; ATTRIBUTOR-NEXT:    call void @use1nonnull(i8* nonnull %a)
442; BOTH-NEXT:    ret void
443; BOTH:       f:
444; BOTH-NEXT:    ret void
445
446  br i1 %a_is_notnull, label %t, label %f
447t:
448  call void @use1nonnull(i8* %a)
449  ret void
450f:
451  ret void
452}
453
454; The callsite must execute in order for the attribute to transfer to the parent.
455; The volatile load can't trap, so we can guarantee that we'll get to the call.
456
457define i8 @parent6(i8* %a, i8* %b) {
458; FNATTR-LABEL: @parent6(i8* nonnull %a, i8* %b)
459; ATTRIBUTOR-LABEL: @parent6(i8* nonnull %a, i8* %b)
460; BOTH-NEXT:    [[C:%.*]] = load volatile i8, i8* %b
461; FNATTR-NEXT:    call void @use1nonnull(i8* %a)
462; ATTRIBUTOR-NEXT:    call void @use1nonnull(i8* nonnull %a)
463; BOTH-NEXT:    ret i8 [[C]]
464
465  %c = load volatile i8, i8* %b
466  call void @use1nonnull(i8* %a)
467  ret i8 %c
468}
469
470; The nonnull callsite is guaranteed to execute, so the argument must be nonnull throughout the parent.
471
472define i8 @parent7(i8* %a) {
473; FNATTR-LABEL: @parent7(i8* nonnull %a)
474; FNATTR-NEXT:    [[RET:%.*]] = call i8 @use1safecall(i8* %a)
475; FNATTR-NEXT:    call void @use1nonnull(i8* %a)
476
477
478; ATTRIBUTOR-LABEL: @parent7(i8* nonnull %a)
479; ATTRIBUTOR-NEXT:    [[RET:%.*]] = call i8 @use1safecall(i8* nonnull %a)
480; ATTRIBUTOR-NEXT:    call void @use1nonnull(i8* nonnull %a)
481
482; BOTH-NEXT: ret i8 [[RET]]
483
484  %ret = call i8 @use1safecall(i8* %a)
485  call void @use1nonnull(i8* %a)
486  ret i8 %ret
487}
488
489; Make sure that an invoke works similarly to a call.
490
491declare i32 @esfp(...)
492
493define i1 @parent8(i8* %a, i8* %bogus1, i8* %b) personality i8* bitcast (i32 (...)* @esfp to i8*){
494; BOTH-LABEL: @parent8(i8* nonnull %a, i8* nocapture readnone %bogus1, i8* nonnull %b)
495; BOTH-NEXT:  entry:
496; FNATTR-NEXT:    invoke void @use2nonnull(i8* %a, i8* %b)
497; ATTRIBUTOR-NEXT:    invoke void @use2nonnull(i8* nonnull %a, i8* nonnull %b)
498; BOTH-NEXT:    to label %cont unwind label %exc
499; BOTH:       cont:
500; BOTH-NEXT:    [[NULL_CHECK:%.*]] = icmp eq i8* %b, null
501; BOTH-NEXT:    ret i1 [[NULL_CHECK]]
502; BOTH:       exc:
503; BOTH-NEXT:    [[LP:%.*]] = landingpad { i8*, i32 }
504; BOTH-NEXT:    filter [0 x i8*] zeroinitializer
505; BOTH-NEXT:    unreachable
506
507entry:
508  invoke void @use2nonnull(i8* %a, i8* %b)
509  to label %cont unwind label %exc
510
511cont:
512  %null_check = icmp eq i8* %b, null
513  ret i1 %null_check
514
515exc:
516  %lp = landingpad { i8*, i32 }
517  filter [0 x i8*] zeroinitializer
518  unreachable
519}
520
521; BOTH: define nonnull i32* @gep1(
522define i32* @gep1(i32* %p) {
523  %q = getelementptr inbounds i32, i32* %p, i32 1
524  ret i32* %q
525}
526
527define i32* @gep1_no_null_opt(i32* %p) #0 {
528; Should't be able to derive nonnull based on gep.
529; BOTH: define i32* @gep1_no_null_opt(
530  %q = getelementptr inbounds i32, i32* %p, i32 1
531  ret i32* %q
532}
533
534; BOTH: define i32 addrspace(3)* @gep2(
535define i32 addrspace(3)* @gep2(i32 addrspace(3)* %p) {
536  %q = getelementptr inbounds i32, i32 addrspace(3)* %p, i32 1
537  ret i32 addrspace(3)* %q
538}
539
540; FNATTR:     define i32 addrspace(3)* @as(i32 addrspace(3)* readnone returned dereferenceable(4) %p)
541; FIXME: We should propagate dereferenceable here but *not* nonnull
542; ATTRIBUTOR: define dereferenceable_or_null(4) i32 addrspace(3)* @as(i32 addrspace(3)* readnone returned dereferenceable(4) dereferenceable_or_null(4) %p)
543define i32 addrspace(3)* @as(i32 addrspace(3)* dereferenceable(4) %p) {
544  ret i32 addrspace(3)* %p
545}
546
547; BOTH: define internal nonnull i32* @g2()
548define internal i32* @g2() {
549  ret i32* inttoptr (i64 4 to i32*)
550}
551
552define  i32* @g1() {
553 %c = call i32* @g2()
554  ret i32* %c
555}
556
557declare void @use_i32_ptr(i32*) readnone nounwind
558; ATTRIBUTOR: define internal void @called_by_weak(i32* nocapture nonnull readnone %a)
559define internal void @called_by_weak(i32* %a) {
560  call void @use_i32_ptr(i32* %a)
561  ret void
562}
563
564; Check we do not annotate the function interface of this weak function.
565; ATTRIBUTOR: define weak_odr void @weak_caller(i32* nonnull %a)
566define weak_odr void @weak_caller(i32* nonnull %a) {
567  call void @called_by_weak(i32* %a)
568  ret void
569}
570
571; Expect nonnull
572; ATTRIBUTOR: define internal void @control(i32* nocapture nonnull readnone align 16 dereferenceable(8) %a)
573define internal void @control(i32* dereferenceable(4) %a) {
574  call void @use_i32_ptr(i32* %a)
575  ret void
576}
577; Avoid nonnull as we do not touch naked functions
578; ATTRIBUTOR: define internal void @naked(i32* dereferenceable(4) %a)
579define internal void @naked(i32* dereferenceable(4) %a) naked {
580  call void @use_i32_ptr(i32* %a)
581  ret void
582}
583; Avoid nonnull as we do not touch optnone
584; ATTRIBUTOR: define internal void @optnone(i32* dereferenceable(4) %a)
585define internal void @optnone(i32* dereferenceable(4) %a) optnone noinline {
586  call void @use_i32_ptr(i32* %a)
587  ret void
588}
589define void @make_live(i32* nonnull dereferenceable(8) %a) {
590  call void @naked(i32* nonnull dereferenceable(8) align 16 %a)
591  call void @control(i32* nonnull dereferenceable(8) align 16 %a)
592  call void @optnone(i32* nonnull dereferenceable(8) align 16 %a)
593  ret void
594}
595
596;int f(int *u, int n){
597;  for(int i = 0;i<n;i++){
598;    h(u);
599;  }
600;  return g(nonnull u);
601;}
602declare void @h(i32*) willreturn nounwind
603declare i32 @g(i32*) willreturn nounwind
604define i32 @nonnull_exec_ctx_1(i32* %a, i32 %b) {
605; FNATTR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1
606; FNATTR-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
607; FNATTR-NEXT:  en:
608; FNATTR-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B:%.*]], 0
609; FNATTR-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
610; FNATTR:       ex:
611; FNATTR-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A:%.*]])
612; FNATTR-NEXT:    ret i32 [[TMP5]]
613; FNATTR:       hd:
614; FNATTR-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
615; FNATTR-NEXT:    tail call void @h(i32* [[A]])
616; FNATTR-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
617; FNATTR-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
618; FNATTR-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
619;
620; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1
621; ATTRIBUTOR-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
622; ATTRIBUTOR-NEXT:  en:
623; ATTRIBUTOR-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B:%.*]], 0
624; ATTRIBUTOR-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
625; ATTRIBUTOR:       ex:
626; ATTRIBUTOR-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A:%.*]])
627; ATTRIBUTOR-NEXT:    ret i32 [[TMP5]]
628; ATTRIBUTOR:       hd:
629; ATTRIBUTOR-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
630; ATTRIBUTOR-NEXT:    tail call void @h(i32* [[A]])
631; ATTRIBUTOR-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
632; ATTRIBUTOR-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
633; ATTRIBUTOR-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
634;
635en:
636  %tmp3 = icmp eq i32 %b, 0
637  br i1 %tmp3, label %ex, label %hd
638
639ex:
640  %tmp5 = tail call i32 @g(i32* nonnull %a)
641  ret i32 %tmp5
642
643hd:
644  %tmp7 = phi i32 [ %tmp8, %hd ], [ 0, %en ]
645  tail call void @h(i32* %a)
646  %tmp8 = add nuw i32 %tmp7, 1
647  %tmp9 = icmp eq i32 %tmp8, %b
648  br i1 %tmp9, label %ex, label %hd
649}
650
651define i32 @nonnull_exec_ctx_1b(i32* %a, i32 %b) {
652; FNATTR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b
653; FNATTR-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
654; FNATTR-NEXT:  en:
655; FNATTR-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B:%.*]], 0
656; FNATTR-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
657; FNATTR:       ex:
658; FNATTR-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A:%.*]])
659; FNATTR-NEXT:    ret i32 [[TMP5]]
660; FNATTR:       hd:
661; FNATTR-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
662; FNATTR-NEXT:    tail call void @h(i32* [[A]])
663; FNATTR-NEXT:    br label [[HD2]]
664; FNATTR:       hd2:
665; FNATTR-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
666; FNATTR-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
667; FNATTR-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
668;
669; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b
670; ATTRIBUTOR-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
671; ATTRIBUTOR-NEXT:  en:
672; ATTRIBUTOR-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B:%.*]], 0
673; ATTRIBUTOR-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
674; ATTRIBUTOR:       ex:
675; ATTRIBUTOR-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A:%.*]])
676; ATTRIBUTOR-NEXT:    ret i32 [[TMP5]]
677; ATTRIBUTOR:       hd:
678; ATTRIBUTOR-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
679; ATTRIBUTOR-NEXT:    tail call void @h(i32* [[A]])
680; ATTRIBUTOR-NEXT:    br label [[HD2]]
681; ATTRIBUTOR:       hd2:
682; ATTRIBUTOR-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
683; ATTRIBUTOR-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
684; ATTRIBUTOR-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
685;
686en:
687  %tmp3 = icmp eq i32 %b, 0
688  br i1 %tmp3, label %ex, label %hd
689
690ex:
691  %tmp5 = tail call i32 @g(i32* nonnull %a)
692  ret i32 %tmp5
693
694hd:
695  %tmp7 = phi i32 [ %tmp8, %hd2 ], [ 0, %en ]
696  tail call void @h(i32* %a)
697  br label %hd2
698
699hd2:
700  %tmp8 = add nuw i32 %tmp7, 1
701  %tmp9 = icmp eq i32 %tmp8, %b
702  br i1 %tmp9, label %ex, label %hd
703}
704
705define i32 @nonnull_exec_ctx_2(i32* %a, i32 %b) willreturn nounwind {
706; FNATTR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2
707; FNATTR-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
708; FNATTR-NEXT:  en:
709; FNATTR-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B:%.*]], 0
710; FNATTR-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
711; FNATTR:       ex:
712; FNATTR-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A:%.*]])
713; FNATTR-NEXT:    ret i32 [[TMP5]]
714; FNATTR:       hd:
715; FNATTR-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
716; FNATTR-NEXT:    tail call void @h(i32* [[A]])
717; FNATTR-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
718; FNATTR-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
719; FNATTR-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
720;
721; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2
722; ATTRIBUTOR-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
723; ATTRIBUTOR-NEXT:  en:
724; ATTRIBUTOR-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B:%.*]], 0
725; ATTRIBUTOR-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
726; ATTRIBUTOR:       ex:
727; ATTRIBUTOR-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A:%.*]])
728; ATTRIBUTOR-NEXT:    ret i32 [[TMP5]]
729; ATTRIBUTOR:       hd:
730; ATTRIBUTOR-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
731; ATTRIBUTOR-NEXT:    tail call void @h(i32* nonnull [[A]])
732; ATTRIBUTOR-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
733; ATTRIBUTOR-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
734; ATTRIBUTOR-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
735;
736en:
737  %tmp3 = icmp eq i32 %b, 0
738  br i1 %tmp3, label %ex, label %hd
739
740ex:
741  %tmp5 = tail call i32 @g(i32* nonnull %a)
742  ret i32 %tmp5
743
744hd:
745  %tmp7 = phi i32 [ %tmp8, %hd ], [ 0, %en ]
746  tail call void @h(i32* %a)
747  %tmp8 = add nuw i32 %tmp7, 1
748  %tmp9 = icmp eq i32 %tmp8, %b
749  br i1 %tmp9, label %ex, label %hd
750}
751
752define i32 @nonnull_exec_ctx_2b(i32* %a, i32 %b) willreturn nounwind {
753; FNATTR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2b
754; FNATTR-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
755; FNATTR-NEXT:  en:
756; FNATTR-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B:%.*]], 0
757; FNATTR-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
758; FNATTR:       ex:
759; FNATTR-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A:%.*]])
760; FNATTR-NEXT:    ret i32 [[TMP5]]
761; FNATTR:       hd:
762; FNATTR-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
763; FNATTR-NEXT:    tail call void @h(i32* [[A]])
764; FNATTR-NEXT:    br label [[HD2]]
765; FNATTR:       hd2:
766; FNATTR-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
767; FNATTR-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
768; FNATTR-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
769;
770; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2b
771; ATTRIBUTOR-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
772; ATTRIBUTOR-NEXT:  en:
773; ATTRIBUTOR-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B:%.*]], 0
774; ATTRIBUTOR-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
775; ATTRIBUTOR:       ex:
776; ATTRIBUTOR-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A:%.*]])
777; ATTRIBUTOR-NEXT:    ret i32 [[TMP5]]
778; ATTRIBUTOR:       hd:
779; ATTRIBUTOR-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
780; ATTRIBUTOR-NEXT:    tail call void @h(i32* nonnull [[A]])
781; ATTRIBUTOR-NEXT:    br label [[HD2]]
782; ATTRIBUTOR:       hd2:
783; ATTRIBUTOR-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
784; ATTRIBUTOR-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
785; ATTRIBUTOR-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
786;
787en:
788  %tmp3 = icmp eq i32 %b, 0
789  br i1 %tmp3, label %ex, label %hd
790
791ex:
792  %tmp5 = tail call i32 @g(i32* nonnull %a)
793  ret i32 %tmp5
794
795hd:
796  %tmp7 = phi i32 [ %tmp8, %hd2 ], [ 0, %en ]
797  tail call void @h(i32* %a)
798  br label %hd2
799
800hd2:
801  %tmp8 = add nuw i32 %tmp7, 1
802  %tmp9 = icmp eq i32 %tmp8, %b
803  br i1 %tmp9, label %ex, label %hd
804}
805
806; Original from PR43833
807declare void @sink(i32*)
808
809; FIXME: the sink argument should be marked nonnull as in @PR43833_simple.
810define void @PR43833(i32* %0, i32 %1) {
811; BOTH-LABEL: @PR43833(
812; BOTH-NEXT:    [[TMP3:%.*]] = icmp sgt i32 [[TMP1:%.*]], 1
813; BOTH-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
814; BOTH:       4:
815; BOTH-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
816; BOTH-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0:%.*]], i64 [[TMP5]]
817; BOTH-NEXT:    br label [[TMP8:%.*]]
818; BOTH:       7:
819; BOTH-NEXT:    ret void
820; BOTH:       8:
821; BOTH-NEXT:    [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
822; BOTH-NEXT:    tail call void @sink(i32* [[TMP6]])
823; BOTH-NEXT:    [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
824; BOTH-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
825; BOTH-NEXT:    br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
826;
827  %3 = icmp sgt i32 %1, 1
828  br i1 %3, label %4, label %7
829
8304:                                                ; preds = %2
831  %5 = zext i32 %1 to i64
832  %6 = getelementptr inbounds i32, i32* %0, i64 %5
833  br label %8
834
8357:                                                ; preds = %8, %2
836  ret void
837
8388:                                                ; preds = %8, %4
839  %9 = phi i32 [ 1, %4 ], [ %10, %8 ]
840  tail call void @sink(i32* %6)
841  %10 = add nuw nsw i32 %9, 1
842  %11 = icmp eq i32 %10, %1
843  br i1 %11, label %7, label %8
844}
845
846; Adjusted from PR43833
847define void @PR43833_simple(i32* %0, i32 %1) {
848; OLD-LABEL: @PR43833_simple(
849; OLD-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP1:%.*]], 0
850; OLD-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
851; OLD:       4:
852; OLD-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
853; OLD-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0:%.*]], i64 [[TMP5]]
854; OLD-NEXT:    br label [[TMP8:%.*]]
855; OLD:       7:
856; OLD-NEXT:    ret void
857; OLD:       8:
858; OLD-NEXT:    [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
859; OLD-NEXT:    tail call void @sink(i32* [[TMP6]])
860; OLD-NEXT:    [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
861; OLD-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
862; OLD-NEXT:    br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
863;
864; ATTRIBUTOR_NPM-LABEL: @PR43833_simple(
865; ATTRIBUTOR_NPM-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP1:%.*]], 0
866; ATTRIBUTOR_NPM-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
867; ATTRIBUTOR_NPM:       4:
868; ATTRIBUTOR_NPM-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
869; ATTRIBUTOR_NPM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0:%.*]], i64 [[TMP5]]
870; ATTRIBUTOR_NPM-NEXT:    br label [[TMP8:%.*]]
871; ATTRIBUTOR_NPM:       7:
872; ATTRIBUTOR_NPM-NEXT:    ret void
873; ATTRIBUTOR_NPM:       8:
874; ATTRIBUTOR_NPM-NEXT:    [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
875; ATTRIBUTOR_NPM-NEXT:    tail call void @sink(i32* nonnull [[TMP6]])
876; ATTRIBUTOR_NPM-NEXT:    [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
877; ATTRIBUTOR_NPM-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
878; ATTRIBUTOR_NPM-NEXT:    br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
879;
880  %3 = icmp ne i32 %1, 0
881  br i1 %3, label %4, label %7
882
8834:                                                ; preds = %2
884  %5 = zext i32 %1 to i64
885  %6 = getelementptr inbounds i32, i32* %0, i64 %5
886  br label %8
887
8887:                                                ; preds = %8, %2
889  ret void
890
8918:                                                ; preds = %8, %4
892  %9 = phi i32 [ 1, %4 ], [ %10, %8 ]
893  tail call void @sink(i32* %6)
894  %10 = add nuw nsw i32 %9, 1
895  %11 = icmp eq i32 %10, %1
896  br i1 %11, label %7, label %8
897}
898
899attributes #0 = { "null-pointer-is-valid"="true" }
900attributes #1 = { nounwind willreturn}
901