Yussur Mustafa Oraji ded1f3ec96
[TSan] Add option to ignore capturing behavior when instrumenting (#148156)
While not needed for most applications, some tools such as
[MUST](https://www.i12.rwth-aachen.de/cms/i12/forschung/forschungsschwerpunkte/lehrstuhl-fuer-hochleistungsrechnen/~nrbe/must/)
depend on the instrumentation being present.
MUST uses the ThreadSanitizer annotation interface to detect data races
in MPI programs, where the capture tracking is detrimental as it has no
bearing on MPI data races, leading to missed races.
2025-08-06 15:47:33 +02:00

140 lines
3.7 KiB
LLVM

; RUN: opt < %s -passes=tsan -S | FileCheck %s
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"
declare void @escape(ptr)
@sink = global ptr null, align 4
define void @captured0() nounwind uwtable sanitize_thread {
entry:
%ptr = alloca i32, align 4
; escapes due to call
call void @escape(ptr %ptr)
store i32 42, ptr %ptr, align 4
ret void
}
; CHECK-LABEL: define void @captured0
; CHECK: __tsan_write
; CHECK: ret void
define void @captured1() nounwind uwtable sanitize_thread {
entry:
%ptr = alloca i32, align 4
; escapes due to store into global
store ptr %ptr, ptr @sink, align 8
store i32 42, ptr %ptr, align 4
ret void
}
; CHECK-LABEL: define void @captured1
; CHECK: __tsan_write
; CHECK: __tsan_write
; CHECK: ret void
define void @captured2() nounwind uwtable sanitize_thread {
entry:
%ptr = alloca i32, align 4
%tmp = alloca ptr, align 8
; transitive escape
store ptr %ptr, ptr %tmp, align 8
%0 = load ptr, ptr %tmp, align 8
store ptr %0, ptr @sink, align 8
store i32 42, ptr %ptr, align 4
ret void
}
; CHECK-LABEL: define void @captured2
; CHECK: __tsan_write
; CHECK: __tsan_write
; CHECK-NOT: __tsan_write
; CHECK: ret void
define void @captured3() nounwind uwtable sanitize_thread {
entry:
%stkobj = alloca [2 x i32], align 8
; escapes due to store into global
store ptr %stkobj, ptr @sink, align 8
; derived is captured as its base object is captured
%derived = getelementptr inbounds i32, ptr %stkobj, i64 1
store i32 42, ptr %derived, align 4
ret void
}
; CHECK-LABEL: define void @captured3
; CHECK: __tsan_write
; CHECK: __tsan_write
; CHECK: ret void
define void @notcaptured0() nounwind uwtable sanitize_thread {
entry:
%ptr = alloca i32, align 4
store i32 42, ptr %ptr, align 4
; escapes due to call
call void @escape(ptr %ptr)
ret void
}
; CHECK-LABEL: define void @notcaptured0
; CHECK: __tsan_write
; CHECK: ret void
define void @notcaptured1() nounwind uwtable sanitize_thread {
entry:
%ptr = alloca i32, align 4
store i32 42, ptr %ptr, align 4
; escapes due to store into global
store ptr %ptr, ptr @sink, align 8
ret void
}
; CHECK-LABEL: define void @notcaptured1
; CHECK: __tsan_write
; CHECK: __tsan_write
; CHECK: ret void
define void @notcaptured2() nounwind uwtable sanitize_thread {
entry:
%ptr = alloca i32, align 4
%tmp = alloca ptr, align 8
store i32 42, ptr %ptr, align 4
; transitive escape
store ptr %ptr, ptr %tmp, align 8
%0 = load ptr, ptr %tmp, align 8
store ptr %0, ptr @sink, align 8
ret void
}
; CHECK-LABEL: define void @notcaptured2
; CHECK: __tsan_write
; CHECK: __tsan_write
; CHECK-NOT: __tsan_write
; CHECK: ret void
define void @notcaptured3(i1 %cond) nounwind uwtable sanitize_thread {
entry:
%stkobj = alloca [2 x i32], align 8
%derived = getelementptr inbounds i32, ptr %stkobj, i64 1
%ptr = select i1 %cond, ptr %derived, ptr %stkobj
store i32 42, ptr %ptr, align 4
ret void
}
; CHECK-LABEL: define void @notcaptured3
; CHECK-NOT: call void @__tsan_write4(ptr %ptr)
; CHECK: ret void
define void @notcaptured4() nounwind uwtable sanitize_thread {
entry:
%stkobj = alloca [10 x i8], align 1
br label %loop
exit:
ret void
loop:
%count = phi i32 [ 0, %entry ], [ %addone, %loop ]
%derived = phi ptr [ %stkobj, %entry ], [ %ptraddone, %loop ]
store i32 %count, ptr %derived, align 4
%ptraddone = getelementptr inbounds i32, ptr %derived, i64 1
%addone = add nuw nsw i32 %count, 1
%eq10 = icmp eq i32 %addone, 10
br i1 %eq10, label %exit, label %loop
}
; CHECK-LABEL: define void @notcaptured4
; CHECK: ret void
; CHECK-NOT: call void @__tsan_write4(ptr %derived)