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=15 -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=15 -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
7
8target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
9
10declare nonnull i8* @ret_nonnull()
11declare void @llvm.assume(i1)
12
13; Return a pointer trivially nonnull (call return attribute)
14define i8* @test1() {
15; CHECK-LABEL: define {{[^@]+}}@test1() {
16; CHECK-NEXT:    [[RET:%.*]] = call nonnull i8* @ret_nonnull()
17; CHECK-NEXT:    ret i8* [[RET]]
18;
19  %ret = call i8* @ret_nonnull()
20  ret i8* %ret
21}
22
23; Return a pointer trivially nonnull (argument attribute)
24define i8* @test2(i8* nonnull %p) {
25; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
26; CHECK-LABEL: define {{[^@]+}}@test2
27; CHECK-SAME: (i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1:[0-9]+]] {
28; CHECK-NEXT:    ret i8* [[P]]
29;
30  ret i8* %p
31}
32
33define i8* @test2A(i1 %c, i8* %ret) {
34; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
35; CHECK-LABEL: define {{[^@]+}}@test2A
36; CHECK-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR2:[0-9]+]] {
37; CHECK-NEXT:    br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
38; CHECK:       A:
39; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR13:[0-9]+]] [ "nonnull"(i8* [[RET]]) ]
40; CHECK-NEXT:    ret i8* [[RET]]
41; CHECK:       B:
42; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "nonnull"(i8* [[RET]]) ]
43; CHECK-NEXT:    ret i8* [[RET]]
44;
45  br i1 %c, label %A, label %B
46A:
47  call void @llvm.assume(i1 true) [ "nonnull"(i8* %ret) ]
48  ret i8* %ret
49B:
50  call void @llvm.assume(i1 true) [ "nonnull"(i8* %ret) ]
51  ret i8* %ret
52}
53
54define i8* @test2B(i1 %c, i8* %ret) {
55; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
56; CHECK-LABEL: define {{[^@]+}}@test2B
57; CHECK-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR2]] {
58; CHECK-NEXT:    br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
59; CHECK:       A:
60; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "dereferenceable"(i8* [[RET]], i32 4) ]
61; CHECK-NEXT:    ret i8* [[RET]]
62; CHECK:       B:
63; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "dereferenceable"(i8* [[RET]], i32 4) ]
64; CHECK-NEXT:    ret i8* [[RET]]
65;
66  br i1 %c, label %A, label %B
67A:
68  call void @llvm.assume(i1 true) [ "dereferenceable"(i8* %ret, i32 4) ]
69  ret i8* %ret
70B:
71  call void @llvm.assume(i1 true) [ "dereferenceable"(i8* %ret, i32 4) ]
72  ret i8* %ret
73}
74
75; Given an SCC where one of the functions can not be marked nonnull,
76; can we still mark the other one which is trivially nonnull
77define i8* @scc_binder(i1 %c) {
78; IS________OPM-LABEL: define {{[^@]+}}@scc_binder
79; IS________OPM-SAME: (i1 [[C:%.*]]) {
80; IS________OPM-NEXT:    br i1 [[C]], label [[REC:%.*]], label [[END:%.*]]
81; IS________OPM:       rec:
82; IS________OPM-NEXT:    [[TMP1:%.*]] = call i8* @test3(i1 [[C]])
83; IS________OPM-NEXT:    br label [[END]]
84; IS________OPM:       end:
85; IS________OPM-NEXT:    ret i8* null
86;
87; IS________NPM-LABEL: define {{[^@]+}}@scc_binder
88; IS________NPM-SAME: (i1 [[C:%.*]]) {
89; IS________NPM-NEXT:    br i1 [[C]], label [[REC:%.*]], label [[END:%.*]]
90; IS________NPM:       rec:
91; IS________NPM-NEXT:    [[TMP1:%.*]] = call i8* @test3(i1 noundef [[C]])
92; IS________NPM-NEXT:    br label [[END]]
93; IS________NPM:       end:
94; IS________NPM-NEXT:    ret i8* null
95;
96  br i1 %c, label %rec, label %end
97rec:
98  call i8* @test3(i1 %c)
99  br label %end
100end:
101  ret i8* null
102}
103
104define i8* @test3(i1 %c) {
105; CHECK-LABEL: define {{[^@]+}}@test3
106; CHECK-SAME: (i1 [[C:%.*]]) {
107; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @scc_binder(i1 [[C]])
108; CHECK-NEXT:    [[RET:%.*]] = call nonnull i8* @ret_nonnull()
109; CHECK-NEXT:    ret i8* [[RET]]
110;
111  call i8* @scc_binder(i1 %c)
112  %ret = call i8* @ret_nonnull()
113  ret i8* %ret
114}
115
116; Given a mutual recursive set of functions, we can mark them
117; nonnull if neither can ever return null.  (In this case, they
118; just never return period.)
119define i8* @test4_helper() {
120; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
121; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper
122; NOT_CGSCC_NPM-SAME: () #[[ATTR3:[0-9]+]] {
123; NOT_CGSCC_NPM-NEXT:    ret i8* undef
124;
125; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
126; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper
127; IS__CGSCC_NPM-SAME: () #[[ATTR1]] {
128; IS__CGSCC_NPM-NEXT:    ret i8* undef
129;
130  %ret = call i8* @test4()
131  ret i8* %ret
132}
133
134define i8* @test4() {
135; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
136; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4
137; NOT_CGSCC_NPM-SAME: () #[[ATTR3]] {
138; NOT_CGSCC_NPM-NEXT:    ret i8* undef
139;
140; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
141; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4
142; IS__CGSCC_NPM-SAME: () #[[ATTR1]] {
143; IS__CGSCC_NPM-NEXT:    ret i8* undef
144;
145  %ret = call i8* @test4_helper()
146  ret i8* %ret
147}
148
149; Given a mutual recursive set of functions which *can* return null
150; make sure we haven't marked them as nonnull.
151define i8* @test5_helper(i1 %c) {
152; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
153; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test5_helper
154; NOT_CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {
155; NOT_CGSCC_NPM-NEXT:    br i1 [[C]], label [[REC:%.*]], label [[END:%.*]]
156; NOT_CGSCC_NPM:       rec:
157; NOT_CGSCC_NPM-NEXT:    br label [[END]]
158; NOT_CGSCC_NPM:       end:
159; NOT_CGSCC_NPM-NEXT:    ret i8* null
160;
161; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
162; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test5_helper
163; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
164; IS__CGSCC_NPM-NEXT:    br i1 [[C]], label [[REC:%.*]], label [[END:%.*]]
165; IS__CGSCC_NPM:       rec:
166; IS__CGSCC_NPM-NEXT:    br label [[END]]
167; IS__CGSCC_NPM:       end:
168; IS__CGSCC_NPM-NEXT:    ret i8* null
169;
170  br i1 %c, label %rec, label %end
171rec:
172  %ret = call i8* @test5(i1 %c)
173  br label %end
174end:
175  ret i8* null
176}
177
178define i8* @test5(i1 %c) {
179; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
180; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test5
181; NOT_CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {
182; NOT_CGSCC_NPM-NEXT:    ret i8* null
183;
184; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
185; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test5
186; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
187; IS__CGSCC_NPM-NEXT:    ret i8* null
188;
189  %ret = call i8* @test5_helper(i1 %c)
190  ret i8* %ret
191}
192
193; Local analysis, but going through a self recursive phi
194define i8* @test6a() {
195;
196; NOT_CGSCC_NPM: Function Attrs: noreturn
197; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6a
198; NOT_CGSCC_NPM-SAME: () #[[ATTR4:[0-9]+]] {
199; NOT_CGSCC_NPM-NEXT:  entry:
200; NOT_CGSCC_NPM-NEXT:    [[RET:%.*]] = call i8* @ret_nonnull()
201; NOT_CGSCC_NPM-NEXT:    br label [[LOOP:%.*]]
202; NOT_CGSCC_NPM:       loop:
203; NOT_CGSCC_NPM-NEXT:    unreachable
204; NOT_CGSCC_NPM:       exit:
205; NOT_CGSCC_NPM-NEXT:    unreachable
206;
207; IS__CGSCC_NPM: Function Attrs: noreturn
208; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6a
209; IS__CGSCC_NPM-SAME: () #[[ATTR3:[0-9]+]] {
210; IS__CGSCC_NPM-NEXT:  entry:
211; IS__CGSCC_NPM-NEXT:    [[RET:%.*]] = call i8* @ret_nonnull()
212; IS__CGSCC_NPM-NEXT:    br label [[LOOP:%.*]]
213; IS__CGSCC_NPM:       loop:
214; IS__CGSCC_NPM-NEXT:    unreachable
215; IS__CGSCC_NPM:       exit:
216; IS__CGSCC_NPM-NEXT:    unreachable
217;
218entry:
219  %ret = call i8* @ret_nonnull()
220  br label %loop
221loop:
222  %phi = phi i8* [%ret, %entry], [%phi, %loop]
223  br i1 undef, label %loop, label %exit
224exit:
225  ret i8* %phi
226}
227
228define i8* @test6b(i1 %c) {
229; IS________OPM-LABEL: define {{[^@]+}}@test6b
230; IS________OPM-SAME: (i1 [[C:%.*]]) {
231; IS________OPM-NEXT:  entry:
232; IS________OPM-NEXT:    [[RET:%.*]] = call nonnull i8* @ret_nonnull()
233; IS________OPM-NEXT:    br label [[LOOP:%.*]]
234; IS________OPM:       loop:
235; IS________OPM-NEXT:    [[PHI:%.*]] = phi i8* [ [[RET]], [[ENTRY:%.*]] ], [ [[PHI]], [[LOOP]] ]
236; IS________OPM-NEXT:    br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
237; IS________OPM:       exit:
238; IS________OPM-NEXT:    ret i8* [[PHI]]
239;
240; IS________NPM-LABEL: define {{[^@]+}}@test6b
241; IS________NPM-SAME: (i1 [[C:%.*]]) {
242; IS________NPM-NEXT:  entry:
243; IS________NPM-NEXT:    [[RET:%.*]] = call nonnull i8* @ret_nonnull()
244; IS________NPM-NEXT:    br label [[LOOP:%.*]]
245; IS________NPM:       loop:
246; IS________NPM-NEXT:    [[PHI:%.*]] = phi i8* [ [[RET]], [[ENTRY:%.*]] ], [ [[RET]], [[LOOP]] ]
247; IS________NPM-NEXT:    br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
248; IS________NPM:       exit:
249; IS________NPM-NEXT:    ret i8* [[RET]]
250;
251entry:
252  %ret = call i8* @ret_nonnull()
253  br label %loop
254loop:
255  %phi = phi i8* [%ret, %entry], [%phi, %loop]
256  br i1 %c, label %loop, label %exit
257exit:
258  ret i8* %phi
259}
260
261define i8* @test7(i8* %a) {
262; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
263; CHECK-LABEL: define {{[^@]+}}@test7
264; CHECK-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
265; CHECK-NEXT:    ret i8* [[A]]
266;
267  %b = getelementptr inbounds i8, i8* %a, i64 0
268  ret i8* %b
269}
270
271define i8* @test8(i8* %a) {
272; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
273; CHECK-LABEL: define {{[^@]+}}@test8
274; CHECK-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
275; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 1
276; CHECK-NEXT:    ret i8* [[B]]
277;
278  %b = getelementptr inbounds i8, i8* %a, i64 1
279  ret i8* %b
280}
281
282define i8* @test9(i8* %a, i64 %n) {
283; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
284; CHECK-LABEL: define {{[^@]+}}@test9
285; CHECK-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR1]] {
286; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]]
287; CHECK-NEXT:    ret i8* [[B]]
288;
289  %b = getelementptr inbounds i8, i8* %a, i64 %n
290  ret i8* %b
291}
292
293; ATTRIBUTOR_OPM: define i8* @test10
294; ATTRIBUTOR_NPM: define nonnull i8* @test10
295define i8* @test10(i8* %a, i64 %n) {
296; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
297; CHECK-LABEL: define {{[^@]+}}@test10
298; CHECK-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR2]] {
299; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[N]], 0
300; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[CMP]]) #[[ATTR13]]
301; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]]
302; CHECK-NEXT:    ret i8* [[B]]
303;
304  %cmp = icmp ne i64 %n, 0
305  call void @llvm.assume(i1 %cmp)
306  %b = getelementptr inbounds i8, i8* %a, i64 %n
307  ret i8* %b
308}
309
310; TEST 11
311; char* test11(char *p) {
312;   return p? p: nonnull();
313; }
314; FIXME: missing nonnull
315define i8* @test11(i8*) local_unnamed_addr {
316; CHECK-LABEL: define {{[^@]+}}@test11
317; CHECK-SAME: (i8* [[TMP0:%.*]]) local_unnamed_addr {
318; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
319; CHECK-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
320; CHECK:       3:
321; CHECK-NEXT:    [[TMP4:%.*]] = tail call i8* @ret_nonnull()
322; CHECK-NEXT:    br label [[TMP5]]
323; CHECK:       5:
324; CHECK-NEXT:    [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ]
325; CHECK-NEXT:    ret i8* [[TMP6]]
326;
327  %2 = icmp eq i8* %0, null
328  br i1 %2, label %3, label %5
329
330; <label>:3:                                      ; preds = %1
331  %4 = tail call i8* @ret_nonnull()
332  br label %5
333
334; <label>:5:                                      ; preds = %3, %1
335  %6 = phi i8* [ %4, %3 ], [ %0, %1 ]
336  ret i8* %6
337}
338
339; TEST 12
340; Simple CallSite Test
341declare void @test12_helper(i8*)
342define void @test12(i8* nonnull %a) {
343; CHECK-LABEL: define {{[^@]+}}@test12
344; CHECK-SAME: (i8* nonnull [[A:%.*]]) {
345; CHECK-NEXT:    tail call void @test12_helper(i8* nonnull [[A]])
346; CHECK-NEXT:    ret void
347;
348  tail call void @test12_helper(i8* %a)
349  ret void
350}
351
352; TEST 13
353; Simple Argument Tests
354declare i8* @unknown()
355define void @test13_helper() {
356; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test13_helper() {
357; NOT_CGSCC_NPM-NEXT:    [[NONNULLPTR:%.*]] = tail call nonnull i8* @ret_nonnull()
358; NOT_CGSCC_NPM-NEXT:    [[MAYBENULLPTR:%.*]] = tail call i8* @unknown()
359; NOT_CGSCC_NPM-NEXT:    tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]]) #[[ATTR5:[0-9]+]]
360; NOT_CGSCC_NPM-NEXT:    tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]]) #[[ATTR5]]
361; NOT_CGSCC_NPM-NEXT:    ret void
362;
363; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test13_helper() {
364; IS__CGSCC_NPM-NEXT:    [[NONNULLPTR:%.*]] = tail call nonnull i8* @ret_nonnull()
365; IS__CGSCC_NPM-NEXT:    [[MAYBENULLPTR:%.*]] = tail call i8* @unknown()
366; IS__CGSCC_NPM-NEXT:    tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]]) #[[ATTR4:[0-9]+]]
367; IS__CGSCC_NPM-NEXT:    tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]]) #[[ATTR4]]
368; IS__CGSCC_NPM-NEXT:    ret void
369;
370  %nonnullptr = tail call i8* @ret_nonnull()
371  %maybenullptr = tail call i8* @unknown()
372  tail call void @test13(i8* %nonnullptr, i8* %nonnullptr, i8* %maybenullptr)
373  tail call void @test13(i8* %nonnullptr, i8* %maybenullptr, i8* %nonnullptr)
374  ret void
375}
376define internal void @test13(i8* %a, i8* %b, i8* %c) {
377;
378; NOT_CGSCC_NPM: Function Attrs: nounwind
379; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test13
380; NOT_CGSCC_NPM-SAME: (i8* noalias nocapture nofree nonnull readnone [[A:%.*]], i8* noalias nocapture nofree readnone [[B:%.*]], i8* noalias nocapture nofree readnone [[C:%.*]]) #[[ATTR5]] {
381; NOT_CGSCC_NPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[A]]) #[[ATTR5]]
382; NOT_CGSCC_NPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[B]]) #[[ATTR5]]
383; NOT_CGSCC_NPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[C]]) #[[ATTR5]]
384; NOT_CGSCC_NPM-NEXT:    ret void
385;
386; IS__CGSCC_NPM: Function Attrs: nounwind
387; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test13
388; IS__CGSCC_NPM-SAME: (i8* noalias nocapture nofree nonnull readnone [[A:%.*]], i8* noalias nocapture nofree readnone [[B:%.*]], i8* noalias nocapture nofree readnone [[C:%.*]]) #[[ATTR4]] {
389; IS__CGSCC_NPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[A]]) #[[ATTR4]]
390; IS__CGSCC_NPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[B]]) #[[ATTR4]]
391; IS__CGSCC_NPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[C]]) #[[ATTR4]]
392; IS__CGSCC_NPM-NEXT:    ret void
393;
394  call void @use_i8_ptr(i8* %a)
395  call void @use_i8_ptr(i8* %b)
396  call void @use_i8_ptr(i8* %c)
397  ret void
398}
399
400declare nonnull i8* @nonnull()
401
402; TEST 14
403; Complex propagation
404; Argument of f1, f2, f3 can be marked with nonnull.
405
406; * Argument
407; 1. In f1:bb6, %arg can be marked with nonnull because of the comparison in bb1
408; 2. Because f2 is internal function, f2(i32* %arg) -> @f2(i32* nonnull %arg)
409; 3. In f1:bb4 %tmp5 is nonnull and f3 is internal function.
410;    Then, f3(i32* %arg) -> @f3(i32* nonnull %arg)
411; 4. We get nonnull in whole f1 call sites so f1(i32* %arg) -> @f1(i32* nonnull %arg)
412
413
414define internal i32* @f1(i32* %arg) {
415; FIXME: missing nonnull It should be nonnull @f1(i32* nonnull readonly %arg)
416; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly
417; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@f1
418; NOT_CGSCC_NPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR6:[0-9]+]] {
419; NOT_CGSCC_NPM-NEXT:  bb:
420; NOT_CGSCC_NPM-NEXT:    [[TMP:%.*]] = icmp eq i32* [[ARG]], null
421; NOT_CGSCC_NPM-NEXT:    br i1 [[TMP]], label [[BB9:%.*]], label [[BB1:%.*]]
422; NOT_CGSCC_NPM:       bb1:
423; NOT_CGSCC_NPM-NEXT:    [[TMP2:%.*]] = load i32, i32* [[ARG]], align 4
424; NOT_CGSCC_NPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
425; NOT_CGSCC_NPM-NEXT:    br i1 [[TMP3]], label [[BB6:%.*]], label [[BB4:%.*]]
426; NOT_CGSCC_NPM:       bb4:
427; NOT_CGSCC_NPM-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i32, i32* [[ARG]], i64 1
428; NOT_CGSCC_NPM-NEXT:    [[TMP5B:%.*]] = tail call i32* @f3(i32* nofree nonnull readonly [[TMP5]]) #[[ATTR14:[0-9]+]]
429; NOT_CGSCC_NPM-NEXT:    [[TMP5C:%.*]] = getelementptr inbounds i32, i32* [[TMP5B]], i64 -1
430; NOT_CGSCC_NPM-NEXT:    br label [[BB9]]
431; NOT_CGSCC_NPM:       bb6:
432; NOT_CGSCC_NPM-NEXT:    [[TMP7:%.*]] = tail call i32* @f2(i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR14]]
433; NOT_CGSCC_NPM-NEXT:    ret i32* [[TMP7]]
434; NOT_CGSCC_NPM:       bb9:
435; NOT_CGSCC_NPM-NEXT:    [[TMP10:%.*]] = phi i32* [ [[TMP5C]], [[BB4]] ], [ inttoptr (i64 4 to i32*), [[BB:%.*]] ]
436; NOT_CGSCC_NPM-NEXT:    ret i32* [[TMP10]]
437;
438; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly
439; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1
440; IS__CGSCC_NPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR5:[0-9]+]] {
441; IS__CGSCC_NPM-NEXT:  bb:
442; IS__CGSCC_NPM-NEXT:    [[TMP:%.*]] = icmp eq i32* [[ARG]], null
443; IS__CGSCC_NPM-NEXT:    br i1 [[TMP]], label [[BB9:%.*]], label [[BB1:%.*]]
444; IS__CGSCC_NPM:       bb1:
445; IS__CGSCC_NPM-NEXT:    [[TMP2:%.*]] = load i32, i32* [[ARG]], align 4
446; IS__CGSCC_NPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
447; IS__CGSCC_NPM-NEXT:    br i1 [[TMP3]], label [[BB6:%.*]], label [[BB4:%.*]]
448; IS__CGSCC_NPM:       bb4:
449; IS__CGSCC_NPM-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i32, i32* [[ARG]], i64 1
450; IS__CGSCC_NPM-NEXT:    [[TMP5B:%.*]] = tail call i32* @f3(i32* nofree nonnull readonly [[TMP5]]) #[[ATTR14:[0-9]+]]
451; IS__CGSCC_NPM-NEXT:    [[TMP5C:%.*]] = getelementptr inbounds i32, i32* [[TMP5B]], i64 -1
452; IS__CGSCC_NPM-NEXT:    br label [[BB9]]
453; IS__CGSCC_NPM:       bb6:
454; IS__CGSCC_NPM-NEXT:    [[TMP7:%.*]] = tail call i32* @f2(i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR14]]
455; IS__CGSCC_NPM-NEXT:    ret i32* [[TMP7]]
456; IS__CGSCC_NPM:       bb9:
457; IS__CGSCC_NPM-NEXT:    [[TMP10:%.*]] = phi i32* [ [[TMP5C]], [[BB4]] ], [ inttoptr (i64 4 to i32*), [[BB:%.*]] ]
458; IS__CGSCC_NPM-NEXT:    ret i32* [[TMP10]]
459;
460
461bb:
462  %tmp = icmp eq i32* %arg, null
463  br i1 %tmp, label %bb9, label %bb1
464
465bb1:                                              ; preds = %bb
466  %tmp2 = load i32, i32* %arg, align 4
467  %tmp3 = icmp eq i32 %tmp2, 0
468  br i1 %tmp3, label %bb6, label %bb4
469
470bb4:                                              ; preds = %bb1
471  %tmp5 = getelementptr inbounds i32, i32* %arg, i64 1
472  %tmp5b = tail call i32* @f3(i32* %tmp5)
473  %tmp5c = getelementptr inbounds i32, i32* %tmp5b, i64 -1
474  br label %bb9
475
476bb6:                                              ; preds = %bb1
477  %tmp7 = tail call i32* @f2(i32* %arg)
478  ret i32* %tmp7
479
480bb9:                                              ; preds = %bb4, %bb
481  %tmp10 = phi i32* [ %tmp5c, %bb4 ], [ inttoptr (i64 4 to i32*), %bb ]
482  ret i32* %tmp10
483}
484
485define internal i32* @f2(i32* %arg) {
486; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly
487; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@f2
488; NOT_CGSCC_NPM-SAME: (i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR6]] {
489; NOT_CGSCC_NPM-NEXT:  bb:
490; NOT_CGSCC_NPM-NEXT:    [[TMP:%.*]] = tail call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR14]]
491; NOT_CGSCC_NPM-NEXT:    ret i32* [[TMP]]
492;
493; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly
494; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f2
495; IS__CGSCC_NPM-SAME: (i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR5]] {
496; IS__CGSCC_NPM-NEXT:  bb:
497; IS__CGSCC_NPM-NEXT:    [[TMP:%.*]] = tail call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR14]]
498; IS__CGSCC_NPM-NEXT:    ret i32* [[TMP]]
499;
500bb:
501  %tmp = tail call i32* @f1(i32* %arg)
502  ret i32* %tmp
503}
504
505define dso_local noalias i32* @f3(i32* %arg) {
506; FIXME: missing nonnull. It should be nonnull @f3(i32* nonnull readonly %arg)
507; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly
508; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@f3
509; NOT_CGSCC_NPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR6]] {
510; NOT_CGSCC_NPM-NEXT:  bb:
511; NOT_CGSCC_NPM-NEXT:    [[TMP:%.*]] = call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR14]]
512; NOT_CGSCC_NPM-NEXT:    ret i32* [[TMP]]
513;
514; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly
515; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f3
516; IS__CGSCC_NPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR5]] {
517; IS__CGSCC_NPM-NEXT:  bb:
518; IS__CGSCC_NPM-NEXT:    [[TMP:%.*]] = call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR14]]
519; IS__CGSCC_NPM-NEXT:    ret i32* [[TMP]]
520;
521bb:
522; FIXME: missing nonnull. It should be @f1(i32* nonnull readonly %arg)
523  %tmp = call i32* @f1(i32* %arg)
524  ret i32* %tmp
525}
526
527; TEST 15
528define void @f15(i8* %arg) {
529; CHECK-LABEL: define {{[^@]+}}@f15
530; CHECK-SAME: (i8* noundef nonnull dereferenceable(4) [[ARG:%.*]]) {
531; CHECK-NEXT:    tail call void @use1(i8* noundef nonnull dereferenceable(4) [[ARG]])
532; CHECK-NEXT:    ret void
533;
534
535  tail call void @use1(i8* dereferenceable(4) %arg)
536  ret void
537}
538
539declare void @fun0() #1
540declare void @fun1(i8*) #1
541declare void @fun2(i8*, i8*) #1
542declare void @fun3(i8*, i8*, i8*) #1
543; TEST 16 simple path test
544; if(..)
545;   fun2(nonnull %a, nonnull %b)
546; else
547;   fun2(nonnull %a, %b)
548; We can say that %a is nonnull but %b is not.
549define void @f16(i8* %a, i8 * %b, i8 %c) {
550; NOT_CGSCC_NPM: Function Attrs: nounwind willreturn
551; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@f16
552; NOT_CGSCC_NPM-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR7:[0-9]+]] {
553; NOT_CGSCC_NPM-NEXT:    [[CMP:%.*]] = icmp eq i8 [[C]], 0
554; NOT_CGSCC_NPM-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
555; NOT_CGSCC_NPM:       if.then:
556; NOT_CGSCC_NPM-NEXT:    tail call void @fun2(i8* nonnull [[A]], i8* nonnull [[B]]) #[[ATTR7]]
557; NOT_CGSCC_NPM-NEXT:    ret void
558; NOT_CGSCC_NPM:       if.else:
559; NOT_CGSCC_NPM-NEXT:    tail call void @fun2(i8* nonnull [[A]], i8* [[B]]) #[[ATTR7]]
560; NOT_CGSCC_NPM-NEXT:    ret void
561;
562; IS__CGSCC_NPM: Function Attrs: nounwind willreturn
563; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f16
564; IS__CGSCC_NPM-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR6:[0-9]+]] {
565; IS__CGSCC_NPM-NEXT:    [[CMP:%.*]] = icmp eq i8 [[C]], 0
566; IS__CGSCC_NPM-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
567; IS__CGSCC_NPM:       if.then:
568; IS__CGSCC_NPM-NEXT:    tail call void @fun2(i8* nonnull [[A]], i8* nonnull [[B]]) #[[ATTR6]]
569; IS__CGSCC_NPM-NEXT:    ret void
570; IS__CGSCC_NPM:       if.else:
571; IS__CGSCC_NPM-NEXT:    tail call void @fun2(i8* nonnull [[A]], i8* [[B]]) #[[ATTR6]]
572; IS__CGSCC_NPM-NEXT:    ret void
573;
574  %cmp = icmp eq i8 %c, 0
575  br i1 %cmp, label %if.then, label %if.else
576if.then:
577  tail call void @fun2(i8* nonnull %a, i8* nonnull %b)
578  ret void
579if.else:
580  tail call void @fun2(i8* nonnull %a, i8* %b)
581  ret void
582}
583; TEST 17 explore child BB test
584; if(..)
585;    ... (willreturn & nounwind)
586; else
587;    ... (willreturn & nounwind)
588; fun1(nonnull %a)
589; We can say that %a is nonnull
590define void @f17(i8* %a, i8 %c) {
591;
592; NOT_CGSCC_NPM: Function Attrs: nounwind willreturn
593; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@f17
594; NOT_CGSCC_NPM-SAME: (i8* nonnull [[A:%.*]], i8 [[C:%.*]]) #[[ATTR7]] {
595; NOT_CGSCC_NPM-NEXT:    [[CMP:%.*]] = icmp eq i8 [[C]], 0
596; NOT_CGSCC_NPM-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
597; NOT_CGSCC_NPM:       if.then:
598; NOT_CGSCC_NPM-NEXT:    tail call void @fun0() #[[ATTR7]]
599; NOT_CGSCC_NPM-NEXT:    br label [[CONT:%.*]]
600; NOT_CGSCC_NPM:       if.else:
601; NOT_CGSCC_NPM-NEXT:    tail call void @fun0() #[[ATTR7]]
602; NOT_CGSCC_NPM-NEXT:    br label [[CONT]]
603; NOT_CGSCC_NPM:       cont:
604; NOT_CGSCC_NPM-NEXT:    tail call void @fun1(i8* nonnull [[A]]) #[[ATTR7]]
605; NOT_CGSCC_NPM-NEXT:    ret void
606;
607; IS__CGSCC_NPM: Function Attrs: nounwind willreturn
608; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f17
609; IS__CGSCC_NPM-SAME: (i8* nonnull [[A:%.*]], i8 [[C:%.*]]) #[[ATTR6]] {
610; IS__CGSCC_NPM-NEXT:    [[CMP:%.*]] = icmp eq i8 [[C]], 0
611; IS__CGSCC_NPM-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
612; IS__CGSCC_NPM:       if.then:
613; IS__CGSCC_NPM-NEXT:    tail call void @fun0() #[[ATTR6]]
614; IS__CGSCC_NPM-NEXT:    br label [[CONT:%.*]]
615; IS__CGSCC_NPM:       if.else:
616; IS__CGSCC_NPM-NEXT:    tail call void @fun0() #[[ATTR6]]
617; IS__CGSCC_NPM-NEXT:    br label [[CONT]]
618; IS__CGSCC_NPM:       cont:
619; IS__CGSCC_NPM-NEXT:    tail call void @fun1(i8* nonnull [[A]]) #[[ATTR6]]
620; IS__CGSCC_NPM-NEXT:    ret void
621;
622  %cmp = icmp eq i8 %c, 0
623  br i1 %cmp, label %if.then, label %if.else
624if.then:
625  tail call void @fun0()
626  br label %cont
627if.else:
628  tail call void @fun0()
629  br label %cont
630cont:
631  tail call void @fun1(i8* nonnull %a)
632  ret void
633}
634; TEST 18 More complex test
635; if(..)
636;    ... (willreturn & nounwind)
637; else
638;    ... (willreturn & nounwind)
639; if(..)
640;    ... (willreturn & nounwind)
641; else
642;    ... (willreturn & nounwind)
643; fun1(nonnull %a)
644
645define void @f18(i8* %a, i8* %b, i8 %c) {
646; NOT_CGSCC_NPM: Function Attrs: nounwind willreturn
647; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@f18
648; NOT_CGSCC_NPM-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR7]] {
649; NOT_CGSCC_NPM-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[C]], 0
650; NOT_CGSCC_NPM-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
651; NOT_CGSCC_NPM:       if.then:
652; NOT_CGSCC_NPM-NEXT:    tail call void @fun0() #[[ATTR7]]
653; NOT_CGSCC_NPM-NEXT:    br label [[CONT:%.*]]
654; NOT_CGSCC_NPM:       if.else:
655; NOT_CGSCC_NPM-NEXT:    tail call void @fun0() #[[ATTR7]]
656; NOT_CGSCC_NPM-NEXT:    br label [[CONT]]
657; NOT_CGSCC_NPM:       cont:
658; NOT_CGSCC_NPM-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[C]], 1
659; NOT_CGSCC_NPM-NEXT:    br i1 [[CMP2]], label [[CONT_THEN:%.*]], label [[CONT_ELSE:%.*]]
660; NOT_CGSCC_NPM:       cont.then:
661; NOT_CGSCC_NPM-NEXT:    tail call void @fun1(i8* nonnull [[B]]) #[[ATTR7]]
662; NOT_CGSCC_NPM-NEXT:    br label [[CONT2:%.*]]
663; NOT_CGSCC_NPM:       cont.else:
664; NOT_CGSCC_NPM-NEXT:    tail call void @fun0() #[[ATTR7]]
665; NOT_CGSCC_NPM-NEXT:    br label [[CONT2]]
666; NOT_CGSCC_NPM:       cont2:
667; NOT_CGSCC_NPM-NEXT:    tail call void @fun1(i8* nonnull [[A]]) #[[ATTR7]]
668; NOT_CGSCC_NPM-NEXT:    ret void
669;
670; IS__CGSCC_NPM: Function Attrs: nounwind willreturn
671; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f18
672; IS__CGSCC_NPM-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR6]] {
673; IS__CGSCC_NPM-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[C]], 0
674; IS__CGSCC_NPM-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
675; IS__CGSCC_NPM:       if.then:
676; IS__CGSCC_NPM-NEXT:    tail call void @fun0() #[[ATTR6]]
677; IS__CGSCC_NPM-NEXT:    br label [[CONT:%.*]]
678; IS__CGSCC_NPM:       if.else:
679; IS__CGSCC_NPM-NEXT:    tail call void @fun0() #[[ATTR6]]
680; IS__CGSCC_NPM-NEXT:    br label [[CONT]]
681; IS__CGSCC_NPM:       cont:
682; IS__CGSCC_NPM-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[C]], 1
683; IS__CGSCC_NPM-NEXT:    br i1 [[CMP2]], label [[CONT_THEN:%.*]], label [[CONT_ELSE:%.*]]
684; IS__CGSCC_NPM:       cont.then:
685; IS__CGSCC_NPM-NEXT:    tail call void @fun1(i8* nonnull [[B]]) #[[ATTR6]]
686; IS__CGSCC_NPM-NEXT:    br label [[CONT2:%.*]]
687; IS__CGSCC_NPM:       cont.else:
688; IS__CGSCC_NPM-NEXT:    tail call void @fun0() #[[ATTR6]]
689; IS__CGSCC_NPM-NEXT:    br label [[CONT2]]
690; IS__CGSCC_NPM:       cont2:
691; IS__CGSCC_NPM-NEXT:    tail call void @fun1(i8* nonnull [[A]]) #[[ATTR6]]
692; IS__CGSCC_NPM-NEXT:    ret void
693;
694  %cmp1 = icmp eq i8 %c, 0
695  br i1 %cmp1, label %if.then, label %if.else
696if.then:
697  tail call void @fun0()
698  br label %cont
699if.else:
700  tail call void @fun0()
701  br label %cont
702cont:
703  %cmp2 = icmp eq i8 %c, 1
704  br i1 %cmp2, label %cont.then, label %cont.else
705cont.then:
706  tail call void @fun1(i8* nonnull %b)
707  br label %cont2
708cont.else:
709  tail call void @fun0()
710  br label %cont2
711cont2:
712  tail call void @fun1(i8* nonnull %a)
713  ret void
714}
715
716; TEST 19: Loop
717
718define void @f19(i8* %a, i8* %b, i8 %c) {
719; NOT_CGSCC_NPM: Function Attrs: nounwind
720; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@f19
721; NOT_CGSCC_NPM-SAME: (i8* [[A:%.*]], i8* nonnull [[B:%.*]], i8 [[C:%.*]]) #[[ATTR5]] {
722; NOT_CGSCC_NPM-NEXT:    br label [[LOOP_HEADER:%.*]]
723; NOT_CGSCC_NPM:       loop.header:
724; NOT_CGSCC_NPM-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[C]], 0
725; NOT_CGSCC_NPM-NEXT:    br i1 [[CMP2]], label [[LOOP_BODY:%.*]], label [[LOOP_EXIT:%.*]]
726; NOT_CGSCC_NPM:       loop.body:
727; NOT_CGSCC_NPM-NEXT:    tail call void @fun1(i8* nonnull [[B]]) #[[ATTR5]]
728; NOT_CGSCC_NPM-NEXT:    tail call void @fun1(i8* nonnull [[A]]) #[[ATTR5]]
729; NOT_CGSCC_NPM-NEXT:    br label [[LOOP_HEADER]]
730; NOT_CGSCC_NPM:       loop.exit:
731; NOT_CGSCC_NPM-NEXT:    tail call void @fun1(i8* nonnull [[B]]) #[[ATTR5]]
732; NOT_CGSCC_NPM-NEXT:    ret void
733;
734; IS__CGSCC_NPM: Function Attrs: nounwind
735; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f19
736; IS__CGSCC_NPM-SAME: (i8* [[A:%.*]], i8* nonnull [[B:%.*]], i8 [[C:%.*]]) #[[ATTR4]] {
737; IS__CGSCC_NPM-NEXT:    br label [[LOOP_HEADER:%.*]]
738; IS__CGSCC_NPM:       loop.header:
739; IS__CGSCC_NPM-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[C]], 0
740; IS__CGSCC_NPM-NEXT:    br i1 [[CMP2]], label [[LOOP_BODY:%.*]], label [[LOOP_EXIT:%.*]]
741; IS__CGSCC_NPM:       loop.body:
742; IS__CGSCC_NPM-NEXT:    tail call void @fun1(i8* nonnull [[B]]) #[[ATTR4]]
743; IS__CGSCC_NPM-NEXT:    tail call void @fun1(i8* nonnull [[A]]) #[[ATTR4]]
744; IS__CGSCC_NPM-NEXT:    br label [[LOOP_HEADER]]
745; IS__CGSCC_NPM:       loop.exit:
746; IS__CGSCC_NPM-NEXT:    tail call void @fun1(i8* nonnull [[B]]) #[[ATTR4]]
747; IS__CGSCC_NPM-NEXT:    ret void
748;
749  br label %loop.header
750loop.header:
751  %cmp2 = icmp eq i8 %c, 0
752  br i1 %cmp2, label %loop.body, label %loop.exit
753loop.body:
754  tail call void @fun1(i8* nonnull %b)
755  tail call void @fun1(i8* nonnull %a)
756  br label %loop.header
757loop.exit:
758  tail call void @fun1(i8* nonnull %b)
759  ret void
760}
761
762; Test propagation of nonnull callsite args back to caller.
763
764declare void @use1(i8* %x)
765declare void @use2(i8* %x, i8* %y);
766declare void @use3(i8* %x, i8* %y, i8* %z);
767
768declare void @use1nonnull(i8* nonnull %x);
769declare void @use2nonnull(i8* nonnull %x, i8* nonnull %y);
770declare void @use3nonnull(i8* nonnull %x, i8* nonnull %y, i8* nonnull %z);
771
772declare i8 @use1safecall(i8* %x) readonly nounwind willreturn ; nounwind+willreturn guarantees that execution continues to successor
773
774; Can't extend non-null to parent for any argument because the 2nd call is not guaranteed to execute.
775
776define void @parent1(i8* %a, i8* %b, i8* %c) {
777; CHECK-LABEL: define {{[^@]+}}@parent1
778; CHECK-SAME: (i8* [[A:%.*]], i8* [[B:%.*]], i8* [[C:%.*]]) {
779; CHECK-NEXT:    call void @use3(i8* [[C]], i8* [[A]], i8* [[B]])
780; CHECK-NEXT:    call void @use3nonnull(i8* nonnull [[B]], i8* nonnull [[C]], i8* nonnull [[A]])
781; CHECK-NEXT:    ret void
782;
783  call void @use3(i8* %c, i8* %a, i8* %b)
784  call void @use3nonnull(i8* %b, i8* %c, i8* %a)
785  ret void
786}
787
788; Extend non-null to parent for all arguments.
789
790define void @parent2(i8* %a, i8* %b, i8* %c) {
791; CHECK-LABEL: define {{[^@]+}}@parent2
792; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* nonnull [[B:%.*]], i8* nonnull [[C:%.*]]) {
793; CHECK-NEXT:    call void @use3nonnull(i8* nonnull [[B]], i8* nonnull [[C]], i8* nonnull [[A]])
794; CHECK-NEXT:    call void @use3(i8* nonnull [[C]], i8* nonnull [[A]], i8* nonnull [[B]])
795; CHECK-NEXT:    ret void
796;
797
798  call void @use3nonnull(i8* %b, i8* %c, i8* %a)
799  call void @use3(i8* %c, i8* %a, i8* %b)
800  ret void
801}
802
803; Extend non-null to parent for 1st argument.
804
805define void @parent3(i8* %a, i8* %b, i8* %c) {
806; CHECK-LABEL: define {{[^@]+}}@parent3
807; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8* [[C:%.*]]) {
808; CHECK-NEXT:    call void @use1nonnull(i8* nonnull [[A]])
809; CHECK-NEXT:    call void @use3(i8* [[C]], i8* [[B]], i8* nonnull [[A]])
810; CHECK-NEXT:    ret void
811;
812
813
814  call void @use1nonnull(i8* %a)
815  call void @use3(i8* %c, i8* %b, i8* %a)
816  ret void
817}
818
819; Extend non-null to parent for last 2 arguments.
820
821define void @parent4(i8* %a, i8* %b, i8* %c) {
822; CHECK-LABEL: define {{[^@]+}}@parent4
823; CHECK-SAME: (i8* [[A:%.*]], i8* nonnull [[B:%.*]], i8* nonnull [[C:%.*]]) {
824; CHECK-NEXT:    call void @use2nonnull(i8* nonnull [[C]], i8* nonnull [[B]])
825; CHECK-NEXT:    call void @use2(i8* [[A]], i8* nonnull [[C]])
826; CHECK-NEXT:    call void @use1(i8* nonnull [[B]])
827; CHECK-NEXT:    ret void
828;
829
830
831
832  call void @use2nonnull(i8* %c, i8* %b)
833  call void @use2(i8* %a, i8* %c)
834  call void @use1(i8* %b)
835  ret void
836}
837
838; The callsite must execute in order for the attribute to transfer to the parent.
839; It appears benign to extend non-null to the parent in this case, but we can't do that
840; because it would incorrectly propagate the wrong information to its callers.
841
842define void @parent5(i8* %a, i1 %a_is_notnull) {
843; CHECK-LABEL: define {{[^@]+}}@parent5
844; CHECK-SAME: (i8* [[A:%.*]], i1 [[A_IS_NOTNULL:%.*]]) {
845; CHECK-NEXT:    br i1 [[A_IS_NOTNULL]], label [[T:%.*]], label [[F:%.*]]
846; CHECK:       t:
847; CHECK-NEXT:    call void @use1nonnull(i8* nonnull [[A]])
848; CHECK-NEXT:    ret void
849; CHECK:       f:
850; CHECK-NEXT:    ret void
851;
852
853  br i1 %a_is_notnull, label %t, label %f
854t:
855  call void @use1nonnull(i8* %a)
856  ret void
857f:
858  ret void
859}
860
861; The callsite must execute in order for the attribute to transfer to the parent.
862; The volatile load can't trap, so we can guarantee that we'll get to the call.
863
864define i8 @parent6(i8* %a, i8* %b) {
865; CHECK-LABEL: define {{[^@]+}}@parent6
866; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* nofree noundef [[B:%.*]]) {
867; CHECK-NEXT:    [[C:%.*]] = load volatile i8, i8* [[B]], align 1
868; CHECK-NEXT:    call void @use1nonnull(i8* nonnull [[A]])
869; CHECK-NEXT:    ret i8 [[C]]
870;
871
872  %c = load volatile i8, i8* %b
873  call void @use1nonnull(i8* %a)
874  ret i8 %c
875}
876
877; The nonnull callsite is guaranteed to execute, so the argument must be nonnull throughout the parent.
878
879define i8 @parent7(i8* %a) {
880; CHECK-LABEL: define {{[^@]+}}@parent7
881; CHECK-SAME: (i8* nonnull [[A:%.*]]) {
882; CHECK-NEXT:    [[RET:%.*]] = call i8 @use1safecall(i8* nonnull readonly [[A]]) #[[ATTR15:[0-9]+]]
883; CHECK-NEXT:    call void @use1nonnull(i8* nonnull [[A]])
884; CHECK-NEXT:    ret i8 [[RET]]
885;
886
887
888  %ret = call i8 @use1safecall(i8* %a)
889  call void @use1nonnull(i8* %a)
890  ret i8 %ret
891}
892
893; Make sure that an invoke works similarly to a call.
894
895declare i32 @esfp(...)
896
897define i1 @parent8(i8* %a, i8* %bogus1, i8* %b) personality i8* bitcast (i32 (...)* @esfp to i8*){
898; NOT_CGSCC_NPM: Function Attrs: nounwind
899; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@parent8
900; NOT_CGSCC_NPM-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) #[[ATTR5]] personality i8* bitcast (i32 (...)* @esfp to i8*) {
901; NOT_CGSCC_NPM-NEXT:  entry:
902; NOT_CGSCC_NPM-NEXT:    invoke void @use2nonnull(i8* nonnull [[A]], i8* nonnull [[B]])
903; NOT_CGSCC_NPM-NEXT:    to label [[CONT:%.*]] unwind label [[EXC:%.*]]
904; NOT_CGSCC_NPM:       cont:
905; NOT_CGSCC_NPM-NEXT:    ret i1 false
906; NOT_CGSCC_NPM:       exc:
907; NOT_CGSCC_NPM-NEXT:    [[LP:%.*]] = landingpad { i8*, i32 }
908; NOT_CGSCC_NPM-NEXT:    filter [0 x i8*] zeroinitializer
909; NOT_CGSCC_NPM-NEXT:    unreachable
910;
911; IS__CGSCC_NPM: Function Attrs: nounwind
912; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@parent8
913; IS__CGSCC_NPM-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) #[[ATTR4]] personality i8* bitcast (i32 (...)* @esfp to i8*) {
914; IS__CGSCC_NPM-NEXT:  entry:
915; IS__CGSCC_NPM-NEXT:    invoke void @use2nonnull(i8* nonnull [[A]], i8* nonnull [[B]])
916; IS__CGSCC_NPM-NEXT:    to label [[CONT:%.*]] unwind label [[EXC:%.*]]
917; IS__CGSCC_NPM:       cont:
918; IS__CGSCC_NPM-NEXT:    ret i1 false
919; IS__CGSCC_NPM:       exc:
920; IS__CGSCC_NPM-NEXT:    [[LP:%.*]] = landingpad { i8*, i32 }
921; IS__CGSCC_NPM-NEXT:    filter [0 x i8*] zeroinitializer
922; IS__CGSCC_NPM-NEXT:    unreachable
923;
924
925entry:
926  invoke void @use2nonnull(i8* %a, i8* %b)
927  to label %cont unwind label %exc
928
929cont:
930  %null_check = icmp eq i8* %b, null
931  ret i1 %null_check
932
933exc:
934  %lp = landingpad { i8*, i32 }
935  filter [0 x i8*] zeroinitializer
936  unreachable
937}
938
939define i32* @gep1(i32* %p) {
940; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
941; CHECK-LABEL: define {{[^@]+}}@gep1
942; CHECK-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] {
943; CHECK-NEXT:    [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1
944; CHECK-NEXT:    ret i32* [[Q]]
945;
946  %q = getelementptr inbounds i32, i32* %p, i32 1
947  ret i32* %q
948}
949
950define i32* @gep1_no_null_opt(i32* %p) #0 {
951; Should't be able to derive nonnull based on gep.
952; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn
953; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@gep1_no_null_opt
954; NOT_CGSCC_NPM-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR9:[0-9]+]] {
955; NOT_CGSCC_NPM-NEXT:    [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1
956; NOT_CGSCC_NPM-NEXT:    ret i32* [[Q]]
957;
958; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn
959; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@gep1_no_null_opt
960; IS__CGSCC_NPM-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR8:[0-9]+]] {
961; IS__CGSCC_NPM-NEXT:    [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1
962; IS__CGSCC_NPM-NEXT:    ret i32* [[Q]]
963;
964  %q = getelementptr inbounds i32, i32* %p, i32 1
965  ret i32* %q
966}
967
968define i32 addrspace(3)* @gep2(i32 addrspace(3)* %p) {
969; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
970; CHECK-LABEL: define {{[^@]+}}@gep2
971; CHECK-SAME: (i32 addrspace(3)* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] {
972; CHECK-NEXT:    [[Q:%.*]] = getelementptr inbounds i32, i32 addrspace(3)* [[P]], i32 1
973; CHECK-NEXT:    ret i32 addrspace(3)* [[Q]]
974;
975  %q = getelementptr inbounds i32, i32 addrspace(3)* %p, i32 1
976  ret i32 addrspace(3)* %q
977}
978
979; FIXME: We should propagate dereferenceable here but *not* nonnull
980define i32 addrspace(3)* @as(i32 addrspace(3)* dereferenceable(4) %p) {
981; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
982; CHECK-LABEL: define {{[^@]+}}@as
983; CHECK-SAME: (i32 addrspace(3)* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] {
984; CHECK-NEXT:    ret i32 addrspace(3)* [[P]]
985;
986  ret i32 addrspace(3)* %p
987}
988
989; CHECK-NOT: @g2()
990define internal i32* @g2() {
991; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
992; IS__CGSCC____-LABEL: define {{[^@]+}}@g2
993; IS__CGSCC____-SAME: () #[[ATTR1]] {
994; IS__CGSCC____-NEXT:    ret i32* inttoptr (i64 4 to i32*)
995;
996  ret i32* inttoptr (i64 4 to i32*)
997}
998
999define i32* @g1() {
1000; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1001; IS__TUNIT____-LABEL: define {{[^@]+}}@g1
1002; IS__TUNIT____-SAME: () #[[ATTR1]] {
1003; IS__TUNIT____-NEXT:    ret i32* inttoptr (i64 4 to i32*)
1004;
1005; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
1006; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@g1
1007; IS__CGSCC_OPM-SAME: () #[[ATTR3]] {
1008; IS__CGSCC_OPM-NEXT:    [[C:%.*]] = call noundef nonnull align 4 i32* @g2() #[[ATTR16:[0-9]+]]
1009; IS__CGSCC_OPM-NEXT:    ret i32* [[C]]
1010;
1011; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
1012; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@g1
1013; IS__CGSCC_NPM-SAME: () #[[ATTR9:[0-9]+]] {
1014; IS__CGSCC_NPM-NEXT:    [[C:%.*]] = call noundef nonnull align 4 i32* @g2() #[[ATTR16:[0-9]+]]
1015; IS__CGSCC_NPM-NEXT:    ret i32* [[C]]
1016;
1017  %c = call i32* @g2()
1018  ret i32* %c
1019}
1020
1021declare void @use_i32_ptr(i32* readnone nocapture) nounwind
1022define internal void @called_by_weak(i32* %a) {
1023; NOT_CGSCC_NPM: Function Attrs: nounwind
1024; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@called_by_weak
1025; NOT_CGSCC_NPM-SAME: (i32* noalias nocapture nonnull readnone [[A:%.*]]) #[[ATTR5]] {
1026; NOT_CGSCC_NPM-NEXT:    call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR5]]
1027; NOT_CGSCC_NPM-NEXT:    ret void
1028;
1029; IS__CGSCC_NPM: Function Attrs: nounwind
1030; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@called_by_weak
1031; IS__CGSCC_NPM-SAME: (i32* noalias nocapture nonnull readnone [[A:%.*]]) #[[ATTR4]] {
1032; IS__CGSCC_NPM-NEXT:    call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR4]]
1033; IS__CGSCC_NPM-NEXT:    ret void
1034;
1035  call void @use_i32_ptr(i32* %a)
1036  ret void
1037}
1038
1039; Check we do not annotate the function interface of this weak function.
1040define weak_odr void @weak_caller(i32* nonnull %a) {
1041;
1042; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@weak_caller
1043; NOT_CGSCC_NPM-SAME: (i32* nonnull [[A:%.*]]) {
1044; NOT_CGSCC_NPM-NEXT:    call void @called_by_weak(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR5]]
1045; NOT_CGSCC_NPM-NEXT:    ret void
1046;
1047; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@weak_caller
1048; IS__CGSCC_NPM-SAME: (i32* nonnull [[A:%.*]]) {
1049; IS__CGSCC_NPM-NEXT:    call void @called_by_weak(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR4]]
1050; IS__CGSCC_NPM-NEXT:    ret void
1051;
1052  call void @called_by_weak(i32* %a)
1053  ret void
1054}
1055
1056; Expect nonnull
1057define internal void @control(i32* dereferenceable(4) %a) {
1058; NOT_CGSCC_NPM: Function Attrs: nounwind
1059; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@control
1060; NOT_CGSCC_NPM-SAME: (i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A:%.*]]) #[[ATTR5]] {
1061; NOT_CGSCC_NPM-NEXT:    call void @use_i32_ptr(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR5]]
1062; NOT_CGSCC_NPM-NEXT:    ret void
1063;
1064; IS__CGSCC_NPM: Function Attrs: nounwind
1065; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@control
1066; IS__CGSCC_NPM-SAME: (i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A:%.*]]) #[[ATTR4]] {
1067; IS__CGSCC_NPM-NEXT:    call void @use_i32_ptr(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR4]]
1068; IS__CGSCC_NPM-NEXT:    ret void
1069;
1070  call void @use_i32_ptr(i32* %a)
1071  ret void
1072}
1073; Avoid nonnull as we do not touch naked functions
1074define internal void @naked(i32* dereferenceable(4) %a) naked {
1075; CHECK: Function Attrs: naked
1076; CHECK-LABEL: define {{[^@]+}}@naked
1077; CHECK-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR10:[0-9]+]] {
1078; CHECK-NEXT:    call void @use_i32_ptr(i32* [[A]])
1079; CHECK-NEXT:    ret void
1080;
1081  call void @use_i32_ptr(i32* %a)
1082  ret void
1083}
1084; Avoid nonnull as we do not touch optnone
1085define internal void @optnone(i32* dereferenceable(4) %a) optnone noinline {
1086;
1087; CHECK: Function Attrs: noinline optnone
1088; CHECK-LABEL: define {{[^@]+}}@optnone
1089; CHECK-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR11:[0-9]+]] {
1090; CHECK-NEXT:    call void @use_i32_ptr(i32* [[A]])
1091; CHECK-NEXT:    ret void
1092;
1093  call void @use_i32_ptr(i32* %a)
1094  ret void
1095}
1096define void @make_live(i32* nonnull dereferenceable(8) %a) {
1097; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@make_live
1098; NOT_CGSCC_NPM-SAME: (i32* noundef nonnull align 16 dereferenceable(8) [[A:%.*]]) {
1099; NOT_CGSCC_NPM-NEXT:    call void @naked(i32* noundef nonnull align 16 dereferenceable(8) [[A]])
1100; NOT_CGSCC_NPM-NEXT:    call void @control(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR5]]
1101; NOT_CGSCC_NPM-NEXT:    call void @optnone(i32* noundef nonnull align 16 dereferenceable(8) [[A]])
1102; NOT_CGSCC_NPM-NEXT:    ret void
1103;
1104; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@make_live
1105; IS__CGSCC_NPM-SAME: (i32* noundef nonnull align 16 dereferenceable(8) [[A:%.*]]) {
1106; IS__CGSCC_NPM-NEXT:    call void @naked(i32* noundef nonnull align 16 dereferenceable(8) [[A]])
1107; IS__CGSCC_NPM-NEXT:    call void @control(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR4]]
1108; IS__CGSCC_NPM-NEXT:    call void @optnone(i32* noundef nonnull align 16 dereferenceable(8) [[A]])
1109; IS__CGSCC_NPM-NEXT:    ret void
1110;
1111  call void @naked(i32* nonnull dereferenceable(8) align 16 %a)
1112  call void @control(i32* nonnull dereferenceable(8) align 16 %a)
1113  call void @optnone(i32* nonnull dereferenceable(8) align 16 %a)
1114  ret void
1115}
1116
1117
1118;int f(int *u, int n){
1119;  for(int i = 0;i<n;i++){
1120;    h(u);
1121;  }
1122;  return g(nonnull u);
1123;}
1124declare void @h(i32*) willreturn nounwind
1125declare i32 @g(i32*) willreturn nounwind
1126define i32 @nonnull_exec_ctx_1(i32* %a, i32 %b) {
1127;
1128; IS________OPM: Function Attrs: nounwind
1129; IS________OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1
1130; IS________OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR5]] {
1131; IS________OPM-NEXT:  en:
1132; IS________OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1133; IS________OPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1134; IS________OPM:       ex:
1135; IS________OPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR5]]
1136; IS________OPM-NEXT:    ret i32 [[TMP5]]
1137; IS________OPM:       hd:
1138; IS________OPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
1139; IS________OPM-NEXT:    tail call void @h(i32* [[A]]) #[[ATTR5]]
1140; IS________OPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1141; IS________OPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1142; IS________OPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1143;
1144; IS__TUNIT_NPM: Function Attrs: nounwind willreturn
1145; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1
1146; IS__TUNIT_NPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] {
1147; IS__TUNIT_NPM-NEXT:  en:
1148; IS__TUNIT_NPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1149; IS__TUNIT_NPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1150; IS__TUNIT_NPM:       ex:
1151; IS__TUNIT_NPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR7]]
1152; IS__TUNIT_NPM-NEXT:    ret i32 [[TMP5]]
1153; IS__TUNIT_NPM:       hd:
1154; IS__TUNIT_NPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
1155; IS__TUNIT_NPM-NEXT:    tail call void @h(i32* [[A]]) #[[ATTR7]]
1156; IS__TUNIT_NPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1157; IS__TUNIT_NPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1158; IS__TUNIT_NPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1159;
1160; IS__CGSCC_NPM: Function Attrs: nounwind willreturn
1161; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1
1162; IS__CGSCC_NPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] {
1163; IS__CGSCC_NPM-NEXT:  en:
1164; IS__CGSCC_NPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1165; IS__CGSCC_NPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1166; IS__CGSCC_NPM:       ex:
1167; IS__CGSCC_NPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR6]]
1168; IS__CGSCC_NPM-NEXT:    ret i32 [[TMP5]]
1169; IS__CGSCC_NPM:       hd:
1170; IS__CGSCC_NPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
1171; IS__CGSCC_NPM-NEXT:    tail call void @h(i32* [[A]]) #[[ATTR6]]
1172; IS__CGSCC_NPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1173; IS__CGSCC_NPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1174; IS__CGSCC_NPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1175;
1176en:
1177  %tmp3 = icmp eq i32 %b, 0
1178  br i1 %tmp3, label %ex, label %hd
1179
1180ex:
1181  %tmp5 = tail call i32 @g(i32* nonnull %a)
1182  ret i32 %tmp5
1183
1184hd:
1185  %tmp7 = phi i32 [ %tmp8, %hd ], [ 0, %en ]
1186  tail call void @h(i32* %a)
1187  %tmp8 = add nuw i32 %tmp7, 1
1188  %tmp9 = icmp eq i32 %tmp8, %b
1189  br i1 %tmp9, label %ex, label %hd
1190}
1191
1192define i32 @nonnull_exec_ctx_1b(i32* %a, i32 %b) {
1193;
1194; IS________OPM: Function Attrs: nounwind
1195; IS________OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b
1196; IS________OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR5]] {
1197; IS________OPM-NEXT:  en:
1198; IS________OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1199; IS________OPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1200; IS________OPM:       ex:
1201; IS________OPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR5]]
1202; IS________OPM-NEXT:    ret i32 [[TMP5]]
1203; IS________OPM:       hd:
1204; IS________OPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
1205; IS________OPM-NEXT:    tail call void @h(i32* [[A]]) #[[ATTR5]]
1206; IS________OPM-NEXT:    br label [[HD2]]
1207; IS________OPM:       hd2:
1208; IS________OPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1209; IS________OPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1210; IS________OPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1211;
1212; IS__TUNIT_NPM: Function Attrs: nounwind willreturn
1213; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b
1214; IS__TUNIT_NPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] {
1215; IS__TUNIT_NPM-NEXT:  en:
1216; IS__TUNIT_NPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1217; IS__TUNIT_NPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1218; IS__TUNIT_NPM:       ex:
1219; IS__TUNIT_NPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR7]]
1220; IS__TUNIT_NPM-NEXT:    ret i32 [[TMP5]]
1221; IS__TUNIT_NPM:       hd:
1222; IS__TUNIT_NPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
1223; IS__TUNIT_NPM-NEXT:    tail call void @h(i32* [[A]]) #[[ATTR7]]
1224; IS__TUNIT_NPM-NEXT:    br label [[HD2]]
1225; IS__TUNIT_NPM:       hd2:
1226; IS__TUNIT_NPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1227; IS__TUNIT_NPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1228; IS__TUNIT_NPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1229;
1230; IS__CGSCC_NPM: Function Attrs: nounwind willreturn
1231; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b
1232; IS__CGSCC_NPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] {
1233; IS__CGSCC_NPM-NEXT:  en:
1234; IS__CGSCC_NPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1235; IS__CGSCC_NPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1236; IS__CGSCC_NPM:       ex:
1237; IS__CGSCC_NPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR6]]
1238; IS__CGSCC_NPM-NEXT:    ret i32 [[TMP5]]
1239; IS__CGSCC_NPM:       hd:
1240; IS__CGSCC_NPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
1241; IS__CGSCC_NPM-NEXT:    tail call void @h(i32* [[A]]) #[[ATTR6]]
1242; IS__CGSCC_NPM-NEXT:    br label [[HD2]]
1243; IS__CGSCC_NPM:       hd2:
1244; IS__CGSCC_NPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1245; IS__CGSCC_NPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1246; IS__CGSCC_NPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1247;
1248en:
1249  %tmp3 = icmp eq i32 %b, 0
1250  br i1 %tmp3, label %ex, label %hd
1251
1252ex:
1253  %tmp5 = tail call i32 @g(i32* nonnull %a)
1254  ret i32 %tmp5
1255
1256hd:
1257  %tmp7 = phi i32 [ %tmp8, %hd2 ], [ 0, %en ]
1258  tail call void @h(i32* %a)
1259  br label %hd2
1260
1261hd2:
1262  %tmp8 = add nuw i32 %tmp7, 1
1263  %tmp9 = icmp eq i32 %tmp8, %b
1264  br i1 %tmp9, label %ex, label %hd
1265}
1266
1267define i32 @nonnull_exec_ctx_2(i32* %a, i32 %b) willreturn nounwind {
1268;
1269; NOT_CGSCC_NPM: Function Attrs: nounwind willreturn
1270; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2
1271; NOT_CGSCC_NPM-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] {
1272; NOT_CGSCC_NPM-NEXT:  en:
1273; NOT_CGSCC_NPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1274; NOT_CGSCC_NPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1275; NOT_CGSCC_NPM:       ex:
1276; NOT_CGSCC_NPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR5]]
1277; NOT_CGSCC_NPM-NEXT:    ret i32 [[TMP5]]
1278; NOT_CGSCC_NPM:       hd:
1279; NOT_CGSCC_NPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
1280; NOT_CGSCC_NPM-NEXT:    tail call void @h(i32* nonnull [[A]]) #[[ATTR5]]
1281; NOT_CGSCC_NPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1282; NOT_CGSCC_NPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1283; NOT_CGSCC_NPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1284;
1285; IS__CGSCC_NPM: Function Attrs: nounwind willreturn
1286; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2
1287; IS__CGSCC_NPM-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] {
1288; IS__CGSCC_NPM-NEXT:  en:
1289; IS__CGSCC_NPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1290; IS__CGSCC_NPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1291; IS__CGSCC_NPM:       ex:
1292; IS__CGSCC_NPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR4]]
1293; IS__CGSCC_NPM-NEXT:    ret i32 [[TMP5]]
1294; IS__CGSCC_NPM:       hd:
1295; IS__CGSCC_NPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
1296; IS__CGSCC_NPM-NEXT:    tail call void @h(i32* nonnull [[A]]) #[[ATTR4]]
1297; IS__CGSCC_NPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1298; IS__CGSCC_NPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1299; IS__CGSCC_NPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1300;
1301en:
1302  %tmp3 = icmp eq i32 %b, 0
1303  br i1 %tmp3, label %ex, label %hd
1304
1305ex:
1306  %tmp5 = tail call i32 @g(i32* nonnull %a)
1307  ret i32 %tmp5
1308
1309hd:
1310  %tmp7 = phi i32 [ %tmp8, %hd ], [ 0, %en ]
1311  tail call void @h(i32* %a)
1312  %tmp8 = add nuw i32 %tmp7, 1
1313  %tmp9 = icmp eq i32 %tmp8, %b
1314  br i1 %tmp9, label %ex, label %hd
1315}
1316
1317define i32 @nonnull_exec_ctx_2b(i32* %a, i32 %b) willreturn nounwind {
1318;
1319; NOT_CGSCC_NPM: Function Attrs: nounwind willreturn
1320; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2b
1321; NOT_CGSCC_NPM-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] {
1322; NOT_CGSCC_NPM-NEXT:  en:
1323; NOT_CGSCC_NPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1324; NOT_CGSCC_NPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1325; NOT_CGSCC_NPM:       ex:
1326; NOT_CGSCC_NPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR5]]
1327; NOT_CGSCC_NPM-NEXT:    ret i32 [[TMP5]]
1328; NOT_CGSCC_NPM:       hd:
1329; NOT_CGSCC_NPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
1330; NOT_CGSCC_NPM-NEXT:    tail call void @h(i32* nonnull [[A]]) #[[ATTR5]]
1331; NOT_CGSCC_NPM-NEXT:    br label [[HD2]]
1332; NOT_CGSCC_NPM:       hd2:
1333; NOT_CGSCC_NPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1334; NOT_CGSCC_NPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1335; NOT_CGSCC_NPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1336;
1337; IS__CGSCC_NPM: Function Attrs: nounwind willreturn
1338; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2b
1339; IS__CGSCC_NPM-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] {
1340; IS__CGSCC_NPM-NEXT:  en:
1341; IS__CGSCC_NPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1342; IS__CGSCC_NPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1343; IS__CGSCC_NPM:       ex:
1344; IS__CGSCC_NPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR4]]
1345; IS__CGSCC_NPM-NEXT:    ret i32 [[TMP5]]
1346; IS__CGSCC_NPM:       hd:
1347; IS__CGSCC_NPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
1348; IS__CGSCC_NPM-NEXT:    tail call void @h(i32* nonnull [[A]]) #[[ATTR4]]
1349; IS__CGSCC_NPM-NEXT:    br label [[HD2]]
1350; IS__CGSCC_NPM:       hd2:
1351; IS__CGSCC_NPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1352; IS__CGSCC_NPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1353; IS__CGSCC_NPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1354;
1355en:
1356  %tmp3 = icmp eq i32 %b, 0
1357  br i1 %tmp3, label %ex, label %hd
1358
1359ex:
1360  %tmp5 = tail call i32 @g(i32* nonnull %a)
1361  ret i32 %tmp5
1362
1363hd:
1364  %tmp7 = phi i32 [ %tmp8, %hd2 ], [ 0, %en ]
1365  tail call void @h(i32* %a)
1366  br label %hd2
1367
1368hd2:
1369  %tmp8 = add nuw i32 %tmp7, 1
1370  %tmp9 = icmp eq i32 %tmp8, %b
1371  br i1 %tmp9, label %ex, label %hd
1372}
1373
1374; Original from PR43833
1375declare void @sink(i32*)
1376
1377define void @PR43833(i32* %0, i32 %1) {
1378; IS________OPM-LABEL: define {{[^@]+}}@PR43833
1379; IS________OPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
1380; IS________OPM-NEXT:    [[TMP3:%.*]] = icmp sgt i32 [[TMP1]], 1
1381; IS________OPM-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
1382; IS________OPM:       4:
1383; IS________OPM-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
1384; IS________OPM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP5]]
1385; IS________OPM-NEXT:    br label [[TMP8:%.*]]
1386; IS________OPM:       7:
1387; IS________OPM-NEXT:    ret void
1388; IS________OPM:       8:
1389; IS________OPM-NEXT:    [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
1390; IS________OPM-NEXT:    tail call void @sink(i32* [[TMP6]])
1391; IS________OPM-NEXT:    [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
1392; IS________OPM-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
1393; IS________OPM-NEXT:    br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
1394;
1395; IS________NPM-LABEL: define {{[^@]+}}@PR43833
1396; IS________NPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
1397; IS________NPM-NEXT:    [[TMP3:%.*]] = icmp sgt i32 [[TMP1]], 1
1398; IS________NPM-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
1399; IS________NPM:       4:
1400; IS________NPM-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
1401; IS________NPM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP5]]
1402; IS________NPM-NEXT:    br label [[TMP8:%.*]]
1403; IS________NPM:       7:
1404; IS________NPM-NEXT:    ret void
1405; IS________NPM:       8:
1406; IS________NPM-NEXT:    [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
1407; IS________NPM-NEXT:    tail call void @sink(i32* nonnull [[TMP6]])
1408; IS________NPM-NEXT:    [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
1409; IS________NPM-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
1410; IS________NPM-NEXT:    br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
1411;
1412  %3 = icmp sgt i32 %1, 1
1413  br i1 %3, label %4, label %7
1414
14154:                                                ; preds = %2
1416  %5 = zext i32 %1 to i64
1417  %6 = getelementptr inbounds i32, i32* %0, i64 %5
1418  br label %8
1419
14207:                                                ; preds = %8, %2
1421  ret void
1422
14238:                                                ; preds = %8, %4
1424  %9 = phi i32 [ 1, %4 ], [ %10, %8 ]
1425  tail call void @sink(i32* %6)
1426  %10 = add nuw nsw i32 %9, 1
1427  %11 = icmp eq i32 %10, %1
1428  br i1 %11, label %7, label %8
1429}
1430
1431; Adjusted from PR43833
1432define void @PR43833_simple(i32* %0, i32 %1) {
1433; IS________OPM-LABEL: define {{[^@]+}}@PR43833_simple
1434; IS________OPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
1435; IS________OPM-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
1436; IS________OPM-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
1437; IS________OPM:       4:
1438; IS________OPM-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
1439; IS________OPM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP5]]
1440; IS________OPM-NEXT:    br label [[TMP8:%.*]]
1441; IS________OPM:       7:
1442; IS________OPM-NEXT:    ret void
1443; IS________OPM:       8:
1444; IS________OPM-NEXT:    [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
1445; IS________OPM-NEXT:    tail call void @sink(i32* [[TMP6]])
1446; IS________OPM-NEXT:    [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
1447; IS________OPM-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
1448; IS________OPM-NEXT:    br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
1449;
1450; IS________NPM-LABEL: define {{[^@]+}}@PR43833_simple
1451; IS________NPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
1452; IS________NPM-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
1453; IS________NPM-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
1454; IS________NPM:       4:
1455; IS________NPM-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
1456; IS________NPM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP5]]
1457; IS________NPM-NEXT:    br label [[TMP8:%.*]]
1458; IS________NPM:       7:
1459; IS________NPM-NEXT:    ret void
1460; IS________NPM:       8:
1461; IS________NPM-NEXT:    [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
1462; IS________NPM-NEXT:    tail call void @sink(i32* nonnull [[TMP6]])
1463; IS________NPM-NEXT:    [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
1464; IS________NPM-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
1465; IS________NPM-NEXT:    br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
1466;
1467  %3 = icmp ne i32 %1, 0
1468  br i1 %3, label %4, label %7
1469
14704:                                                ; preds = %2
1471  %5 = zext i32 %1 to i64
1472  %6 = getelementptr inbounds i32, i32* %0, i64 %5
1473  br label %8
1474
14757:                                                ; preds = %8, %2
1476  ret void
1477
14788:                                                ; preds = %8, %4
1479  %9 = phi i32 [ 1, %4 ], [ %10, %8 ]
1480  tail call void @sink(i32* %6)
1481  %10 = add nuw nsw i32 %9, 1
1482  %11 = icmp eq i32 %10, %1
1483  br i1 %11, label %7, label %8
1484}
1485
1486declare i8* @strrchr(i8* %0, i32 %1) nofree nounwind readonly willreturn
1487
1488; We should not mark the return of @strrchr as `nonnull`, it may well be NULL!
1489define i8* @mybasename(i8* nofree readonly %str) {
1490; CHECK: Function Attrs: nofree nounwind readonly willreturn
1491; CHECK-LABEL: define {{[^@]+}}@mybasename
1492; CHECK-SAME: (i8* nofree readonly [[STR:%.*]]) #[[ATTR12:[0-9]+]] {
1493; CHECK-NEXT:    [[CALL:%.*]] = call i8* @strrchr(i8* nofree readonly [[STR]], i32 noundef 47) #[[ATTR15]]
1494; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8* [[CALL]], null
1495; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 1
1496; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i8* [[ADD_PTR]], i8* [[STR]]
1497; CHECK-NEXT:    ret i8* [[COND]]
1498;
1499  %call = call i8* @strrchr(i8* %str, i32 47)
1500  %tobool = icmp ne i8* %call, null
1501  %add.ptr = getelementptr inbounds i8, i8* %call, i64 1
1502  %cond = select i1 %tobool, i8* %add.ptr, i8* %str
1503  ret i8* %cond
1504}
1505
1506define void @nonnull_assume_pos(i8* %arg) {
1507; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_assume_pos
1508; ATTRIBUTOR-SAME: (i8* nocapture nofree nonnull readnone [[ARG:%.*]])
1509; ATTRIBUTOR-NEXT:    call void @llvm.assume(i1 true) #11 [ "nonnull"(i8* [[ARG]]) ]
1510; ATTRIBUTOR-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]])
1511; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = call i8* @unknown()
1512; ATTRIBUTOR-NEXT:    ret void
1513;
1514; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
1515; NOT_CGSCC_NPM-SAME: (i8* nocapture nofree nonnull readnone [[ARG:%.*]]) {
1516; NOT_CGSCC_NPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "nonnull"(i8* [[ARG]]) ]
1517; NOT_CGSCC_NPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR5]]
1518; NOT_CGSCC_NPM-NEXT:    [[TMP1:%.*]] = call i8* @unknown()
1519; NOT_CGSCC_NPM-NEXT:    ret void
1520;
1521; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
1522; IS__CGSCC_NPM-SAME: (i8* nocapture nofree nonnull readnone [[ARG:%.*]]) {
1523; IS__CGSCC_NPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "nonnull"(i8* [[ARG]]) ]
1524; IS__CGSCC_NPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR4]]
1525; IS__CGSCC_NPM-NEXT:    [[TMP1:%.*]] = call i8* @unknown()
1526; IS__CGSCC_NPM-NEXT:    ret void
1527;
1528  call void @llvm.assume(i1 true) ["nonnull"(i8* %arg)]
1529  call void @use_i8_ptr(i8* %arg)
1530  call i8* @unknown()
1531  ret void
1532}
1533define void @nonnull_assume_neg(i8* %arg) {
1534; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_assume_neg
1535; ATTRIBUTOR-SAME: (i8* nocapture nofree readnone [[ARG:%.*]])
1536; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = call i8* @unknown()
1537; ATTRIBUTOR-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[ARG]])
1538; ATTRIBUTOR-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(i8* [[ARG]]) ]
1539; ATTRIBUTOR-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]])
1540; ATTRIBUTOR-NEXT:    [[TMP2:%.*]] = call i8* @unknown()
1541; ATTRIBUTOR-NEXT:    call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]])
1542; ATTRIBUTOR-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(i8* [[ARG]]) ]
1543; ATTRIBUTOR-NEXT:    call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]])
1544; ATTRIBUTOR-NEXT:    ret void
1545;
1546;
1547; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@nonnull_assume_neg
1548; NOT_CGSCC_NPM-SAME: (i8* nocapture nofree readnone [[ARG:%.*]]) {
1549; NOT_CGSCC_NPM-NEXT:    [[TMP1:%.*]] = call i8* @unknown()
1550; NOT_CGSCC_NPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[ARG]]) #[[ATTR5]]
1551; NOT_CGSCC_NPM-NEXT:    call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG]]) ]
1552; NOT_CGSCC_NPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR5]]
1553; NOT_CGSCC_NPM-NEXT:    [[TMP2:%.*]] = call i8* @unknown()
1554; NOT_CGSCC_NPM-NEXT:    call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR5]]
1555; NOT_CGSCC_NPM-NEXT:    call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG]]) ]
1556; NOT_CGSCC_NPM-NEXT:    call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR5]]
1557; NOT_CGSCC_NPM-NEXT:    ret void
1558;
1559; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@nonnull_assume_neg
1560; IS__CGSCC_NPM-SAME: (i8* nocapture nofree readnone [[ARG:%.*]]) {
1561; IS__CGSCC_NPM-NEXT:    [[TMP1:%.*]] = call i8* @unknown()
1562; IS__CGSCC_NPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[ARG]]) #[[ATTR4]]
1563; IS__CGSCC_NPM-NEXT:    call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG]]) ]
1564; IS__CGSCC_NPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR4]]
1565; IS__CGSCC_NPM-NEXT:    [[TMP2:%.*]] = call i8* @unknown()
1566; IS__CGSCC_NPM-NEXT:    call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR4]]
1567; IS__CGSCC_NPM-NEXT:    call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG]]) ]
1568; IS__CGSCC_NPM-NEXT:    call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR4]]
1569; IS__CGSCC_NPM-NEXT:    ret void
1570;
1571  call i8* @unknown()
1572  call void @use_i8_ptr(i8* %arg)
1573  call void @llvm.assume(i1 true) ["nonnull"(i8* %arg)]
1574  call void @use_i8_ptr(i8* %arg)
1575  call i8* @unknown()
1576  call void @use_i8_ptr_ret(i8* %arg)
1577  call void @llvm.assume(i1 true) ["nonnull"(i8* %arg)]
1578  call void @use_i8_ptr_ret(i8* %arg)
1579  ret void
1580}
1581declare void @use_i8_ptr(i8* nofree nocapture readnone) nounwind
1582declare void @use_i8_ptr_ret(i8* nofree nocapture readnone) nounwind willreturn
1583
1584define i8* @nonnull_function_ptr_1() {
1585; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1586; CHECK-LABEL: define {{[^@]+}}@nonnull_function_ptr_1
1587; CHECK-SAME: () #[[ATTR1]] {
1588; CHECK-NEXT:    ret i8* bitcast (i8* ()* @nonnull_function_ptr_1 to i8*)
1589;
1590  %bc = bitcast i8*()* @nonnull_function_ptr_1 to i8*
1591  ret i8* %bc
1592}
1593
1594declare i8* @function_decl()
1595define i8* @nonnull_function_ptr_2() {
1596; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1597; CHECK-LABEL: define {{[^@]+}}@nonnull_function_ptr_2
1598; CHECK-SAME: () #[[ATTR1]] {
1599; CHECK-NEXT:    ret i8* bitcast (i8* ()* @function_decl to i8*)
1600;
1601  %bc = bitcast i8*()* @function_decl to i8*
1602  ret i8* %bc
1603}
1604
1605; FIXME: nonnull should not be propagated to the caller's p unless there is noundef
1606define void @nonnull_caller(i8* %p) {
1607; CHECK-LABEL: define {{[^@]+}}@nonnull_caller
1608; CHECK-SAME: (i8* nonnull [[P:%.*]]) {
1609; CHECK-NEXT:    call void @nonnull_callee(i8* nonnull [[P]])
1610; CHECK-NEXT:    ret void
1611;
1612  call void @nonnull_callee(i8* %p)
1613  ret void
1614}
1615
1616declare void @nonnull_callee(i8* nonnull %p)
1617
1618attributes #0 = { null_pointer_is_valid }
1619attributes #1 = { nounwind willreturn}
1620;.
1621; IS__TUNIT____: attributes #[[ATTR0:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn }
1622; IS__TUNIT____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
1623; IS__TUNIT____: attributes #[[ATTR2]] = { inaccessiblememonly nofree norecurse nosync nounwind willreturn }
1624; IS__TUNIT____: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn }
1625; IS__TUNIT____: attributes #[[ATTR4]] = { noreturn }
1626; IS__TUNIT____: attributes #[[ATTR5]] = { nounwind }
1627; IS__TUNIT____: attributes #[[ATTR6]] = { argmemonly nofree nosync nounwind readonly }
1628; IS__TUNIT____: attributes #[[ATTR7]] = { nounwind willreturn }
1629; IS__TUNIT____: attributes #[[ATTR8:[0-9]+]] = { nounwind readonly willreturn }
1630; IS__TUNIT____: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn }
1631; IS__TUNIT____: attributes #[[ATTR10]] = { naked }
1632; IS__TUNIT____: attributes #[[ATTR11]] = { noinline optnone }
1633; IS__TUNIT____: attributes #[[ATTR12]] = { nofree nounwind readonly willreturn }
1634; IS__TUNIT____: attributes #[[ATTR13]] = { willreturn }
1635; IS__TUNIT____: attributes #[[ATTR14]] = { nofree nosync nounwind readonly }
1636; IS__TUNIT____: attributes #[[ATTR15]] = { readonly willreturn }
1637;.
1638; IS__CGSCC_OPM: attributes #[[ATTR0:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn }
1639; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
1640; IS__CGSCC_OPM: attributes #[[ATTR2]] = { inaccessiblememonly nofree norecurse nosync nounwind willreturn }
1641; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn }
1642; IS__CGSCC_OPM: attributes #[[ATTR4]] = { noreturn }
1643; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nounwind }
1644; IS__CGSCC_OPM: attributes #[[ATTR6]] = { argmemonly nofree nosync nounwind readonly }
1645; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nounwind willreturn }
1646; IS__CGSCC_OPM: attributes #[[ATTR8:[0-9]+]] = { nounwind readonly willreturn }
1647; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn }
1648; IS__CGSCC_OPM: attributes #[[ATTR10]] = { naked }
1649; IS__CGSCC_OPM: attributes #[[ATTR11]] = { noinline optnone }
1650; IS__CGSCC_OPM: attributes #[[ATTR12]] = { nofree nounwind readonly willreturn }
1651; IS__CGSCC_OPM: attributes #[[ATTR13]] = { willreturn }
1652; IS__CGSCC_OPM: attributes #[[ATTR14]] = { nofree nosync nounwind readonly }
1653; IS__CGSCC_OPM: attributes #[[ATTR15]] = { readonly willreturn }
1654; IS__CGSCC_OPM: attributes #[[ATTR16]] = { readnone willreturn }
1655;.
1656; IS__CGSCC_NPM: attributes #[[ATTR0:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn }
1657; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
1658; IS__CGSCC_NPM: attributes #[[ATTR2]] = { inaccessiblememonly nofree norecurse nosync nounwind willreturn }
1659; IS__CGSCC_NPM: attributes #[[ATTR3]] = { noreturn }
1660; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nounwind }
1661; IS__CGSCC_NPM: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind readonly }
1662; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nounwind willreturn }
1663; IS__CGSCC_NPM: attributes #[[ATTR7:[0-9]+]] = { nounwind readonly willreturn }
1664; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn }
1665; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nofree nosync nounwind readnone willreturn }
1666; IS__CGSCC_NPM: attributes #[[ATTR10]] = { naked }
1667; IS__CGSCC_NPM: attributes #[[ATTR11]] = { noinline optnone }
1668; IS__CGSCC_NPM: attributes #[[ATTR12]] = { nofree nounwind readonly willreturn }
1669; IS__CGSCC_NPM: attributes #[[ATTR13]] = { willreturn }
1670; IS__CGSCC_NPM: attributes #[[ATTR14]] = { nofree nosync nounwind readonly }
1671; IS__CGSCC_NPM: attributes #[[ATTR15]] = { readonly willreturn }
1672; IS__CGSCC_NPM: attributes #[[ATTR16]] = { readnone willreturn }
1673;.
1674