[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Analysis / StackSafetyAnalysis / ipa.ll
blob23eb9b26319bdf42a9183ec20f213e6fe4ff8671
1 ; REQUIRES: aarch64-registered-target
2 ; REQUIRES: shell
4 ; RUN: llvm-as %s -o %t0.bc
5 ; RUN: llvm-as %S/Inputs/ipa.ll -o %t1.bc
6 ; RUN: llvm-link -disable-lazy-loading %t0.bc %t1.bc -o %t.combined.bc
8 ; RUN: opt -S -analyze -stack-safety-local %t.combined.bc -enable-new-pm=0 | FileCheck %s --check-prefixes=CHECK,LOCAL
9 ; RUN: opt -S -passes="print<stack-safety-local>" -disable-output %t.combined.bc 2>&1 | FileCheck %s --check-prefixes=CHECK,LOCAL
11 ; RUN: opt -S -analyze -stack-safety %t.combined.bc -enable-new-pm=0 | FileCheck %s --check-prefixes=CHECK,GLOBAL,NOLTO
12 ; RUN: opt -S -passes="print-stack-safety" -disable-output %t.combined.bc 2>&1 | FileCheck %s --check-prefixes=CHECK,GLOBAL,NOLTO
14 ; Do an end-to-test using the new LTO API
15 ; TODO: Hideous llvm-lto2 invocation, add a --default-symbol-resolution to llvm-lto2?
16 ; RUN: opt -module-summary %s -o %t.summ0.bc
17 ; RUN: opt -module-summary %S/Inputs/ipa.ll -o %t.summ1.bc
19 ; RUN: llvm-dis %t.summ0.bc -o - > %t.ids.txt
20 ; RUN: llvm-dis %t.summ1.bc -o - >> %t.ids.txt
22 ; RUN: echo > %t.res.txt \
23 ; RUN:  -r %t.summ0.bc,ExternalCall, \
24 ; RUN:  -r %t.summ0.bc,f1,px \
25 ; RUN:  -r %t.summ0.bc,f2,px \
26 ; RUN:  -r %t.summ0.bc,f3,px \
27 ; RUN:  -r %t.summ0.bc,f4,px \
28 ; RUN:  -r %t.summ0.bc,f5,px \
29 ; RUN:  -r %t.summ0.bc,f6,px \
30 ; RUN:  -r %t.summ0.bc,f7,px \
31 ; RUN:  -r %t.summ0.bc,f8left,px \
32 ; RUN:  -r %t.summ0.bc,f8oobleft,px \
33 ; RUN:  -r %t.summ0.bc,f8oobright,px \
34 ; RUN:  -r %t.summ0.bc,f8right,px \
35 ; RUN:  -r %t.summ0.bc,InterposableCall,px \
36 ; RUN:  -r %t.summ0.bc,InterposableWrite1, \
37 ; RUN:  -r %t.summ0.bc,PreemptableCall,px \
38 ; RUN:  -r %t.summ0.bc,PreemptableWrite1, \
39 ; RUN:  -r %t.summ0.bc,PrivateCall,px \
40 ; RUN:  -r %t.summ0.bc,Rec2, \
41 ; RUN:  -r %t.summ0.bc,RecursiveNoOffset, \
42 ; RUN:  -r %t.summ0.bc,RecursiveWithOffset, \
43 ; RUN:  -r %t.summ0.bc,ReturnDependent, \
44 ; RUN:  -r %t.summ0.bc,TestCrossModuleConflict,px \
45 ; RUN:  -r %t.summ0.bc,TestCrossModuleOnce,px \
46 ; RUN:  -r %t.summ0.bc,TestCrossModuleTwice,px \
47 ; RUN:  -r %t.summ0.bc,TestCrossModuleWeak,px \
48 ; RUN:  -r %t.summ0.bc,TestRecursiveNoOffset,px \
49 ; RUN:  -r %t.summ0.bc,TestRecursiveWithOffset,px \
50 ; RUN:  -r %t.summ0.bc,TestUpdateArg,px \
51 ; RUN:  -r %t.summ0.bc,TwoArguments,px \
52 ; RUN:  -r %t.summ0.bc,TwoArgumentsOOBBoth,px \
53 ; RUN:  -r %t.summ0.bc,TwoArgumentsOOBOne,px \
54 ; RUN:  -r %t.summ0.bc,TwoArgumentsOOBOther,px \
55 ; RUN:  -r %t.summ0.bc,Weak,x \
56 ; RUN:  -r %t.summ0.bc,Write1, \
57 ; RUN:  -r %t.summ0.bc,Write1DiffModule,x \
58 ; RUN:  -r %t.summ0.bc,Write1Module0,px \
59 ; RUN:  -r %t.summ0.bc,Write1Private,x \
60 ; RUN:  -r %t.summ0.bc,Write1SameModule,x \
61 ; RUN:  -r %t.summ0.bc,Write1Weak,x \
62 ; RUN:  -r %t.summ0.bc,Write4_2, \
63 ; RUN:  -r %t.summ0.bc,Write4, \
64 ; RUN:  -r %t.summ0.bc,Write8, \
65 ; RUN:  -r %t.summ0.bc,WriteAndReturn8, \
66 ; RUN:  -r %t.summ1.bc,ExternalCall,px \
67 ; RUN:  -r %t.summ1.bc,InterposableWrite1,px \
68 ; RUN:  -r %t.summ1.bc,PreemptableWrite1,px \
69 ; RUN:  -r %t.summ1.bc,Rec0,px \
70 ; RUN:  -r %t.summ1.bc,Rec1,px \
71 ; RUN:  -r %t.summ1.bc,Rec2,px \
72 ; RUN:  -r %t.summ1.bc,RecursiveNoOffset,px \
73 ; RUN:  -r %t.summ1.bc,RecursiveWithOffset,px \
74 ; RUN:  -r %t.summ1.bc,ReturnAlloca,px \
75 ; RUN:  -r %t.summ1.bc,ReturnDependent,px \
76 ; RUN:  -r %t.summ1.bc,Weak,x \
77 ; RUN:  -r %t.summ1.bc,Write1,px \
78 ; RUN:  -r %t.summ1.bc,Write1DiffModule,px \
79 ; RUN:  -r %t.summ1.bc,Write1Module0,x \
80 ; RUN:  -r %t.summ1.bc,Write1Private,px \
81 ; RUN:  -r %t.summ1.bc,Write1SameModule,px \
82 ; RUN:  -r %t.summ1.bc,Write1Weak,px \
83 ; RUN:  -r %t.summ1.bc,Write4_2,px \
84 ; RUN:  -r %t.summ1.bc,Write4,px \
85 ; RUN:  -r %t.summ1.bc,Write8,px \
86 ; RUN:  -r %t.summ1.bc,WriteAndReturn8,px
88 ; RUN: llvm-lto2 run %t.summ0.bc %t.summ1.bc -o %t.lto -stack-safety-print -stack-safety-run -save-temps -thinlto-threads 1 -O0 \
89 ; RUN:  $(cat %t.res.txt) \
90 ; RUN:    2>&1 | FileCheck %s --check-prefixes=CHECK,GLOBAL,LTO
92 ; RUN: llvm-lto2 run %t.summ0.bc %t.summ1.bc -o %t.lto -stack-safety-run -thinlto-distributed-indexes -thinlto-threads 1 -O0 $(cat %t.res.txt)
93 ; RUN: (cat %t.ids.txt ; llvm-dis %t.summ1.bc.thinlto.bc -o -) | FileCheck --check-prefixes=INDEX %s
95 ; RUN: llvm-lto2 run %t.summ0.bc %t.summ1.bc -o %t-newpm.lto -use-new-pm -stack-safety-print -stack-safety-run -save-temps -thinlto-threads 1 -O0 \
96 ; RUN:  $(cat %t.res.txt) \
97 ; RUN:    2>&1 | FileCheck %s --check-prefixes=CHECK,GLOBAL,LTO
99 ; RUN: llvm-lto2 run %t.summ0.bc %t.summ1.bc -o %t-newpm.lto -stack-safety-run -thinlto-distributed-indexes -thinlto-threads 1 -O0 $(cat %t.res.txt)
100 ; RUN: (cat %t.ids.txt ; llvm-dis %t.summ1.bc.thinlto.bc -o -) | FileCheck --check-prefixes=INDEX %s
102 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
103 target triple = "aarch64-unknown-linux"
105 attributes #0 = { noinline sanitize_memtag "target-features"="+mte,+neon" }
107 declare void @Write1(i8* %p)
108 declare void @Write4(i8* %p)
109 declare void @Write4_2(i8* %p, i8* %q)
110 declare void @Write8(i8* %p)
111 declare dso_local i8* @WriteAndReturn8(i8* %p)
112 declare dso_local void @ExternalCall(i8* %p)
113 declare void @PreemptableWrite1(i8* %p)
114 declare void @InterposableWrite1(i8* %p)
115 declare i8* @ReturnDependent(i8* %p)
116 declare void @Rec2(i8* %p)
117 declare void @RecursiveNoOffset(i32* %p, i32 %size, i32* %acc)
118 declare void @RecursiveWithOffset(i32 %size, i32* %acc)
119 declare void @Write1SameModule(i8* %p)
120 declare void @Write1DiffModule(i8* %p)
121 declare void @Write1Private(i8* %p)
122 declare void @Write1Weak(i8* %p)
124 ; Basic out-of-bounds.
125 define void @f1() #0 {
126 ; CHECK-LABEL: @f1 dso_preemptable{{$}}
127 ; CHECK-NEXT: args uses:
128 ; CHECK-NEXT: allocas uses:
129 ; LOCAL-NEXT: x[4]: empty-set, @Write8(arg0, [0,1)){{$}}
130 ; GLOBAL-NEXT: x[4]: [0,8), @Write8(arg0, [0,1)){{$}}
131 ; CHECK-EMPTY:
132 entry:
133   %x = alloca i32, align 4
134   %x1 = bitcast i32* %x to i8*
135   call void @Write8(i8* %x1)
136   ret void
139 ; Basic in-bounds.
140 define void @f2() #0 {
141 ; CHECK-LABEL: @f2 dso_preemptable{{$}}
142 ; CHECK-NEXT: args uses:
143 ; CHECK-NEXT: allocas uses:
144 ; LOCAL-NEXT: x[4]: empty-set, @Write1(arg0, [0,1)){{$}}
145 ; GLOBAL-NEXT: x[4]: [0,1), @Write1(arg0, [0,1)){{$}}
146 ; CHECK-EMPTY:
147 entry:
148   %x = alloca i32, align 4
149   %x1 = bitcast i32* %x to i8*
150   call void @Write1(i8* %x1)
151   ret void
154 ; Another basic in-bounds.
155 define void @f3() #0 {
156 ; CHECK-LABEL: @f3 dso_preemptable{{$}}
157 ; CHECK-NEXT: args uses:
158 ; CHECK-NEXT: allocas uses:
159 ; LOCAL-NEXT: x[4]: empty-set, @Write4(arg0, [0,1)){{$}}
160 ; GLOBAL-NEXT: x[4]: [0,4), @Write4(arg0, [0,1)){{$}}
161 ; CHECK-EMPTY:
162 entry:
163   %x = alloca i32, align 4
164   %x1 = bitcast i32* %x to i8*
165   call void @Write4(i8* %x1)
166   ret void
169 ; In-bounds with offset.
170 define void @f4() #0 {
171 ; CHECK-LABEL: @f4 dso_preemptable{{$}}
172 ; CHECK-NEXT: args uses:
173 ; CHECK-NEXT: allocas uses:
174 ; LOCAL-NEXT: x[4]: empty-set, @Write1(arg0, [1,2)){{$}}
175 ; GLOBAL-NEXT: x[4]: [1,2), @Write1(arg0, [1,2)){{$}}
176 ; CHECK-EMPTY:
177 entry:
178   %x = alloca i32, align 4
179   %x1 = bitcast i32* %x to i8*
180   %x2 = getelementptr i8, i8* %x1, i64 1
181   call void @Write1(i8* %x2)
182   ret void
185 ; Out-of-bounds with offset.
186 define void @f5() #0 {
187 ; CHECK-LABEL: @f5 dso_preemptable{{$}}
188 ; CHECK-NEXT: args uses:
189 ; CHECK-NEXT: allocas uses:
190 ; LOCAL-NEXT: empty-set, @Write4(arg0, [1,2)){{$}}
191 ; GLOBAL-NEXT: [1,5), @Write4(arg0, [1,2)){{$}}
192 ; CHECK-EMPTY:
193 entry:
194   %x = alloca i32, align 4
195   %x1 = bitcast i32* %x to i8*
196   %x2 = getelementptr i8, i8* %x1, i64 1
197   call void @Write4(i8* %x2)
198   ret void
201 ; External call.
202 define void @f6() #0 {
203 ; CHECK-LABEL: @f6 dso_preemptable{{$}}
204 ; CHECK-NEXT: args uses:
205 ; CHECK-NEXT: allocas uses:
206 ; LOCAL-NEXT: x[4]: empty-set, @ExternalCall(arg0, [0,1)){{$}}
207 ; GLOBAL-NEXT: x[4]: full-set, @ExternalCall(arg0, [0,1)){{$}}
208 ; CHECK-EMPTY:
209 entry:
210   %x = alloca i32, align 4
211   %x1 = bitcast i32* %x to i8*
212   call void @ExternalCall(i8* %x1)
213   ret void
216 ; Call to dso_preemptable function
217 define void @PreemptableCall() #0 {
218 ; CHECK-LABEL: @PreemptableCall dso_preemptable{{$}}
219 ; CHECK-NEXT: args uses:
220 ; CHECK-NEXT: allocas uses:
221 ; LOCAL-NEXT: x[4]: empty-set, @PreemptableWrite1(arg0, [0,1)){{$}}
222 ; GLOBAL-NEXT: x[4]: full-set, @PreemptableWrite1(arg0, [0,1)){{$}}
223 ; CHECK-EMPTY:
224 entry:
225   %x = alloca i32, align 4
226   %x1 = bitcast i32* %x to i8*
227   call void @PreemptableWrite1(i8* %x1)
228   ret void
231 ; Call to function with interposable linkage
232 define void @InterposableCall() #0 {
233 ; CHECK-LABEL: @InterposableCall dso_preemptable{{$}}
234 ; CHECK-NEXT: args uses:
235 ; CHECK-NEXT: allocas uses:
236 ; LOCAL-NEXT: x[4]: empty-set, @InterposableWrite1(arg0, [0,1)){{$}}
237 ; NOLTO-NEXT: x[4]: full-set, @InterposableWrite1(arg0, [0,1)){{$}}
238 ; LTO-NEXT: x[4]: [0,1), @InterposableWrite1(arg0, [0,1)){{$}}
239 ; CHECK-EMPTY:
240 entry:
241   %x = alloca i32, align 4
242   %x1 = bitcast i32* %x to i8*
243   call void @InterposableWrite1(i8* %x1)
244   ret void
247 ; Call to function with private linkage
248 define void @PrivateCall() #0 {
249 ; CHECK-LABEL: @PrivateCall dso_preemptable{{$}}
250 ; CHECK-NEXT: args uses:
251 ; CHECK-NEXT: allocas uses:
252 ; LOCAL-NEXT: x[4]: empty-set, @PrivateWrite1(arg0, [0,1)){{$}}
253 ; GLOBAL-NEXT: x[4]: [0,1), @PrivateWrite1(arg0, [0,1)){{$}}
254 ; CHECK-EMPTY:
255 entry:
256   %x = alloca i32, align 4
257   %x1 = bitcast i32* %x to i8*
258   call void @PrivateWrite1(i8* %x1)
259   ret void
262 define private void @PrivateWrite1(i8* %p) #0 {
263 ; CHECK-LABEL: @PrivateWrite1{{$}}
264 ; CHECK-NEXT: args uses:
265 ; CHECK-NEXT: p[]: [0,1){{$}}
266 ; CHECK-NEXT: allocas uses:
267 ; CHECK-EMPTY:
268 entry:
269   store i8 0, i8* %p, align 1
270   ret void
273 ; Caller returns a dependent value.
274 ; FIXME: alloca considered unsafe even if the return value is unused.
275 define void @f7() #0 {
276 ; CHECK-LABEL: @f7 dso_preemptable{{$}}
277 ; CHECK-NEXT: args uses:
278 ; CHECK-NEXT: allocas uses:
279 ; LOCAL-NEXT: x[4]: empty-set, @ReturnDependent(arg0, [0,1)){{$}}
280 ; GLOBAL-NEXT: x[4]: full-set, @ReturnDependent(arg0, [0,1)){{$}}
281 ; CHECK-EMPTY:
282 entry:
283   %x = alloca i32, align 4
284   %x1 = bitcast i32* %x to i8*
285   %x2 = call i8* @ReturnDependent(i8* %x1)
286   ret void
289 define void @f8left() #0 {
290 ; CHECK-LABEL: @f8left dso_preemptable{{$}}
291 ; CHECK-NEXT: args uses:
292 ; CHECK-NEXT: allocas uses:
293 ; LOCAL-NEXT: x[8]: empty-set, @Rec2(arg0, [2,3)){{$}}
294 ; GLOBAL-NEXT: x[8]: [0,4), @Rec2(arg0, [2,3)){{$}}
295 ; CHECK-EMPTY:
296 entry:
297   %x = alloca i64, align 4
298   %x1 = bitcast i64* %x to i8*
299   %x2 = getelementptr i8, i8* %x1, i64 2
300 ; 2 + [-2, 2) = [0, 4) => OK
301   call void @Rec2(i8* %x2)
302   ret void
305 define void @f8right() #0 {
306 ; CHECK-LABEL: @f8right dso_preemptable{{$}}
307 ; CHECK-NEXT: args uses:
308 ; CHECK-NEXT: allocas uses:
309 ; LOCAL-NEXT: x[8]: empty-set, @Rec2(arg0, [6,7)){{$}}
310 ; GLOBAL-NEXT: x[8]: [4,8), @Rec2(arg0, [6,7)){{$}}
311 ; CHECK-EMPTY:
312 entry:
313   %x = alloca i64, align 4
314   %x1 = bitcast i64* %x to i8*
315   %x2 = getelementptr i8, i8* %x1, i64 6
316 ; 6 + [-2, 2) = [4, 8) => OK
317   call void @Rec2(i8* %x2)
318   ret void
321 define void @f8oobleft() #0 {
322 ; CHECK-LABEL: @f8oobleft dso_preemptable{{$}}
323 ; CHECK-NEXT: args uses:
324 ; CHECK-NEXT: allocas uses:
325 ; LOCAL-NEXT: x[8]: empty-set, @Rec2(arg0, [1,2)){{$}}
326 ; GLOBAL-NEXT: x[8]: [-1,3), @Rec2(arg0, [1,2)){{$}}
327 ; CHECK-EMPTY:
328 entry:
329   %x = alloca i64, align 4
330   %x1 = bitcast i64* %x to i8*
331   %x2 = getelementptr i8, i8* %x1, i64 1
332 ; 1 + [-2, 2) = [-1, 3) => NOT OK
333   call void @Rec2(i8* %x2)
334   ret void
337 define void @f8oobright() #0 {
338 ; CHECK-LABEL: @f8oobright dso_preemptable{{$}}
339 ; CHECK-NEXT: args uses:
340 ; CHECK-NEXT: allocas uses:
341 ; LOCAL-NEXT: x[8]: empty-set, @Rec2(arg0, [7,8)){{$}}
342 ; GLOBAL-NEXT: x[8]: [5,9), @Rec2(arg0, [7,8)){{$}}
343 ; CHECK-EMPTY:
344 entry:
345   %x = alloca i64, align 4
346   %x1 = bitcast i64* %x to i8*
347   %x2 = getelementptr i8, i8* %x1, i64 7
348 ; 7 + [-2, 2) = [5, 9) => NOT OK
349   call void @Rec2(i8* %x2)
350   ret void
353 define void @TwoArguments() #0 {
354 ; CHECK-LABEL: @TwoArguments dso_preemptable{{$}}
355 ; CHECK-NEXT: args uses:
356 ; CHECK-NEXT: allocas uses:
357 ; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg0, [4,5)), @Write4_2(arg1, [0,1)){{$}}
358 ; GLOBAL-NEXT: x[8]: [0,8), @Write4_2(arg0, [4,5)), @Write4_2(arg1, [0,1)){{$}}
359 ; CHECK-EMPTY:
360 entry:
361   %x = alloca i64, align 4
362   %x1 = bitcast i64* %x to i8*
363   %x2 = getelementptr i8, i8* %x1, i64 4
364   call void @Write4_2(i8* %x2, i8* %x1)
365   ret void
368 define void @TwoArgumentsOOBOne() #0 {
369 ; CHECK-LABEL: @TwoArgumentsOOBOne dso_preemptable{{$}}
370 ; CHECK-NEXT: args uses:
371 ; CHECK-NEXT: allocas uses:
372 ; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg0, [5,6)), @Write4_2(arg1, [0,1)){{$}}
373 ; GLOBAL-NEXT: x[8]: [0,9), @Write4_2(arg0, [5,6)), @Write4_2(arg1, [0,1)){{$}}
374 ; CHECK-EMPTY:
375 entry:
376   %x = alloca i64, align 4
377   %x1 = bitcast i64* %x to i8*
378   %x2 = getelementptr i8, i8* %x1, i64 5
379   call void @Write4_2(i8* %x2, i8* %x1)
380   ret void
383 define void @TwoArgumentsOOBOther() #0 {
384 ; CHECK-LABEL: @TwoArgumentsOOBOther dso_preemptable{{$}}
385 ; CHECK-NEXT: args uses:
386 ; CHECK-NEXT: allocas uses:
387 ; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg0, [4,5)), @Write4_2(arg1, [-1,0)){{$}}
388 ; GLOBAL-NEXT: x[8]: [-1,8), @Write4_2(arg0, [4,5)), @Write4_2(arg1, [-1,0)){{$}}
389 ; CHECK-EMPTY:
390 entry:
391   %x = alloca i64, align 4
392   %x0 = bitcast i64* %x to i8*
393   %x1 = getelementptr i8, i8* %x0, i64 -1
394   %x2 = getelementptr i8, i8* %x0, i64 4
395   call void @Write4_2(i8* %x2, i8* %x1)
396   ret void
399 define void @TwoArgumentsOOBBoth() #0 {
400 ; CHECK-LABEL: @TwoArgumentsOOBBoth dso_preemptable{{$}}
401 ; CHECK-NEXT: args uses:
402 ; CHECK-NEXT: allocas uses:
403 ; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg0, [5,6)), @Write4_2(arg1, [-1,0)){{$}}
404 ; GLOBAL-NEXT: x[8]: [-1,9), @Write4_2(arg0, [5,6)), @Write4_2(arg1, [-1,0)){{$}}
405 ; CHECK-EMPTY:
406 entry:
407   %x = alloca i64, align 4
408   %x0 = bitcast i64* %x to i8*
409   %x1 = getelementptr i8, i8* %x0, i64 -1
410   %x2 = getelementptr i8, i8* %x0, i64 5
411   call void @Write4_2(i8* %x2, i8* %x1)
412   ret void
415 define i32 @TestRecursiveNoOffset(i32* %p, i32 %size) #0 {
416 ; CHECK-LABEL: @TestRecursiveNoOffset dso_preemptable{{$}}
417 ; CHECK-NEXT: args uses:
418 ; LOCAL-NEXT: p[]: empty-set, @RecursiveNoOffset(arg0, [0,1)){{$}}
419 ; GLOBAL-NEXT: p[]: full-set, @RecursiveNoOffset(arg0, [0,1)){{$}}
420 ; CHECK-NEXT: allocas uses:
421 ; CHECK-NEXT: sum[4]: [0,4), @RecursiveNoOffset(arg2, [0,1)){{$}}
422 ; CHECK-EMPTY:
423 entry:
424   %sum = alloca i32, align 4
425   %0 = bitcast i32* %sum to i8*
426   store i32 0, i32* %sum, align 4
427   call void @RecursiveNoOffset(i32* %p, i32 %size, i32* %sum)
428   %1 = load i32, i32* %sum, align 4
429   ret i32 %1
432 define void @TestRecursiveWithOffset(i32 %size) #0 {
433 ; CHECK-LABEL: @TestRecursiveWithOffset dso_preemptable{{$}}
434 ; CHECK-NEXT: args uses:
435 ; CHECK-NEXT: allocas uses:
436 ; LOCAL-NEXT: sum[64]: empty-set, @RecursiveWithOffset(arg1, [0,1)){{$}}
437 ; GLOBAL-NEXT: sum[64]: full-set, @RecursiveWithOffset(arg1, [0,1)){{$}}
438 ; CHECK-EMPTY:
439 entry:
440   %sum = alloca i32, i64 16, align 4
441   call void @RecursiveWithOffset(i32 %size, i32* %sum)
442   ret void
445 ; FIXME: IPA should detect that access is safe
446 define void @TestUpdateArg() #0 {
447 ; CHECK-LABEL: @TestUpdateArg dso_preemptable{{$}}
448 ; CHECK-NEXT: args uses:
449 ; CHECK-NEXT: allocas uses:
450 ; LOCAL-NEXT: x[16]: empty-set, @WriteAndReturn8(arg0, [0,1)){{$}}
451 ; GLOBAL-NEXT: x[16]: full-set, @WriteAndReturn8(arg0, [0,1)){{$}}
452 ; CHECK-EMPTY:
453 entry:
454   %x = alloca i8, i64 16, align 4
455   %0 = call i8* @WriteAndReturn8(i8* %x)
456   ret void
459 define void @TestCrossModuleOnce() #0 {
460 ; CHECK-DAG: @TestCrossModuleOnce dso_preemptable{{$}}
461 ; CHECK-NEXT: args uses:
462 ; CHECK-NEXT: allocas uses:
463 ; LOCAL-NEXT: y[1]: empty-set, @Write1SameModule(arg0, [0,1)){{$}}
464 ; GLOBAL-NEXT: y[1]: [0,1), @Write1SameModule(arg0, [0,1)){{$}}
465 ; CHECK-EMPTY:
466 entry:
467   %y = alloca i8, align 4
468   call void @Write1SameModule(i8* %y)
469   ret void
472 define void @TestCrossModuleTwice() #0 {
473 ; CHECK-DAG: @TestCrossModuleTwice dso_preemptable{{$}}
474 ; CHECK-NEXT: args uses:
475 ; CHECK-NEXT: allocas uses:
476 ; LOCAL-NEXT: z[1]: empty-set, @Write1DiffModule(arg0, [0,1)){{$}}
477 ; GLOBAL-NEXT: z[1]: [0,1), @Write1DiffModule(arg0, [0,1)){{$}}
478 ; CHECK-EMPTY:
479 entry:
480   %z = alloca i8, align 4
481   call void @Write1DiffModule(i8* %z)
482   ret void
485 define void @TestCrossModuleConflict() #0 {
486 ; CHECK-DAG: @TestCrossModuleConflict dso_preemptable{{$}}
487 ; CHECK-NEXT: args uses:
488 ; CHECK-NEXT: allocas uses:
489 ; LOCAL-NEXT: x[1]: empty-set, @Write1Private(arg0, [0,1)){{$}}
490 ; GLOBAL-NEXT: x[1]: [-1,0), @Write1Private(arg0, [0,1)){{$}}
491 ; CHECK-EMPTY:
492 entry:
493   %x = alloca i8, align 4
494   call void @Write1Private(i8* %x)
495   ret void
498 ; FIXME: LTO should match NOLTO
499 define void @TestCrossModuleWeak() #0 {
500 ; CHECK-DAG: @TestCrossModuleWeak dso_preemptable{{$}}
501 ; CHECK-NEXT: args uses:
502 ; CHECK-NEXT: allocas uses:
503 ; LOCAL-NEXT: x[1]: empty-set, @Write1Weak(arg0, [0,1)){{$}}
504 ; NOLTO-NEXT: x[1]: [1,2), @Write1Weak(arg0, [0,1)){{$}}
505 ; LTO-NEXT: x[1]: full-set, @Write1Weak(arg0, [0,1)){{$}}
506 ; CHECK-EMPTY:
507 entry:
508   %x = alloca i8, align 4
509   call void @Write1Weak(i8* %x)
510   ret void
513 define private dso_local void @Private(i8* %p) #0 {
514 entry:
515   %p1 = getelementptr i8, i8* %p, i64 1
516   store i8 0, i8* %p1, align 1
517   ret void
520 define dso_local void @Write1Module0(i8* %p) #0 {
521 entry:
522   store i8 0, i8* %p, align 1
523   ret void
526 define dso_local void @Weak(i8* %p) #0 {
527 entry:
528   %p1 = getelementptr i8, i8* %p, i64 1
529   store i8 0, i8* %p1, align 1
530   ret void
533 ; The rest is from Inputs/ipa.ll
535 ; CHECK-LABEL: @Write1{{$}}
536 ; CHECK-NEXT: args uses:
537 ; CHECK-NEXT: p[]: [0,1){{$}}
538 ; CHECK-NEXT: allocas uses:
539 ; CHECK-EMPTY:
541 ; CHECK-LABEL: @Write4{{$}}
542 ; CHECK-NEXT: args uses:
543 ; CHECK-NEXT: p[]: [0,4){{$}}
544 ; CHECK-NEXT: allocas uses:
545 ; CHECK-EMPTY:
547 ; CHECK-LABEL: @Write4_2{{$}}
548 ; CHECK-NEXT: args uses:
549 ; CHECK-NEXT: p[]: [0,4){{$}}
550 ; CHECK-NEXT: q[]: [0,4){{$}}
551 ; CHECK-NEXT: allocas uses:
552 ; CHECK-EMPTY:
554 ; CHECK-LABEL: @Write8{{$}}
555 ; CHECK-NEXT: args uses:
556 ; CHECK-NEXT: p[]: [0,8){{$}}
557 ; CHECK-NEXT: allocas uses:
558 ; CHECK-EMPTY:
560 ; CHECK-LABEL: @WriteAndReturn8{{$}}
561 ; CHECK-NEXT: args uses:
562 ; CHECK-NEXT: p[]: full-set{{$}}
563 ; CHECK-NEXT: allocas uses:
564 ; CHECK-EMPTY:
566 ; CHECK-LABEL: @PreemptableWrite1 dso_preemptable{{$}}
567 ; CHECK-NEXT: args uses:
568 ; CHECK-NEXT: p[]: [0,1){{$}}
569 ; CHECK-NEXT: allocas uses:
570 ; CHECK-EMPTY:
572 ; CHECK-LABEL: @InterposableWrite1 interposable{{$}}
573 ; CHECK-NEXT: args uses:
574 ; CHECK-NEXT: p[]: [0,1){{$}}
575 ; CHECK-NEXT: allocas uses:
576 ; CHECK-EMPTY:
578 ; CHECK-LABEL: @ReturnDependent{{$}}
579 ; CHECK-NEXT: args uses:
580 ; CHECK-NEXT: p[]: full-set{{$}}
581 ; CHECK-NEXT: allocas uses:
582 ; CHECK-EMPTY:
584 ; CHECK-LABEL: @Rec0{{$}}
585 ; CHECK-NEXT: args uses:
586 ; LOCAL-NEXT: p[]: empty-set, @Write4(arg0, [2,3)){{$}}
587 ; GLOBAL-NEXT: p[]: [2,6)
588 ; CHECK-NEXT: allocas uses:
589 ; CHECK-EMPTY:
591 ; CHECK-LABEL: @Rec1{{$}}
592 ; CHECK-NEXT: args uses:
593 ; LOCAL-NEXT: p[]: empty-set, @Rec0(arg0, [1,2)){{$}}
594 ; GLOBAL-NEXT: p[]: [3,7)
595 ; CHECK-NEXT: allocas uses:
596 ; CHECK-EMPTY:
598 ; CHECK-LABEL: @Rec2{{$}}
599 ; CHECK-NEXT: args uses:
600 ; LOCAL-NEXT: p[]: empty-set, @Rec1(arg0, [-5,-4)){{$}}
601 ; GLOBAL-NEXT: p[]: [-2,2)
602 ; CHECK-NEXT: allocas uses:
603 ; CHECK-EMPTY:
605 ; CHECK-LABEL: @RecursiveNoOffset{{$}}
606 ; CHECK-NEXT: args uses:
607 ; LOCAL-NEXT: p[]: [0,4), @RecursiveNoOffset(arg0, [4,5)){{$}}
608 ; GLOBAL-NEXT: p[]: full-set, @RecursiveNoOffset(arg0, [4,5)){{$}}
609 ; CHECK-NEXT: acc[]: [0,4), @RecursiveNoOffset(arg2, [0,1)){{$}}
610 ; CHECK-NEXT: allocas uses:
611 ; CHECK-EMPTY:
613 ; CHECK-LABEL: @RecursiveWithOffset{{$}}
614 ; CHECK-NEXT: args uses:
615 ; LOCAL-NEXT: acc[]: [0,4), @RecursiveWithOffset(arg1, [4,5)){{$}}
616 ; GLOBAL-NEXT: acc[]: full-set, @RecursiveWithOffset(arg1, [4,5)){{$}}
617 ; CHECK-NEXT: allocas uses:
618 ; CHECK-EMPTY:
620 ; CHECK-LABEL: @ReturnAlloca
621 ; CHECK-NEXT: args uses:
622 ; CHECK-NEXT: allocas uses:
623 ; CHECK-NEXT: x[8]: full-set
624 ; CHECK-EMPTY:
626 ; INDEX-LABEL: ^0 = module:
627 ; INDEX-DAG: name: "ReturnDependent"{{.*}} guid = [[ReturnDependent:[-0-9]+]]
628 ; INDEX-DAG: name: "Private"{{.*}} guid = [[Private:[-0-9]+]]
629 ; INDEX-DAG: name: "TwoArgumentsOOBOther"{{.*}} guid = [[TwoArgumentsOOBOther:[-0-9]+]]
630 ; INDEX-DAG: name: "Rec2"{{.*}} guid = [[Rec2:[-0-9]+]]
631 ; INDEX-DAG: name: "f1"{{.*}} guid = [[f1:[-0-9]+]]
632 ; INDEX-DAG: name: "PrivateWrite1"{{.*}} guid = [[PrivateWrite1:[-0-9]+]]
633 ; INDEX-DAG: name: "TestRecursiveNoOffset"{{.*}} guid = [[TestRecursiveNoOffset:[-0-9]+]]
634 ; INDEX-DAG: name: "f8left"{{.*}} guid = [[f8left:[-0-9]+]]
635 ; INDEX-DAG: name: "Write4"{{.*}} guid = [[Write4:[-0-9]+]]
636 ; INDEX-DAG: name: "f7"{{.*}} guid = [[f7:[-0-9]+]]
637 ; INDEX-DAG: name: "Write1SameModule"{{.*}} guid = [[Write1SameModule:[-0-9]+]]
638 ; INDEX-DAG: name: "Write8"{{.*}} guid = [[Write8:[-0-9]+]]
639 ; INDEX-DAG: name: "TwoArgumentsOOBOne"{{.*}} guid = [[TwoArgumentsOOBOne:[-0-9]+]]
640 ; INDEX-DAG: name: "f3"{{.*}} guid = [[f3:[-0-9]+]]
641 ; INDEX-DAG: name: "f8right"{{.*}} guid = [[f8right:[-0-9]+]]
642 ; INDEX-DAG: name: "Write4_2"{{.*}} guid = [[Write4_2:[-0-9]+]]
643 ; INDEX-DAG: name: "RecursiveWithOffset"{{.*}} guid = [[RecursiveWithOffset:[-0-9]+]]
644 ; INDEX-DAG: name: "Weak"{{.*}} guid = [[Weak:[-0-9]+]]
645 ; INDEX-DAG: name: "Write1Private"{{.*}} guid = [[Write1Private:[-0-9]+]]
646 ; INDEX-DAG: name: "TestUpdateArg"{{.*}} guid = [[TestUpdateArg:[-0-9]+]]
647 ; INDEX-DAG: name: "TestCrossModuleTwice"{{.*}} guid = [[TestCrossModuleTwice:[-0-9]+]]
648 ; INDEX-DAG: name: "TestCrossModuleWeak"{{.*}} guid = [[TestCrossModuleWeak:[-0-9]+]]
649 ; INDEX-DAG: name: "f2"{{.*}} guid = [[f2:[-0-9]+]]
650 ; INDEX-DAG: name: "PrivateCall"{{.*}} guid = [[PrivateCall:[-0-9]+]]
651 ; INDEX-DAG: name: "TestRecursiveWithOffset"{{.*}} guid = [[TestRecursiveWithOffset:[-0-9]+]]
652 ; INDEX-DAG: name: "f8oobleft"{{.*}} guid = [[f8oobleft:[-0-9]+]]
653 ; INDEX-DAG: name: "InterposableWrite1"{{.*}} guid = [[InterposableWrite1:[-0-9]+]]
654 ; INDEX-DAG: name: "f4"{{.*}} guid = [[f4:[-0-9]+]]
655 ; INDEX-DAG: name: "TestCrossModuleConflict"{{.*}} guid = [[TestCrossModuleConflict:[-0-9]+]]
656 ; INDEX-DAG: name: "RecursiveNoOffset"{{.*}} guid = [[RecursiveNoOffset:[-0-9]+]]
657 ; INDEX-DAG: name: "TwoArgumentsOOBBoth"{{.*}} guid = [[TwoArgumentsOOBBoth:[-0-9]+]]
658 ; INDEX-DAG: name: "f5"{{.*}} guid = [[f5:[-0-9]+]]
659 ; INDEX-DAG: name: "f6"{{.*}} guid = [[f6:[-0-9]+]]
660 ; INDEX-DAG: name: "Write1Weak"{{.*}} guid = [[Write1Weak:[-0-9]+]]
661 ; INDEX-DAG: name: "Write1"{{.*}} guid = [[Write1:[-0-9]+]]
662 ; INDEX-DAG: name: "PreemptableWrite1"{{.*}} guid = [[PreemptableWrite1:[-0-9]+]]
663 ; INDEX-DAG: name: "f8oobright"{{.*}} guid = [[f8oobright:[-0-9]+]]
664 ; INDEX-DAG: name: "InterposableCall"{{.*}} guid = [[InterposableCall:[-0-9]+]]
665 ; INDEX-DAG: name: "TestCrossModuleOnce"{{.*}} guid = [[TestCrossModuleOnce:[-0-9]+]]
666 ; INDEX-DAG: name: "WriteAndReturn8"{{.*}} guid = [[WriteAndReturn8:[-0-9]+]]
667 ; INDEX-DAG: name: "TwoArguments"{{.*}} guid = [[TwoArguments:[-0-9]+]]
668 ; INDEX-DAG: name: "Write1Module0"{{.*}} guid = [[Write1Module0:[-0-9]+]]
669 ; INDEX-DAG: name: "PreemptableCall"{{.*}} guid = [[PreemptableCall:[-0-9]+]]
670 ; INDEX-DAG: name: "Write1DiffModule"{{.*}} guid = [[Write1DiffModule:[-0-9]+]]
671 ; INDEX-DAG: name: "ExternalCall"{{.*}} guid = [[ExternalCall:[-0-9]+]]
672 ; INDEX-LABEL: = blockcount:
674 ; INDEX-LABEL: ^0 = module:
675 ; INDEX-DAG: name: "ReturnDependent"{{.*}} guid = [[ReturnDependent:[-0-9]+]]
676 ; INDEX-DAG: name: "Rec0"{{.*}} guid = [[Rec0:[-0-9]+]]
677 ; INDEX-DAG: name: "Rec2"{{.*}} guid = [[Rec2:[-0-9]+]]
678 ; INDEX-DAG: name: "Write4"{{.*}} guid = [[Write4:[-0-9]+]]
679 ; INDEX-DAG: name: "Write1SameModule"{{.*}} guid = [[Write1SameModule:[-0-9]+]]
680 ; INDEX-DAG: name: "Write8"{{.*}} guid = [[Write8:[-0-9]+]]
681 ; INDEX-DAG: name: "Write4_2"{{.*}} guid = [[Write4_2:[-0-9]+]]
682 ; INDEX-DAG: name: "RecursiveWithOffset"{{.*}} guid = [[RecursiveWithOffset:[-0-9]+]]
683 ; INDEX-DAG: name: "Weak"{{.*}} guid = [[Weak:[-0-9]+]]
684 ; INDEX-DAG: name: "Write1Private"{{.*}} guid = [[Write1Private:[-0-9]+]]
685 ; INDEX-DAG: name: "InterposableWrite1"{{.*}} guid = [[InterposableWrite1:[-0-9]+]]
686 ; INDEX-DAG: name: "Private"{{.*}} guid = [[Private:[-0-9]+]]
687 ; INDEX-DAG: name: "Rec1"{{.*}} guid = [[Rec1:[-0-9]+]]
688 ; INDEX-DAG: name: "RecursiveNoOffset"{{.*}} guid = [[RecursiveNoOffset:[-0-9]+]]
689 ; INDEX-DAG: name: "Write1Weak"{{.*}} guid = [[Write1Weak:[-0-9]+]]
690 ; INDEX-DAG: name: "Write1"{{.*}} guid = [[Write1:[-0-9]+]]
691 ; INDEX-DAG: name: "PreemptableWrite1"{{.*}} guid = [[PreemptableWrite1:[-0-9]+]]
692 ; INDEX-DAG: name: "WriteAndReturn8"{{.*}} guid = [[WriteAndReturn8:[-0-9]+]]
693 ; INDEX-DAG: name: "Write1Module0"{{.*}} guid = [[Write1Module0:[-0-9]+]]
694 ; INDEX-DAG: name: "Write1DiffModule"{{.*}} guid = [[Write1DiffModule:[-0-9]+]]
695 ; INDEX-DAG: name: "ExternalCall"{{.*}} guid = [[ExternalCall:[-0-9]+]]
696 ; INDEX-DAG: name: "ReturnAlloca"{{.*}} guid = [[ReturnAlloca:[-0-9]+]]
697 ; INDEX-LABEL: = blockcount:
699 ; INDEX-LABEL: ^0 = module:
700 ; INDEX-DAG: guid: [[ReturnDependent]], {{.*}}, funcFlags: ({{.*}}))))
701 ; INDEX-DAG: guid: [[Rec0]], {{.*}}, params: ((param: 0, offset: [2, 5])))))
702 ; INDEX-DAG: guid: [[Rec2]], {{.*}}, params: ((param: 0, offset: [-2, 1])))))
703 ; INDEX-DAG: guid: [[Write4]], {{.*}}, params: ((param: 0, offset: [0, 3])))))
704 ; INDEX-DAG: guid: [[Write1SameModule]], {{.*}}, params: ((param: 0, offset: [0, 0])))))
705 ; INDEX-DAG: guid: [[Write8]], {{.*}}, params: ((param: 0, offset: [0, 7])))))
706 ; INDEX-DAG: guid: [[Write4_2]], {{.*}}, params: ((param: 0, offset: [0, 3]), (param: 1, offset: [0, 3])))))
707 ; INDEX-DAG: guid: [[RecursiveWithOffset]], {{.*}}, calls: ((callee: ^{{[0-9]+}})))))
708 ; INDEX-DAG: guid: [[Weak]], {{.*}}, funcFlags: ({{.*}}))))
709 ; INDEX-DAG: guid: [[Write1Private]], {{.*}}, params: ((param: 0, offset: [-1, -1])))))
710 ; INDEX-DAG: guid: [[InterposableWrite1]], {{.*}}, params: ((param: 0, offset: [0, 0])))))
711 ; INDEX-DAG: guid: [[Private]], {{.*}}, params: ((param: 0, offset: [-1, -1])))))
712 ; INDEX-DAG: guid: [[Rec1]], {{.*}}, params: ((param: 0, offset: [3, 6])))))
713 ; INDEX-DAG: guid: [[RecursiveNoOffset]], {{.*}}, params: ((param: 2, offset: [0, 3])))))
714 ; INDEX-DAG: guid: [[Write1Weak]], {{.*}}, calls: ((callee: ^{{[0-9]+}})))))
715 ; INDEX-DAG: guid: [[Write1]], {{.*}}, params: ((param: 0, offset: [0, 0])))))
716 ; INDEX-DAG: guid: [[PreemptableWrite1]], {{.*}}, funcFlags: ({{.*}}))))
717 ; INDEX-DAG: guid: [[WriteAndReturn8]], {{.*}}, funcFlags: ({{.*}}))))
718 ; INDEX-DAG: guid: [[Write1DiffModule]], {{.*}}, funcFlags: ({{.*}}))))
719 ; INDEX-DAG: guid: [[ReturnAlloca]], {{.*}}, insts: 2)))
720 ; INDEX-LABEL: blockcount: