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