Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / Attributor / noalias.ll
blob00ca83d0c5d688131374bf4908e04d853af05701
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-annotate-decl-cs  -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
5 ; TEST 1 - negative.
7 ; void *G;
8 ; void *foo(){
9 ;   void *V = malloc(4);
10 ;   G = V;
11 ;   return V;
12 ; }
14 @G = external global ptr
17 ; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = external global ptr
18 ; CHECK: @[[ALIAS_OF_P:[a-zA-Z0-9_$"\\.-]+]] = external global ptr
20 define ptr @foo() {
21 ; CHECK-LABEL: define {{[^@]+}}@foo() {
22 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
23 ; CHECK-NEXT:    store ptr [[TMP1]], ptr @G, align 8
24 ; CHECK-NEXT:    ret ptr [[TMP1]]
26   %1 = tail call noalias ptr @malloc(i64 4)
27   store ptr %1, ptr @G, align 8
28   ret ptr %1
31 declare noalias ptr @malloc(i64)
33 ; TEST 2
34 ; call noalias function in return instruction.
36 define ptr @return_noalias(){
37 ; CHECK-LABEL: define {{[^@]+}}@return_noalias() {
38 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
39 ; CHECK-NEXT:    ret ptr [[TMP1]]
41   %1 = tail call noalias ptr @malloc(i64 4)
42   ret ptr %1
45 define void @nocapture(ptr %a){
46 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
47 ; CHECK-LABEL: define {{[^@]+}}@nocapture
48 ; CHECK-SAME: (ptr nocapture nofree readnone [[A:%.*]]) #[[ATTR0:[0-9]+]] {
49 ; CHECK-NEXT:    ret void
51   ret void
54 define ptr @return_noalias_looks_like_capture(){
55 ; CHECK-LABEL: define {{[^@]+}}@return_noalias_looks_like_capture() {
56 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
57 ; CHECK-NEXT:    ret ptr [[TMP1]]
59   %1 = tail call noalias ptr @malloc(i64 4)
60   call void @nocapture(ptr %1)
61   ret ptr %1
64 define ptr @return_noalias_casted(){
65 ; CHECK-LABEL: define {{[^@]+}}@return_noalias_casted() {
66 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
67 ; CHECK-NEXT:    ret ptr [[TMP1]]
69   %1 = tail call noalias ptr @malloc(i64 4)
70   ret ptr %1
73 declare ptr @alias()
75 ; TEST 3
76 define ptr @call_alias(){
77 ; CHECK-LABEL: define {{[^@]+}}@call_alias() {
78 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call ptr @alias()
79 ; CHECK-NEXT:    ret ptr [[TMP1]]
81   %1 = tail call ptr @alias()
82   ret ptr %1
85 ; TEST 4
86 ; void *baz();
87 ; void *foo(int a);
89 ; void *bar()  {
90 ;   foo(0);
91 ;    return baz();
92 ; }
94 ; void *foo(int a)  {
95 ;   if (a)
96 ;   bar();
97 ;   return malloc(4);
98 ; }
100 define ptr @bar() nounwind uwtable {
101 ; TUNIT: Function Attrs: nounwind uwtable
102 ; TUNIT-LABEL: define {{[^@]+}}@bar
103 ; TUNIT-SAME: () #[[ATTR1:[0-9]+]] {
104 ; TUNIT-NEXT:    [[TMP1:%.*]] = tail call ptr (...) @baz() #[[ATTR2:[0-9]+]]
105 ; TUNIT-NEXT:    ret ptr [[TMP1]]
107 ; CGSCC: Function Attrs: nounwind uwtable
108 ; CGSCC-LABEL: define {{[^@]+}}@bar
109 ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] {
110 ; CGSCC-NEXT:    [[TMP1:%.*]] = tail call ptr (...) @baz() #[[ATTR3:[0-9]+]]
111 ; CGSCC-NEXT:    ret ptr [[TMP1]]
113   %1 = tail call ptr (...) @baz()
114   ret ptr %1
117 define ptr @foo1(i32 %0) nounwind uwtable {
118 ; TUNIT: Function Attrs: nounwind uwtable
119 ; TUNIT-LABEL: define {{[^@]+}}@foo1
120 ; TUNIT-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] {
121 ; TUNIT-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0
122 ; TUNIT-NEXT:    br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
123 ; TUNIT:       3:
124 ; TUNIT-NEXT:    [[TMP4:%.*]] = tail call ptr (...) @baz() #[[ATTR2]]
125 ; TUNIT-NEXT:    br label [[TMP5]]
126 ; TUNIT:       5:
127 ; TUNIT-NEXT:    [[TMP6:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
128 ; TUNIT-NEXT:    ret ptr [[TMP6]]
130 ; CGSCC: Function Attrs: nounwind uwtable
131 ; CGSCC-LABEL: define {{[^@]+}}@foo1
132 ; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] {
133 ; CGSCC-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0
134 ; CGSCC-NEXT:    br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
135 ; CGSCC:       3:
136 ; CGSCC-NEXT:    [[TMP4:%.*]] = tail call ptr (...) @baz() #[[ATTR3]]
137 ; CGSCC-NEXT:    br label [[TMP5]]
138 ; CGSCC:       5:
139 ; CGSCC-NEXT:    [[TMP6:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
140 ; CGSCC-NEXT:    ret ptr [[TMP6]]
142   %2 = icmp eq i32 %0, 0
143   br i1 %2, label %5, label %3
145 3:                                                ; preds = %1
146   %4 = tail call ptr (...) @baz()
147   br label %5
149 5:                                                ; preds = %1, %3
150   %6 = tail call noalias ptr @malloc(i64 4)
151   ret ptr %6
154 declare ptr @baz(...) nounwind uwtable
156 ; TEST 5
158 ; Returning global pointer. Should not be noalias.
159 define ptr @getter() {
160 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
161 ; CHECK-LABEL: define {{[^@]+}}@getter
162 ; CHECK-SAME: () #[[ATTR0]] {
163 ; CHECK-NEXT:    ret ptr @G
165   ret ptr @G
168 ; Returning global pointer. Should not be noalias.
169 define ptr @calle1(){
170 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
171 ; TUNIT-LABEL: define {{[^@]+}}@calle1
172 ; TUNIT-SAME: () #[[ATTR0]] {
173 ; TUNIT-NEXT:    ret ptr @G
175 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
176 ; CGSCC-LABEL: define {{[^@]+}}@calle1
177 ; CGSCC-SAME: () #[[ATTR2:[0-9]+]] {
178 ; CGSCC-NEXT:    [[TMP1:%.*]] = call noundef nonnull align 8 dereferenceable(8) ptr @getter() #[[ATTR12:[0-9]+]]
179 ; CGSCC-NEXT:    ret ptr [[TMP1]]
181   %1 = call ptr @getter()
182   ret ptr %1
185 ; TEST 6
186 declare noalias ptr @strdup(ptr nocapture) nounwind
188 define ptr @test6() nounwind uwtable ssp {
189 ; TUNIT: Function Attrs: nounwind ssp uwtable
190 ; TUNIT-LABEL: define {{[^@]+}}@test6
191 ; TUNIT-SAME: () #[[ATTR3:[0-9]+]] {
192 ; TUNIT-NEXT:    [[X:%.*]] = alloca [2 x i8], align 1
193 ; TUNIT-NEXT:    store i8 97, ptr [[X]], align 1
194 ; TUNIT-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], ptr [[X]], i64 0, i64 1
195 ; TUNIT-NEXT:    store i8 0, ptr [[ARRAYIDX1]], align 1
196 ; TUNIT-NEXT:    [[CALL:%.*]] = call noalias ptr @strdup(ptr noalias nocapture noundef nonnull dereferenceable(2) [[X]]) #[[ATTR2]]
197 ; TUNIT-NEXT:    ret ptr [[CALL]]
199 ; CGSCC: Function Attrs: nounwind ssp uwtable
200 ; CGSCC-LABEL: define {{[^@]+}}@test6
201 ; CGSCC-SAME: () #[[ATTR4:[0-9]+]] {
202 ; CGSCC-NEXT:    [[X:%.*]] = alloca [2 x i8], align 1
203 ; CGSCC-NEXT:    store i8 97, ptr [[X]], align 1
204 ; CGSCC-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], ptr [[X]], i64 0, i64 1
205 ; CGSCC-NEXT:    store i8 0, ptr [[ARRAYIDX1]], align 1
206 ; CGSCC-NEXT:    [[CALL:%.*]] = call noalias ptr @strdup(ptr noalias nocapture noundef nonnull dereferenceable(2) [[X]]) #[[ATTR3]]
207 ; CGSCC-NEXT:    ret ptr [[CALL]]
209   %x = alloca [2 x i8], align 1
210   store i8 97, ptr %x, align 1
211   %arrayidx1 = getelementptr inbounds [2 x i8], ptr %x, i64 0, i64 1
212   store i8 0, ptr %arrayidx1, align 1
213   %call = call noalias ptr @strdup(ptr %x) nounwind
214   ret ptr %call
217 ; TEST 7
219 define ptr @test7() nounwind {
220 ; TUNIT: Function Attrs: nounwind
221 ; TUNIT-LABEL: define {{[^@]+}}@test7
222 ; TUNIT-SAME: () #[[ATTR2]] {
223 ; TUNIT-NEXT:  entry:
224 ; TUNIT-NEXT:    [[A:%.*]] = call noalias ptr @malloc(i64 noundef 4) #[[ATTR2]]
225 ; TUNIT-NEXT:    [[TOBOOL:%.*]] = icmp eq ptr [[A]], null
226 ; TUNIT-NEXT:    br i1 [[TOBOOL]], label [[RETURN:%.*]], label [[IF_END:%.*]]
227 ; TUNIT:       if.end:
228 ; TUNIT-NEXT:    store i8 7, ptr [[A]], align 1
229 ; TUNIT-NEXT:    br label [[RETURN]]
230 ; TUNIT:       return:
231 ; TUNIT-NEXT:    [[RETVAL_0:%.*]] = phi ptr [ [[A]], [[IF_END]] ], [ null, [[ENTRY:%.*]] ]
232 ; TUNIT-NEXT:    ret ptr [[RETVAL_0]]
234 ; CGSCC: Function Attrs: nounwind
235 ; CGSCC-LABEL: define {{[^@]+}}@test7
236 ; CGSCC-SAME: () #[[ATTR3]] {
237 ; CGSCC-NEXT:  entry:
238 ; CGSCC-NEXT:    [[A:%.*]] = call noalias ptr @malloc(i64 noundef 4) #[[ATTR3]]
239 ; CGSCC-NEXT:    [[TOBOOL:%.*]] = icmp eq ptr [[A]], null
240 ; CGSCC-NEXT:    br i1 [[TOBOOL]], label [[RETURN:%.*]], label [[IF_END:%.*]]
241 ; CGSCC:       if.end:
242 ; CGSCC-NEXT:    store i8 7, ptr [[A]], align 1
243 ; CGSCC-NEXT:    br label [[RETURN]]
244 ; CGSCC:       return:
245 ; CGSCC-NEXT:    [[RETVAL_0:%.*]] = phi ptr [ [[A]], [[IF_END]] ], [ null, [[ENTRY:%.*]] ]
246 ; CGSCC-NEXT:    ret ptr [[RETVAL_0]]
248 entry:
249   %A = call noalias ptr @malloc(i64 4) nounwind
250   %tobool = icmp eq ptr %A, null
251   br i1 %tobool, label %return, label %if.end
253 if.end:
254   store i8 7, ptr %A
255   br label %return
257 return:
258   %retval.0 = phi ptr [ %A, %if.end ], [ null, %entry ]
259   ret ptr %retval.0
262 ; TEST 8
264 define ptr @test8(ptr %0) nounwind uwtable {
265 ; CHECK: Function Attrs: nounwind uwtable
266 ; CHECK-LABEL: define {{[^@]+}}@test8
267 ; CHECK-SAME: (ptr [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] {
268 ; CHECK-NEXT:    [[TMP2:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
269 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne ptr [[TMP0]], null
270 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
271 ; CHECK:       4:
272 ; CHECK-NEXT:    store i8 10, ptr [[TMP2]], align 1
273 ; CHECK-NEXT:    br label [[TMP5]]
274 ; CHECK:       5:
275 ; CHECK-NEXT:    ret ptr [[TMP2]]
277   %2 = tail call noalias ptr @malloc(i64 4)
278   %3 = icmp ne ptr %0, null
279   br i1 %3, label %4, label %5
281 4:                                                ; preds = %1
282   store i8 10, ptr %2
283   br label %5
285 5:                                                ; preds = %1, %4
286   ret ptr %2
289 ; TEST 9
290 ; Simple Argument Test
291 declare void @use_i8(ptr nocapture)
292 define internal void @test9a(ptr %a, ptr %b) {
293 ; TUNIT: Function Attrs: memory(readwrite, argmem: none)
294 ; TUNIT-LABEL: define {{[^@]+}}@test9a
295 ; TUNIT-SAME: () #[[ATTR4:[0-9]+]] {
296 ; TUNIT-NEXT:    call void @use_i8(ptr noundef align 4294967296 null)
297 ; TUNIT-NEXT:    ret void
299 ; CGSCC: Function Attrs: memory(readwrite, argmem: none)
300 ; CGSCC-LABEL: define {{[^@]+}}@test9a
301 ; CGSCC-SAME: () #[[ATTR5:[0-9]+]] {
302 ; CGSCC-NEXT:    call void @use_i8(ptr noundef align 4294967296 null)
303 ; CGSCC-NEXT:    ret void
305   call void @use_i8(ptr null)
306   ret void
308 define internal void @test9b(ptr %a, ptr %b) {
309 ; FIXME: %b should be noalias
310 ; CHECK-LABEL: define {{[^@]+}}@test9b
311 ; CHECK-SAME: (ptr noalias nocapture [[A:%.*]], ptr nocapture [[B:%.*]]) {
312 ; CHECK-NEXT:    call void @use_i8(ptr noalias nocapture [[A]])
313 ; CHECK-NEXT:    call void @use_i8(ptr nocapture [[B]])
314 ; CHECK-NEXT:    ret void
316   call void @use_i8(ptr %a)
317   call void @use_i8(ptr %b)
318   ret void
320 define internal void @test9c(ptr %a, ptr %b, ptr %c) {
321 ; CHECK-LABEL: define {{[^@]+}}@test9c
322 ; CHECK-SAME: (ptr noalias nocapture [[A:%.*]], ptr nocapture [[B:%.*]], ptr nocapture [[C:%.*]]) {
323 ; CHECK-NEXT:    call void @use_i8(ptr noalias nocapture [[A]])
324 ; CHECK-NEXT:    call void @use_i8(ptr nocapture [[B]])
325 ; CHECK-NEXT:    call void @use_i8(ptr nocapture [[C]])
326 ; CHECK-NEXT:    ret void
328   call void @use_i8(ptr %a)
329   call void @use_i8(ptr %b)
330   call void @use_i8(ptr %c)
331   ret void
333 define void @test9_helper(ptr %a, ptr %b) {
334 ; CHECK-LABEL: define {{[^@]+}}@test9_helper
335 ; CHECK-SAME: (ptr nocapture [[A:%.*]], ptr nocapture [[B:%.*]]) {
336 ; CHECK-NEXT:    tail call void @test9a()
337 ; CHECK-NEXT:    tail call void @test9a()
338 ; CHECK-NEXT:    tail call void @test9b(ptr noalias nocapture [[A]], ptr nocapture [[B]])
339 ; CHECK-NEXT:    tail call void @test9b(ptr noalias nocapture [[B]], ptr noalias nocapture [[A]])
340 ; CHECK-NEXT:    tail call void @test9c(ptr noalias nocapture [[A]], ptr nocapture [[B]], ptr nocapture [[B]])
341 ; CHECK-NEXT:    tail call void @test9c(ptr noalias nocapture [[B]], ptr noalias nocapture [[A]], ptr noalias nocapture [[A]])
342 ; CHECK-NEXT:    ret void
344   tail call void @test9a(ptr noalias %a, ptr %b)
345   tail call void @test9a(ptr noalias %b, ptr noalias %a)
346   tail call void @test9b(ptr noalias %a, ptr %b)
347   tail call void @test9b(ptr noalias %b, ptr noalias %a)
348   tail call void @test9c(ptr noalias %a, ptr %b, ptr %b)
349   tail call void @test9c(ptr noalias %b, ptr noalias %a, ptr noalias %a)
350   ret void
354 ; TEST 10
355 ; Simple CallSite Test
357 declare void @test10_helper_1(ptr %a)
358 define void @test10_helper_2(ptr noalias %a) {
359 ; CHECK-LABEL: define {{[^@]+}}@test10_helper_2
360 ; CHECK-SAME: (ptr noalias [[A:%.*]]) {
361 ; CHECK-NEXT:    tail call void @test10_helper_1(ptr [[A]])
362 ; CHECK-NEXT:    ret void
364   tail call void @test10_helper_1(ptr %a)
365   ret void
367 define void @test10(ptr noalias %a) {
368 ; CHECK-LABEL: define {{[^@]+}}@test10
369 ; CHECK-SAME: (ptr noalias [[A:%.*]]) {
370 ; CHECK-NEXT:    tail call void @test10_helper_1(ptr [[A]])
371 ; CHECK-NEXT:    tail call void @test10_helper_2(ptr [[A]])
372 ; CHECK-NEXT:    ret void
374 ; FIXME: missing noalias
375   tail call void @test10_helper_1(ptr %a)
377   tail call void @test10_helper_2(ptr %a)
378   ret void
381 ; TEST 11
382 ; CallSite Test
384 declare void @test11_helper(ptr %a, ptr %b)
385 define void @test11(ptr noalias %a) {
386 ; CHECK-LABEL: define {{[^@]+}}@test11
387 ; CHECK-SAME: (ptr noalias [[A:%.*]]) {
388 ; CHECK-NEXT:    tail call void @test11_helper(ptr [[A]], ptr [[A]])
389 ; CHECK-NEXT:    ret void
391   tail call void @test11_helper(ptr %a, ptr %a)
392   ret void
396 ; TEST 12
397 ; CallSite Argument
398 declare void @use_nocapture(ptr nocapture)
399 declare void @use(ptr)
400 define void @test12_1() {
401 ; CHECK-LABEL: define {{[^@]+}}@test12_1() {
402 ; CHECK-NEXT:    [[A:%.*]] = alloca i8, align 4
403 ; CHECK-NEXT:    [[B:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
404 ; CHECK-NEXT:    tail call void @use_nocapture(ptr noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A]])
405 ; CHECK-NEXT:    tail call void @use_nocapture(ptr noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A]])
406 ; CHECK-NEXT:    tail call void @use_nocapture(ptr noalias nocapture [[B]])
407 ; CHECK-NEXT:    tail call void @use_nocapture(ptr noalias nocapture [[B]])
408 ; CHECK-NEXT:    ret void
410   %A = alloca i8, align 4
411   %B = tail call noalias ptr @malloc(i64 4)
412   tail call void @use_nocapture(ptr %A)
413   tail call void @use_nocapture(ptr %A)
414   tail call void @use_nocapture(ptr %B)
415   tail call void @use_nocapture(ptr %B)
416   ret void
419 define void @test12_2(){
420 ; CHECK-LABEL: define {{[^@]+}}@test12_2() {
421 ; CHECK-NEXT:    [[A:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
422 ; CHECK-NEXT:    tail call void @use_nocapture(ptr nocapture [[A]])
423 ; CHECK-NEXT:    tail call void @use_nocapture(ptr nocapture [[A]])
424 ; CHECK-NEXT:    tail call void @use(ptr [[A]])
425 ; CHECK-NEXT:    tail call void @use_nocapture(ptr nocapture [[A]])
426 ; CHECK-NEXT:    ret void
428 ; FIXME: This should be @use_nocapture(ptr noalias [[A]])
429 ; FIXME: This should be @use_nocapture(ptr noalias nocapture [[A]])
430   %A = tail call noalias ptr @malloc(i64 4)
431   tail call void @use_nocapture(ptr %A)
432   tail call void @use_nocapture(ptr %A)
433   tail call void @use(ptr %A)
434   tail call void @use_nocapture(ptr %A)
435   ret void
438 declare void @two_args(ptr nocapture , ptr nocapture)
439 define void @test12_3(){
440 ; CHECK-LABEL: define {{[^@]+}}@test12_3() {
441 ; CHECK-NEXT:    [[A:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
442 ; CHECK-NEXT:    tail call void @two_args(ptr nocapture [[A]], ptr nocapture [[A]])
443 ; CHECK-NEXT:    ret void
445   %A = tail call noalias ptr @malloc(i64 4)
446   tail call void @two_args(ptr %A, ptr %A)
447   ret void
450 define void @test12_4(){
451 ; CHECK-LABEL: define {{[^@]+}}@test12_4() {
452 ; CHECK-NEXT:    [[A:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
453 ; CHECK-NEXT:    [[B:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
454 ; CHECK-NEXT:    [[A_1:%.*]] = getelementptr i8, ptr [[A]], i64 1
455 ; CHECK-NEXT:    tail call void @two_args(ptr noalias nocapture [[A]], ptr noalias nocapture [[B]])
456 ; CHECK-NEXT:    tail call void @two_args(ptr nocapture [[A]], ptr nocapture [[A]])
457 ; CHECK-NEXT:    tail call void @two_args(ptr nocapture [[A]], ptr nocapture [[A_1]])
458 ; CHECK-NEXT:    tail call void @two_args(ptr noalias nocapture [[A]], ptr noalias nocapture [[B]])
459 ; CHECK-NEXT:    ret void
461   %A = tail call noalias ptr @malloc(i64 4)
462   %B = tail call noalias ptr @malloc(i64 4)
463   %A_1 = getelementptr i8, ptr %A, i64 1
465   tail call void @two_args(ptr %A, ptr %B)
467   tail call void @two_args(ptr %A, ptr %A)
469   tail call void @two_args(ptr %A, ptr %A_1)
471 ; FIXME: This should be @two_args(ptr noalias nocapture %A, ptr noalias nocapture %B)
472   tail call void @two_args(ptr %A, ptr %B)
473   ret void
476 ; TEST 13
477 define void @use_i8_internal(ptr %a) {
478 ; CHECK-LABEL: define {{[^@]+}}@use_i8_internal
479 ; CHECK-SAME: (ptr nocapture [[A:%.*]]) {
480 ; CHECK-NEXT:    call void @use_i8(ptr nocapture [[A]])
481 ; CHECK-NEXT:    ret void
483   call void @use_i8(ptr %a)
484   ret void
487 define void @test13_use_noalias(){
488 ; CHECK-LABEL: define {{[^@]+}}@test13_use_noalias() {
489 ; CHECK-NEXT:    [[M1:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
490 ; CHECK-NEXT:    call void @use_i8_internal(ptr noalias nocapture [[M1]])
491 ; CHECK-NEXT:    ret void
493 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13_use_noalias()
494 ; IS__CGSCC_OPM-NEXT:    [[M1:%.*]] = tail call noalias ptr @malloc(i64 4)
495 ; IS__CGSCC_OPM-NEXT:    call void @use_i8_internal(ptr noalias [[M1]])
496 ; IS__CGSCC_OPM-NEXT:    ret void
497   %m1 = tail call noalias ptr @malloc(i64 4)
498   call void @use_i8_internal(ptr %m1)
499   ret void
502 define void @test13_use_alias(){
503 ; CHECK-LABEL: define {{[^@]+}}@test13_use_alias() {
504 ; CHECK-NEXT:    [[M1:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
505 ; CHECK-NEXT:    call void @use_i8_internal(ptr noalias nocapture [[M1]])
506 ; CHECK-NEXT:    call void @use_i8_internal(ptr noalias nocapture [[M1]])
507 ; CHECK-NEXT:    ret void
509   %m1 = tail call noalias ptr @malloc(i64 4)
510   call void @use_i8_internal(ptr %m1)
511   call void @use_i8_internal(ptr %m1)
512   ret void
515 ; TEST 14 i2p casts
516 define internal i32 @p2i(ptr %arg) {
517 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
518 ; CHECK-LABEL: define {{[^@]+}}@p2i
519 ; CHECK-SAME: (ptr noalias nofree readnone [[ARG:%.*]]) #[[ATTR0]] {
520 ; CHECK-NEXT:    [[P2I:%.*]] = ptrtoint ptr [[ARG]] to i32
521 ; CHECK-NEXT:    ret i32 [[P2I]]
523   %p2i = ptrtoint ptr %arg to i32
524   ret i32 %p2i
527 define i32 @i2p(ptr %arg) {
528 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read)
529 ; TUNIT-LABEL: define {{[^@]+}}@i2p
530 ; TUNIT-SAME: (ptr nofree readonly [[ARG:%.*]]) #[[ATTR5:[0-9]+]] {
531 ; TUNIT-NEXT:    [[C:%.*]] = call i32 @p2i(ptr noalias nofree readnone [[ARG]]) #[[ATTR11:[0-9]+]]
532 ; TUNIT-NEXT:    [[I2P:%.*]] = inttoptr i32 [[C]] to ptr
533 ; TUNIT-NEXT:    [[CALL:%.*]] = call i32 @ret(ptr nocapture nofree noundef readonly align 4 [[I2P]]) #[[ATTR12:[0-9]+]]
534 ; TUNIT-NEXT:    ret i32 [[CALL]]
536 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(read)
537 ; CGSCC-LABEL: define {{[^@]+}}@i2p
538 ; CGSCC-SAME: (ptr nofree readonly [[ARG:%.*]]) #[[ATTR6:[0-9]+]] {
539 ; CGSCC-NEXT:    [[C:%.*]] = call i32 @p2i(ptr noalias nofree readnone [[ARG]]) #[[ATTR12]]
540 ; CGSCC-NEXT:    [[I2P:%.*]] = inttoptr i32 [[C]] to ptr
541 ; CGSCC-NEXT:    [[CALL:%.*]] = call i32 @ret(ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[I2P]]) #[[ATTR13:[0-9]+]]
542 ; CGSCC-NEXT:    ret i32 [[CALL]]
544   %c = call i32 @p2i(ptr %arg)
545   %i2p = inttoptr i32 %c to ptr
546   %call = call i32 @ret(ptr %i2p)
547   ret i32 %call
549 define internal i32 @ret(ptr %arg) {
550 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
551 ; TUNIT-LABEL: define {{[^@]+}}@ret
552 ; TUNIT-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR6:[0-9]+]] {
553 ; TUNIT-NEXT:    [[L:%.*]] = load i32, ptr [[ARG]], align 4
554 ; TUNIT-NEXT:    ret i32 [[L]]
556 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
557 ; CGSCC-LABEL: define {{[^@]+}}@ret
558 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR7:[0-9]+]] {
559 ; CGSCC-NEXT:    [[L:%.*]] = load i32, ptr [[ARG]], align 4
560 ; CGSCC-NEXT:    ret i32 [[L]]
562   %l = load i32, ptr %arg
563   ret i32 %l
566 ; Test to propagate noalias where value is assumed to be no-capture in all the
567 ; uses possibly executed before this callsite.
568 ; IR referred from musl/src/strtod.c file
570 %struct._IO_FILE = type { i32, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, i32, ptr, ptr, i32, i32, i32, i16, i8, i8, i32, i32, ptr, i64, ptr, ptr, ptr, [4 x i8], i64, i64, ptr, ptr, ptr, [4 x i8] }
571 %struct.__locale_struct = type { [6 x ptr] }
572 %struct.__locale_map = type opaque
574 ; Function Attrs: nounwind optsize
575 define internal fastcc double @strtox(ptr %s, ptr %p, i32 %prec) unnamed_addr {
576 ; TUNIT-LABEL: define {{[^@]+}}@strtox
577 ; TUNIT-SAME: (ptr [[S:%.*]]) unnamed_addr {
578 ; TUNIT-NEXT:  entry:
579 ; TUNIT-NEXT:    [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8
580 ; TUNIT-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 144, ptr nocapture nofree noundef nonnull align 8 dereferenceable(240) [[F]]) #[[ATTR13:[0-9]+]]
581 ; TUNIT-NEXT:    [[CALL:%.*]] = call i32 @sh_fromstring(ptr noundef nonnull align 8 dereferenceable(240) [[F]], ptr [[S]])
582 ; TUNIT-NEXT:    call void @__shlim(ptr noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0)
583 ; TUNIT-NEXT:    [[CALL1:%.*]] = call double @__floatscan(ptr noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1)
584 ; TUNIT-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 144, ptr nocapture nofree noundef nonnull align 8 dereferenceable(240) [[F]])
585 ; TUNIT-NEXT:    ret double [[CALL1]]
587 ; CGSCC-LABEL: define {{[^@]+}}@strtox
588 ; CGSCC-SAME: (ptr [[S:%.*]]) unnamed_addr {
589 ; CGSCC-NEXT:  entry:
590 ; CGSCC-NEXT:    [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8
591 ; CGSCC-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 144, ptr nocapture nofree noundef nonnull align 8 dereferenceable(240) [[F]]) #[[ATTR14:[0-9]+]]
592 ; CGSCC-NEXT:    [[CALL:%.*]] = call i32 @sh_fromstring(ptr noundef nonnull align 8 dereferenceable(240) [[F]], ptr [[S]])
593 ; CGSCC-NEXT:    call void @__shlim(ptr noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0)
594 ; CGSCC-NEXT:    [[CALL1:%.*]] = call double @__floatscan(ptr noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1)
595 ; CGSCC-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 144, ptr nocapture nofree noundef nonnull align 8 dereferenceable(240) [[F]])
596 ; CGSCC-NEXT:    ret double [[CALL1]]
598 entry:
599   %f = alloca %struct._IO_FILE, align 8
600   call void @llvm.lifetime.start.p0(i64 144, ptr nonnull %f)
601   %call = call i32 @sh_fromstring(ptr nonnull %f, ptr %s)
602   call void @__shlim(ptr nonnull %f, i64 0)
603   %call1 = call double @__floatscan(ptr nonnull %f, i32 %prec, i32 1)
604   call void @llvm.lifetime.end.p0(i64 144, ptr nonnull %f)
606   ret double %call1
609 ; Function Attrs: nounwind optsize
610 define dso_local double @strtod(ptr noalias %s, ptr noalias %p) {
611 ; CHECK-LABEL: define {{[^@]+}}@strtod
612 ; CHECK-SAME: (ptr noalias [[S:%.*]], ptr noalias nocapture nofree readnone [[P:%.*]]) {
613 ; CHECK-NEXT:  entry:
614 ; CHECK-NEXT:    [[CALL:%.*]] = tail call fastcc double @strtox(ptr [[S]])
615 ; CHECK-NEXT:    ret double [[CALL]]
617 entry:
618   %call = tail call fastcc double @strtox(ptr %s, ptr %p, i32 1)
619   ret double %call
622 ; Function Attrs: argmemonly nounwind willreturn
623 declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
625 ; Function Attrs: optsize
626 declare dso_local i32 @sh_fromstring(...) local_unnamed_addr
628 ; Function Attrs: optsize
629 declare dso_local void @__shlim(ptr, i64) local_unnamed_addr
631 ; Function Attrs: optsize
632 declare dso_local double @__floatscan(ptr, i32, i32) local_unnamed_addr
634 ; Function Attrs: argmemonly nounwind willreturn
635 declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
637 ; Test 15
638 ; propagate noalias to some callsite arguments that there is no possibly reachable capture before it
640 @alias_of_p = external global ptr
642 define void @make_alias(ptr %p) {
643 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
644 ; TUNIT-LABEL: define {{[^@]+}}@make_alias
645 ; TUNIT-SAME: (ptr nofree writeonly [[P:%.*]]) #[[ATTR8:[0-9]+]] {
646 ; TUNIT-NEXT:    store ptr [[P]], ptr @alias_of_p, align 8
647 ; TUNIT-NEXT:    ret void
649 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
650 ; CGSCC-LABEL: define {{[^@]+}}@make_alias
651 ; CGSCC-SAME: (ptr nofree writeonly [[P:%.*]]) #[[ATTR9:[0-9]+]] {
652 ; CGSCC-NEXT:    store ptr [[P]], ptr @alias_of_p, align 8
653 ; CGSCC-NEXT:    ret void
655   store ptr %p, ptr @alias_of_p
656   ret void
659 define void @only_store(ptr %p) {
660 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
661 ; TUNIT-LABEL: define {{[^@]+}}@only_store
662 ; TUNIT-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR9:[0-9]+]] {
663 ; TUNIT-NEXT:    store i32 0, ptr [[P]], align 4
664 ; TUNIT-NEXT:    ret void
666 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
667 ; CGSCC-LABEL: define {{[^@]+}}@only_store
668 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR10:[0-9]+]] {
669 ; CGSCC-NEXT:    store i32 0, ptr [[P]], align 4
670 ; CGSCC-NEXT:    ret void
672   store i32 0, ptr %p
673   ret void
676 define void @test15_caller(ptr noalias %p, i32 %c) {
677 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
678 ; TUNIT-LABEL: define {{[^@]+}}@test15_caller
679 ; TUNIT-SAME: (ptr noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR8]] {
680 ; TUNIT-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
681 ; TUNIT-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
682 ; TUNIT:       if.then:
683 ; TUNIT-NEXT:    tail call void @only_store(ptr noalias nocapture nofree noundef writeonly align 4 [[P]]) #[[ATTR14:[0-9]+]]
684 ; TUNIT-NEXT:    br label [[IF_END]]
685 ; TUNIT:       if.end:
686 ; TUNIT-NEXT:    tail call void @make_alias(ptr nofree writeonly [[P]]) #[[ATTR14]]
687 ; TUNIT-NEXT:    ret void
689 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write)
690 ; CGSCC-LABEL: define {{[^@]+}}@test15_caller
691 ; CGSCC-SAME: (ptr noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR11:[0-9]+]] {
692 ; CGSCC-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
693 ; CGSCC-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
694 ; CGSCC:       if.then:
695 ; CGSCC-NEXT:    tail call void @only_store(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR15:[0-9]+]]
696 ; CGSCC-NEXT:    br label [[IF_END]]
697 ; CGSCC:       if.end:
698 ; CGSCC-NEXT:    tail call void @make_alias(ptr nofree writeonly [[P]]) #[[ATTR15]]
699 ; CGSCC-NEXT:    ret void
701   %tobool = icmp eq i32 %c, 0
702   br i1 %tobool, label %if.end, label %if.then
705 if.then:
706   tail call void @only_store(ptr %p)
707   br label %if.end
709 if.end:
710   tail call void @make_alias(ptr %p)
711   ret void
714 ; Test 16
716 ; __attribute__((noinline)) static void test16_sub(int * restrict p, int c1, int c2) {
717 ;   if (c1) {
718 ;     only_store(p);
719 ;     make_alias(p);
720 ;   }
721 ;   if (!c2) {
722 ;     only_store(p);
723 ;   }
724 ; }
725 ; void test16_caller(int * restrict p, int c) {
726 ;   test16_sub(p, c, c);
727 ; }
729 ; FIXME: this should be tail @only_store(ptr noalias %p)
730 ;        when test16_caller is called, c1 always equals to c2. (Note that linkage is internal)
731 ;        Therefore, only one of the two conditions of if statementes will be fulfilled.
733 define internal void @test16_sub(ptr noalias %p, i32 %c1, i32 %c2) {
734 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
735 ; TUNIT-LABEL: define {{[^@]+}}@test16_sub
736 ; TUNIT-SAME: (ptr noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR8]] {
737 ; TUNIT-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C1]], 0
738 ; TUNIT-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
739 ; TUNIT:       if.then:
740 ; TUNIT-NEXT:    tail call void @only_store(ptr nocapture nofree noundef writeonly align 4 [[P]]) #[[ATTR14]]
741 ; TUNIT-NEXT:    tail call void @make_alias(ptr nofree writeonly align 4 [[P]]) #[[ATTR14]]
742 ; TUNIT-NEXT:    br label [[IF_END]]
743 ; TUNIT:       if.end:
744 ; TUNIT-NEXT:    [[TOBOOL1:%.*]] = icmp eq i32 [[C2]], 0
745 ; TUNIT-NEXT:    br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]
746 ; TUNIT:       if.then2:
747 ; TUNIT-NEXT:    tail call void @only_store(ptr nocapture nofree noundef writeonly align 4 [[P]]) #[[ATTR14]]
748 ; TUNIT-NEXT:    br label [[IF_END3]]
749 ; TUNIT:       if.end3:
750 ; TUNIT-NEXT:    ret void
752 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write)
753 ; CGSCC-LABEL: define {{[^@]+}}@test16_sub
754 ; CGSCC-SAME: (ptr noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR11]] {
755 ; CGSCC-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C1]], 0
756 ; CGSCC-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
757 ; CGSCC:       if.then:
758 ; CGSCC-NEXT:    tail call void @only_store(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR15]]
759 ; CGSCC-NEXT:    tail call void @make_alias(ptr nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR15]]
760 ; CGSCC-NEXT:    br label [[IF_END]]
761 ; CGSCC:       if.end:
762 ; CGSCC-NEXT:    [[TOBOOL1:%.*]] = icmp eq i32 [[C2]], 0
763 ; CGSCC-NEXT:    br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]
764 ; CGSCC:       if.then2:
765 ; CGSCC-NEXT:    tail call void @only_store(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR15]]
766 ; CGSCC-NEXT:    br label [[IF_END3]]
767 ; CGSCC:       if.end3:
768 ; CGSCC-NEXT:    ret void
770   %tobool = icmp eq i32 %c1, 0
771   br i1 %tobool, label %if.end, label %if.then
773 if.then:
774   tail call void @only_store(ptr %p)
775   tail call void @make_alias(ptr %p)
776   br label %if.end
777 if.end:
779   %tobool1 = icmp eq i32 %c2, 0
780   br i1 %tobool1, label %if.then2, label %if.end3
782 if.then2:
783   tail call void @only_store(ptr %p)
784   br label %if.end3
785 if.end3:
787   ret void
790 define void @test16_caller(ptr %p, i32 %c) {
791 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
792 ; TUNIT-LABEL: define {{[^@]+}}@test16_caller
793 ; TUNIT-SAME: (ptr nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR8]] {
794 ; TUNIT-NEXT:    tail call void @test16_sub(ptr nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR14]]
795 ; TUNIT-NEXT:    ret void
797 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write)
798 ; CGSCC-LABEL: define {{[^@]+}}@test16_caller
799 ; CGSCC-SAME: (ptr nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR11]] {
800 ; CGSCC-NEXT:    tail call void @test16_sub(ptr nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR15]]
801 ; CGSCC-NEXT:    ret void
803   tail call void @test16_sub(ptr %p, i32 %c, i32 %c)
804   ret void
807 ; test 17
809 ; only_store is not called after make_alias is called.
811 ; void test17_caller(int* p, int c) {
812 ;   if(c) {
813 ;     make_alias(p);
814 ;     if(0 == 0) {
815 ;       goto l3;
816 ;     } else {
817 ;       goto l2;
818 ;     }
819 ;   }
820 ;   l2:
821 ;     only_store(p);
822 ;   l3:
823 ;   return;
824 ; }
826 define void @test17_caller(ptr noalias %p, i32 %c) {
827 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
828 ; TUNIT-LABEL: define {{[^@]+}}@test17_caller
829 ; TUNIT-SAME: (ptr noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR8]] {
830 ; TUNIT-NEXT:  entry:
831 ; TUNIT-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
832 ; TUNIT-NEXT:    br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]]
833 ; TUNIT:       l1:
834 ; TUNIT-NEXT:    tail call void @make_alias(ptr nofree writeonly [[P]]) #[[ATTR14]]
835 ; TUNIT-NEXT:    br label [[L3:%.*]]
836 ; TUNIT:       l2:
837 ; TUNIT-NEXT:    tail call void @only_store(ptr noalias nocapture nofree noundef writeonly align 4 [[P]]) #[[ATTR14]]
838 ; TUNIT-NEXT:    br label [[L3]]
839 ; TUNIT:       l3:
840 ; TUNIT-NEXT:    ret void
842 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write)
843 ; CGSCC-LABEL: define {{[^@]+}}@test17_caller
844 ; CGSCC-SAME: (ptr noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR11]] {
845 ; CGSCC-NEXT:  entry:
846 ; CGSCC-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
847 ; CGSCC-NEXT:    br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]]
848 ; CGSCC:       l1:
849 ; CGSCC-NEXT:    tail call void @make_alias(ptr nofree writeonly [[P]]) #[[ATTR15]]
850 ; CGSCC-NEXT:    br label [[L3:%.*]]
851 ; CGSCC:       l2:
852 ; CGSCC-NEXT:    tail call void @only_store(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR15]]
853 ; CGSCC-NEXT:    br label [[L3]]
854 ; CGSCC:       l3:
855 ; CGSCC-NEXT:    ret void
857 entry:
858   %tobool = icmp eq i32 %c, 0
859   br i1 %tobool, label %l1, label %l2
862   tail call void @make_alias(ptr %p)
863   %tobool2 = icmp eq i32 0, 0
864   br i1 %tobool2, label %l3, label %l2
867   tail call void @only_store(ptr %p)
868   br label %l3
871   ret void
874 ; test 18
875 ; void test18_caller(int* p, int c) {
876 ;   if(c) {
877 ;     make_alias(p);
878 ;     noreturn();
879 ;   }
880 ;   only_store(p);
881 ;   return;
882 ; }
884 define void @noreturn() {
885 ; TUNIT: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
886 ; TUNIT-LABEL: define {{[^@]+}}@noreturn
887 ; TUNIT-SAME: () #[[ATTR10:[0-9]+]] {
888 ; TUNIT-NEXT:    ret void
890 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
891 ; CGSCC-LABEL: define {{[^@]+}}@noreturn
892 ; CGSCC-SAME: () #[[ATTR2]] {
893 ; CGSCC-NEXT:    ret void
895   call void @noreturn()
896   ret void
899 define void @test18_caller(ptr noalias %p, i32 %c) {
900 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
901 ; TUNIT-LABEL: define {{[^@]+}}@test18_caller
902 ; TUNIT-SAME: (ptr noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR8]] {
903 ; TUNIT-NEXT:  entry:
904 ; TUNIT-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
905 ; TUNIT-NEXT:    br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]]
906 ; TUNIT:       l1:
907 ; TUNIT-NEXT:    tail call void @make_alias(ptr nofree writeonly [[P]]) #[[ATTR14]]
908 ; TUNIT-NEXT:    br label [[L2]]
909 ; TUNIT:       l2:
910 ; TUNIT-NEXT:    tail call void @only_store(ptr nocapture nofree noundef writeonly align 4 [[P]]) #[[ATTR14]]
911 ; TUNIT-NEXT:    ret void
913 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write)
914 ; CGSCC-LABEL: define {{[^@]+}}@test18_caller
915 ; CGSCC-SAME: (ptr noalias nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]], i32 [[C:%.*]]) #[[ATTR11]] {
916 ; CGSCC-NEXT:  entry:
917 ; CGSCC-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
918 ; CGSCC-NEXT:    br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]]
919 ; CGSCC:       l1:
920 ; CGSCC-NEXT:    tail call void @make_alias(ptr nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR15]]
921 ; CGSCC-NEXT:    br label [[L2]]
922 ; CGSCC:       l2:
923 ; CGSCC-NEXT:    tail call void @only_store(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR15]]
924 ; CGSCC-NEXT:    ret void
926 entry:
927   %tobool = icmp eq i32 %c, 0
928   br i1 %tobool, label %l1, label %l2
931   tail call void @make_alias(ptr %p)
932   tail call void @noreturn()
933   br label %l2
936   tail call void @only_store(ptr %p)
937   ret void
940 ; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
941 ; TUNIT: attributes #[[ATTR1]] = { nounwind uwtable }
942 ; TUNIT: attributes #[[ATTR2]] = { nounwind }
943 ; TUNIT: attributes #[[ATTR3]] = { nounwind ssp uwtable }
944 ; TUNIT: attributes #[[ATTR4]] = { memory(readwrite, argmem: none) }
945 ; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(read) }
946 ; TUNIT: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
947 ; TUNIT: attributes #[[ATTR7:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
948 ; TUNIT: attributes #[[ATTR8]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
949 ; TUNIT: attributes #[[ATTR9]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
950 ; TUNIT: attributes #[[ATTR10]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
951 ; TUNIT: attributes #[[ATTR11]] = { nofree nosync nounwind willreturn memory(none) }
952 ; TUNIT: attributes #[[ATTR12]] = { nofree nosync nounwind willreturn memory(read) }
953 ; TUNIT: attributes #[[ATTR13]] = { nofree willreturn memory(readwrite) }
954 ; TUNIT: attributes #[[ATTR14]] = { nofree nosync nounwind willreturn memory(write) }
956 ; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
957 ; CGSCC: attributes #[[ATTR1]] = { nounwind uwtable }
958 ; CGSCC: attributes #[[ATTR2]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
959 ; CGSCC: attributes #[[ATTR3]] = { nounwind }
960 ; CGSCC: attributes #[[ATTR4]] = { nounwind ssp uwtable }
961 ; CGSCC: attributes #[[ATTR5]] = { memory(readwrite, argmem: none) }
962 ; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree nosync nounwind willreturn memory(read) }
963 ; CGSCC: attributes #[[ATTR7]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
964 ; CGSCC: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
965 ; CGSCC: attributes #[[ATTR9]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
966 ; CGSCC: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
967 ; CGSCC: attributes #[[ATTR11]] = { mustprogress nofree nosync nounwind willreturn memory(write) }
968 ; CGSCC: attributes #[[ATTR12]] = { nofree nosync willreturn }
969 ; CGSCC: attributes #[[ATTR13]] = { nofree willreturn memory(read) }
970 ; CGSCC: attributes #[[ATTR14]] = { nofree willreturn memory(readwrite) }
971 ; CGSCC: attributes #[[ATTR15]] = { nofree nounwind willreturn memory(write) }