1; RUN: opt -S -passes="print<stack-safety-local>" -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,LOCAL
2; RUN: opt -S -passes="print-stack-safety" -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,GLOBAL
3
4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5target triple = "x86_64-unknown-linux-gnu"
6
7@sink = global i8* null, align 8
8
9declare void @llvm.memset.p0i8.i32(i8* %dest, i8 %val, i32 %len, i1 %isvolatile)
10declare void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 %isvolatile)
11declare void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 %isvolatile)
12declare void @llvm.memset.p0i8.i64(i8* %dest, i8 %val, i64 %len, i1 %isvolatile)
13
14declare void @unknown_call(i8* %dest)
15declare i8* @retptr(i8* returned)
16
17; Address leaked.
18define void @LeakAddress() {
19; CHECK-LABEL: @LeakAddress dso_preemptable{{$}}
20; CHECK-NEXT: args uses:
21; CHECK-NEXT: allocas uses:
22; CHECK-NEXT: x[4]: full-set{{$}}
23; GLOBAL-NEXT: safe accesses:
24; CHECK-EMPTY:
25entry:
26  %x = alloca i32, align 4
27  %x1 = bitcast i32* %x to i8*
28  store i8* %x1, i8** @sink, align 8
29  ret void
30}
31
32define void @StoreInBounds() {
33; CHECK-LABEL: @StoreInBounds dso_preemptable{{$}}
34; CHECK-NEXT: args uses:
35; CHECK-NEXT: allocas uses:
36; CHECK-NEXT: x[4]: [0,1){{$}}
37; GLOBAL-NEXT: safe accesses:
38; GLOBAL-NEXT: store i8 0, i8* %x1, align 1
39; CHECK-EMPTY:
40entry:
41  %x = alloca i32, align 4
42  %x1 = bitcast i32* %x to i8*
43  store i8 0, i8* %x1, align 1
44  ret void
45}
46
47define void @StoreInBounds2() {
48; CHECK-LABEL: @StoreInBounds2 dso_preemptable{{$}}
49; CHECK-NEXT: args uses:
50; CHECK-NEXT: allocas uses:
51; CHECK-NEXT: x[4]: [0,4){{$}}
52; GLOBAL-NEXT: safe accesses:
53; GLOBAL-NEXT: store i32 0, i32* %x, align 4
54; CHECK-EMPTY:
55entry:
56  %x = alloca i32, align 4
57  store i32 0, i32* %x, align 4
58  ret void
59}
60
61define void @StoreInBounds3() {
62; CHECK-LABEL: @StoreInBounds3 dso_preemptable{{$}}
63; CHECK-NEXT: args uses:
64; CHECK-NEXT: allocas uses:
65; CHECK-NEXT: x[4]: [2,3){{$}}
66; GLOBAL-NEXT: safe accesses:
67; GLOBAL-NEXT: store i8 0, i8* %x2, align 1
68; CHECK-EMPTY:
69entry:
70  %x = alloca i32, align 4
71  %x1 = bitcast i32* %x to i8*
72  %x2 = getelementptr i8, i8* %x1, i64 2
73  store i8 0, i8* %x2, align 1
74  ret void
75}
76
77; FIXME: ScalarEvolution does not look through ptrtoint/inttoptr.
78define void @StoreInBounds4() {
79; CHECK-LABEL: @StoreInBounds4 dso_preemptable{{$}}
80; CHECK-NEXT: args uses:
81; CHECK-NEXT: allocas uses:
82; CHECK-NEXT: x[4]: full-set{{$}}
83; GLOBAL-NEXT: safe accesses:
84; CHECK-EMPTY:
85entry:
86  %x = alloca i32, align 4
87  %x1 = ptrtoint i32* %x to i64
88  %x2 = add i64 %x1, 2
89  %x3 = inttoptr i64 %x2 to i8*
90  store i8 0, i8* %x3, align 1
91  ret void
92}
93
94define void @StoreInBounds6() {
95; CHECK-LABEL: @StoreInBounds6 dso_preemptable{{$}}
96; CHECK-NEXT: args uses:
97; CHECK-NEXT: allocas uses:
98; GLOBAL-NEXT: x[4]: full-set, @retptr(arg0, [0,1)){{$}}
99; LOCAL-NEXT: x[4]: [0,1), @retptr(arg0, [0,1)){{$}}
100; GLOBAL-NEXT: safe accesses:
101; GLOBAL-NEXT: store i8 0, i8* %x2, align 1
102; CHECK-EMPTY:
103entry:
104  %x = alloca i32, align 4
105  %x1 = bitcast i32* %x to i8*
106  %x2 = call i8* @retptr(i8* %x1)
107  store i8 0, i8* %x2, align 1
108  ret void
109}
110
111define dso_local void @WriteMinMax(i8* %p) {
112; CHECK-LABEL: @WriteMinMax{{$}}
113; CHECK-NEXT: args uses:
114; CHECK-NEXT: p[]: full-set
115; CHECK-NEXT: allocas uses:
116; GLOBAL-NEXT: safe accesses:
117; GLOBAL-NEXT: store i8 0, i8* %p1, align 1
118; GLOBAL-NEXT: store i8 0, i8* %p2, align 1
119; CHECK-EMPTY:
120entry:
121  %p1 = getelementptr i8, i8* %p, i64 9223372036854775805
122  store i8 0, i8* %p1, align 1
123  %p2 = getelementptr i8, i8* %p, i64 -9223372036854775805
124  store i8 0, i8* %p2, align 1
125  ret void
126}
127
128define dso_local void @WriteMax(i8* %p) {
129; CHECK-LABEL: @WriteMax{{$}}
130; CHECK-NEXT: args uses:
131; CHECK-NEXT: p[]: [-9223372036854775807,9223372036854775806)
132; CHECK-NEXT: allocas uses:
133; GLOBAL-NEXT: safe accesses:
134; GLOBAL-NEXT: call void @llvm.memset.p0i8.i64(i8* %p, i8 1, i64 9223372036854775806, i1 false)
135; GLOBAL-NEXT: call void @llvm.memset.p0i8.i64(i8* %p2, i8 1, i64 9223372036854775806, i1 false)
136; CHECK-EMPTY:
137entry:
138  call void @llvm.memset.p0i8.i64(i8* %p, i8 1, i64 9223372036854775806, i1 0)
139  %p2 = getelementptr i8, i8* %p, i64 -9223372036854775807
140  call void @llvm.memset.p0i8.i64(i8* %p2, i8 1, i64 9223372036854775806, i1 0)
141  ret void
142}
143
144define void @StoreOutOfBounds() {
145; CHECK-LABEL: @StoreOutOfBounds dso_preemptable{{$}}
146; CHECK-NEXT: args uses:
147; CHECK-NEXT: allocas uses:
148; CHECK-NEXT: x[4]: [2,6){{$}}
149; GLOBAL-NEXT: safe accesses:
150; CHECK-EMPTY:
151entry:
152  %x = alloca i32, align 4
153  %x1 = bitcast i32* %x to i8*
154  %x2 = getelementptr i8, i8* %x1, i64 2
155  %x3 = bitcast i8* %x2 to i32*
156  store i32 0, i32* %x3, align 1
157  ret void
158}
159
160define void @StoreOutOfBounds2() {
161; CHECK-LABEL: @StoreOutOfBounds2 dso_preemptable{{$}}
162; CHECK-NEXT: args uses:
163; CHECK-NEXT: allocas uses:
164; GLOBAL-NEXT: x[4]: full-set, @retptr(arg0, [2,3)){{$}}
165; LOCAL-NEXT: x[4]: [2,6), @retptr(arg0, [2,3)){{$}}
166; GLOBAL-NEXT: safe accesses:
167; CHECK-EMPTY:
168entry:
169  %x = alloca i32, align 4
170  %x1 = bitcast i32* %x to i8*
171  %x2 = getelementptr i8, i8* %x1, i64 2
172  %x3 = call i8* @retptr(i8* %x2)
173  %x4 = bitcast i8* %x3 to i32*
174  store i32 0, i32* %x4, align 1
175  ret void
176}
177
178; There is no difference in load vs store handling.
179define void @LoadInBounds() {
180; CHECK-LABEL: @LoadInBounds dso_preemptable{{$}}
181; CHECK-NEXT: args uses:
182; CHECK-NEXT: allocas uses:
183; CHECK-NEXT: x[4]: [0,1){{$}}
184; GLOBAL-NEXT: safe accesses:
185; GLOBAL-NEXT: %v = load i8, i8* %x1, align 1
186; CHECK-EMPTY:
187entry:
188  %x = alloca i32, align 4
189  %x1 = bitcast i32* %x to i8*
190  %v = load i8, i8* %x1, align 1
191  ret void
192}
193
194define void @LoadOutOfBounds() {
195; CHECK-LABEL: @LoadOutOfBounds dso_preemptable{{$}}
196; CHECK-NEXT: args uses:
197; CHECK-NEXT: allocas uses:
198; CHECK-NEXT: x[4]: [2,6){{$}}
199; GLOBAL-NEXT: safe accesses:
200; CHECK-EMPTY:
201entry:
202  %x = alloca i32, align 4
203  %x1 = bitcast i32* %x to i8*
204  %x2 = getelementptr i8, i8* %x1, i64 2
205  %x3 = bitcast i8* %x2 to i32*
206  %v = load i32, i32* %x3, align 1
207  ret void
208}
209
210; Leak through ret.
211define i8* @Ret() {
212; CHECK-LABEL: @Ret dso_preemptable{{$}}
213; CHECK-NEXT: args uses:
214; CHECK-NEXT: allocas uses:
215; CHECK-NEXT: x[4]: full-set{{$}}
216; GLOBAL-NEXT: safe accesses:
217; CHECK-EMPTY:
218entry:
219  %x = alloca i32, align 4
220  %x1 = bitcast i32* %x to i8*
221  %x2 = getelementptr i8, i8* %x1, i64 2
222  ret i8* %x2
223}
224
225declare void @Foo(i16* %p)
226
227define void @DirectCall() {
228; CHECK-LABEL: @DirectCall dso_preemptable{{$}}
229; CHECK-NEXT: args uses:
230; CHECK-NEXT: allocas uses:
231; LOCAL-NEXT: x[8]: empty-set, @Foo(arg0, [2,3)){{$}}
232; GLOBAL-NEXT: x[8]: full-set, @Foo(arg0, [2,3)){{$}}
233; GLOBAL-NEXT: safe accesses:
234; CHECK-EMPTY:
235entry:
236  %x = alloca i64, align 4
237  %x1 = bitcast i64* %x to i16*
238  %x2 = getelementptr i16, i16* %x1, i64 1
239  call void @Foo(i16* %x2);
240  ret void
241}
242
243; Indirect calls can not be analyzed (yet).
244; FIXME: %p[]: full-set looks invalid
245define void @IndirectCall(void (i8*)* %p) {
246; CHECK-LABEL: @IndirectCall dso_preemptable{{$}}
247; CHECK-NEXT: args uses:
248; CHECK-NEXT: p[]: full-set{{$}}
249; CHECK-NEXT: allocas uses:
250; CHECK-NEXT: x[4]: full-set{{$}}
251; GLOBAL-NEXT: safe accesses:
252; CHECK-EMPTY:
253entry:
254  %x = alloca i32, align 4
255  %x1 = bitcast i32* %x to i8*
256  call void %p(i8* %x1);
257  ret void
258}
259
260define void @NonConstantOffset(i1 zeroext %z) {
261; CHECK-LABEL: @NonConstantOffset dso_preemptable{{$}}
262; CHECK-NEXT: args uses:
263; CHECK-NEXT: allocas uses:
264; FIXME: SCEV can't look through selects.
265; CHECK-NEXT: x[4]: [0,4){{$}}
266; GLOBAL-NEXT: safe accesses:
267; GLOBAL-NEXT: store i8 0, i8* %x2, align 1
268; CHECK-EMPTY:
269entry:
270  %x = alloca i32, align 4
271  %x1 = bitcast i32* %x to i8*
272  %idx = select i1 %z, i64 1, i64 2
273  %x2 = getelementptr i8, i8* %x1, i64 %idx
274  store i8 0, i8* %x2, align 1
275  ret void
276}
277
278define void @NegativeOffset() {
279; CHECK-LABEL: @NegativeOffset dso_preemptable{{$}}
280; CHECK-NEXT: args uses:
281; CHECK-NEXT: allocas uses:
282; CHECK-NEXT: x[40]: [-1600000000000,-1599999999996){{$}}
283; GLOBAL-NEXT: safe accesses:
284; CHECK-EMPTY:
285entry:
286  %x = alloca i32, i32 10, align 4
287  %x2 = getelementptr i32, i32* %x, i64 -400000000000
288  store i32 0, i32* %x2, align 1
289  ret void
290}
291
292define void @PossiblyNegativeOffset(i16 %z) {
293; CHECK-LABEL: @PossiblyNegativeOffset dso_preemptable{{$}}
294; CHECK-NEXT: args uses:
295; CHECK-NEXT: allocas uses:
296; CHECK-NEXT: x[40]: [-131072,131072){{$}}
297; GLOBAL-NEXT: safe accesses:
298; CHECK-EMPTY:
299entry:
300  %x = alloca i32, i32 10, align 4
301  %x2 = getelementptr i32, i32* %x, i16 %z
302  store i32 0, i32* %x2, align 1
303  ret void
304}
305
306define void @NonConstantOffsetOOB(i1 zeroext %z) {
307; CHECK-LABEL: @NonConstantOffsetOOB dso_preemptable{{$}}
308; CHECK-NEXT: args uses:
309; CHECK-NEXT: allocas uses:
310; CHECK-NEXT: x[4]: [0,6){{$}}
311; GLOBAL-NEXT: safe accesses:
312; CHECK-EMPTY:
313entry:
314  %x = alloca i32, align 4
315  %x1 = bitcast i32* %x to i8*
316  %idx = select i1 %z, i64 1, i64 4
317  %x2 = getelementptr i8, i8* %x1, i64 %idx
318  store i8 0, i8* %x2, align 1
319  ret void
320}
321
322define void @ArrayAlloca() {
323; CHECK-LABEL: @ArrayAlloca dso_preemptable{{$}}
324; CHECK-NEXT: args uses:
325; CHECK-NEXT: allocas uses:
326; CHECK-NEXT: x[40]: [36,40){{$}}
327; GLOBAL-NEXT: safe accesses:
328; GLOBAL-NEXT: store i32 0, i32* %x3, align 1
329; CHECK-EMPTY:
330entry:
331  %x = alloca i32, i32 10, align 4
332  %x1 = bitcast i32* %x to i8*
333  %x2 = getelementptr i8, i8* %x1, i64 36
334  %x3 = bitcast i8* %x2 to i32*
335  store i32 0, i32* %x3, align 1
336  ret void
337}
338
339define void @ArrayAllocaOOB() {
340; CHECK-LABEL: @ArrayAllocaOOB dso_preemptable{{$}}
341; CHECK-NEXT: args uses:
342; CHECK-NEXT: allocas uses:
343; CHECK-NEXT: x[40]: [37,41){{$}}
344; GLOBAL-NEXT: safe accesses:
345; CHECK-EMPTY:
346entry:
347  %x = alloca i32, i32 10, align 4
348  %x1 = bitcast i32* %x to i8*
349  %x2 = getelementptr i8, i8* %x1, i64 37
350  %x3 = bitcast i8* %x2 to i32*
351  store i32 0, i32* %x3, align 1
352  ret void
353}
354
355define void @DynamicAllocaUnused(i64 %size) {
356; CHECK-LABEL: @DynamicAllocaUnused dso_preemptable{{$}}
357; CHECK-NEXT: args uses:
358; CHECK-NEXT: allocas uses:
359; CHECK-NEXT: x[0]: empty-set{{$}}
360; GLOBAL-NEXT: safe accesses:
361; CHECK-EMPTY:
362entry:
363  %x = alloca i32, i64 %size, align 16
364  ret void
365}
366
367; Dynamic alloca with unknown size.
368define void @DynamicAlloca(i64 %size) {
369; CHECK-LABEL: @DynamicAlloca dso_preemptable{{$}}
370; CHECK-NEXT: args uses:
371; CHECK-NEXT: allocas uses:
372; CHECK-NEXT: x[0]: [0,4){{$}}
373; GLOBAL-NEXT: safe accesses:
374; CHECK-EMPTY:
375entry:
376  %x = alloca i32, i64 %size, align 16
377  store i32 0, i32* %x, align 1
378  ret void
379}
380
381; Dynamic alloca with limited size.
382; FIXME: could be proved safe. Implement.
383define void @DynamicAllocaFiniteSizeRange(i1 zeroext %z) {
384; CHECK-LABEL: @DynamicAllocaFiniteSizeRange dso_preemptable{{$}}
385; CHECK-NEXT: args uses:
386; CHECK-NEXT: allocas uses:
387; CHECK-NEXT: x[0]: [0,4){{$}}
388; GLOBAL-NEXT: safe accesses:
389; CHECK-EMPTY:
390entry:
391  %size = select i1 %z, i64 3, i64 5
392  %x = alloca i32, i64 %size, align 16
393  store i32 0, i32* %x, align 1
394  ret void
395}
396
397define signext i8 @SimpleLoop() {
398; CHECK-LABEL: @SimpleLoop dso_preemptable{{$}}
399; CHECK-NEXT: args uses:
400; CHECK-NEXT: allocas uses:
401; CHECK-NEXT: x[10]: [0,10){{$}}
402; GLOBAL-NEXT: safe accesses:
403; GLOBAL-NEXT: %1 = load volatile i8, i8* %p.09, align 1
404; CHECK-EMPTY:
405entry:
406  %x = alloca [10 x i8], align 1
407  %0 = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 0
408  %lftr.limit = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 10
409  br label %for.body
410
411for.body:
412  %sum.010 = phi i8 [ 0, %entry ], [ %add, %for.body ]
413  %p.09 = phi i8* [ %0, %entry ], [ %incdec.ptr, %for.body ]
414  %incdec.ptr = getelementptr inbounds i8, i8* %p.09, i64 1
415  %1 = load volatile i8, i8* %p.09, align 1
416  %add = add i8 %1, %sum.010
417  %exitcond = icmp eq i8* %incdec.ptr, %lftr.limit
418  br i1 %exitcond, label %for.cond.cleanup, label %for.body
419
420for.cond.cleanup:
421  ret i8 %add
422}
423
424; OOB in a loop.
425define signext i8 @SimpleLoopOOB() {
426; CHECK-LABEL: @SimpleLoopOOB dso_preemptable{{$}}
427; CHECK-NEXT: args uses:
428; CHECK-NEXT: allocas uses:
429; CHECK-NEXT: x[10]: [0,11){{$}}
430; GLOBAL-NEXT: safe accesses:
431; CHECK-EMPTY:
432entry:
433  %x = alloca [10 x i8], align 1
434  %0 = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 0
435 ; 11 iterations
436  %lftr.limit = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 11
437  br label %for.body
438
439for.body:
440  %sum.010 = phi i8 [ 0, %entry ], [ %add, %for.body ]
441  %p.09 = phi i8* [ %0, %entry ], [ %incdec.ptr, %for.body ]
442  %incdec.ptr = getelementptr inbounds i8, i8* %p.09, i64 1
443  %1 = load volatile i8, i8* %p.09, align 1
444  %add = add i8 %1, %sum.010
445  %exitcond = icmp eq i8* %incdec.ptr, %lftr.limit
446  br i1 %exitcond, label %for.cond.cleanup, label %for.body
447
448for.cond.cleanup:
449  ret i8 %add
450}
451
452define dso_local void @SizeCheck(i32 %sz) {
453; CHECK-LABEL: @SizeCheck{{$}}
454; CHECK-NEXT: args uses:
455; CHECK-NEXT: allocas uses:
456; CHECK-NEXT: x1[128]: [0,4294967295){{$}}
457; GLOBAL-NEXT: safe accesses:
458; CHECK-EMPTY:
459entry:
460  %x1 = alloca [128 x i8], align 16
461  %x1.sub = getelementptr inbounds [128 x i8], [128 x i8]* %x1, i64 0, i64 0
462  %cmp = icmp slt i32 %sz, 129
463  br i1 %cmp, label %if.then, label %if.end
464
465if.then:
466  call void @llvm.memset.p0i8.i32(i8* nonnull align 16 %x1.sub, i8 0, i32 %sz, i1 false)
467  br label %if.end
468
469if.end:
470  ret void
471}
472
473; FIXME: scalable allocas are considered to be of size zero, and scalable accesses to be full-range.
474; This effectively disables safety analysis for scalable allocations.
475define void @Scalable(<vscale x 4 x i32>* %p, <vscale x 4 x i32>* %unused, <vscale x 4 x i32> %v) {
476; CHECK-LABEL: @Scalable dso_preemptable{{$}}
477; CHECK-NEXT: args uses:
478; CHECK-NEXT:   p[]: full-set
479; CHECK-NEXT:   unused[]: empty-set
480; CHECK-NEXT: allocas uses:
481; CHECK-NEXT:   x[0]: [0,1){{$}}
482; GLOBAL-NEXT: safe accesses:
483; GLOBAL-NEXT: store <vscale x 4 x i32> %v, <vscale x 4 x i32>* %p, align 4
484; CHECK-EMPTY:
485entry:
486  %x = alloca <vscale x 4 x i32>, align 4
487  %x1 = bitcast <vscale x 4 x i32>* %x to i8*
488  store i8 0, i8* %x1, align 1
489  store <vscale x 4 x i32> %v, <vscale x 4 x i32>* %p, align 4
490  ret void
491}
492
493%zerosize_type = type {}
494
495define void @ZeroSize(%zerosize_type *%p)  {
496; CHECK-LABEL: @ZeroSize dso_preemptable{{$}}
497; CHECK-NEXT: args uses:
498; CHECK-NEXT:   p[]: empty-set
499; CHECK-NEXT: allocas uses:
500; CHECK-NEXT:   x[0]: empty-set
501; GLOBAL-NEXT: safe accesses:
502; GLOBAL-NEXT: store %zerosize_type undef, %zerosize_type* %x, align 4
503; GLOBAL-NEXT: store %zerosize_type undef, %zerosize_type* undef, align 4
504; GLOBAL-NEXT: load %zerosize_type, %zerosize_type* %p, align
505; CHECK-EMPTY:
506entry:
507  %x = alloca %zerosize_type, align 4
508  store %zerosize_type undef, %zerosize_type* %x, align 4
509  store %zerosize_type undef, %zerosize_type* undef, align 4
510  %val = load %zerosize_type, %zerosize_type* %p, align 4
511  ret void
512}
513
514define void @OperandBundle() {
515; CHECK-LABEL: @OperandBundle dso_preemptable{{$}}
516; CHECK-NEXT: args uses:
517; CHECK-NEXT: allocas uses:
518; CHECK-NEXT:   a[4]: full-set
519; GLOBAL-NEXT: safe accesses:
520; CHECK-EMPTY:
521entry:
522  %a = alloca i32, align 4
523  call void @LeakAddress() ["unknown"(i32* %a)]
524  ret void
525}
526
527define void @ByVal(i16* byval(i16) %p) {
528  ; CHECK-LABEL: @ByVal dso_preemptable{{$}}
529  ; CHECK-NEXT: args uses:
530  ; CHECK-NEXT: allocas uses:
531  ; GLOBAL-NEXT: safe accesses:
532  ; CHECK-EMPTY:
533entry:
534  ret void
535}
536
537define void @TestByVal() {
538; CHECK-LABEL: @TestByVal dso_preemptable{{$}}
539; CHECK-NEXT: args uses:
540; CHECK-NEXT: allocas uses:
541; CHECK-NEXT: x[2]: [0,2)
542; CHECK-NEXT: y[8]: [0,2)
543; GLOBAL-NEXT: safe accesses:
544; GLOBAL-NEXT: call void @ByVal(i16* byval(i16) %x)
545; GLOBAL-NEXT: call void @ByVal(i16* byval(i16) %y1)
546; CHECK-EMPTY:
547entry:
548  %x = alloca i16, align 4
549  call void @ByVal(i16* byval(i16) %x)
550
551  %y = alloca i64, align 4
552  %y1 = bitcast i64* %y to i16*
553  call void @ByVal(i16* byval(i16) %y1)
554
555  ret void
556}
557
558declare void @ByValArray([100000 x i64]* byval([100000 x i64]) %p)
559
560define void @TestByValArray() {
561; CHECK-LABEL: @TestByValArray dso_preemptable{{$}}
562; CHECK-NEXT: args uses:
563; CHECK-NEXT: allocas uses:
564; CHECK-NEXT: z[800000]: [500000,1300000)
565; GLOBAL-NEXT: safe accesses:
566; CHECK-EMPTY:
567entry:
568  %z = alloca [100000 x i64], align 4
569  %z1 = bitcast [100000 x i64]* %z to i8*
570  %z2 = getelementptr i8, i8* %z1, i64 500000
571  %z3 = bitcast i8* %z2 to [100000 x i64]*
572  call void @ByValArray([100000 x i64]* byval([100000 x i64]) %z3)
573  ret void
574}
575
576define dso_local i8 @LoadMinInt64(i8* %p) {
577  ; CHECK-LABEL: @LoadMinInt64{{$}}
578  ; CHECK-NEXT: args uses:
579  ; CHECK-NEXT: p[]: [-9223372036854775808,-9223372036854775807){{$}}
580  ; CHECK-NEXT: allocas uses:
581  ; GLOBAL-NEXT: safe accesses:
582  ; GLOBAL-NEXT: load i8, i8* %p2, align 1
583  ; CHECK-EMPTY:
584  %p2 = getelementptr i8, i8* %p, i64 -9223372036854775808
585  %v = load i8, i8* %p2, align 1
586  ret i8 %v
587}
588
589define void @Overflow() {
590; CHECK-LABEL: @Overflow dso_preemptable{{$}}
591; CHECK-NEXT: args uses:
592; CHECK-NEXT: allocas uses:
593; LOCAL-NEXT: x[1]: empty-set, @LoadMinInt64(arg0, [-9223372036854775808,-9223372036854775807)){{$}}
594; GLOBAL-NEXT: x[1]: full-set, @LoadMinInt64(arg0, [-9223372036854775808,-9223372036854775807)){{$}}
595; GLOBAL-NEXT: safe accesses:
596; CHECK-EMPTY:
597entry:
598  %x = alloca i8, align 4
599  %x2 = getelementptr i8, i8* %x, i64 -9223372036854775808
600  %v = call i8 @LoadMinInt64(i8* %x2)
601  ret void
602}
603
604define void @DeadBlock(i64* %p) {
605; CHECK-LABEL: @DeadBlock dso_preemptable{{$}}
606; CHECK-NEXT: args uses:
607; CHECK-NEXT: p[]: empty-set{{$}}
608; CHECK-NEXT: allocas uses:
609; CHECK-NEXT: x[1]: empty-set{{$}}
610; GLOBAL-NEXT: safe accesses:
611; GLOBAL-NEXT: store i8 5, i8* %x
612; GLOBAL-NEXT: store i64 -5, i64* %p
613; CHECK-EMPTY:
614entry:
615  %x = alloca i8, align 4
616  br label %end
617
618dead:
619  store i8 5, i8* %x
620  store i64 -5, i64* %p
621  br label %end
622
623end:
624  ret void
625}
626
627define void @LifeNotStarted() {
628; CHECK-LABEL: @LifeNotStarted dso_preemptable{{$}}
629; CHECK-NEXT: args uses:
630; CHECK-NEXT: allocas uses:
631; CHECK: x[1]: full-set{{$}}
632; CHECK: y[1]: full-set{{$}}
633; CHECK: z[1]: full-set{{$}}
634; GLOBAL-NEXT: safe accesses:
635; CHECK-EMPTY:
636entry:
637  %x = alloca i8, align 4
638  %y = alloca i8, align 4
639  %z = alloca i8, align 4
640
641  store i8 5, i8* %x
642  %n = load i8, i8* %y
643  call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false)
644
645  call void @llvm.lifetime.start.p0i8(i64 1, i8* %x)
646  call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
647  call void @llvm.lifetime.start.p0i8(i64 1, i8* %z)
648
649  ret void
650}
651
652define void @LifeOK() {
653; CHECK-LABEL: @LifeOK dso_preemptable{{$}}
654; CHECK-NEXT: args uses:
655; CHECK-NEXT: allocas uses:
656; CHECK: x[1]: [0,1){{$}}
657; CHECK: y[1]: [0,1){{$}}
658; CHECK: z[1]: [0,1){{$}}
659; GLOBAL-NEXT: safe accesses:
660; GLOBAL-NEXT: store i8 5, i8* %x
661; GLOBAL-NEXT: %n = load i8, i8* %y
662; GLOBAL-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false)
663; CHECK-EMPTY:
664entry:
665  %x = alloca i8, align 4
666  %y = alloca i8, align 4
667  %z = alloca i8, align 4
668
669  call void @llvm.lifetime.start.p0i8(i64 1, i8* %x)
670  call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
671  call void @llvm.lifetime.start.p0i8(i64 1, i8* %z)
672
673  store i8 5, i8* %x
674  %n = load i8, i8* %y
675  call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false)
676
677  ret void
678}
679
680define void @LifeEnded() {
681; CHECK-LABEL: @LifeEnded dso_preemptable{{$}}
682; CHECK-NEXT: args uses:
683; CHECK-NEXT: allocas uses:
684; CHECK: x[1]: full-set{{$}}
685; CHECK: y[1]: full-set{{$}}
686; CHECK: z[1]: full-set{{$}}
687; GLOBAL-NEXT: safe accesses:
688; CHECK-EMPTY:
689entry:
690  %x = alloca i8, align 4
691  %y = alloca i8, align 4
692  %z = alloca i8, align 4
693
694  call void @llvm.lifetime.start.p0i8(i64 1, i8* %x)
695  call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
696  call void @llvm.lifetime.start.p0i8(i64 1, i8* %z)
697
698  call void @llvm.lifetime.end.p0i8(i64 1, i8* %x)
699  call void @llvm.lifetime.end.p0i8(i64 1, i8* %y)
700  call void @llvm.lifetime.end.p0i8(i64 1, i8* %z)
701
702  store i8 5, i8* %x
703  %n = load i8, i8* %y
704  call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false)
705
706  ret void
707}
708
709define void @TwoAllocasOK() {
710; CHECK-LABEL: @TwoAllocasOK
711; CHECK-NEXT: args uses:
712; CHECK-NEXT: allocas uses:
713; CHECK: a[4]: [0,1){{$}}
714; CHECK: y[1]: [0,1){{$}}
715; GLOBAL-NEXT: safe accesses:
716; GLOBAL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %y, i8* %x, i32 1, i1 false)
717; CHECK-EMPTY:
718entry:
719  %a = alloca i32, align 4
720  %x = bitcast i32* %a to i8*
721  %y = alloca i8, align 4
722  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %y, i8* %x, i32 1, i1 false)
723  ret void
724}
725
726define void @TwoAllocasOOBDest() {
727; CHECK-LABEL: @TwoAllocasOOBDest
728; CHECK-NEXT: args uses:
729; CHECK-NEXT: allocas uses:
730; CHECK: a[4]: [0,4){{$}}
731; CHECK: y[1]: [0,4){{$}}
732; GLOBAL-NEXT: safe accesses:
733; CHECK-EMPTY:
734entry:
735  %a = alloca i32, align 4
736  %x = bitcast i32* %a to i8*
737  %y = alloca i8, align 4
738  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %y, i8* %x, i32 4, i1 false)
739  ret void
740}
741
742define void @TwoAllocasOOBSource() {
743; CHECK-LABEL: @TwoAllocasOOBSource
744; CHECK-NEXT: args uses:
745; CHECK-NEXT: allocas uses:
746; CHECK: a[4]: [0,4){{$}}
747; CHECK: y[1]: [0,4){{$}}
748; GLOBAL-NEXT: safe accesses:
749; CHECK-EMPTY:
750entry:
751  %a = alloca i32, align 4
752  %x = bitcast i32* %a to i8*
753  %y = alloca i8, align 4
754  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x, i8* %y, i32 4, i1 false)
755  ret void
756}
757
758define void @TwoAllocasOOBBoth() {
759; CHECK-LABEL: @TwoAllocasOOBBoth
760; CHECK-NEXT: args uses:
761; CHECK-NEXT: allocas uses:
762; CHECK: a[4]: [0,5){{$}}
763; CHECK: y[1]: [0,5){{$}}
764; GLOBAL-NEXT: safe accesses:
765; CHECK-EMPTY:
766entry:
767  %a = alloca i32, align 4
768  %x = bitcast i32* %a to i8*
769  %y = alloca i8, align 4
770  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %y, i8* %x, i32 5, i1 false)
771  ret void
772}
773
774define void @MixedAccesses() {
775; CHECK-LABEL: @MixedAccesses
776; CHECK-NEXT: args uses:
777; CHECK-NEXT: allocas uses:
778; CHECK: a[4]: [0,5){{$}}
779; GLOBAL-NEXT: safe accesses:
780; GLOBAL-NEXT: call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false)
781; CHECK-EMPTY:
782entry:
783  %a = alloca i32, align 4
784  %x = bitcast i32* %a to i8*
785  call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 5, i1 false)
786  call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false)
787  ret void
788}
789
790define void @MixedAccesses2() {
791; CHECK-LABEL: @MixedAccesses2
792; CHECK-NEXT: args uses:
793; CHECK-NEXT: allocas uses:
794; CHECK: a[4]: [0,8){{$}}
795; GLOBAL-NEXT: safe accesses:
796; GLOBAL-NEXT: load i32, i32* %a, align 4
797; CHECK-EMPTY:
798entry:
799  %a = alloca i32, align 4
800  %a1 = bitcast i32* %a to i64*
801  %n1 = load i64, i64* %a1, align 4
802  %n2 = load i32, i32* %a, align 4
803  ret void
804}
805
806define void @MixedAccesses3(void (i8*)* %func) {
807; CHECK-LABEL: @MixedAccesses3
808; CHECK-NEXT: args uses:
809; CHECK-NEXT: func[]: full-set
810; CHECK-NEXT: allocas uses:
811; CHECK: a[4]: full-set{{$}}
812; GLOBAL-NEXT: safe accesses:
813; GLOBAL-NEXT: load i32, i32* %a, align 4
814; CHECK-EMPTY:
815entry:
816  %a = alloca i32, align 4
817  %x = bitcast i32* %a to i8*
818  %n2 = load i32, i32* %a, align 4
819  call void %func(i8* %x)
820  ret void
821}
822
823define void @MixedAccesses4() {
824; CHECK-LABEL: @MixedAccesses4
825; CHECK-NEXT: args uses:
826; CHECK-NEXT: allocas uses:
827; CHECK: a[4]: full-set{{$}}
828; CHECK: a1[8]: [0,8){{$}}
829; GLOBAL-NEXT: safe accesses:
830; GLOBAL-NEXT: load i32, i32* %a, align 4
831; CHECK-EMPTY:
832entry:
833  %a = alloca i32, align 4
834  %a1 = alloca i32*, align 4
835  %n2 = load i32, i32* %a, align 4
836  store i32* %a, i32** %a1
837  ret void
838}
839
840define i32* @MixedAccesses5(i1 %x, i32* %y) {
841; CHECK-LABEL: @MixedAccesses5
842; CHECK-NEXT: args uses:
843; CHECK: y[]: full-set
844; CHECK-NEXT: allocas uses:
845; CHECK: a[4]: full-set{{$}}
846; GLOBAL-NEXT: safe accesses:
847; GLOBAL-NEXT: load i32, i32* %a, align 4
848; CHECK-EMPTY:
849entry:
850  %a = alloca i32, align 4
851  br i1 %x, label %tlabel, label %flabel
852flabel:
853  %n = load i32, i32* %a, align 4
854  ret i32* %y
855tlabel:
856  ret i32* %a
857}
858
859define void @MixedAccesses6(i8* %arg) {
860; CHECK-LABEL: @MixedAccesses6
861; CHECK-NEXT: args uses:
862; CHECK-NEXT: arg[]: [0,4)
863; CHECK-NEXT: allocas uses:
864; CHECK: a[4]: [0,4)
865; GLOBAL-NEXT: safe accesses:
866; GLOBAL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x, i8* %arg, i32 4, i1 false)
867; CHECK-EMPTY:
868entry:
869  %a = alloca i32, align 4
870  %x = bitcast i32* %a to i8*
871  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x, i8* %arg, i32 4, i1 false)
872  ret void
873}
874
875define void @MixedAccesses7(i1 %cond, i8* %arg) {
876; SECV doesn't support select, so we consider this non-stack-safe, even through
877; it is.
878;
879; CHECK-LABEL: @MixedAccesses7
880; CHECK-NEXT: args uses:
881; CHECK-NEXT: arg[]: full-set
882; CHECK-NEXT: allocas uses:
883; CHECK: a[4]: full-set
884; GLOBAL-NEXT: safe accesses:
885; CHECK-EMPTY:
886entry:
887  %a = alloca i32, align 4
888  %x = bitcast i32* %a to i8*
889  %x1 = select i1 %cond, i8* %arg, i8* %x
890  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %arg, i32 4, i1 false)
891  ret void
892}
893
894define void @NoStackAccess(i8* %arg1, i8* %arg2) {
895; CHECK-LABEL: @NoStackAccess
896; CHECK-NEXT: args uses:
897; CHECK-NEXT: arg1[]: [0,4)
898; CHECK-NEXT: arg2[]: [0,4)
899; CHECK-NEXT: allocas uses:
900; CHECK: a[4]: empty-set{{$}}
901; GLOBAL-NEXT: safe accesses:
902; GLOBAL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %arg1, i8* %arg2, i32 4, i1 false)
903; CHECK-EMPTY:
904entry:
905  %a = alloca i32, align 4
906  %x = bitcast i32* %a to i8*
907  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %arg1, i8* %arg2, i32 4, i1 false)
908  ret void
909}
910
911define void @DoubleLifetime() {
912; CHECK-LABEL: @DoubleLifetime
913; CHECK-NEXT: args uses:
914; CHECK-NEXT: allocas uses:
915; CHECK: a[4]: full-set{{$}}
916; GLOBAL-NEXT: safe accesses:
917; GLOBAL-NEXT: call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false)
918; CHECK-EMPTY:
919entry:
920  %a = alloca i32, align 4
921  %x = bitcast i32* %a to i8*
922  call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
923  call void @llvm.lifetime.end.p0i8(i64 4, i8* %x)
924  call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 true)
925
926  call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
927  call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false)
928  call void @llvm.lifetime.end.p0i8(i64 4, i8* %x)
929  ret void
930}
931
932define void @DoubleLifetime2() {
933; CHECK-LABEL: @DoubleLifetime2
934; CHECK-NEXT: args uses:
935; CHECK-NEXT: allocas uses:
936; CHECK: a[4]: full-set{{$}}
937; GLOBAL-NEXT: safe accesses:
938; GLOBAL-NEXT: call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false)
939; CHECK-EMPTY:
940entry:
941  %a = alloca i32, align 4
942  %x = bitcast i32* %a to i8*
943  call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
944  call void @llvm.lifetime.end.p0i8(i64 4, i8* %x)
945  %n = load i32, i32* %a
946
947  call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
948  call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false)
949  call void @llvm.lifetime.end.p0i8(i64 4, i8* %x)
950  ret void
951}
952
953define void @DoubleLifetime3() {
954; CHECK-LABEL: @DoubleLifetime3
955; CHECK-NEXT: args uses:
956; CHECK-NEXT: allocas uses:
957; CHECK: a[4]: full-set{{$}}
958; GLOBAL-NEXT: safe accesses:
959; GLOBAL-NEXT: call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false)
960; CHECK-EMPTY:
961entry:
962  %a = alloca i32, align 4
963  %x = bitcast i32* %a to i8*
964  call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
965  call void @llvm.lifetime.end.p0i8(i64 4, i8* %x)
966  store i32 5, i32* %a
967
968  call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
969  call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false)
970  call void @llvm.lifetime.end.p0i8(i64 4, i8* %x)
971  ret void
972}
973
974define void @DoubleLifetime4() {
975; CHECK-LABEL: @DoubleLifetime4
976; CHECK-NEXT: args uses:
977; CHECK-NEXT: allocas uses:
978; CHECK: a[4]: full-set{{$}}
979; GLOBAL-NEXT: safe accesses:
980; GLOBAL-NEXT: call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false)
981; CHECK-EMPTY:
982entry:
983  %a = alloca i32, align 4
984  %x = bitcast i32* %a to i8*
985  call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
986  call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false)
987  call void @llvm.lifetime.end.p0i8(i64 4, i8* %x)
988  call void @unknown_call(i8* %x)
989  ret void
990}
991
992declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
993declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
994