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)