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
4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5 target triple = "x86_64-unknown-linux-gnu"
7 @sink = global i8* null, align 8
9 declare void @llvm.memset.p0i8.i32(i8* %dest, i8 %val, i32 %len, i1 %isvolatile)
10 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 %isvolatile)
11 declare void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 %isvolatile)
12 declare void @llvm.memset.p0i8.i64(i8* %dest, i8 %val, i64 %len, i1 %isvolatile)
14 declare void @unknown_call(i8* %dest)
15 declare i8* @retptr(i8* returned)
18 define 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:
26 %x = alloca i32, align 4
27 %x1 = bitcast i32* %x to i8*
28 store i8* %x1, i8** @sink, align 8
32 define 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
41 %x = alloca i32, align 4
42 %x1 = bitcast i32* %x to i8*
43 store i8 0, i8* %x1, align 1
47 define 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
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
63 br i1 %c2, label %c2.true, label %false
66 %x2 = getelementptr i8, i8* %x1, i64 %i
67 store i8 0, i8* %x2, align 1
74 define 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
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
94 define 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
103 %x = alloca i32, align 4
104 store i32 0, i32* %x, align 4
108 define 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
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
124 ; FIXME: ScalarEvolution does not look through ptrtoint/inttoptr.
125 define 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:
133 %x = alloca i32, align 4
134 %x1 = ptrtoint i32* %x to i64
136 %x3 = inttoptr i64 %x2 to i8*
137 store i8 0, i8* %x3, align 1
141 define 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
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
158 define 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
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
175 define 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)
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)
191 define 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:
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
207 define 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:
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
222 br i1 %c2, label %c2.true, label %false
225 %x2 = getelementptr i8, i8* %x1, i64 %i
226 store i8 0, i8* %x2, align 1
233 define 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:
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
247 %x2 = getelementptr i8, i8* %x1, i64 %i
248 store i8 0, i8* %x2, align 1
255 define 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:
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
273 ; There is no difference in load vs store handling.
274 define 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
283 %x = alloca i32, align 4
284 %x1 = bitcast i32* %x to i8*
285 %v = load i8, i8* %x1, align 1
289 define 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:
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
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:
314 %x = alloca i32, align 4
315 %x1 = bitcast i32* %x to i8*
316 %x2 = getelementptr i8, i8* %x1, i64 2
320 declare void @Foo(i16* %p)
322 define 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:
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);
338 ; Indirect calls can not be analyzed (yet).
339 ; FIXME: %p[]: full-set looks invalid
340 define 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:
349 %x = alloca i32, align 4
350 %x1 = bitcast i32* %x to i8*
351 call void %p(i8* %x1);
355 define 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
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
373 define 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:
381 %x = alloca i32, i32 10, align 4
382 %x2 = getelementptr i32, i32* %x, i64 -400000000000
383 store i32 0, i32* %x2, align 1
387 define 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:
395 %x = alloca i32, i32 10, align 4
396 %x2 = getelementptr i32, i32* %x, i16 %z
397 store i32 0, i32* %x2, align 1
401 define 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:
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
417 define 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
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
434 define 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:
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
450 define 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:
458 %x = alloca i32, i64 %size, align 16
462 ; Dynamic alloca with unknown size.
463 define 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:
471 %x = alloca i32, i64 %size, align 16
472 store i32 0, i32* %x, align 1
476 ; Dynamic alloca with limited size.
477 ; FIXME: could be proved safe. Implement.
478 define 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:
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
492 define 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
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
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
520 define 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:
528 %x = alloca [10 x i8], align 1
529 %0 = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 0
531 %lftr.limit = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 11
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
547 define 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:
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
561 call void @llvm.memset.p0i8.i32(i8* nonnull align 16 %x1.sub, i8 0, i32 %sz, i1 false)
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.
570 define 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
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
588 %zerosize_type = type {}
590 define 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
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
609 define 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:
617 %a = alloca i32, align 4
618 call void @LeakAddress() ["unknown"(i32* %a)]
622 define 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:
632 define 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)
643 %x = alloca i16, align 4
644 call void @ByVal(i16* byval(i16) %x)
646 %y = alloca i64, align 4
647 %y1 = bitcast i64* %y to i16*
648 call void @ByVal(i16* byval(i16) %y1)
653 declare void @ByValArray([100000 x i64]* byval([100000 x i64]) %p)
655 define 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:
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)
671 define 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
679 %p2 = getelementptr i8, i8* %p, i64 -9223372036854775808
680 %v = load i8, i8* %p2, align 1
684 define 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:
693 %x = alloca i8, align 4
694 %x2 = getelementptr i8, i8* %x, i64 -9223372036854775808
695 %v = call i8 @LoadMinInt64(i8* %x2)
699 define 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
710 %x = alloca i8, align 4
715 store i64 -5, i64* %p
722 define 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:
732 %x = alloca i8, align 4
733 %y = alloca i8, align 4
734 %z = alloca i8, align 4
738 call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false)
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)
747 define 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)
760 %x = alloca i8, align 4
761 %y = alloca i8, align 4
762 %z = alloca i8, align 4
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)
770 call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false)
775 define 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:
785 %x = alloca i8, align 4
786 %y = alloca i8, align 4
787 %z = alloca i8, align 4
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)
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)
799 call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false)
804 define 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)
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)
821 define 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:
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)
837 define 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:
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)
853 define 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:
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)
869 define 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)
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)
885 define 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
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
901 define 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
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)
918 define 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
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
935 define 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
945 %a = alloca i32, align 4
946 br i1 %x, label %tlabel, label %flabel
948 %n = load i32, i32* %a, align 4
954 define void @MixedAccesses6(i8* %arg) {
955 ; CHECK-LABEL: @MixedAccesses6
956 ; CHECK-NEXT: args uses:
957 ; CHECK-NEXT: arg[]: [0,4)
958 ; CHECK-NEXT: allocas uses:
960 ; GLOBAL-NEXT: safe accesses:
961 ; GLOBAL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x, i8* %arg, i32 4, i1 false)
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)
970 define void @MixedAccesses7(i1 %cond, i8* %arg) {
971 ; SECV doesn't support select, so we consider this non-stack-safe, even through
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:
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)
989 define 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)
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)
1006 define 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)
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)
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)
1027 define 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)
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
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)
1048 define 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)
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
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)
1069 define 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)
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)
1087 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
1088 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)