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