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 4 5target 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" 6target triple = "x86_64-unknown-linux-gnu" 7 8declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) nounwind 9declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) nounwind 10 11define void @lifetime_no_size() sanitize_address { 12 ; CHECK-LABEL: define void @lifetime_no_size() 13entry: 14 %i = alloca i32, align 4 15 %i.ptr = bitcast i32* %i to i8* 16 17 ; Poison memory in prologue: F1F1F1F104F3F3F3 18 ; CHECK: store i64 -868083100587789839, i64* %{{[0-9]+}} 19 20 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %i.ptr) 21 ; Check that lifetime with no size are ignored. 22 ; CHECK-NOT: store 23 ; CHECK: call void @llvm.lifetime.start 24 25 store volatile i8 0, i8* %i.ptr 26 ; CHECK: store volatile 27 28 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %i.ptr) 29 ; Check that lifetime with no size are ignored. 30 ; CHECK-NOT: store 31 ; CHECK: call void @llvm.lifetime.end 32 33 ; Unpoison stack frame on exit. 34 ; CHECK: store i64 0, i64* %{{[0-9]+}} 35 ; CHECK: ret void 36 ret void 37} 38 39; Generic case of lifetime analysis. 40define void @lifetime() sanitize_address { 41 ; CHECK-LABEL: define void @lifetime() 42 43 ; Regular variable lifetime intrinsics. 44 %i = alloca i32, align 4 45 %i.ptr = bitcast i32* %i to i8* 46 47 ; Poison memory in prologue: F1F1F1F1F8F3F3F3 48 ; CHECK: store i64 -868082052615769615, i64* %{{[0-9]+}} 49 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 54 55 store volatile i8 0, i8* %i.ptr 56 ; CHECK: store volatile 57 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 61 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 66 67 ; Lifetime intrinsics for array. 68 %arr = alloca [10 x i32], align 16 69 %arr.ptr = bitcast [10 x i32]* %arr to i8* 70 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) 74 75 store volatile i8 0, i8* %arr.ptr 76 ; CHECK: store volatile 77 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) 81 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 86 87 store volatile i8 0, i8* %i.ptr 88 ; CHECK: store volatile 89 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 93 94 ; Memory is unpoisoned at function exit (only once). 95 ; CHECK: store i64 0, i64* %{{[0-9]+}} 96 ; CHECK-NEXT: ret void 97 ret void 98} 99 100; Check that arguments of lifetime may come from phi nodes. 101define void @phi_args(i1 %x) sanitize_address { 102 ; CHECK-LABEL: define void @phi_args(i1 %x) 103 104entry: 105 %i = alloca i64, align 4 106 %i.ptr = bitcast i64* %i to i8* 107 108 ; Poison memory in prologue: F1F1F1F1F8F3F3F3 109 ; CHECK: store i64 -868082052615769615, i64* %{{[0-9]+}} 110 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 114 115 store volatile i8 0, i8* %i.ptr 116 ; CHECK: store volatile 117 118 br i1 %x, label %bb0, label %bb1 119 120bb0: 121 %i.ptr2 = bitcast i64* %i to i8* 122 br label %bb1 123 124bb1: 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 129 130 ret void 131 ; CHECK: store i64 0, i64* %{{[0-9]+}} 132 ; CHECK-NEXT: ret void 133} 134 135; Check that arguments of lifetime may come from getelementptr nodes. 136define void @getelementptr_args() sanitize_address{ 137 ; CHECK-LABEL: define void @getelementptr_args 138entry: 139 %x = alloca [1024 x i8], align 16 140 %d = alloca i8*, align 8 141 142 ; F1F1F1F1 143 ; CHECK: store i32 -235802127, i32* %{{[0-9]+}} 144 ; F3F3F3F3F3F3F3F3 145 ; CHECK: store i64 -868082074056920077, i64* %{{[0-9]+}} 146 ; F3F3F3F3F3F3F3F3 147 ; CHECK: store i64 -868082074056920077, i64* %{{[0-9]+}} 148 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 153 154 store i8* %0, i8** %d, align 8 155 ; CHECK: store i8 156 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 160 161 ret void 162 ; CHECK: call void @__asan_set_shadow_00(i64 %{{[0-9]+}}, i64 148) 163 ; CHECK-NEXT: ret void 164} 165 166define void @zero_sized(i64 %a) #0 { 167; CHECK-LABEL: define void @zero_sized(i64 %a) 168 169entry: 170 %a.addr = alloca i64, align 8 171 %b = alloca [0 x i8], align 1 172 store i64 %a, i64* %a.addr, align 8 173 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 178 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 183 184 ret void 185 ; CHECK-NEXT: ret void 186} 187