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