From ad488d7cc95930a40a8bb4ef3d2f3f13540f442a Mon Sep 17 00:00:00 2001 From: Vladislav Dzhidzhoev Date: Wed, 20 Aug 2025 23:08:14 +0200 Subject: [PATCH 1/2] [DwarfDebug] Restore broken test llvm/test/DebugInfo/X86/pr12831.ll This test was added in 4d358b55fa to fix the issue with emission of empty DW_TAG_subprogram tags (https://bugs.llvm.org/show_bug.cgi?id=12831). However, the test output is not checked properly, and it contains: ``` 0x00000206: DW_TAG_subprogram 0x00000207: DW_TAG_reference_type DW_AT_type (0x00000169 "class ") ``` The reason is that the DIE for the definition DISubprogram "writeExpr" is created during the call to `getOrCreateSubprogramDIE(declaration of writeExpr)`. Therefore, when `getOrCreateSubprogramDIE(definition of writeExpr)` is first called, we get a recursive chain of calls: ``` getOrCreateSubprogramDIE(definition of writeExpr) ... getOrCreateSubprogramDIE(declaration of writeExpr) ... getOrCreateSubprogramDIE(definition of writeExpr) ``` The outer call doesn't expect that the DIE for the definition of writeExpr will be created during the creation of declaration DIE. In this PR, a check is added to fix that. I'm not sure whether the problem described in https://bugs.llvm.org/show_bug.cgi?id=12831 is still relevant (I wasn't able to reproduce the problem with C++ reproducer from there). But if this test stays in repo, it should be fixed. --- llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 4 +++ llvm/test/DebugInfo/X86/pr12831.ll | 37 ++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index b03fac2d22a52..a99e63672b4bb 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1351,6 +1351,10 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal) { ContextDIE = &getUnitDie(); // Build the decl now to ensure it precedes the definition. getOrCreateSubprogramDIE(SPDecl); + // Check whether the DIE for SP has already been created after the call + // above. + if (DIE *SPDie = getDIE(SP)) + return SPDie; } } diff --git a/llvm/test/DebugInfo/X86/pr12831.ll b/llvm/test/DebugInfo/X86/pr12831.ll index 402bc9aa04505..c37c017a52c29 100644 --- a/llvm/test/DebugInfo/X86/pr12831.ll +++ b/llvm/test/DebugInfo/X86/pr12831.ll @@ -1,4 +1,39 @@ -; RUN: llc %s -mtriple=x86_64-unknown-linux-gnu -o /dev/null +; RUN: llc %s -mtriple=x86_64-unknown-linux-gnu -filetype=obj -o - | llvm-dwarfdump - | FileCheck %s + +; Check that there are no empty DW_TAG_subprogram tags. +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT +; CHECK-NOT: DW_TAG_subprogram target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" From 50789dd0e4008b4d9601ecb1e7202470ffbce6ed Mon Sep 17 00:00:00 2001 From: Vladislav Dzhidzhoev Date: Wed, 27 Aug 2025 18:19:07 +0200 Subject: [PATCH 2/2] Added FIXME comment --- llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index a99e63672b4bb..477b66484c20c 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1353,6 +1353,9 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal) { getOrCreateSubprogramDIE(SPDecl); // Check whether the DIE for SP has already been created after the call // above. + // FIXME: Should the creation of definition subprogram DIE during + // the creation of declaration subprogram DIE be allowed? + // See https://github.com/llvm/llvm-project/pull/154636. if (DIE *SPDie = getDIE(SP)) return SPDie; }