[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / Attributor / noalias.ll
blob2dc3d42533fddf54bcce6efb3c765aa769330e06
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=7 -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=7 -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
8 ; TEST 1 - negative.
10 ; void *G;
11 ; void *foo(){
12 ;   void *V = malloc(4);
13 ;   G = V;
14 ;   return V;
15 ; }
17 @G = external global i8*
20 ; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = external global i8*
21 ; CHECK: @[[ALIAS_OF_P:[a-zA-Z0-9_$"\\.-]+]] = external global i32*
23 define 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]]
29   %1 = tail call noalias i8* @malloc(i64 4)
30   store i8* %1, i8** @G, align 8
31   ret i8* %1
34 declare noalias i8* @malloc(i64)
36 ; TEST 2
37 ; call noalias function in return instruction.
39 define 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]]
44   %1 = tail call noalias i8* @malloc(i64 4)
45   ret i8* %1
48 define void @nocapture(i8* %a){
49 ; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
50 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@nocapture
51 ; NOT_CGSCC_NPM-SAME: (i8* nocapture nofree readnone [[A:%.*]]) #[[ATTR0:[0-9]+]] {
52 ; NOT_CGSCC_NPM-NEXT:    ret void
54 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
55 ; IS__CGSCC____-LABEL: define {{[^@]+}}@nocapture
56 ; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[A:%.*]]) #[[ATTR0:[0-9]+]] {
57 ; IS__CGSCC____-NEXT:    ret void
59   ret void
62 define i8* @return_noalias_looks_like_capture(){
63 ; CHECK-LABEL: define {{[^@]+}}@return_noalias_looks_like_capture() {
64 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
65 ; CHECK-NEXT:    ret i8* [[TMP1]]
67   %1 = tail call noalias i8* @malloc(i64 4)
68   call void @nocapture(i8* %1)
69   ret i8* %1
72 define i16* @return_noalias_casted(){
73 ; CHECK-LABEL: define {{[^@]+}}@return_noalias_casted() {
74 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
75 ; CHECK-NEXT:    [[C:%.*]] = bitcast i8* [[TMP1]] to i16*
76 ; CHECK-NEXT:    ret i16* [[C]]
78   %1 = tail call noalias i8* @malloc(i64 4)
79   %c = bitcast i8* %1 to i16*
80   ret i16* %c
83 declare i8* @alias()
85 ; TEST 3
86 define i8* @call_alias(){
87 ; CHECK-LABEL: define {{[^@]+}}@call_alias() {
88 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call i8* @alias()
89 ; CHECK-NEXT:    ret i8* [[TMP1]]
91   %1 = tail call i8* @alias()
92   ret i8* %1
95 ; TEST 4
96 ; void *baz();
97 ; void *foo(int a);
99 ; void *bar()  {
100 ;   foo(0);
101 ;    return baz();
102 ; }
104 ; void *foo(int a)  {
105 ;   if (a)
106 ;   bar();
107 ;   return malloc(4);
108 ; }
110 define i8* @bar() nounwind uwtable {
111 ; CHECK: Function Attrs: nounwind uwtable
112 ; CHECK-LABEL: define {{[^@]+}}@bar
113 ; CHECK-SAME: () #[[ATTR1:[0-9]+]] {
114 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call i8* (...) @baz() #[[ATTR2:[0-9]+]]
115 ; CHECK-NEXT:    ret i8* [[TMP1]]
117   %1 = tail call i8* (...) @baz()
118   ret i8* %1
121 define i8* @foo1(i32 %0) nounwind uwtable {
122 ; CHECK: Function Attrs: nounwind uwtable
123 ; CHECK-LABEL: define {{[^@]+}}@foo1
124 ; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] {
125 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0
126 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
127 ; CHECK:       3:
128 ; CHECK-NEXT:    [[TMP4:%.*]] = tail call i8* (...) @baz() #[[ATTR2]]
129 ; CHECK-NEXT:    br label [[TMP5]]
130 ; CHECK:       5:
131 ; CHECK-NEXT:    [[TMP6:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
132 ; CHECK-NEXT:    ret i8* [[TMP6]]
134   %2 = icmp eq i32 %0, 0
135   br i1 %2, label %5, label %3
137 3:                                                ; preds = %1
138   %4 = tail call i8* (...) @baz()
139   br label %5
141 5:                                                ; preds = %1, %3
142   %6 = tail call noalias i8* @malloc(i64 4)
143   ret i8* %6
146 declare i8* @baz(...) nounwind uwtable
148 ; TEST 5
150 ; Returning global pointer. Should not be noalias.
151 define i8** @getter() {
152 ; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
153 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@getter
154 ; NOT_CGSCC_NPM-SAME: () #[[ATTR0]] {
155 ; NOT_CGSCC_NPM-NEXT:    ret i8** @G
157 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
158 ; IS__CGSCC____-LABEL: define {{[^@]+}}@getter
159 ; IS__CGSCC____-SAME: () #[[ATTR0]] {
160 ; IS__CGSCC____-NEXT:    ret i8** @G
162   ret i8** @G
165 ; Returning global pointer. Should not be noalias.
166 define i8** @calle1(){
167 ; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
168 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@calle1
169 ; NOT_CGSCC_NPM-SAME: () #[[ATTR0]] {
170 ; NOT_CGSCC_NPM-NEXT:    ret i8** @G
172 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
173 ; IS__CGSCC____-LABEL: define {{[^@]+}}@calle1
174 ; IS__CGSCC____-SAME: () #[[ATTR0]] {
175 ; IS__CGSCC____-NEXT:    ret i8** @G
177   %1 = call i8** @getter()
178   ret i8** %1
181 ; TEST 6
182 declare noalias i8* @strdup(i8* nocapture) nounwind
184 define i8* @test6() nounwind uwtable ssp {
185 ; CHECK: Function Attrs: nounwind ssp uwtable
186 ; CHECK-LABEL: define {{[^@]+}}@test6
187 ; CHECK-SAME: () #[[ATTR3:[0-9]+]] {
188 ; CHECK-NEXT:    [[X:%.*]] = alloca [2 x i8], align 1
189 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 0
190 ; CHECK-NEXT:    store i8 97, i8* [[ARRAYIDX]], align 1
191 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 1
192 ; CHECK-NEXT:    store i8 0, i8* [[ARRAYIDX1]], align 1
193 ; CHECK-NEXT:    [[CALL:%.*]] = call noalias i8* @strdup(i8* nocapture noundef nonnull dereferenceable(2) [[ARRAYIDX]]) #[[ATTR2]]
194 ; CHECK-NEXT:    ret i8* [[CALL]]
196   %x = alloca [2 x i8], align 1
197   %arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %x, i64 0, i64 0
198   store i8 97, i8* %arrayidx, align 1
199   %arrayidx1 = getelementptr inbounds [2 x i8], [2 x i8]* %x, i64 0, i64 1
200   store i8 0, i8* %arrayidx1, align 1
201   %call = call noalias i8* @strdup(i8* %arrayidx) nounwind
202   ret i8* %call
205 ; TEST 7
207 define i8* @test7() nounwind {
208 ; CHECK: Function Attrs: nounwind
209 ; CHECK-LABEL: define {{[^@]+}}@test7
210 ; CHECK-SAME: () #[[ATTR2]] {
211 ; CHECK-NEXT:  entry:
212 ; CHECK-NEXT:    [[A:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR2]]
213 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8* [[A]], null
214 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[RETURN:%.*]], label [[IF_END:%.*]]
215 ; CHECK:       if.end:
216 ; CHECK-NEXT:    store i8 7, i8* [[A]], align 1
217 ; CHECK-NEXT:    br label [[RETURN]]
218 ; CHECK:       return:
219 ; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i8* [ [[A]], [[IF_END]] ], [ null, [[ENTRY:%.*]] ]
220 ; CHECK-NEXT:    ret i8* [[RETVAL_0]]
222 entry:
223   %A = call noalias i8* @malloc(i64 4) nounwind
224   %tobool = icmp eq i8* %A, null
225   br i1 %tobool, label %return, label %if.end
227 if.end:
228   store i8 7, i8* %A
229   br label %return
231 return:
232   %retval.0 = phi i8* [ %A, %if.end ], [ null, %entry ]
233   ret i8* %retval.0
236 ; TEST 8
238 define i8* @test8(i32* %0) nounwind uwtable {
239 ; CHECK: Function Attrs: nounwind uwtable
240 ; CHECK-LABEL: define {{[^@]+}}@test8
241 ; CHECK-SAME: (i32* [[TMP0:%.*]]) #[[ATTR1]] {
242 ; CHECK-NEXT:    [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
243 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32* [[TMP0]], null
244 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
245 ; CHECK:       4:
246 ; CHECK-NEXT:    store i8 10, i8* [[TMP2]], align 1
247 ; CHECK-NEXT:    br label [[TMP5]]
248 ; CHECK:       5:
249 ; CHECK-NEXT:    ret i8* [[TMP2]]
251   %2 = tail call noalias i8* @malloc(i64 4)
252   %3 = icmp ne i32* %0, null
253   br i1 %3, label %4, label %5
255 4:                                                ; preds = %1
256   store i8 10, i8* %2
257   br label %5
259 5:                                                ; preds = %1, %4
260   ret i8* %2
263 ; TEST 9
264 ; Simple Argument Test
265 declare void @use_i8(i8* nocapture)
266 define internal void @test9a(i8* %a, i8* %b) {
267 ; CHECK-LABEL: define {{[^@]+}}@test9a() {
268 ; CHECK-NEXT:    call void @use_i8(i8* noalias nocapture noundef align 536870912 null)
269 ; CHECK-NEXT:    ret void
271   call void @use_i8(i8* null)
272   ret void
274 define internal void @test9b(i8* %a, i8* %b) {
275 ; FIXME: %b should be noalias
276 ; CHECK-LABEL: define {{[^@]+}}@test9b
277 ; CHECK-SAME: (i8* noalias nocapture [[A:%.*]], i8* nocapture [[B:%.*]]) {
278 ; CHECK-NEXT:    call void @use_i8(i8* noalias nocapture [[A]])
279 ; CHECK-NEXT:    call void @use_i8(i8* nocapture [[B]])
280 ; CHECK-NEXT:    ret void
282   call void @use_i8(i8* %a)
283   call void @use_i8(i8* %b)
284   ret void
286 define internal void @test9c(i8* %a, i8* %b, i8* %c) {
287 ; CHECK-LABEL: define {{[^@]+}}@test9c
288 ; CHECK-SAME: (i8* noalias nocapture [[A:%.*]], i8* nocapture [[B:%.*]], i8* nocapture [[C:%.*]]) {
289 ; CHECK-NEXT:    call void @use_i8(i8* noalias nocapture [[A]])
290 ; CHECK-NEXT:    call void @use_i8(i8* nocapture [[B]])
291 ; CHECK-NEXT:    call void @use_i8(i8* nocapture [[C]])
292 ; CHECK-NEXT:    ret void
294   call void @use_i8(i8* %a)
295   call void @use_i8(i8* %b)
296   call void @use_i8(i8* %c)
297   ret void
299 define void @test9_helper(i8* %a, i8* %b) {
300 ; CHECK-LABEL: define {{[^@]+}}@test9_helper
301 ; CHECK-SAME: (i8* nocapture [[A:%.*]], i8* nocapture [[B:%.*]]) {
302 ; CHECK-NEXT:    tail call void @test9a()
303 ; CHECK-NEXT:    tail call void @test9a()
304 ; CHECK-NEXT:    tail call void @test9b(i8* noalias nocapture [[A]], i8* nocapture [[B]])
305 ; CHECK-NEXT:    tail call void @test9b(i8* noalias nocapture [[B]], i8* noalias nocapture [[A]])
306 ; CHECK-NEXT:    tail call void @test9c(i8* noalias nocapture [[A]], i8* nocapture [[B]], i8* nocapture [[B]])
307 ; CHECK-NEXT:    tail call void @test9c(i8* noalias nocapture [[B]], i8* noalias nocapture [[A]], i8* noalias nocapture [[A]])
308 ; CHECK-NEXT:    ret void
310   tail call void @test9a(i8* noalias %a, i8* %b)
311   tail call void @test9a(i8* noalias %b, i8* noalias %a)
312   tail call void @test9b(i8* noalias %a, i8* %b)
313   tail call void @test9b(i8* noalias %b, i8* noalias %a)
314   tail call void @test9c(i8* noalias %a, i8* %b, i8* %b)
315   tail call void @test9c(i8* noalias %b, i8* noalias %a, i8* noalias %a)
316   ret void
320 ; TEST 10
321 ; Simple CallSite Test
323 declare void @test10_helper_1(i8* %a)
324 define void @test10_helper_2(i8* noalias %a) {
325 ; CHECK-LABEL: define {{[^@]+}}@test10_helper_2
326 ; CHECK-SAME: (i8* noalias [[A:%.*]]) {
327 ; CHECK-NEXT:    tail call void @test10_helper_1(i8* [[A]])
328 ; CHECK-NEXT:    ret void
330   tail call void @test10_helper_1(i8* %a)
331   ret void
333 define void @test10(i8* noalias %a) {
334 ; CHECK-LABEL: define {{[^@]+}}@test10
335 ; CHECK-SAME: (i8* noalias [[A:%.*]]) {
336 ; CHECK-NEXT:    tail call void @test10_helper_1(i8* [[A]])
337 ; CHECK-NEXT:    tail call void @test10_helper_2(i8* noalias [[A]])
338 ; CHECK-NEXT:    ret void
340 ; FIXME: missing noalias
341   tail call void @test10_helper_1(i8* %a)
343   tail call void @test10_helper_2(i8* %a)
344   ret void
347 ; TEST 11
348 ; CallSite Test
350 declare void @test11_helper(i8* %a, i8 *%b)
351 define void @test11(i8* noalias %a) {
352 ; CHECK-LABEL: define {{[^@]+}}@test11
353 ; CHECK-SAME: (i8* noalias [[A:%.*]]) {
354 ; CHECK-NEXT:    tail call void @test11_helper(i8* [[A]], i8* [[A]])
355 ; CHECK-NEXT:    ret void
357   tail call void @test11_helper(i8* %a, i8* %a)
358   ret void
362 ; TEST 12
363 ; CallSite Argument
364 declare void @use_nocapture(i8* nocapture)
365 declare void @use(i8*)
366 define void @test12_1() {
367 ; CHECK-LABEL: define {{[^@]+}}@test12_1() {
368 ; CHECK-NEXT:    [[A:%.*]] = alloca i8, align 4
369 ; CHECK-NEXT:    [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
370 ; CHECK-NEXT:    tail call void @use_nocapture(i8* noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A]])
371 ; CHECK-NEXT:    tail call void @use_nocapture(i8* noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A]])
372 ; CHECK-NEXT:    tail call void @use_nocapture(i8* noalias nocapture [[B]])
373 ; CHECK-NEXT:    tail call void @use_nocapture(i8* noalias nocapture [[B]])
374 ; CHECK-NEXT:    ret void
376   %A = alloca i8, align 4
377   %B = tail call noalias i8* @malloc(i64 4)
378   tail call void @use_nocapture(i8* %A)
379   tail call void @use_nocapture(i8* %A)
380   tail call void @use_nocapture(i8* %B)
381   tail call void @use_nocapture(i8* %B)
382   ret void
385 define void @test12_2(){
386 ; CHECK-LABEL: define {{[^@]+}}@test12_2() {
387 ; CHECK-NEXT:    [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
388 ; CHECK-NEXT:    tail call void @use_nocapture(i8* noalias nocapture [[A]])
389 ; CHECK-NEXT:    tail call void @use_nocapture(i8* noalias nocapture [[A]])
390 ; CHECK-NEXT:    tail call void @use(i8* [[A]])
391 ; CHECK-NEXT:    tail call void @use_nocapture(i8* nocapture [[A]])
392 ; CHECK-NEXT:    ret void
394 ; FIXME: This should be @use_nocapture(i8* noalias [[A]])
395 ; FIXME: This should be @use_nocapture(i8* noalias nocapture [[A]])
396   %A = tail call noalias i8* @malloc(i64 4)
397   tail call void @use_nocapture(i8* %A)
398   tail call void @use_nocapture(i8* %A)
399   tail call void @use(i8* %A)
400   tail call void @use_nocapture(i8* %A)
401   ret void
404 declare void @two_args(i8* nocapture , i8* nocapture)
405 define void @test12_3(){
406 ; CHECK-LABEL: define {{[^@]+}}@test12_3() {
407 ; CHECK-NEXT:    [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
408 ; CHECK-NEXT:    tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A]])
409 ; CHECK-NEXT:    ret void
411   %A = tail call noalias i8* @malloc(i64 4)
412   tail call void @two_args(i8* %A, i8* %A)
413   ret void
416 define void @test12_4(){
417 ; IS________OPM-LABEL: define {{[^@]+}}@test12_4() {
418 ; IS________OPM-NEXT:    [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
419 ; IS________OPM-NEXT:    [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
420 ; IS________OPM-NEXT:    [[A_0:%.*]] = getelementptr i8, i8* [[A]], i64 0
421 ; IS________OPM-NEXT:    [[A_1:%.*]] = getelementptr i8, i8* [[A]], i64 1
422 ; IS________OPM-NEXT:    [[B_0:%.*]] = getelementptr i8, i8* [[B]], i64 0
423 ; IS________OPM-NEXT:    tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[B]])
424 ; IS________OPM-NEXT:    tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A_0]])
425 ; IS________OPM-NEXT:    tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A_1]])
426 ; IS________OPM-NEXT:    tail call void @two_args(i8* nocapture [[A_0]], i8* nocapture [[B_0]])
427 ; IS________OPM-NEXT:    ret void
429 ; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test12_4() {
430 ; NOT_TUNIT_OPM-NEXT:    [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
431 ; NOT_TUNIT_OPM-NEXT:    [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
432 ; NOT_TUNIT_OPM-NEXT:    [[A_1:%.*]] = getelementptr i8, i8* [[A]], i64 1
433 ; NOT_TUNIT_OPM-NEXT:    tail call void @two_args(i8* noalias nocapture [[A]], i8* noalias nocapture [[B]])
434 ; NOT_TUNIT_OPM-NEXT:    tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A]])
435 ; NOT_TUNIT_OPM-NEXT:    tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A_1]])
436 ; NOT_TUNIT_OPM-NEXT:    tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[B]])
437 ; NOT_TUNIT_OPM-NEXT:    ret void
439   %A = tail call noalias i8* @malloc(i64 4)
440   %B = tail call noalias i8* @malloc(i64 4)
441   %A_0 = getelementptr i8, i8* %A, i64 0
442   %A_1 = getelementptr i8, i8* %A, i64 1
443   %B_0 = getelementptr i8, i8* %B, i64 0
445   tail call void @two_args(i8* %A, i8* %B)
447   tail call void @two_args(i8* %A, i8* %A_0)
449   tail call void @two_args(i8* %A, i8* %A_1)
451 ; FIXME: This should be @two_args(i8* noalias nocapture %A_0, i8* noalias nocapture %B_0)
452   tail call void @two_args(i8* %A_0, i8* %B_0)
453   ret void
456 ; TEST 13
457 define void @use_i8_internal(i8* %a) {
458 ; CHECK-LABEL: define {{[^@]+}}@use_i8_internal
459 ; CHECK-SAME: (i8* nocapture [[A:%.*]]) {
460 ; CHECK-NEXT:    call void @use_i8(i8* nocapture [[A]])
461 ; CHECK-NEXT:    ret void
463   call void @use_i8(i8* %a)
464   ret void
467 define void @test13_use_noalias(){
468 ; IS________OPM-LABEL: define {{[^@]+}}@test13_use_noalias() {
469 ; IS________OPM-NEXT:    [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
470 ; IS________OPM-NEXT:    [[C1:%.*]] = bitcast i8* [[M1]] to i16*
471 ; IS________OPM-NEXT:    [[C2:%.*]] = bitcast i16* [[C1]] to i8*
472 ; IS________OPM-NEXT:    call void @use_i8_internal(i8* noalias nocapture [[C2]])
473 ; IS________OPM-NEXT:    ret void
475 ; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test13_use_noalias() {
476 ; NOT_TUNIT_OPM-NEXT:    [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
477 ; NOT_TUNIT_OPM-NEXT:    call void @use_i8_internal(i8* noalias nocapture [[M1]])
478 ; NOT_TUNIT_OPM-NEXT:    ret void
480 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13_use_noalias()
481 ; IS__CGSCC_OPM-NEXT:    [[M1:%.*]] = tail call noalias i8* @malloc(i64 4)
482 ; IS__CGSCC_OPM-NEXT:    [[C1:%.*]] = bitcast i8* [[M1]] to i16*
483 ; IS__CGSCC_OPM-NEXT:    [[C2:%.*]] = bitcast i16* [[C1]] to i8*
484 ; IS__CGSCC_OPM-NEXT:    call void @use_i8_internal(i8* noalias [[C2]])
485 ; IS__CGSCC_OPM-NEXT:    ret void
486   %m1 = tail call noalias i8* @malloc(i64 4)
487   %c1 = bitcast i8* %m1 to i16*
488   %c2 = bitcast i16* %c1 to i8*
489   call void @use_i8_internal(i8* %c2)
490   ret void
493 define void @test13_use_alias(){
494 ; IS________OPM-LABEL: define {{[^@]+}}@test13_use_alias() {
495 ; IS________OPM-NEXT:    [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
496 ; IS________OPM-NEXT:    [[C1:%.*]] = bitcast i8* [[M1]] to i16*
497 ; IS________OPM-NEXT:    [[C2A:%.*]] = bitcast i16* [[C1]] to i8*
498 ; IS________OPM-NEXT:    [[C2B:%.*]] = bitcast i16* [[C1]] to i8*
499 ; IS________OPM-NEXT:    call void @use_i8_internal(i8* nocapture [[C2A]])
500 ; IS________OPM-NEXT:    call void @use_i8_internal(i8* nocapture [[C2B]])
501 ; IS________OPM-NEXT:    ret void
503 ; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test13_use_alias() {
504 ; NOT_TUNIT_OPM-NEXT:    [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
505 ; NOT_TUNIT_OPM-NEXT:    call void @use_i8_internal(i8* nocapture [[M1]])
506 ; NOT_TUNIT_OPM-NEXT:    call void @use_i8_internal(i8* nocapture [[M1]])
507 ; NOT_TUNIT_OPM-NEXT:    ret void
509   %m1 = tail call noalias i8* @malloc(i64 4)
510   %c1 = bitcast i8* %m1 to i16*
511   %c2a = bitcast i16* %c1 to i8*
512   %c2b = bitcast i16* %c1 to i8*
513   call void @use_i8_internal(i8* %c2a)
514   call void @use_i8_internal(i8* %c2b)
515   ret void
518 ; TEST 14 i2p casts
519 define internal i32 @p2i(i32* %arg) {
520 ; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
521 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@p2i
522 ; NOT_CGSCC_NPM-SAME: (i32* noalias nofree readnone [[ARG:%.*]]) #[[ATTR0]] {
523 ; NOT_CGSCC_NPM-NEXT:    [[P2I:%.*]] = ptrtoint i32* [[ARG]] to i32
524 ; NOT_CGSCC_NPM-NEXT:    ret i32 [[P2I]]
526 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
527 ; IS__CGSCC____-LABEL: define {{[^@]+}}@p2i
528 ; IS__CGSCC____-SAME: (i32* noalias nofree readnone [[ARG:%.*]]) #[[ATTR0]] {
529 ; IS__CGSCC____-NEXT:    [[P2I:%.*]] = ptrtoint i32* [[ARG]] to i32
530 ; IS__CGSCC____-NEXT:    ret i32 [[P2I]]
532   %p2i = ptrtoint i32* %arg to i32
533   ret i32 %p2i
536 define i32 @i2p(i32* %arg) {
537 ; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readonly willreturn
538 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@i2p
539 ; NOT_CGSCC_NPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR4:[0-9]+]] {
540 ; NOT_CGSCC_NPM-NEXT:    [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]]) #[[ATTR0]]
541 ; NOT_CGSCC_NPM-NEXT:    [[I2P:%.*]] = inttoptr i32 [[C]] to i8*
542 ; NOT_CGSCC_NPM-NEXT:    [[BC:%.*]] = bitcast i8* [[I2P]] to i32*
543 ; NOT_CGSCC_NPM-NEXT:    [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree readonly align 4 [[BC]]) #[[ATTR4]]
544 ; NOT_CGSCC_NPM-NEXT:    ret i32 [[CALL]]
546 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
547 ; IS__CGSCC____-LABEL: define {{[^@]+}}@i2p
548 ; IS__CGSCC____-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR4:[0-9]+]] {
549 ; IS__CGSCC____-NEXT:    [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]]) #[[ATTR10:[0-9]+]]
550 ; IS__CGSCC____-NEXT:    [[I2P:%.*]] = inttoptr i32 [[C]] to i8*
551 ; IS__CGSCC____-NEXT:    [[BC:%.*]] = bitcast i8* [[I2P]] to i32*
552 ; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[BC]]) #[[ATTR11:[0-9]+]]
553 ; IS__CGSCC____-NEXT:    ret i32 [[CALL]]
555   %c = call i32 @p2i(i32* %arg)
556   %i2p = inttoptr i32 %c to i8*
557   %bc = bitcast i8* %i2p to i32*
558   %call = call i32 @ret(i32* %bc)
559   ret i32 %call
561 define internal i32 @ret(i32* %arg) {
562 ; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
563 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@ret
564 ; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR5:[0-9]+]] {
565 ; NOT_CGSCC_NPM-NEXT:    [[L:%.*]] = load i32, i32* [[ARG]], align 4
566 ; NOT_CGSCC_NPM-NEXT:    ret i32 [[L]]
568 ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
569 ; IS__CGSCC____-LABEL: define {{[^@]+}}@ret
570 ; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR5:[0-9]+]] {
571 ; IS__CGSCC____-NEXT:    [[L:%.*]] = load i32, i32* [[ARG]], align 4
572 ; IS__CGSCC____-NEXT:    ret i32 [[L]]
574   %l = load i32, i32* %arg
575   ret i32 %l
578 ; Test to propagate noalias where value is assumed to be no-capture in all the
579 ; uses possibly executed before this callsite.
580 ; IR referred from musl/src/strtod.c file
582 %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] }
583 %struct.__locale_struct = type { [6 x %struct.__locale_map*] }
584 %struct.__locale_map = type opaque
586 ; Function Attrs: nounwind optsize
587 define internal fastcc double @strtox(i8* %s, i8** %p, i32 %prec) unnamed_addr {
588 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@strtox
589 ; NOT_CGSCC_NPM-SAME: (i8* [[S:%.*]]) unnamed_addr {
590 ; NOT_CGSCC_NPM-NEXT:  entry:
591 ; NOT_CGSCC_NPM-NEXT:    [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8
592 ; NOT_CGSCC_NPM-NEXT:    [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8*
593 ; NOT_CGSCC_NPM-NEXT:    call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR10:[0-9]+]]
594 ; 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]])
595 ; NOT_CGSCC_NPM-NEXT:    call void @__shlim(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0)
596 ; NOT_CGSCC_NPM-NEXT:    [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1)
597 ; NOT_CGSCC_NPM-NEXT:    call void @llvm.lifetime.end.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]])
598 ; NOT_CGSCC_NPM-NEXT:    ret double [[CALL1]]
600 ; IS__CGSCC____-LABEL: define {{[^@]+}}@strtox
601 ; IS__CGSCC____-SAME: (i8* [[S:%.*]]) unnamed_addr {
602 ; IS__CGSCC____-NEXT:  entry:
603 ; IS__CGSCC____-NEXT:    [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8
604 ; IS__CGSCC____-NEXT:    [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8*
605 ; IS__CGSCC____-NEXT:    call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR12:[0-9]+]]
606 ; 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]])
607 ; IS__CGSCC____-NEXT:    call void @__shlim(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0)
608 ; IS__CGSCC____-NEXT:    [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1)
609 ; IS__CGSCC____-NEXT:    call void @llvm.lifetime.end.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]])
610 ; IS__CGSCC____-NEXT:    ret double [[CALL1]]
612 entry:
613   %f = alloca %struct._IO_FILE, align 8
614   %0 = bitcast %struct._IO_FILE* %f to i8*
615   call void @llvm.lifetime.start.p0i8(i64 144, i8* nonnull %0)
616   %call = call i32 bitcast (i32 (...)* @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull %f, i8* %s)
617   call void @__shlim(%struct._IO_FILE* nonnull %f, i64 0)
618   %call1 = call double @__floatscan(%struct._IO_FILE* nonnull %f, i32 %prec, i32 1)
619   call void @llvm.lifetime.end.p0i8(i64 144, i8* nonnull %0)
621   ret double %call1
624 ; Function Attrs: nounwind optsize
625 define dso_local double @strtod(i8* noalias %s, i8** noalias %p) {
626 ; CHECK-LABEL: define {{[^@]+}}@strtod
627 ; CHECK-SAME: (i8* noalias [[S:%.*]], i8** noalias nocapture nofree readnone [[P:%.*]]) {
628 ; CHECK-NEXT:  entry:
629 ; CHECK-NEXT:    [[CALL:%.*]] = tail call fastcc double @strtox(i8* [[S]])
630 ; CHECK-NEXT:    ret double [[CALL]]
632 entry:
633   %call = tail call fastcc double @strtox(i8* %s, i8** %p, i32 1)
634   ret double %call
637 ; Function Attrs: argmemonly nounwind willreturn
638 declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
640 ; Function Attrs: optsize
641 declare dso_local i32 @sh_fromstring(...) local_unnamed_addr
643 ; Function Attrs: optsize
644 declare dso_local void @__shlim(%struct._IO_FILE*, i64) local_unnamed_addr
646 ; Function Attrs: optsize
647 declare dso_local double @__floatscan(%struct._IO_FILE*, i32, i32) local_unnamed_addr
649 ; Function Attrs: argmemonly nounwind willreturn
650 declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
652 ; Test 15
653 ; propagate noalias to some callsite arguments that there is no possibly reachable capture before it
655 @alias_of_p = external global i32*
657 define void @make_alias(i32* %p) {
658 ; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly
659 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@make_alias
660 ; NOT_CGSCC_NPM-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR7:[0-9]+]] {
661 ; NOT_CGSCC_NPM-NEXT:    store i32* [[P]], i32** @alias_of_p, align 8
662 ; NOT_CGSCC_NPM-NEXT:    ret void
664 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
665 ; IS__CGSCC____-LABEL: define {{[^@]+}}@make_alias
666 ; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR7:[0-9]+]] {
667 ; IS__CGSCC____-NEXT:    store i32* [[P]], i32** @alias_of_p, align 8
668 ; IS__CGSCC____-NEXT:    ret void
670   store i32* %p, i32** @alias_of_p
671   ret void
674 define void @only_store(i32* %p) {
675 ; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
676 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@only_store
677 ; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR8:[0-9]+]] {
678 ; NOT_CGSCC_NPM-NEXT:    store i32 0, i32* [[P]], align 4
679 ; NOT_CGSCC_NPM-NEXT:    ret void
681 ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
682 ; IS__CGSCC____-LABEL: define {{[^@]+}}@only_store
683 ; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR8:[0-9]+]] {
684 ; IS__CGSCC____-NEXT:    store i32 0, i32* [[P]], align 4
685 ; IS__CGSCC____-NEXT:    ret void
687   store i32 0, i32* %p
688   ret void
691 define void @test15_caller(i32* noalias %p, i32 %c) {
692 ; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly
693 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test15_caller
694 ; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] {
695 ; NOT_CGSCC_NPM-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
696 ; NOT_CGSCC_NPM-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
697 ; NOT_CGSCC_NPM:       if.then:
698 ; NOT_CGSCC_NPM-NEXT:    tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) #[[ATTR7]]
699 ; NOT_CGSCC_NPM-NEXT:    br label [[IF_END]]
700 ; NOT_CGSCC_NPM:       if.end:
701 ; NOT_CGSCC_NPM-NEXT:    tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR7]]
702 ; NOT_CGSCC_NPM-NEXT:    ret void
704 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
705 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test15_caller
706 ; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] {
707 ; IS__CGSCC____-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
708 ; IS__CGSCC____-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
709 ; IS__CGSCC____:       if.then:
710 ; IS__CGSCC____-NEXT:    tail call void @only_store(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13:[0-9]+]]
711 ; IS__CGSCC____-NEXT:    br label [[IF_END]]
712 ; IS__CGSCC____:       if.end:
713 ; IS__CGSCC____-NEXT:    tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR13]]
714 ; IS__CGSCC____-NEXT:    ret void
716   %tobool = icmp eq i32 %c, 0
717   br i1 %tobool, label %if.end, label %if.then
720 if.then:
721   tail call void @only_store(i32* %p)
722   br label %if.end
724 if.end:
725   tail call void @make_alias(i32* %p)
726   ret void
729 ; Test 16
731 ; __attribute__((noinline)) static void test16_sub(int * restrict p, int c1, int c2) {
732 ;   if (c1) {
733 ;     only_store(p);
734 ;     make_alias(p);
735 ;   }
736 ;   if (!c2) {
737 ;     only_store(p);
738 ;   }
739 ; }
740 ; void test16_caller(int * restrict p, int c) {
741 ;   test16_sub(p, c, c);
742 ; }
744 ; FIXME: this should be tail @only_store(i32* noalias %p)
745 ;        when test16_caller is called, c1 always equals to c2. (Note that linkage is internal)
746 ;        Therefore, only one of the two conditions of if statementes will be fulfilled.
748 define internal void @test16_sub(i32* noalias %p, i32 %c1, i32 %c2) {
749 ; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly
750 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test16_sub
751 ; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR7]] {
752 ; NOT_CGSCC_NPM-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C1]], 0
753 ; NOT_CGSCC_NPM-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
754 ; NOT_CGSCC_NPM:       if.then:
755 ; NOT_CGSCC_NPM-NEXT:    tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) #[[ATTR7]]
756 ; NOT_CGSCC_NPM-NEXT:    tail call void @make_alias(i32* nofree writeonly align 4 [[P]]) #[[ATTR7]]
757 ; NOT_CGSCC_NPM-NEXT:    br label [[IF_END]]
758 ; NOT_CGSCC_NPM:       if.end:
759 ; NOT_CGSCC_NPM-NEXT:    [[TOBOOL1:%.*]] = icmp eq i32 [[C2]], 0
760 ; NOT_CGSCC_NPM-NEXT:    br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]
761 ; NOT_CGSCC_NPM:       if.then2:
762 ; NOT_CGSCC_NPM-NEXT:    tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR7]]
763 ; NOT_CGSCC_NPM-NEXT:    br label [[IF_END3]]
764 ; NOT_CGSCC_NPM:       if.end3:
765 ; NOT_CGSCC_NPM-NEXT:    ret void
767 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
768 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test16_sub
769 ; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR7]] {
770 ; IS__CGSCC____-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C1]], 0
771 ; IS__CGSCC____-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
772 ; IS__CGSCC____:       if.then:
773 ; IS__CGSCC____-NEXT:    tail call void @only_store(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]]
774 ; IS__CGSCC____-NEXT:    tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]]
775 ; IS__CGSCC____-NEXT:    br label [[IF_END]]
776 ; IS__CGSCC____:       if.end:
777 ; IS__CGSCC____-NEXT:    [[TOBOOL1:%.*]] = icmp eq i32 [[C2]], 0
778 ; IS__CGSCC____-NEXT:    br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]
779 ; IS__CGSCC____:       if.then2:
780 ; IS__CGSCC____-NEXT:    tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]]
781 ; IS__CGSCC____-NEXT:    br label [[IF_END3]]
782 ; IS__CGSCC____:       if.end3:
783 ; IS__CGSCC____-NEXT:    ret void
785   %tobool = icmp eq i32 %c1, 0
786   br i1 %tobool, label %if.end, label %if.then
788 if.then:
789   tail call void @only_store(i32* %p)
790   tail call void @make_alias(i32* %p)
791   br label %if.end
792 if.end:
794   %tobool1 = icmp eq i32 %c2, 0
795   br i1 %tobool1, label %if.then2, label %if.end3
797 if.then2:
798   tail call void @only_store(i32* %p)
799   br label %if.end3
800 if.end3:
802   ret void
805 define void @test16_caller(i32* %p, i32 %c) {
806 ; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly
807 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test16_caller
808 ; NOT_CGSCC_NPM-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] {
809 ; NOT_CGSCC_NPM-NEXT:    tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR7]]
810 ; NOT_CGSCC_NPM-NEXT:    ret void
812 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
813 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test16_caller
814 ; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] {
815 ; IS__CGSCC____-NEXT:    tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR13]]
816 ; IS__CGSCC____-NEXT:    ret void
818   tail call void @test16_sub(i32* %p, i32 %c, i32 %c)
819   ret void
822 ; test 17
824 ; only_store is not called after make_alias is called.
826 ; void test17_caller(int* p, int c) {
827 ;   if(c) {
828 ;     make_alias(p);
829 ;     if(0 == 0) {
830 ;       goto l3;
831 ;     } else {
832 ;       goto l2;
833 ;     }
834 ;   }
835 ;   l2:
836 ;     only_store(p);
837 ;   l3:
838 ;   return;
839 ; }
841 define void @test17_caller(i32* noalias %p, i32 %c) {
842 ; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly
843 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test17_caller
844 ; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] {
845 ; NOT_CGSCC_NPM-NEXT:  entry:
846 ; NOT_CGSCC_NPM-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
847 ; NOT_CGSCC_NPM-NEXT:    br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]]
848 ; NOT_CGSCC_NPM:       l1:
849 ; NOT_CGSCC_NPM-NEXT:    tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR7]]
850 ; NOT_CGSCC_NPM-NEXT:    br label [[L3:%.*]]
851 ; NOT_CGSCC_NPM:       l2:
852 ; NOT_CGSCC_NPM-NEXT:    tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR7]]
853 ; NOT_CGSCC_NPM-NEXT:    br label [[L3]]
854 ; NOT_CGSCC_NPM:       l3:
855 ; NOT_CGSCC_NPM-NEXT:    ret void
857 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
858 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test17_caller
859 ; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] {
860 ; IS__CGSCC____-NEXT:  entry:
861 ; IS__CGSCC____-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
862 ; IS__CGSCC____-NEXT:    br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]]
863 ; IS__CGSCC____:       l1:
864 ; IS__CGSCC____-NEXT:    tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR13]]
865 ; IS__CGSCC____-NEXT:    br label [[L3:%.*]]
866 ; IS__CGSCC____:       l2:
867 ; IS__CGSCC____-NEXT:    tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]]
868 ; IS__CGSCC____-NEXT:    br label [[L3]]
869 ; IS__CGSCC____:       l3:
870 ; IS__CGSCC____-NEXT:    ret void
872 entry:
873   %tobool = icmp eq i32 %c, 0
874   br i1 %tobool, label %l1, label %l2
877   tail call void @make_alias(i32* %p)
878   %tobool2 = icmp eq i32 0, 0
879   br i1 %tobool2, label %l3, label %l2
882   tail call void @only_store(i32* %p)
883   br label %l3
886   ret void
889 ; test 18
890 ; void test18_caller(int* p, int c) {
891 ;   if(c) {
892 ;     make_alias(p);
893 ;     noreturn();
894 ;   }
895 ;   only_store(p);
896 ;   return;
897 ; }
899 define void @noreturn() {
900 ; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
901 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@noreturn
902 ; NOT_CGSCC_NPM-SAME: () #[[ATTR9:[0-9]+]] {
903 ; NOT_CGSCC_NPM-NEXT:    unreachable
905 ; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
906 ; IS__CGSCC____-LABEL: define {{[^@]+}}@noreturn
907 ; IS__CGSCC____-SAME: () #[[ATTR9:[0-9]+]] {
908 ; IS__CGSCC____-NEXT:    unreachable
910   call void @noreturn()
911   ret void
914 define void @test18_caller(i32* noalias %p, i32 %c) {
915 ; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly
916 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test18_caller
917 ; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] {
918 ; NOT_CGSCC_NPM-NEXT:  entry:
919 ; NOT_CGSCC_NPM-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
920 ; NOT_CGSCC_NPM-NEXT:    br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]]
921 ; NOT_CGSCC_NPM:       l1:
922 ; NOT_CGSCC_NPM-NEXT:    tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR7]]
923 ; NOT_CGSCC_NPM-NEXT:    unreachable
924 ; NOT_CGSCC_NPM:       l2:
925 ; NOT_CGSCC_NPM-NEXT:    tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR7]]
926 ; NOT_CGSCC_NPM-NEXT:    ret void
928 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
929 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test18_caller
930 ; IS__CGSCC____-SAME: (i32* noalias nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] {
931 ; IS__CGSCC____-NEXT:  entry:
932 ; IS__CGSCC____-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
933 ; IS__CGSCC____-NEXT:    br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]]
934 ; IS__CGSCC____:       l1:
935 ; IS__CGSCC____-NEXT:    tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]]
936 ; IS__CGSCC____-NEXT:    unreachable
937 ; IS__CGSCC____:       l2:
938 ; IS__CGSCC____-NEXT:    tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]]
939 ; IS__CGSCC____-NEXT:    ret void
941 entry:
942   %tobool = icmp eq i32 %c, 0
943   br i1 %tobool, label %l1, label %l2
946   tail call void @make_alias(i32* %p)
947   tail call void @noreturn()
948   br label %l2
951   tail call void @only_store(i32* %p)
952   ret void
955 ; NOT_CGSCC_NPM: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
956 ; NOT_CGSCC_NPM: attributes #[[ATTR1]] = { nounwind uwtable }
957 ; NOT_CGSCC_NPM: attributes #[[ATTR2]] = { nounwind }
958 ; NOT_CGSCC_NPM: attributes #[[ATTR3]] = { nounwind ssp uwtable }
959 ; NOT_CGSCC_NPM: attributes #[[ATTR4]] = { nofree nosync nounwind readonly willreturn }
960 ; NOT_CGSCC_NPM: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind readonly willreturn }
961 ; NOT_CGSCC_NPM: attributes #[[ATTR6:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn }
962 ; NOT_CGSCC_NPM: attributes #[[ATTR7]] = { nofree nosync nounwind willreturn writeonly }
963 ; NOT_CGSCC_NPM: attributes #[[ATTR8]] = { argmemonly nofree nosync nounwind willreturn writeonly }
964 ; NOT_CGSCC_NPM: attributes #[[ATTR9]] = { nofree noreturn nosync nounwind readnone willreturn }
965 ; NOT_CGSCC_NPM: attributes #[[ATTR10]] = { willreturn }
967 ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
968 ; IS__CGSCC____: attributes #[[ATTR1]] = { nounwind uwtable }
969 ; IS__CGSCC____: attributes #[[ATTR2]] = { nounwind }
970 ; IS__CGSCC____: attributes #[[ATTR3]] = { nounwind ssp uwtable }
971 ; IS__CGSCC____: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind readonly willreturn }
972 ; IS__CGSCC____: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
973 ; IS__CGSCC____: attributes #[[ATTR6:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn }
974 ; IS__CGSCC____: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn writeonly }
975 ; IS__CGSCC____: attributes #[[ATTR8]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
976 ; IS__CGSCC____: attributes #[[ATTR9]] = { nofree norecurse noreturn nosync nounwind readnone willreturn }
977 ; IS__CGSCC____: attributes #[[ATTR10]] = { readnone willreturn }
978 ; IS__CGSCC____: attributes #[[ATTR11]] = { readonly willreturn }
979 ; IS__CGSCC____: attributes #[[ATTR12]] = { willreturn }
980 ; IS__CGSCC____: attributes #[[ATTR13]] = { nounwind willreturn writeonly }