[flang-commits] [flang] [flang][Multi-Image] Moving Mutli-image lowering to PRIF into the MIF dialect (PR #161179)
Jean-Didier PAILLEUX via flang-commits
flang-commits at lists.llvm.org
Mon Sep 29 04:46:25 PDT 2025
https://github.com/JDPailleux created https://github.com/llvm/llvm-project/pull/161179
Support for multi-image features has begun to be integrated into LLVM. A new dialect which simplifies lowering to PRIF wil be proposed in this PR.
The initial definition of this dialect (MIF) is based only on operations already upstreamed in LLVM and the current lowering will be moved to this dialect.
Features like TEAMs and the use of coarrays will follow later in other PRs.
Any feedback regarding what is proposed is welcome.
>From cea250942b2784642a5c28d875179fed647a5b12 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Mon, 29 Sep 2025 13:31:57 +0200
Subject: [PATCH 1/2] [flang] Defining bases of the MIF Dialect
---
.../flang/Optimizer/Dialect/CMakeLists.txt | 1 +
.../Optimizer/Dialect/MIF/CMakeLists.txt | 9 +
.../flang/Optimizer/Dialect/MIF/MIFDialect.h | 31 ++
.../flang/Optimizer/Dialect/MIF/MIFDialect.td | 38 +++
.../flang/Optimizer/Dialect/MIF/MIFOps.h | 20 ++
.../flang/Optimizer/Dialect/MIF/MIFOps.td | 274 ++++++++++++++++++
.../include/flang/Optimizer/Support/InitFIR.h | 3 +-
flang/lib/Frontend/CMakeLists.txt | 2 +
flang/lib/Lower/CMakeLists.txt | 2 +
flang/lib/Optimizer/Builder/CMakeLists.txt | 2 +
flang/lib/Optimizer/Dialect/CMakeLists.txt | 1 +
.../lib/Optimizer/Dialect/MIF/CMakeLists.txt | 20 ++
.../lib/Optimizer/Dialect/MIF/MIFDialect.cpp | 24 ++
flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp | 133 +++++++++
flang/lib/Optimizer/Transforms/CMakeLists.txt | 2 +
flang/tools/bbc/CMakeLists.txt | 1 +
flang/tools/fir-lsp-server/CMakeLists.txt | 3 +-
flang/tools/fir-opt/CMakeLists.txt | 1 +
flang/tools/tco/CMakeLists.txt | 1 +
flang/unittests/Optimizer/CMakeLists.txt | 4 +-
20 files changed, 569 insertions(+), 3 deletions(-)
create mode 100644 flang/include/flang/Optimizer/Dialect/MIF/CMakeLists.txt
create mode 100644 flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
create mode 100644 flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.td
create mode 100644 flang/include/flang/Optimizer/Dialect/MIF/MIFOps.h
create mode 100644 flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
create mode 100644 flang/lib/Optimizer/Dialect/MIF/CMakeLists.txt
create mode 100644 flang/lib/Optimizer/Dialect/MIF/MIFDialect.cpp
create mode 100644 flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
diff --git a/flang/include/flang/Optimizer/Dialect/CMakeLists.txt b/flang/include/flang/Optimizer/Dialect/CMakeLists.txt
index adefcfea0b5dc..7b1a12932276a 100644
--- a/flang/include/flang/Optimizer/Dialect/CMakeLists.txt
+++ b/flang/include/flang/Optimizer/Dialect/CMakeLists.txt
@@ -1,5 +1,6 @@
add_subdirectory(CUF)
add_subdirectory(FIRCG)
+add_subdirectory(MIF)
# This replicates part of the add_mlir_dialect cmake function from MLIR that
# cannot be used her because it expects to be run inside MLIR directory which
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/CMakeLists.txt b/flang/include/flang/Optimizer/Dialect/MIF/CMakeLists.txt
new file mode 100644
index 0000000000000..27ba3889c8045
--- /dev/null
+++ b/flang/include/flang/Optimizer/Dialect/MIF/CMakeLists.txt
@@ -0,0 +1,9 @@
+set(LLVM_TARGET_DEFINITIONS MIFDialect.td)
+mlir_tablegen(MIFDialect.h.inc -gen-dialect-decls -dialect=mif)
+mlir_tablegen(MIFDialect.cpp.inc -gen-dialect-defs -dialect=mif)
+
+# Add Multi Image Fortran operations
+set(LLVM_TARGET_DEFINITIONS MIFOps.td)
+mlir_tablegen(MIFOps.h.inc -gen-op-decls)
+mlir_tablegen(MIFOps.cpp.inc -gen-op-defs)
+add_public_tablegen_target(MIFOpsIncGen)
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
new file mode 100644
index 0000000000000..f862d9175a6ae
--- /dev/null
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
@@ -0,0 +1,31 @@
+//===- MIF.h - MIF dialect --------------------------------*- C++-*-==//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_OPTIMIZER_DIALECT_MIF_MIF_H
+#define FORTRAN_OPTIMIZER_DIALECT_MIF_MIF_H
+
+#include "mlir/Bytecode/BytecodeOpInterface.h"
+#include "mlir/IR/Dialect.h"
+#include "mlir/IR/OpDefinition.h"
+#include "mlir/IR/OpImplementation.h"
+#include "mlir/IR/SymbolTable.h"
+#include "mlir/Interfaces/CallInterfaces.h"
+#include "mlir/Interfaces/InferTypeOpInterface.h"
+#include "mlir/Interfaces/SideEffectInterfaces.h"
+#include "mlir/Interfaces/VectorInterfaces.h"
+
+// #include "flang/Optimizer/Dialect/FIRAttr.h"
+// #include "flang/Optimizer/Dialect/FIRType.h"
+
+//===----------------------------------------------------------------------===//
+// MIFDialect
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Dialect/MIF/MIFDialect.h.inc"
+
+#endif // FORTRAN_OPTIMIZER_DIALECT_MIF_MIF_H
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.td
new file mode 100644
index 0000000000000..f8be6a86a79fe
--- /dev/null
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.td
@@ -0,0 +1,38 @@
+//===-- MIFDialect.td - MIF dialect base definitions - tablegen ---------*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Definition of the Multi-Image Fortran (MIF) dialect
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_DIALECT_MIF_MIFDIALECT
+#define FORTRAN_DIALECT_MIF_MIFDIALECT
+
+include "mlir/IR/AttrTypeBase.td"
+include "mlir/IR/EnumAttr.td"
+include "mlir/IR/OpBase.td"
+
+def MIFDialect : Dialect {
+ let name = "mif";
+
+ let summary = "Multi-Image Fortran dialect";
+
+ let description = [{
+ The "MIF" dialect is designed to contain the basic coarray operations
+ in Fortran and all multi image operations as descibed in the standard.
+ This includes synchronization operations, atomic operations,
+ image queries, teams, criticals, etc. The MIF dialect operations use
+ the FIR types and are tightly coupled with FIR and HLFIR.
+ }];
+
+ let cppNamespace = "::mif";
+ let dependentDialects = ["fir::FIROpsDialect"];
+}
+
+#endif // FORTRAN_DIALECT_MIF_MIFDIALECT
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.h b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.h
new file mode 100644
index 0000000000000..a9e53c21171c4
--- /dev/null
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.h
@@ -0,0 +1,20 @@
+//===-- Optimizer/Dialect/MIF/MIFOps.h - MIF operations ---------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_OPTIMIZER_DIALECT_MIF_MIFOPS_H
+#define FORTRAN_OPTIMIZER_DIALECT_MIF_MIFOPS_H
+
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Dialect/MIF/MIFDialect.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/IR/OpDefinition.h"
+
+#define GET_OP_CLASSES
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h.inc"
+
+#endif // FORTRAN_OPTIMIZER_DIALECT_MIF_MIFOPS_H
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
new file mode 100644
index 0000000000000..115ef0c65a76f
--- /dev/null
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -0,0 +1,274 @@
+//===-- MIFOps.td - MIF operation definitions ------*- tablegen -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Definition of the MIF dialect operations
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_DIALECT_MIF_MIF_OPS
+#define FORTRAN_DIALECT_MIF_MIF_OPS
+
+include "flang/Optimizer/Dialect/MIF/MIFDialect.td"
+include "flang/Optimizer/Dialect/FIRTypes.td"
+include "flang/Optimizer/Dialect/FIRAttr.td"
+include "mlir/Dialect/LLVMIR/LLVMAttrDefs.td"
+include "mlir/Dialect/LLVMIR/LLVMOpBase.td"
+include "mlir/Interfaces/LoopLikeInterface.td"
+include "mlir/IR/BuiltinAttributes.td"
+
+class mif_Op<string mnemonic, list<Trait> traits>
+ : Op<MIFDialect, mnemonic, traits>;
+
+//===----------------------------------------------------------------------===//
+// Initialization and Finalization
+//===----------------------------------------------------------------------===//
+
+def mif_InitOp : mif_Op<"init", []> {
+ let summary = "Initialize the parallel environment";
+ let description = [{This operation will initialize the parallel environment}];
+
+ let results = (outs I32:$stat);
+ let assemblyFormat = "`->` type($stat) attr-dict";
+}
+
+//===----------------------------------------------------------------------===//
+// Image Queries
+//===----------------------------------------------------------------------===//
+
+def mif_NumImagesOp
+ : mif_Op<"num_images", [NoMemoryEffect, AttrSizedOperandSegments]> {
+ let summary = "Query the number of images in the specified or current team";
+ let description = [{
+ This operation query the number of images in the specified or current
+ team and can be called with 3 differents way :
+ - `num_images()`
+ - `num_images(team)`
+ - `num_images(team_number)`
+
+ Arguments:
+ - `team` : Shall be a scalar of type `team_type` from the `ISO_FORTRAN_ENV`
+ module with a value that identifies the current or ancestor team.
+ - `team_number` : Shall be an integer scalar. It shall identify the
+ initial team or a sibling team of the current team.
+
+ Result Value: The number of images in the specified team, or in the current
+ team if no team is specified.
+ }];
+
+ let arguments = (ins Optional<AnyInteger>:$team_number,
+ Optional<AnyRefOrBoxType>:$team);
+ let results = (outs I32:$res);
+
+ let builders = [OpBuilder<(ins CArg<"mlir::Value", "{}">:$teamArg)>];
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ ( `team_number` `(` $team_number^ `:` type($team_number) `)` )?
+ ( `team` `(` $team^ `:` type($team) `)` )?
+ attr-dict `->` type($res)
+ }];
+}
+
+def mif_ThisImageOp
+ : mif_Op<"this_image", [NoMemoryEffect, AttrSizedOperandSegments]> {
+ let summary = "Determine the image index of the current image";
+ let description = [{
+ Arguments:
+ - `coarray` : Shall be a coarray of any type.
+ - `dim` : Shall be an integer scalar. Its value shall be in the range of
+ 1 <= DIM <= N, where N is the corank of the coarray.
+ - `team`(optional) : Shall be a scalar of type `team_type` from
+ ISO_FORTRAN_ENV. If the `coarray` is present, it shall be
+ established in that team.
+
+ Results:
+ - Case(1) : The result of `this_image([team])` is a scalar with a value
+ equal to the index of the image in the current or specified team.
+ - Case(2) : The result of `this_image(coarray [,team])` is the sequence of
+ cosubscript values for `coarray`.
+ - Case(3) : The result of `this_image(coarray, dim [,team])` is the value of
+ cosubscript `dim` in the sequence of cosubscript values for `coarray`.
+
+ Example:
+ ```fortran
+ REAL :: A[10, 0:9, 0:*]
+ ```
+ If we take a look on the example and we are on image 5, `this_image` has the
+ value 5, `this_image(A)` has the value [5, 0, 0].
+ }];
+
+ let arguments = (ins Optional<fir_BoxType>:$coarray,
+ Optional<AnyInteger>:$dim, Optional<fir_BoxType>:$team);
+ let results = (outs I32:$res);
+
+ let builders = [OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$team)>,
+ OpBuilder<(ins "mlir::Value":$team)>];
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ ( `coarray` `(` $coarray^ `:` type($coarray) `)` )?
+ ( `team` `(` $team^ `:` type($team) `)` )?
+ ( `dim` `(` $dim^ `:` type($dim) `)` )?
+ attr-dict `->` type($res)
+ }];
+}
+
+//===----------------------------------------------------------------------===//
+// Synchronization
+//===----------------------------------------------------------------------===//
+
+def mif_SyncAllOp : mif_Op<"sync_all", [AttrSizedOperandSegments,
+ MemoryEffects<[MemWrite]>]> {
+ let summary =
+ "Performs a collective synchronization of all images in the current team";
+
+ let arguments = (ins Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+ Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+ let assemblyFormat = [{
+ (`stat` `(` $stat^ `:` type($stat) `)` )?
+ (`errmsg` `(` $errmsg^ `:` type($errmsg) `)` )?
+ attr-dict
+ }];
+}
+
+def mif_SyncImagesOp : mif_Op<"sync_images", [AttrSizedOperandSegments,
+ MemoryEffects<[MemWrite]>]> {
+ let summary = "Performs a synchronization of image with each of the other "
+ "images in the `image_set`";
+ let description = [{
+ This operation can take an optional argument `image_set`, wich must be an integer expression
+ and must be scalar or rank one. If `image_set` is omitted from the call, this operation will
+ adopt the behavior of the Fortran statement `SYNC IMAGES(*)`.
+ }];
+
+ let arguments = (ins Optional<AnyRefOrBoxType>:$image_set,
+ Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+ Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ (`image_set` `(` $image_set^ `:` type($image_set) `)` )?
+ (`stat` `(` $stat^ `:` type($stat) `)` )?
+ (`errmsg` `(` $errmsg^ `:` type($errmsg) `)` )?
+ attr-dict
+ }];
+}
+
+def mif_SyncMemoryOp : mif_Op<"sync_memory", [AttrSizedOperandSegments,
+ MemoryEffects<[MemWrite]>]> {
+ let summary = "Operation that ends one segment and begins another.";
+ let description = [{
+ Operation that ends one segment and begins another; Those two segments can
+ be ordered by user-defined way with respect to segments on other images.
+ }];
+
+ let arguments = (ins Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+ Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+ let assemblyFormat = [{
+ (`stat` `(` $stat^ `:` type($stat) `)` )?
+ (`errmsg` `(` $errmsg^ `:` type($errmsg) `)` )?
+ attr-dict
+ }];
+}
+
+//===----------------------------------------------------------------------===//
+// Collective Operations
+//===----------------------------------------------------------------------===//
+
+def mif_CoBroadcastOp : mif_Op<"co_broadcast", [AttrSizedOperandSegments,
+ MemoryEffects<[MemWrite]>]> {
+ let summary = "Broadcast value to images.";
+ let description = [{
+ The co_broadcast operation performs the computation of the sum
+ across images.
+ }];
+
+ let arguments = (ins fir_BoxType:$a,
+ AnyIntegerType:$source_image,
+ Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+ Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+
+ let assemblyFormat = [{
+ $a `:` qualified(type($a))
+ `source` `(` $source_image `:` type($source_image) `)`
+ (`stat` `(` $stat^ `:` type($stat) `)` )?
+ (`errmsg` `(` $errmsg^ `:` type($errmsg) `)` )?
+ attr-dict
+ }];
+}
+
+def mif_CoMaxOp
+ : mif_Op<"co_max", [AttrSizedOperandSegments, MemoryEffects<[MemWrite]>]> {
+ let summary = "Compute maximum value across images.";
+ let description = [{
+ The co_max operation performs the computation of the maximum
+ across images.
+ }];
+
+ let arguments = (ins fir_BoxType:$a,
+ Optional<AnyIntegerType>:$result_image,
+ Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+ Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ $a `:` qualified(type($a))
+ (`result` `(` $result_image^ `:` type($result_image) `)` )?
+ (`stat` `(` $stat^ `:` type($stat) `)` )?
+ (`errmsg` `(` $errmsg^ `:` type($errmsg) `)` )?
+ attr-dict
+ }];
+}
+
+def mif_CoMinOp
+ : mif_Op<"co_min", [AttrSizedOperandSegments, MemoryEffects<[MemWrite]>]> {
+ let summary = "Compute minimum value across images.";
+ let description = [{
+ The co_min operation performs the computation of the minimum
+ across images.
+ }];
+
+ let arguments = (ins fir_BoxType:$a,
+ Optional<AnyIntegerType>:$result_image,
+ Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+ Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ $a `:` qualified(type($a))
+ (`result` `(` $result_image^ `:` type($result_image) `)` )?
+ (`stat` `(` $stat^ `:` type($stat) `)` )?
+ (`errmsg` `(` $errmsg^ `:` type($errmsg) `)` )?
+ attr-dict
+ }];
+}
+
+def mif_CoSumOp
+ : mif_Op<"co_sum", [AttrSizedOperandSegments, MemoryEffects<[MemWrite]>]> {
+ let summary = "Compute sum across images.";
+ let description = [{
+ The co_sum operation performs the computation of the sum
+ across images.
+ }];
+
+ let arguments = (ins fir_BoxType:$a,
+ Optional<AnyIntegerType>:$result_image,
+ Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+ Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ $a `:` qualified(type($a))
+ (`result` `(` $result_image^ `:` type($result_image) `)` )?
+ (`stat` `(` $stat^ `:` type($stat) `)` )?
+ (`errmsg` `(` $errmsg^ `:` type($errmsg) `)` )?
+ attr-dict
+ }];
+}
+
+#endif // FORTRAN_DIALECT_MIF_MIF_OPS
diff --git a/flang/include/flang/Optimizer/Support/InitFIR.h b/flang/include/flang/Optimizer/Support/InitFIR.h
index 3e42ffd41591e..67e9287ddad4f 100644
--- a/flang/include/flang/Optimizer/Support/InitFIR.h
+++ b/flang/include/flang/Optimizer/Support/InitFIR.h
@@ -16,6 +16,7 @@
#include "flang/Optimizer/Dialect/CUF/CUFDialect.h"
#include "flang/Optimizer/Dialect/CUF/CUFToLLVMIRTranslation.h"
#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/MIF/MIFDialect.h"
#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
#include "flang/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.h"
#include "flang/Optimizer/OpenMP/Support/RegisterOpenMPExtensions.h"
@@ -51,7 +52,7 @@ namespace fir::support {
mlir::vector::VectorDialect, mlir::math::MathDialect, \
mlir::complex::ComplexDialect, mlir::DLTIDialect, cuf::CUFDialect, \
mlir::NVVM::NVVMDialect, mlir::gpu::GPUDialect, \
- mlir::index::IndexDialect
+ mlir::index::IndexDialect, mif::MIFDialect
#define FLANG_CODEGEN_DIALECT_LIST FIRCodeGenDialect, mlir::LLVM::LLVMDialect
diff --git a/flang/lib/Frontend/CMakeLists.txt b/flang/lib/Frontend/CMakeLists.txt
index fa0d5ecfdb9bd..2b3bc0e9c2269 100644
--- a/flang/lib/Frontend/CMakeLists.txt
+++ b/flang/lib/Frontend/CMakeLists.txt
@@ -19,6 +19,7 @@ add_flang_library(flangFrontend
FIROptCodeGenPassIncGen
FIROptTransformsPassIncGen
HLFIRDialect
+ MIFDialect
LINK_LIBS
CUFDialect
@@ -41,6 +42,7 @@ add_flang_library(flangFrontend
FIROpenACCSupport
FIROpenMPSupport
FlangOpenMPTransforms
+ MIFDialect
LINK_COMPONENTS
Passes
diff --git a/flang/lib/Lower/CMakeLists.txt b/flang/lib/Lower/CMakeLists.txt
index eb4d57d733ddb..3d0b4e4cd82eb 100644
--- a/flang/lib/Lower/CMakeLists.txt
+++ b/flang/lib/Lower/CMakeLists.txt
@@ -45,6 +45,7 @@ add_flang_library(FortranLower
FIRDialect
FIRTransforms
HLFIRDialect
+ MIFDialect
LINK_LIBS
CUFAttrs
@@ -61,6 +62,7 @@ add_flang_library(FortranLower
FortranEvaluate
FortranSemantics
FortranUtils
+ MIFDialect
LINK_COMPONENTS
Support
diff --git a/flang/lib/Optimizer/Builder/CMakeLists.txt b/flang/lib/Optimizer/Builder/CMakeLists.txt
index 404afd185fd31..db4fa912ee57b 100644
--- a/flang/lib/Optimizer/Builder/CMakeLists.txt
+++ b/flang/lib/Optimizer/Builder/CMakeLists.txt
@@ -42,6 +42,7 @@ add_flang_library(FIRBuilder
CUFDialect
FIRDialect
HLFIRDialect
+ MIFDialect
LINK_LIBS
CUFAttrs
@@ -52,6 +53,7 @@ add_flang_library(FIRBuilder
FortranEvaluate
FortranSupport
HLFIRDialect
+ MIFDialect
MLIR_DEPS
${dialect_libs}
diff --git a/flang/lib/Optimizer/Dialect/CMakeLists.txt b/flang/lib/Optimizer/Dialect/CMakeLists.txt
index 4fd4d285341e2..65d1f2c027548 100644
--- a/flang/lib/Optimizer/Dialect/CMakeLists.txt
+++ b/flang/lib/Optimizer/Dialect/CMakeLists.txt
@@ -1,6 +1,7 @@
add_subdirectory(Support)
add_subdirectory(CUF)
add_subdirectory(FIRCG)
+add_subdirectory(MIF)
add_flang_library(FIRDialect
FIRAttr.cpp
diff --git a/flang/lib/Optimizer/Dialect/MIF/CMakeLists.txt b/flang/lib/Optimizer/Dialect/MIF/CMakeLists.txt
new file mode 100644
index 0000000000000..d52ab097ddbf4
--- /dev/null
+++ b/flang/lib/Optimizer/Dialect/MIF/CMakeLists.txt
@@ -0,0 +1,20 @@
+add_flang_library(MIFDialect
+ MIFDialect.cpp
+ MIFOps.cpp
+
+ DEPENDS
+ MLIRIR
+ MIFOpsIncGen
+
+ LINK_LIBS
+ FIRDialect
+ FIRDialectSupport
+ FIRSupport
+ MLIRIR
+ MLIRTargetLLVMIRExport
+
+ LINK_COMPONENTS
+ AsmParser
+ AsmPrinter
+ Remarks
+)
diff --git a/flang/lib/Optimizer/Dialect/MIF/MIFDialect.cpp b/flang/lib/Optimizer/Dialect/MIF/MIFDialect.cpp
new file mode 100644
index 0000000000000..edc723d319aa4
--- /dev/null
+++ b/flang/lib/Optimizer/Dialect/MIF/MIFDialect.cpp
@@ -0,0 +1,24 @@
+//===- MIFDialect.cpp - MIF dialect implementation ------------------------===//
+//
+// 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
+// C
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Dialect/MIF/MIFDialect.h"
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
+
+//===----------------------------------------------------------------------===//
+/// Tablegen Definitions
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Dialect/MIF/MIFDialect.cpp.inc"
+
+void mif::MIFDialect::initialize() {
+ addOperations<
+#define GET_OP_LIST
+#include "flang/Optimizer/Dialect/MIF/MIFOps.cpp.inc"
+ >();
+}
diff --git a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
new file mode 100644
index 0000000000000..21803a03509e3
--- /dev/null
+++ b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
@@ -0,0 +1,133 @@
+//===- MIFOps.cpp - MIF dialect ops implementation ----------------===//
+//
+// 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/Dialect/MIF/MIFOps.h"
+#include "flang/Optimizer/Dialect/FIRAttr.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Dialect/MIF/MIFDialect.h"
+#include "mlir/IR/Matchers.h"
+#include "mlir/IR/PatternMatch.h"
+#include "llvm/ADT/SmallVector.h"
+
+#define GET_OP_CLASSES
+#include "flang/Optimizer/Dialect/MIF/MIFOps.cpp.inc"
+
+//===----------------------------------------------------------------------===//
+// NumImagesOp
+//===----------------------------------------------------------------------===//
+
+void mif::NumImagesOp::build(mlir::OpBuilder &builder,
+ mlir::OperationState &result,
+ mlir::Value teamArg) {
+ bool isTeamNumber =
+ teamArg && fir::unwrapPassByRefType(teamArg.getType()).isInteger();
+ if (isTeamNumber)
+ build(builder, result, teamArg, /*team*/ mlir::Value{});
+ else
+ build(builder, result, /*team_number*/ mlir::Value{}, teamArg);
+}
+
+llvm::LogicalResult mif::NumImagesOp::verify() {
+ if (getTeam() && getTeamNumber())
+ return emitOpError(
+ "team and team_number must not be provided at the same time");
+ return mlir::success();
+}
+
+//===----------------------------------------------------------------------===//
+// ThisImageOp
+//===----------------------------------------------------------------------===//
+
+void mif::ThisImageOp::build(mlir::OpBuilder &builder,
+ mlir::OperationState &result, mlir::Value coarray,
+ mlir::Value team) {
+ build(builder, result, coarray, /*dim*/ mlir::Value{}, team);
+}
+
+void mif::ThisImageOp::build(mlir::OpBuilder &builder,
+ mlir::OperationState &result, mlir::Value team) {
+ build(builder, result, /*coarray*/ mlir::Value{}, /*dim*/ mlir::Value{},
+ team);
+}
+
+llvm::LogicalResult mif::ThisImageOp::verify() {
+ if (getDim() && !getCoarray())
+ return emitOpError(
+ "`dim` must be provied at the same time as the `coarray` argument.");
+ return mlir::success();
+}
+
+//===----------------------------------------------------------------------===//
+// SyncImagesOp
+//===----------------------------------------------------------------------===//
+
+llvm::LogicalResult mif::SyncImagesOp::verify() {
+ if (getImageSet()) {
+ mlir::Type t = getImageSet().getType();
+ fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(t);
+ if (auto seqTy =
+ mlir::dyn_cast<fir::SequenceType>(boxTy.getElementType())) {
+ if (seqTy.getDimension() != 0 && seqTy.getDimension() != 1)
+ return emitOpError(
+ "`image_set` must be a boxed integer expression of rank 1.");
+ if (!fir::isa_integer(seqTy.getElementType()))
+ return emitOpError("`image_set` must be a boxed array of integer.");
+ } else if (!fir::isa_integer(boxTy.getElementType()))
+ return emitOpError(
+ "`image_set` must be a boxed scalar integer expression.");
+ }
+ return mlir::success();
+}
+
+//===----------------------------------------------------------------------===//
+// CoMaxOp
+//===----------------------------------------------------------------------===//
+
+llvm::LogicalResult mif::CoMaxOp::verify() {
+ fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType());
+ mlir::Type elemTy = boxTy.getElementType();
+ if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(elemTy))
+ elemTy = seqTy.getElementType();
+
+ if (!fir::isa_real(elemTy) && !fir::isa_integer(elemTy) &&
+ !fir::isa_complex(elemTy) && !fir::isa_char(elemTy))
+ return emitOpError("`A` shall be of type integer, real or character.");
+ return mlir::success();
+}
+
+//===----------------------------------------------------------------------===//
+// CoMinOp
+//===----------------------------------------------------------------------===//
+
+llvm::LogicalResult mif::CoMinOp::verify() {
+ fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType());
+ mlir::Type elemTy = boxTy.getElementType();
+ if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(elemTy))
+ elemTy = seqTy.getElementType();
+
+ if (!fir::isa_real(elemTy) && !fir::isa_integer(elemTy) &&
+ !fir::isa_complex(elemTy) && !fir::isa_char(elemTy))
+ return emitOpError("`A` shall be of type integer, real or character.");
+ return mlir::success();
+}
+
+//===----------------------------------------------------------------------===//
+// CoSumOp
+//===----------------------------------------------------------------------===//
+
+llvm::LogicalResult mif::CoSumOp::verify() {
+ fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType());
+ mlir::Type elemTy = boxTy.getElementType();
+ if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(elemTy))
+ elemTy = seqTy.getElementType();
+
+ if (!fir::isa_real(elemTy) && !fir::isa_integer(elemTy) &&
+ !fir::isa_complex(elemTy))
+ return emitOpError("`A` shall be of numeric type.");
+ return mlir::success();
+}
diff --git a/flang/lib/Optimizer/Transforms/CMakeLists.txt b/flang/lib/Optimizer/Transforms/CMakeLists.txt
index 4ec16274830fe..db2623dfa99bc 100644
--- a/flang/lib/Optimizer/Transforms/CMakeLists.txt
+++ b/flang/lib/Optimizer/Transforms/CMakeLists.txt
@@ -43,6 +43,7 @@ add_flang_library(FIRTransforms
FIRDialect
FIROptTransformsPassIncGen
HLFIROpsIncGen
+ MIFDialect
LINK_LIBS
CUFAttrs
@@ -56,6 +57,7 @@ add_flang_library(FIRTransforms
FIRSupport
FortranSupport
HLFIRDialect
+ MIFDialect
MLIR_LIBS
MLIRAffineUtils
diff --git a/flang/tools/bbc/CMakeLists.txt b/flang/tools/bbc/CMakeLists.txt
index 7516157731b5e..2d0521464a747 100644
--- a/flang/tools/bbc/CMakeLists.txt
+++ b/flang/tools/bbc/CMakeLists.txt
@@ -35,6 +35,7 @@ target_link_libraries(bbc PRIVATE
FortranEvaluate
FortranSemantics
FortranLower
+ MIFDialect
)
mlir_target_link_libraries(bbc PRIVATE
diff --git a/flang/tools/fir-lsp-server/CMakeLists.txt b/flang/tools/fir-lsp-server/CMakeLists.txt
index 86cde79a66830..17ed948608c33 100644
--- a/flang/tools/fir-lsp-server/CMakeLists.txt
+++ b/flang/tools/fir-lsp-server/CMakeLists.txt
@@ -13,7 +13,8 @@ target_link_libraries(fir-lsp-server PRIVATE
FIRDialect
FIROpenACCSupport
FIROpenMPSupport
- HLFIRDialect)
+ HLFIRDialect
+ MIFDialect)
mlir_target_link_libraries(fir-lsp-server PRIVATE
MLIRLspServerLib
diff --git a/flang/tools/fir-opt/CMakeLists.txt b/flang/tools/fir-opt/CMakeLists.txt
index 4ee9752727b87..a8475a9e8e05c 100644
--- a/flang/tools/fir-opt/CMakeLists.txt
+++ b/flang/tools/fir-opt/CMakeLists.txt
@@ -25,6 +25,7 @@ target_link_libraries(fir-opt PRIVATE
FIROpenMPSupport
FlangOpenMPTransforms
FIRAnalysis
+ MIFDialect
${test_libs}
)
diff --git a/flang/tools/tco/CMakeLists.txt b/flang/tools/tco/CMakeLists.txt
index ab2aab2cf99a6..5ab8952898a6c 100644
--- a/flang/tools/tco/CMakeLists.txt
+++ b/flang/tools/tco/CMakeLists.txt
@@ -23,6 +23,7 @@ target_link_libraries(tco PRIVATE
FIROpenMPSupport
FlangOpenMPTransforms
FortranSupport
+ MIFDialect
)
mlir_target_link_libraries(tco PRIVATE
diff --git a/flang/unittests/Optimizer/CMakeLists.txt b/flang/unittests/Optimizer/CMakeLists.txt
index a84d54d96102a..3a04008b9b795 100644
--- a/flang/unittests/Optimizer/CMakeLists.txt
+++ b/flang/unittests/Optimizer/CMakeLists.txt
@@ -13,6 +13,7 @@ set(LIBS
FIRDialectSupport
FIRSupport
HLFIRDialect
+ MIFDialect
)
add_flang_unittest(FlangOptimizerTests
@@ -42,7 +43,8 @@ DEPENDS
CUFDialect
FIRDialect
FIRSupport
- HLFIRDialect)
+ HLFIRDialect
+ MIFDialect)
if(NOT FLANG_STANDALONE_BUILD)
add_dependencies(FlangOptimizerTests
>From 561f2c90a99747239ed997a44e6668b6cbdf7952 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Mon, 29 Sep 2025 13:33:00 +0200
Subject: [PATCH 2/2] [flang][Multi-Image] Moving Mutli-image lowering to PRIF
into the MIF Dialect
---
.../flang/Optimizer/Builder/Runtime/Coarray.h | 85 ---
.../Optimizer/Transforms/MIFOpConversion.h | 41 ++
.../flang/Optimizer/Transforms/Passes.td | 5 +
flang/lib/Lower/Runtime.cpp | 27 +-
flang/lib/Optimizer/Builder/CMakeLists.txt | 1 -
flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 99 +---
.../lib/Optimizer/Builder/Runtime/Coarray.cpp | 228 --------
flang/lib/Optimizer/Builder/Runtime/Main.cpp | 4 +-
flang/lib/Optimizer/Passes/Pipelines.cpp | 1 +
flang/lib/Optimizer/Transforms/CMakeLists.txt | 1 +
.../Optimizer/Transforms/MIFOpConversion.cpp | 487 ++++++++++++++++++
.../test/Driver/mlir-debug-pass-pipeline.f90 | 1 +
flang/test/Driver/mlir-pass-pipeline.f90 | 1 +
flang/test/Fir/MIF/co_broadcast.mlir | 148 ++++++
flang/test/Fir/MIF/co_max.mlir | 174 +++++++
flang/test/Fir/MIF/co_min.mlir | 174 +++++++
flang/test/Fir/MIF/co_sum.mlir | 152 ++++++
flang/test/Fir/MIF/init.mlir | 24 +
flang/test/Fir/MIF/num_images.mlir | 33 ++
flang/test/Fir/MIF/sync_all.mlir | 56 ++
flang/test/Fir/MIF/sync_images.mlir | 97 ++++
flang/test/Fir/MIF/sync_memory.mlir | 56 ++
flang/test/Fir/MIF/this_image.mlir | 27 +
flang/test/Fir/basic-program.fir | 1 +
flang/test/Lower/Coarray/co_broadcast.f90 | 92 ----
flang/test/Lower/Coarray/co_max.f90 | 112 ----
flang/test/Lower/Coarray/co_min.f90 | 112 ----
flang/test/Lower/Coarray/co_sum.f90 | 122 -----
flang/test/Lower/Coarray/sync_all.f90 | 37 --
flang/test/Lower/Coarray/sync_images.f90 | 62 ---
flang/test/Lower/Coarray/sync_memory.f90 | 37 --
flang/test/Lower/MIF/co_broadcast.f90 | 57 ++
flang/test/Lower/MIF/co_max.f90 | 60 +++
flang/test/Lower/MIF/co_min.f90 | 60 +++
flang/test/Lower/MIF/co_sum.f90 | 51 ++
.../Lower/{Coarray => MIF}/coarray-init.f90 | 4 +-
.../Lower/{Coarray => MIF}/num_images.f90 | 6 +-
flang/test/Lower/MIF/sync_all.f90 | 27 +
flang/test/Lower/MIF/sync_images.f90 | 39 ++
flang/test/Lower/MIF/sync_memory.f90 | 27 +
.../Lower/{Coarray => MIF}/this_image.f90 | 4 +-
41 files changed, 1842 insertions(+), 990 deletions(-)
delete mode 100644 flang/include/flang/Optimizer/Builder/Runtime/Coarray.h
create mode 100644 flang/include/flang/Optimizer/Transforms/MIFOpConversion.h
delete mode 100644 flang/lib/Optimizer/Builder/Runtime/Coarray.cpp
create mode 100644 flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
create mode 100644 flang/test/Fir/MIF/co_broadcast.mlir
create mode 100644 flang/test/Fir/MIF/co_max.mlir
create mode 100644 flang/test/Fir/MIF/co_min.mlir
create mode 100644 flang/test/Fir/MIF/co_sum.mlir
create mode 100644 flang/test/Fir/MIF/init.mlir
create mode 100644 flang/test/Fir/MIF/num_images.mlir
create mode 100644 flang/test/Fir/MIF/sync_all.mlir
create mode 100644 flang/test/Fir/MIF/sync_images.mlir
create mode 100644 flang/test/Fir/MIF/sync_memory.mlir
create mode 100644 flang/test/Fir/MIF/this_image.mlir
delete mode 100644 flang/test/Lower/Coarray/co_broadcast.f90
delete mode 100644 flang/test/Lower/Coarray/co_max.f90
delete mode 100644 flang/test/Lower/Coarray/co_min.f90
delete mode 100644 flang/test/Lower/Coarray/co_sum.f90
delete mode 100644 flang/test/Lower/Coarray/sync_all.f90
delete mode 100644 flang/test/Lower/Coarray/sync_images.f90
delete mode 100644 flang/test/Lower/Coarray/sync_memory.f90
create mode 100644 flang/test/Lower/MIF/co_broadcast.f90
create mode 100644 flang/test/Lower/MIF/co_max.f90
create mode 100644 flang/test/Lower/MIF/co_min.f90
create mode 100644 flang/test/Lower/MIF/co_sum.f90
rename flang/test/Lower/{Coarray => MIF}/coarray-init.f90 (57%)
rename flang/test/Lower/{Coarray => MIF}/num_images.f90 (61%)
create mode 100644 flang/test/Lower/MIF/sync_all.f90
create mode 100644 flang/test/Lower/MIF/sync_images.f90
create mode 100644 flang/test/Lower/MIF/sync_memory.f90
rename flang/test/Lower/{Coarray => MIF}/this_image.f90 (64%)
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h b/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h
deleted file mode 100644
index 20bfb7c124af2..0000000000000
--- a/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h
+++ /dev/null
@@ -1,85 +0,0 @@
-//===-- Coarray.h -- generate Coarray intrinsics runtime calls --*- C++ -*-===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COARRAY_H
-#define FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COARRAY_H
-
-#include "flang/Lower/AbstractConverter.h"
-#include "flang/Optimizer/Support/InternalNames.h"
-#include "mlir/Dialect/Func/IR/FuncOps.h"
-
-namespace fir {
-class ExtendedValue;
-class FirOpBuilder;
-} // namespace fir
-
-namespace fir::runtime {
-
-// Get the function type for a prif subroutine with a variable number of
-// arguments
-#define PRIF_FUNCTYPE(...) \
- mlir::FunctionType::get(builder.getContext(), /*inputs*/ {__VA_ARGS__}, \
- /*result*/ {})
-
-// Default prefix for subroutines of PRIF compiled with LLVM
-#define PRIFNAME_SUB(fmt) \
- []() { \
- std::ostringstream oss; \
- oss << "prif_" << fmt; \
- return fir::NameUniquer::doProcedure({"prif"}, {}, oss.str()); \
- }()
-
-#define PRIF_STAT_TYPE builder.getRefType(builder.getI32Type())
-#define PRIF_ERRMSG_TYPE \
- fir::BoxType::get(fir::CharacterType::get(builder.getContext(), 1, \
- fir::CharacterType::unknownLen()))
-
-/// Generate Call to runtime prif_init
-mlir::Value genInitCoarray(fir::FirOpBuilder &builder, mlir::Location loc);
-
-/// Generate Call to runtime prif_num_images
-mlir::Value getNumImages(fir::FirOpBuilder &builder, mlir::Location loc);
-
-/// Generate Call to runtime prif_num_images_with_team or
-/// prif_num_images_with_team_number
-mlir::Value getNumImagesWithTeam(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value team);
-
-/// Generate Call to runtime prif_this_image_no_coarray
-mlir::Value getThisImage(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value team = {});
-
-/// Generate call to runtime subroutine prif_co_broadcast
-void genCoBroadcast(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value A, mlir::Value sourceImage, mlir::Value stat,
- mlir::Value errmsg);
-
-/// Generate call to runtime subroutine prif_co_max and prif_co_max_character
-void genCoMax(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value A,
- mlir::Value resultImage, mlir::Value stat, mlir::Value errmsg);
-
-/// Generate call to runtime subroutine prif_co_min or prif_co_min_character
-void genCoMin(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value A,
- mlir::Value resultImage, mlir::Value stat, mlir::Value errmsg);
-
-/// Generate call to runtime subroutine prif_co_sum
-void genCoSum(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value A,
- mlir::Value resultImage, mlir::Value stat, mlir::Value errmsg);
-
-/// Generate call to runtime subroutine prif_sync_all
-void genSyncAllStatement(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value stat, mlir::Value errmsg);
-/// Generate call to runtime subroutine prif_sync_memory
-void genSyncMemoryStatement(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value stat, mlir::Value errmsg);
-/// Generate call to runtime subroutine prif_sync_images
-void genSyncImagesStatement(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value imageSet, mlir::Value stat,
- mlir::Value errmsg);
-} // namespace fir::runtime
-#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COARRAY_H
diff --git a/flang/include/flang/Optimizer/Transforms/MIFOpConversion.h b/flang/include/flang/Optimizer/Transforms/MIFOpConversion.h
new file mode 100644
index 0000000000000..45148dab1cfb0
--- /dev/null
+++ b/flang/include/flang/Optimizer/Transforms/MIFOpConversion.h
@@ -0,0 +1,41 @@
+//===------- Optimizer/Transforms/MIFOpToLLVMConversion.h -------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_OPTIMIZER_TRANSFORMS_MIFOPCONVERSION_H_
+#define FORTRAN_OPTIMIZER_TRANSFORMS_MIFOPCONVERSION_H_
+
+#include "flang/Optimizer/Support/InternalNames.h"
+#include "mlir/Conversion/LLVMCommon/Pattern.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Pass/PassRegistry.h"
+
+namespace fir {
+class LLVMTypeConverter;
+}
+
+namespace mif {
+
+// Default prefix for subroutines of PRIF compiled with LLVM
+#define PRIFNAME_SUB(fmt) \
+ []() { \
+ std::ostringstream oss; \
+ oss << "prif_" << fmt; \
+ return fir::NameUniquer::doProcedure({"prif"}, {}, oss.str()); \
+ }()
+
+#define PRIF_STAT_TYPE builder.getRefType(builder.getI32Type())
+#define PRIF_ERRMSG_TYPE \
+ fir::BoxType::get(fir::CharacterType::get(builder.getContext(), 1, \
+ fir::CharacterType::unknownLen()))
+
+/// Patterns that convert MIF operations to runtime calls.
+void populateMIFOpConversionPatterns(fir::LLVMTypeConverter &converter,
+ mlir::RewritePatternSet &patterns);
+} // namespace mif
+
+#endif // FORTRAN_OPTIMIZER_TRANSFORMS_MIFOPCONVERSION_H_
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td
index 88573fa9dff7d..ee530eb0227a4 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -576,4 +576,9 @@ def OptimizeArrayRepacking
}];
}
+def MIFOpConversion : Pass<"mif-convert", "mlir::ModuleOp"> {
+ let summary = "Convert some MIF operations to runtime calls";
+ let dependentDialects = ["fir::FIROpsDialect", "mlir::LLVM::LLVMDialect"];
+}
+
#endif // FLANG_OPTIMIZER_TRANSFORMS_PASSES
diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp
index b19ca0182b4b5..cb555249125f6 100644
--- a/flang/lib/Lower/Runtime.cpp
+++ b/flang/lib/Lower/Runtime.cpp
@@ -12,10 +12,10 @@
#include "flang/Lower/OpenMP.h"
#include "flang/Lower/StatementContext.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
-#include "flang/Optimizer/Builder/Runtime/Coarray.h"
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Runtime/misc-intrinsic.h"
#include "flang/Runtime/pointer.h"
@@ -52,7 +52,6 @@ static void genUnreachable(fir::FirOpBuilder &builder, mlir::Location loc) {
static std::pair<mlir::Value, mlir::Value> getStatAndErrmsg(
Fortran::lower::AbstractConverter &converter, mlir::Location loc,
const std::list<Fortran::parser::StatOrErrmsg> &statOrErrList) {
- fir::FirOpBuilder &builder = converter.getFirOpBuilder();
Fortran::lower::StatementContext stmtCtx;
mlir::Value errMsgExpr, statExpr;
@@ -71,16 +70,6 @@ static std::pair<mlir::Value, mlir::Value> getStatAndErrmsg(
statOrErr.u);
}
- if (!statExpr) {
- statExpr = fir::AbsentOp::create(builder, loc,
- builder.getRefType(builder.getI32Type()));
- }
- if (!errMsgExpr) {
- errMsgExpr = fir::AbsentOp::create(
- builder, loc,
- fir::BoxType::get(fir::CharacterType::get(
- builder.getContext(), 1, fir::CharacterType::unknownLen())));
- }
return {statExpr, errMsgExpr};
}
@@ -215,7 +204,7 @@ void Fortran::lower::genSyncAllStatement(
auto [statAddr, errMsgAddr] = getStatAndErrmsg(converter, loc, statOrErrList);
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
- fir::runtime::genSyncAllStatement(builder, loc, statAddr, errMsgAddr);
+ mif::SyncAllOp::create(builder, loc, statAddr, errMsgAddr);
}
void Fortran::lower::genSyncImagesStatement(
@@ -244,16 +233,12 @@ void Fortran::lower::genSyncImagesStatement(
fir::getBase(converter.genExprBox(loc, *expr, stmtCtx));
},
[&](const Fortran::parser::Star &) {
- imageSet = fir::AbsentOp::create(
- builder, loc,
- fir::BoxType::get(fir::SequenceType::get(
- {fir::SequenceType::getUnknownExtent()},
- builder.getI32Type())));
+ // Image set is not set.
+ imageSet = mlir::Value{};
}},
imgSet.u);
- fir::runtime::genSyncImagesStatement(builder, loc, imageSet, statAddr,
- errMsgAddr);
+ mif::SyncImagesOp::create(builder, loc, imageSet, statAddr, errMsgAddr);
}
void Fortran::lower::genSyncMemoryStatement(
@@ -267,7 +252,7 @@ void Fortran::lower::genSyncMemoryStatement(
auto [statAddr, errMsgAddr] = getStatAndErrmsg(converter, loc, statOrErrList);
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
- fir::runtime::genSyncMemoryStatement(builder, loc, statAddr, errMsgAddr);
+ mif::SyncMemoryOp::create(builder, loc, statAddr, errMsgAddr);
}
void Fortran::lower::genSyncTeamStatement(
diff --git a/flang/lib/Optimizer/Builder/CMakeLists.txt b/flang/lib/Optimizer/Builder/CMakeLists.txt
index db4fa912ee57b..1f95259a857da 100644
--- a/flang/lib/Optimizer/Builder/CMakeLists.txt
+++ b/flang/lib/Optimizer/Builder/CMakeLists.txt
@@ -16,7 +16,6 @@ add_flang_library(FIRBuilder
Runtime/Allocatable.cpp
Runtime/ArrayConstructor.cpp
Runtime/Assign.cpp
- Runtime/Coarray.cpp
Runtime/Character.cpp
Runtime/Command.cpp
Runtime/CUDA/Descriptor.cpp
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 71d35e37bbe94..1921a26484e4a 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -25,7 +25,6 @@
#include "flang/Optimizer/Builder/Runtime/Allocatable.h"
#include "flang/Optimizer/Builder/Runtime/CUDA/Descriptor.h"
#include "flang/Optimizer/Builder/Runtime/Character.h"
-#include "flang/Optimizer/Builder/Runtime/Coarray.h"
#include "flang/Optimizer/Builder/Runtime/Command.h"
#include "flang/Optimizer/Builder/Runtime/Derived.h"
#include "flang/Optimizer/Builder/Runtime/Exceptions.h"
@@ -40,6 +39,7 @@
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "flang/Optimizer/Support/FatalError.h"
@@ -400,28 +400,28 @@ static constexpr IntrinsicHandler handlers[]{
{"co_broadcast",
&I::genCoBroadcast,
{{{"a", asBox},
- {"source_image", asAddr},
+ {"source_image", asValue},
{"stat", asAddr, handleDynamicOptional},
{"errmsg", asBox, handleDynamicOptional}}},
/*isElemental*/ false},
{"co_max",
&I::genCoMax,
{{{"a", asBox},
- {"result_image", asAddr, handleDynamicOptional},
+ {"result_image", asValue, handleDynamicOptional},
{"stat", asAddr, handleDynamicOptional},
{"errmsg", asBox, handleDynamicOptional}}},
/*isElemental*/ false},
{"co_min",
&I::genCoMin,
{{{"a", asBox},
- {"result_image", asAddr, handleDynamicOptional},
+ {"result_image", asValue, handleDynamicOptional},
{"stat", asAddr, handleDynamicOptional},
{"errmsg", asBox, handleDynamicOptional}}},
/*isElemental*/ false},
{"co_sum",
&I::genCoSum,
{{{"a", asBox},
- {"result_image", asAddr, handleDynamicOptional},
+ {"result_image", asValue, handleDynamicOptional},
{"stat", asAddr, handleDynamicOptional},
{"errmsg", asBox, handleDynamicOptional}}},
/*isElemental*/ false},
@@ -813,7 +813,7 @@ static constexpr IntrinsicHandler handlers[]{
{"null", &I::genNull, {{{"mold", asInquired}}}, /*isElemental=*/false},
{"num_images",
&I::genNumImages,
- {{{"team", asAddr}, {"team_number", asAddr}}},
+ {{{"team_number", asValue}, {"team", asBox}}},
/*isElemental*/ false},
{"pack",
&I::genPack,
@@ -3702,79 +3702,40 @@ mlir::Value IntrinsicLibrary::genCmplx(mlir::Type resultType,
void IntrinsicLibrary::genCoBroadcast(llvm::ArrayRef<fir::ExtendedValue> args) {
converter->checkCoarrayEnabled();
assert(args.size() == 4);
- mlir::Value sourceImage = fir::getBase(args[1]);
- mlir::Value status =
- isStaticallyAbsent(args[2])
- ? fir::AbsentOp::create(builder, loc,
- builder.getRefType(builder.getI32Type()))
- .getResult()
- : fir::getBase(args[2]);
- mlir::Value errmsg =
- isStaticallyAbsent(args[3])
- ? fir::AbsentOp::create(builder, loc, PRIF_ERRMSG_TYPE).getResult()
- : fir::getBase(args[3]);
- fir::runtime::genCoBroadcast(builder, loc, fir::getBase(args[0]), sourceImage,
- status, errmsg);
+ mif::CoBroadcastOp::create(builder, loc, fir::getBase(args[0]),
+ /*sourceImage*/ fir::getBase(args[1]),
+ /*status*/ fir::getBase(args[2]),
+ /*errmsg*/ fir::getBase(args[3]));
}
// CO_MAX
void IntrinsicLibrary::genCoMax(llvm::ArrayRef<fir::ExtendedValue> args) {
converter->checkCoarrayEnabled();
assert(args.size() == 4);
- mlir::Value refNone =
- fir::AbsentOp::create(builder, loc,
- builder.getRefType(builder.getI32Type()))
- .getResult();
- mlir::Value resultImage =
- isStaticallyAbsent(args[1]) ? refNone : fir::getBase(args[1]);
- mlir::Value status =
- isStaticallyAbsent(args[2]) ? refNone : fir::getBase(args[2]);
- mlir::Value errmsg =
- isStaticallyAbsent(args[3])
- ? fir::AbsentOp::create(builder, loc, PRIF_ERRMSG_TYPE).getResult()
- : fir::getBase(args[3]);
- fir::runtime::genCoMax(builder, loc, fir::getBase(args[0]), resultImage,
- status, errmsg);
+ mif::CoMaxOp::create(builder, loc, fir::getBase(args[0]),
+ /*resultImage*/ fir::getBase(args[1]),
+ /*status*/ fir::getBase(args[2]),
+ /*errmsg*/ fir::getBase(args[3]));
}
// CO_MIN
void IntrinsicLibrary::genCoMin(llvm::ArrayRef<fir::ExtendedValue> args) {
converter->checkCoarrayEnabled();
assert(args.size() == 4);
- mlir::Value refNone =
- fir::AbsentOp::create(builder, loc,
- builder.getRefType(builder.getI32Type()))
- .getResult();
- mlir::Value resultImage =
- isStaticallyAbsent(args[1]) ? refNone : fir::getBase(args[1]);
- mlir::Value status =
- isStaticallyAbsent(args[2]) ? refNone : fir::getBase(args[2]);
- mlir::Value errmsg =
- isStaticallyAbsent(args[3])
- ? fir::AbsentOp::create(builder, loc, PRIF_ERRMSG_TYPE).getResult()
- : fir::getBase(args[3]);
- fir::runtime::genCoMin(builder, loc, fir::getBase(args[0]), resultImage,
- status, errmsg);
+ mif::CoMinOp::create(builder, loc, fir::getBase(args[0]),
+ /*resultImage*/ fir::getBase(args[1]),
+ /*status*/ fir::getBase(args[2]),
+ /*errmsg*/ fir::getBase(args[3]));
}
// CO_SUM
void IntrinsicLibrary::genCoSum(llvm::ArrayRef<fir::ExtendedValue> args) {
converter->checkCoarrayEnabled();
assert(args.size() == 4);
- mlir::Value absentInt =
- fir::AbsentOp::create(builder, loc,
- builder.getRefType(builder.getI32Type()))
- .getResult();
- mlir::Value resultImage =
- isStaticallyAbsent(args[1]) ? absentInt : fir::getBase(args[1]);
- mlir::Value status =
- isStaticallyAbsent(args[2]) ? absentInt : fir::getBase(args[2]);
- mlir::Value errmsg =
- isStaticallyAbsent(args[3])
- ? fir::AbsentOp::create(builder, loc, PRIF_ERRMSG_TYPE).getResult()
- : fir::getBase(args[3]);
- fir::runtime::genCoSum(builder, loc, fir::getBase(args[0]), resultImage,
- status, errmsg);
+ mif::CoSumOp::create(builder, loc, fir::getBase(args[0]),
+ /*resultImage*/ fir::getBase(args[1]),
+ /*status*/ fir::getBase(args[2]),
+ /*errmsg*/ fir::getBase(args[3]));
}
// COMMAND_ARGUMENT_COUNT
@@ -7443,9 +7404,9 @@ IntrinsicLibrary::genNumImages(mlir::Type resultType,
assert(args.size() == 0 || args.size() == 1);
if (args.size())
- return fir::runtime::getNumImagesWithTeam(builder, loc,
- fir::getBase(args[0]));
- return fir::runtime::getNumImages(builder, loc);
+ return mif::NumImagesOp::create(builder, loc, fir::getBase(args[0]))
+ .getResult();
+ return mif::NumImagesOp::create(builder, loc).getResult();
}
// CLOCK, CLOCK64, GLOBALTIMER
@@ -8523,17 +8484,11 @@ IntrinsicLibrary::genThisImage(mlir::Type resultType,
converter->checkCoarrayEnabled();
assert(args.size() >= 1 && args.size() <= 3);
const bool coarrayIsAbsent = args.size() == 1;
- mlir::Value team =
- !isStaticallyAbsent(args, args.size() - 1)
- ? fir::getBase(args[args.size() - 1])
- : builder
- .create<fir::AbsentOp>(loc,
- fir::BoxType::get(builder.getNoneType()))
- .getResult();
+ mlir::Value team = fir::getBase(args[args.size() - 1]);
if (!coarrayIsAbsent)
TODO(loc, "this_image with coarray argument.");
- mlir::Value res = fir::runtime::getThisImage(builder, loc, team);
+ mlir::Value res = mif::ThisImageOp::create(builder, loc, team);
return builder.createConvert(loc, resultType, res);
}
diff --git a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp
deleted file mode 100644
index 364e7b753c6ee..0000000000000
--- a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-//===-- Coarray.cpp -- runtime API for coarray intrinsics -----------------===//
-//
-// 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/Runtime/Coarray.h"
-#include "flang/Optimizer/Builder/FIRBuilder.h"
-#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
-#include "mlir/Dialect/Func/IR/FuncOps.h"
-
-using namespace Fortran::runtime;
-using namespace Fortran::semantics;
-
-// Most PRIF functions take `errmsg` and `errmsg_alloc` as two optional
-// arguments of intent (out). One is allocatable, the other is not.
-// It is the responsibility of the compiler to ensure that the appropriate
-// optional argument is passed, and at most one must be provided in a given
-// call.
-// Depending on the type of `errmsg`, this function will return the pair
-// corresponding to (`errmsg`, `errmsg_alloc`).
-static std::pair<mlir::Value, mlir::Value>
-genErrmsgPRIF(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value errmsg) {
- bool isAllocatableErrmsg = fir::isAllocatableType(errmsg.getType());
-
- mlir::Value absent = fir::AbsentOp::create(builder, loc, PRIF_ERRMSG_TYPE);
- mlir::Value errMsg = isAllocatableErrmsg ? absent : errmsg;
- mlir::Value errMsgAlloc = isAllocatableErrmsg ? errmsg : absent;
- return {errMsg, errMsgAlloc};
-}
-
-/// Generate Call to runtime prif_init
-mlir::Value fir::runtime::genInitCoarray(fir::FirOpBuilder &builder,
- mlir::Location loc) {
- mlir::Type i32Ty = builder.getI32Type();
- mlir::Value result = builder.createTemporary(loc, i32Ty);
- mlir::FunctionType ftype = PRIF_FUNCTYPE(builder.getRefType(i32Ty));
- mlir::func::FuncOp funcOp =
- builder.createFunction(loc, PRIFNAME_SUB("init"), ftype);
- llvm::SmallVector<mlir::Value> args =
- fir::runtime::createArguments(builder, loc, ftype, result);
- fir::CallOp::create(builder, loc, funcOp, args);
- return fir::LoadOp::create(builder, loc, result);
-}
-
-/// Generate Call to runtime prif_num_images
-mlir::Value fir::runtime::getNumImages(fir::FirOpBuilder &builder,
- mlir::Location loc) {
- mlir::Value result = builder.createTemporary(loc, builder.getI32Type());
- mlir::FunctionType ftype =
- PRIF_FUNCTYPE(builder.getRefType(builder.getI32Type()));
- mlir::func::FuncOp funcOp =
- builder.createFunction(loc, PRIFNAME_SUB("num_images"), ftype);
- llvm::SmallVector<mlir::Value> args =
- fir::runtime::createArguments(builder, loc, ftype, result);
- fir::CallOp::create(builder, loc, funcOp, args);
- return fir::LoadOp::create(builder, loc, result);
-}
-
-/// Generate Call to runtime prif_num_images_with_{team|team_number}
-mlir::Value fir::runtime::getNumImagesWithTeam(fir::FirOpBuilder &builder,
- mlir::Location loc,
- mlir::Value team) {
- bool isTeamNumber = fir::unwrapPassByRefType(team.getType()).isInteger();
- std::string numImagesName = isTeamNumber
- ? PRIFNAME_SUB("num_images_with_team_number")
- : PRIFNAME_SUB("num_images_with_team");
-
- mlir::Value result = builder.createTemporary(loc, builder.getI32Type());
- mlir::Type refTy = builder.getRefType(builder.getI32Type());
- mlir::FunctionType ftype =
- isTeamNumber
- ? PRIF_FUNCTYPE(builder.getRefType(builder.getI64Type()), refTy)
- : PRIF_FUNCTYPE(fir::BoxType::get(builder.getNoneType()), refTy);
- mlir::func::FuncOp funcOp = builder.createFunction(loc, numImagesName, ftype);
-
- if (!isTeamNumber)
- team = builder.createBox(loc, team);
- llvm::SmallVector<mlir::Value> args =
- fir::runtime::createArguments(builder, loc, ftype, team, result);
- fir::CallOp::create(builder, loc, funcOp, args);
- return fir::LoadOp::create(builder, loc, result);
-}
-
-/// Generate Call to runtime prif_this_image_no_coarray
-mlir::Value fir::runtime::getThisImage(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Value team) {
- mlir::Type refTy = builder.getRefType(builder.getI32Type());
- mlir::Type boxTy = fir::BoxType::get(builder.getNoneType());
- mlir::FunctionType ftype = PRIF_FUNCTYPE(boxTy, refTy);
- mlir::func::FuncOp funcOp =
- builder.createFunction(loc, PRIFNAME_SUB("this_image_no_coarray"), ftype);
-
- mlir::Value result = builder.createTemporary(loc, builder.getI32Type());
- mlir::Value teamArg =
- !team ? fir::AbsentOp::create(builder, loc, boxTy) : team;
- llvm::SmallVector<mlir::Value> args =
- fir::runtime::createArguments(builder, loc, ftype, teamArg, result);
- fir::CallOp::create(builder, loc, funcOp, args);
- return fir::LoadOp::create(builder, loc, result);
-}
-
-/// Generate call to collective subroutines except co_reduce
-/// A must be lowered as a box
-void genCollectiveSubroutine(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value A, mlir::Value rootImage,
- mlir::Value stat, mlir::Value errmsg,
- std::string coName) {
- mlir::Type boxTy = fir::BoxType::get(builder.getNoneType());
- mlir::FunctionType ftype =
- PRIF_FUNCTYPE(boxTy, builder.getRefType(builder.getI32Type()),
- PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE);
- mlir::func::FuncOp funcOp = builder.createFunction(loc, coName, ftype);
-
- auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg);
- llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
- builder, loc, ftype, A, rootImage, stat, errmsgArg, errmsgAllocArg);
- fir::CallOp::create(builder, loc, funcOp, args);
-}
-
-/// Generate call to runtime subroutine prif_co_broadcast
-void fir::runtime::genCoBroadcast(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Value A,
- mlir::Value sourceImage, mlir::Value stat,
- mlir::Value errmsg) {
- genCollectiveSubroutine(builder, loc, A, sourceImage, stat, errmsg,
- PRIFNAME_SUB("co_broadcast"));
-}
-
-/// Generate call to runtime subroutine prif_co_max or prif_co_max_character
-void fir::runtime::genCoMax(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value A, mlir::Value resultImage,
- mlir::Value stat, mlir::Value errmsg) {
- mlir::Type argTy =
- fir::unwrapSequenceType(fir::unwrapPassByRefType(A.getType()));
- if (mlir::isa<fir::CharacterType>(argTy))
- genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg,
- PRIFNAME_SUB("co_max_character"));
- else
- genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg,
- PRIFNAME_SUB("co_max"));
-}
-
-/// Generate call to runtime subroutine prif_co_min or prif_co_min_character
-void fir::runtime::genCoMin(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value A, mlir::Value resultImage,
- mlir::Value stat, mlir::Value errmsg) {
- mlir::Type argTy =
- fir::unwrapSequenceType(fir::unwrapPassByRefType(A.getType()));
- if (mlir::isa<fir::CharacterType>(argTy))
- genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg,
- PRIFNAME_SUB("co_min_character"));
- else
- genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg,
- PRIFNAME_SUB("co_min"));
-}
-
-/// Generate call to runtime subroutine prif_co_sum
-void fir::runtime::genCoSum(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value A, mlir::Value resultImage,
- mlir::Value stat, mlir::Value errmsg) {
- genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg,
- PRIFNAME_SUB("co_sum"));
-}
-
-/// Generate call to runtime subroutine prif_sync_all
-void fir::runtime::genSyncAllStatement(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Value stat,
- mlir::Value errmsg) {
- mlir::FunctionType ftype =
- PRIF_FUNCTYPE(PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE);
- mlir::func::FuncOp funcOp =
- builder.createFunction(loc, PRIFNAME_SUB("sync_all"), ftype);
-
- auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg);
- llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
- builder, loc, ftype, stat, errmsgArg, errmsgAllocArg);
- fir::CallOp::create(builder, loc, funcOp, args);
-}
-
-/// Generate call to runtime subroutine prif_sync_memory
-void fir::runtime::genSyncMemoryStatement(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Value stat,
- mlir::Value errmsg) {
- mlir::FunctionType ftype =
- PRIF_FUNCTYPE(PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE);
- mlir::func::FuncOp funcOp =
- builder.createFunction(loc, PRIFNAME_SUB("sync_memory"), ftype);
-
- auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg);
- llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
- builder, loc, ftype, stat, errmsgArg, errmsgAllocArg);
- fir::CallOp::create(builder, loc, funcOp, args);
-}
-
-/// Generate call to runtime subroutine prif_sync_images
-void fir::runtime::genSyncImagesStatement(fir::FirOpBuilder &builder,
- mlir::Location loc,
- mlir::Value imageSet,
- mlir::Value stat,
- mlir::Value errmsg) {
- mlir::Type imgSetTy = fir::BoxType::get(fir::SequenceType::get(
- {fir::SequenceType::getUnknownExtent()}, builder.getI32Type()));
- mlir::FunctionType ftype = PRIF_FUNCTYPE(imgSetTy, PRIF_STAT_TYPE,
- PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE);
- mlir::func::FuncOp funcOp =
- builder.createFunction(loc, PRIFNAME_SUB("sync_images"), ftype);
-
- // If imageSet is scalar, PRIF require to pass an array of size 1.
- if (auto boxTy = mlir::dyn_cast<fir::BoxType>(imageSet.getType())) {
- if (!mlir::isa<fir::SequenceType>(boxTy.getEleTy())) {
- mlir::Value one =
- builder.createIntegerConstant(loc, builder.getI32Type(), 1);
- mlir::Value shape = fir::ShapeOp::create(builder, loc, one);
- imageSet = fir::ReboxOp::create(
- builder, loc,
- fir::BoxType::get(fir::SequenceType::get({1}, builder.getI32Type())),
- imageSet, shape, mlir::Value{});
- }
- }
- auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg);
- llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
- builder, loc, ftype, imageSet, stat, errmsgArg, errmsgAllocArg);
- fir::CallOp::create(builder, loc, funcOp, args);
-}
diff --git a/flang/lib/Optimizer/Builder/Runtime/Main.cpp b/flang/lib/Optimizer/Builder/Runtime/Main.cpp
index d303e0ad63842..9ce5e172f3cd3 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Main.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Main.cpp
@@ -10,11 +10,11 @@
#include "flang/Lower/EnvironmentDefault.h"
#include "flang/Optimizer/Builder/BoxValue.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
-#include "flang/Optimizer/Builder/Runtime/Coarray.h"
#include "flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h"
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
#include "flang/Runtime/CUDA/init.h"
#include "flang/Runtime/main.h"
#include "flang/Runtime/stop.h"
@@ -71,7 +71,7 @@ void fir::runtime::genMain(
fir::CallOp::create(builder, loc, initFn);
}
if (initCoarrayEnv)
- fir::runtime::genInitCoarray(builder, loc);
+ mif::InitOp::create(builder, loc);
fir::CallOp::create(builder, loc, qqMainFn);
fir::CallOp::create(builder, loc, stopFn);
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp
index c089941688352..f3edc076d6eec 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -348,6 +348,7 @@ void createDebugPasses(mlir::PassManager &pm,
void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
MLIRToLLVMPassPipelineConfig config,
llvm::StringRef inputFilename) {
+ pm.addPass(fir::createMIFOpConversion());
fir::addBoxedProcedurePass(pm);
if (config.OptLevel.isOptimizingForSpeed() && config.AliasAnalysis &&
!disableFirAliasTags && !useOldAliasTags)
diff --git a/flang/lib/Optimizer/Transforms/CMakeLists.txt b/flang/lib/Optimizer/Transforms/CMakeLists.txt
index db2623dfa99bc..0388439f89a54 100644
--- a/flang/lib/Optimizer/Transforms/CMakeLists.txt
+++ b/flang/lib/Optimizer/Transforms/CMakeLists.txt
@@ -36,6 +36,7 @@ add_flang_library(FIRTransforms
SimplifyFIROperations.cpp
OptimizeArrayRepacking.cpp
ConvertComplexPow.cpp
+ MIFOpConversion.cpp
DEPENDS
CUFAttrs
diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
new file mode 100644
index 0000000000000..10aa0028ddcac
--- /dev/null
+++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
@@ -0,0 +1,487 @@
+//===-- MIFOpConversion.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/Transforms/MIFOpConversion.h"
+#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
+#include "flang/Optimizer/Builder/Todo.h"
+#include "flang/Optimizer/CodeGen/TypeConverter.h"
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
+#include "flang/Optimizer/HLFIR/HLFIROps.h"
+#include "flang/Optimizer/Support/DataLayout.h"
+#include "mlir/IR/Matchers.h"
+#include "mlir/Transforms/DialectConversion.h"
+#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
+
+namespace fir {
+#define GEN_PASS_DEF_MIFOPCONVERSION
+#include "flang/Optimizer/Transforms/Passes.h.inc"
+} // namespace fir
+
+using namespace mlir;
+using namespace Fortran::runtime;
+
+namespace {
+
+// Most PRIF functions take `errmsg` and `errmsg_alloc` as two optional
+// arguments of intent (out). One is allocatable, the other is not.
+// It is the responsibility of the compiler to ensure that the appropriate
+// optional argument is passed, and at most one must be provided in a given
+// call.
+// Depending on the type of `errmsg`, this function will return the pair
+// corresponding to (`errmsg`, `errmsg_alloc`).
+static std::pair<mlir::Value, mlir::Value>
+genErrmsgPRIF(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value errmsg) {
+ mlir::Value absent = fir::AbsentOp::create(builder, loc, PRIF_ERRMSG_TYPE);
+ if (!errmsg)
+ return {absent, absent};
+
+ bool isAllocatableErrmsg = fir::isAllocatableType(errmsg.getType());
+ mlir::Value errMsg = isAllocatableErrmsg ? absent : errmsg;
+ mlir::Value errMsgAlloc = isAllocatableErrmsg ? errmsg : absent;
+ return {errMsg, errMsgAlloc};
+}
+
+/// Convert mif.init operation to runtime call of 'prif_init'
+struct MIFInitOpConversion : public mlir::OpRewritePattern<mif::InitOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::InitOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::Type i32Ty = builder.getI32Type();
+ mlir::Value result = builder.createTemporary(loc, i32Ty);
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/ {builder.getRefType(i32Ty)}, /*results*/ {});
+ mlir::func::FuncOp funcOp =
+ builder.createFunction(loc, PRIFNAME_SUB("init"), ftype);
+ llvm::SmallVector<mlir::Value> args =
+ fir::runtime::createArguments(builder, loc, ftype, result);
+ fir::CallOp::create(builder, loc, funcOp, args);
+ rewriter.replaceOpWithNewOp<fir::LoadOp>(op, result);
+ return mlir::success();
+ }
+};
+
+/// Convert mif.this_image operation to PRIF runtime call
+struct MIFThisImageOpConversion
+ : public mlir::OpRewritePattern<mif::ThisImageOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::ThisImageOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ if (op.getCoarray())
+ TODO(loc, "mif.this_image op with coarray argument.");
+ else {
+ mlir::Type i32Ty = builder.getI32Type();
+ mlir::Type boxTy = fir::BoxType::get(rewriter.getNoneType());
+ mlir::Value result = builder.createTemporary(loc, i32Ty);
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/ {boxTy, builder.getRefType(i32Ty)}, /*results*/ {});
+ mlir::Value teamArg = op.getTeam();
+ if (!op.getTeam())
+ teamArg = fir::AbsentOp::create(builder, loc, boxTy);
+
+ mlir::func::FuncOp funcOp = builder.createFunction(
+ loc, PRIFNAME_SUB("this_image_no_coarray"), ftype);
+ llvm::SmallVector<mlir::Value> args =
+ fir::runtime::createArguments(builder, loc, ftype, teamArg, result);
+ fir::CallOp::create(builder, loc, funcOp, args);
+ rewriter.replaceOpWithNewOp<fir::LoadOp>(op, result);
+ return mlir::success();
+ }
+ }
+};
+
+/// Convert mif.num_images operation to runtime call of
+/// prif_num_images_with_{team|team_number}
+struct MIFNumImagesOpConversion
+ : public mlir::OpRewritePattern<mif::NumImagesOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::NumImagesOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::Type i32Ty = builder.getI32Type();
+ mlir::Type i64Ty = builder.getI64Type();
+ mlir::Type boxTy = fir::BoxType::get(rewriter.getNoneType());
+ mlir::Value result = builder.createTemporary(loc, i32Ty);
+
+ mlir::func::FuncOp funcOp;
+ llvm::SmallVector<mlir::Value> args;
+ if (!op.getTeam() && !op.getTeamNumber()) {
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/ {builder.getRefType(i32Ty)}, /*results*/ {});
+ funcOp = builder.createFunction(loc, PRIFNAME_SUB("num_images"), ftype);
+ args = fir::runtime::createArguments(builder, loc, ftype, result);
+ } else {
+ if (op.getTeam()) {
+ mlir::FunctionType ftype =
+ mlir::FunctionType::get(builder.getContext(),
+ /*inputs*/
+ {boxTy, builder.getRefType(i32Ty)},
+ /*results*/ {});
+ funcOp = builder.createFunction(
+ loc, PRIFNAME_SUB("num_images_with_team"), ftype);
+ args = fir::runtime::createArguments(builder, loc, ftype, op.getTeam(),
+ result);
+ } else {
+ mlir::Value teamNumber = builder.createTemporary(loc, i64Ty);
+ mlir::Value cst = op.getTeamNumber();
+ if (op.getTeamNumber().getType() != i64Ty)
+ cst = fir::ConvertOp::create(builder, loc, i64Ty, op.getTeamNumber());
+ fir::StoreOp::create(builder, loc, cst, teamNumber);
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/ {builder.getRefType(i64Ty), builder.getRefType(i32Ty)},
+ /*results*/ {});
+ funcOp = builder.createFunction(
+ loc, PRIFNAME_SUB("num_images_with_team_number"), ftype);
+ args = fir::runtime::createArguments(builder, loc, ftype, teamNumber,
+ result);
+ }
+ }
+ fir::CallOp::create(builder, loc, funcOp, args);
+ rewriter.replaceOpWithNewOp<fir::LoadOp>(op, result);
+ return mlir::success();
+ }
+};
+
+/// Convert mif.sync_all operation to runtime call of 'prif_sync_all'
+struct MIFSyncAllOpConversion : public mlir::OpRewritePattern<mif::SyncAllOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::SyncAllOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/ {PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE},
+ /*results*/ {});
+ mlir::func::FuncOp funcOp =
+ builder.createFunction(loc, PRIFNAME_SUB("sync_all"), ftype);
+
+ auto [errmsgArg, errmsgAllocArg] =
+ genErrmsgPRIF(builder, loc, op.getErrmsg());
+ mlir::Value stat = op.getStat();
+ if (!stat)
+ stat = fir::AbsentOp::create(builder, loc, PRIF_STAT_TYPE);
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, ftype, stat, errmsgArg, errmsgAllocArg);
+ rewriter.replaceOpWithNewOp<fir::CallOp>(op, funcOp, args);
+ return mlir::success();
+ }
+};
+
+/// Convert mif.sync_images operation to runtime call of 'prif_sync_images'
+struct MIFSyncImagesOpConversion
+ : public mlir::OpRewritePattern<mif::SyncImagesOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::SyncImagesOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::Type imgSetTy = fir::BoxType::get(fir::SequenceType::get(
+ {fir::SequenceType::getUnknownExtent()}, builder.getI32Type()));
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/
+ {imgSetTy, PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE},
+ /*results*/ {});
+ mlir::func::FuncOp funcOp =
+ builder.createFunction(loc, PRIFNAME_SUB("sync_images"), ftype);
+
+ // If imageSet is scalar, PRIF require to pass an array of size 1.
+ mlir::Value imageSet = op.getImageSet();
+ if (!imageSet)
+ imageSet = fir::AbsentOp::create(builder, loc, imgSetTy);
+ else if (auto boxTy = mlir::dyn_cast<fir::BoxType>(imageSet.getType())) {
+ if (!mlir::isa<fir::SequenceType>(boxTy.getEleTy())) {
+ mlir::Value one =
+ builder.createIntegerConstant(loc, builder.getI32Type(), 1);
+ mlir::Value shape = fir::ShapeOp::create(builder, loc, one);
+ imageSet =
+ fir::ReboxOp::create(builder, loc,
+ fir::BoxType::get(fir::SequenceType::get(
+ {1}, builder.getI32Type())),
+ imageSet, shape, mlir::Value{});
+ }
+ }
+ auto [errmsgArg, errmsgAllocArg] =
+ genErrmsgPRIF(builder, loc, op.getErrmsg());
+ mlir::Value stat = op.getStat();
+ if (!stat)
+ stat = fir::AbsentOp::create(builder, loc, PRIF_STAT_TYPE);
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, ftype, imageSet, stat, errmsgArg, errmsgAllocArg);
+ rewriter.replaceOpWithNewOp<fir::CallOp>(op, funcOp, args);
+ return mlir::success();
+ }
+};
+
+/// Convert mif.sync_memory operation to runtime call of 'prif_sync_memory'
+struct MIFSyncMemoryOpConversion
+ : public mlir::OpRewritePattern<mif::SyncMemoryOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::SyncMemoryOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/ {PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE},
+ /*results*/ {});
+ mlir::func::FuncOp funcOp =
+ builder.createFunction(loc, PRIFNAME_SUB("sync_memory"), ftype);
+
+ auto [errmsgArg, errmsgAllocArg] =
+ genErrmsgPRIF(builder, loc, op.getErrmsg());
+ mlir::Value stat = op.getStat();
+ if (!stat)
+ stat = fir::AbsentOp::create(builder, loc, PRIF_STAT_TYPE);
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, ftype, stat, errmsgArg, errmsgAllocArg);
+ rewriter.replaceOpWithNewOp<fir::CallOp>(op, funcOp, args);
+ return mlir::success();
+ }
+};
+
+/// Generate call to collective subroutines except co_reduce
+/// A must be lowered as a box
+static fir::CallOp genCollectiveSubroutine(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value A,
+ mlir::Value rootImage,
+ mlir::Value stat, mlir::Value errmsg,
+ std::string coName) {
+ mlir::Type boxTy = fir::BoxType::get(builder.getNoneType());
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/
+ {boxTy, builder.getRefType(builder.getI32Type()), PRIF_STAT_TYPE,
+ PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE},
+ /*results*/ {});
+ mlir::func::FuncOp funcOp = builder.createFunction(loc, coName, ftype);
+
+ auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg);
+ if (!stat)
+ stat = fir::AbsentOp::create(builder, loc, PRIF_STAT_TYPE);
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, ftype, A, rootImage, stat, errmsgArg, errmsgAllocArg);
+ return fir::CallOp::create(builder, loc, funcOp, args);
+}
+
+/// Convert mif.co_broadcast operation to runtime call of 'prif_co_broadcast'
+struct MIFCoBroadcastOpConversion
+ : public mlir::OpRewritePattern<mif::CoBroadcastOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::CoBroadcastOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::Type i32Ty = builder.getI32Type();
+ mlir::Value sourceImage = builder.createTemporary(loc, i32Ty);
+ mlir::Value cst = op.getSourceImage();
+ if (op.getSourceImage().getType() != i32Ty)
+ cst = fir::ConvertOp::create(builder, loc, i32Ty, op.getSourceImage());
+ fir::StoreOp::create(builder, loc, cst, sourceImage);
+
+ fir::CallOp callOp = genCollectiveSubroutine(
+ builder, loc, op.getA(), sourceImage, op.getStat(), op.getErrmsg(),
+ PRIFNAME_SUB("co_broadcast"));
+ rewriter.replaceOp(op, callOp);
+ return mlir::success();
+ }
+};
+
+/// Convert mif.co_max operation to runtime call of 'prif_co_max'
+struct MIFCoMaxOpConversion : public mlir::OpRewritePattern<mif::CoMaxOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::CoMaxOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::Value resultImage;
+ mlir::Type i32Ty = builder.getI32Type();
+ if (!op.getResultImage())
+ resultImage =
+ fir::AbsentOp::create(builder, loc, builder.getRefType(i32Ty));
+ else {
+ resultImage = builder.createTemporary(loc, i32Ty);
+ mlir::Value cst = op.getResultImage();
+ if (op.getResultImage().getType() != i32Ty)
+ cst = fir::ConvertOp::create(builder, loc, i32Ty, op.getResultImage());
+ fir::StoreOp::create(builder, loc, cst, resultImage);
+ }
+
+ fir::CallOp callOp;
+ mlir::Type argTy =
+ fir::unwrapSequenceType(fir::unwrapPassByRefType(op.getA().getType()));
+ if (mlir::isa<fir::CharacterType>(argTy))
+ callOp = genCollectiveSubroutine(builder, loc, op.getA(), resultImage,
+ op.getStat(), op.getErrmsg(),
+ PRIFNAME_SUB("co_max_character"));
+ else
+ callOp = genCollectiveSubroutine(builder, loc, op.getA(), resultImage,
+ op.getStat(), op.getErrmsg(),
+ PRIFNAME_SUB("co_max"));
+ rewriter.replaceOp(op, callOp);
+ return mlir::success();
+ }
+};
+
+/// Convert mif.co_min operation to runtime call of 'prif_co_min'
+struct MIFCoMinOpConversion : public mlir::OpRewritePattern<mif::CoMinOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::CoMinOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::Value resultImage;
+ mlir::Type i32Ty = builder.getI32Type();
+ if (!op.getResultImage())
+ resultImage =
+ fir::AbsentOp::create(builder, loc, builder.getRefType(i32Ty));
+ else {
+ resultImage = builder.createTemporary(loc, i32Ty);
+ mlir::Value cst = op.getResultImage();
+ if (op.getResultImage().getType() != i32Ty)
+ cst = fir::ConvertOp::create(builder, loc, i32Ty, op.getResultImage());
+ fir::StoreOp::create(builder, loc, cst, resultImage);
+ }
+
+ fir::CallOp callOp;
+ mlir::Type argTy =
+ fir::unwrapSequenceType(fir::unwrapPassByRefType(op.getA().getType()));
+ if (mlir::isa<fir::CharacterType>(argTy))
+ callOp = genCollectiveSubroutine(builder, loc, op.getA(), resultImage,
+ op.getStat(), op.getErrmsg(),
+ PRIFNAME_SUB("co_min_character"));
+ else
+ callOp = genCollectiveSubroutine(builder, loc, op.getA(), resultImage,
+ op.getStat(), op.getErrmsg(),
+ PRIFNAME_SUB("co_min"));
+ rewriter.replaceOp(op, callOp);
+ return mlir::success();
+ }
+};
+
+/// Convert mif.co_sum operation to runtime call of 'prif_co_sum'
+struct MIFCoSumOpConversion : public mlir::OpRewritePattern<mif::CoSumOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::CoSumOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::Value resultImage;
+ mlir::Type i32Ty = builder.getI32Type();
+ if (!op.getResultImage())
+ resultImage =
+ fir::AbsentOp::create(builder, loc, builder.getRefType(i32Ty));
+ else {
+ resultImage = builder.createTemporary(loc, i32Ty);
+ mlir::Value cst = op.getResultImage();
+ if (op.getResultImage().getType() != i32Ty)
+ cst = fir::ConvertOp::create(builder, loc, i32Ty, op.getResultImage());
+ fir::StoreOp::create(builder, loc, cst, resultImage);
+ }
+
+ fir::CallOp callOp = genCollectiveSubroutine(
+ builder, loc, op.getA(), resultImage, op.getStat(), op.getErrmsg(),
+ PRIFNAME_SUB("co_sum"));
+ rewriter.replaceOp(op, callOp);
+ return mlir::success();
+ }
+};
+
+class MIFOpConversion : public fir::impl::MIFOpConversionBase<MIFOpConversion> {
+public:
+ void runOnOperation() override {
+ auto *ctx = &getContext();
+ mlir::RewritePatternSet patterns(ctx);
+ mlir::ConversionTarget target(*ctx);
+
+ mlir::Operation *op = getOperation();
+ mlir::ModuleOp module = mlir::dyn_cast<mlir::ModuleOp>(op);
+ if (!module)
+ return signalPassFailure();
+ mlir::SymbolTable symtab(module);
+
+ std::optional<mlir::DataLayout> dl = fir::support::getOrSetMLIRDataLayout(
+ module, /*allowDefaultLayout=*/true);
+ fir::LLVMTypeConverter typeConverter(module, /*applyTBAA=*/false,
+ /*forceUnifiedTBAATree=*/false, *dl);
+ mif::populateMIFOpConversionPatterns(typeConverter, patterns);
+
+ target.addLegalDialect<fir::FIROpsDialect>();
+ target.addLegalOp<mlir::ModuleOp>();
+
+ if (mlir::failed(mlir::applyPartialConversion(getOperation(), target,
+ std::move(patterns)))) {
+ mlir::emitError(mlir::UnknownLoc::get(ctx),
+ "error in MIF op conversion\n");
+ return signalPassFailure();
+ }
+ }
+};
+} // namespace
+
+void mif::populateMIFOpConversionPatterns(fir::LLVMTypeConverter &converter,
+ mlir::RewritePatternSet &patterns) {
+ patterns.insert<MIFInitOpConversion, MIFThisImageOpConversion,
+ MIFNumImagesOpConversion, MIFSyncAllOpConversion,
+ MIFSyncImagesOpConversion, MIFSyncMemoryOpConversion,
+ MIFCoBroadcastOpConversion, MIFCoMaxOpConversion,
+ MIFCoMinOpConversion, MIFCoSumOpConversion>(
+ patterns.getContext());
+}
diff --git a/flang/test/Driver/mlir-debug-pass-pipeline.f90 b/flang/test/Driver/mlir-debug-pass-pipeline.f90
index 5943a3c61c342..eb5165e36c919 100644
--- a/flang/test/Driver/mlir-debug-pass-pipeline.f90
+++ b/flang/test/Driver/mlir-debug-pass-pipeline.f90
@@ -100,6 +100,7 @@
! ALL-NEXT: CSE
! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd
! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
+! ALL-NEXT: MIFOpConversion
! ALL-NEXT: BoxedProcedurePass
! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private']
diff --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90
index df558392c5fc2..3b6a9d7cda7ed 100644
--- a/flang/test/Driver/mlir-pass-pipeline.f90
+++ b/flang/test/Driver/mlir-pass-pipeline.f90
@@ -142,6 +142,7 @@
! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
! O2-NEXT: 'func.func' Pipeline
! O2-NEXT: SetRuntimeCallAttributes
+! ALL-NEXT: MIFOpConversion
! ALL-NEXT: BoxedProcedurePass
! O2-NEXT: AddAliasTags
diff --git a/flang/test/Fir/MIF/co_broadcast.mlir b/flang/test/Fir/MIF/co_broadcast.mlir
new file mode 100644
index 0000000000000..de622a474c4e1
--- /dev/null
+++ b/flang/test/Fir/MIF/co_broadcast.mlir
@@ -0,0 +1,148 @@
+// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git at github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_CO_BROADCAST"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %c2 = arith.constant 2 : index
+ %1 = fir.alloca !fir.array<2xcomplex<f32>> {bindc_name = "array_c", uniq_name = "_QFEarray_c"}
+ %2 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %3:2 = hlfir.declare %1(%2) {uniq_name = "_QFEarray_c"} : (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.ref<!fir.array<2xcomplex<f32>>>)
+ %c2_0 = arith.constant 2 : index
+ %4 = fir.alloca !fir.array<2xf64> {bindc_name = "array_d", uniq_name = "_QFEarray_d"}
+ %5 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %6:2 = hlfir.declare %4(%5) {uniq_name = "_QFEarray_d"} : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf64>>, !fir.ref<!fir.array<2xf64>>)
+ %c2_1 = arith.constant 2 : index
+ %7 = fir.alloca !fir.array<2xi32> {bindc_name = "array_i", uniq_name = "_QFEarray_i"}
+ %8 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %9:2 = hlfir.declare %7(%8) {uniq_name = "_QFEarray_i"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>)
+ %c2_2 = arith.constant 2 : index
+ %10 = fir.alloca !fir.array<2xf32> {bindc_name = "array_r", uniq_name = "_QFEarray_r"}
+ %11 = fir.shape %c2_2 : (index) -> !fir.shape<1>
+ %12:2 = hlfir.declare %10(%11) {uniq_name = "_QFEarray_r"} : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf32>>, !fir.ref<!fir.array<2xf32>>)
+ %13 = fir.alloca complex<f32> {bindc_name = "c", uniq_name = "_QFEc"}
+ %14:2 = hlfir.declare %13 {uniq_name = "_QFEc"} : (!fir.ref<complex<f32>>) -> (!fir.ref<complex<f32>>, !fir.ref<complex<f32>>)
+ %15 = fir.alloca f64 {bindc_name = "d", uniq_name = "_QFEd"}
+ %16:2 = hlfir.declare %15 {uniq_name = "_QFEd"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
+ %17 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+ %18:2 = hlfir.declare %17 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %c1 = arith.constant 1 : index
+ %19 = fir.alloca !fir.char<1> {bindc_name = "message", uniq_name = "_QFEmessage"}
+ %20:2 = hlfir.declare %19 typeparams %c1 {uniq_name = "_QFEmessage"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+ %21 = fir.alloca f32 {bindc_name = "r", uniq_name = "_QFEr"}
+ %22:2 = hlfir.declare %21 {uniq_name = "_QFEr"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+ %23 = fir.alloca i32 {bindc_name = "status", uniq_name = "_QFEstatus"}
+ %24:2 = hlfir.declare %23 {uniq_name = "_QFEstatus"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %c1_i32 = arith.constant 1 : i32
+ %25 = fir.embox %18#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.co_broadcast %25 : !fir.box<i32> source(%c1_i32 : i32)
+ %c1_i32_3 = arith.constant 1 : i32
+ %26 = fir.embox %14#0 : (!fir.ref<complex<f32>>) -> !fir.box<complex<f32>>
+ mif.co_broadcast %26 : !fir.box<complex<f32>> source(%c1_i32_3 : i32) stat(%24#0 : !fir.ref<i32>)
+ %c1_i32_4 = arith.constant 1 : i32
+ %27 = fir.embox %16#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ %28 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_broadcast %27 : !fir.box<f64> source(%c1_i32_4 : i32) stat(%24#0 : !fir.ref<i32>) errmsg(%28 : !fir.box<!fir.char<1>>)
+ %c1_i32_5 = arith.constant 1 : i32
+ %29 = fir.embox %22#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ %30 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_broadcast %29 : !fir.box<f32> source(%c1_i32_5 : i32) stat(%24#0 : !fir.ref<i32>) errmsg(%30 : !fir.box<!fir.char<1>>)
+ %c1_i32_6 = arith.constant 1 : i32
+ %31 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %32 = fir.embox %9#0(%31) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ mif.co_broadcast %32 : !fir.box<!fir.array<2xi32>> source(%c1_i32_6 : i32)
+ %c1_i32_7 = arith.constant 1 : i32
+ %33 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %34 = fir.embox %3#0(%33) : (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.shape<1>) -> !fir.box<!fir.array<2xcomplex<f32>>>
+ mif.co_broadcast %34 : !fir.box<!fir.array<2xcomplex<f32>>> source(%c1_i32_7 : i32)
+ %c1_i32_8 = arith.constant 1 : i32
+ %35 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %36 = fir.embox %6#0(%35) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ mif.co_broadcast %36 : !fir.box<!fir.array<2xf64>> source(%c1_i32_8 : i32) stat(%24#0 : !fir.ref<i32>)
+ %c1_i32_9 = arith.constant 1 : i32
+ %37 = fir.shape %c2_2 : (index) -> !fir.shape<1>
+ %38 = fir.embox %12#0(%37) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ %39 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_broadcast %38 : !fir.box<!fir.array<2xf32>> source(%c1_i32_9 : i32) stat(%24#0 : !fir.ref<i32>) errmsg(%39 : !fir.box<!fir.char<1>>)
+ return
+ }
+ func.func private @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, !llvm.ptr)
+ func.func private @_FortranAProgramEndStatement()
+ func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 {
+ %0 = fir.zero_bits !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
+ fir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) fastmath<contract> : (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>) -> ()
+ %1 = mif.init -> i32
+ fir.call @_QQmain() fastmath<contract> : () -> ()
+ fir.call @_FortranAProgramEndStatement() fastmath<contract> : () -> ()
+ %c0_i32 = arith.constant 0 : i32
+ return %c0_i32 : i32
+ }
+}
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<complex<f32>>) -> !fir.box<complex<f32>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.convert %[[V1]] : (!fir.box<complex<f32>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V3]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.shape<1>) -> !fir.box<!fir.array<2xcomplex<f32>>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xcomplex<f32>>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
diff --git a/flang/test/Fir/MIF/co_max.mlir b/flang/test/Fir/MIF/co_max.mlir
new file mode 100644
index 0000000000000..6c36714fcf2a1
--- /dev/null
+++ b/flang/test/Fir/MIF/co_max.mlir
@@ -0,0 +1,174 @@
+// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git at github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_CO_MAX"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %c1 = arith.constant 1 : index
+ %c2 = arith.constant 2 : index
+ %1 = fir.alloca !fir.array<2x!fir.char<1>> {bindc_name = "array_c", uniq_name = "_QFEarray_c"}
+ %2 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %3:2 = hlfir.declare %1(%2) typeparams %c1 {uniq_name = "_QFEarray_c"} : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>, index) -> (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.ref<!fir.array<2x!fir.char<1>>>)
+ %c2_0 = arith.constant 2 : index
+ %4 = fir.alloca !fir.array<2xf64> {bindc_name = "array_d", uniq_name = "_QFEarray_d"}
+ %5 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %6:2 = hlfir.declare %4(%5) {uniq_name = "_QFEarray_d"} : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf64>>, !fir.ref<!fir.array<2xf64>>)
+ %c2_1 = arith.constant 2 : index
+ %7 = fir.alloca !fir.array<2xi32> {bindc_name = "array_i", uniq_name = "_QFEarray_i"}
+ %8 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %9:2 = hlfir.declare %7(%8) {uniq_name = "_QFEarray_i"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>)
+ %c2_2 = arith.constant 2 : index
+ %10 = fir.alloca !fir.array<2xf32> {bindc_name = "array_r", uniq_name = "_QFEarray_r"}
+ %11 = fir.shape %c2_2 : (index) -> !fir.shape<1>
+ %12:2 = hlfir.declare %10(%11) {uniq_name = "_QFEarray_r"} : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf32>>, !fir.ref<!fir.array<2xf32>>)
+ %c1_3 = arith.constant 1 : index
+ %13 = fir.alloca !fir.char<1> {bindc_name = "c", uniq_name = "_QFEc"}
+ %14:2 = hlfir.declare %13 typeparams %c1_3 {uniq_name = "_QFEc"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+ %15 = fir.alloca f64 {bindc_name = "d", uniq_name = "_QFEd"}
+ %16:2 = hlfir.declare %15 {uniq_name = "_QFEd"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
+ %17 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+ %18:2 = hlfir.declare %17 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %c1_4 = arith.constant 1 : index
+ %19 = fir.alloca !fir.char<1> {bindc_name = "message", uniq_name = "_QFEmessage"}
+ %20:2 = hlfir.declare %19 typeparams %c1_4 {uniq_name = "_QFEmessage"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+ %21 = fir.alloca f32 {bindc_name = "r", uniq_name = "_QFEr"}
+ %22:2 = hlfir.declare %21 {uniq_name = "_QFEr"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+ %23 = fir.alloca i32 {bindc_name = "status", uniq_name = "_QFEstatus"}
+ %24:2 = hlfir.declare %23 {uniq_name = "_QFEstatus"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %25 = fir.embox %18#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.co_max %25 : !fir.box<i32>
+ %26 = fir.embox %14#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_max %26 : !fir.box<!fir.char<1>>
+ %27 = fir.embox %16#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ mif.co_max %27 : !fir.box<f64>
+ %28 = fir.embox %22#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ mif.co_max %28 : !fir.box<f32>
+ %c1_i32 = arith.constant 1 : i32
+ %29 = fir.embox %18#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.co_max %29 : !fir.box<i32> result(%c1_i32 : i32)
+ %c1_i32_5 = arith.constant 1 : i32
+ %30 = fir.embox %16#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ %31 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_max %30 : !fir.box<f64> result(%c1_i32_5 : i32) stat(%24#0 : !fir.ref<i32>) errmsg(%31 : !fir.box<!fir.char<1>>)
+ %c1_i32_6 = arith.constant 1 : i32
+ %32 = fir.embox %22#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ %33 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_max %32 : !fir.box<f32> result(%c1_i32_6 : i32) stat(%24#0 : !fir.ref<i32>) errmsg(%33 : !fir.box<!fir.char<1>>)
+ %34 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %35 = fir.embox %9#0(%34) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ mif.co_max %35 : !fir.box<!fir.array<2xi32>>
+ %c1_i32_7 = arith.constant 1 : i32
+ %36 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %37 = fir.embox %3#0(%36) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
+ mif.co_max %37 : !fir.box<!fir.array<2x!fir.char<1>>> result(%c1_i32_7 : i32)
+ %c1_i32_8 = arith.constant 1 : i32
+ %38 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %39 = fir.embox %6#0(%38) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ mif.co_max %39 : !fir.box<!fir.array<2xf64>> result(%c1_i32_8 : i32) stat(%24#0 : !fir.ref<i32>)
+ %c1_i32_9 = arith.constant 1 : i32
+ %40 = fir.shape %c2_2 : (index) -> !fir.shape<1>
+ %41 = fir.embox %12#0(%40) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ %42 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_max %41 : !fir.box<!fir.array<2xf32>> result(%c1_i32_9 : i32) stat(%24#0 : !fir.ref<i32>) errmsg(%42 : !fir.box<!fir.char<1>>)
+ return
+ }
+ func.func private @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, !llvm.ptr)
+ func.func private @_FortranAProgramEndStatement()
+ func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 {
+ %0 = fir.zero_bits !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
+ fir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) fastmath<contract> : (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>) -> ()
+ %1 = mif.init -> i32
+ fir.call @_QQmain() fastmath<contract> : () -> ()
+ fir.call @_FortranAProgramEndStatement() fastmath<contract> : () -> ()
+ %c0_i32 = arith.constant 0 : i32
+ return %c0_i32 : i32
+ }
+}
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.char<1>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max_character(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2x!fir.char<1>>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max_character(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
diff --git a/flang/test/Fir/MIF/co_min.mlir b/flang/test/Fir/MIF/co_min.mlir
new file mode 100644
index 0000000000000..00b89f4a30a0d
--- /dev/null
+++ b/flang/test/Fir/MIF/co_min.mlir
@@ -0,0 +1,174 @@
+// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git at github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_CO_MIN"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %c1 = arith.constant 1 : index
+ %c2 = arith.constant 2 : index
+ %1 = fir.alloca !fir.array<2x!fir.char<1>> {bindc_name = "array_c", uniq_name = "_QFEarray_c"}
+ %2 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %3:2 = hlfir.declare %1(%2) typeparams %c1 {uniq_name = "_QFEarray_c"} : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>, index) -> (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.ref<!fir.array<2x!fir.char<1>>>)
+ %c2_0 = arith.constant 2 : index
+ %4 = fir.alloca !fir.array<2xf64> {bindc_name = "array_d", uniq_name = "_QFEarray_d"}
+ %5 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %6:2 = hlfir.declare %4(%5) {uniq_name = "_QFEarray_d"} : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf64>>, !fir.ref<!fir.array<2xf64>>)
+ %c2_1 = arith.constant 2 : index
+ %7 = fir.alloca !fir.array<2xi32> {bindc_name = "array_i", uniq_name = "_QFEarray_i"}
+ %8 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %9:2 = hlfir.declare %7(%8) {uniq_name = "_QFEarray_i"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>)
+ %c2_2 = arith.constant 2 : index
+ %10 = fir.alloca !fir.array<2xf32> {bindc_name = "array_r", uniq_name = "_QFEarray_r"}
+ %11 = fir.shape %c2_2 : (index) -> !fir.shape<1>
+ %12:2 = hlfir.declare %10(%11) {uniq_name = "_QFEarray_r"} : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf32>>, !fir.ref<!fir.array<2xf32>>)
+ %c1_3 = arith.constant 1 : index
+ %13 = fir.alloca !fir.char<1> {bindc_name = "c", uniq_name = "_QFEc"}
+ %14:2 = hlfir.declare %13 typeparams %c1_3 {uniq_name = "_QFEc"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+ %15 = fir.alloca f64 {bindc_name = "d", uniq_name = "_QFEd"}
+ %16:2 = hlfir.declare %15 {uniq_name = "_QFEd"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
+ %17 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+ %18:2 = hlfir.declare %17 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %c1_4 = arith.constant 1 : index
+ %19 = fir.alloca !fir.char<1> {bindc_name = "message", uniq_name = "_QFEmessage"}
+ %20:2 = hlfir.declare %19 typeparams %c1_4 {uniq_name = "_QFEmessage"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+ %21 = fir.alloca f32 {bindc_name = "r", uniq_name = "_QFEr"}
+ %22:2 = hlfir.declare %21 {uniq_name = "_QFEr"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+ %23 = fir.alloca i32 {bindc_name = "status", uniq_name = "_QFEstatus"}
+ %24:2 = hlfir.declare %23 {uniq_name = "_QFEstatus"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %25 = fir.embox %18#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.co_min %25 : !fir.box<i32>
+ %26 = fir.embox %14#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_min %26 : !fir.box<!fir.char<1>>
+ %27 = fir.embox %16#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ mif.co_min %27 : !fir.box<f64>
+ %28 = fir.embox %22#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ mif.co_min %28 : !fir.box<f32>
+ %c1_i32 = arith.constant 1 : i32
+ %29 = fir.embox %18#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.co_min %29 : !fir.box<i32> result(%c1_i32 : i32)
+ %c1_i32_5 = arith.constant 1 : i32
+ %30 = fir.embox %16#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ %31 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_min %30 : !fir.box<f64> result(%c1_i32_5 : i32) stat(%24#0 : !fir.ref<i32>) errmsg(%31 : !fir.box<!fir.char<1>>)
+ %c1_i32_6 = arith.constant 1 : i32
+ %32 = fir.embox %22#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ %33 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_min %32 : !fir.box<f32> result(%c1_i32_6 : i32) stat(%24#0 : !fir.ref<i32>) errmsg(%33 : !fir.box<!fir.char<1>>)
+ %34 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %35 = fir.embox %9#0(%34) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ mif.co_min %35 : !fir.box<!fir.array<2xi32>>
+ %c1_i32_7 = arith.constant 1 : i32
+ %36 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %37 = fir.embox %3#0(%36) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
+ mif.co_min %37 : !fir.box<!fir.array<2x!fir.char<1>>> result(%c1_i32_7 : i32)
+ %c1_i32_8 = arith.constant 1 : i32
+ %38 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %39 = fir.embox %6#0(%38) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ mif.co_min %39 : !fir.box<!fir.array<2xf64>> result(%c1_i32_8 : i32) stat(%24#0 : !fir.ref<i32>)
+ %c1_i32_9 = arith.constant 1 : i32
+ %40 = fir.shape %c2_2 : (index) -> !fir.shape<1>
+ %41 = fir.embox %12#0(%40) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ %42 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_min %41 : !fir.box<!fir.array<2xf32>> result(%c1_i32_9 : i32) stat(%24#0 : !fir.ref<i32>) errmsg(%42 : !fir.box<!fir.char<1>>)
+ return
+ }
+ func.func private @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, !llvm.ptr)
+ func.func private @_FortranAProgramEndStatement()
+ func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 {
+ %0 = fir.zero_bits !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
+ fir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) fastmath<contract> : (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>) -> ()
+ %1 = mif.init -> i32
+ fir.call @_QQmain() fastmath<contract> : () -> ()
+ fir.call @_FortranAProgramEndStatement() fastmath<contract> : () -> ()
+ %c0_i32 = arith.constant 0 : i32
+ return %c0_i32 : i32
+ }
+}
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.char<1>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min_character(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2x!fir.char<1>>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min_character(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
diff --git a/flang/test/Fir/MIF/co_sum.mlir b/flang/test/Fir/MIF/co_sum.mlir
new file mode 100644
index 0000000000000..11f8e213fa4e7
--- /dev/null
+++ b/flang/test/Fir/MIF/co_sum.mlir
@@ -0,0 +1,152 @@
+// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git at github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_CO_SUM"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %c1 = arith.constant 1 : index
+ %c2 = arith.constant 2 : index
+ %1 = fir.alloca !fir.array<2x!fir.char<1>> {bindc_name = "array_c", uniq_name = "_QFEarray_c"}
+ %2 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %3:2 = hlfir.declare %1(%2) typeparams %c1 {uniq_name = "_QFEarray_c"} : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>, index) -> (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.ref<!fir.array<2x!fir.char<1>>>)
+ %c2_0 = arith.constant 2 : index
+ %4 = fir.alloca !fir.array<2xf64> {bindc_name = "array_d", uniq_name = "_QFEarray_d"}
+ %5 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %6:2 = hlfir.declare %4(%5) {uniq_name = "_QFEarray_d"} : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf64>>, !fir.ref<!fir.array<2xf64>>)
+ %c2_1 = arith.constant 2 : index
+ %7 = fir.alloca !fir.array<2xi32> {bindc_name = "array_i", uniq_name = "_QFEarray_i"}
+ %8 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %9:2 = hlfir.declare %7(%8) {uniq_name = "_QFEarray_i"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>)
+ %c2_2 = arith.constant 2 : index
+ %10 = fir.alloca !fir.array<2xf32> {bindc_name = "array_r", uniq_name = "_QFEarray_r"}
+ %11 = fir.shape %c2_2 : (index) -> !fir.shape<1>
+ %12:2 = hlfir.declare %10(%11) {uniq_name = "_QFEarray_r"} : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf32>>, !fir.ref<!fir.array<2xf32>>)
+ %c1_3 = arith.constant 1 : index
+ %13 = fir.alloca !fir.char<1> {bindc_name = "c", uniq_name = "_QFEc"}
+ %14:2 = hlfir.declare %13 typeparams %c1_3 {uniq_name = "_QFEc"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+ %15 = fir.alloca f64 {bindc_name = "d", uniq_name = "_QFEd"}
+ %16:2 = hlfir.declare %15 {uniq_name = "_QFEd"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
+ %17 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+ %18:2 = hlfir.declare %17 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %c1_4 = arith.constant 1 : index
+ %19 = fir.alloca !fir.char<1> {bindc_name = "message", uniq_name = "_QFEmessage"}
+ %20:2 = hlfir.declare %19 typeparams %c1_4 {uniq_name = "_QFEmessage"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+ %21 = fir.alloca f32 {bindc_name = "r", uniq_name = "_QFEr"}
+ %22:2 = hlfir.declare %21 {uniq_name = "_QFEr"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+ %23 = fir.alloca i32 {bindc_name = "status", uniq_name = "_QFEstatus"}
+ %24:2 = hlfir.declare %23 {uniq_name = "_QFEstatus"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %25 = fir.embox %18#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.co_sum %25 : !fir.box<i32>
+ %27 = fir.embox %16#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ mif.co_sum %27 : !fir.box<f64>
+ %28 = fir.embox %22#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ mif.co_sum %28 : !fir.box<f32>
+ %c1_i32 = arith.constant 1 : i32
+ %29 = fir.embox %18#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.co_sum %29 : !fir.box<i32> result(%c1_i32 : i32)
+ %c1_i32_5 = arith.constant 1 : i32
+ %30 = fir.embox %16#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ %31 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_sum %30 : !fir.box<f64> result(%c1_i32_5 : i32) stat(%24#0 : !fir.ref<i32>) errmsg(%31 : !fir.box<!fir.char<1>>)
+ %c1_i32_6 = arith.constant 1 : i32
+ %32 = fir.embox %22#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ %33 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_sum %32 : !fir.box<f32> result(%c1_i32_6 : i32) stat(%24#0 : !fir.ref<i32>) errmsg(%33 : !fir.box<!fir.char<1>>)
+ %34 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %35 = fir.embox %9#0(%34) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ mif.co_sum %35 : !fir.box<!fir.array<2xi32>>
+ %c1_i32_8 = arith.constant 1 : i32
+ %38 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %39 = fir.embox %6#0(%38) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ mif.co_sum %39 : !fir.box<!fir.array<2xf64>> result(%c1_i32_8 : i32) stat(%24#0 : !fir.ref<i32>)
+ %c1_i32_9 = arith.constant 1 : i32
+ %40 = fir.shape %c2_2 : (index) -> !fir.shape<1>
+ %41 = fir.embox %12#0(%40) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ %42 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_sum %41 : !fir.box<!fir.array<2xf32>> result(%c1_i32_9 : i32) stat(%24#0 : !fir.ref<i32>) errmsg(%42 : !fir.box<!fir.char<1>>)
+ return
+ }
+ func.func private @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, !llvm.ptr)
+ func.func private @_FortranAProgramEndStatement()
+ func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 {
+ %0 = fir.zero_bits !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
+ fir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) fastmath<contract> : (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>) -> ()
+ %1 = mif.init -> i32
+ fir.call @_QQmain() fastmath<contract> : () -> ()
+ fir.call @_FortranAProgramEndStatement() fastmath<contract> : () -> ()
+ %c0_i32 = arith.constant 0 : i32
+ return %c0_i32 : i32
+ }
+}
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V3]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
diff --git a/flang/test/Fir/MIF/init.mlir b/flang/test/Fir/MIF/init.mlir
new file mode 100644
index 0000000000000..0f1177f92427e
--- /dev/null
+++ b/flang/test/Fir/MIF/init.mlir
@@ -0,0 +1,24 @@
+// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git at github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_INIT"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ return
+ }
+ func.func private @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, !llvm.ptr)
+ func.func private @_FortranAProgramEndStatement()
+ func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 {
+ %0 = fir.zero_bits !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
+ fir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) fastmath<contract> : (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>) -> ()
+ %1 = mif.init -> i32
+ fir.call @_QQmain() fastmath<contract> : () -> ()
+ fir.call @_FortranAProgramEndStatement() fastmath<contract> : () -> ()
+ %c0_i32 = arith.constant 0 : i32
+ return %c0_i32 : i32
+ }
+}
+
+
+// CHECK-LABEL: func.func @main
+// CHECK: %[[VAL_0:.*]] = fir.alloca i32
+// CHECK: fir.call @_QMprifPprif_init(%[[VAL_0]]) : (!fir.ref<i32>) -> ()
diff --git a/flang/test/Fir/MIF/num_images.mlir b/flang/test/Fir/MIF/num_images.mlir
new file mode 100644
index 0000000000000..8a337a09a2c72
--- /dev/null
+++ b/flang/test/Fir/MIF/num_images.mlir
@@ -0,0 +1,33 @@
+// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git at github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+ %2:2 = hlfir.declare %1 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %3 = fir.alloca i32 {bindc_name = "team_number", uniq_name = "_QFEteam_number"}
+ %4:2 = hlfir.declare %3 {uniq_name = "_QFEteam_number"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %5 = mif.num_images -> i32
+ hlfir.assign %5 to %2#0 : i32, !fir.ref<i32>
+ %6 = fir.load %4#0 : !fir.ref<i32>
+ %7 = mif.num_images team_number(%6 : i32) -> i32
+ hlfir.assign %7 to %2#0 : i32, !fir.ref<i32>
+ return
+ }
+ func.func private @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, !llvm.ptr)
+ func.func private @_FortranAProgramEndStatement()
+ func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 {
+ %0 = fir.zero_bits !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
+ fir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) fastmath<contract> : (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>) -> ()
+ %1 = mif.init -> i32
+ fir.call @_QQmain() fastmath<contract> : () -> ()
+ fir.call @_FortranAProgramEndStatement() fastmath<contract> : () -> ()
+ %c0_i32 = arith.constant 0 : i32
+ return %c0_i32 : i32
+ }
+}
+
+
+// CHECK-LABEL: func.func @_QQmain
+// CHECK: fir.call @_QMprifPprif_num_images(
+// CHECK: fir.call @_QMprifPprif_num_images_with_team_number(
diff --git a/flang/test/Fir/MIF/sync_all.mlir b/flang/test/Fir/MIF/sync_all.mlir
new file mode 100644
index 0000000000000..76f88dc39c9d0
--- /dev/null
+++ b/flang/test/Fir/MIF/sync_all.mlir
@@ -0,0 +1,56 @@
+// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git at github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_SYNC_ALL"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QFEerror_message) : !fir.ref<!fir.char<1,128>>
+ %c128 = arith.constant 128 : index
+ %2:2 = hlfir.declare %1 typeparams %c128 {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ %3 = fir.alloca i32 {bindc_name = "sync_status", uniq_name = "_QFEsync_status"}
+ %4:2 = hlfir.declare %3 {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ mif.sync_all
+ mif.sync_all stat(%4#0 : !fir.ref<i32>)
+ %5 = fir.embox %2#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ mif.sync_all errmsg(%5 : !fir.box<!fir.char<1,128>>)
+ %6 = fir.embox %2#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ mif.sync_all stat(%4#0 : !fir.ref<i32>) errmsg(%6 : !fir.box<!fir.char<1,128>>)
+ return
+ }
+ fir.global internal @_QFEerror_message : !fir.char<1,128> {
+ %0 = fir.zero_bits !fir.char<1,128>
+ fir.has_value %0 : !fir.char<1,128>
+ }
+ func.func private @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, !llvm.ptr)
+ func.func private @_FortranAProgramEndStatement()
+ func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 {
+ %0 = fir.zero_bits !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
+ fir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) fastmath<contract> : (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>) -> ()
+ %1 = mif.init -> i32
+ fir.call @_QQmain() fastmath<contract> : () -> ()
+ fir.call @_FortranAProgramEndStatement() fastmath<contract> : () -> ()
+ %c0_i32 = arith.constant 0 : i32
+ return %c0_i32 : i32
+ }
+}
+
+
+// CHECK: %[[ERRMSG:.*]]:2 = hlfir.declare %[[E:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+// CHECK: %[[STAT:.*]]:2 = hlfir.declare %[[S:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+
+// CHECK: %[[VAL_1:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: %[[VAL_2:.*]] = fir.absent !fir.ref<i32>
+// CHECK: fir.call @_QMprifPprif_sync_all(%[[VAL_2]], %[[VAL_1]], %[[VAL_1]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+// CHECK: %[[VAL_3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: fir.call @_QMprifPprif_sync_all(%[[STAT]]#0, %[[VAL_3]], %[[VAL_3]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+// CHECK: %[[VAL_4:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+// CHECK: %[[VAL_5:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: %[[VAL_6:.*]] = fir.absent !fir.ref<i32>
+// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+// CHECK: fir.call @_QMprifPprif_sync_all(%[[VAL_6]], %[[VAL_7]], %[[VAL_5]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+// CHECK: %[[VAL_8:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+// CHECK: %[[VAL_9:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+// CHECK: fir.call @_QMprifPprif_sync_all(%[[STAT]]#0, %[[VAL_10]], %[[VAL_9]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
diff --git a/flang/test/Fir/MIF/sync_images.mlir b/flang/test/Fir/MIF/sync_images.mlir
new file mode 100644
index 0000000000000..41719c2c88127
--- /dev/null
+++ b/flang/test/Fir/MIF/sync_images.mlir
@@ -0,0 +1,97 @@
+// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git at github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_SYNC_IMAGES"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QFEerror_message) : !fir.ref<!fir.char<1,128>>
+ %c128 = arith.constant 128 : index
+ %2:2 = hlfir.declare %1 typeparams %c128 {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ %3 = fir.alloca i32 {bindc_name = "me", uniq_name = "_QFEme"}
+ %4:2 = hlfir.declare %3 {uniq_name = "_QFEme"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %5 = fir.alloca i32 {bindc_name = "sync_status", uniq_name = "_QFEsync_status"}
+ %6:2 = hlfir.declare %5 {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %7 = fir.embox %2#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ mif.sync_images stat(%6#0 : !fir.ref<i32>) errmsg(%7 : !fir.box<!fir.char<1,128>>)
+ %8 = fir.embox %2#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ %9 = fir.embox %4#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.sync_images image_set(%9 : !fir.box<i32>) stat(%6#0 : !fir.ref<i32>) errmsg(%8 : !fir.box<!fir.char<1,128>>)
+ %10 = fir.embox %2#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ %11 = fir.address_of(@_QQro.1xi4.0) : !fir.ref<!fir.array<1xi32>>
+ %c1 = arith.constant 1 : index
+ %12 = fir.shape %c1 : (index) -> !fir.shape<1>
+ %13:2 = hlfir.declare %11(%12) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.1xi4.0"} : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<1xi32>>, !fir.ref<!fir.array<1xi32>>)
+ %14 = fir.shape %c1 : (index) -> !fir.shape<1>
+ %15 = fir.embox %13#0(%14) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ mif.sync_images image_set(%15 : !fir.box<!fir.array<1xi32>>) stat(%6#0 : !fir.ref<i32>) errmsg(%10 : !fir.box<!fir.char<1,128>>)
+ mif.sync_images
+ %16 = fir.embox %4#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.sync_images image_set(%16 : !fir.box<i32>)
+ %17 = fir.address_of(@_QQro.1xi4.0) : !fir.ref<!fir.array<1xi32>>
+ %c1_0 = arith.constant 1 : index
+ %18 = fir.shape %c1_0 : (index) -> !fir.shape<1>
+ %19:2 = hlfir.declare %17(%18) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.1xi4.0"} : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<1xi32>>, !fir.ref<!fir.array<1xi32>>)
+ %20 = fir.shape %c1_0 : (index) -> !fir.shape<1>
+ %21 = fir.embox %19#0(%20) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ mif.sync_images image_set(%21 : !fir.box<!fir.array<1xi32>>)
+ return
+ }
+ fir.global internal @_QFEerror_message : !fir.char<1,128> {
+ %0 = fir.zero_bits !fir.char<1,128>
+ fir.has_value %0 : !fir.char<1,128>
+ }
+ fir.global internal @_QQro.1xi4.0(dense<1> : tensor<1xi32>) constant : !fir.array<1xi32>
+ func.func private @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, !llvm.ptr)
+ func.func private @_FortranAProgramEndStatement()
+ func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 {
+ %0 = fir.zero_bits !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
+ fir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) fastmath<contract> : (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>) -> ()
+ %1 = mif.init -> i32
+ fir.call @_QQmain() fastmath<contract> : () -> ()
+ fir.call @_FortranAProgramEndStatement() fastmath<contract> : () -> ()
+ %c0_i32 = arith.constant 0 : i32
+ return %c0_i32 : i32
+ }
+}
+
+ // CHECK: %[[ERRMSG:.*]]:2 = hlfir.declare %[[E:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ // CHECK: %[[ME:.*]]:2 = hlfir.declare %[[M:.*]] {uniq_name = "_QFEme"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ // CHECK: %[[STAT:.*]]:2 = hlfir.declare %[[S:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+
+ // CHECK: %[[VAL_1:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ // CHECK: %[[VAL_2:.*]] = fir.absent !fir.box<!fir.array<?xi32>>
+ // CHECK: %[[VAL_3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_sync_images(%[[VAL_2]], %[[STAT]]#0, %[[VAL_4]], %[[VAL_3]]) : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[VAL_5:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ // CHECK: %[[VAL_6:.*]] = fir.embox %[[ME]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: %[[VAL_7:.*]] = fir.rebox %[[VAL_6]](%[[SHAPE:.*]]) : (!fir.box<i32>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ // CHECK: %[[VAL_8:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_7]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
+ // CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_5]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_sync_images(%[[VAL_9]], %[[STAT]]#0, %[[VAL_10]], %[[VAL_8]]) : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[VAL_11:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ // CHECK: %[[VAL_12:.*]] = fir.embox %[[IMG_SET:.*]]#0(%[[SHAPE_1:.*]]) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ // CHECK: %[[VAL_13:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
+ // CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_11]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_sync_images(%[[VAL_14]], %[[STAT]]#0, %[[VAL_15]], %[[VAL_13]]) : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[VAL_16:.*]] = fir.absent !fir.box<!fir.array<?xi32>>
+ // CHECK: %[[VAL_17:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[VAL_18:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: fir.call @_QMprifPprif_sync_images(%[[VAL_16]], %[[VAL_18]], %[[VAL_17]], %[[VAL_17]]) : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[VAL_19:.*]] = fir.embox %[[ME]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: %[[VAL_20:.*]] = fir.rebox %[[VAL_19]](%[[SHAPE_2:.*]]) : (!fir.box<i32>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ // CHECK: %[[VAL_21:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[VAL_22:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
+ // CHECK: fir.call @_QMprifPprif_sync_images(%[[VAL_23]], %[[VAL_22]], %[[VAL_21]], %[[VAL_21]]) : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[VAL_24:.*]] = fir.embox %[[IMG_SET:.*]]#0(%[[SHAPE_3:.*]]) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ // CHECK: %[[VAL_25:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[VAL_26:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_24]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
+ // CHECK: fir.call @_QMprifPprif_sync_images(%[[VAL_27]], %[[VAL_26]], %[[VAL_25]], %[[VAL_25]]) : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
diff --git a/flang/test/Fir/MIF/sync_memory.mlir b/flang/test/Fir/MIF/sync_memory.mlir
new file mode 100644
index 0000000000000..b3d21d814107f
--- /dev/null
+++ b/flang/test/Fir/MIF/sync_memory.mlir
@@ -0,0 +1,56 @@
+// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git at github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_sync_memory"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QFEerror_message) : !fir.ref<!fir.char<1,128>>
+ %c128 = arith.constant 128 : index
+ %2:2 = hlfir.declare %1 typeparams %c128 {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ %3 = fir.alloca i32 {bindc_name = "sync_status", uniq_name = "_QFEsync_status"}
+ %4:2 = hlfir.declare %3 {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ mif.sync_memory
+ mif.sync_memory stat(%4#0 : !fir.ref<i32>)
+ %5 = fir.embox %2#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ mif.sync_memory errmsg(%5 : !fir.box<!fir.char<1,128>>)
+ %6 = fir.embox %2#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ mif.sync_memory stat(%4#0 : !fir.ref<i32>) errmsg(%6 : !fir.box<!fir.char<1,128>>)
+ return
+ }
+ fir.global internal @_QFEerror_message : !fir.char<1,128> {
+ %0 = fir.zero_bits !fir.char<1,128>
+ fir.has_value %0 : !fir.char<1,128>
+ }
+ func.func private @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, !llvm.ptr)
+ func.func private @_FortranAProgramEndStatement()
+ func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 {
+ %0 = fir.zero_bits !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
+ fir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) fastmath<contract> : (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>) -> ()
+ %1 = mif.init -> i32
+ fir.call @_QQmain() fastmath<contract> : () -> ()
+ fir.call @_FortranAProgramEndStatement() fastmath<contract> : () -> ()
+ %c0_i32 = arith.constant 0 : i32
+ return %c0_i32 : i32
+ }
+}
+
+
+// CHECK: %[[ERRMSG:.*]]:2 = hlfir.declare %[[E:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+// CHECK: %[[STAT:.*]]:2 = hlfir.declare %[[S:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+
+// CHECK: %[[VAL_1:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: %[[VAL_2:.*]] = fir.absent !fir.ref<i32>
+// CHECK: fir.call @_QMprifPprif_sync_memory(%[[VAL_2]], %[[VAL_1]], %[[VAL_1]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+// CHECK: %[[VAL_3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: fir.call @_QMprifPprif_sync_memory(%[[STAT]]#0, %[[VAL_3]], %[[VAL_3]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+// CHECK: %[[VAL_4:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+// CHECK: %[[VAL_5:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: %[[VAL_6:.*]] = fir.absent !fir.ref<i32>
+// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+// CHECK: fir.call @_QMprifPprif_sync_memory(%[[VAL_6]], %[[VAL_7]], %[[VAL_5]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+// CHECK: %[[VAL_8:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+// CHECK: %[[VAL_9:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+// CHECK: fir.call @_QMprifPprif_sync_memory(%[[STAT]]#0, %[[VAL_10]], %[[VAL_9]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
diff --git a/flang/test/Fir/MIF/this_image.mlir b/flang/test/Fir/MIF/this_image.mlir
new file mode 100644
index 0000000000000..e9c5e89cd0093
--- /dev/null
+++ b/flang/test/Fir/MIF/this_image.mlir
@@ -0,0 +1,27 @@
+// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git at github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+ %2:2 = hlfir.declare %1 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %3 = mif.this_image -> i32
+ hlfir.assign %3 to %2#0 : i32, !fir.ref<i32>
+ return
+ }
+ func.func private @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, !llvm.ptr)
+ func.func private @_FortranAProgramEndStatement()
+ func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 {
+ %0 = fir.zero_bits !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
+ fir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) fastmath<contract> : (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>) -> ()
+ %1 = mif.init -> i32
+ fir.call @_QQmain() fastmath<contract> : () -> ()
+ fir.call @_FortranAProgramEndStatement() fastmath<contract> : () -> ()
+ %c0_i32 = arith.constant 0 : i32
+ return %c0_i32 : i32
+ }
+}
+
+
+// CHECK-LABEL: func.func @_QQmain
+// CHECK: fir.call @_QMprifPprif_this_image_no_coarray(
diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir
index 195e5ad7f9dc8..875e3f75f1ca5 100644
--- a/flang/test/Fir/basic-program.fir
+++ b/flang/test/Fir/basic-program.fir
@@ -131,6 +131,7 @@ func.func @_QQmain() {
// PASSES-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
// PASSES-NEXT: 'func.func' Pipeline
// PASSES-NEXT: SetRuntimeCallAttributes
+// PASSES-NEXT: MIFOpConversion
// PASSES-NEXT: BoxedProcedurePass
// PASSES-NEXT: AddAliasTags
diff --git a/flang/test/Lower/Coarray/co_broadcast.f90 b/flang/test/Lower/Coarray/co_broadcast.f90
deleted file mode 100644
index be7fdcb99252c..0000000000000
--- a/flang/test/Lower/Coarray/co_broadcast.f90
+++ /dev/null
@@ -1,92 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
-
-program test_co_broadcast
- integer :: i, array_i(2), status
- real :: r, array_r(2)
- double precision :: d, array_d(2)
- complex :: c, array_c(2)
- character(len=1) :: message
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(i, source_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<complex<f32>>) -> !fir.box<complex<f32>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<complex<f32>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V2]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(c, source_image=1, stat=status)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(d, source_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(r, source_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(array_i, source_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.shape<1>) -> !fir.box<!fir.array<2xcomplex<f32>>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xcomplex<f32>>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(array_c, source_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(array_d, source_image=1, stat=status)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(array_r, source_image=1, stat= status, errmsg=message)
-
-end program
diff --git a/flang/test/Lower/Coarray/co_max.f90 b/flang/test/Lower/Coarray/co_max.f90
deleted file mode 100644
index 56d863389d02b..0000000000000
--- a/flang/test/Lower/Coarray/co_max.f90
+++ /dev/null
@@ -1,112 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
-
-program test_co_max
- integer :: i, array_i(2), status
- real :: r, array_r(2)
- double precision :: d, array_d(2)
- character(len=1) :: c, array_c(2), message
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(i)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.char<1>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max_character(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(c)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(d)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(r)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(i, result_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(d, result_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(r, result_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(array_i)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2x!fir.char<1>>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max_character(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(array_c, result_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(array_d, result_image=1, stat=status)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(array_r, result_image=1, stat= status, errmsg=message)
-
-end program
diff --git a/flang/test/Lower/Coarray/co_min.f90 b/flang/test/Lower/Coarray/co_min.f90
deleted file mode 100644
index dde878bb14dbf..0000000000000
--- a/flang/test/Lower/Coarray/co_min.f90
+++ /dev/null
@@ -1,112 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
-
-program test_co_min
- integer :: i, array_i(2), status
- real :: r, array_r(2)
- double precision :: d, array_d(2)
- character(len=1) :: c, array_c(2), message
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(i)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.char<1>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min_character(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(c)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(d)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(r)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(i, result_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(d, result_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(r, result_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(array_i)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2x!fir.char<1>>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min_character(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(array_c, result_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(array_d, result_image=1, stat=status)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(array_r, result_image=1, stat= status, errmsg=message)
-
-end program
diff --git a/flang/test/Lower/Coarray/co_sum.f90 b/flang/test/Lower/Coarray/co_sum.f90
deleted file mode 100644
index 2932b54c60a8d..0000000000000
--- a/flang/test/Lower/Coarray/co_sum.f90
+++ /dev/null
@@ -1,122 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
-
-program test_co_sum
- integer :: i, array_i(2), status
- real :: r, array_r(2)
- double precision :: d, array_d(2)
- complex :: c, array_c(2)
- character(len=1) :: message
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(i)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<complex<f32>>) -> !fir.box<complex<f32>>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<complex<f32>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(c)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(d)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(r)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(i, result_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C]]#0 : (!fir.ref<complex<f32>>) -> !fir.box<complex<f32>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<complex<f32>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V2]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(c, result_image=1, stat=status)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(d, result_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(r, result_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(array_i)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.shape<1>) -> !fir.box<!fir.array<2xcomplex<f32>>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xcomplex<f32>>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(array_c, result_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(array_d, result_image=1, stat=status)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(array_r, result_image=1, stat= status, errmsg=message)
-
-end program
diff --git a/flang/test/Lower/Coarray/sync_all.f90 b/flang/test/Lower/Coarray/sync_all.f90
deleted file mode 100644
index c2c12d8cdf237..0000000000000
--- a/flang/test/Lower/Coarray/sync_all.f90
+++ /dev/null
@@ -1,37 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY
-! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY
-
-program test_sync_all
- implicit none
- ! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable.
-
- ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
- ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
- integer sync_status
- character(len=128) :: error_message
-
- ! COARRAY: %[[VAL_3:.*]] = fir.absent !fir.ref<i32>
- ! COARRAY: %[[VAL_4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_5:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync all
-
- ! COARRAY: %[[VAL_6:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_7:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[STAT]]#0, %[[VAL_6]], %[[VAL_7]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync all(stat=sync_status)
-
- ! COARRAY: %[[VAL_8:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
- ! COARRAY: %[[VAL_9:.*]] = fir.absent !fir.ref<i32>
- ! COARRAY: %[[VAL_10:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_11:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[VAL_9]], %[[VAL_11]], %[[VAL_10]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync all( errmsg=error_message)
-
- ! COARRAY: %[[VAL_12:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
- ! COARRAY: %[[VAL_13:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[STAT]]#0, %[[VAL_14]], %[[VAL_13]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync all(stat=sync_status, errmsg=error_message)
-
-end program test_sync_all
diff --git a/flang/test/Lower/Coarray/sync_images.f90 b/flang/test/Lower/Coarray/sync_images.f90
deleted file mode 100644
index 0224bf235c36c..0000000000000
--- a/flang/test/Lower/Coarray/sync_images.f90
+++ /dev/null
@@ -1,62 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY
-! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY
-
-program test_sync_images
- implicit none
- ! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable.
-
- ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
- ! COARRAY: %[[ME:.*]]:2 = hlfir.declare %[[VAL_3:.*]] {uniq_name = "_QFEme"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
- ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
- integer sync_status, me
- character(len=128) :: error_message
-
- ! COARRAY: %[[VAL_1:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
- ! COARRAY: %[[VAL_2:.*]] = fir.absent !fir.box<!fir.array<?xi32>>
- ! COARRAY: %[[VAL_3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_4:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_2]], %[[STAT]]#0, %[[VAL_4]], %[[VAL_3]]) fastmath<contract> : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync images(*, stat=sync_status, errmsg=error_message)
-
- ! COARRAY: %[[VAL_5:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
- ! COARRAY: %[[VAL_6:.*]] = fir.embox %[[ME]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! COARRAY: %[[VAL_7:.*]] = fir.rebox %[[VAL_6]](%[[SHAPE:.*]]) : (!fir.box<i32>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
- ! COARRAY: %[[VAL_8:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_9:.*]] = fir.convert %[[VAL_7]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
- ! COARRAY: %[[VAL_10:.*]] = fir.convert %[[VAL_5]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_9]], %[[STAT]]#0, %[[VAL_10]], %[[VAL_8]]) fastmath<contract> : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync images(me, stat=sync_status, errmsg=error_message)
-
- ! COARRAY: %[[VAL_11:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
- ! COARRAY: %[[VAL_12:.*]] = fir.embox %[[IMG_SET:.*]]#0(%[[SHAPE_1:.*]]) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
- ! COARRAY: %[[VAL_13:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
- ! COARRAY: %[[VAL_15:.*]] = fir.convert %[[VAL_11]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_14]], %[[STAT]]#0, %[[VAL_15]], %[[VAL_13]]) fastmath<contract> : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync images([1], stat=sync_status, errmsg=error_message)
-
- ! COARRAY: %[[VAL_17:.*]] = fir.absent !fir.ref<i32>
- ! COARRAY: %[[VAL_18:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_19:.*]] = fir.absent !fir.box<!fir.array<?xi32>>
- ! COARRAY: %[[VAL_20:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_19]], %[[VAL_17]], %[[VAL_18]], %[[VAL_20]]) fastmath<contract> : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync images(*)
-
- ! COARRAY: %[[VAL_23:.*]] = fir.absent !fir.ref<i32>
- ! COARRAY: %[[VAL_24:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_21:.*]] = fir.embox %[[ME]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! COARRAY: %[[VAL_22:.*]] = fir.rebox %[[VAL_21]](%[[SHAPE_2:.*]]) : (!fir.box<i32>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
- ! COARRAY: %[[VAL_25:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_26:.*]] = fir.convert %[[VAL_22]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
- ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_26]], %[[VAL_23]], %[[VAL_24]], %[[VAL_25]]) fastmath<contract> : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync images(me)
-
- ! COARRAY: %[[VAL_28:.*]] = fir.absent !fir.ref<i32>
- ! COARRAY: %[[VAL_29:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_27:.*]] = fir.embox %[[IMG_SET:.*]]#0(%[[SHAPE_3:.*]]) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
- ! COARRAY: %[[VAL_30:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_31:.*]] = fir.convert %[[VAL_27]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
- ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_31]], %[[VAL_28]], %[[VAL_29]], %[[VAL_30]]) fastmath<contract> : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync images([1])
-
-end program test_sync_images
diff --git a/flang/test/Lower/Coarray/sync_memory.f90 b/flang/test/Lower/Coarray/sync_memory.f90
deleted file mode 100644
index 773cb6fe4efb7..0000000000000
--- a/flang/test/Lower/Coarray/sync_memory.f90
+++ /dev/null
@@ -1,37 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY
-! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY
-
-program test_sync_memory
- implicit none
- ! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable.
-
- ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
- ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
- integer sync_status
- character(len=128) :: error_message
-
- ! COARRAY: %[[VAL_3:.*]] = fir.absent !fir.ref<i32>
- ! COARRAY: %[[VAL_4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_5:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_memory(%[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync memory
-
- ! COARRAY: %[[VAL_6:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_7:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_memory(%[[STAT]]#0, %[[VAL_6]], %[[VAL_7]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync memory(stat=sync_status)
-
- ! COARRAY: %[[VAL_8:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
- ! COARRAY: %[[VAL_9:.*]] = fir.absent !fir.ref<i32>
- ! COARRAY: %[[VAL_10:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_11:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_memory(%[[VAL_9]], %[[VAL_11]], %[[VAL_10]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync memory( errmsg=error_message)
-
- ! COARRAY: %[[VAL_12:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
- ! COARRAY: %[[VAL_13:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_memory(%[[STAT]]#0, %[[VAL_14]], %[[VAL_13]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync memory(stat=sync_status, errmsg=error_message)
-
-end program test_sync_memory
diff --git a/flang/test/Lower/MIF/co_broadcast.f90 b/flang/test/Lower/MIF/co_broadcast.f90
new file mode 100644
index 0000000000000..5a2860cf9ce18
--- /dev/null
+++ b/flang/test/Lower/MIF/co_broadcast.f90
@@ -0,0 +1,57 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
+
+program test_co_broadcast
+ integer :: i, array_i(2), status
+ real :: r, array_r(2)
+ double precision :: d, array_d(2)
+ complex :: c, array_c(2)
+ character(len=1) :: message
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: mif.co_broadcast %[[V1]] : !fir.box<i32> source(%[[C1_i32:.*]] : i32)
+ call co_broadcast(i, source_image=1)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<complex<f32>>) -> !fir.box<complex<f32>>
+ ! CHECK: mif.co_broadcast %[[V1]] : !fir.box<complex<f32>> source(%[[C1_i32:.*]] : i32) stat(%[[STATUS:.*]]#0 : !fir.ref<i32>)
+ call co_broadcast(c, source_image=1, stat=status)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_broadcast %[[V1]] : !fir.box<f64> source(%[[C1_i32:.*]] : i32) stat(%[[STATUS]]#0 : !fir.ref<i32>) errmsg(%[[V2]] : !fir.box<!fir.char<1>>)
+ call co_broadcast(d, source_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_broadcast %[[V1]] : !fir.box<f32> source(%[[C1_i32:.*]] : i32) stat(%[[STATUS]]#0 : !fir.ref<i32>) errmsg(%[[V2]] : !fir.box<!fir.char<1>>)
+ call co_broadcast(r, source_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ ! CHECK: mif.co_broadcast %[[V1]] : !fir.box<!fir.array<2xi32>> source(%[[C1_i32:.*]] : i32)
+ call co_broadcast(array_i, source_image=1)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.shape<1>) -> !fir.box<!fir.array<2xcomplex<f32>>>
+ ! CHECK: mif.co_broadcast %[[V1]] : !fir.box<!fir.array<2xcomplex<f32>>> source(%[[C1_i32:.*]] : i32)
+ call co_broadcast(array_c, source_image=1)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ ! CHECK: mif.co_broadcast %[[V1]] : !fir.box<!fir.array<2xf64>> source(%[[C1_i32:.*]] : i32) stat(%[[STATUS]]#0 : !fir.ref<i32>)
+ call co_broadcast(array_d, source_image=1, stat=status)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_broadcast %[[V1]] : !fir.box<!fir.array<2xf32>> source(%[[C1_i32:.*]] : i32) stat(%[[STATUS]]#0 : !fir.ref<i32>) errmsg(%[[V2]] : !fir.box<!fir.char<1>>)
+ call co_broadcast(array_r, source_image=1, stat= status, errmsg=message)
+
+end program
diff --git a/flang/test/Lower/MIF/co_max.f90 b/flang/test/Lower/MIF/co_max.f90
new file mode 100644
index 0000000000000..77d063148dc43
--- /dev/null
+++ b/flang/test/Lower/MIF/co_max.f90
@@ -0,0 +1,60 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
+
+program test_co_max
+ integer :: i, array_i(2), status
+ real :: r, array_r(2)
+ double precision :: d, array_d(2)
+ character(len=1) :: c, array_c(2), message
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: mif.co_max %[[V1]] : !fir.box<i32>
+ call co_max(i)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_max %[[V1]] : !fir.box<!fir.char<1>>
+ call co_max(c)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ ! CHECK: mif.co_max %[[V1]] : !fir.box<f64>
+ call co_max(d)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: mif.co_max %[[V1]] : !fir.box<f32>
+ call co_max(r)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: mif.co_max %[[V1]] : !fir.box<i32> result(%[[C1_i32:.*]] : i32)
+ call co_max(i, result_image=1)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_max %[[V1]] : !fir.box<f64> result(%[[C1_i32:.*]] : i32) stat(%[[STATUS:.*]]#0 : !fir.ref<i32>) errmsg(%[[V2]] : !fir.box<!fir.char<1>>)
+ call co_max(d, result_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_max %[[V1]] : !fir.box<f32> result(%[[C1_i32:.*]] : i32) stat(%[[STATUS]]#0 : !fir.ref<i32>) errmsg(%[[V2]] : !fir.box<!fir.char<1>>)
+ call co_max(r, result_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ ! CHECK: mif.co_max %[[V1]] : !fir.box<!fir.array<2xi32>>
+ call co_max(array_i)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
+ ! CHECK: mif.co_max %[[V1]] : !fir.box<!fir.array<2x!fir.char<1>>> result(%[[C1_i32:.*]] : i32)
+ call co_max(array_c, result_image=1)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ ! CHECK: mif.co_max %[[V1]] : !fir.box<!fir.array<2xf64>> result(%[[C1_i32:.*]] : i32) stat(%[[STATUS]]#0 : !fir.ref<i32>)
+ call co_max(array_d, result_image=1, stat=status)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_max %[[V1]] : !fir.box<!fir.array<2xf32>> result(%[[C1_i32:.*]] : i32) stat(%[[STATUS]]#0 : !fir.ref<i32>) errmsg(%[[V2]] : !fir.box<!fir.char<1>>)
+ call co_max(array_r, result_image=1, stat= status, errmsg=message)
+
+end program
diff --git a/flang/test/Lower/MIF/co_min.f90 b/flang/test/Lower/MIF/co_min.f90
new file mode 100644
index 0000000000000..b1dd3b3f12b51
--- /dev/null
+++ b/flang/test/Lower/MIF/co_min.f90
@@ -0,0 +1,60 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
+
+program test_co_min
+ integer :: i, array_i(2), status
+ real :: r, array_r(2)
+ double precision :: d, array_d(2)
+ character(len=1) :: c, array_c(2), message
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: mif.co_min %[[V1]] : !fir.box<i32>
+ call co_min(i)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_min %[[V1]] : !fir.box<!fir.char<1>>
+ call co_min(c)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ ! CHECK: mif.co_min %[[V1]] : !fir.box<f64>
+ call co_min(d)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: mif.co_min %[[V1]] : !fir.box<f32>
+ call co_min(r)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: mif.co_min %[[V1]] : !fir.box<i32> result(%[[C1_i32:.*]] : i32)
+ call co_min(i, result_image=1)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_min %[[V1]] : !fir.box<f64> result(%[[C1_i32:.*]] : i32) stat(%[[STATUS:.*]]#0 : !fir.ref<i32>) errmsg(%[[V2]] : !fir.box<!fir.char<1>>)
+ call co_min(d, result_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_min %[[V1]] : !fir.box<f32> result(%[[C1_i32:.*]] : i32) stat(%[[STATUS]]#0 : !fir.ref<i32>) errmsg(%[[V2]] : !fir.box<!fir.char<1>>)
+ call co_min(r, result_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ ! CHECK: mif.co_min %[[V1]] : !fir.box<!fir.array<2xi32>>
+ call co_min(array_i)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
+ ! CHECK: mif.co_min %[[V1]] : !fir.box<!fir.array<2x!fir.char<1>>> result(%[[C1_i32:.*]] : i32)
+ call co_min(array_c, result_image=1)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ ! CHECK: mif.co_min %[[V1]] : !fir.box<!fir.array<2xf64>> result(%[[C1_i32:.*]] : i32) stat(%[[STATUS]]#0 : !fir.ref<i32>)
+ call co_min(array_d, result_image=1, stat=status)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_min %[[V1]] : !fir.box<!fir.array<2xf32>> result(%[[C1_i32:.*]] : i32) stat(%[[STATUS]]#0 : !fir.ref<i32>) errmsg(%[[V2]] : !fir.box<!fir.char<1>>)
+ call co_min(array_r, result_image=1, stat= status, errmsg=message)
+
+end program
diff --git a/flang/test/Lower/MIF/co_sum.f90 b/flang/test/Lower/MIF/co_sum.f90
new file mode 100644
index 0000000000000..5c76ea54b66fa
--- /dev/null
+++ b/flang/test/Lower/MIF/co_sum.f90
@@ -0,0 +1,51 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
+
+program test_co_sum
+ integer :: i, array_i(2), status
+ real :: r, array_r(2)
+ double precision :: d, array_d(2)
+ character(len=1) :: c, array_c(2), message
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: mif.co_sum %[[V1]] : !fir.box<i32>
+ call co_sum(i)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ ! CHECK: mif.co_sum %[[V1]] : !fir.box<f64>
+ call co_sum(d)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: mif.co_sum %[[V1]] : !fir.box<f32>
+ call co_sum(r)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: mif.co_sum %[[V1]] : !fir.box<i32> result(%[[C1_i32:.*]] : i32)
+ call co_sum(i, result_image=1)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_sum %[[V1]] : !fir.box<f64> result(%[[C1_i32:.*]] : i32) stat(%[[STATUS:.*]]#0 : !fir.ref<i32>) errmsg(%[[V2]] : !fir.box<!fir.char<1>>)
+ call co_sum(d, result_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_sum %[[V1]] : !fir.box<f32> result(%[[C1_i32:.*]] : i32) stat(%[[STATUS]]#0 : !fir.ref<i32>) errmsg(%[[V2]] : !fir.box<!fir.char<1>>)
+ call co_sum(r, result_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ ! CHECK: mif.co_sum %[[V1]] : !fir.box<!fir.array<2xi32>>
+ call co_sum(array_i)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ ! CHECK: mif.co_sum %[[V1]] : !fir.box<!fir.array<2xf64>> result(%[[C1_i32:.*]] : i32) stat(%[[STATUS]]#0 : !fir.ref<i32>)
+ call co_sum(array_d, result_image=1, stat=status)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_sum %[[V1]] : !fir.box<!fir.array<2xf32>> result(%[[C1_i32:.*]] : i32) stat(%[[STATUS]]#0 : !fir.ref<i32>) errmsg(%[[V2]] : !fir.box<!fir.char<1>>)
+ call co_sum(array_r, result_image=1, stat= status, errmsg=message)
+
+end program
diff --git a/flang/test/Lower/Coarray/coarray-init.f90 b/flang/test/Lower/MIF/coarray-init.f90
similarity index 57%
rename from flang/test/Lower/Coarray/coarray-init.f90
rename to flang/test/Lower/MIF/coarray-init.f90
index 055bc0fc4da72..e3544736df284 100644
--- a/flang/test/Lower/Coarray/coarray-init.f90
+++ b/flang/test/Lower/MIF/coarray-init.f90
@@ -7,5 +7,5 @@ program test_init
! ALL-LABEL: func.func @main
! ALL: fir.call @_FortranAProgramStart
-! COARRAY: fir.call @_QMprifPprif_init(%[[ARG:.*]]) fastmath<contract> : (!fir.ref<i32>) -> ()
-! NOCOARRAY-NOT: fir.call @_QMprifPprif_init(%[[ARG:.*]]) fastmath<contract> : (!fir.ref<i32>) -> ()
+! COARRAY: mif.init -> i32
+! NOCOARRAY-NOT: mif.init
diff --git a/flang/test/Lower/Coarray/num_images.f90 b/flang/test/Lower/MIF/num_images.f90
similarity index 61%
rename from flang/test/Lower/Coarray/num_images.f90
rename to flang/test/Lower/MIF/num_images.f90
index ebfce5db0dbfb..ba28fdf56793f 100644
--- a/flang/test/Lower/Coarray/num_images.f90
+++ b/flang/test/Lower/MIF/num_images.f90
@@ -6,13 +6,13 @@ program test
integer :: team_number
type(team_type) :: team
- ! CHECK: fir.call @_QMprifPprif_num_images
+ ! CHECK: mif.num_images -> i32
i = num_images()
- ! CHECK: fir.call @_QMprifPprif_num_images_with_team_number
+ ! CHECK: mif.num_images team_number(%[[TEAM_NUMBER:.*]] : {{.*}}) -> i32
i = num_images(TEAM_NUMBER=team_number)
- ! CHECK: fir.call @_QMprifPprif_num_images_with_team
+ ! CHECK: mif.num_images team(%[[TEAM:.*]]#0 : {{.*}}) -> i32
i = num_images(TEAM=team)
end program
diff --git a/flang/test/Lower/MIF/sync_all.f90 b/flang/test/Lower/MIF/sync_all.f90
new file mode 100644
index 0000000000000..c2c2a41186da2
--- /dev/null
+++ b/flang/test/Lower/MIF/sync_all.f90
@@ -0,0 +1,27 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY
+! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY
+
+program test_sync_all
+ implicit none
+ ! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable.
+
+ ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ integer sync_status
+ character(len=128) :: error_message
+
+ ! COARRAY: mif.sync_all
+ sync all
+
+ ! COARRAY: mif.sync_all stat(%[[STAT]]#0 : !fir.ref<i32>)
+ sync all(stat=sync_status)
+
+ ! COARRAY: %[[VAL_1:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: mif.sync_all errmsg(%[[VAL_1]] : !fir.box<!fir.char<1,128>>)
+ sync all( errmsg=error_message)
+
+ ! COARRAY: %[[VAL_2:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: mif.sync_all stat(%[[STAT]]#0 : !fir.ref<i32>) errmsg(%[[VAL_2]] : !fir.box<!fir.char<1,128>>)
+ sync all(stat=sync_status, errmsg=error_message)
+
+end program test_sync_all
diff --git a/flang/test/Lower/MIF/sync_images.f90 b/flang/test/Lower/MIF/sync_images.f90
new file mode 100644
index 0000000000000..b9a901568dfc3
--- /dev/null
+++ b/flang/test/Lower/MIF/sync_images.f90
@@ -0,0 +1,39 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY
+! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY
+
+program test_sync_images
+ implicit none
+ ! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable.
+
+ ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ ! COARRAY: %[[ME:.*]]:2 = hlfir.declare %[[VAL_3:.*]] {uniq_name = "_QFEme"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ integer sync_status, me
+ character(len=128) :: error_message
+
+ ! COARRAY: %[[VAL_1:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: mif.sync_images stat(%[[STAT]]#0 : !fir.ref<i32>) errmsg(%[[VAL_1]] : !fir.box<!fir.char<1,128>>)
+ sync images(*, stat=sync_status, errmsg=error_message)
+
+ ! COARRAY: %[[VAL_2:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: %[[VAL_3:.*]] = fir.embox %[[ME]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! COARRAY: mif.sync_images image_set(%[[VAL_3]] : !fir.box<i32>) stat(%[[STAT]]#0 : !fir.ref<i32>) errmsg(%[[VAL_2]] : !fir.box<!fir.char<1,128>>)
+ sync images(me, stat=sync_status, errmsg=error_message)
+
+ ! COARRAY: %[[VAL_4:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: %[[VAL_5:.*]] = fir.embox %[[IMG_SET:.*]]#0(%[[SHAPE_1:.*]]) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ ! COARRAY: mif.sync_images image_set(%[[VAL_5]] : !fir.box<!fir.array<1xi32>>) stat(%[[STAT]]#0 : !fir.ref<i32>) errmsg(%[[VAL_4]] : !fir.box<!fir.char<1,128>>)
+ sync images([1], stat=sync_status, errmsg=error_message)
+
+ ! COARRAY: mif.sync_images
+ sync images(*)
+
+ ! COARRAY: %[[VAL_6:.*]] = fir.embox %[[ME]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! COARRAY: mif.sync_images image_set(%[[VAL_6]] : !fir.box<i32>)
+ sync images(me)
+
+ ! COARRAY: %[[VAL_7:.*]] = fir.embox %[[IMG_SET:.*]]#0(%[[SHAPE_3:.*]]) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ ! COARRAY: mif.sync_images image_set(%[[VAL_7]] : !fir.box<!fir.array<1xi32>>)
+ sync images([1])
+
+end program test_sync_images
diff --git a/flang/test/Lower/MIF/sync_memory.f90 b/flang/test/Lower/MIF/sync_memory.f90
new file mode 100644
index 0000000000000..3d44256cfb2c2
--- /dev/null
+++ b/flang/test/Lower/MIF/sync_memory.f90
@@ -0,0 +1,27 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY
+! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY
+
+program test_sync_memory
+ implicit none
+ ! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable.
+
+ ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ integer sync_status
+ character(len=128) :: error_message
+
+ ! COARRAY: mif.sync_memory
+ sync memory
+
+ ! COARRAY: mif.sync_memory stat(%[[STAT]]#0 : !fir.ref<i32>)
+ sync memory(stat=sync_status)
+
+ ! COARRAY: %[[VAL_1:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: mif.sync_memory errmsg(%[[VAL_1]] : !fir.box<!fir.char<1,128>>)
+ sync memory( errmsg=error_message)
+
+ ! COARRAY: %[[VAL_2:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: mif.sync_memory stat(%[[STAT]]#0 : !fir.ref<i32>) errmsg(%[[VAL_2]] : !fir.box<!fir.char<1,128>>)
+ sync memory(stat=sync_status, errmsg=error_message)
+
+end program test_sync_memory
diff --git a/flang/test/Lower/Coarray/this_image.f90 b/flang/test/Lower/MIF/this_image.f90
similarity index 64%
rename from flang/test/Lower/Coarray/this_image.f90
rename to flang/test/Lower/MIF/this_image.f90
index 143504b5f922c..57d169aad280e 100644
--- a/flang/test/Lower/Coarray/this_image.f90
+++ b/flang/test/Lower/MIF/this_image.f90
@@ -5,10 +5,10 @@ program test
integer :: i
type(team_type) :: team
- ! CHECK: fir.call @_QMprifPprif_this_image_no_coarray
+ ! CHECK: mif.this_image -> i32
i = this_image()
- ! CHECK: fir.call @_QMprifPprif_this_image_no_coarray
+ ! CHECK: mif.this_image team(%[[TEAM:.*]] : {{.*}}) -> i32
i = this_image(TEAM=team)
end program
More information about the flang-commits
mailing list