[llvm] [DebugInfo] Transfer strcmp DILocation to generated inline code (PR #108531)
Stephen Tozer via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 13 03:49:22 PDT 2024
https://github.com/SLTozer created https://github.com/llvm/llvm-project/pull/108531
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; even though it would be technically more accurate, pragmatically I believe that copying the call's location will be more useful for users.
>From a85f00d6bac5f17416b977a5ab0d86d30a3d0258 Mon Sep 17 00:00:00 2001
From: Stephen Tozer <stephen.tozer at sony.com>
Date: Fri, 13 Sep 2024 11:35:29 +0100
Subject: [PATCH] [DebugInfo] Transfer strcmp DILocation to generated inline
code
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; even though it would be technically more accurate,
pragmatically I believe that copying the call's location will be more
useful for users.
---
.../AggressiveInstCombine.cpp | 7 +++
.../inline-strcmp-debugloc.ll | 56 +++++++++++++++++++
2 files changed, 63 insertions(+)
create mode 100644 llvm/test/Transforms/AggressiveInstCombine/inline-strcmp-debugloc.ll
diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index 09ffc2d184f18b..01642b0677aba3 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -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 =
diff --git a/llvm/test/Transforms/AggressiveInstCombine/inline-strcmp-debugloc.ll b/llvm/test/Transforms/AggressiveInstCombine/inline-strcmp-debugloc.ll
new file mode 100644
index 00000000000000..94c912876d7b94
--- /dev/null
+++ b/llvm/test/Transforms/AggressiveInstCombine/inline-strcmp-debugloc.ll
@@ -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
+
+ at .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]])
+;.
More information about the llvm-commits
mailing list