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=2 -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=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
4; TODO: The old pass manager cgscc run is disabled as it causes a crash on windows which is under investigation: http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/25479/steps/test-check-all/logs/FAIL%3A%20LLVM%3A%3Anoalias.ll
5; 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
6; 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
7
8; TEST 1 - negative.
9
10; void *G;
11; void *foo(){
12;   void *V = malloc(4);
13;   G = V;
14;   return V;
15; }
16
17@G = external global i8*
18
19;.
20; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = external global i8*
21; CHECK: @[[ALIAS_OF_P:[a-zA-Z0-9_$"\\.-]+]] = external global i32*
22;.
23define i8* @foo() {
24; CHECK-LABEL: define {{[^@]+}}@foo() {
25; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
26; CHECK-NEXT:    store i8* [[TMP1]], i8** @G, align 8
27; CHECK-NEXT:    ret i8* [[TMP1]]
28;
29  %1 = tail call noalias i8* @malloc(i64 4)
30  store i8* %1, i8** @G, align 8
31  ret i8* %1
32}
33
34declare noalias i8* @malloc(i64)
35
36; TEST 2
37; call noalias function in return instruction.
38
39define i8* @return_noalias(){
40; CHECK-LABEL: define {{[^@]+}}@return_noalias() {
41; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
42; CHECK-NEXT:    ret i8* [[TMP1]]
43;
44  %1 = tail call noalias i8* @malloc(i64 4)
45  ret i8* %1
46}
47
48define void @nocapture(i8* %a){
49; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
50; CHECK-LABEL: define {{[^@]+}}@nocapture
51; CHECK-SAME: (i8* nocapture nofree readnone [[A:%.*]]) #[[ATTR0:[0-9]+]] {
52; CHECK-NEXT:    ret void
53;
54  ret void
55}
56
57define i8* @return_noalias_looks_like_capture(){
58; CHECK-LABEL: define {{[^@]+}}@return_noalias_looks_like_capture() {
59; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
60; CHECK-NEXT:    ret i8* [[TMP1]]
61;
62  %1 = tail call noalias i8* @malloc(i64 4)
63  call void @nocapture(i8* %1)
64  ret i8* %1
65}
66
67define i16* @return_noalias_casted(){
68; CHECK-LABEL: define {{[^@]+}}@return_noalias_casted() {
69; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
70; CHECK-NEXT:    [[C:%.*]] = bitcast i8* [[TMP1]] to i16*
71; CHECK-NEXT:    ret i16* [[C]]
72;
73  %1 = tail call noalias i8* @malloc(i64 4)
74  %c = bitcast i8* %1 to i16*
75  ret i16* %c
76}
77
78declare i8* @alias()
79
80; TEST 3
81define i8* @call_alias(){
82; CHECK-LABEL: define {{[^@]+}}@call_alias() {
83; CHECK-NEXT:    [[TMP1:%.*]] = tail call i8* @alias()
84; CHECK-NEXT:    ret i8* [[TMP1]]
85;
86  %1 = tail call i8* @alias()
87  ret i8* %1
88}
89
90; TEST 4
91; void *baz();
92; void *foo(int a);
93;
94; void *bar()  {
95;   foo(0);
96;    return baz();
97; }
98;
99; void *foo(int a)  {
100;   if (a)
101;   bar();
102;   return malloc(4);
103; }
104
105define i8* @bar() nounwind uwtable {
106; NOT_CGSCC_NPM: Function Attrs: nounwind uwtable
107; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@bar
108; NOT_CGSCC_NPM-SAME: () #[[ATTR1:[0-9]+]] {
109; NOT_CGSCC_NPM-NEXT:    [[TMP1:%.*]] = tail call i8* (...) @baz() #[[ATTR2:[0-9]+]]
110; NOT_CGSCC_NPM-NEXT:    ret i8* [[TMP1]]
111;
112; IS__CGSCC____: Function Attrs: nounwind uwtable
113; IS__CGSCC____-LABEL: define {{[^@]+}}@bar
114; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] {
115; IS__CGSCC____-NEXT:    [[TMP1:%.*]] = tail call i8* (...) @baz() #[[ATTR3:[0-9]+]]
116; IS__CGSCC____-NEXT:    ret i8* [[TMP1]]
117;
118  %1 = tail call i8* (...) @baz()
119  ret i8* %1
120}
121
122define i8* @foo1(i32 %0) nounwind uwtable {
123; NOT_CGSCC_NPM: Function Attrs: nounwind uwtable
124; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@foo1
125; NOT_CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] {
126; NOT_CGSCC_NPM-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0
127; NOT_CGSCC_NPM-NEXT:    br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
128; NOT_CGSCC_NPM:       3:
129; NOT_CGSCC_NPM-NEXT:    [[TMP4:%.*]] = tail call i8* (...) @baz() #[[ATTR2]]
130; NOT_CGSCC_NPM-NEXT:    br label [[TMP5]]
131; NOT_CGSCC_NPM:       5:
132; NOT_CGSCC_NPM-NEXT:    [[TMP6:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
133; NOT_CGSCC_NPM-NEXT:    ret i8* [[TMP6]]
134;
135; IS__CGSCC____: Function Attrs: nounwind uwtable
136; IS__CGSCC____-LABEL: define {{[^@]+}}@foo1
137; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] {
138; IS__CGSCC____-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0
139; IS__CGSCC____-NEXT:    br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
140; IS__CGSCC____:       3:
141; IS__CGSCC____-NEXT:    [[TMP4:%.*]] = tail call i8* (...) @baz() #[[ATTR3]]
142; IS__CGSCC____-NEXT:    br label [[TMP5]]
143; IS__CGSCC____:       5:
144; IS__CGSCC____-NEXT:    [[TMP6:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
145; IS__CGSCC____-NEXT:    ret i8* [[TMP6]]
146;
147  %2 = icmp eq i32 %0, 0
148  br i1 %2, label %5, label %3
149
1503:                                                ; preds = %1
151  %4 = tail call i8* (...) @baz()
152  br label %5
153
1545:                                                ; preds = %1, %3
155  %6 = tail call noalias i8* @malloc(i64 4)
156  ret i8* %6
157}
158
159declare i8* @baz(...) nounwind uwtable
160
161; TEST 5
162
163; Returning global pointer. Should not be noalias.
164define i8** @getter() {
165; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
166; CHECK-LABEL: define {{[^@]+}}@getter
167; CHECK-SAME: () #[[ATTR0]] {
168; CHECK-NEXT:    ret i8** @G
169;
170  ret i8** @G
171}
172
173; Returning global pointer. Should not be noalias.
174define i8** @calle1(){
175; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
176; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@calle1
177; NOT_CGSCC_NPM-SAME: () #[[ATTR0]] {
178; NOT_CGSCC_NPM-NEXT:    ret i8** @G
179;
180; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn
181; IS__CGSCC____-LABEL: define {{[^@]+}}@calle1
182; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] {
183; IS__CGSCC____-NEXT:    [[TMP1:%.*]] = call noundef nonnull align 8 dereferenceable(8) i8** @getter() #[[ATTR11:[0-9]+]]
184; IS__CGSCC____-NEXT:    ret i8** [[TMP1]]
185;
186  %1 = call i8** @getter()
187  ret i8** %1
188}
189
190; TEST 6
191declare noalias i8* @strdup(i8* nocapture) nounwind
192
193define i8* @test6() nounwind uwtable ssp {
194; NOT_CGSCC_NPM: Function Attrs: nounwind ssp uwtable
195; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6
196; NOT_CGSCC_NPM-SAME: () #[[ATTR3:[0-9]+]] {
197; NOT_CGSCC_NPM-NEXT:    [[X:%.*]] = alloca [2 x i8], align 1
198; NOT_CGSCC_NPM-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 0
199; NOT_CGSCC_NPM-NEXT:    store i8 97, i8* [[ARRAYIDX]], align 1
200; NOT_CGSCC_NPM-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 1
201; NOT_CGSCC_NPM-NEXT:    store i8 0, i8* [[ARRAYIDX1]], align 1
202; NOT_CGSCC_NPM-NEXT:    [[CALL:%.*]] = call noalias i8* @strdup(i8* nocapture noundef nonnull dereferenceable(2) [[ARRAYIDX]]) #[[ATTR2]]
203; NOT_CGSCC_NPM-NEXT:    ret i8* [[CALL]]
204;
205; IS__CGSCC____: Function Attrs: nounwind ssp uwtable
206; IS__CGSCC____-LABEL: define {{[^@]+}}@test6
207; IS__CGSCC____-SAME: () #[[ATTR4:[0-9]+]] {
208; IS__CGSCC____-NEXT:    [[X:%.*]] = alloca [2 x i8], align 1
209; IS__CGSCC____-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 0
210; IS__CGSCC____-NEXT:    store i8 97, i8* [[ARRAYIDX]], align 1
211; IS__CGSCC____-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 1
212; IS__CGSCC____-NEXT:    store i8 0, i8* [[ARRAYIDX1]], align 1
213; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call noalias i8* @strdup(i8* nocapture noundef nonnull dereferenceable(2) [[ARRAYIDX]]) #[[ATTR3]]
214; IS__CGSCC____-NEXT:    ret i8* [[CALL]]
215;
216  %x = alloca [2 x i8], align 1
217  %arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %x, i64 0, i64 0
218  store i8 97, i8* %arrayidx, align 1
219  %arrayidx1 = getelementptr inbounds [2 x i8], [2 x i8]* %x, i64 0, i64 1
220  store i8 0, i8* %arrayidx1, align 1
221  %call = call noalias i8* @strdup(i8* %arrayidx) nounwind
222  ret i8* %call
223}
224
225; TEST 7
226
227define i8* @test7() nounwind {
228; NOT_CGSCC_NPM: Function Attrs: nounwind
229; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test7
230; NOT_CGSCC_NPM-SAME: () #[[ATTR2]] {
231; NOT_CGSCC_NPM-NEXT:  entry:
232; NOT_CGSCC_NPM-NEXT:    [[A:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR2]]
233; NOT_CGSCC_NPM-NEXT:    [[TOBOOL:%.*]] = icmp eq i8* [[A]], null
234; NOT_CGSCC_NPM-NEXT:    br i1 [[TOBOOL]], label [[RETURN:%.*]], label [[IF_END:%.*]]
235; NOT_CGSCC_NPM:       if.end:
236; NOT_CGSCC_NPM-NEXT:    store i8 7, i8* [[A]], align 1
237; NOT_CGSCC_NPM-NEXT:    br label [[RETURN]]
238; NOT_CGSCC_NPM:       return:
239; NOT_CGSCC_NPM-NEXT:    [[RETVAL_0:%.*]] = phi i8* [ [[A]], [[IF_END]] ], [ null, [[ENTRY:%.*]] ]
240; NOT_CGSCC_NPM-NEXT:    ret i8* [[RETVAL_0]]
241;
242; IS__CGSCC____: Function Attrs: nounwind
243; IS__CGSCC____-LABEL: define {{[^@]+}}@test7
244; IS__CGSCC____-SAME: () #[[ATTR3]] {
245; IS__CGSCC____-NEXT:  entry:
246; IS__CGSCC____-NEXT:    [[A:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR3]]
247; IS__CGSCC____-NEXT:    [[TOBOOL:%.*]] = icmp eq i8* [[A]], null
248; IS__CGSCC____-NEXT:    br i1 [[TOBOOL]], label [[RETURN:%.*]], label [[IF_END:%.*]]
249; IS__CGSCC____:       if.end:
250; IS__CGSCC____-NEXT:    store i8 7, i8* [[A]], align 1
251; IS__CGSCC____-NEXT:    br label [[RETURN]]
252; IS__CGSCC____:       return:
253; IS__CGSCC____-NEXT:    [[RETVAL_0:%.*]] = phi i8* [ [[A]], [[IF_END]] ], [ null, [[ENTRY:%.*]] ]
254; IS__CGSCC____-NEXT:    ret i8* [[RETVAL_0]]
255;
256entry:
257  %A = call noalias i8* @malloc(i64 4) nounwind
258  %tobool = icmp eq i8* %A, null
259  br i1 %tobool, label %return, label %if.end
260
261if.end:
262  store i8 7, i8* %A
263  br label %return
264
265return:
266  %retval.0 = phi i8* [ %A, %if.end ], [ null, %entry ]
267  ret i8* %retval.0
268}
269
270; TEST 8
271
272define i8* @test8(i32* %0) nounwind uwtable {
273; CHECK: Function Attrs: nounwind uwtable
274; CHECK-LABEL: define {{[^@]+}}@test8
275; CHECK-SAME: (i32* [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] {
276; CHECK-NEXT:    [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
277; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32* [[TMP0]], null
278; CHECK-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
279; CHECK:       4:
280; CHECK-NEXT:    store i8 10, i8* [[TMP2]], align 1
281; CHECK-NEXT:    br label [[TMP5]]
282; CHECK:       5:
283; CHECK-NEXT:    ret i8* [[TMP2]]
284;
285  %2 = tail call noalias i8* @malloc(i64 4)
286  %3 = icmp ne i32* %0, null
287  br i1 %3, label %4, label %5
288
2894:                                                ; preds = %1
290  store i8 10, i8* %2
291  br label %5
292
2935:                                                ; preds = %1, %4
294  ret i8* %2
295}
296
297; TEST 9
298; Simple Argument Test
299declare void @use_i8(i8* nocapture)
300define internal void @test9a(i8* %a, i8* %b) {
301; CHECK-LABEL: define {{[^@]+}}@test9a() {
302; CHECK-NEXT:    call void @use_i8(i8* noalias nocapture noundef align 4294967296 null)
303; CHECK-NEXT:    ret void
304;
305  call void @use_i8(i8* null)
306  ret void
307}
308define internal void @test9b(i8* %a, i8* %b) {
309; FIXME: %b should be noalias
310; CHECK-LABEL: define {{[^@]+}}@test9b
311; CHECK-SAME: (i8* noalias nocapture [[A:%.*]], i8* nocapture [[B:%.*]]) {
312; CHECK-NEXT:    call void @use_i8(i8* noalias nocapture [[A]])
313; CHECK-NEXT:    call void @use_i8(i8* nocapture [[B]])
314; CHECK-NEXT:    ret void
315;
316  call void @use_i8(i8* %a)
317  call void @use_i8(i8* %b)
318  ret void
319}
320define internal void @test9c(i8* %a, i8* %b, i8* %c) {
321; CHECK-LABEL: define {{[^@]+}}@test9c
322; CHECK-SAME: (i8* noalias nocapture [[A:%.*]], i8* nocapture [[B:%.*]], i8* nocapture [[C:%.*]]) {
323; CHECK-NEXT:    call void @use_i8(i8* noalias nocapture [[A]])
324; CHECK-NEXT:    call void @use_i8(i8* nocapture [[B]])
325; CHECK-NEXT:    call void @use_i8(i8* nocapture [[C]])
326; CHECK-NEXT:    ret void
327;
328  call void @use_i8(i8* %a)
329  call void @use_i8(i8* %b)
330  call void @use_i8(i8* %c)
331  ret void
332}
333define void @test9_helper(i8* %a, i8* %b) {
334; CHECK-LABEL: define {{[^@]+}}@test9_helper
335; CHECK-SAME: (i8* nocapture [[A:%.*]], i8* nocapture [[B:%.*]]) {
336; CHECK-NEXT:    tail call void @test9a()
337; CHECK-NEXT:    tail call void @test9a()
338; CHECK-NEXT:    tail call void @test9b(i8* noalias nocapture [[A]], i8* nocapture [[B]])
339; CHECK-NEXT:    tail call void @test9b(i8* noalias nocapture [[B]], i8* noalias nocapture [[A]])
340; CHECK-NEXT:    tail call void @test9c(i8* noalias nocapture [[A]], i8* nocapture [[B]], i8* nocapture [[B]])
341; CHECK-NEXT:    tail call void @test9c(i8* noalias nocapture [[B]], i8* noalias nocapture [[A]], i8* noalias nocapture [[A]])
342; CHECK-NEXT:    ret void
343;
344  tail call void @test9a(i8* noalias %a, i8* %b)
345  tail call void @test9a(i8* noalias %b, i8* noalias %a)
346  tail call void @test9b(i8* noalias %a, i8* %b)
347  tail call void @test9b(i8* noalias %b, i8* noalias %a)
348  tail call void @test9c(i8* noalias %a, i8* %b, i8* %b)
349  tail call void @test9c(i8* noalias %b, i8* noalias %a, i8* noalias %a)
350  ret void
351}
352
353
354; TEST 10
355; Simple CallSite Test
356
357declare void @test10_helper_1(i8* %a)
358define void @test10_helper_2(i8* noalias %a) {
359; CHECK-LABEL: define {{[^@]+}}@test10_helper_2
360; CHECK-SAME: (i8* noalias [[A:%.*]]) {
361; CHECK-NEXT:    tail call void @test10_helper_1(i8* [[A]])
362; CHECK-NEXT:    ret void
363;
364  tail call void @test10_helper_1(i8* %a)
365  ret void
366}
367define void @test10(i8* noalias %a) {
368; CHECK-LABEL: define {{[^@]+}}@test10
369; CHECK-SAME: (i8* noalias [[A:%.*]]) {
370; CHECK-NEXT:    tail call void @test10_helper_1(i8* [[A]])
371; CHECK-NEXT:    tail call void @test10_helper_2(i8* noalias [[A]])
372; CHECK-NEXT:    ret void
373;
374; FIXME: missing noalias
375  tail call void @test10_helper_1(i8* %a)
376
377  tail call void @test10_helper_2(i8* %a)
378  ret void
379}
380
381; TEST 11
382; CallSite Test
383
384declare void @test11_helper(i8* %a, i8 *%b)
385define void @test11(i8* noalias %a) {
386; CHECK-LABEL: define {{[^@]+}}@test11
387; CHECK-SAME: (i8* noalias [[A:%.*]]) {
388; CHECK-NEXT:    tail call void @test11_helper(i8* [[A]], i8* [[A]])
389; CHECK-NEXT:    ret void
390;
391  tail call void @test11_helper(i8* %a, i8* %a)
392  ret void
393}
394
395
396; TEST 12
397; CallSite Argument
398declare void @use_nocapture(i8* nocapture)
399declare void @use(i8*)
400define void @test12_1() {
401; CHECK-LABEL: define {{[^@]+}}@test12_1() {
402; CHECK-NEXT:    [[A:%.*]] = alloca i8, align 4
403; CHECK-NEXT:    [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
404; CHECK-NEXT:    tail call void @use_nocapture(i8* noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A]])
405; CHECK-NEXT:    tail call void @use_nocapture(i8* noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A]])
406; CHECK-NEXT:    tail call void @use_nocapture(i8* noalias nocapture [[B]])
407; CHECK-NEXT:    tail call void @use_nocapture(i8* noalias nocapture [[B]])
408; CHECK-NEXT:    ret void
409;
410  %A = alloca i8, align 4
411  %B = tail call noalias i8* @malloc(i64 4)
412  tail call void @use_nocapture(i8* %A)
413  tail call void @use_nocapture(i8* %A)
414  tail call void @use_nocapture(i8* %B)
415  tail call void @use_nocapture(i8* %B)
416  ret void
417}
418
419define void @test12_2(){
420; CHECK-LABEL: define {{[^@]+}}@test12_2() {
421; CHECK-NEXT:    [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
422; CHECK-NEXT:    tail call void @use_nocapture(i8* nocapture [[A]])
423; CHECK-NEXT:    tail call void @use_nocapture(i8* nocapture [[A]])
424; CHECK-NEXT:    tail call void @use(i8* [[A]])
425; CHECK-NEXT:    tail call void @use_nocapture(i8* nocapture [[A]])
426; CHECK-NEXT:    ret void
427;
428; FIXME: This should be @use_nocapture(i8* noalias [[A]])
429; FIXME: This should be @use_nocapture(i8* noalias nocapture [[A]])
430  %A = tail call noalias i8* @malloc(i64 4)
431  tail call void @use_nocapture(i8* %A)
432  tail call void @use_nocapture(i8* %A)
433  tail call void @use(i8* %A)
434  tail call void @use_nocapture(i8* %A)
435  ret void
436}
437
438declare void @two_args(i8* nocapture , i8* nocapture)
439define void @test12_3(){
440; CHECK-LABEL: define {{[^@]+}}@test12_3() {
441; CHECK-NEXT:    [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
442; CHECK-NEXT:    tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A]])
443; CHECK-NEXT:    ret void
444;
445  %A = tail call noalias i8* @malloc(i64 4)
446  tail call void @two_args(i8* %A, i8* %A)
447  ret void
448}
449
450define void @test12_4(){
451; IS________OPM-LABEL: define {{[^@]+}}@test12_4() {
452; IS________OPM-NEXT:    [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
453; IS________OPM-NEXT:    [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
454; IS________OPM-NEXT:    [[A_1:%.*]] = getelementptr i8, i8* [[A]], i64 1
455; IS________OPM-NEXT:    tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[B]])
456; IS________OPM-NEXT:    tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A]])
457; IS________OPM-NEXT:    tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A_1]])
458; IS________OPM-NEXT:    tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[B]])
459; IS________OPM-NEXT:    ret void
460;
461; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test12_4() {
462; NOT_TUNIT_OPM-NEXT:    [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
463; NOT_TUNIT_OPM-NEXT:    [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
464; NOT_TUNIT_OPM-NEXT:    [[A_1:%.*]] = getelementptr i8, i8* [[A]], i64 1
465; NOT_TUNIT_OPM-NEXT:    tail call void @two_args(i8* noalias nocapture [[A]], i8* noalias nocapture [[B]])
466; NOT_TUNIT_OPM-NEXT:    tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A]])
467; NOT_TUNIT_OPM-NEXT:    tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A_1]])
468; NOT_TUNIT_OPM-NEXT:    tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[B]])
469; NOT_TUNIT_OPM-NEXT:    ret void
470;
471  %A = tail call noalias i8* @malloc(i64 4)
472  %B = tail call noalias i8* @malloc(i64 4)
473  %A_0 = getelementptr i8, i8* %A, i64 0
474  %A_1 = getelementptr i8, i8* %A, i64 1
475  %B_0 = getelementptr i8, i8* %B, i64 0
476
477  tail call void @two_args(i8* %A, i8* %B)
478
479  tail call void @two_args(i8* %A, i8* %A_0)
480
481  tail call void @two_args(i8* %A, i8* %A_1)
482
483; FIXME: This should be @two_args(i8* noalias nocapture %A_0, i8* noalias nocapture %B_0)
484  tail call void @two_args(i8* %A_0, i8* %B_0)
485  ret void
486}
487
488; TEST 13
489define void @use_i8_internal(i8* %a) {
490; CHECK-LABEL: define {{[^@]+}}@use_i8_internal
491; CHECK-SAME: (i8* nocapture [[A:%.*]]) {
492; CHECK-NEXT:    call void @use_i8(i8* nocapture [[A]])
493; CHECK-NEXT:    ret void
494;
495  call void @use_i8(i8* %a)
496  ret void
497}
498
499define void @test13_use_noalias(){
500; CHECK-LABEL: define {{[^@]+}}@test13_use_noalias() {
501; CHECK-NEXT:    [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
502; CHECK-NEXT:    call void @use_i8_internal(i8* noalias nocapture [[M1]])
503; CHECK-NEXT:    ret void
504;
505; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13_use_noalias()
506; IS__CGSCC_OPM-NEXT:    [[M1:%.*]] = tail call noalias i8* @malloc(i64 4)
507; IS__CGSCC_OPM-NEXT:    [[C1:%.*]] = bitcast i8* [[M1]] to i16*
508; IS__CGSCC_OPM-NEXT:    [[C2:%.*]] = bitcast i16* [[C1]] to i8*
509; IS__CGSCC_OPM-NEXT:    call void @use_i8_internal(i8* noalias [[C2]])
510; IS__CGSCC_OPM-NEXT:    ret void
511  %m1 = tail call noalias i8* @malloc(i64 4)
512  %c1 = bitcast i8* %m1 to i16*
513  %c2 = bitcast i16* %c1 to i8*
514  call void @use_i8_internal(i8* %c2)
515  ret void
516}
517
518define void @test13_use_alias(){
519; CHECK-LABEL: define {{[^@]+}}@test13_use_alias() {
520; CHECK-NEXT:    [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
521; CHECK-NEXT:    call void @use_i8_internal(i8* nocapture [[M1]])
522; CHECK-NEXT:    call void @use_i8_internal(i8* nocapture [[M1]])
523; CHECK-NEXT:    ret void
524;
525  %m1 = tail call noalias i8* @malloc(i64 4)
526  %c1 = bitcast i8* %m1 to i16*
527  %c2a = bitcast i16* %c1 to i8*
528  %c2b = bitcast i16* %c1 to i8*
529  call void @use_i8_internal(i8* %c2a)
530  call void @use_i8_internal(i8* %c2b)
531  ret void
532}
533
534; TEST 14 i2p casts
535define internal i32 @p2i(i32* %arg) {
536; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
537; CHECK-LABEL: define {{[^@]+}}@p2i
538; CHECK-SAME: (i32* noalias nofree readnone [[ARG:%.*]]) #[[ATTR0]] {
539; CHECK-NEXT:    [[P2I:%.*]] = ptrtoint i32* [[ARG]] to i32
540; CHECK-NEXT:    ret i32 [[P2I]]
541;
542  %p2i = ptrtoint i32* %arg to i32
543  ret i32 %p2i
544}
545
546define i32 @i2p(i32* %arg) {
547; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
548; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@i2p
549; NOT_CGSCC_NPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR4:[0-9]+]] {
550; NOT_CGSCC_NPM-NEXT:    [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]]) #[[ATTR9:[0-9]+]]
551; NOT_CGSCC_NPM-NEXT:    [[I2P:%.*]] = inttoptr i32 [[C]] to i8*
552; NOT_CGSCC_NPM-NEXT:    [[BC:%.*]] = bitcast i8* [[I2P]] to i32*
553; NOT_CGSCC_NPM-NEXT:    [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree readonly align 4 [[BC]]) #[[ATTR10:[0-9]+]]
554; NOT_CGSCC_NPM-NEXT:    ret i32 [[CALL]]
555;
556; IS__CGSCC____: Function Attrs: nofree nosync nounwind readonly willreturn
557; IS__CGSCC____-LABEL: define {{[^@]+}}@i2p
558; IS__CGSCC____-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR5:[0-9]+]] {
559; IS__CGSCC____-NEXT:    [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]]) #[[ATTR11]]
560; IS__CGSCC____-NEXT:    [[I2P:%.*]] = inttoptr i32 [[C]] to i8*
561; IS__CGSCC____-NEXT:    [[BC:%.*]] = bitcast i8* [[I2P]] to i32*
562; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[BC]]) #[[ATTR12:[0-9]+]]
563; IS__CGSCC____-NEXT:    ret i32 [[CALL]]
564;
565  %c = call i32 @p2i(i32* %arg)
566  %i2p = inttoptr i32 %c to i8*
567  %bc = bitcast i8* %i2p to i32*
568  %call = call i32 @ret(i32* %bc)
569  ret i32 %call
570}
571define internal i32 @ret(i32* %arg) {
572; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
573; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@ret
574; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR5:[0-9]+]] {
575; NOT_CGSCC_NPM-NEXT:    [[L:%.*]] = load i32, i32* [[ARG]], align 4
576; NOT_CGSCC_NPM-NEXT:    ret i32 [[L]]
577;
578; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
579; IS__CGSCC____-LABEL: define {{[^@]+}}@ret
580; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR6:[0-9]+]] {
581; IS__CGSCC____-NEXT:    [[L:%.*]] = load i32, i32* [[ARG]], align 4
582; IS__CGSCC____-NEXT:    ret i32 [[L]]
583;
584  %l = load i32, i32* %arg
585  ret i32 %l
586}
587
588; Test to propagate noalias where value is assumed to be no-capture in all the
589; uses possibly executed before this callsite.
590; IR referred from musl/src/strtod.c file
591
592%struct._IO_FILE = type { i32, i8*, i8*, i32 (%struct._IO_FILE*)*, i8*, i8*, i8*, i8*, i32 (%struct._IO_FILE*, i8*, i32)*, i32 (%struct._IO_FILE*, i8*, i32)*, i64 (%struct._IO_FILE*, i64, i32)*, i8*, i32, %struct._IO_FILE*, %struct._IO_FILE*, i32, i32, i32, i16, i8, i8, i32, i32, i8*, i64, i8*, i8*, i8*, [4 x i8], i64, i64, %struct._IO_FILE*, %struct._IO_FILE*, %struct.__locale_struct*, [4 x i8] }
593%struct.__locale_struct = type { [6 x %struct.__locale_map*] }
594%struct.__locale_map = type opaque
595
596; Function Attrs: nounwind optsize
597define internal fastcc double @strtox(i8* %s, i8** %p, i32 %prec) unnamed_addr {
598; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@strtox
599; NOT_CGSCC_NPM-SAME: (i8* [[S:%.*]]) unnamed_addr {
600; NOT_CGSCC_NPM-NEXT:  entry:
601; NOT_CGSCC_NPM-NEXT:    [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8
602; NOT_CGSCC_NPM-NEXT:    [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8*
603; NOT_CGSCC_NPM-NEXT:    call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR11:[0-9]+]]
604; NOT_CGSCC_NPM-NEXT:    [[CALL:%.*]] = call i32 bitcast (i32 (...)* @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull align 8 dereferenceable(240) [[F]], i8* [[S]])
605; NOT_CGSCC_NPM-NEXT:    call void @__shlim(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0)
606; NOT_CGSCC_NPM-NEXT:    [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1)
607; NOT_CGSCC_NPM-NEXT:    call void @llvm.lifetime.end.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]])
608; NOT_CGSCC_NPM-NEXT:    ret double [[CALL1]]
609;
610; IS__CGSCC____-LABEL: define {{[^@]+}}@strtox
611; IS__CGSCC____-SAME: (i8* [[S:%.*]]) unnamed_addr {
612; IS__CGSCC____-NEXT:  entry:
613; IS__CGSCC____-NEXT:    [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8
614; IS__CGSCC____-NEXT:    [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8*
615; IS__CGSCC____-NEXT:    call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR13:[0-9]+]]
616; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call i32 bitcast (i32 (...)* @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull align 8 dereferenceable(240) [[F]], i8* [[S]])
617; IS__CGSCC____-NEXT:    call void @__shlim(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0)
618; IS__CGSCC____-NEXT:    [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1)
619; IS__CGSCC____-NEXT:    call void @llvm.lifetime.end.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]])
620; IS__CGSCC____-NEXT:    ret double [[CALL1]]
621;
622entry:
623  %f = alloca %struct._IO_FILE, align 8
624  %0 = bitcast %struct._IO_FILE* %f to i8*
625  call void @llvm.lifetime.start.p0i8(i64 144, i8* nonnull %0)
626  %call = call i32 bitcast (i32 (...)* @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull %f, i8* %s)
627  call void @__shlim(%struct._IO_FILE* nonnull %f, i64 0)
628  %call1 = call double @__floatscan(%struct._IO_FILE* nonnull %f, i32 %prec, i32 1)
629  call void @llvm.lifetime.end.p0i8(i64 144, i8* nonnull %0)
630
631  ret double %call1
632}
633
634; Function Attrs: nounwind optsize
635define dso_local double @strtod(i8* noalias %s, i8** noalias %p) {
636; CHECK-LABEL: define {{[^@]+}}@strtod
637; CHECK-SAME: (i8* noalias [[S:%.*]], i8** noalias nocapture nofree readnone [[P:%.*]]) {
638; CHECK-NEXT:  entry:
639; CHECK-NEXT:    [[CALL:%.*]] = tail call fastcc double @strtox(i8* [[S]])
640; CHECK-NEXT:    ret double [[CALL]]
641;
642entry:
643  %call = tail call fastcc double @strtox(i8* %s, i8** %p, i32 1)
644  ret double %call
645}
646
647; Function Attrs: argmemonly nounwind willreturn
648declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
649
650; Function Attrs: optsize
651declare dso_local i32 @sh_fromstring(...) local_unnamed_addr
652
653; Function Attrs: optsize
654declare dso_local void @__shlim(%struct._IO_FILE*, i64) local_unnamed_addr
655
656; Function Attrs: optsize
657declare dso_local double @__floatscan(%struct._IO_FILE*, i32, i32) local_unnamed_addr
658
659; Function Attrs: argmemonly nounwind willreturn
660declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
661
662; Test 15
663; propagate noalias to some callsite arguments that there is no possibly reachable capture before it
664
665@alias_of_p = external global i32*
666
667define void @make_alias(i32* %p) {
668; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
669; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@make_alias
670; NOT_CGSCC_NPM-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR7:[0-9]+]] {
671; NOT_CGSCC_NPM-NEXT:    store i32* [[P]], i32** @alias_of_p, align 8
672; NOT_CGSCC_NPM-NEXT:    ret void
673;
674; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
675; IS__CGSCC____-LABEL: define {{[^@]+}}@make_alias
676; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR8:[0-9]+]] {
677; IS__CGSCC____-NEXT:    store i32* [[P]], i32** @alias_of_p, align 8
678; IS__CGSCC____-NEXT:    ret void
679;
680  store i32* %p, i32** @alias_of_p
681  ret void
682}
683
684define void @only_store(i32* %p) {
685; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
686; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@only_store
687; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR8:[0-9]+]] {
688; NOT_CGSCC_NPM-NEXT:    store i32 0, i32* [[P]], align 4
689; NOT_CGSCC_NPM-NEXT:    ret void
690;
691; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
692; IS__CGSCC____-LABEL: define {{[^@]+}}@only_store
693; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR9:[0-9]+]] {
694; IS__CGSCC____-NEXT:    store i32 0, i32* [[P]], align 4
695; IS__CGSCC____-NEXT:    ret void
696;
697  store i32 0, i32* %p
698  ret void
699}
700
701define void @test15_caller(i32* noalias %p, i32 %c) {
702; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
703; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test15_caller
704; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] {
705; NOT_CGSCC_NPM-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
706; NOT_CGSCC_NPM-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
707; NOT_CGSCC_NPM:       if.then:
708; NOT_CGSCC_NPM-NEXT:    tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) #[[ATTR12:[0-9]+]]
709; NOT_CGSCC_NPM-NEXT:    br label [[IF_END]]
710; NOT_CGSCC_NPM:       if.end:
711; NOT_CGSCC_NPM-NEXT:    tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR12]]
712; NOT_CGSCC_NPM-NEXT:    ret void
713;
714; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly
715; IS__CGSCC____-LABEL: define {{[^@]+}}@test15_caller
716; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR10:[0-9]+]] {
717; IS__CGSCC____-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
718; IS__CGSCC____-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
719; IS__CGSCC____:       if.then:
720; IS__CGSCC____-NEXT:    tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14:[0-9]+]]
721; IS__CGSCC____-NEXT:    br label [[IF_END]]
722; IS__CGSCC____:       if.end:
723; IS__CGSCC____-NEXT:    tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR14]]
724; IS__CGSCC____-NEXT:    ret void
725;
726  %tobool = icmp eq i32 %c, 0
727  br i1 %tobool, label %if.end, label %if.then
728
729
730if.then:
731  tail call void @only_store(i32* %p)
732  br label %if.end
733
734if.end:
735  tail call void @make_alias(i32* %p)
736  ret void
737}
738
739; Test 16
740;
741; __attribute__((noinline)) static void test16_sub(int * restrict p, int c1, int c2) {
742;   if (c1) {
743;     only_store(p);
744;     make_alias(p);
745;   }
746;   if (!c2) {
747;     only_store(p);
748;   }
749; }
750; void test16_caller(int * restrict p, int c) {
751;   test16_sub(p, c, c);
752; }
753;
754; FIXME: this should be tail @only_store(i32* noalias %p)
755;        when test16_caller is called, c1 always equals to c2. (Note that linkage is internal)
756;        Therefore, only one of the two conditions of if statementes will be fulfilled.
757
758define internal void @test16_sub(i32* noalias %p, i32 %c1, i32 %c2) {
759; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
760; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test16_sub
761; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR7]] {
762; NOT_CGSCC_NPM-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C1]], 0
763; NOT_CGSCC_NPM-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
764; NOT_CGSCC_NPM:       if.then:
765; NOT_CGSCC_NPM-NEXT:    tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) #[[ATTR12]]
766; NOT_CGSCC_NPM-NEXT:    tail call void @make_alias(i32* nofree writeonly align 4 [[P]]) #[[ATTR12]]
767; NOT_CGSCC_NPM-NEXT:    br label [[IF_END]]
768; NOT_CGSCC_NPM:       if.end:
769; NOT_CGSCC_NPM-NEXT:    [[TOBOOL1:%.*]] = icmp eq i32 [[C2]], 0
770; NOT_CGSCC_NPM-NEXT:    br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]
771; NOT_CGSCC_NPM:       if.then2:
772; NOT_CGSCC_NPM-NEXT:    tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR12]]
773; NOT_CGSCC_NPM-NEXT:    br label [[IF_END3]]
774; NOT_CGSCC_NPM:       if.end3:
775; NOT_CGSCC_NPM-NEXT:    ret void
776;
777; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly
778; IS__CGSCC____-LABEL: define {{[^@]+}}@test16_sub
779; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR10]] {
780; IS__CGSCC____-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C1]], 0
781; IS__CGSCC____-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
782; IS__CGSCC____:       if.then:
783; IS__CGSCC____-NEXT:    tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]]
784; IS__CGSCC____-NEXT:    tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]]
785; IS__CGSCC____-NEXT:    br label [[IF_END]]
786; IS__CGSCC____:       if.end:
787; IS__CGSCC____-NEXT:    [[TOBOOL1:%.*]] = icmp eq i32 [[C2]], 0
788; IS__CGSCC____-NEXT:    br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]
789; IS__CGSCC____:       if.then2:
790; IS__CGSCC____-NEXT:    tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]]
791; IS__CGSCC____-NEXT:    br label [[IF_END3]]
792; IS__CGSCC____:       if.end3:
793; IS__CGSCC____-NEXT:    ret void
794;
795  %tobool = icmp eq i32 %c1, 0
796  br i1 %tobool, label %if.end, label %if.then
797
798if.then:
799  tail call void @only_store(i32* %p)
800  tail call void @make_alias(i32* %p)
801  br label %if.end
802if.end:
803
804  %tobool1 = icmp eq i32 %c2, 0
805  br i1 %tobool1, label %if.then2, label %if.end3
806
807if.then2:
808  tail call void @only_store(i32* %p)
809  br label %if.end3
810if.end3:
811
812  ret void
813}
814
815define void @test16_caller(i32* %p, i32 %c) {
816; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
817; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test16_caller
818; NOT_CGSCC_NPM-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] {
819; NOT_CGSCC_NPM-NEXT:    tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR12]]
820; NOT_CGSCC_NPM-NEXT:    ret void
821;
822; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly
823; IS__CGSCC____-LABEL: define {{[^@]+}}@test16_caller
824; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR10]] {
825; IS__CGSCC____-NEXT:    tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR14]]
826; IS__CGSCC____-NEXT:    ret void
827;
828  tail call void @test16_sub(i32* %p, i32 %c, i32 %c)
829  ret void
830}
831
832; test 17
833;
834; only_store is not called after make_alias is called.
835;
836; void test17_caller(int* p, int c) {
837;   if(c) {
838;     make_alias(p);
839;     if(0 == 0) {
840;       goto l3;
841;     } else {
842;       goto l2;
843;     }
844;   }
845;   l2:
846;     only_store(p);
847;   l3:
848;   return;
849; }
850
851define void @test17_caller(i32* noalias %p, i32 %c) {
852; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
853; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test17_caller
854; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] {
855; NOT_CGSCC_NPM-NEXT:  entry:
856; NOT_CGSCC_NPM-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
857; NOT_CGSCC_NPM-NEXT:    br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]]
858; NOT_CGSCC_NPM:       l1:
859; NOT_CGSCC_NPM-NEXT:    tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR12]]
860; NOT_CGSCC_NPM-NEXT:    br label [[L3:%.*]]
861; NOT_CGSCC_NPM:       l2:
862; NOT_CGSCC_NPM-NEXT:    tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR12]]
863; NOT_CGSCC_NPM-NEXT:    br label [[L3]]
864; NOT_CGSCC_NPM:       l3:
865; NOT_CGSCC_NPM-NEXT:    ret void
866;
867; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly
868; IS__CGSCC____-LABEL: define {{[^@]+}}@test17_caller
869; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR10]] {
870; IS__CGSCC____-NEXT:  entry:
871; IS__CGSCC____-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
872; IS__CGSCC____-NEXT:    br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]]
873; IS__CGSCC____:       l1:
874; IS__CGSCC____-NEXT:    tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR14]]
875; IS__CGSCC____-NEXT:    br label [[L3:%.*]]
876; IS__CGSCC____:       l2:
877; IS__CGSCC____-NEXT:    tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]]
878; IS__CGSCC____-NEXT:    br label [[L3]]
879; IS__CGSCC____:       l3:
880; IS__CGSCC____-NEXT:    ret void
881;
882entry:
883  %tobool = icmp eq i32 %c, 0
884  br i1 %tobool, label %l1, label %l2
885
886l1:
887  tail call void @make_alias(i32* %p)
888  %tobool2 = icmp eq i32 0, 0
889  br i1 %tobool2, label %l3, label %l2
890
891l2:
892  tail call void @only_store(i32* %p)
893  br label %l3
894
895l3:
896  ret void
897}
898
899; test 18
900; void test18_caller(int* p, int c) {
901;   if(c) {
902;     make_alias(p);
903;     noreturn();
904;   }
905;   only_store(p);
906;   return;
907; }
908
909define void @noreturn() {
910; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
911; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@noreturn
912; NOT_CGSCC_NPM-SAME: () #[[ATTR9]] {
913; NOT_CGSCC_NPM-NEXT:    ret void
914;
915; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn
916; IS__CGSCC____-LABEL: define {{[^@]+}}@noreturn
917; IS__CGSCC____-SAME: () #[[ATTR2]] {
918; IS__CGSCC____-NEXT:    ret void
919;
920  call void @noreturn()
921  ret void
922}
923
924define void @test18_caller(i32* noalias %p, i32 %c) {
925; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
926; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test18_caller
927; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] {
928; NOT_CGSCC_NPM-NEXT:  entry:
929; NOT_CGSCC_NPM-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
930; NOT_CGSCC_NPM-NEXT:    br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]]
931; NOT_CGSCC_NPM:       l1:
932; NOT_CGSCC_NPM-NEXT:    tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR12]]
933; NOT_CGSCC_NPM-NEXT:    br label [[L2]]
934; NOT_CGSCC_NPM:       l2:
935; NOT_CGSCC_NPM-NEXT:    tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR12]]
936; NOT_CGSCC_NPM-NEXT:    ret void
937;
938; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly
939; IS__CGSCC____-LABEL: define {{[^@]+}}@test18_caller
940; IS__CGSCC____-SAME: (i32* noalias nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]], i32 [[C:%.*]]) #[[ATTR10]] {
941; IS__CGSCC____-NEXT:  entry:
942; IS__CGSCC____-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
943; IS__CGSCC____-NEXT:    br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]]
944; IS__CGSCC____:       l1:
945; IS__CGSCC____-NEXT:    tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]]
946; IS__CGSCC____-NEXT:    br label [[L2]]
947; IS__CGSCC____:       l2:
948; IS__CGSCC____-NEXT:    tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]]
949; IS__CGSCC____-NEXT:    ret void
950;
951entry:
952  %tobool = icmp eq i32 %c, 0
953  br i1 %tobool, label %l1, label %l2
954
955l1:
956  tail call void @make_alias(i32* %p)
957  tail call void @noreturn()
958  br label %l2
959
960l2:
961  tail call void @only_store(i32* %p)
962  ret void
963}
964;.
965; NOT_CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
966; NOT_CGSCC_NPM: attributes #[[ATTR1]] = { nounwind uwtable }
967; NOT_CGSCC_NPM: attributes #[[ATTR2]] = { nounwind }
968; NOT_CGSCC_NPM: attributes #[[ATTR3]] = { nounwind ssp uwtable }
969; NOT_CGSCC_NPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind readonly willreturn }
970; NOT_CGSCC_NPM: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
971; NOT_CGSCC_NPM: attributes #[[ATTR6:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn }
972; NOT_CGSCC_NPM: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn writeonly }
973; NOT_CGSCC_NPM: attributes #[[ATTR8]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
974; NOT_CGSCC_NPM: attributes #[[ATTR9]] = { nofree nosync nounwind readnone willreturn }
975; NOT_CGSCC_NPM: attributes #[[ATTR10]] = { nofree nosync nounwind readonly willreturn }
976; NOT_CGSCC_NPM: attributes #[[ATTR11]] = { willreturn }
977; NOT_CGSCC_NPM: attributes #[[ATTR12]] = { nofree nosync nounwind willreturn writeonly }
978;.
979; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
980; IS__CGSCC____: attributes #[[ATTR1]] = { nounwind uwtable }
981; IS__CGSCC____: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn }
982; IS__CGSCC____: attributes #[[ATTR3]] = { nounwind }
983; IS__CGSCC____: attributes #[[ATTR4]] = { nounwind ssp uwtable }
984; IS__CGSCC____: attributes #[[ATTR5]] = { nofree nosync nounwind readonly willreturn }
985; IS__CGSCC____: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
986; IS__CGSCC____: attributes #[[ATTR7:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn }
987; IS__CGSCC____: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn writeonly }
988; IS__CGSCC____: attributes #[[ATTR9]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
989; IS__CGSCC____: attributes #[[ATTR10]] = { nofree nosync nounwind willreturn writeonly }
990; IS__CGSCC____: attributes #[[ATTR11]] = { readnone willreturn }
991; IS__CGSCC____: attributes #[[ATTR12]] = { readonly willreturn }
992; IS__CGSCC____: attributes #[[ATTR13]] = { willreturn }
993; IS__CGSCC____: attributes #[[ATTR14]] = { nounwind willreturn writeonly }
994;.
995