[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