1; RUN: opt < %s -tsan -S -enable-new-pm=0 | FileCheck %s 2; RUN: opt < %s -passes='function(tsan),module(tsan-module)' -S | FileCheck %s 3 4target 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" 5target triple = "x86_64-unknown-linux-gnu" 6 7define i32 @read_4_bytes(i32* %a) sanitize_thread { 8entry: 9 %tmp1 = load i32, i32* %a, align 4 10 ret i32 %tmp1 11} 12 13; CHECK: @llvm.global_ctors = {{.*}}@tsan.module_ctor 14 15; CHECK: define i32 @read_4_bytes(i32* %a) 16; CHECK: call void @__tsan_func_entry(i8* %0) 17; CHECK-NEXT: %1 = bitcast i32* %a to i8* 18; CHECK-NEXT: call void @__tsan_read4(i8* %1) 19; CHECK-NEXT: %tmp1 = load i32, i32* %a, align 4 20; CHECK-NEXT: call void @__tsan_func_exit() 21; CHECK: ret i32 22 23 24declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) 25declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) 26declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) 27 28 29; Check that tsan converts mem intrinsics back to function calls. 30 31define void @MemCpyTest(i8* nocapture %x, i8* nocapture %y) sanitize_thread { 32entry: 33 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %x, i8* align 4 %y, i64 16, i1 false) 34 ret void 35; CHECK: define void @MemCpyTest 36; CHECK: call i8* @memcpy 37; CHECK: ret void 38} 39 40define void @MemMoveTest(i8* nocapture %x, i8* nocapture %y) sanitize_thread { 41entry: 42 tail call void @llvm.memmove.p0i8.p0i8.i64(i8* align 4 %x, i8* align 4 %y, i64 16, i1 false) 43 ret void 44; CHECK: define void @MemMoveTest 45; CHECK: call i8* @memmove 46; CHECK: ret void 47} 48 49define void @MemSetTest(i8* nocapture %x) sanitize_thread { 50entry: 51 tail call void @llvm.memset.p0i8.i64(i8* align 4 %x, i8 77, i64 16, i1 false) 52 ret void 53; CHECK: define void @MemSetTest 54; CHECK: call i8* @memset 55; CHECK: ret void 56} 57 58; CHECK-LABEL: @SwiftError 59; CHECK-NOT: __tsan_read 60; CHECK-NOT: __tsan_write 61; CHECK: ret 62define void @SwiftError(i8** swifterror) sanitize_thread { 63 %swifterror_ptr_value = load i8*, i8** %0 64 store i8* null, i8** %0 65 %swifterror_addr = alloca swifterror i8* 66 %swifterror_ptr_value_2 = load i8*, i8** %swifterror_addr 67 store i8* null, i8** %swifterror_addr 68 ret void 69} 70 71; CHECK-LABEL: @SwiftErrorCall 72; CHECK-NOT: __tsan_read 73; CHECK-NOT: __tsan_write 74; CHECK: ret 75define void @SwiftErrorCall(i8** swifterror) sanitize_thread { 76 %swifterror_addr = alloca swifterror i8* 77 store i8* null, i8** %0 78 call void @SwiftError(i8** %0) 79 ret void 80} 81 82; CHECK-LABEL: @NakedTest(i32* %a) 83; CHECK-NEXT: call void @foo() 84; CHECK-NEXT: %tmp1 = load i32, i32* %a, align 4 85; CHECK-NEXT: ret i32 %tmp1 86define i32 @NakedTest(i32* %a) naked sanitize_thread { 87 call void @foo() 88 %tmp1 = load i32, i32* %a, align 4 89 ret i32 %tmp1 90} 91 92declare void @foo() nounwind 93 94; CHECK: define internal void @tsan.module_ctor() 95; CHECK: call void @__tsan_init() 96