[llvm] [NVPTX] Fix for LTO dwarf emission when multiple CUs with a mix of DebugDirectivesOnly and NoDebug (PR #190371)

via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 3 10:43:08 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-debuginfo

@llvm/pr-subscribers-llvm-ir

Author: Daniel Donenfeld (daniel-donenfeld)

<details>
<summary>Changes</summary>

Only emit the initial .loc dwarf directive if the CU requires debug information. When a module contains multiple CUs where one is DebugDirectiveOnly and the rest are NoDebug, we attempt to emit dwarf for the NoDebug compile units leading to an assertion when calling emitDwarfFile0Directive when in getOrCreateDwarfCompileUnit. I added a lit test for this case which used to assert.

---
Full diff: https://github.com/llvm/llvm-project/pull/190371.diff


3 Files Affected:

- (modified) llvm/include/llvm/IR/DebugInfoMetadata.h (+1) 
- (modified) llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp (+5-1) 
- (added) llvm/test/DebugInfo/NVPTX/no-debug-loc.ll (+46) 


``````````diff
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index e28b47d87d4e5..77307294f1be2 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -2123,6 +2123,7 @@ class DICompileUnit : public DIScope {
   DebugEmissionKind getEmissionKind() const {
     return (DebugEmissionKind)EmissionKind;
   }
+  bool isNoDebug() const { return EmissionKind == NoDebug; }
   bool isDebugDirectivesOnly() const {
     return EmissionKind == DebugDirectivesOnly;
   }
diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
index 9e7a58498040e..8ffdfe749ed7b 100644
--- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
@@ -377,7 +377,11 @@ void NVPTXAsmPrinter::emitFunctionEntryLabel() {
   // Emit initial .loc debug directive for correct relocation symbol data.
   if (const DISubprogram *SP = MF->getFunction().getSubprogram()) {
     assert(SP->getUnit());
-    if (!SP->getUnit()->isDebugDirectivesOnly())
+    // NoDebug and DebugDirectivesOnly do not require emitting the initial loc
+    // directive. NoDebug does not require any debug directives and the initial
+    // loc directive is not needed for DebugDirectivesOnly as it is redundant
+    // assuming this is a non-empty function.
+    if (!SP->getUnit()->isDebugDirectivesOnly() && !SP->getUnit()->isNoDebug())
       emitInitialRawDwarfLocDirective(*MF);
   }
 }
diff --git a/llvm/test/DebugInfo/NVPTX/no-debug-loc.ll b/llvm/test/DebugInfo/NVPTX/no-debug-loc.ll
new file mode 100644
index 0000000000000..8b4a4039cac6e
--- /dev/null
+++ b/llvm/test/DebugInfo/NVPTX/no-debug-loc.ll
@@ -0,0 +1,46 @@
+; RUN: llc < %s -mtriple=nvptx64-nvidia-cuda | FileCheck %s
+; RUN: %if ptxas %{ llc < %s -mtriple=nvptx64-nvidia-cuda | %ptxas-verify %}
+
+;; When a module contains multiple CUs where one is DebugDirectiveOnly and
+;; the rest are NoDebug, we would attempt to emit dwarf directives for the
+;; NoDebug CUs leading to an assertion. This test verifies that we only emit
+;; dwarf directives for the DebugDirectiveOnly CU.
+
+define i32 @foo(i32 %a, i32 %b) !dbg !5 {
+
+; CHECK:     .loc    [[FILE:[0-9]+]] 26 0          // debug_directives_only.cu:26:0
+; CHECK-NOT: .loc    [[FILE]]        26 0          // debug_directives_only.cu:26:0
+; CHECK:     .loc    [[FILE]]        40 22         // debug_directives_only.cu:40:22
+
+  %add = add i32 %b, %a, !dbg !8
+  ret i32 %add, !dbg !8
+}
+
+define i32 @bar(i32 %a, i32 %b) !dbg !40 {
+
+; CHECK-NOT: .loc
+
+  %add = add i32 %b, %a, !dbg !41
+  ret i32 %add, !dbg !41
+}
+
+; CHECK:     .file   [[FILE]] "/test/directory/debug_directives_only.cu"
+; CHECK-NOT: .file   {{[0-9]*}} "/test/directory/no_debug.cu"
+
+!llvm.dbg.cu = !{!0, !2}
+!nvvm.annotations = !{}
+!llvm.module.flags = !{!4}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: DebugDirectivesOnly)
+!1 = !DIFile(filename: "debug_directives_only.cu", directory: "/test/directory/")
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: NoDebug)
+!3 = !DIFile(filename: "no_debug.cu", directory: "/test/directory/")
+!4 = !{i32 1, !"Debug Info Version", i32 3}
+!5 = distinct !DISubprogram(name: "kernel", linkageName: "foo", scope: !1, file: !1, line: 123, type: !6, scopeLine: 26, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
+!6 = !DISubroutineType(types: !7)
+!7 = !{}
+!8 = !DILocation(line: 40, column: 22, scope: !31)
+!31 = distinct !DILexicalBlock(scope: !5, file: !1, line: 3, column: 17)
+!40 = distinct !DISubprogram(name: "kernel", linkageName: "bar", scope: !3, file: !3, line: 234, type: !6, scopeLine: 26, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)
+!41 = !DILocation(line: 40, column: 22, scope: !42)
+!42 = distinct !DILexicalBlock(scope: !40, file: !3, line: 6, column: 8)

``````````

</details>


https://github.com/llvm/llvm-project/pull/190371


More information about the llvm-commits mailing list