[flang-commits] [flang] [flang][debug] Spill a call-defined address for dbg_declare (PR #235169)
via flang-commits
flang-commits at lists.llvm.org
Fri Oct 23 18:00:20 PDT 2026
https://github.com/jiel-nv updated https://github.com/llvm/llvm-project/pull/235169
>From aeb46b141c27780bde6e84faedf0e74f9c88a0bd Mon Sep 17 00:00:00 2001
From: jiel-nv <jiel at nvidia.com>
Date: Fri, 23 Oct 2026 17:05:50 -0700
Subject: [PATCH 1/2] [flang][debug] Spill a call-defined address for
dbg_declare
---
flang/lib/Optimizer/CodeGen/CodeGen.cpp | 20 ++++++++-
flang/test/Fir/declare-codegen-debug-call.fir | 42 +++++++++++++++++++
2 files changed, 60 insertions(+), 2 deletions(-)
create mode 100644 flang/test/Fir/declare-codegen-debug-call.fir
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 21b433bf49387..74662060d2764 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -72,6 +72,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/TypeSwitch.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/CommandLine.h"
namespace fir {
@@ -370,8 +371,23 @@ struct DeclareOpConversion : public fir::FIROpConversion<fir::cg::XDeclareOp> {
if (auto varAttr =
mlir::dyn_cast_or_null<mlir::LLVM::DILocalVariableAttr>(
fusedLoc.getMetadata())) {
- mlir::LLVM::DbgDeclareOp::create(rewriter, fusedLoc, memRef, varAttr,
- nullptr);
+ mlir::Value addr = memRef;
+ mlir::LLVM::DIExpressionAttr expr;
+ // A variable whose storage address is returned by a call has no stack
+ // slot to point at, and a declare on an SSA value only describes it
+ // where that value is live. Spill the address to a slot and deref it.
+ if (addr.getDefiningOp<mlir::LLVM::CallOp>()) {
+ mlir::Value slot = this->genAllocaAndAddrCastWithType(
+ fusedLoc, addr.getType(), defaultAlign, rewriter);
+ mlir::LLVM::StoreOp::create(rewriter, fusedLoc, addr, slot);
+ addr = slot;
+ expr = mlir::LLVM::DIExpressionAttr::get(
+ rewriter.getContext(), {mlir::LLVM::DIExpressionElemAttr::get(
+ rewriter.getContext(),
+ llvm::dwarf::DW_OP_deref, {})});
+ }
+ mlir::LLVM::DbgDeclareOp::create(rewriter, fusedLoc, addr, varAttr,
+ expr);
}
}
rewriter.replaceOp(declareOp, memRef);
diff --git a/flang/test/Fir/declare-codegen-debug-call.fir b/flang/test/Fir/declare-codegen-debug-call.fir
new file mode 100644
index 0000000000000..f0e990b03754c
--- /dev/null
+++ b/flang/test/Fir/declare-codegen-debug-call.fir
@@ -0,0 +1,42 @@
+// Test the debug intrinsic for a variable whose storage address is returned by
+// a call. Such a variable has no alloca to point at, so the declare must be
+// given a home slot holding the address and dereference it.
+// RUN: fir-opt --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" --mlir-print-debuginfo %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
+ func.func private @alloc() -> !fir.ref<!fir.array<100xf32>>
+ func.func @test_address_from_call() {
+ %0 = fir.call @alloc() : () -> !fir.ref<!fir.array<100xf32>>
+ %1 = fircg.ext_declare %0 uniq_name("m") : (!fir.ref<!fir.array<100xf32>>) -> !fir.ref<!fir.array<100xf32>> loc(#loc_m)
+ return
+ }
+
+ func.func @test_address_from_allocmem() {
+ %0 = fir.allocmem !fir.array<100xf32>
+ %1 = fircg.ext_declare %0 uniq_name("h") : (!fir.heap<!fir.array<100xf32>>) -> !fir.heap<!fir.array<100xf32>> loc(#loc_h)
+ fir.freemem %1 : !fir.heap<!fir.array<100xf32>>
+ return
+ }
+}
+
+#di_file = #llvm.di_file<"test.cuf" in "">
+#di_compile_unit = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, producer = "Flang", isOptimized = false, emissionKind = Full>
+#di_subprogram = #llvm.di_subprogram<compileUnit = #di_compile_unit, scope = #di_file, name = "test_address_from_call", file = #di_file, subprogramFlags = Definition>
+#di_subprogram_heap = #llvm.di_subprogram<compileUnit = #di_compile_unit, scope = #di_file, name = "test_address_from_allocmem", file = #di_file, subprogramFlags = Definition>
+#di_real = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real(kind=4)", sizeInBits = 32, encoding = DW_ATE_float>
+#di_m = #llvm.di_local_variable<scope = #di_subprogram, name = "m", file = #di_file, line = 4, type = #di_real>
+#di_h = #llvm.di_local_variable<scope = #di_subprogram_heap, name = "h", file = #di_file, line = 9, type = #di_real>
+#loc_m = loc(fused<#di_m>["test.cuf":4:11])
+#loc_h = loc(fused<#di_h>["test.cuf":9:11])
+
+// CHECK-LABEL: llvm.func @test_address_from_call
+// CHECK: %[[SLOT:[^ ]+]] = llvm.alloca %{{[^ ]+}} x !llvm.ptr
+// CHECK: %[[ADDR:[^ ]+]] = llvm.call @alloc()
+// CHECK: llvm.store %[[ADDR]], %[[SLOT]]
+// CHECK: llvm.intr.dbg.declare #[[M:[^ ]+]] #llvm.di_expression<[DW_OP_deref]> = %[[SLOT]] : !llvm.ptr
+
+// CHECK-LABEL: llvm.func @test_address_from_allocmem
+// CHECK: %[[HSLOT:[^ ]+]] = llvm.alloca %{{[^ ]+}} x !llvm.ptr
+// CHECK: %[[HADDR:[^ ]+]] = llvm.call @malloc
+// CHECK: llvm.store %[[HADDR]], %[[HSLOT]]
+// CHECK: llvm.intr.dbg.declare #[[H:[^ ]+]] #llvm.di_expression<[DW_OP_deref]> = %[[HSLOT]] : !llvm.ptr
>From 1c1d9a8d3ef59c48708b68fd1818b727e5e9d0b8 Mon Sep 17 00:00:00 2001
From: jiel-nv <37816794+jiel-nv at users.noreply.github.com>
Date: Fri, 23 Oct 2026 18:00:10 -0700
Subject: [PATCH 2/2] Fix format
---
flang/lib/Optimizer/CodeGen/CodeGen.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 74662060d2764..9b41c2f850716 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -382,9 +382,9 @@ struct DeclareOpConversion : public fir::FIROpConversion<fir::cg::XDeclareOp> {
mlir::LLVM::StoreOp::create(rewriter, fusedLoc, addr, slot);
addr = slot;
expr = mlir::LLVM::DIExpressionAttr::get(
- rewriter.getContext(), {mlir::LLVM::DIExpressionElemAttr::get(
- rewriter.getContext(),
- llvm::dwarf::DW_OP_deref, {})});
+ rewriter.getContext(),
+ {mlir::LLVM::DIExpressionElemAttr::get(
+ rewriter.getContext(), llvm::dwarf::DW_OP_deref, {})});
}
mlir::LLVM::DbgDeclareOp::create(rewriter, fusedLoc, addr, varAttr,
expr);
More information about the flang-commits
mailing list