Skip to content

Commit

Permalink
[ThreadSanitizer] Add fallback DebugLocation for memintrinsic calls
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
melver committed Jul 17, 2023
1 parent 913f7e9 commit 4eef2e3
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ static ConstantInt *createOrdering(IRBuilder<> *IRB, AtomicOrdering ord) {
// replaced back with intrinsics. If that becomes wrong at some point,
// we will need to call e.g. __tsan_memset to avoid the intrinsics.
bool ThreadSanitizer::instrumentMemIntrinsic(Instruction *I) {
IRBuilder<> IRB(I);
InstrumentationIRBuilder IRB(I);
if (MemSetInst *M = dyn_cast<MemSetInst>(I)) {
IRB.CreateCall(
MemsetFn,
Expand Down
23 changes: 19 additions & 4 deletions llvm/test/Instrumentation/ThreadSanitizer/missing_dbg.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,22 @@ entry:
}
; CHECK-LABEL: @with_dbg
; CHECK-NEXT: entry:
; CHECK: call void @__tsan_func_entry(ptr %0), !dbg [[DBG:![0-9]+]]
; CHECK: call void @__tsan_read4(ptr %a), !dbg [[DBG]]
; CHECK: call void @__tsan_func_exit(), !dbg [[DBG]]
; CHECK: call void @__tsan_func_entry(ptr %0), !dbg [[DBG1:![0-9]+]]
; CHECK: call void @__tsan_read4(ptr %a), !dbg [[DBG1]]
; CHECK: call void @__tsan_func_exit(), !dbg [[DBG1]]

declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1)

define void @memintrinsic(ptr nocapture %x, ptr nocapture %y) sanitize_thread !dbg !7 {
entry:
tail call void @llvm.memcpy.p0.p0.i64(ptr align 4 %x, ptr align 4 %y, i64 16, i1 false)
ret void
}
; CHECK-LABEL: @memintrinsic
; CHECK-NEXT: entry:
; CHECK: call void @__tsan_func_entry(ptr %0), !dbg [[DBG2:![0-9]+]]
; CHECK: call ptr @__tsan_memcpy(ptr %x, ptr %y, i64 16), !dbg [[DBG2]]
; CHECK: call void @__tsan_func_exit(), !dbg [[DBG2]]

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

; CHECK: [[DBG]] = !DILocation(line: 0, scope: !3)
; CHECK: [[DBG1]] = !DILocation(line: 0, scope: !3)
; CHECK: [[DBG2]] = !DILocation(line: 0, scope: !7)

0 comments on commit 4eef2e3

Please sign in to comment.