[Mlir-commits] [mlir] 8f48e19 - [mlir][LLVMIR] Add export coverage for retained local variables (#209911)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Mon Jul 20 23:12:44 PDT 2026


Author: qyingwu
Date: 2026-07-21T08:12:38+02:00
New Revision: 8f48e1980f9da4e4d859c1c2713561195d043454

URL: https://github.com/llvm/llvm-project/commit/8f48e1980f9da4e4d859c1c2713561195d043454
DIFF: https://github.com/llvm/llvm-project/commit/8f48e1980f9da4e4d859c1c2713561195d043454.diff

LOG: [mlir][LLVMIR] Add export coverage for retained local variables (#209911)

Adds export coverage for a retained local variable case where MLIR may
contain separate `DILocalVariableAttr`s for the same source-level
variable.

A local variable can appear both in a `DISubprogram`'s `retainedNodes`
and in a debug intrinsic such as `dbg.value` or `dbg.declare`. During
import, the `retainedNodes` path may see the variable while the
containing subprogram is represented by a self-recursive placeholder,
while the debug intrinsic path later sees the finalized subprogram. This
can produce two MLIR local variable attrs with different subprogram
scopes.

The exported LLVM IR debug metadata is still canonical for this case:
both the debug intrinsic and the subprogram `retainedNodes` reference
the same `DILocalVariable` metadata node. This patch adds regression
coverage for that export behavior without extending the recursive
debug-info machinery.

Added: 
    

Modified: 
    mlir/test/Target/LLVMIR/llvmir-debug.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
index 72dadb2602c52..b93a38be6634d 100644
--- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
@@ -421,6 +421,53 @@ llvm.func @imp_fn() {
 
 // -----
 
+// Retained local variables may be represented separately from debug intrinsic
+// variables in MLIR. Ensure export reuses a single LLVM DILocalVariable node.
+
+#file = #llvm.di_file<"test.c" in "">
+#cu = #llvm.di_compile_unit<
+  id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #file
+>
+#void = #llvm.di_null_type
+#int = #llvm.di_basic_type<
+  tag = DW_TAG_base_type, name = "int",
+  sizeInBits = 32, encoding = DW_ATE_signed
+>
+#sp_self = #llvm.di_subprogram<recId = distinct[1]<>, isRecSelf = true>
+#retained_local = #llvm.di_local_variable<
+  scope = #sp_self, name = "retained_arg", file = #file,
+  line = 1, arg = 1, type = #int
+>
+#sp_type = #llvm.di_subroutine_type<types = #void, #int>
+#sp = #llvm.di_subprogram<
+  recId = distinct[1]<>, id = distinct[2]<>, compileUnit = #cu,
+  scope = #file, name = "fn_with_retained_local_export",
+  file = #file, line = 1, scopeLine = 1, subprogramFlags = Definition,
+  type = #sp_type, retainedNodes = [#retained_local]
+>
+#dbg_local = #llvm.di_local_variable<
+  scope = #sp, name = "retained_arg", file = #file,
+  line = 1, arg = 1, type = #int
+>
+
+// CHECK-LABEL: define void @fn_with_retained_local_export(
+// CHECK-SAME: i32 %[[ARG:.*]]) !dbg ![[SP:[0-9]+]]
+llvm.func @fn_with_retained_local_export(%arg0: i32) {
+  // RECORDS: #dbg_value(i32 %[[ARG]], ![[LOCAL:[0-9]+]],
+  // RECORDS-SAME: !DIExpression(), !{{.*}})
+  llvm.intr.dbg.value #dbg_local = %arg0 : i32 loc(fused<#sp>["test.c":1:1])
+  llvm.return
+} loc(fused<#sp>["test.c":1:1])
+
+// CHECK-DAG: ![[SP]] = distinct !DISubprogram(
+// CHECK-SAME: name: "fn_with_retained_local_export"
+// CHECK-SAME: retainedNodes: ![[NODES:[0-9]+]]
+// CHECK-DAG: ![[NODES]] = !{![[LOCAL]]}
+// CHECK-DAG: ![[LOCAL]] = !DILocalVariable(name: "retained_arg", arg: 1,
+// CHECK-SAME: scope: ![[SP]]
+
+// -----
+
 // Nameless and scopeless global constant.
 
 // CHECK-LABEL: @.str.1 = external constant [10 x i8]


        


More information about the Mlir-commits mailing list