[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