From c808e665ce5a74ed37b807865b92646c4bbbbf3d Mon Sep 17 00:00:00 2001 From: Oliver Stannard Date: Thu, 26 Sep 2024 10:24:30 +0200 Subject: [PATCH] [DebugInfo] Don't emit .loc directive with all values zero (#109978) When emitting debug info for code alignment, it was possible to emit a .loc directive with a file number of zero, which is invalid for DWARF 4 and earlier. This happened because getCurrentDwarfLoc() returned a zero-initialised value when there hadn't been a previous .loc directive emitted. --------- Co-authored-by: Paul T Robinson --- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 10 ++++--- llvm/test/DebugInfo/ARM/align-func-start.ll | 30 +++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 llvm/test/DebugInfo/ARM/align-func-start.ll diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index e9649f9ff81658..f94240e6d2224b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -3682,8 +3682,10 @@ void DwarfDebug::beginCodeAlignment(const MachineBasicBlock &MBB) { return; auto PrevLoc = Asm->OutStreamer->getContext().getCurrentDwarfLoc(); - Asm->OutStreamer->emitDwarfLocDirective( - PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0, StringRef()); - MCDwarfLineEntry::make(Asm->OutStreamer.get(), - Asm->OutStreamer->getCurrentSectionOnly()); + if (PrevLoc.getLine()) { + Asm->OutStreamer->emitDwarfLocDirective( + PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0, StringRef()); + MCDwarfLineEntry::make(Asm->OutStreamer.get(), + Asm->OutStreamer->getCurrentSectionOnly()); + } } diff --git a/llvm/test/DebugInfo/ARM/align-func-start.ll b/llvm/test/DebugInfo/ARM/align-func-start.ll new file mode 100644 index 00000000000000..ebdf4b200dfffc --- /dev/null +++ b/llvm/test/DebugInfo/ARM/align-func-start.ll @@ -0,0 +1,30 @@ +; RUN: llc -mtriple=arm-none-eabi < %s | FileCheck %s +; RUN: llc -mtriple=arm-none-eabi < %s | llvm-mc --triple=arm-none-eabi -mcpu=cortex-m3 + +; Check that, when an aligned loop is the first thing in a function, we do not +; emit an invalid .loc directive, which is rejected by the assembly parser. + +; CHECK-NOT: .loc 0 +; CHECK: .loc 1 2 3 prologue_end +; CHECK-NOT: .loc 0 + +define dso_local void @foo() "target-cpu"="cortex-m3" !dbg !8 { +entry: + br label %while.body, !dbg !11 + +while.body: + br label %while.body, !dbg !11 +} + + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 20.0.0git (git@github.com:llvm/llvm-project.git 1c984b86b389bbc71c8c2988d1d707e2f32878bd)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/work/scratch") +!2 = !{i32 7, !"Dwarf Version", i32 4} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!8 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!9 = !DISubroutineType(types: !10) +!10 = !{null} +!11 = !DILocation(line: 2, column: 3, scope: !8)