[flang-commits] [flang] 7016730 - [flang] Take the debug record's location from the declaration. (#229484)
via flang-commits
flang-commits at lists.llvm.org
Wed Oct 7 00:47:38 PDT 2026
Author: Abid Qadeer
Date: 2026-10-07T08:47:30+01:00
New Revision: 7016730d795c610d5e62b2662f292e2ffecdd60d
URL: https://github.com/llvm/llvm-project/commit/7016730d795c610d5e62b2662f292e2ffecdd60d
DIFF: https://github.com/llvm/llvm-project/commit/7016730d795c610d5e62b2662f292e2ffecdd60d.diff
LOG: [flang] Take the debug record's location from the declaration. (#229484)
`DeclareOpConversion` gives the `DbgDeclareOp` it creates the location
of the memref (the alloca) instead of the location of the `XDeclareOp`.
This is problematic in 2 ways.
1. The `XDeclareOp` better represents where the variable is declared.
The memref is where the variable's memory happens to be allocated, and
for a dummy argument it is a block argument, so the record ends up on
the procedure statement. For a subroutine whose dummies `n` and `a` are
declared on lines 2 and 3, their `#dbg_declare` records are both at line
1 today, and at lines 2 and 3 with this change.
2. It requires the alloca to have a valid location. If it does not, the
`DbgDeclareOp` gets none either, and a debug record without a location
is invalid, so it is dropped during the MLIR to LLVM IR translation and
the variable disappears from the debug info altogether.
This PR makes `DeclareOpConversion` use the location of the
`XDeclareOp`. A similar change is done for `DeclareValueOpConversion`.
Assisted By: Cursor
Co-authored-by: Cursor <cursoragent at cursor.com>
Added:
flang/test/Fir/declare-codegen-debug.fir
Modified:
flang/lib/Optimizer/CodeGen/CodeGen.cpp
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index e5ba1ae7ff974..4923cfe2e1878 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -322,8 +322,8 @@ 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, memRef.getLoc(), memRef,
- varAttr, nullptr);
+ mlir::LLVM::DbgDeclareOp::create(rewriter, fusedLoc, memRef, varAttr,
+ nullptr);
}
}
rewriter.replaceOp(declareOp, memRef);
@@ -343,7 +343,7 @@ struct DeclareValueOpConversion
if (auto varAttr =
mlir::dyn_cast_or_null<mlir::LLVM::DILocalVariableAttr>(
fusedLoc.getMetadata())) {
- mlir::LLVM::DbgValueOp::create(rewriter, value.getLoc(), value, varAttr,
+ mlir::LLVM::DbgValueOp::create(rewriter, fusedLoc, value, varAttr,
nullptr);
}
}
diff --git a/flang/test/Fir/declare-codegen-debug.fir b/flang/test/Fir/declare-codegen-debug.fir
new file mode 100644
index 0000000000000..5e981dcf95e46
--- /dev/null
+++ b/flang/test/Fir/declare-codegen-debug.fir
@@ -0,0 +1,31 @@
+// Test that the debug intrinsic for a declared variable gets its location from
+// the declaration and not from the allocation.
+// 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 @test_codegen() {
+ %0 = fir.alloca i32 loc(#loc_alloca)
+ %1 = fircg.ext_declare %0 uniq_name("x") : (!fir.ref<i32>) -> !fir.ref<i32> loc(#loc_x)
+ %2 = fir.alloca i32 loc(unknown)
+ %3 = fircg.ext_declare %2 uniq_name("y") : (!fir.ref<i32>) -> !fir.ref<i32> loc(#loc_y)
+ return
+ }
+}
+
+#di_file = #llvm.di_file<"test.f90" 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_codegen", file = #di_file, subprogramFlags = Definition>
+#di_int = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer(kind=4)", sizeInBits = 32, encoding = DW_ATE_signed>
+#di_x = #llvm.di_local_variable<scope = #di_subprogram, name = "x", file = #di_file, line = 3, type = #di_int>
+#di_y = #llvm.di_local_variable<scope = #di_subprogram, name = "y", file = #di_file, line = 4, type = #di_int>
+#loc_alloca = loc("test.f90":99:1)
+#loc_x = loc(fused<#di_x>["test.f90":3:11])
+#loc_y = loc(fused<#di_y>["test.f90":4:11])
+
+// CHECK-LABEL: llvm.func @test_codegen
+// CHECK: llvm.intr.dbg.declare #[[X:[^ ]+]] = %{{[^ ]+}} : !llvm.ptr loc(#[[X_LOC:[^)]+]])
+// CHECK: llvm.intr.dbg.declare #[[Y:[^ ]+]] = %{{[^ ]+}} : !llvm.ptr loc(#[[Y_LOC:[^)]+]])
+// CHECK: #[[X_FILE:[^ ]+]] = loc("test.f90":3:11)
+// CHECK: #[[Y_FILE:[^ ]+]] = loc("test.f90":4:11)
+// CHECK: #[[X_LOC]] = loc(fused<#[[X]]>[#[[X_FILE]]])
+// CHECK: #[[Y_LOC]] = loc(fused<#[[Y]]>[#[[Y_FILE]]])
More information about the flang-commits
mailing list