[llvm] [DwarfDebug] Avoid generating extra DW_TAG_subprogram entries (PR #154636)
Vladislav Dzhidzhoev via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 27 09:20:42 PDT 2025
https://github.com/dzhidzhoev updated https://github.com/llvm/llvm-project/pull/154636
>From ad488d7cc95930a40a8bb4ef3d2f3f13540f442a Mon Sep 17 00:00:00 2001
From: Vladislav Dzhidzhoev <vdzhidzhoev at accesssoftek.com>
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 <vdzhidzhoev at accesssoftek.com>
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;
}
More information about the llvm-commits
mailing list