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