llvm.org GIT mirror llvm / 4ef1999
tsan: implement no_sanitize_thread attribute If a function has no_sanitize_thread attribute, do not instrument memory accesses in it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192871 91177308-0d34-0410-b5e6-96231b3b80d8 Dmitry Vyukov 7 years ago
7 changed file(s) with 47 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
357357 // (e.g. variables that do not escape, etc).
358358
359359 // Instrument memory accesses.
360 if (ClInstrumentMemoryAccesses)
360 if (ClInstrumentMemoryAccesses && F.hasFnAttribute(Attribute::SanitizeThread))
361361 for (size_t i = 0, n = AllLoadsAndStores.size(); i < n; ++i) {
362362 Res |= instrumentLoadOrStore(AllLoadsAndStores[i]);
363363 }
0 ; RUN: opt < %s -tsan -S | FileCheck %s
1
2 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"
3 target triple = "x86_64-unknown-linux-gnu"
4
5 ; no sanitize_thread attribute here
6 define i32 @read_4_bytes(i32* %a) {
7 entry:
8 %tmp1 = load i32* %a, align 4
9 ret i32 %tmp1
10 }
11
12 ; CHECK: define i32 @read_4_bytes(i32* %a) {
13 ; CHECK-NEXT: entry:
14 ; CHECK-NEXT: %tmp1 = load i32* %a, align 4
15 ; CHECK: ret i32 %tmp1
16
17 ; no sanitize_thread attribute here
18 define i32 @read_4_bytes_and_call(i32* %a) {
19 entry:
20 call void @foo()
21 %tmp1 = load i32* %a, align 4
22 ret i32 %tmp1
23 }
24
25 ; CHECK: define i32 @read_4_bytes_and_call(i32* %a) {
26 ; CHECK-NEXT: entry:
27 ; CHECK-NEXT: %0 = call i8* @llvm.returnaddress(i32 0)
28 ; CHECK-NEXT: call void @__tsan_func_entry(i8* %0)
29 ; CHECK-NEXT: call void @foo()
30 ; CHECK-NEXT: %tmp1 = load i32* %a, align 4
31 ; CHECK-NEXT: call void @__tsan_func_exit()
32 ; CHECK-NEXT: ret i32 %tmp1
33
34 declare void @foo()
35
11
22 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"
33
4 define void @IncrementMe(i32* nocapture %ptr) nounwind uwtable {
4 define void @IncrementMe(i32* nocapture %ptr) nounwind uwtable sanitize_thread {
55 entry:
66 %0 = load i32* %ptr, align 4
77 %inc = add nsw i32 %0, 1
1313 ; CHECK: __tsan_write
1414 ; CHECK: ret void
1515
16 define void @IncrementMeWithCallInBetween(i32* nocapture %ptr) nounwind uwtable {
16 define void @IncrementMeWithCallInBetween(i32* nocapture %ptr) nounwind uwtable sanitize_thread {
1717 entry:
1818 %0 = load i32* %ptr, align 4
1919 %inc = add nsw i32 %0, 1
33 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"
44
55 @const_global = external constant i32
6 define i32 @read_from_const_global() nounwind uwtable readnone {
6 define i32 @read_from_const_global() nounwind uwtable sanitize_thread readnone {
77 entry:
88 %0 = load i32* @const_global, align 4
99 ret i32 %0
1313 ; CHECK: ret i32
1414
1515 @non_const_global = global i32 0, align 4
16 define i32 @read_from_non_const_global() nounwind uwtable readonly {
16 define i32 @read_from_non_const_global() nounwind uwtable sanitize_thread readonly {
1717 entry:
1818 %0 = load i32* @non_const_global, align 4
1919 ret i32 %0
2424 ; CHECK: ret i32
2525
2626 @const_global_array = external constant [10 x i32]
27 define i32 @read_from_const_global_array(i32 %idx) nounwind uwtable readnone {
27 define i32 @read_from_const_global_array(i32 %idx) nounwind uwtable sanitize_thread readnone {
2828 entry:
2929 %idxprom = sext i32 %idx to i64
3030 %arrayidx = getelementptr inbounds [10 x i32]* @const_global_array, i64 0, i64 %idxprom
3737 ; CHECK: ret i32
3838
3939 %struct.Foo = type { i32 (...)** }
40 define void @call_virtual_func(%struct.Foo* %f) uwtable {
40 define void @call_virtual_func(%struct.Foo* %f) uwtable sanitize_thread {
4141 entry:
4242 %0 = bitcast %struct.Foo* %f to void (%struct.Foo*)***
4343 %vtable = load void (%struct.Foo*)*** %0, align 8, !tbaa !2
22 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"
33 target triple = "x86_64-unknown-linux-gnu"
44
5 define i32 @read_4_bytes(i32* %a) {
5 define i32 @read_4_bytes(i32* %a) sanitize_thread {
66 entry:
77 %tmp1 = load i32* %a, align 4
88 ret i32 %tmp1
1010
1111 ; CHECK: @llvm.global_ctors = {{.*}}@__tsan_init
1212
13 ; CHECK: define i32 @read_4_bytes(i32* %a) {
13 ; CHECK: define i32 @read_4_bytes(i32* %a)
1414 ; CHECK: call void @__tsan_func_entry(i8* %0)
1515 ; CHECK-NEXT: %1 = bitcast i32* %a to i8*
1616 ; CHECK-NEXT: call void @__tsan_read4(i8* %1)
11 ; Check that vptr reads are treated in a special way.
22 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"
33
4 define i8 @Foo(i8* %a) nounwind uwtable {
4 define i8 @Foo(i8* %a) nounwind uwtable sanitize_thread {
55 entry:
66 ; CHECK: call void @__tsan_vptr_read
77 %0 = load i8* %a, align 8, !tbaa !0
11 ; Check that vtable pointer updates are treated in a special way.
22 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"
33
4 define void @Foo(i8** nocapture %a, i8* %b) nounwind uwtable {
4 define void @Foo(i8** nocapture %a, i8* %b) nounwind uwtable sanitize_thread {
55 entry:
66 ; CHECK: call void @__tsan_vptr_update
77 store i8* %b, i8** %a, align 8, !tbaa !0