Skip to content

Commit

Permalink
[DebugInfo] Transfer strcmp DILocation to generated inline code (#108531
Browse files Browse the repository at this point in the history
)

When AggressiveInstCombine inlines a strcmp call, we currently copy the
strcmp's DILocation only to the br instruction that jumps to the inline
code. While this is roughly analogous to the original call, it leaves
the generated code without any source location, which is precarious for
a memory operation. This patch copies the strcmp call's DILocation to
all the generated code.

An alternative solution would be to generate a new DILocation with a
line 0 location and an inlinedAt pointing to the original call location,
but this would still give limited attribution to the generated code
without traversing the DIE, whereas the submitted solution allows
attribution with just the line table; even though it would be
technically more accurate, pragmatically I believe that copying the
call's location will be more useful for users.
  • Loading branch information
SLTozer committed Sep 23, 2024
1 parent 04d8e36 commit 40d6497
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,13 @@ void StrNCmpInliner::inlineCompare(Value *LHS, StringRef RHS, uint64_t N,
bool Swapped) {
auto &Ctx = CI->getContext();
IRBuilder<> B(Ctx);
// We want these instructions to be recognized as inlined instructions for the
// compare call, but we don't have a source location for the definition of
// that function, since we're generating that code now. Because the generated
// code is a viable point for a memory access error, we make the pragmatic
// choice here to directly use CI's location so that we have useful
// attribution for the generated code.
B.SetCurrentDebugLocation(CI->getDebugLoc());

BasicBlock *BBCI = CI->getParent();
BasicBlock *BBTail =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
;; Tests that when we replace a call to strcmp with compiler-generated inline
;; code, we pass the strcmp call's dbg location to the inline code.
; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s

@.str = constant [3 x i8] c"-h\00"

define i32 @main() {
; CHECK-LABEL: define i32 @main() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: br label %[[SUB_0:.*]], !dbg [[DBG4:![0-9]+]]
; CHECK: [[SUB_0]]:
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr null, align 1, !dbg [[DBG4]]
; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[TMP0]] to i32, !dbg [[DBG4]]
; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[TMP1]], 45, !dbg [[DBG4]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0, !dbg [[DBG4]]
; CHECK-NEXT: br i1 [[TMP3]], label %[[NE:.*]], label %[[SUB_1:.*]], !dbg [[DBG4]]
; CHECK: [[SUB_1]]:
; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr getelementptr inbounds (i8, ptr null, i64 1), align 1, !dbg [[DBG4]]
; CHECK-NEXT: [[TMP5:%.*]] = zext i8 [[TMP4]] to i32, !dbg [[DBG4]]
; CHECK-NEXT: [[TMP6:%.*]] = sub i32 [[TMP5]], 104, !dbg [[DBG4]]
; CHECK-NEXT: [[TMP7:%.*]] = icmp ne i32 [[TMP6]], 0, !dbg [[DBG4]]
; CHECK-NEXT: br i1 [[TMP7]], label %[[NE]], label %[[SUB_2:.*]], !dbg [[DBG4]]
; CHECK: [[SUB_2]]:
; CHECK-NEXT: br label %[[NE]], !dbg [[DBG4]]
; CHECK: [[NE]]:
; CHECK-NEXT: br label %[[ENTRY_TAIL:.*]], !dbg [[DBG4]]
; CHECK: [[ENTRY_TAIL]]:
; CHECK-NEXT: ret i32 0
;
entry:
%call.i = call i32 @strcmp(ptr null, ptr @.str), !dbg !4
%cmp.i.not = icmp eq i32 %call.i, 0
ret i32 0
}

declare i32 @strcmp(ptr, ptr)

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3}

!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 20.0.0git", isOptimized: true, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !2)
!1 = !DIFile(filename: "test.c", directory: "/tmp")
!2 = !{}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = !DILocation(line: 258, column: 10, scope: !5)
!5 = distinct !DISubprogram(name: "streq", scope: !1, file: !1, line: 257, type: !7, scopeLine: 257, unit: !0, retainedNodes: !2)
!7 = !DISubroutineType(types: !2)
;.
; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], producer: "{{.*}}clang version {{.*}}", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: [[META2:![0-9]+]], retainedTypes: [[META2]], globals: [[META2]])
; CHECK: [[META1]] = !DIFile(filename: "test.c", directory: {{.*}})
; CHECK: [[META2]] = !{}
; CHECK: [[DBG4]] = !DILocation(line: 258, column: 10, scope: [[META5:![0-9]+]])
; CHECK: [[META5]] = distinct !DISubprogram(name: "streq", scope: [[META1]], file: [[META1]], line: 257, type: [[META6:![0-9]+]], scopeLine: 257, spFlags: DISPFlagDefinition, unit: [[META0]], retainedNodes: [[META2]])
; CHECK: [[META6]] = !DISubroutineType(types: [[META2]])
;.

0 comments on commit 40d6497

Please sign in to comment.