Skip to content

Commit 005d56d

Browse files
abidhaadeshps-mcw
authored andcommitted
[flang][debug] Make common blocks data extraction more robust. (llvm#168752)
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 llvm#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.
1 parent 4df9a8f commit 005d56d

File tree

6 files changed

+139
-72
lines changed

6 files changed

+139
-72
lines changed

flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,17 +225,25 @@ def fircg_XDeclareOp : fircg_Op<"ext_declare", [AttrSizedOperandSegments]> {
225225
let description = [{
226226
Prior to lowering to LLVM IR dialect, a DeclareOp will
227227
be converted to an extended DeclareOp.
228+
229+
Most operands are inherited from fir.declare except for the shape and shift
230+
operands, which are "expanded" forms of the corresponding shape/shift
231+
operands of fir.declare.
228232
}];
229233

230234
let arguments = (ins AnyRefOrBox:$memref, Variadic<AnyIntegerType>:$shape,
231235
Variadic<AnyIntegerType>:$shift, Variadic<AnyIntegerType>:$typeparams,
232-
Optional<fir_DummyScopeType>:$dummy_scope, Builtin_StringAttr:$uniq_name,
236+
Optional<fir_DummyScopeType>:$dummy_scope,
237+
Optional<AnyReferenceLike>:$storage,
238+
DefaultValuedAttr<UI64Attr, "0">:$storage_offset,
239+
Builtin_StringAttr:$uniq_name,
233240
OptionalAttr<UI32Attr>:$dummy_arg_no);
234241
let results = (outs AnyRefOrBox);
235242

236243
let assemblyFormat = [{
237244
$memref (`(` $shape^ `)`)? (`origin` $shift^)? (`typeparams` $typeparams^)?
238245
(`dummy_scope` $dummy_scope^ (`arg` $dummy_arg_no^)?)?
246+
(`storage` `(` $storage^ `[` $storage_offset `]` `)`)?
239247
attr-dict `:` functional-type(operands, results)
240248
}];
241249

flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ class DeclareOpConversion : public mlir::OpRewritePattern<fir::DeclareOp> {
310310
auto xDeclOp = fir::cg::XDeclareOp::create(
311311
rewriter, loc, declareOp.getType(), declareOp.getMemref(), shapeOpers,
312312
shiftOpers, declareOp.getTypeparams(), declareOp.getDummyScope(),
313+
declareOp.getStorage(), declareOp.getStorageOffset(),
313314
declareOp.getUniqName(), dummyArgNoAttr);
314315
LLVM_DEBUG(llvm::dbgs()
315316
<< "rewriting " << declareOp << " to " << xDeclOp << '\n');

flang/lib/Optimizer/Transforms/AddDebugInfo.cpp

Lines changed: 71 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -144,62 +144,80 @@ bool AddDebugInfoPass::createCommonBlockGlobal(
144144
fir::DebugTypeGenerator &typeGen, mlir::SymbolTable *symbolTable) {
145145
mlir::MLIRContext *context = &getContext();
146146
mlir::OpBuilder builder(context);
147-
std::optional<std::int64_t> optint;
148-
mlir::Operation *op = declOp.getMemref().getDefiningOp();
149147

150-
if (auto conOp = mlir::dyn_cast_if_present<fir::ConvertOp>(op))
151-
op = conOp.getValue().getDefiningOp();
148+
std::optional<std::int64_t> offset;
149+
mlir::Value storage = declOp.getStorage();
150+
if (!storage)
151+
return false;
152+
153+
// Extract offset from storage_offset attribute
154+
uint64_t storageOffset = declOp.getStorageOffset();
155+
if (storageOffset != 0)
156+
offset = static_cast<std::int64_t>(storageOffset);
157+
158+
// Get the GlobalOp from the storage value.
159+
// The storage may be wrapped in ConvertOp, so unwrap it first.
160+
mlir::Operation *storageOp = storage.getDefiningOp();
161+
if (auto convertOp = mlir::dyn_cast_if_present<fir::ConvertOp>(storageOp))
162+
storageOp = convertOp.getValue().getDefiningOp();
163+
164+
auto addrOfOp = mlir::dyn_cast_if_present<fir::AddrOfOp>(storageOp);
165+
if (!addrOfOp)
166+
return false;
167+
168+
mlir::SymbolRefAttr sym = addrOfOp.getSymbol();
169+
fir::GlobalOp global =
170+
symbolTable->lookup<fir::GlobalOp>(sym.getRootReference());
171+
if (!global)
172+
return false;
173+
174+
// Check if the global is actually a common block by demangling its name.
175+
// Module EQUIVALENCE variables also use storage operands but are mangled
176+
// as VARIABLE type, so we reject them to avoid treating them as common
177+
// blocks.
178+
llvm::StringRef globalSymbol = sym.getRootReference();
179+
auto globalResult = fir::NameUniquer::deconstruct(globalSymbol);
180+
if (globalResult.first == fir::NameUniquer::NameKind::VARIABLE)
181+
return false;
182+
183+
// FIXME: We are trying to extract the name of the common block from the
184+
// name of the global. As part of mangling, GetCommonBlockObjectName can
185+
// add a trailing _ in the name of that global. The demangle function
186+
// does not seem to handle such cases. So the following hack is used to
187+
// remove the trailing '_'.
188+
llvm::StringRef commonName = globalSymbol;
189+
if (commonName != Fortran::common::blankCommonObjectName &&
190+
!commonName.empty() && commonName.back() == '_')
191+
commonName = commonName.drop_back();
192+
193+
// Create the debug attributes.
194+
unsigned line = getLineFromLoc(global.getLoc());
195+
mlir::LLVM::DICommonBlockAttr commonBlock =
196+
getOrCreateCommonBlockAttr(commonName, fileAttr, scopeAttr, line);
197+
198+
mlir::LLVM::DITypeAttr diType = typeGen.convertType(
199+
fir::unwrapRefType(declOp.getType()), fileAttr, scopeAttr, declOp);
200+
201+
line = getLineFromLoc(declOp.getLoc());
202+
auto gvAttr = mlir::LLVM::DIGlobalVariableAttr::get(
203+
context, commonBlock, mlir::StringAttr::get(context, name),
204+
declOp.getUniqName(), fileAttr, line, diType,
205+
/*isLocalToUnit*/ false, /*isDefinition*/ true, /* alignInBits*/ 0);
206+
207+
// Create DIExpression for offset if needed
208+
mlir::LLVM::DIExpressionAttr expr;
209+
if (offset && *offset != 0) {
210+
llvm::SmallVector<mlir::LLVM::DIExpressionElemAttr> ops;
211+
ops.push_back(mlir::LLVM::DIExpressionElemAttr::get(
212+
context, llvm::dwarf::DW_OP_plus_uconst, *offset));
213+
expr = mlir::LLVM::DIExpressionAttr::get(context, ops);
214+
}
152215

153-
if (auto cordOp = mlir::dyn_cast_if_present<fir::CoordinateOp>(op)) {
154-
auto coors = cordOp.getCoor();
155-
if (coors.size() != 1)
156-
return false;
157-
optint = fir::getIntIfConstant(coors[0]);
158-
if (!optint)
159-
return false;
160-
op = cordOp.getRef().getDefiningOp();
161-
if (auto conOp2 = mlir::dyn_cast_if_present<fir::ConvertOp>(op))
162-
op = conOp2.getValue().getDefiningOp();
216+
auto dbgExpr = mlir::LLVM::DIGlobalVariableExpressionAttr::get(
217+
global.getContext(), gvAttr, expr);
218+
globalToGlobalExprsMap[global].push_back(dbgExpr);
163219

164-
if (auto addrOfOp = mlir::dyn_cast_if_present<fir::AddrOfOp>(op)) {
165-
mlir::SymbolRefAttr sym = addrOfOp.getSymbol();
166-
if (auto global =
167-
symbolTable->lookup<fir::GlobalOp>(sym.getRootReference())) {
168-
169-
unsigned line = getLineFromLoc(global.getLoc());
170-
llvm::StringRef commonName(sym.getRootReference());
171-
// FIXME: We are trying to extract the name of the common block from the
172-
// name of the global. As part of mangling, GetCommonBlockObjectName can
173-
// add a trailing _ in the name of that global. The demangle function
174-
// does not seem to handle such cases. So the following hack is used to
175-
// remove the trailing '_'.
176-
if (commonName != Fortran::common::blankCommonObjectName &&
177-
commonName.back() == '_')
178-
commonName = commonName.drop_back();
179-
mlir::LLVM::DICommonBlockAttr commonBlock =
180-
getOrCreateCommonBlockAttr(commonName, fileAttr, scopeAttr, line);
181-
mlir::LLVM::DITypeAttr diType = typeGen.convertType(
182-
fir::unwrapRefType(declOp.getType()), fileAttr, scopeAttr, declOp);
183-
line = getLineFromLoc(declOp.getLoc());
184-
auto gvAttr = mlir::LLVM::DIGlobalVariableAttr::get(
185-
context, commonBlock, mlir::StringAttr::get(context, name),
186-
declOp.getUniqName(), fileAttr, line, diType,
187-
/*isLocalToUnit*/ false, /*isDefinition*/ true, /* alignInBits*/ 0);
188-
mlir::LLVM::DIExpressionAttr expr;
189-
if (*optint != 0) {
190-
llvm::SmallVector<mlir::LLVM::DIExpressionElemAttr> ops;
191-
ops.push_back(mlir::LLVM::DIExpressionElemAttr::get(
192-
context, llvm::dwarf::DW_OP_plus_uconst, *optint));
193-
expr = mlir::LLVM::DIExpressionAttr::get(context, ops);
194-
}
195-
auto dbgExpr = mlir::LLVM::DIGlobalVariableExpressionAttr::get(
196-
global.getContext(), gvAttr, expr);
197-
globalToGlobalExprsMap[global].push_back(dbgExpr);
198-
return true;
199-
}
200-
}
201-
}
202-
return false;
220+
return true;
203221
}
204222

205223
void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp,

flang/test/Fir/declare-codegen.fir

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,23 @@ func.func @unreachable_code(%arg0: !fir.ref<!fir.char<1,10>>) {
5252
// NODECL-NOT: uniq_name = "live_code"
5353
// DECL-LABEL: func.func @unreachable_code(
5454
// DECL: uniq_name = "live_code"
55+
56+
// Test that storage and storage_offset operands are preserved during conversion
57+
func.func @test_storage_operands() {
58+
%c0 = arith.constant 0 : index
59+
%c4 = arith.constant 4 : index
60+
%0 = fir.address_of(@common_block) : !fir.ref<!fir.array<8xi8>>
61+
%1 = fir.coordinate_of %0, %c0 : (!fir.ref<!fir.array<8xi8>>, index) -> !fir.ref<i8>
62+
%2 = fir.convert %1 : (!fir.ref<i8>) -> !fir.ref<f32>
63+
%3 = fir.declare %2 storage(%0[0]) {uniq_name = "_QFEx"} : (!fir.ref<f32>, !fir.ref<!fir.array<8xi8>>) -> !fir.ref<f32>
64+
%4 = fir.coordinate_of %0, %c4 : (!fir.ref<!fir.array<8xi8>>, index) -> !fir.ref<i8>
65+
%5 = fir.convert %4 : (!fir.ref<i8>) -> !fir.ref<i32>
66+
%6 = fir.declare %5 storage(%0[4]) {uniq_name = "_QFEy"} : (!fir.ref<i32>, !fir.ref<!fir.array<8xi8>>) -> !fir.ref<i32>
67+
return
68+
}
69+
fir.global @common_block : !fir.array<8xi8>
70+
71+
// DECL-LABEL: func.func @test_storage_operands()
72+
// DECL: %[[STORAGE:.*]] = fir.address_of(@common_block) : !fir.ref<!fir.array<8xi8>>
73+
// DECL: fircg.ext_declare {{.*}} storage(%[[STORAGE]][0]) {uniq_name = "_QFEx"}
74+
// DECL: fircg.ext_declare {{.*}} storage(%[[STORAGE]][4]) {uniq_name = "_QFEy"}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
2+
3+
! Test that module EQUIVALENCE does not generate DICommonBlock.
4+
5+
module data_module
6+
real :: var1, var2
7+
equivalence (var1, var2)
8+
end module data_module
9+
10+
subroutine test_module_equiv
11+
use data_module
12+
var1 = 1.5
13+
var2 = 2.5
14+
end subroutine
15+
16+
program main
17+
call test_module_equiv()
18+
end program
19+
20+
! CHECK-NOT: DICommonBlock

flang/test/Transforms/debug-common-block.fir

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@ module {
1616
%1 = fir.convert %0 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
1717
%2 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
1818
%3 = fir.convert %2 : (!fir.ref<i8>) -> !fir.ref<f32>
19-
%4 = fircg.ext_declare %3 {uniq_name = "_QFf1Ex"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc4)
19+
%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)
2020
%5 = fir.address_of(@a_) : !fir.ref<tuple<i32, !fir.array<8xi8>>>
2121
%6 = fir.convert %5 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
2222
%7 = fir.coordinate_of %6, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
2323
%8 = fir.convert %7 : (!fir.ref<i8>) -> !fir.ref<f32>
24-
%9 = fircg.ext_declare %8 {uniq_name = "_QFf1Exa"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc5)
24+
%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)
2525
%10 = fir.coordinate_of %1, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
2626
%11 = fir.convert %10 : (!fir.ref<i8>) -> !fir.ref<f32>
27-
%12 = fircg.ext_declare %11 {uniq_name = "_QFf1Ey"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc6)
27+
%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)
2828
%13 = fir.coordinate_of %6, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
2929
%14 = fir.convert %13 : (!fir.ref<i8>) -> !fir.ref<f32>
30-
%15 = fircg.ext_declare %14 {uniq_name = "_QFf1Eya"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc7)
30+
%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)
3131
return
3232
} loc(#loc3)
3333
func.func @f2() {
@@ -40,24 +40,24 @@ module {
4040
%1 = fir.convert %0 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
4141
%2 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
4242
%3 = fir.convert %2 : (!fir.ref<i8>) -> !fir.ref<f32>
43-
%4 = fircg.ext_declare %3 {uniq_name = "_QFf2Ex"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc9)
43+
%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)
4444
%5 = fir.address_of(@a_) : !fir.ref<tuple<i32, !fir.array<8xi8>>>
4545
%6 = fir.convert %5 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
4646
%7 = fir.coordinate_of %6, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
4747
%8 = fir.convert %7 : (!fir.ref<i8>) -> !fir.ref<f32>
48-
%9 = fircg.ext_declare %8 {uniq_name = "_QFf2Exa"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc10)
48+
%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)
4949
%10 = fir.coordinate_of %1, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
5050
%11 = fir.convert %10 : (!fir.ref<i8>) -> !fir.ref<f32>
51-
%12 = fircg.ext_declare %11 {uniq_name = "_QFf2Ey"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc11)
51+
%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)
5252
%13 = fir.coordinate_of %6, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
5353
%14 = fir.convert %13 : (!fir.ref<i8>) -> !fir.ref<f32>
54-
%15 = fircg.ext_declare %14 {uniq_name = "_QFf2Eya"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc12)
54+
%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)
5555
%16 = fir.coordinate_of %1, %c8 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
5656
%17 = fir.convert %16 : (!fir.ref<i8>) -> !fir.ref<f32>
57-
%18 = fircg.ext_declare %17 {uniq_name = "_QFf2Ez"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc13)
57+
%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)
5858
%19 = fir.coordinate_of %6, %c8 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
5959
%20 = fir.convert %19 : (!fir.ref<i8>) -> !fir.ref<f32>
60-
%21 = fircg.ext_declare %20 {uniq_name = "_QFf2Eza"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc14)
60+
%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)
6161
return
6262
} loc(#loc8)
6363
func.func @f3() {
@@ -69,12 +69,12 @@ module {
6969
%1 = fir.convert %0 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
7070
%2 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
7171
%3 = fir.convert %2 : (!fir.ref<i8>) -> !fir.ref<i32>
72-
%4 = fircg.ext_declare %3 {uniq_name = "_QFf3Ex"} : (!fir.ref<i32>) -> !fir.ref<i32> loc(#loc16)
72+
%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)
7373
%5 = fir.address_of(@a_) : !fir.ref<tuple<i32, !fir.array<8xi8>>>
7474
%6 = fir.convert %5 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
7575
%7 = fir.coordinate_of %6, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
7676
%8 = fir.convert %7 : (!fir.ref<i8>) -> !fir.ref<i32>
77-
%9 = fircg.ext_declare %8 {uniq_name = "_QFf3Exa"} : (!fir.ref<i32>) -> !fir.ref<i32> loc(#loc17)
77+
%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)
7878
return
7979
} loc(#loc15)
8080
func.func @test() {
@@ -87,24 +87,24 @@ module {
8787
%1 = fir.convert %0 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
8888
%2 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
8989
%3 = fir.convert %2 : (!fir.ref<i8>) -> !fir.ref<f32>
90-
%4 = fircg.ext_declare %3 {uniq_name = "_QFEv1"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc19)
90+
%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)
9191
%5 = fir.coordinate_of %1, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
9292
%6 = fir.convert %5 : (!fir.ref<i8>) -> !fir.ref<f32>
93-
%7 = fircg.ext_declare %6 {uniq_name = "_QFEv2"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc20)
93+
%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)
9494
%8 = fir.coordinate_of %1, %c8 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
9595
%9 = fir.convert %8 : (!fir.ref<i8>) -> !fir.ref<f32>
96-
%10 = fircg.ext_declare %9 {uniq_name = "_QFEv3"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc21)
96+
%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)
9797
%11 = fir.address_of(@a_) : !fir.ref<tuple<i32, !fir.array<8xi8>>>
9898
%12 = fir.convert %11 : (!fir.ref<tuple<i32, !fir.array<8xi8>>>) -> !fir.ref<!fir.array<?xi8>>
9999
%13 = fir.coordinate_of %12, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
100100
%14 = fir.convert %13 : (!fir.ref<i8>) -> !fir.ref<f32>
101-
%15 = fircg.ext_declare %14 {uniq_name = "_QFEva1"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc22)
101+
%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)
102102
%16 = fir.coordinate_of %12, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
103103
%17 = fir.convert %16 : (!fir.ref<i8>) -> !fir.ref<f32>
104-
%18 = fircg.ext_declare %17 {uniq_name = "_QFEva2"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc23)
104+
%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)
105105
%19 = fir.coordinate_of %12, %c8 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
106106
%20 = fir.convert %19 : (!fir.ref<i8>) -> !fir.ref<f32>
107-
%21 = fircg.ext_declare %20 {uniq_name = "_QFEva3"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc24)
107+
%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)
108108
return
109109
} loc(#loc18)
110110
}

0 commit comments

Comments
 (0)