[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Analysis / StackSafetyAnalysis / local.ll
blobf6bad4715036a654d605b43ce1f3516c87d3452a
1 ; RUN: opt -S -analyze -stack-safety-local < %s -enable-new-pm=0 | FileCheck %s --check-prefixes=CHECK,LOCAL
2 ; RUN: opt -S -passes="print<stack-safety-local>" -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,LOCAL
3 ; RUN: opt -S -analyze -stack-safety < %s -enable-new-pm=0 | FileCheck %s --check-prefixes=CHECK,GLOBAL
4 ; RUN: opt -S -passes="print-stack-safety" -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,GLOBAL
6 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7 target triple = "x86_64-unknown-linux-gnu"
9 @sink = global i8* null, align 8
11 declare void @llvm.memset.p0i8.i32(i8* %dest, i8 %val, i32 %len, i1 %isvolatile)
12 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 %isvolatile)
13 declare void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 %isvolatile)
14 declare void @llvm.memset.p0i8.i64(i8* %dest, i8 %val, i64 %len, i1 %isvolatile)
16 ; Address leaked.
17 define void @LeakAddress() {
18 ; CHECK-LABEL: @LeakAddress dso_preemptable{{$}}
19 ; CHECK-NEXT: args uses:
20 ; CHECK-NEXT: allocas uses:
21 ; CHECK-NEXT: x[4]: full-set{{$}}
22 ; CHECK-EMPTY:
23 entry:
24   %x = alloca i32, align 4
25   %x1 = bitcast i32* %x to i8*
26   store i8* %x1, i8** @sink, align 8
27   ret void
30 define void @StoreInBounds() {
31 ; CHECK-LABEL: @StoreInBounds dso_preemptable{{$}}
32 ; CHECK-NEXT: args uses:
33 ; CHECK-NEXT: allocas uses:
34 ; CHECK-NEXT: x[4]: [0,1){{$}}
35 ; CHECK-EMPTY:
36 entry:
37   %x = alloca i32, align 4
38   %x1 = bitcast i32* %x to i8*
39   store i8 0, i8* %x1, align 1
40   ret void
43 define void @StoreInBounds2() {
44 ; CHECK-LABEL: @StoreInBounds2 dso_preemptable{{$}}
45 ; CHECK-NEXT: args uses:
46 ; CHECK-NEXT: allocas uses:
47 ; CHECK-NEXT: x[4]: [0,4){{$}}
48 ; CHECK-EMPTY:
49 entry:
50   %x = alloca i32, align 4
51   store i32 0, i32* %x, align 4
52   ret void
55 define void @StoreInBounds3() {
56 ; CHECK-LABEL: @StoreInBounds3 dso_preemptable{{$}}
57 ; CHECK-NEXT: args uses:
58 ; CHECK-NEXT: allocas uses:
59 ; CHECK-NEXT: x[4]: [2,3){{$}}
60 ; CHECK-EMPTY:
61 entry:
62   %x = alloca i32, align 4
63   %x1 = bitcast i32* %x to i8*
64   %x2 = getelementptr i8, i8* %x1, i64 2
65   store i8 0, i8* %x2, align 1
66   ret void
69 ; FIXME: ScalarEvolution does not look through ptrtoint/inttoptr.
70 define void @StoreInBounds4() {
71 ; CHECK-LABEL: @StoreInBounds4 dso_preemptable{{$}}
72 ; CHECK-NEXT: args uses:
73 ; CHECK-NEXT: allocas uses:
74 ; CHECK-NEXT: x[4]: full-set{{$}}
75 ; CHECK-EMPTY:
76 entry:
77   %x = alloca i32, align 4
78   %x1 = ptrtoint i32* %x to i64
79   %x2 = add i64 %x1, 2
80   %x3 = inttoptr i64 %x2 to i8*
81   store i8 0, i8* %x3, align 1
82   ret void
85 define dso_local void @WriteMinMax(i8* %p) {
86 ; CHECK-LABEL: @WriteMinMax{{$}}
87 ; CHECK-NEXT: args uses:
88 ; CHECK-NEXT: p[]: full-set
89 ; CHECK-NEXT: allocas uses:
90 ; CHECK-EMPTY:
91 entry:
92   %p1 = getelementptr i8, i8* %p, i64 9223372036854775805
93   store i8 0, i8* %p1, align 1
94   %p2 = getelementptr i8, i8* %p, i64 -9223372036854775805
95   store i8 0, i8* %p2, align 1
96   ret void
99 define dso_local void @WriteMax(i8* %p) {
100 ; CHECK-LABEL: @WriteMax{{$}}
101 ; CHECK-NEXT: args uses:
102 ; CHECK-NEXT: p[]: [-9223372036854775807,9223372036854775806)
103 ; CHECK-NEXT: allocas uses:
104 ; CHECK-EMPTY:
105 entry:
106   call void @llvm.memset.p0i8.i64(i8* %p, i8 1, i64 9223372036854775806, i1 0)
107   %p2 = getelementptr i8, i8* %p, i64 -9223372036854775807
108   call void @llvm.memset.p0i8.i64(i8* %p2, i8 1, i64 9223372036854775806, i1 0)
109   ret void
112 define void @StoreOutOfBounds() {
113 ; CHECK-LABEL: @StoreOutOfBounds dso_preemptable{{$}}
114 ; CHECK-NEXT: args uses:
115 ; CHECK-NEXT: allocas uses:
116 ; CHECK-NEXT: x[4]: [2,6){{$}}
117 ; CHECK-EMPTY:
118 entry:
119   %x = alloca i32, align 4
120   %x1 = bitcast i32* %x to i8*
121   %x2 = getelementptr i8, i8* %x1, i64 2
122   %x3 = bitcast i8* %x2 to i32*
123   store i32 0, i32* %x3, align 1
124   ret void
127 ; There is no difference in load vs store handling.
128 define void @LoadInBounds() {
129 ; CHECK-LABEL: @LoadInBounds dso_preemptable{{$}}
130 ; CHECK-NEXT: args uses:
131 ; CHECK-NEXT: allocas uses:
132 ; CHECK-NEXT: x[4]: [0,1){{$}}
133 ; CHECK-EMPTY:
134 entry:
135   %x = alloca i32, align 4
136   %x1 = bitcast i32* %x to i8*
137   %v = load i8, i8* %x1, align 1
138   ret void
141 define void @LoadOutOfBounds() {
142 ; CHECK-LABEL: @LoadOutOfBounds dso_preemptable{{$}}
143 ; CHECK-NEXT: args uses:
144 ; CHECK-NEXT: allocas uses:
145 ; CHECK-NEXT: x[4]: [2,6){{$}}
146 ; CHECK-EMPTY:
147 entry:
148   %x = alloca i32, align 4
149   %x1 = bitcast i32* %x to i8*
150   %x2 = getelementptr i8, i8* %x1, i64 2
151   %x3 = bitcast i8* %x2 to i32*
152   %v = load i32, i32* %x3, align 1
153   ret void
156 ; Leak through ret.
157 define i8* @Ret() {
158 ; CHECK-LABEL: @Ret dso_preemptable{{$}}
159 ; CHECK-NEXT: args uses:
160 ; CHECK-NEXT: allocas uses:
161 ; CHECK-NEXT: x[4]: full-set{{$}}
162 ; CHECK-EMPTY:
163 entry:
164   %x = alloca i32, align 4
165   %x1 = bitcast i32* %x to i8*
166   %x2 = getelementptr i8, i8* %x1, i64 2
167   ret i8* %x2
170 declare void @Foo(i16* %p)
172 define void @DirectCall() {
173 ; CHECK-LABEL: @DirectCall dso_preemptable{{$}}
174 ; CHECK-NEXT: args uses:
175 ; CHECK-NEXT: allocas uses:
176 ; LOCAL-NEXT: x[8]: empty-set, @Foo(arg0, [2,3)){{$}}
177 ; GLOBAL-NEXT: x[8]: full-set, @Foo(arg0, [2,3)){{$}}
178 ; CHECK-EMPTY:
179 entry:
180   %x = alloca i64, align 4
181   %x1 = bitcast i64* %x to i16*
182   %x2 = getelementptr i16, i16* %x1, i64 1
183   call void @Foo(i16* %x2);
184   ret void
187 ; Indirect calls can not be analyzed (yet).
188 ; FIXME: %p[]: full-set looks invalid
189 define void @IndirectCall(void (i8*)* %p) {
190 ; CHECK-LABEL: @IndirectCall dso_preemptable{{$}}
191 ; CHECK-NEXT: args uses:
192 ; CHECK-NEXT: p[]: full-set{{$}}
193 ; CHECK-NEXT: allocas uses:
194 ; CHECK-NEXT: x[4]: full-set{{$}}
195 ; CHECK-EMPTY:
196 entry:
197   %x = alloca i32, align 4
198   %x1 = bitcast i32* %x to i8*
199   call void %p(i8* %x1);
200   ret void
203 define void @NonConstantOffset(i1 zeroext %z) {
204 ; CHECK-LABEL: @NonConstantOffset dso_preemptable{{$}}
205 ; CHECK-NEXT: args uses:
206 ; CHECK-NEXT: allocas uses:
207 ; FIXME: SCEV can't look through selects.
208 ; CHECK-NEXT: x[4]: [0,4){{$}}
209 ; CHECK-EMPTY:
210 entry:
211   %x = alloca i32, align 4
212   %x1 = bitcast i32* %x to i8*
213   %idx = select i1 %z, i64 1, i64 2
214   %x2 = getelementptr i8, i8* %x1, i64 %idx
215   store i8 0, i8* %x2, align 1
216   ret void
219 define void @NegativeOffset() {
220 ; CHECK-LABEL: @NegativeOffset dso_preemptable{{$}}
221 ; CHECK-NEXT: args uses:
222 ; CHECK-NEXT: allocas uses:
223 ; CHECK-NEXT: x[40]: [-1600000000000,-1599999999996){{$}}
224 ; CHECK-EMPTY:
225 entry:
226   %x = alloca i32, i32 10, align 4
227   %x2 = getelementptr i32, i32* %x, i64 -400000000000
228   store i32 0, i32* %x2, align 1
229   ret void
232 define void @PossiblyNegativeOffset(i16 %z) {
233 ; CHECK-LABEL: @PossiblyNegativeOffset dso_preemptable{{$}}
234 ; CHECK-NEXT: args uses:
235 ; CHECK-NEXT: allocas uses:
236 ; CHECK-NEXT: x[40]: [-131072,131072){{$}}
237 ; CHECK-EMPTY:
238 entry:
239   %x = alloca i32, i32 10, align 4
240   %x2 = getelementptr i32, i32* %x, i16 %z
241   store i32 0, i32* %x2, align 1
242   ret void
245 define void @NonConstantOffsetOOB(i1 zeroext %z) {
246 ; CHECK-LABEL: @NonConstantOffsetOOB dso_preemptable{{$}}
247 ; CHECK-NEXT: args uses:
248 ; CHECK-NEXT: allocas uses:
249 ; CHECK-NEXT: x[4]: [0,6){{$}}
250 ; CHECK-EMPTY:
251 entry:
252   %x = alloca i32, align 4
253   %x1 = bitcast i32* %x to i8*
254   %idx = select i1 %z, i64 1, i64 4
255   %x2 = getelementptr i8, i8* %x1, i64 %idx
256   store i8 0, i8* %x2, align 1
257   ret void
260 define void @ArrayAlloca() {
261 ; CHECK-LABEL: @ArrayAlloca dso_preemptable{{$}}
262 ; CHECK-NEXT: args uses:
263 ; CHECK-NEXT: allocas uses:
264 ; CHECK-NEXT: x[40]: [36,40){{$}}
265 ; CHECK-EMPTY:
266 entry:
267   %x = alloca i32, i32 10, align 4
268   %x1 = bitcast i32* %x to i8*
269   %x2 = getelementptr i8, i8* %x1, i64 36
270   %x3 = bitcast i8* %x2 to i32*
271   store i32 0, i32* %x3, align 1
272   ret void
275 define void @ArrayAllocaOOB() {
276 ; CHECK-LABEL: @ArrayAllocaOOB dso_preemptable{{$}}
277 ; CHECK-NEXT: args uses:
278 ; CHECK-NEXT: allocas uses:
279 ; CHECK-NEXT: x[40]: [37,41){{$}}
280 ; CHECK-EMPTY:
281 entry:
282   %x = alloca i32, i32 10, align 4
283   %x1 = bitcast i32* %x to i8*
284   %x2 = getelementptr i8, i8* %x1, i64 37
285   %x3 = bitcast i8* %x2 to i32*
286   store i32 0, i32* %x3, align 1
287   ret void
290 define void @DynamicAllocaUnused(i64 %size) {
291 ; CHECK-LABEL: @DynamicAllocaUnused dso_preemptable{{$}}
292 ; CHECK-NEXT: args uses:
293 ; CHECK-NEXT: allocas uses:
294 ; CHECK-NEXT: x[0]: empty-set{{$}}
295 ; CHECK-EMPTY:
296 entry:
297   %x = alloca i32, i64 %size, align 16
298   ret void
301 ; Dynamic alloca with unknown size.
302 define void @DynamicAlloca(i64 %size) {
303 ; CHECK-LABEL: @DynamicAlloca dso_preemptable{{$}}
304 ; CHECK-NEXT: args uses:
305 ; CHECK-NEXT: allocas uses:
306 ; CHECK-NEXT: x[0]: [0,4){{$}}
307 ; CHECK-EMPTY:
308 entry:
309   %x = alloca i32, i64 %size, align 16
310   store i32 0, i32* %x, align 1
311   ret void
314 ; Dynamic alloca with limited size.
315 ; FIXME: could be proved safe. Implement.
316 define void @DynamicAllocaFiniteSizeRange(i1 zeroext %z) {
317 ; CHECK-LABEL: @DynamicAllocaFiniteSizeRange dso_preemptable{{$}}
318 ; CHECK-NEXT: args uses:
319 ; CHECK-NEXT: allocas uses:
320 ; CHECK-NEXT: x[0]: [0,4){{$}}
321 ; CHECK-EMPTY:
322 entry:
323   %size = select i1 %z, i64 3, i64 5
324   %x = alloca i32, i64 %size, align 16
325   store i32 0, i32* %x, align 1
326   ret void
329 define signext i8 @SimpleLoop() {
330 ; CHECK-LABEL: @SimpleLoop dso_preemptable{{$}}
331 ; CHECK-NEXT: args uses:
332 ; CHECK-NEXT: allocas uses:
333 ; CHECK-NEXT: x[10]: [0,10){{$}}
334 ; CHECK-EMPTY:
335 entry:
336   %x = alloca [10 x i8], align 1
337   %0 = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 0
338   %lftr.limit = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 10
339   br label %for.body
341 for.body:
342   %sum.010 = phi i8 [ 0, %entry ], [ %add, %for.body ]
343   %p.09 = phi i8* [ %0, %entry ], [ %incdec.ptr, %for.body ]
344   %incdec.ptr = getelementptr inbounds i8, i8* %p.09, i64 1
345   %1 = load volatile i8, i8* %p.09, align 1
346   %add = add i8 %1, %sum.010
347   %exitcond = icmp eq i8* %incdec.ptr, %lftr.limit
348   br i1 %exitcond, label %for.cond.cleanup, label %for.body
350 for.cond.cleanup:
351   ret i8 %add
354 ; OOB in a loop.
355 define signext i8 @SimpleLoopOOB() {
356 ; CHECK-LABEL: @SimpleLoopOOB dso_preemptable{{$}}
357 ; CHECK-NEXT: args uses:
358 ; CHECK-NEXT: allocas uses:
359 ; CHECK-NEXT: x[10]: [0,11){{$}}
360 ; CHECK-EMPTY:
361 entry:
362   %x = alloca [10 x i8], align 1
363   %0 = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 0
364  ; 11 iterations
365   %lftr.limit = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 11
366   br label %for.body
368 for.body:
369   %sum.010 = phi i8 [ 0, %entry ], [ %add, %for.body ]
370   %p.09 = phi i8* [ %0, %entry ], [ %incdec.ptr, %for.body ]
371   %incdec.ptr = getelementptr inbounds i8, i8* %p.09, i64 1
372   %1 = load volatile i8, i8* %p.09, align 1
373   %add = add i8 %1, %sum.010
374   %exitcond = icmp eq i8* %incdec.ptr, %lftr.limit
375   br i1 %exitcond, label %for.cond.cleanup, label %for.body
377 for.cond.cleanup:
378   ret i8 %add
381 define dso_local void @SizeCheck(i32 %sz) {
382 ; CHECK-LABEL: @SizeCheck{{$}}
383 ; CHECK-NEXT: args uses:
384 ; CHECK-NEXT: allocas uses:
385 ; CHECK-NEXT: x1[128]: [0,4294967295){{$}}
386 ; CHECK-EMPTY:
387 entry:
388   %x1 = alloca [128 x i8], align 16
389   %x1.sub = getelementptr inbounds [128 x i8], [128 x i8]* %x1, i64 0, i64 0
390   %cmp = icmp slt i32 %sz, 129
391   br i1 %cmp, label %if.then, label %if.end
393 if.then:
394   call void @llvm.memset.p0i8.i32(i8* nonnull align 16 %x1.sub, i8 0, i32 %sz, i1 false)
395   br label %if.end
397 if.end:
398   ret void
401 ; FIXME: scalable allocas are considered to be of size zero, and scalable accesses to be full-range.
402 ; This effectively disables safety analysis for scalable allocations.
403 define void @Scalable(<vscale x 4 x i32>* %p, <vscale x 4 x i32>* %unused, <vscale x 4 x i32> %v) {
404 ; CHECK-LABEL: @Scalable dso_preemptable{{$}}
405 ; CHECK-NEXT: args uses:
406 ; CHECK-NEXT:   p[]: full-set
407 ; CHECK-NEXT:   unused[]: empty-set
408 ; CHECK-NEXT: allocas uses:
409 ; CHECK-NEXT:   x[0]: [0,1){{$}}
410 ; CHECK-EMPTY:
411 entry:
412   %x = alloca <vscale x 4 x i32>, align 4
413   %x1 = bitcast <vscale x 4 x i32>* %x to i8*
414   store i8 0, i8* %x1, align 1
415   store <vscale x 4 x i32> %v, <vscale x 4 x i32>* %p, align 4
416   ret void
419 %zerosize_type = type {}
421 define void @ZeroSize(%zerosize_type *%p)  {
422 ; CHECK-LABEL: @ZeroSize dso_preemptable{{$}}
423 ; CHECK-NEXT: args uses:
424 ; CHECK-NEXT:   p[]: empty-set
425 ; CHECK-NEXT: allocas uses:
426 ; CHECK-NEXT:   x[0]: empty-set
427 ; CHECK-EMPTY:
428 entry:
429   %x = alloca %zerosize_type, align 4
430   store %zerosize_type undef, %zerosize_type* %x, align 4
431   store %zerosize_type undef, %zerosize_type* undef, align 4
432   %val = load %zerosize_type, %zerosize_type* %p, align 4
433   ret void
436 define void @OperandBundle() {
437 ; CHECK-LABEL: @OperandBundle dso_preemptable{{$}}
438 ; CHECK-NEXT: args uses:
439 ; CHECK-NEXT: allocas uses:
440 ; CHECK-NEXT:   a[4]: full-set
441 ; CHECK-EMPTY:
442 entry:
443   %a = alloca i32, align 4
444   call void @LeakAddress() ["unknown"(i32* %a)]
445   ret void
448 define void @ByVal(i16* byval(i16) %p) {
449   ; CHECK-LABEL: @ByVal dso_preemptable{{$}}
450   ; CHECK-NEXT: args uses:
451   ; CHECK-NEXT: allocas uses:
452   ; CHECK-EMPTY:
453 entry:
454   ret void
457 define void @TestByVal() {
458 ; CHECK-LABEL: @TestByVal dso_preemptable{{$}}
459 ; CHECK-NEXT: args uses:
460 ; CHECK-NEXT: allocas uses:
461 ; CHECK-NEXT: x[2]: [0,2)
462 ; CHECK-NEXT: y[8]: [0,2)
463 ; CHECK-EMPTY:
464 entry:
465   %x = alloca i16, align 4
466   call void @ByVal(i16* byval(i16) %x)
468   %y = alloca i64, align 4
469   %y1 = bitcast i64* %y to i16*
470   call void @ByVal(i16* byval(i16) %y1)
472   ret void
475 declare void @ByValArray([100000 x i64]* byval([100000 x i64]) %p)
477 define void @TestByValArray() {
478 ; CHECK-LABEL: @TestByValArray dso_preemptable{{$}}
479 ; CHECK-NEXT: args uses:
480 ; CHECK-NEXT: allocas uses:
481 ; CHECK-NEXT: z[800000]: [500000,1300000)
482 ; CHECK-EMPTY:
483 entry:
484   %z = alloca [100000 x i64], align 4
485   %z1 = bitcast [100000 x i64]* %z to i8*
486   %z2 = getelementptr i8, i8* %z1, i64 500000
487   %z3 = bitcast i8* %z2 to [100000 x i64]*
488   call void @ByValArray([100000 x i64]* byval([100000 x i64]) %z3)
489   ret void
492 define dso_local i8 @LoadMinInt64(i8* %p) {
493   ; CHECK-LABEL: @LoadMinInt64{{$}}
494   ; CHECK-NEXT: args uses:
495   ; CHECK-NEXT: p[]: [-9223372036854775808,-9223372036854775807){{$}}
496   ; CHECK-NEXT: allocas uses:
497   ; CHECK-EMPTY:
498   %p2 = getelementptr i8, i8* %p, i64 -9223372036854775808
499   %v = load i8, i8* %p2, align 1
500   ret i8 %v
503 define void @Overflow() {
504 ; CHECK-LABEL: @Overflow dso_preemptable{{$}}
505 ; CHECK-NEXT: args uses:
506 ; CHECK-NEXT: allocas uses:
507 ; LOCAL-NEXT: x[1]: empty-set, @LoadMinInt64(arg0, [-9223372036854775808,-9223372036854775807)){{$}}
508 ; GLOBAL-NEXT: x[1]: full-set, @LoadMinInt64(arg0, [-9223372036854775808,-9223372036854775807)){{$}}
509 ; CHECK-EMPTY:
510 entry:
511   %x = alloca i8, align 4
512   %x2 = getelementptr i8, i8* %x, i64 -9223372036854775808
513   %v = call i8 @LoadMinInt64(i8* %x2)
514   ret void
517 define void @DeadBlock(i64* %p) {
518 ; CHECK-LABEL: @DeadBlock dso_preemptable{{$}}
519 ; CHECK-NEXT: args uses:
520 ; CHECK-NEXT: p[]: empty-set{{$}}
521 ; CHECK-NEXT: allocas uses:
522 ; CHECK-NEXT: x[1]: empty-set{{$}}
523 ; CHECK-EMPTY:
524 entry:
525   %x = alloca i8, align 4
526   br label %end
528 dead:
529   store i8 5, i8* %x
530   store i64 -5, i64* %p
531   br label %end
533 end:
534   ret void
537 define void @LifeNotStarted() {
538 ; CHECK-LABEL: @LifeNotStarted dso_preemptable{{$}}
539 ; CHECK-NEXT: args uses:
540 ; CHECK-NEXT: allocas uses:
541 ; CHECK: x[1]: full-set{{$}}
542 ; CHECK: y[1]: full-set{{$}}
543 ; CHECK: z[1]: full-set{{$}}
544 ; CHECK-EMPTY:
545 entry:
546   %x = alloca i8, align 4
547   %y = alloca i8, align 4
548   %z = alloca i8, align 4
550   store i8 5, i8* %x
551   %n = load i8, i8* %y
552   call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false)
554   call void @llvm.lifetime.start.p0i8(i64 1, i8* %x)
555   call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
556   call void @llvm.lifetime.start.p0i8(i64 1, i8* %z)
558   ret void
561 define void @LifeOK() {
562 ; CHECK-LABEL: @LifeOK dso_preemptable{{$}}
563 ; CHECK-NEXT: args uses:
564 ; CHECK-NEXT: allocas uses:
565 ; CHECK: x[1]: [0,1){{$}}
566 ; CHECK: y[1]: [0,1){{$}}
567 ; CHECK: z[1]: [0,1){{$}}
568 ; CHECK-EMPTY:
569 entry:
570   %x = alloca i8, align 4
571   %y = alloca i8, align 4
572   %z = alloca i8, align 4
574   call void @llvm.lifetime.start.p0i8(i64 1, i8* %x)
575   call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
576   call void @llvm.lifetime.start.p0i8(i64 1, i8* %z)
578   store i8 5, i8* %x
579   %n = load i8, i8* %y
580   call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false)
582   ret void
585 define void @LifeEnded() {
586 ; CHECK-LABEL: @LifeEnded dso_preemptable{{$}}
587 ; CHECK-NEXT: args uses:
588 ; CHECK-NEXT: allocas uses:
589 ; CHECK: x[1]: full-set{{$}}
590 ; CHECK: y[1]: full-set{{$}}
591 ; CHECK: z[1]: full-set{{$}}
592 ; CHECK-EMPTY:
593 entry:
594   %x = alloca i8, align 4
595   %y = alloca i8, align 4
596   %z = alloca i8, align 4
598   call void @llvm.lifetime.start.p0i8(i64 1, i8* %x)
599   call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
600   call void @llvm.lifetime.start.p0i8(i64 1, i8* %z)
602   call void @llvm.lifetime.end.p0i8(i64 1, i8* %x)
603   call void @llvm.lifetime.end.p0i8(i64 1, i8* %y)
604   call void @llvm.lifetime.end.p0i8(i64 1, i8* %z)
606   store i8 5, i8* %x
607   %n = load i8, i8* %y
608   call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false)
610   ret void
613 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
614 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)