Skip to content

Commit 4eef2e3

Browse files
committed
[ThreadSanitizer] Add fallback DebugLocation for memintrinsic calls
When building with debug info enabled, some load/store instructions do not have a DebugLocation attached. When using the default IRBuilder, it attempts to copy the DebugLocation from the insertion-point instruction. When there's no DebugLocation, no attempt is made to add one. Add a fallback DebugLocation with the help of InstrumentationIRBuilder for memintrinsics. In particular, the compiler may optimize load/store without debug info into memintrinsics, which then are missing debug info as well.
1 parent 913f7e9 commit 4eef2e3

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ static ConstantInt *createOrdering(IRBuilder<> *IRB, AtomicOrdering ord) {
689689
// replaced back with intrinsics. If that becomes wrong at some point,
690690
// we will need to call e.g. __tsan_memset to avoid the intrinsics.
691691
bool ThreadSanitizer::instrumentMemIntrinsic(Instruction *I) {
692-
IRBuilder<> IRB(I);
692+
InstrumentationIRBuilder IRB(I);
693693
if (MemSetInst *M = dyn_cast<MemSetInst>(I)) {
694694
IRB.CreateCall(
695695
MemsetFn,

llvm/test/Instrumentation/ThreadSanitizer/missing_dbg.ll

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,22 @@ entry:
99
}
1010
; CHECK-LABEL: @with_dbg
1111
; CHECK-NEXT: entry:
12-
; CHECK: call void @__tsan_func_entry(ptr %0), !dbg [[DBG:![0-9]+]]
13-
; CHECK: call void @__tsan_read4(ptr %a), !dbg [[DBG]]
14-
; CHECK: call void @__tsan_func_exit(), !dbg [[DBG]]
12+
; CHECK: call void @__tsan_func_entry(ptr %0), !dbg [[DBG1:![0-9]+]]
13+
; CHECK: call void @__tsan_read4(ptr %a), !dbg [[DBG1]]
14+
; CHECK: call void @__tsan_func_exit(), !dbg [[DBG1]]
15+
16+
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1)
17+
18+
define void @memintrinsic(ptr nocapture %x, ptr nocapture %y) sanitize_thread !dbg !7 {
19+
entry:
20+
tail call void @llvm.memcpy.p0.p0.i64(ptr align 4 %x, ptr align 4 %y, i64 16, i1 false)
21+
ret void
22+
}
23+
; CHECK-LABEL: @memintrinsic
24+
; CHECK-NEXT: entry:
25+
; CHECK: call void @__tsan_func_entry(ptr %0), !dbg [[DBG2:![0-9]+]]
26+
; CHECK: call ptr @__tsan_memcpy(ptr %x, ptr %y, i64 16), !dbg [[DBG2]]
27+
; CHECK: call void @__tsan_func_exit(), !dbg [[DBG2]]
1528

1629
define i32 @without_dbg(ptr %a) sanitize_thread {
1730
entry:
@@ -36,5 +49,7 @@ entry:
3649
!3 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 190, type: !4, scopeLine: 192, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0)
3750
!4 = !DISubroutineType(types: !5)
3851
!5 = !{}
52+
!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 195, type: !4, scopeLine: 199, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0)
3953

40-
; CHECK: [[DBG]] = !DILocation(line: 0, scope: !3)
54+
; CHECK: [[DBG1]] = !DILocation(line: 0, scope: !3)
55+
; CHECK: [[DBG2]] = !DILocation(line: 0, scope: !7)

0 commit comments

Comments
 (0)