1 ; Test handling of llvm.lifetime intrinsics.
2 ; RUN: opt < %s -passes=asan -asan-use-after-scope -asan-use-after-return=never -S | FileCheck %s --check-prefixes=CHECK,CHECK-DEFAULT
3 ; RUN: opt < %s -passes=asan -asan-use-after-scope -asan-use-after-return=never -asan-instrument-dynamic-allocas=0 -S | FileCheck %s --check-prefixes=CHECK,CHECK-NO-DYNAMIC
5 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
6 target triple = "x86_64-unknown-linux-gnu"
8 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) nounwind
9 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) nounwind
11 define void @lifetime_no_size() sanitize_address {
12 ; CHECK-LABEL: define void @lifetime_no_size()
14 %i = alloca i32, align 4
16 ; Poison memory in prologue: F1F1F1F104F3F3F3
17 ; CHECK: store i64 -868083100587789839, ptr %{{[0-9]+}}
19 call void @llvm.lifetime.start.p0(i64 -1, ptr %i)
20 ; Check that lifetime with no size are ignored.
22 ; CHECK: call void @llvm.lifetime.start
24 store volatile i8 0, ptr %i
25 ; CHECK: store volatile
27 call void @llvm.lifetime.end.p0(i64 -1, ptr %i)
28 ; Check that lifetime with no size are ignored.
30 ; CHECK: call void @llvm.lifetime.end
32 ; Unpoison stack frame on exit.
33 ; CHECK: store i64 0, ptr %{{[0-9]+}}
38 ; Generic case of lifetime analysis.
39 define void @lifetime() sanitize_address {
40 ; CHECK-LABEL: define void @lifetime()
42 ; Regular variable lifetime intrinsics.
43 %i = alloca i32, align 4
45 ; Poison memory in prologue: F1F1F1F1F8F3F3F3
46 ; CHECK: store i64 -868082052615769615, ptr %{{[0-9]+}}
48 ; Memory is unpoisoned at llvm.lifetime.start
49 call void @llvm.lifetime.start.p0(i64 3, ptr %i)
50 ; CHECK: store i8 4, ptr %{{[0-9]+}}
51 ; CHECK-NEXT: llvm.lifetime.start
53 store volatile i8 0, ptr %i
54 ; CHECK: store volatile
56 call void @llvm.lifetime.end.p0(i64 4, ptr %i)
57 ; CHECK: store i8 -8, ptr %{{[0-9]+}}
58 ; CHECK-NEXT: call void @llvm.lifetime.end
60 ; Memory is poisoned at every call to llvm.lifetime.end
61 call void @llvm.lifetime.end.p0(i64 2, ptr %i)
62 ; CHECK: store i8 -8, ptr %{{[0-9]+}}
63 ; CHECK-NEXT: call void @llvm.lifetime.end
65 ; Lifetime intrinsics for array.
66 %arr = alloca [10 x i32], align 16
68 call void @llvm.lifetime.start.p0(i64 40, ptr %arr)
69 ; CHECK-DEFAULT: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 40)
70 ; CHECK-NO-DYNAMIC-NOT: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 40)
72 store volatile i8 0, ptr %arr
73 ; CHECK: store volatile
75 call void @llvm.lifetime.end.p0(i64 40, ptr %arr)
76 ; CHECK-DEFAULT: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 40)
77 ; CHECK-NO-DYNAMIC-NOT: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 40)
79 ; One more lifetime start/end for the same variable %i.
80 call void @llvm.lifetime.start.p0(i64 2, ptr %i)
81 ; CHECK: store i8 4, ptr %{{[0-9]+}}
82 ; CHECK-NEXT: llvm.lifetime.start
84 store volatile i8 0, ptr %i
85 ; CHECK: store volatile
87 call void @llvm.lifetime.end.p0(i64 4, ptr %i)
88 ; CHECK: store i8 -8, ptr %{{[0-9]+}}
89 ; CHECK-NEXT: llvm.lifetime.end
91 ; Memory is unpoisoned at function exit (only once).
92 ; CHECK: store i64 0, ptr %{{[0-9]+}}
93 ; CHECK-NEXT: ret void
97 ; Check that arguments of lifetime may come from phi nodes.
98 define void @phi_args(i1 %x) sanitize_address {
99 ; CHECK-LABEL: define void @phi_args(i1 %x)
102 %i = alloca i64, align 4
104 ; Poison memory in prologue: F1F1F1F1F8F3F3F3
105 ; CHECK: store i64 -868082052615769615, ptr %{{[0-9]+}}
107 call void @llvm.lifetime.start.p0(i64 8, ptr %i)
108 ; CHECK: store i8 0, ptr %{{[0-9]+}}
109 ; CHECK-NEXT: llvm.lifetime.start
111 store volatile i8 0, ptr %i
112 ; CHECK: store volatile
114 br i1 %x, label %bb0, label %bb1
120 %i.phi = phi ptr [ %i, %entry ], [ %i, %bb0 ]
121 call void @llvm.lifetime.end.p0(i64 8, ptr %i.phi)
122 ; CHECK: store i8 -8, ptr %{{[0-9]+}}
123 ; CHECK-NEXT: llvm.lifetime.end
126 ; CHECK: store i64 0, ptr %{{[0-9]+}}
127 ; CHECK-NEXT: ret void
130 ; Check that arguments of lifetime may come from getelementptr nodes.
131 define void @getelementptr_args() sanitize_address{
132 ; CHECK-LABEL: define void @getelementptr_args
134 %x = alloca [1024 x i8], align 16
135 %d = alloca ptr, align 8
138 ; CHECK: store i32 -235802127, ptr %{{[0-9]+}}
140 ; CHECK: store i64 -868082074056920077, ptr %{{[0-9]+}}
142 ; CHECK: store i64 -868082074056920077, ptr %{{[0-9]+}}
144 call void @llvm.lifetime.start.p0(i64 1024, ptr %x)
145 ; CHECK: call void @__asan_set_shadow_00(i64 %{{[0-9]+}}, i64 128)
146 ; CHECK-NEXT: call void @llvm.lifetime.start
148 store ptr %x, ptr %d, align 8
151 call void @llvm.lifetime.end.p0(i64 1024, ptr %x)
152 ; CHECK: call void @__asan_set_shadow_f8(i64 %{{[0-9]+}}, i64 128)
153 ; CHECK-NEXT: call void @llvm.lifetime.end
156 ; CHECK: call void @__asan_set_shadow_00(i64 %{{[0-9]+}}, i64 148)
157 ; CHECK-NEXT: ret void
160 define void @zero_sized(i64 %a) #0 {
161 ; CHECK-LABEL: define void @zero_sized(i64 %a)
164 %a.addr = alloca i64, align 8
165 %b = alloca [0 x i8], align 1
166 store i64 %a, ptr %a.addr, align 8
168 call void @llvm.lifetime.start.p0(i64 0, ptr %b) #2
169 ; CHECK: call void @llvm.lifetime.start
171 call void @llvm.lifetime.end.p0(i64 0, ptr %b) #2
172 ; CHECK: call void @llvm.lifetime.end
175 ; CHECK-NEXT: ret void