1 ; RUN: opt < %s -tsan -S | FileCheck %s 2 3 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" 4 target triple = "x86_64-unknown-linux-gnu" 5 6 define i32 @read_4_bytes(i32* %a) sanitize_thread { 7 entry: 8 %tmp1 = load i32, i32* %a, align 4 9 ret i32 %tmp1 10 } 11 12 ; CHECK: @llvm.global_ctors = {{.*}}@tsan.module_ctor 13 14 ; CHECK: define i32 @read_4_bytes(i32* %a) 15 ; CHECK: call void @__tsan_func_entry(i8* %0) 16 ; CHECK-NEXT: %1 = bitcast i32* %a to i8* 17 ; CHECK-NEXT: call void @__tsan_read4(i8* %1) 18 ; CHECK-NEXT: %tmp1 = load i32, i32* %a, align 4 19 ; CHECK-NEXT: call void @__tsan_func_exit() 20 ; CHECK: ret i32 21 22 23 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) 24 declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) 25 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) 26 27 28 ; Check that tsan converts mem intrinsics back to function calls. 29 30 define void @MemCpyTest(i8* nocapture %x, i8* nocapture %y) sanitize_thread { 31 entry: 32 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %x, i8* %y, i64 16, i32 4, i1 false) 33 ret void 34 ; CHECK: define void @MemCpyTest 35 ; CHECK: call i8* @memcpy 36 ; CHECK: ret void 37 } 38 39 define void @MemMoveTest(i8* nocapture %x, i8* nocapture %y) sanitize_thread { 40 entry: 41 tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %x, i8* %y, i64 16, i32 4, i1 false) 42 ret void 43 ; CHECK: define void @MemMoveTest 44 ; CHECK: call i8* @memmove 45 ; CHECK: ret void 46 } 47 48 define void @MemSetTest(i8* nocapture %x) sanitize_thread { 49 entry: 50 tail call void @llvm.memset.p0i8.i64(i8* %x, i8 77, i64 16, i32 4, i1 false) 51 ret void 52 ; CHECK: define void @MemSetTest 53 ; CHECK: call i8* @memset 54 ; CHECK: ret void 55 } 56 57 ; CHECK: define internal void @tsan.module_ctor() 58 ; CHECK: call void @__tsan_init() 59