1 ; Test handling of llvm.lifetime intrinsics.
2 ; RUN: opt < %s -asan -asan-module -asan-use-after-scope -asan-use-after-return=0 -S | FileCheck %s --check-prefixes=CHECK,CHECK-DEFAULT
3 ; RUN: opt < %s -asan -asan-module -asan-use-after-scope -asan-use-after-return=0 -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.p0i8(i64, i8* nocapture) nounwind
9 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) nounwind
11 define void @lifetime_no_size() sanitize_address {
12 ; CHECK-LABEL: define void @lifetime_no_size()
14 %i = alloca i32, align 4
15 %i.ptr = bitcast i32* %i to i8*
17 ; Poison memory in prologue: F1F1F1F104F3F3F3
18 ; CHECK: store i64 -868083100587789839, i64* %{{[0-9]+}}
20 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %i.ptr)
21 ; Check that lifetime with no size are ignored.
23 ; CHECK: call void @llvm.lifetime.start
25 store volatile i8 0, i8* %i.ptr
26 ; CHECK: store volatile
28 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %i.ptr)
29 ; Check that lifetime with no size are ignored.
31 ; CHECK: call void @llvm.lifetime.end
33 ; Unpoison stack frame on exit.
34 ; CHECK: store i64 0, i64* %{{[0-9]+}}
39 ; Generic case of lifetime analysis.
40 define void @lifetime() sanitize_address {
41 ; CHECK-LABEL: define void @lifetime()
43 ; Regular variable lifetime intrinsics.
44 %i = alloca i32, align 4
45 %i.ptr = bitcast i32* %i to i8*
47 ; Poison memory in prologue: F1F1F1F1F8F3F3F3
48 ; CHECK: store i64 -868082052615769615, i64* %{{[0-9]+}}
50 ; Memory is unpoisoned at llvm.lifetime.start
51 call void @llvm.lifetime.start.p0i8(i64 3, i8* %i.ptr)
52 ; CHECK: store i8 4, i8* %{{[0-9]+}}
53 ; CHECK-NEXT: llvm.lifetime.start
55 store volatile i8 0, i8* %i.ptr
56 ; CHECK: store volatile
58 call void @llvm.lifetime.end.p0i8(i64 4, i8* %i.ptr)
59 ; CHECK: store i8 -8, i8* %{{[0-9]+}}
60 ; CHECK-NEXT: call void @llvm.lifetime.end
62 ; Memory is poisoned at every call to llvm.lifetime.end
63 call void @llvm.lifetime.end.p0i8(i64 2, i8* %i.ptr)
64 ; CHECK: store i8 -8, i8* %{{[0-9]+}}
65 ; CHECK-NEXT: call void @llvm.lifetime.end
67 ; Lifetime intrinsics for array.
68 %arr = alloca [10 x i32], align 16
69 %arr.ptr = bitcast [10 x i32]* %arr to i8*
71 call void @llvm.lifetime.start.p0i8(i64 40, i8* %arr.ptr)
72 ; CHECK-DEFAULT: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 40)
73 ; CHECK-NO-DYNAMIC-NOT: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 40)
75 store volatile i8 0, i8* %arr.ptr
76 ; CHECK: store volatile
78 call void @llvm.lifetime.end.p0i8(i64 40, i8* %arr.ptr)
79 ; CHECK-DEFAULT: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 40)
80 ; CHECK-NO-DYNAMIC-NOT: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 40)
82 ; One more lifetime start/end for the same variable %i.
83 call void @llvm.lifetime.start.p0i8(i64 2, i8* %i.ptr)
84 ; CHECK: store i8 4, i8* %{{[0-9]+}}
85 ; CHECK-NEXT: llvm.lifetime.start
87 store volatile i8 0, i8* %i.ptr
88 ; CHECK: store volatile
90 call void @llvm.lifetime.end.p0i8(i64 4, i8* %i.ptr)
91 ; CHECK: store i8 -8, i8* %{{[0-9]+}}
92 ; CHECK-NEXT: llvm.lifetime.end
94 ; Memory is unpoisoned at function exit (only once).
95 ; CHECK: store i64 0, i64* %{{[0-9]+}}
96 ; CHECK-NEXT: ret void
100 ; Check that arguments of lifetime may come from phi nodes.
101 define void @phi_args(i1 %x) sanitize_address {
102 ; CHECK-LABEL: define void @phi_args(i1 %x)
105 %i = alloca i64, align 4
106 %i.ptr = bitcast i64* %i to i8*
108 ; Poison memory in prologue: F1F1F1F1F8F3F3F3
109 ; CHECK: store i64 -868082052615769615, i64* %{{[0-9]+}}
111 call void @llvm.lifetime.start.p0i8(i64 8, i8* %i.ptr)
112 ; CHECK: store i8 0, i8* %{{[0-9]+}}
113 ; CHECK-NEXT: llvm.lifetime.start
115 store volatile i8 0, i8* %i.ptr
116 ; CHECK: store volatile
118 br i1 %x, label %bb0, label %bb1
121 %i.ptr2 = bitcast i64* %i to i8*
125 %i.phi = phi i8* [ %i.ptr, %entry ], [ %i.ptr2, %bb0 ]
126 call void @llvm.lifetime.end.p0i8(i64 8, i8* %i.phi)
127 ; CHECK: store i8 -8, i8* %{{[0-9]+}}
128 ; CHECK-NEXT: llvm.lifetime.end
131 ; CHECK: store i64 0, i64* %{{[0-9]+}}
132 ; CHECK-NEXT: ret void
135 ; Check that arguments of lifetime may come from getelementptr nodes.
136 define void @getelementptr_args() sanitize_address{
137 ; CHECK-LABEL: define void @getelementptr_args
139 %x = alloca [1024 x i8], align 16
140 %d = alloca i8*, align 8
143 ; CHECK: store i32 -235802127, i32* %{{[0-9]+}}
145 ; CHECK: store i64 -868082074056920077, i64* %{{[0-9]+}}
147 ; CHECK: store i64 -868082074056920077, i64* %{{[0-9]+}}
149 %0 = getelementptr inbounds [1024 x i8], [1024 x i8]* %x, i64 0, i64 0
150 call void @llvm.lifetime.start.p0i8(i64 1024, i8* %0)
151 ; CHECK: call void @__asan_set_shadow_00(i64 %{{[0-9]+}}, i64 128)
152 ; CHECK-NEXT: call void @llvm.lifetime.start
154 store i8* %0, i8** %d, align 8
157 call void @llvm.lifetime.end.p0i8(i64 1024, i8* %0)
158 ; CHECK: call void @__asan_set_shadow_f8(i64 %{{[0-9]+}}, i64 128)
159 ; CHECK-NEXT: call void @llvm.lifetime.end
162 ; CHECK: call void @__asan_set_shadow_00(i64 %{{[0-9]+}}, i64 148)
163 ; CHECK-NEXT: ret void
166 define void @zero_sized(i64 %a) #0 {
167 ; CHECK-LABEL: define void @zero_sized(i64 %a)
170 %a.addr = alloca i64, align 8
171 %b = alloca [0 x i8], align 1
172 store i64 %a, i64* %a.addr, align 8
174 %0 = bitcast [0 x i8]* %b to i8*
175 call void @llvm.lifetime.start.p0i8(i64 0, i8* %0) #2
176 ; CHECK: %{{[0-9]+}} = bitcast
177 ; CHECK-NEXT: call void @llvm.lifetime.start
179 %1 = bitcast [0 x i8]* %b to i8*
180 call void @llvm.lifetime.end.p0i8(i64 0, i8* %1) #2
181 ; CHECK-NEXT: %{{[0-9]+}} = bitcast
182 ; CHECK-NEXT: call void @llvm.lifetime.end
185 ; CHECK-NEXT: ret void