[llvm] [DebugInfo] Fix line 0 records incorrectly having is_stmt set (PR #166627)

via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 7 19:28:19 PST 2025


https://github.com/RoshanYSingh23 updated https://github.com/llvm/llvm-project/pull/166627

>From 2c456779cce2aa252cec637a00501942197bb933 Mon Sep 17 00:00:00 2001
From: RoshanYSingh23 <roshanroshys at gmail.com>
Date: Sat, 8 Nov 2025 07:35:35 +0530
Subject: [PATCH] [DebugInfo] Fix line 0 records incorrectly having is_stmt set

Fixes issue #33870 (Bugzilla #34522)

Line 0 debug records should not have the is_stmt flag set in DWARF.
This change ensures is_stmt is only set for non-zero line numbers.

Changes made in DwarfDebug.cpp:
- beginInstruction: Only set is_stmt for prologue_end if line != 0
- beginInstruction: Only set is_stmt for key instructions if line != 0
- emitInitialLocDirective: Set is_stmt=0 if scopeLine == 0

Added two test cases to verify the behavior:
- llvm/test/DebugInfo/X86/line-0-no-is-stmt.ll: Verifies line 0 does not get is_stmt
- llvm/test/DebugInfo/X86/line-nonzero-has-is-stmt.ll: Verifies non-zero lines do get is_stmt
---
 llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp    | 15 ++++++---
 llvm/test/DebugInfo/X86/line-0-no-is-stmt.ll  | 33 +++++++++++++++++++
 .../DebugInfo/X86/line-nonzero-has-is-stmt.ll | 30 +++++++++++++++++
 3 files changed, 74 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/DebugInfo/X86/line-0-no-is-stmt.ll
 create mode 100644 llvm/test/DebugInfo/X86/line-nonzero-has-is-stmt.ll

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 567acf75d1b8d..6730b48592321 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -2199,12 +2199,16 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
   if (DL.getLine() == 0 && LastAsmLine == 0)
     return;
   if (MI == PrologEndLoc) {
-    Flags |= DWARF2_FLAG_PROLOGUE_END | DWARF2_FLAG_IS_STMT;
+    Flags |= DWARF2_FLAG_PROLOGUE_END;
+    // Don't set is_stmt for line 0
+    if (DL.getLine() != 0)
+      Flags |= DWARF2_FLAG_IS_STMT;
     PrologEndLoc = nullptr;
   }
 
   if (ScopeUsesKeyInstructions) {
-    if (IsKey)
+    // Don't set is_stmt for line 0
+    if (IsKey && DL.getLine() != 0)
       Flags |= DWARF2_FLAG_IS_STMT;
   } else {
     // If the line changed, we call that a new statement; unless we went to
@@ -2400,8 +2404,11 @@ DwarfDebug::emitInitialLocDirective(const MachineFunction &MF, unsigned CUID) {
   (void)getOrCreateDwarfCompileUnit(SP->getUnit());
   // We'd like to list the prologue as "not statements" but GDB behaves
   // poorly if we do that. Revisit this with caution/GDB (7.5+) testing.
-  ::recordSourceLine(*Asm, SP->getScopeLine(), 0, SP, DWARF2_FLAG_IS_STMT,
-                     CUID, getDwarfVersion(), getUnits());
+  // However, we should not set is_stmt for line 0.
+  unsigned ScopeLine = SP->getScopeLine();
+  unsigned Flags = (ScopeLine != 0) ? DWARF2_FLAG_IS_STMT : 0;
+  ::recordSourceLine(*Asm, ScopeLine, 0, SP, Flags, CUID, getDwarfVersion(),
+                     getUnits());
   return PrologEndLoc;
 }
 
diff --git a/llvm/test/DebugInfo/X86/line-0-no-is-stmt.ll b/llvm/test/DebugInfo/X86/line-0-no-is-stmt.ll
new file mode 100644
index 0000000000000..1b268197e3681
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/line-0-no-is-stmt.ll
@@ -0,0 +1,33 @@
+; Test that line 0 records don't have is_stmt set
+; This tests the fix for LLVM issue #33870 (Bugzilla #34522)
+;
+; When scopeLine is 0, the initial location directive should not have is_stmt set.
+
+; RUN: %llc_dwarf -mtriple=x86_64-unknown-linux -O0 -filetype=obj < %s | llvm-dwarfdump --debug-line - | FileCheck %s
+
+; The line table entry for line 0 should exist but not have "is_stmt" in its Flags
+; CHECK: Address
+; CHECK: 0x{{[0-9a-f]+}} 0 0
+; CHECK-NOT: is_stmt
+; CHECK: end_sequence
+
+define void @foo() !dbg !6 {
+entry:
+  ret void, !dbg !9
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
+!1 = !DIFile(filename: "test.c", directory: "/tmp")
+!2 = !{i32 2, !"Dwarf Version", i32 4}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"wchar_size", i32 4}
+!5 = !{}
+; scopeLine is 0 (line 0 should not have is_stmt)
+!6 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 10, type: !7, scopeLine: 0, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !5)
+!7 = !DISubroutineType(types: !8)
+!8 = !{null}
+; Line 0 location (should not have is_stmt)
+!9 = !DILocation(line: 0, column: 0, scope: !6)
diff --git a/llvm/test/DebugInfo/X86/line-nonzero-has-is-stmt.ll b/llvm/test/DebugInfo/X86/line-nonzero-has-is-stmt.ll
new file mode 100644
index 0000000000000..a708810384bf3
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/line-nonzero-has-is-stmt.ll
@@ -0,0 +1,30 @@
+; Test that non-zero line records DO have is_stmt set
+; This is for comparison with line 0 behavior (issue #33870 / Bugzilla #34522)
+;
+; When scopeLine is non-zero, the initial location directive should have is_stmt set.
+
+; RUN: %llc_dwarf -mtriple=x86_64-unknown-linux -O0 -filetype=obj < %s | llvm-dwarfdump --debug-line - | FileCheck %s
+
+; With scopeLine=10, we should see line 10 with is_stmt and prologue_end
+; CHECK: 0x{{[0-9a-f]+}} 10 {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} is_stmt prologue_end
+
+define void @bar() !dbg !6 {
+entry:
+  ret void, !dbg !9
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
+!1 = !DIFile(filename: "test.c", directory: "/tmp")
+!2 = !{i32 2, !"Dwarf Version", i32 4}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"wchar_size", i32 4}
+!5 = !{}
+; scopeLine is 10 (non-zero line should have is_stmt)
+!6 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 10, type: !7, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !5)
+!7 = !DISubroutineType(types: !8)
+!8 = !{null}
+; Line 10 location (should have is_stmt)
+!9 = !DILocation(line: 10, column: 5, scope: !6)



More information about the llvm-commits mailing list