[flang-commits] [flang] [Flang][MIF] Allocation of NON-ALLOCATABLE SAVE coarray (PR #205847)
Jean-Didier PAILLEUX via flang-commits
flang-commits at lists.llvm.org
Mon Jul 13 03:50:27 PDT 2026
https://github.com/JDPailleux updated https://github.com/llvm/llvm-project/pull/205847
>From 0423dc76997ef62a747a95e8696b5d8340039613 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Mon, 4 May 2026 13:45:54 +0200
Subject: [PATCH 1/6] [Flang][MIF] Allocation of NON-ALLOCATABLE SAVE coarray
---
flang/include/flang/Lower/MultiImageFortran.h | 5 +
.../flang/Optimizer/Builder/MIFCommon.h | 9 ++
.../flang/Optimizer/Transforms/Passes.td | 5 +
flang/lib/Lower/Bridge.cpp | 9 --
flang/lib/Lower/ConvertVariable.cpp | 11 +-
flang/lib/Lower/MultiImageFortran.cpp | 23 ++++
flang/lib/Optimizer/Builder/MIFCommon.cpp | 36 ++++++
flang/lib/Optimizer/Builder/Runtime/Main.cpp | 3 +-
flang/lib/Optimizer/Passes/Pipelines.cpp | 2 +
flang/lib/Optimizer/Transforms/CMakeLists.txt | 1 +
.../Transforms/EmitMIFGlobalCtors.cpp | 109 ++++++++++++++++++
flang/test/Fir/basic-program.fir | 1 +
flang/test/Lower/MIF/coarray_allocation4.f90 | 71 +++++++++++-
flang/test/Lower/MIF/coarray_allocation5.f90 | 26 ++++-
14 files changed, 291 insertions(+), 20 deletions(-)
create mode 100644 flang/lib/Optimizer/Transforms/EmitMIFGlobalCtors.cpp
diff --git a/flang/include/flang/Lower/MultiImageFortran.h b/flang/include/flang/Lower/MultiImageFortran.h
index 002f156c807f2..c9b9e9f17cf39 100644
--- a/flang/include/flang/Lower/MultiImageFortran.h
+++ b/flang/include/flang/Lower/MultiImageFortran.h
@@ -76,6 +76,11 @@ mlir::Value genAllocateCoarray(
std::nullopt,
mlir::Value errMsg = {}, bool hasStat = false);
+void genAllocateNonAllocatableSaveCoarray(AbstractConverter &converter,
+ mlir::Location loc,
+ const semantics::Symbol &sym,
+ mlir::Value addr);
+
//===----------------------------------------------------------------------===//
// COARRAY expressions
//===----------------------------------------------------------------------===//
diff --git a/flang/include/flang/Optimizer/Builder/MIFCommon.h b/flang/include/flang/Optimizer/Builder/MIFCommon.h
index 91b8a037e2801..c9b3b4409af1c 100644
--- a/flang/include/flang/Optimizer/Builder/MIFCommon.h
+++ b/flang/include/flang/Optimizer/Builder/MIFCommon.h
@@ -13,6 +13,9 @@
#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
static constexpr llvm::StringRef coarrayHandleSuffix = "_coarray_handle";
+static constexpr llvm::StringRef mifInitializationName = "__mif_initialization";
+static constexpr llvm::StringRef mifSaveCoarraysAllocName =
+ "__mif_save_coarrays_allocate";
namespace mif {
@@ -22,6 +25,12 @@ mlir::Value genImageIndex(fir::FirOpBuilder &, mlir::Location loc,
mlir::Value coarray, mlir::Value sub,
mlir::Value team);
+mlir::func::FuncOp getOrCreateInitFunc(mlir::OpBuilder &builder,
+ mlir::ModuleOp mod,
+ llvm::StringRef name);
+
+void genMIFInit(fir::FirOpBuilder &, mlir::Location loc);
+
} // namespace mif
#endif // FORTRAN_OPTIMIZER_TRANSFORMS_MIFCOMMON_H_
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td
index 4a042926b7a75..482260f26751d 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -691,6 +691,11 @@ def MIFOpConversion : Pass<"mif-convert", "mlir::ModuleOp"> {
"mlir::cf::ControlFlowDialect", "mlir::DLTIDialect"];
}
+def EmitMIFGlobalCtors : Pass<"emit-mif-global-ctors", "mlir::ModuleOp"> {
+ let summary = "Generate GlobalCtorOp to init MIF and allocate coarrays.";
+ let dependentDialects = ["fir::FIROpsDialect", "mlir::LLVM::LLVMDialect"];
+}
+
def LoopInvariantCodeMotion : Pass<"flang-licm", "::mlir::func::FuncOp"> {
let summary = "Hoist invariants from loops";
let description = [{
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 8658a6fb29a44..e2c895351c977 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -6634,15 +6634,6 @@ class FirConverter : public Fortran::lower::AbstractConverter {
if (sym.name() == "numeric_storage_size" && owner.IsModule() &&
DEREF(owner.symbol()).name() == "iso_fortran_env")
continue;
-
- if (Fortran::evaluate::IsCoarray(sym) &&
- !Fortran::semantics::IsAllocatable(sym) &&
- Fortran::semantics::IsSaved(sym)) {
- mlir::Location loc = toLocation();
- TODO(
- loc,
- "coarray: non-ALLOCATABLE SAVE coarray outside the main program");
- }
}
Fortran::lower::defineModuleVariable(*this, var);
}
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index ae11a9230d1b0..6e38f4f4f64e0 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -2634,11 +2634,12 @@ void Fortran::lower::mapSymbolAttributes(
assert(!Fortran::semantics::IsAllocatable(sym) &&
"must be a non-ALLOCATABLE coarray");
if (Fortran::semantics::IsSaved(sym) &&
- sym.owner().kind() != Fortran::semantics::Scope::Kind::MainProgram)
- TODO(loc,
- "coarray: non-ALLOCATABLE SAVE coarray outside the main program");
- ;
- Fortran::lower::genAllocateCoarray(converter, loc, sym, addr);
+ (sym.owner().kind() != Fortran::semantics::Scope::Kind::MainProgram ||
+ var.isModuleOrSubmoduleVariable()))
+ Fortran::lower::genAllocateNonAllocatableSaveCoarray(converter, loc, sym,
+ addr);
+ else
+ Fortran::lower::genAllocateCoarray(converter, loc, sym, addr);
::genDeclareSymbol(converter, symMap, sym, addr, len, extents, lbounds,
replace);
return;
diff --git a/flang/lib/Lower/MultiImageFortran.cpp b/flang/lib/Lower/MultiImageFortran.cpp
index d5770dc197513..ec6f3c17188e4 100644
--- a/flang/lib/Lower/MultiImageFortran.cpp
+++ b/flang/lib/Lower/MultiImageFortran.cpp
@@ -18,6 +18,8 @@
#include "flang/Optimizer/Builder/MIFCommon.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Parser/parse-tree.h"
+#include "flang/Semantics/expression.h"
+#include "mlir/IR/IRMapping.h"
//===----------------------------------------------------------------------===//
// Synchronization statements
@@ -449,6 +451,27 @@ mlir::Value Fortran::lower::genAllocateCoarray(
return stat;
}
+void Fortran::lower::genAllocateNonAllocatableSaveCoarray(
+ Fortran::lower::AbstractConverter &converter, mlir::Location loc,
+ const semantics::Symbol &sym, mlir::Value addr) {
+ fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+ mlir::ModuleOp mod = builder.getModule();
+ mlir::IRMapping mapping;
+
+ auto func = mif::getOrCreateInitFunc(builder, mod, mifSaveCoarraysAllocName);
+
+ mlir::Block &entry = func.getBody().front();
+ auto returnOp = entry.getTerminator();
+
+ mlir::OpBuilder::InsertionGuard guard(builder);
+ builder.setInsertionPoint(returnOp);
+
+ mlir::Operation &op = *addr.getDefiningOp();
+ mlir::Operation *localAddrOp = builder.clone(op, mapping);
+ Fortran::lower::genAllocateCoarray(converter, loc, sym,
+ localAddrOp->getResult(0));
+}
+
//===----------------------------------------------------------------------===//
// COARRAY expressions
//===----------------------------------------------------------------------===//
diff --git a/flang/lib/Optimizer/Builder/MIFCommon.cpp b/flang/lib/Optimizer/Builder/MIFCommon.cpp
index 8f08ce4573bbf..52cadabe1550f 100644
--- a/flang/lib/Optimizer/Builder/MIFCommon.cpp
+++ b/flang/lib/Optimizer/Builder/MIFCommon.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "flang/Optimizer/Builder/MIFCommon.h"
+#include "flang/Lower/MultiImageFortran.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/HLFIRTools.h"
#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
@@ -80,3 +81,38 @@ mlir::Value mif::genImageIndex(fir::FirOpBuilder &builder, mlir::Location loc,
(*subCastAndCleanup.second)();
return imageIndex;
}
+
+mlir::func::FuncOp mif::getOrCreateInitFunc(mlir::OpBuilder &builder,
+ mlir::ModuleOp mod,
+ llvm::StringRef name) {
+
+ if (auto func = mod.lookupSymbol<mlir::func::FuncOp>(name))
+ return func;
+
+ auto funcType = builder.getFunctionType({}, {});
+ mlir::OpBuilder::InsertionGuard guard(builder);
+ builder.setInsertionPointToEnd(mod.getBody());
+
+ mlir::Location loc = mod.getLoc();
+ auto func = mlir::func::FuncOp::create(builder, loc, name, funcType);
+ func.setPublic();
+
+ func.addEntryBlock();
+ builder.setInsertionPointToEnd(&func.getBody().front());
+ mlir::func::ReturnOp::create(builder, loc);
+
+ return func;
+}
+
+void mif::genMIFInit(fir::FirOpBuilder &builder, mlir::Location loc) {
+ mlir::ModuleOp mod = builder.getModule();
+ auto func = getOrCreateInitFunc(builder, mod, mifInitializationName);
+
+ mlir::Block &entry = func.getBody().front();
+ auto returnOp = entry.getTerminator();
+
+ mlir::OpBuilder::InsertionGuard guard(builder);
+ builder.setInsertionPoint(returnOp);
+
+ mif::InitOp::create(builder, loc);
+}
diff --git a/flang/lib/Optimizer/Builder/Runtime/Main.cpp b/flang/lib/Optimizer/Builder/Runtime/Main.cpp
index acc7700891805..9b8c79a8addeb 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Main.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Main.cpp
@@ -10,6 +10,7 @@
#include "flang/Lower/EnvironmentDefault.h"
#include "flang/Optimizer/Builder/BoxValue.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/MIFCommon.h"
#include "flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h"
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
@@ -69,7 +70,7 @@ void fir::runtime::genMain(
fir::CallOp::create(builder, loc, initFn);
}
if (initCoarrayEnv)
- mif::InitOp::create(builder, loc);
+ mif::genMIFInit(builder, loc);
fir::CallOp::create(builder, loc, qqMainFn);
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp
index 5fa70096e0e41..54d828c028c14 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -11,6 +11,7 @@
#include "flang/Optimizer/Passes/Pipelines.h"
#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Builder/MIFCommon.h"
#include "flang/Optimizer/OpenACC/Passes.h"
#include "mlir/Conversion/Passes.h"
#include "mlir/Dialect/LLVMIR/Transforms/Passes.h"
@@ -460,6 +461,7 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
}
fir::addFIRToLLVMPass(pm, config);
+ pm.addPass(fir::createEmitMIFGlobalCtors());
if (config.EnableOpenMP && !config.EnableOpenMPSimd) {
// Remove all non target-related operations from host functions still
diff --git a/flang/lib/Optimizer/Transforms/CMakeLists.txt b/flang/lib/Optimizer/Transforms/CMakeLists.txt
index 0f062255f3ba4..8ff67d901b31d 100644
--- a/flang/lib/Optimizer/Transforms/CMakeLists.txt
+++ b/flang/lib/Optimizer/Transforms/CMakeLists.txt
@@ -28,6 +28,7 @@ add_flang_library(FIRTransforms
ControlFlowConverter.cpp
ConvertComplexPow.cpp
DebugTypeGenerator.cpp
+ EmitMIFGlobalCtors.cpp
ExternalNameConversion.cpp
FIRToSCF.cpp
FIRToMemRef.cpp
diff --git a/flang/lib/Optimizer/Transforms/EmitMIFGlobalCtors.cpp b/flang/lib/Optimizer/Transforms/EmitMIFGlobalCtors.cpp
new file mode 100644
index 0000000000000..cadfd42046ff7
--- /dev/null
+++ b/flang/lib/Optimizer/Transforms/EmitMIFGlobalCtors.cpp
@@ -0,0 +1,109 @@
+//===-- EmitMIFGlobalCtors.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Builder/MIFCommon.h"
+#include "flang/Optimizer/Builder/Runtime/Inquiry.h"
+#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/Pass/Pass.h"
+
+namespace fir {
+#define GEN_PASS_DEF_EMITMIFGLOBALCTORS
+#include "flang/Optimizer/Transforms/Passes.h.inc"
+} // namespace fir
+
+using namespace mlir;
+using namespace Fortran::runtime;
+
+namespace {
+
+class EmitMIFGlobalCtors
+ : public fir::impl::EmitMIFGlobalCtorsBase<EmitMIFGlobalCtors> {
+public:
+ void runOnOperation() override {
+ mlir::ModuleOp mod = getOperation();
+ mlir::MLIRContext *ctx = mod.getContext();
+ mlir::OpBuilder builder(ctx);
+ builder.setInsertionPointToEnd(mod.getBody());
+ mlir::Location loc = builder.getUnknownLoc();
+
+ llvm::SmallVector<mlir::Attribute> funcs, priorities, data;
+ mlir::Type i32Ty = mlir::IntegerType::get(ctx, 32);
+ mlir::Attribute zeroAttr = mlir::LLVM::ZeroAttr::get(builder.getContext());
+
+ // Setting priority 0 for the initialization of mif.
+ if (mod.lookupSymbol<mlir::LLVM::LLVMFuncOp>(mifInitializationName)) {
+ funcs.push_back(mlir::FlatSymbolRefAttr::get(ctx, mifInitializationName));
+ priorities.push_back(mlir::IntegerAttr::get(i32Ty, 0));
+ data.push_back(zeroAttr);
+ }
+
+ // We set priority 1 because 0 is used for the function that call
+ // `mif.init`, to ensure that it is called after the parallel environment
+ // initialization.
+ if (mod.lookupSymbol<mlir::LLVM::LLVMFuncOp>(mifSaveCoarraysAllocName)) {
+ funcs.push_back(
+ mlir::FlatSymbolRefAttr::get(ctx, mifSaveCoarraysAllocName));
+ priorities.push_back(mlir::IntegerAttr::get(i32Ty, 1));
+ data.push_back(zeroAttr);
+ }
+
+ if (funcs.empty())
+ return;
+
+ // We check whether a GlobalCtorsOp already exists to avoid having
+ // multiple instances.
+ mlir::LLVM::GlobalCtorsOp globalCtors;
+ mod.walk([&](mlir::LLVM::GlobalCtorsOp op) { globalCtors = op; });
+
+ if (globalCtors) {
+ llvm::SmallVector<mlir::Attribute> mergedFuncs(
+ globalCtors.getCtors().begin(), globalCtors.getCtors().end());
+ llvm::SmallVector<mlir::Attribute> mergedPriorities(
+ globalCtors.getPriorities().begin(),
+ globalCtors.getPriorities().end());
+ llvm::SmallVector<mlir::Attribute> mergedData(
+ globalCtors.getData().begin(), globalCtors.getData().end());
+
+ llvm::SmallDenseSet<llvm::StringRef> existingNames;
+ for (auto attr : globalCtors.getCtors())
+ existingNames.insert(
+ llvm::cast<mlir::FlatSymbolRefAttr>(attr).getValue());
+
+ for (auto [func, priority, d] : llvm::zip(funcs, priorities, data)) {
+ auto name = llvm::cast<mlir::FlatSymbolRefAttr>(func).getValue();
+ if (!existingNames.contains(name)) {
+ mergedFuncs.push_back(func);
+ mergedPriorities.push_back(priority);
+ mergedData.push_back(d);
+ }
+ }
+
+ // Deleting the existing GlobalCtorsOp and creating a new one that
+ // contains the merged attributes.
+ builder.setInsertionPoint(globalCtors);
+ mlir::LLVM::GlobalCtorsOp::create(builder, globalCtors.getLoc(),
+ builder.getArrayAttr(mergedFuncs),
+ builder.getArrayAttr(mergedPriorities),
+ builder.getArrayAttr(mergedData));
+ globalCtors.erase();
+ } else {
+ builder.setInsertionPointToEnd(mod.getBody());
+ mlir::LLVM::GlobalCtorsOp::create(
+ builder, loc, builder.getArrayAttr(funcs),
+ builder.getArrayAttr(priorities), builder.getArrayAttr(data));
+ }
+ }
+};
+
+} // namespace
diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir
index 471e5a89046eb..1fb7ed81f547c 100644
--- a/flang/test/Fir/basic-program.fir
+++ b/flang/test/Fir/basic-program.fir
@@ -184,6 +184,7 @@ func.func @_QQmain() {
// PASSES-NEXT: LowerNontemporalPass
// PASSES-NEXT: FIRToLLVMLowering
// PASSES-NEXT: ReconcileUnrealizedCasts
+// PASSES-NEXT: EmitMIFGlobalCtors
// PASSES-NEXT: HostOpFilteringPass
// PASSES-NEXT: 'llvm.func' Pipeline
// PASSES-NEXT: StackToSharedPass
diff --git a/flang/test/Lower/MIF/coarray_allocation4.f90 b/flang/test/Lower/MIF/coarray_allocation4.f90
index f0278ea2cd534..1f10067d651ba 100644
--- a/flang/test/Lower/MIF/coarray_allocation4.f90
+++ b/flang/test/Lower/MIF/coarray_allocation4.f90
@@ -1,8 +1,75 @@
-! RUN: not %flang_fc1 -emit-hlfir -fcoarray %s -o - 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -emit-llvm -fcoarray %s -o - 2>&1 | FileCheck %s --check-prefix=LLVM
-!CHECK: not yet implemented: coarray: non-ALLOCATABLE SAVE coarray outside the main program
+! LLVM: llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @__mif_initialization, ptr null }, { i32, ptr, ptr } { i32 1, ptr @__mif_save_coarrays_allocate, ptr null }]
subroutine test_coarray_save()
implicit none
real, SAVE :: n[*]
+ real, SAVE :: m[*]
+ real, SAVE :: p[*]
end subroutine test_coarray_save
+
+program main
+ call test_coarray_save()
+end program
+
+! CHECK-LABEL: func.func @_QPtest_coarray_save()
+! CHECK: %0 = fir.dummy_scope : !fir.dscope
+! CHECK: %1 = fir.address_of(@_QFtest_coarray_saveEm) : !fir.ref<f32>
+! CHECK: %2:2 = hlfir.declare %1 {uniq_name = "_QFtest_coarray_saveEm"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: %3 = fir.address_of(@_QFtest_coarray_saveEn) : !fir.ref<f32>
+! CHECK: %4:2 = hlfir.declare %3 {uniq_name = "_QFtest_coarray_saveEn"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: %5 = fir.address_of(@_QFtest_coarray_saveEp) : !fir.ref<f32>
+! CHECK: %6:2 = hlfir.declare %5 {uniq_name = "_QFtest_coarray_saveEp"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: return
+
+! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "MAIN"}
+! CHECK: %0 = fir.dummy_scope : !fir.dscope
+! CHECK: fir.call @_QPtest_coarray_save() fastmath<contract> : () -> ()
+! CHECK: return
+
+! CHECK: fir.global internal @_QFtest_coarray_saveEm : f32
+
+! CHECK-LABEL: func.func @__mif_save_coarrays_allocate()
+! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.array<0xi64>
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<1xi64>
+! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.array<0xi64>
+! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.array<1xi64>
+! CHECK: %[[VAL_4:.*]] = fir.alloca !fir.array<0xi64>
+! CHECK: %[[VAL_5:.*]] = fir.alloca !fir.array<1xi64>
+! CHECK: %[[VAL_6:.*]] = fir.address_of(@_QFtest_coarray_saveEm) : !fir.ref<f32>
+! CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64
+! CHECK: %[[C1_I64_0:.*]] = arith.constant 1 : i64
+! CHECK: %[[C0:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_7:.*]] = fir.coordinate_of %[[VAL_5]], %[[C0]] : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
+! CHECK: fir.store %[[C1_I64_0]] to %[[VAL_7]] : !fir.ref<i64>
+! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_5]] : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
+! CHECK: %[[C1_I64_1:.*]] = arith.constant 1 : i64
+! CHECK: %[[VAL_9:.*]] = fir.embox %[[VAL_4]] : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
+! CHECK: mif.alloc_coarray %[[VAL_6]] lcobounds %[[VAL_8]] ucobounds %[[VAL_9]] {uniq_name = "_QFtest_coarray_saveEm"} : (!fir.ref<f32>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
+! CHECK: %[[VAL_10:.*]] = fir.address_of(@_QFtest_coarray_saveEn) : !fir.ref<f32>
+! CHECK: %[[C1_I64_2:.*]] = arith.constant 1 : i64
+! CHECK: %[[C1_I64_3:.*]] = arith.constant 1 : i64
+! CHECK: %[[C0_4:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_11:.*]] = fir.coordinate_of %[[VAL_3]], %[[C0_4]] : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
+! CHECK: fir.store %[[C1_I64_3]] to %[[VAL_11]] : !fir.ref<i64>
+! CHECK: %[[VAL_12:.*]] = fir.embox %[[VAL_3]] : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
+! CHECK: %[[C1_I64_5:.*]] = arith.constant 1 : i64
+! CHECK: %[[VAL_13:.*]] = fir.embox %[[VAL_2]] : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
+! CHECK: mif.alloc_coarray %[[VAL_10]] lcobounds %[[VAL_12]] ucobounds %[[VAL_13]] {uniq_name = "_QFtest_coarray_saveEn"} : (!fir.ref<f32>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
+! CHECK: %[[VAL_14:.*]] = fir.address_of(@_QFtest_coarray_saveEp) : !fir.ref<f32>
+! CHECK: %[[C1_I64_6:.*]] = arith.constant 1 : i64
+! CHECK: %[[C1_I64_7:.*]] = arith.constant 1 : i64
+! CHECK: %[[C0_8:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_15:.*]] = fir.coordinate_of %[[VAL_1]], %[[C0_8]] : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
+! CHECK: fir.store %[[C1_I64_7]] to %[[VAL_15]] : !fir.ref<i64>
+! CHECK: %[[VAL_16:.*]] = fir.embox %[[VAL_1]] : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
+! CHECK: %[[VAL_C1_I64_9:.*]] = arith.constant 1 : i64
+! CHECK: %[[VAL_17:.*]] = fir.embox %[[VAL_0]] : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
+! CHECK: mif.alloc_coarray %[[VAL_14:.*]] lcobounds %[[VAL_16]] ucobounds %[[VAL_17]] {uniq_name = "_QFtest_coarray_saveEp"} : (!fir.ref<f32>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
+! CHECK: return
+
+! CHECK: fir.global internal @_QFtest_coarray_saveEn : f32
+! CHECK: fir.global internal @_QFtest_coarray_saveEp : f32
+
diff --git a/flang/test/Lower/MIF/coarray_allocation5.f90 b/flang/test/Lower/MIF/coarray_allocation5.f90
index 42058363bf9fb..34e7a57fff778 100644
--- a/flang/test/Lower/MIF/coarray_allocation5.f90
+++ b/flang/test/Lower/MIF/coarray_allocation5.f90
@@ -1,8 +1,28 @@
-! RUN: not %flang_fc1 -emit-hlfir -fcoarray %s -o - 2>&1 | FileCheck %s
-
-!CHECK: not yet implemented: coarray: non-ALLOCATABLE SAVE coarray outside the main program
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-llvm -fcoarray %s -o - 2>&1 | FileCheck %s --check-prefix=LLVM
module m_coarray_test
implicit none
real :: module_coarray[*]
end module m_coarray_test
+
+program test
+ use m_coarray_test
+end program
+
+! LLVM: llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @__mif_initialization, ptr null }, { i32, ptr, ptr } { i32 1, ptr @__mif_save_coarrays_allocate, ptr null }]
+
+! CHECK-LABEL: func.func @__mif_save_coarrays_allocate()
+! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.array<0xi64>
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<1xi64>
+! CHECK: %[[VAL_2:.*]] = fir.address_of(@_QMm_coarray_testEmodule_coarray) : !fir.ref<f32>
+! CHECK: %c1_i64 = arith.constant 1 : i64
+! CHECK: %c1_i64_0 = arith.constant 1 : i64
+! CHECK: %c0 = arith.constant 0 : index
+! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %c0 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
+! CHECK: fir.store %c1_i64_0 to %[[VAL_3]] : !fir.ref<i64>
+! CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_1]] : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
+! CHECK: %c1_i64_1 = arith.constant 1 : i64
+! CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_0]] : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
+! CHECK: mif.alloc_coarray %[[VAL_2]] lcobounds %[[VAL_4]] ucobounds %[[VAL_5]] {uniq_name = "_QMm_coarray_testEmodule_coarray"} : (!fir.ref<f32>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
+! CHECK: return
>From fe946f84b78309051f4dc46fc5f4ed0e6ff71007 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Fri, 26 Jun 2026 16:42:32 +0200
Subject: [PATCH 2/6] Assume that many mif.init can be called and remove
useless ctors on mif.init
---
flang/include/flang/Optimizer/Builder/MIFCommon.h | 3 ---
flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td | 7 ++++++-
flang/lib/Lower/MultiImageFortran.cpp | 6 ++++++
flang/lib/Optimizer/Builder/MIFCommon.cpp | 13 -------------
flang/lib/Optimizer/Builder/Runtime/Main.cpp | 3 +--
.../lib/Optimizer/Transforms/EmitMIFGlobalCtors.cpp | 11 +----------
6 files changed, 14 insertions(+), 29 deletions(-)
diff --git a/flang/include/flang/Optimizer/Builder/MIFCommon.h b/flang/include/flang/Optimizer/Builder/MIFCommon.h
index c9b3b4409af1c..67eb3e1081be3 100644
--- a/flang/include/flang/Optimizer/Builder/MIFCommon.h
+++ b/flang/include/flang/Optimizer/Builder/MIFCommon.h
@@ -13,7 +13,6 @@
#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
static constexpr llvm::StringRef coarrayHandleSuffix = "_coarray_handle";
-static constexpr llvm::StringRef mifInitializationName = "__mif_initialization";
static constexpr llvm::StringRef mifSaveCoarraysAllocName =
"__mif_save_coarrays_allocate";
@@ -29,8 +28,6 @@ mlir::func::FuncOp getOrCreateInitFunc(mlir::OpBuilder &builder,
mlir::ModuleOp mod,
llvm::StringRef name);
-void genMIFInit(fir::FirOpBuilder &, mlir::Location loc);
-
} // namespace mif
#endif // FORTRAN_OPTIMIZER_TRANSFORMS_MIFCOMMON_H_
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
index 4acbeec47eb2e..337a9eab0b087 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -32,7 +32,12 @@ class region_Op<string mnemonic, list<Trait> traits = []>
def mif_InitOp : mif_Op<"init", []> {
let summary = "Initialize the parallel environment";
- let description = [{This operation will initialize the parallel environment}];
+ let description = [{
+ This operation will initialize the parallel environment and shall be called
+ prior to any other MIF operations.
+ Any second or subsequent call to mif.init is guaranteed to return
+ immediately with no effect.
+ }];
let results = (outs I32:$stat);
let assemblyFormat = "`->` type($stat) attr-dict";
diff --git a/flang/lib/Lower/MultiImageFortran.cpp b/flang/lib/Lower/MultiImageFortran.cpp
index ec6f3c17188e4..66ffca0b850dd 100644
--- a/flang/lib/Lower/MultiImageFortran.cpp
+++ b/flang/lib/Lower/MultiImageFortran.cpp
@@ -459,6 +459,7 @@ void Fortran::lower::genAllocateNonAllocatableSaveCoarray(
mlir::IRMapping mapping;
auto func = mif::getOrCreateInitFunc(builder, mod, mifSaveCoarraysAllocName);
+ bool funcIsEmpty = func.empty();
mlir::Block &entry = func.getBody().front();
auto returnOp = entry.getTerminator();
@@ -466,6 +467,11 @@ void Fortran::lower::genAllocateNonAllocatableSaveCoarray(
mlir::OpBuilder::InsertionGuard guard(builder);
builder.setInsertionPoint(returnOp);
+ // If the function is empty, then we add the MIF initialization operation
+ // at the beginning.
+ if (funcIsEmpty)
+ mif::InitOp::create(builder, loc);
+
mlir::Operation &op = *addr.getDefiningOp();
mlir::Operation *localAddrOp = builder.clone(op, mapping);
Fortran::lower::genAllocateCoarray(converter, loc, sym,
diff --git a/flang/lib/Optimizer/Builder/MIFCommon.cpp b/flang/lib/Optimizer/Builder/MIFCommon.cpp
index 52cadabe1550f..3080177b7af13 100644
--- a/flang/lib/Optimizer/Builder/MIFCommon.cpp
+++ b/flang/lib/Optimizer/Builder/MIFCommon.cpp
@@ -103,16 +103,3 @@ mlir::func::FuncOp mif::getOrCreateInitFunc(mlir::OpBuilder &builder,
return func;
}
-
-void mif::genMIFInit(fir::FirOpBuilder &builder, mlir::Location loc) {
- mlir::ModuleOp mod = builder.getModule();
- auto func = getOrCreateInitFunc(builder, mod, mifInitializationName);
-
- mlir::Block &entry = func.getBody().front();
- auto returnOp = entry.getTerminator();
-
- mlir::OpBuilder::InsertionGuard guard(builder);
- builder.setInsertionPoint(returnOp);
-
- mif::InitOp::create(builder, loc);
-}
diff --git a/flang/lib/Optimizer/Builder/Runtime/Main.cpp b/flang/lib/Optimizer/Builder/Runtime/Main.cpp
index 9b8c79a8addeb..acc7700891805 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Main.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Main.cpp
@@ -10,7 +10,6 @@
#include "flang/Lower/EnvironmentDefault.h"
#include "flang/Optimizer/Builder/BoxValue.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
-#include "flang/Optimizer/Builder/MIFCommon.h"
#include "flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h"
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
@@ -70,7 +69,7 @@ void fir::runtime::genMain(
fir::CallOp::create(builder, loc, initFn);
}
if (initCoarrayEnv)
- mif::genMIFInit(builder, loc);
+ mif::InitOp::create(builder, loc);
fir::CallOp::create(builder, loc, qqMainFn);
diff --git a/flang/lib/Optimizer/Transforms/EmitMIFGlobalCtors.cpp b/flang/lib/Optimizer/Transforms/EmitMIFGlobalCtors.cpp
index cadfd42046ff7..f5e2c35733f21 100644
--- a/flang/lib/Optimizer/Transforms/EmitMIFGlobalCtors.cpp
+++ b/flang/lib/Optimizer/Transforms/EmitMIFGlobalCtors.cpp
@@ -42,19 +42,10 @@ class EmitMIFGlobalCtors
mlir::Attribute zeroAttr = mlir::LLVM::ZeroAttr::get(builder.getContext());
// Setting priority 0 for the initialization of mif.
- if (mod.lookupSymbol<mlir::LLVM::LLVMFuncOp>(mifInitializationName)) {
- funcs.push_back(mlir::FlatSymbolRefAttr::get(ctx, mifInitializationName));
- priorities.push_back(mlir::IntegerAttr::get(i32Ty, 0));
- data.push_back(zeroAttr);
- }
-
- // We set priority 1 because 0 is used for the function that call
- // `mif.init`, to ensure that it is called after the parallel environment
- // initialization.
if (mod.lookupSymbol<mlir::LLVM::LLVMFuncOp>(mifSaveCoarraysAllocName)) {
funcs.push_back(
mlir::FlatSymbolRefAttr::get(ctx, mifSaveCoarraysAllocName));
- priorities.push_back(mlir::IntegerAttr::get(i32Ty, 1));
+ priorities.push_back(mlir::IntegerAttr::get(i32Ty, 0));
data.push_back(zeroAttr);
}
>From 50cec4db0c7008148e588eac3382e2c1f26198fd Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Wed, 1 Jul 2026 10:13:04 +0200
Subject: [PATCH 3/6] Fix tests
---
flang/test/Lower/MIF/coarray_allocation4.f90 | 2 +-
flang/test/Lower/MIF/coarray_allocation5.f90 | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/flang/test/Lower/MIF/coarray_allocation4.f90 b/flang/test/Lower/MIF/coarray_allocation4.f90
index 1f10067d651ba..d93208c153213 100644
--- a/flang/test/Lower/MIF/coarray_allocation4.f90
+++ b/flang/test/Lower/MIF/coarray_allocation4.f90
@@ -1,7 +1,7 @@
! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - 2>&1 | FileCheck %s
! RUN: %flang_fc1 -emit-llvm -fcoarray %s -o - 2>&1 | FileCheck %s --check-prefix=LLVM
-! LLVM: llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @__mif_initialization, ptr null }, { i32, ptr, ptr } { i32 1, ptr @__mif_save_coarrays_allocate, ptr null }]
+! LLVM: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @__mif_save_coarrays_allocate, ptr null }]
subroutine test_coarray_save()
implicit none
diff --git a/flang/test/Lower/MIF/coarray_allocation5.f90 b/flang/test/Lower/MIF/coarray_allocation5.f90
index 34e7a57fff778..96ee068f8fa75 100644
--- a/flang/test/Lower/MIF/coarray_allocation5.f90
+++ b/flang/test/Lower/MIF/coarray_allocation5.f90
@@ -10,7 +10,7 @@ program test
use m_coarray_test
end program
-! LLVM: llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @__mif_initialization, ptr null }, { i32, ptr, ptr } { i32 1, ptr @__mif_save_coarrays_allocate, ptr null }]
+! LLVM: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @__mif_save_coarrays_allocate, ptr null }]
! CHECK-LABEL: func.func @__mif_save_coarrays_allocate()
! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.array<0xi64>
>From 794ae488874f69b82ea753b29de7e3932d4cc1fd Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Fri, 3 Jul 2026 11:06:05 +0200
Subject: [PATCH 4/6] Add TODO on default initialization for coarray variables
---
flang/lib/Lower/ConvertVariable.cpp | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 6e38f4f4f64e0..583da1f1ae9d3 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -698,10 +698,15 @@ static void instantiateGlobal(Fortran::lower::AbstractConverter &converter,
mlir::StringAttr linkage = getLinkageAttribute(converter, var);
fir::GlobalOp global;
- if (Fortran::evaluate::IsCoarray(sym))
+ if (Fortran::evaluate::IsCoarray(sym)) {
if (hasFinalization(sym) || hasAllocatableDirectComponent(sym))
TODO(loc, "coarray: coarray with an allocatable direct component and/or "
"requiring finalization");
+ const auto *details =
+ sym.detailsIf<Fortran::semantics::ObjectEntityDetails>();
+ if (details && details->init())
+ TODO(loc, "coarray: default initialization.");
+ }
if (var.isModuleOrSubmoduleVariable()) {
// A non-intrinsic module global is defined when lowering the module.
>From dda46079775ea153357d2a7edde4938444eeec7f Mon Sep 17 00:00:00 2001
From: Jean-Didier PAILLEUX <jean-di.pailleux at outlook.com>
Date: Tue, 7 Jul 2026 10:59:15 +0200
Subject: [PATCH 5/6] Update flang/lib/Lower/ConvertVariable.cpp
Co-authored-by: Dan Bonachea <dobonachea at lbl.gov>
---
flang/lib/Lower/ConvertVariable.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 583da1f1ae9d3..f971feb0f01df 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -705,7 +705,7 @@ static void instantiateGlobal(Fortran::lower::AbstractConverter &converter,
const auto *details =
sym.detailsIf<Fortran::semantics::ObjectEntityDetails>();
if (details && details->init())
- TODO(loc, "coarray: default initialization.");
+ TODO(loc, "coarray: initialization");
}
if (var.isModuleOrSubmoduleVariable()) {
>From 443ca476050f2af5cc6237c0bf21009c2833a2b8 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Fri, 10 Jul 2026 14:06:52 +0200
Subject: [PATCH 6/6] Using builder.createFunction + Fix missing mif.init in
the GlobalCtors function
---
flang/include/flang/Optimizer/Builder/MIFCommon.h | 2 +-
flang/lib/Optimizer/Builder/MIFCommon.cpp | 15 +++++++--------
flang/test/Lower/MIF/coarray_allocation4.f90 | 1 +
flang/test/Lower/MIF/coarray_allocation5.f90 | 1 +
4 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/flang/include/flang/Optimizer/Builder/MIFCommon.h b/flang/include/flang/Optimizer/Builder/MIFCommon.h
index 67eb3e1081be3..8c986dee0d179 100644
--- a/flang/include/flang/Optimizer/Builder/MIFCommon.h
+++ b/flang/include/flang/Optimizer/Builder/MIFCommon.h
@@ -24,7 +24,7 @@ mlir::Value genImageIndex(fir::FirOpBuilder &, mlir::Location loc,
mlir::Value coarray, mlir::Value sub,
mlir::Value team);
-mlir::func::FuncOp getOrCreateInitFunc(mlir::OpBuilder &builder,
+mlir::func::FuncOp getOrCreateInitFunc(fir::FirOpBuilder &builder,
mlir::ModuleOp mod,
llvm::StringRef name);
diff --git a/flang/lib/Optimizer/Builder/MIFCommon.cpp b/flang/lib/Optimizer/Builder/MIFCommon.cpp
index 3080177b7af13..56225cda34fdb 100644
--- a/flang/lib/Optimizer/Builder/MIFCommon.cpp
+++ b/flang/lib/Optimizer/Builder/MIFCommon.cpp
@@ -82,23 +82,22 @@ mlir::Value mif::genImageIndex(fir::FirOpBuilder &builder, mlir::Location loc,
return imageIndex;
}
-mlir::func::FuncOp mif::getOrCreateInitFunc(mlir::OpBuilder &builder,
+mlir::func::FuncOp mif::getOrCreateInitFunc(fir::FirOpBuilder &builder,
mlir::ModuleOp mod,
llvm::StringRef name) {
-
- if (auto func = mod.lookupSymbol<mlir::func::FuncOp>(name))
+ mlir::Location loc = mod.getLoc();
+ auto funcType = builder.getFunctionType({}, {});
+ auto func = builder.createFunction(loc, name, funcType);
+ if (!func.empty())
return func;
- auto funcType = builder.getFunctionType({}, {});
+ func.setPublic();
mlir::OpBuilder::InsertionGuard guard(builder);
builder.setInsertionPointToEnd(mod.getBody());
- mlir::Location loc = mod.getLoc();
- auto func = mlir::func::FuncOp::create(builder, loc, name, funcType);
- func.setPublic();
-
func.addEntryBlock();
builder.setInsertionPointToEnd(&func.getBody().front());
+ mif::InitOp::create(builder, loc);
mlir::func::ReturnOp::create(builder, loc);
return func;
diff --git a/flang/test/Lower/MIF/coarray_allocation4.f90 b/flang/test/Lower/MIF/coarray_allocation4.f90
index d93208c153213..450fad07f9933 100644
--- a/flang/test/Lower/MIF/coarray_allocation4.f90
+++ b/flang/test/Lower/MIF/coarray_allocation4.f90
@@ -38,6 +38,7 @@ program main
! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.array<1xi64>
! CHECK: %[[VAL_4:.*]] = fir.alloca !fir.array<0xi64>
! CHECK: %[[VAL_5:.*]] = fir.alloca !fir.array<1xi64>
+! CHECK: %[[INIT_STAT:.*]] = mif.init -> i32
! CHECK: %[[VAL_6:.*]] = fir.address_of(@_QFtest_coarray_saveEm) : !fir.ref<f32>
! CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64
! CHECK: %[[C1_I64_0:.*]] = arith.constant 1 : i64
diff --git a/flang/test/Lower/MIF/coarray_allocation5.f90 b/flang/test/Lower/MIF/coarray_allocation5.f90
index 96ee068f8fa75..c1a7958b67454 100644
--- a/flang/test/Lower/MIF/coarray_allocation5.f90
+++ b/flang/test/Lower/MIF/coarray_allocation5.f90
@@ -15,6 +15,7 @@ program test
! CHECK-LABEL: func.func @__mif_save_coarrays_allocate()
! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.array<0xi64>
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<1xi64>
+! CHECK: %[[INIT_STAT:.*]] = mif.init -> i32
! CHECK: %[[VAL_2:.*]] = fir.address_of(@_QMm_coarray_testEmodule_coarray) : !fir.ref<f32>
! CHECK: %c1_i64 = arith.constant 1 : i64
! CHECK: %c1_i64_0 = arith.constant 1 : i64
More information about the flang-commits
mailing list