[flang-commits] [flang] [flang][debug] Make common blocks data extraction more robust. (PR #168752)
Abid Qadeer via flang-commits
flang-commits at lists.llvm.org
Wed Nov 19 12:09:38 PST 2025
https://github.com/abidh updated https://github.com/llvm/llvm-project/pull/168752
>From b059f68a24e1b5e02fcefa932d783ac72ec93a27 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Wed, 19 Nov 2025 14:20:15 +0000
Subject: [PATCH 1/3] [flang][debug] Make common blocks data extraction more
robust.
Our current implementation for extracting information about common block
required traversal of FIR which was not ideal but previously there was
no other way to obtain that information. The `[hl]fir.declare` was
extended in commit https://github.com/llvm/llvm-project/pull/155325
to include storage and storage_offset. This commit adds these operands
in `fircg.ext_declare` and then use them in `AddDebugInfoPass` to create
debug data for common blocks.
---
.../flang/Optimizer/Dialect/FIRCG/CGOps.td | 6 +-
flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp | 1 +
.../lib/Optimizer/Transforms/AddDebugInfo.cpp | 116 ++++++++++--------
flang/test/Fir/declare-codegen.fir | 20 +++
flang/test/Transforms/debug-common-block.fir | 36 +++---
5 files changed, 107 insertions(+), 72 deletions(-)
diff --git a/flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td b/flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td
index 04f839386498c..1ddd2703bc448 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td
@@ -229,12 +229,16 @@ def fircg_XDeclareOp : fircg_Op<"ext_declare", [AttrSizedOperandSegments]> {
let arguments = (ins AnyRefOrBox:$memref, Variadic<AnyIntegerType>:$shape,
Variadic<AnyIntegerType>:$shift, Variadic<AnyIntegerType>:$typeparams,
- Optional<fir_DummyScopeType>:$dummy_scope, Builtin_StringAttr:$uniq_name);
+ Optional<fir_DummyScopeType>:$dummy_scope,
+ Optional<AnyReferenceLike>:$storage,
+ DefaultValuedAttr<UI64Attr, "0">:$storage_offset,
+ Builtin_StringAttr:$uniq_name);
let results = (outs AnyRefOrBox);
let assemblyFormat = [{
$memref (`(` $shape^ `)`)? (`origin` $shift^)? (`typeparams` $typeparams^)?
(`dummy_scope` $dummy_scope^)?
+ (`storage` `(` $storage^ `[` $storage_offset `]` `)`)?
attr-dict `:` functional-type(operands, results)
}];
diff --git a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
index 1b1d43c11c707..2672a565c7ff2 100644
--- a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
+++ b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
@@ -306,6 +306,7 @@ class DeclareOpConversion : public mlir::OpRewritePattern<fir::DeclareOp> {
auto xDeclOp = fir::cg::XDeclareOp::create(
rewriter, loc, declareOp.getType(), declareOp.getMemref(), shapeOpers,
shiftOpers, declareOp.getTypeparams(), declareOp.getDummyScope(),
+ declareOp.getStorage(), declareOp.getStorageOffset(),
declareOp.getUniqName());
LLVM_DEBUG(llvm::dbgs()
<< "rewriting " << declareOp << " to " << xDeclOp << '\n');
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index e006d2e878fd8..00fe2ddcdfef2 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -144,62 +144,72 @@ bool AddDebugInfoPass::createCommonBlockGlobal(
fir::DebugTypeGenerator &typeGen, mlir::SymbolTable *symbolTable) {
mlir::MLIRContext *context = &getContext();
mlir::OpBuilder builder(context);
- std::optional<std::int64_t> optint;
- mlir::Operation *op = declOp.getMemref().getDefiningOp();
- if (auto conOp = mlir::dyn_cast_if_present<fir::ConvertOp>(op))
- op = conOp.getValue().getDefiningOp();
+ std::optional<std::int64_t> offset;
+ mlir::Value storage = declOp.getStorage();
+ if (!storage)
+ return false;
+
+ // Extract offset from storage_offset attribute
+ uint64_t storageOffset = declOp.getStorageOffset();
+ if (storageOffset != 0)
+ offset = static_cast<std::int64_t>(storageOffset);
+
+ // Get the GlobalOp from the storage value.
+ // The storage may be wrapped in ConvertOp, so unwrap it first.
+ mlir::Operation *storageOp = storage.getDefiningOp();
+ if (auto convertOp = mlir::dyn_cast_if_present<fir::ConvertOp>(storageOp))
+ storageOp = convertOp.getValue().getDefiningOp();
+
+ auto addrOfOp = mlir::dyn_cast_if_present<fir::AddrOfOp>(storageOp);
+ if (!addrOfOp)
+ return false;
+
+ mlir::SymbolRefAttr sym = addrOfOp.getSymbol();
+ fir::GlobalOp global =
+ symbolTable->lookup<fir::GlobalOp>(sym.getRootReference());
+ if (!global)
+ return false;
+
+ // FIXME: We are trying to extract the name of the common block from the
+ // name of the global. As part of mangling, GetCommonBlockObjectName can
+ // add a trailing _ in the name of that global. The demangle function
+ // does not seem to handle such cases. So the following hack is used to
+ // remove the trailing '_'.
+ llvm::StringRef globalSymbol = sym.getRootReference();
+ llvm::StringRef commonName = globalSymbol;
+ if (commonName != Fortran::common::blankCommonObjectName &&
+ !commonName.empty() && commonName.back() == '_')
+ commonName = commonName.drop_back();
+
+ // Create the debug attributes.
+ unsigned line = getLineFromLoc(global.getLoc());
+ mlir::LLVM::DICommonBlockAttr commonBlock =
+ getOrCreateCommonBlockAttr(commonName, fileAttr, scopeAttr, line);
+
+ mlir::LLVM::DITypeAttr diType = typeGen.convertType(
+ fir::unwrapRefType(declOp.getType()), fileAttr, scopeAttr, declOp);
+
+ line = getLineFromLoc(declOp.getLoc());
+ auto gvAttr = mlir::LLVM::DIGlobalVariableAttr::get(
+ context, commonBlock, mlir::StringAttr::get(context, name),
+ declOp.getUniqName(), fileAttr, line, diType,
+ /*isLocalToUnit*/ false, /*isDefinition*/ true, /* alignInBits*/ 0);
+
+ // Create DIExpression for offset if needed
+ mlir::LLVM::DIExpressionAttr expr;
+ if (offset && *offset != 0) {
+ llvm::SmallVector<mlir::LLVM::DIExpressionElemAttr> ops;
+ ops.push_back(mlir::LLVM::DIExpressionElemAttr::get(
+ context, llvm::dwarf::DW_OP_plus_uconst, *offset));
+ expr = mlir::LLVM::DIExpressionAttr::get(context, ops);
+ }
- if (auto cordOp = mlir::dyn_cast_if_present<fir::CoordinateOp>(op)) {
- auto coors = cordOp.getCoor();
- if (coors.size() != 1)
- return false;
- optint = fir::getIntIfConstant(coors[0]);
- if (!optint)
- return false;
- op = cordOp.getRef().getDefiningOp();
- if (auto conOp2 = mlir::dyn_cast_if_present<fir::ConvertOp>(op))
- op = conOp2.getValue().getDefiningOp();
+ auto dbgExpr = mlir::LLVM::DIGlobalVariableExpressionAttr::get(
+ global.getContext(), gvAttr, expr);
+ globalToGlobalExprsMap[global].push_back(dbgExpr);
- if (auto addrOfOp = mlir::dyn_cast_if_present<fir::AddrOfOp>(op)) {
- mlir::SymbolRefAttr sym = addrOfOp.getSymbol();
- if (auto global =
- symbolTable->lookup<fir::GlobalOp>(sym.getRootReference())) {
-
- unsigned line = getLineFromLoc(global.getLoc());
- llvm::StringRef commonName(sym.getRootReference());
- // FIXME: We are trying to extract the name of the common block from the
- // name of the global. As part of mangling, GetCommonBlockObjectName can
- // add a trailing _ in the name of that global. The demangle function
- // does not seem to handle such cases. So the following hack is used to
- // remove the trailing '_'.
- if (commonName != Fortran::common::blankCommonObjectName &&
- commonName.back() == '_')
- commonName = commonName.drop_back();
- mlir::LLVM::DICommonBlockAttr commonBlock =
- getOrCreateCommonBlockAttr(commonName, fileAttr, scopeAttr, line);
- mlir::LLVM::DITypeAttr diType = typeGen.convertType(
- fir::unwrapRefType(declOp.getType()), fileAttr, scopeAttr, declOp);
- line = getLineFromLoc(declOp.getLoc());
- auto gvAttr = mlir::LLVM::DIGlobalVariableAttr::get(
- context, commonBlock, mlir::StringAttr::get(context, name),
- declOp.getUniqName(), fileAttr, line, diType,
- /*isLocalToUnit*/ false, /*isDefinition*/ true, /* alignInBits*/ 0);
- mlir::LLVM::DIExpressionAttr expr;
- if (*optint != 0) {
- llvm::SmallVector<mlir::LLVM::DIExpressionElemAttr> ops;
- ops.push_back(mlir::LLVM::DIExpressionElemAttr::get(
- context, llvm::dwarf::DW_OP_plus_uconst, *optint));
- expr = mlir::LLVM::DIExpressionAttr::get(context, ops);
- }
- auto dbgExpr = mlir::LLVM::DIGlobalVariableExpressionAttr::get(
- global.getContext(), gvAttr, expr);
- globalToGlobalExprsMap[global].push_back(dbgExpr);
- return true;
- }
- }
- }
- return false;
+ return true;
}
void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp,
diff --git a/flang/test/Fir/declare-codegen.fir b/flang/test/Fir/declare-codegen.fir
index fe8d84ef2d19f..9413525a5dbd3 100644
--- a/flang/test/Fir/declare-codegen.fir
+++ b/flang/test/Fir/declare-codegen.fir
@@ -52,3 +52,23 @@ func.func @unreachable_code(%arg0: !fir.ref<!fir.char<1,10>>) {
// NODECL-NOT: uniq_name = "live_code"
// DECL-LABEL: func.func @unreachable_code(
// DECL: uniq_name = "live_code"
+
+// Test that storage and storage_offset operands are preserved during conversion
+func.func @test_storage_operands() {
+ %c0 = arith.constant 0 : index
+ %c4 = arith.constant 4 : index
+ %0 = fir.address_of(@common_block) : !fir.ref<!fir.array<8xi8>>
+ %1 = fir.coordinate_of %0, %c0 : (!fir.ref<!fir.array<8xi8>>, index) -> !fir.ref<i8>
+ %2 = fir.convert %1 : (!fir.ref<i8>) -> !fir.ref<f32>
+ %3 = fir.declare %2 storage(%0[0]) {uniq_name = "_QFEx"} : (!fir.ref<f32>, !fir.ref<!fir.array<8xi8>>) -> !fir.ref<f32>
+ %4 = fir.coordinate_of %0, %c4 : (!fir.ref<!fir.array<8xi8>>, index) -> !fir.ref<i8>
+ %5 = fir.convert %4 : (!fir.ref<i8>) -> !fir.ref<i32>
+ %6 = fir.declare %5 storage(%0[4]) {uniq_name = "_QFEy"} : (!fir.ref<i32>, !fir.ref<!fir.array<8xi8>>) -> !fir.ref<i32>
+ return
+}
+fir.global @common_block : !fir.array<8xi8>
+
+// DECL-LABEL: func.func @test_storage_operands()
+// DECL: %[[STORAGE:.*]] = fir.address_of(@common_block) : !fir.ref<!fir.array<8xi8>>
+// DECL: fircg.ext_declare {{.*}} storage(%[[STORAGE]][0]) {uniq_name = "_QFEx"}
+// DECL: fircg.ext_declare {{.*}} storage(%[[STORAGE]][4]) {uniq_name = "_QFEy"}
diff --git a/flang/test/Transforms/debug-common-block.fir b/flang/test/Transforms/debug-common-block.fir
index d68b524225df5..1d2beae0e0ef4 100644
--- a/flang/test/Transforms/debug-common-block.fir
+++ b/flang/test/Transforms/debug-common-block.fir
@@ -16,18 +16,18 @@ module {
%1 = fir.convert %0 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
%2 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%3 = fir.convert %2 : (!fir.ref<i8>) -> !fir.ref<f32>
- %4 = fircg.ext_declare %3 {uniq_name = "_QFf1Ex"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc4)
+ %4 = fircg.ext_declare %3 storage(%0[0]) {uniq_name = "_QFf1Ex"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc4)
%5 = fir.address_of(@a_) : !fir.ref<tuple<i32, !fir.array<8xi8>>>
%6 = fir.convert %5 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
%7 = fir.coordinate_of %6, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%8 = fir.convert %7 : (!fir.ref<i8>) -> !fir.ref<f32>
- %9 = fircg.ext_declare %8 {uniq_name = "_QFf1Exa"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc5)
+ %9 = fircg.ext_declare %8 storage(%5[0]) {uniq_name = "_QFf1Exa"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc5)
%10 = fir.coordinate_of %1, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%11 = fir.convert %10 : (!fir.ref<i8>) -> !fir.ref<f32>
- %12 = fircg.ext_declare %11 {uniq_name = "_QFf1Ey"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc6)
+ %12 = fircg.ext_declare %11 storage(%0[4]) {uniq_name = "_QFf1Ey"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc6)
%13 = fir.coordinate_of %6, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%14 = fir.convert %13 : (!fir.ref<i8>) -> !fir.ref<f32>
- %15 = fircg.ext_declare %14 {uniq_name = "_QFf1Eya"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc7)
+ %15 = fircg.ext_declare %14 storage(%5[4]) {uniq_name = "_QFf1Eya"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc7)
return
} loc(#loc3)
func.func @f2() {
@@ -40,24 +40,24 @@ module {
%1 = fir.convert %0 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
%2 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%3 = fir.convert %2 : (!fir.ref<i8>) -> !fir.ref<f32>
- %4 = fircg.ext_declare %3 {uniq_name = "_QFf2Ex"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc9)
+ %4 = fircg.ext_declare %3 storage(%0[0]) {uniq_name = "_QFf2Ex"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc9)
%5 = fir.address_of(@a_) : !fir.ref<tuple<i32, !fir.array<8xi8>>>
%6 = fir.convert %5 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
%7 = fir.coordinate_of %6, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%8 = fir.convert %7 : (!fir.ref<i8>) -> !fir.ref<f32>
- %9 = fircg.ext_declare %8 {uniq_name = "_QFf2Exa"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc10)
+ %9 = fircg.ext_declare %8 storage(%5[0]) {uniq_name = "_QFf2Exa"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc10)
%10 = fir.coordinate_of %1, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%11 = fir.convert %10 : (!fir.ref<i8>) -> !fir.ref<f32>
- %12 = fircg.ext_declare %11 {uniq_name = "_QFf2Ey"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc11)
+ %12 = fircg.ext_declare %11 storage(%0[4]) {uniq_name = "_QFf2Ey"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc11)
%13 = fir.coordinate_of %6, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%14 = fir.convert %13 : (!fir.ref<i8>) -> !fir.ref<f32>
- %15 = fircg.ext_declare %14 {uniq_name = "_QFf2Eya"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc12)
+ %15 = fircg.ext_declare %14 storage(%5[4]) {uniq_name = "_QFf2Eya"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc12)
%16 = fir.coordinate_of %1, %c8 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%17 = fir.convert %16 : (!fir.ref<i8>) -> !fir.ref<f32>
- %18 = fircg.ext_declare %17 {uniq_name = "_QFf2Ez"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc13)
+ %18 = fircg.ext_declare %17 storage(%0[8]) {uniq_name = "_QFf2Ez"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc13)
%19 = fir.coordinate_of %6, %c8 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%20 = fir.convert %19 : (!fir.ref<i8>) -> !fir.ref<f32>
- %21 = fircg.ext_declare %20 {uniq_name = "_QFf2Eza"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc14)
+ %21 = fircg.ext_declare %20 storage(%5[8]) {uniq_name = "_QFf2Eza"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc14)
return
} loc(#loc8)
func.func @f3() {
@@ -69,12 +69,12 @@ module {
%1 = fir.convert %0 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
%2 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%3 = fir.convert %2 : (!fir.ref<i8>) -> !fir.ref<i32>
- %4 = fircg.ext_declare %3 {uniq_name = "_QFf3Ex"} : (!fir.ref<i32>) -> !fir.ref<i32> loc(#loc16)
+ %4 = fircg.ext_declare %3 storage(%0[0]) {uniq_name = "_QFf3Ex"} : (!fir.ref<i32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<i32> loc(#loc16)
%5 = fir.address_of(@a_) : !fir.ref<tuple<i32, !fir.array<8xi8>>>
%6 = fir.convert %5 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
%7 = fir.coordinate_of %6, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%8 = fir.convert %7 : (!fir.ref<i8>) -> !fir.ref<i32>
- %9 = fircg.ext_declare %8 {uniq_name = "_QFf3Exa"} : (!fir.ref<i32>) -> !fir.ref<i32> loc(#loc17)
+ %9 = fircg.ext_declare %8 storage(%5[0]) {uniq_name = "_QFf3Exa"} : (!fir.ref<i32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<i32> loc(#loc17)
return
} loc(#loc15)
func.func @test() {
@@ -87,24 +87,24 @@ module {
%1 = fir.convert %0 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
%2 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%3 = fir.convert %2 : (!fir.ref<i8>) -> !fir.ref<f32>
- %4 = fircg.ext_declare %3 {uniq_name = "_QFEv1"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc19)
+ %4 = fircg.ext_declare %3 storage(%0[0]) {uniq_name = "_QFEv1"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc19)
%5 = fir.coordinate_of %1, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%6 = fir.convert %5 : (!fir.ref<i8>) -> !fir.ref<f32>
- %7 = fircg.ext_declare %6 {uniq_name = "_QFEv2"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc20)
+ %7 = fircg.ext_declare %6 storage(%0[4]) {uniq_name = "_QFEv2"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc20)
%8 = fir.coordinate_of %1, %c8 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%9 = fir.convert %8 : (!fir.ref<i8>) -> !fir.ref<f32>
- %10 = fircg.ext_declare %9 {uniq_name = "_QFEv3"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc21)
+ %10 = fircg.ext_declare %9 storage(%0[8]) {uniq_name = "_QFEv3"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc21)
%11 = fir.address_of(@a_) : !fir.ref<tuple<i32, !fir.array<8xi8>>>
%12 = fir.convert %11 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
%13 = fir.coordinate_of %12, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%14 = fir.convert %13 : (!fir.ref<i8>) -> !fir.ref<f32>
- %15 = fircg.ext_declare %14 {uniq_name = "_QFEva1"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc22)
+ %15 = fircg.ext_declare %14 storage(%11[0]) {uniq_name = "_QFEva1"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc22)
%16 = fir.coordinate_of %12, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%17 = fir.convert %16 : (!fir.ref<i8>) -> !fir.ref<f32>
- %18 = fircg.ext_declare %17 {uniq_name = "_QFEva2"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc23)
+ %18 = fircg.ext_declare %17 storage(%11[4]) {uniq_name = "_QFEva2"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc23)
%19 = fir.coordinate_of %12, %c8 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
%20 = fir.convert %19 : (!fir.ref<i8>) -> !fir.ref<f32>
- %21 = fircg.ext_declare %20 {uniq_name = "_QFEva3"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc24)
+ %21 = fircg.ext_declare %20 storage(%11[8]) {uniq_name = "_QFEva3"} : (!fir.ref<f32>, !fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<f32> loc(#loc24)
return
} loc(#loc18)
}
>From 0f091f8def95e2aa570c4d2fc1c46d7d1ca31076 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Wed, 19 Nov 2025 20:02:21 +0000
Subject: [PATCH 2/3] Reject module equivalance variables.
---
flang/lib/Optimizer/Transforms/AddDebugInfo.cpp | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 00fe2ddcdfef2..f726f00f9fb50 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -171,12 +171,20 @@ bool AddDebugInfoPass::createCommonBlockGlobal(
if (!global)
return false;
+ // Check if the global is actually a common block by demangling its name.
+ // Module EQUIVALENCE variables also use storage operands but are mangled
+ // as VARIABLE type, so we reject them to avoid treating them as common
+ // blocks.
+ llvm::StringRef globalSymbol = sym.getRootReference();
+ auto globalResult = fir::NameUniquer::deconstruct(globalSymbol);
+ if (globalResult.first == fir::NameUniquer::NameKind::VARIABLE)
+ return false;
+
// FIXME: We are trying to extract the name of the common block from the
// name of the global. As part of mangling, GetCommonBlockObjectName can
// add a trailing _ in the name of that global. The demangle function
// does not seem to handle such cases. So the following hack is used to
// remove the trailing '_'.
- llvm::StringRef globalSymbol = sym.getRootReference();
llvm::StringRef commonName = globalSymbol;
if (commonName != Fortran::common::blankCommonObjectName &&
!commonName.empty() && commonName.back() == '_')
>From 4188d4fc95a581b9550a0491cf925f9eae0a0d4e Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Wed, 19 Nov 2025 20:09:13 +0000
Subject: [PATCH 3/3] Add comments.
---
flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td b/flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td
index 1ddd2703bc448..90d8a67d0b242 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td
@@ -225,6 +225,10 @@ def fircg_XDeclareOp : fircg_Op<"ext_declare", [AttrSizedOperandSegments]> {
let description = [{
Prior to lowering to LLVM IR dialect, a DeclareOp will
be converted to an extended DeclareOp.
+
+ Most operands are inherited from fir.declare except for the shape and shift
+ operands, which are "expanded" forms of the corresponding shape/shift
+ operands of fir.declare.
}];
let arguments = (ins AnyRefOrBox:$memref, Variadic<AnyIntegerType>:$shape,
More information about the flang-commits
mailing list