140 lines · plain
1; RUN: opt < %s -passes=tsan -S | FileCheck %s2 3target 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"4 5declare void @escape(ptr)6 7@sink = global ptr null, align 48 9define void @captured0() nounwind uwtable sanitize_thread {10entry:11 %ptr = alloca i32, align 412 ; escapes due to call13 call void @escape(ptr %ptr)14 store i32 42, ptr %ptr, align 415 ret void16}17; CHECK-LABEL: define void @captured018; CHECK: __tsan_write19; CHECK: ret void20 21define void @captured1() nounwind uwtable sanitize_thread {22entry:23 %ptr = alloca i32, align 424 ; escapes due to store into global25 store ptr %ptr, ptr @sink, align 826 store i32 42, ptr %ptr, align 427 ret void28}29; CHECK-LABEL: define void @captured130; CHECK: __tsan_write31; CHECK: __tsan_write32; CHECK: ret void33 34define void @captured2() nounwind uwtable sanitize_thread {35entry:36 %ptr = alloca i32, align 437 %tmp = alloca ptr, align 838 ; transitive escape39 store ptr %ptr, ptr %tmp, align 840 %0 = load ptr, ptr %tmp, align 841 store ptr %0, ptr @sink, align 842 store i32 42, ptr %ptr, align 443 ret void44}45; CHECK-LABEL: define void @captured246; CHECK: __tsan_write47; CHECK: __tsan_write48; CHECK-NOT: __tsan_write49; CHECK: ret void50 51define void @captured3() nounwind uwtable sanitize_thread {52entry:53 %stkobj = alloca [2 x i32], align 854 ; escapes due to store into global55 store ptr %stkobj, ptr @sink, align 856 ; derived is captured as its base object is captured57 %derived = getelementptr inbounds i32, ptr %stkobj, i64 158 store i32 42, ptr %derived, align 459 ret void60}61; CHECK-LABEL: define void @captured362; CHECK: __tsan_write63; CHECK: __tsan_write64; CHECK: ret void65 66define void @notcaptured0() nounwind uwtable sanitize_thread {67entry:68 %ptr = alloca i32, align 469 store i32 42, ptr %ptr, align 470 ; escapes due to call71 call void @escape(ptr %ptr)72 ret void73}74; CHECK-LABEL: define void @notcaptured075; CHECK: __tsan_write76; CHECK: ret void77 78define void @notcaptured1() nounwind uwtable sanitize_thread {79entry:80 %ptr = alloca i32, align 481 store i32 42, ptr %ptr, align 482 ; escapes due to store into global83 store ptr %ptr, ptr @sink, align 884 ret void85}86; CHECK-LABEL: define void @notcaptured187; CHECK: __tsan_write88; CHECK: __tsan_write89; CHECK: ret void90 91define void @notcaptured2() nounwind uwtable sanitize_thread {92entry:93 %ptr = alloca i32, align 494 %tmp = alloca ptr, align 895 store i32 42, ptr %ptr, align 496 ; transitive escape97 store ptr %ptr, ptr %tmp, align 898 %0 = load ptr, ptr %tmp, align 899 store ptr %0, ptr @sink, align 8100 ret void101}102; CHECK-LABEL: define void @notcaptured2103; CHECK: __tsan_write104; CHECK: __tsan_write105; CHECK-NOT: __tsan_write106; CHECK: ret void107 108define void @notcaptured3(i1 %cond) nounwind uwtable sanitize_thread {109entry:110 %stkobj = alloca [2 x i32], align 8111 %derived = getelementptr inbounds i32, ptr %stkobj, i64 1112 %ptr = select i1 %cond, ptr %derived, ptr %stkobj113 store i32 42, ptr %ptr, align 4114 ret void115}116; CHECK-LABEL: define void @notcaptured3117; CHECK-NOT: call void @__tsan_write4(ptr %ptr)118; CHECK: ret void119 120define void @notcaptured4() nounwind uwtable sanitize_thread {121entry:122 %stkobj = alloca [10 x i8], align 1123 br label %loop124 125exit:126 ret void127 128loop:129 %count = phi i32 [ 0, %entry ], [ %addone, %loop ]130 %derived = phi ptr [ %stkobj, %entry ], [ %ptraddone, %loop ]131 store i32 %count, ptr %derived, align 4132 %ptraddone = getelementptr inbounds i32, ptr %derived, i64 1133 %addone = add nuw nsw i32 %count, 1134 %eq10 = icmp eq i32 %addone, 10135 br i1 %eq10, label %exit, label %loop136}137; CHECK-LABEL: define void @notcaptured4138; CHECK: ret void139; CHECK-NOT: call void @__tsan_write4(ptr %derived)140