Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -225,17 +225,25 @@ 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,
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,
OptionalAttr<UI32Attr>:$dummy_arg_no);
let results = (outs AnyRefOrBox);

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

Expand Down
1 change: 1 addition & 0 deletions flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,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(), dummyArgNoAttr);
LLVM_DEBUG(llvm::dbgs()
<< "rewriting " << declareOp << " to " << xDeclOp << '\n');
Expand Down
124 changes: 71 additions & 53 deletions flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,62 +144,80 @@ 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;

// Check if the global is actually a common block by demangling its name.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did the previous commit break any existing LIT tests? If not, can you please add one for regression testing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exiting tests are fine. It just occurred to me that I should test it with module equivalance and I saw that those variables were also being marked as common block so I added this check to prevent this. I will add a test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a test. Please let me know if you have any other comments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, Abid! It looks great.

// 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 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,
Expand Down
20 changes: 20 additions & 0 deletions flang/test/Fir/declare-codegen.fir
Original file line number Diff line number Diff line change
Expand Up @@ -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"}
20 changes: 20 additions & 0 deletions flang/test/Integration/debug-module-equivalence.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s

! Test that module EQUIVALENCE does not generate DICommonBlock.

module data_module
real :: var1, var2
equivalence (var1, var2)
end module data_module

subroutine test_module_equiv
use data_module
var1 = 1.5
var2 = 2.5
end subroutine

program main
call test_module_equiv()
end program

! CHECK-NOT: DICommonBlock
36 changes: 18 additions & 18 deletions flang/test/Transforms/debug-common-block.fir
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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() {
Expand All @@ -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() {
Expand All @@ -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)
}
Expand Down