[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
Thu Oct 9 01:54:23 PDT 2025


https://github.com/JDPailleux updated https://github.com/llvm/llvm-project/pull/161179

>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 01/11] [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 02/11] [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

>From bbf6263b78f554617df8a666518d071afc7c7029 Mon Sep 17 00:00:00 2001
From: Jean-Didier PAILLEUX <jean-di.pailleux at outlook.com>
Date: Wed, 1 Oct 2025 16:16:29 +0200
Subject: [PATCH 03/11] Update
 flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td

Co-authored-by: Dan Bonachea <dobonachea at lbl.gov>
---
 flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
index 115ef0c65a76f..a9b34647ca48d 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -184,8 +184,7 @@ 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.
+    The co_broadcast operation broadcasts a value from one image to the other images.
   }];
 
   let arguments = (ins fir_BoxType:$a, 

>From 82cc1c8e959ee621c70237a11c054018c0ddc74a Mon Sep 17 00:00:00 2001
From: Jean-Didier PAILLEUX <jean-di.pailleux at outlook.com>
Date: Wed, 1 Oct 2025 16:16:39 +0200
Subject: [PATCH 04/11] Update flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp

Co-authored-by: Dan Bonachea <dobonachea at lbl.gov>
---
 flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
index 21803a03509e3..c75b96415da88 100644
--- a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
+++ b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
@@ -95,7 +95,7 @@ llvm::LogicalResult mif::CoMaxOp::verify() {
     elemTy = seqTy.getElementType();
 
   if (!fir::isa_real(elemTy) && !fir::isa_integer(elemTy) &&
-      !fir::isa_complex(elemTy) && !fir::isa_char(elemTy))
+      !fir::isa_char(elemTy))
     return emitOpError("`A` shall be of type integer, real or character.");
   return mlir::success();
 }

>From 84aa9e58856c255caf7c43a70b92bcc36921b1ef Mon Sep 17 00:00:00 2001
From: Jean-Didier PAILLEUX <jean-di.pailleux at outlook.com>
Date: Wed, 1 Oct 2025 16:17:33 +0200
Subject: [PATCH 05/11] Update flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp

Co-authored-by: Dan Bonachea <dobonachea at lbl.gov>
---
 flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
index c75b96415da88..b7839bc667280 100644
--- a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
+++ b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
@@ -111,7 +111,7 @@ llvm::LogicalResult mif::CoMinOp::verify() {
     elemTy = seqTy.getElementType();
 
   if (!fir::isa_real(elemTy) && !fir::isa_integer(elemTy) &&
-      !fir::isa_complex(elemTy) && !fir::isa_char(elemTy))
+      !fir::isa_char(elemTy))
     return emitOpError("`A` shall be of type integer, real or character.");
   return mlir::success();
 }

>From c621e2d85fb3248c4aa2558f54fabf76d4aba095 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Wed, 1 Oct 2025 16:13:35 +0200
Subject: [PATCH 06/11] Applying feedback

- Add decoration MemWrite and MemRead
- Remote useless --split-file flag
- Remote useless Start/End/Main in the conversion tests
- Replace PRIF macro type by static functions
- Remove unecessary things
---
 .../include/flang/Optimizer/Dialect/FIRType.h |  3 +
 .../flang/Optimizer/Dialect/MIF/MIFOps.td     | 44 ++++-----
 .../Optimizer/Transforms/MIFOpConversion.h    | 18 +---
 flang/lib/Optimizer/Dialect/FIRType.cpp       |  7 ++
 flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp    | 10 +-
 .../Optimizer/Transforms/MIFOpConversion.cpp  | 94 +++++++++++--------
 flang/test/Fir/MIF/co_broadcast.mlir          | 13 +--
 flang/test/Fir/MIF/co_max.mlir                | 13 +--
 flang/test/Fir/MIF/co_min.mlir                | 13 +--
 flang/test/Fir/MIF/co_sum.mlir                | 13 +--
 flang/test/Fir/MIF/num_images.mlir            | 13 +--
 flang/test/Fir/MIF/sync_all.mlir              | 13 +--
 flang/test/Fir/MIF/sync_images.mlir           | 14 +--
 flang/test/Fir/MIF/sync_memory.mlir           | 13 +--
 flang/test/Fir/MIF/this_image.mlir            | 13 +--
 15 files changed, 98 insertions(+), 196 deletions(-)

diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h
index 6188c4460dadd..3b11b8f6c8ab7 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRType.h
+++ b/flang/include/flang/Optimizer/Dialect/FIRType.h
@@ -53,6 +53,9 @@ class BaseBoxType : public mlir::Type {
   /// Unwrap element type from fir.heap, fir.ptr and fir.array.
   mlir::Type unwrapInnerType() const;
 
+  // Get the element type or the fir.array
+  mlir::Type getElementOrSequenceType() const;
+
   /// Is this the box for an assumed rank?
   bool isAssumedRank() const;
 
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
index a9b34647ca48d..ca0dfd27df339 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -17,10 +17,6 @@
 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>;
@@ -41,8 +37,7 @@ def mif_InitOp : mif_Op<"init", []> {
 // Image Queries
 //===----------------------------------------------------------------------===//
 
-def mif_NumImagesOp
-    : mif_Op<"num_images", [NoMemoryEffect, AttrSizedOperandSegments]> {
+def mif_NumImagesOp : mif_Op<"num_images", [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
@@ -75,8 +70,7 @@ def mif_NumImagesOp
   }];
 }
 
-def mif_ThisImageOp
-    : mif_Op<"this_image", [NoMemoryEffect, AttrSizedOperandSegments]> {
+def mif_ThisImageOp : mif_Op<"this_image", [AttrSizedOperandSegments]> {
   let summary = "Determine the image index of the current image";
   let description = [{
     Arguments:
@@ -104,7 +98,7 @@ def mif_ThisImageOp
   }];
 
   let arguments = (ins Optional<fir_BoxType>:$coarray,
-                       Optional<AnyInteger>:$dim, Optional<fir_BoxType>:$team);
+      Optional<AnyInteger>:$dim, Optional<AnyRefOrBoxType>:$team);
   let results = (outs I32:$res);
 
   let builders = [OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$team)>,
@@ -187,10 +181,10 @@ def mif_CoBroadcastOp : mif_Op<"co_broadcast", [AttrSizedOperandSegments,
     The co_broadcast operation broadcasts a value from one image to the other images.
   }];
 
-  let arguments = (ins fir_BoxType:$a, 
-                       AnyIntegerType:$source_image,
-                       Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
-                       Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+  let arguments = (ins Arg<fir_BoxType, "", [MemRead, MemWrite]>:$a,
+      AnyIntegerType:$source_image,
+      Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+      Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
 
   let assemblyFormat = [{
     $a `:` qualified(type($a)) 
@@ -209,10 +203,10 @@ def mif_CoMaxOp
     across images.
   }];
 
-  let arguments = (ins fir_BoxType:$a, 
-                       Optional<AnyIntegerType>:$result_image,
-                       Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
-                       Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+  let arguments = (ins Arg<fir_BoxType, "", [MemRead, MemWrite]>:$a,
+      Optional<AnyIntegerType>:$result_image,
+      Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+      Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
 
   let hasVerifier = 1;
   let assemblyFormat = [{
@@ -232,10 +226,10 @@ def mif_CoMinOp
     across images.
   }];
 
-  let arguments = (ins fir_BoxType:$a,
-                       Optional<AnyIntegerType>:$result_image,
-                       Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
-                       Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+  let arguments = (ins Arg<fir_BoxType, "", [MemRead, MemWrite]>:$a,
+      Optional<AnyIntegerType>:$result_image,
+      Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+      Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
 
   let hasVerifier = 1;
   let assemblyFormat = [{
@@ -255,10 +249,10 @@ def mif_CoSumOp
     across images.
   }];
 
-  let arguments = (ins fir_BoxType:$a, 
-                       Optional<AnyIntegerType>:$result_image,
-                       Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
-                       Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+  let arguments = (ins Arg<fir_BoxType, "", [MemRead, MemWrite]>:$a,
+      Optional<AnyIntegerType>:$result_image,
+      Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+      Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
 
   let hasVerifier = 1;
   let assemblyFormat = [{
diff --git a/flang/include/flang/Optimizer/Transforms/MIFOpConversion.h b/flang/include/flang/Optimizer/Transforms/MIFOpConversion.h
index 45148dab1cfb0..93c724748102c 100644
--- a/flang/include/flang/Optimizer/Transforms/MIFOpConversion.h
+++ b/flang/include/flang/Optimizer/Transforms/MIFOpConversion.h
@@ -9,7 +9,6 @@
 #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"
@@ -20,22 +19,9 @@ 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);
+void populateMIFOpConversionPatterns(mlir::RewritePatternSet &patterns);
+
 } // namespace mif
 
 #endif // FORTRAN_OPTIMIZER_TRANSFORMS_MIFOPCONVERSION_H_
diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp
index 4a9579cfde37c..015e374dbc357 100644
--- a/flang/lib/Optimizer/Dialect/FIRType.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -1420,6 +1420,13 @@ mlir::Type BaseBoxType::unwrapInnerType() const {
   return fir::unwrapInnerType(getEleTy());
 }
 
+mlir::Type BaseBoxType::getElementOrSequenceType() const {
+  mlir::Type eleTy = getEleTy();
+  if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(eleTy))
+    return seqTy;
+  return fir::unwrapRefType(eleTy);
+}
+
 static mlir::Type
 changeTypeShape(mlir::Type type,
                 std::optional<fir::SequenceType::ShapeRef> newShape) {
diff --git a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
index b7839bc667280..66c7c757a1fe0 100644
--- a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
+++ b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
@@ -70,8 +70,8 @@ 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 (auto seqTy = mlir::dyn_cast<fir::SequenceType>(
+            boxTy.getElementOrSequenceType())) {
       if (seqTy.getDimension() != 0 && seqTy.getDimension() != 1)
         return emitOpError(
             "`image_set` must be a boxed integer expression of rank 1.");
@@ -90,7 +90,7 @@ llvm::LogicalResult mif::SyncImagesOp::verify() {
 
 llvm::LogicalResult mif::CoMaxOp::verify() {
   fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType());
-  mlir::Type elemTy = boxTy.getElementType();
+  mlir::Type elemTy = boxTy.getElementOrSequenceType();
   if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(elemTy))
     elemTy = seqTy.getElementType();
 
@@ -106,7 +106,7 @@ llvm::LogicalResult mif::CoMaxOp::verify() {
 
 llvm::LogicalResult mif::CoMinOp::verify() {
   fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType());
-  mlir::Type elemTy = boxTy.getElementType();
+  mlir::Type elemTy = boxTy.getElementOrSequenceType();
   if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(elemTy))
     elemTy = seqTy.getElementType();
 
@@ -122,7 +122,7 @@ llvm::LogicalResult mif::CoMinOp::verify() {
 
 llvm::LogicalResult mif::CoSumOp::verify() {
   fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType());
-  mlir::Type elemTy = boxTy.getElementType();
+  mlir::Type elemTy = boxTy.getElementOrSequenceType();
   if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(elemTy))
     elemTy = seqTy.getElementType();
 
diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
index 10aa0028ddcac..1d917a7b406ae 100644
--- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
@@ -15,6 +15,7 @@
 #include "flang/Optimizer/Dialect/MIF/MIFOps.h"
 #include "flang/Optimizer/HLFIR/HLFIROps.h"
 #include "flang/Optimizer/Support/DataLayout.h"
+#include "flang/Optimizer/Support/InternalNames.h"
 #include "mlir/IR/Matchers.h"
 #include "mlir/Transforms/DialectConversion.h"
 #include "mlir/Transforms/GreedyPatternRewriteDriver.h"
@@ -29,6 +30,22 @@ using namespace Fortran::runtime;
 
 namespace {
 
+// Default prefix for subroutines of PRIF compiled with LLVM
+static std::string getPRIFProcName(std::string fmt) {
+  std::ostringstream oss;
+  oss << "prif_" << fmt;
+  return fir::NameUniquer::doProcedure({"prif"}, {}, oss.str());
+}
+
+static mlir::Type getPRIFStatType(fir::FirOpBuilder &builder) {
+  return builder.getRefType(builder.getI32Type());
+}
+
+static mlir::Type getPRIFErrmsgType(fir::FirOpBuilder &builder) {
+  return fir::BoxType::get(fir::CharacterType::get(
+      builder.getContext(), 1, fir::CharacterType::unknownLen()));
+}
+
 // 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
@@ -39,7 +56,8 @@ namespace {
 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);
+  mlir::Value absent =
+      fir::AbsentOp::create(builder, loc, getPRIFErrmsgType(builder));
   if (!errmsg)
     return {absent, absent};
 
@@ -66,7 +84,7 @@ struct MIFInitOpConversion : public mlir::OpRewritePattern<mif::InitOp> {
         builder.getContext(),
         /*inputs*/ {builder.getRefType(i32Ty)}, /*results*/ {});
     mlir::func::FuncOp funcOp =
-        builder.createFunction(loc, PRIFNAME_SUB("init"), ftype);
+        builder.createFunction(loc, getPRIFProcName("init"), ftype);
     llvm::SmallVector<mlir::Value> args =
         fir::runtime::createArguments(builder, loc, ftype, result);
     fir::CallOp::create(builder, loc, funcOp, args);
@@ -101,7 +119,7 @@ struct MIFThisImageOpConversion
         teamArg = fir::AbsentOp::create(builder, loc, boxTy);
 
       mlir::func::FuncOp funcOp = builder.createFunction(
-          loc, PRIFNAME_SUB("this_image_no_coarray"), ftype);
+          loc, getPRIFProcName("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);
@@ -135,7 +153,8 @@ struct MIFNumImagesOpConversion
       mlir::FunctionType ftype = mlir::FunctionType::get(
           builder.getContext(),
           /*inputs*/ {builder.getRefType(i32Ty)}, /*results*/ {});
-      funcOp = builder.createFunction(loc, PRIFNAME_SUB("num_images"), ftype);
+      funcOp =
+          builder.createFunction(loc, getPRIFProcName("num_images"), ftype);
       args = fir::runtime::createArguments(builder, loc, ftype, result);
     } else {
       if (op.getTeam()) {
@@ -145,7 +164,7 @@ struct MIFNumImagesOpConversion
                                     {boxTy, builder.getRefType(i32Ty)},
                                     /*results*/ {});
         funcOp = builder.createFunction(
-            loc, PRIFNAME_SUB("num_images_with_team"), ftype);
+            loc, getPRIFProcName("num_images_with_team"), ftype);
         args = fir::runtime::createArguments(builder, loc, ftype, op.getTeam(),
                                              result);
       } else {
@@ -159,7 +178,7 @@ struct MIFNumImagesOpConversion
             /*inputs*/ {builder.getRefType(i64Ty), builder.getRefType(i32Ty)},
             /*results*/ {});
         funcOp = builder.createFunction(
-            loc, PRIFNAME_SUB("num_images_with_team_number"), ftype);
+            loc, getPRIFProcName("num_images_with_team_number"), ftype);
         args = fir::runtime::createArguments(builder, loc, ftype, teamNumber,
                                              result);
       }
@@ -181,18 +200,19 @@ struct MIFSyncAllOpConversion : public mlir::OpRewritePattern<mif::SyncAllOp> {
     fir::FirOpBuilder builder(rewriter, mod);
     mlir::Location loc = op.getLoc();
 
+    mlir::Type errmsgTy = getPRIFErrmsgType(builder);
     mlir::FunctionType ftype = mlir::FunctionType::get(
         builder.getContext(),
-        /*inputs*/ {PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE},
+        /*inputs*/ {getPRIFStatType(builder), errmsgTy, errmsgTy},
         /*results*/ {});
     mlir::func::FuncOp funcOp =
-        builder.createFunction(loc, PRIFNAME_SUB("sync_all"), ftype);
+        builder.createFunction(loc, getPRIFProcName("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);
+      stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder));
     llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
         builder, loc, ftype, stat, errmsgArg, errmsgAllocArg);
     rewriter.replaceOpWithNewOp<fir::CallOp>(op, funcOp, args);
@@ -212,15 +232,16 @@ struct MIFSyncImagesOpConversion
     fir::FirOpBuilder builder(rewriter, mod);
     mlir::Location loc = op.getLoc();
 
+    mlir::Type errmsgTy = getPRIFErrmsgType(builder);
     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},
+        {imgSetTy, getPRIFStatType(builder), errmsgTy, errmsgTy},
         /*results*/ {});
     mlir::func::FuncOp funcOp =
-        builder.createFunction(loc, PRIFNAME_SUB("sync_images"), ftype);
+        builder.createFunction(loc, getPRIFProcName("sync_images"), ftype);
 
     // If imageSet is scalar, PRIF require to pass an array of size 1.
     mlir::Value imageSet = op.getImageSet();
@@ -242,7 +263,7 @@ struct MIFSyncImagesOpConversion
         genErrmsgPRIF(builder, loc, op.getErrmsg());
     mlir::Value stat = op.getStat();
     if (!stat)
-      stat = fir::AbsentOp::create(builder, loc, PRIF_STAT_TYPE);
+      stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder));
     llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
         builder, loc, ftype, imageSet, stat, errmsgArg, errmsgAllocArg);
     rewriter.replaceOpWithNewOp<fir::CallOp>(op, funcOp, args);
@@ -262,18 +283,19 @@ struct MIFSyncMemoryOpConversion
     fir::FirOpBuilder builder(rewriter, mod);
     mlir::Location loc = op.getLoc();
 
+    mlir::Type errmsgTy = getPRIFErrmsgType(builder);
     mlir::FunctionType ftype = mlir::FunctionType::get(
         builder.getContext(),
-        /*inputs*/ {PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE},
+        /*inputs*/ {getPRIFStatType(builder), errmsgTy, errmsgTy},
         /*results*/ {});
     mlir::func::FuncOp funcOp =
-        builder.createFunction(loc, PRIFNAME_SUB("sync_memory"), ftype);
+        builder.createFunction(loc, getPRIFProcName("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);
+      stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder));
     llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
         builder, loc, ftype, stat, errmsgArg, errmsgAllocArg);
     rewriter.replaceOpWithNewOp<fir::CallOp>(op, funcOp, args);
@@ -288,18 +310,19 @@ static fir::CallOp genCollectiveSubroutine(fir::FirOpBuilder &builder,
                                            mlir::Value rootImage,
                                            mlir::Value stat, mlir::Value errmsg,
                                            std::string coName) {
+  mlir::Type errmsgTy = getPRIFErrmsgType(builder);
   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::FunctionType ftype =
+      mlir::FunctionType::get(builder.getContext(),
+                              /*inputs*/
+                              {boxTy, builder.getRefType(builder.getI32Type()),
+                               getPRIFStatType(builder), errmsgTy, errmsgTy},
+                              /*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);
+    stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder));
   llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
       builder, loc, ftype, A, rootImage, stat, errmsgArg, errmsgAllocArg);
   return fir::CallOp::create(builder, loc, funcOp, args);
@@ -326,7 +349,7 @@ struct MIFCoBroadcastOpConversion
 
     fir::CallOp callOp = genCollectiveSubroutine(
         builder, loc, op.getA(), sourceImage, op.getStat(), op.getErrmsg(),
-        PRIFNAME_SUB("co_broadcast"));
+        getPRIFProcName("co_broadcast"));
     rewriter.replaceOp(op, callOp);
     return mlir::success();
   }
@@ -362,11 +385,11 @@ struct MIFCoMaxOpConversion : public mlir::OpRewritePattern<mif::CoMaxOp> {
     if (mlir::isa<fir::CharacterType>(argTy))
       callOp = genCollectiveSubroutine(builder, loc, op.getA(), resultImage,
                                        op.getStat(), op.getErrmsg(),
-                                       PRIFNAME_SUB("co_max_character"));
+                                       getPRIFProcName("co_max_character"));
     else
       callOp = genCollectiveSubroutine(builder, loc, op.getA(), resultImage,
                                        op.getStat(), op.getErrmsg(),
-                                       PRIFNAME_SUB("co_max"));
+                                       getPRIFProcName("co_max"));
     rewriter.replaceOp(op, callOp);
     return mlir::success();
   }
@@ -402,11 +425,11 @@ struct MIFCoMinOpConversion : public mlir::OpRewritePattern<mif::CoMinOp> {
     if (mlir::isa<fir::CharacterType>(argTy))
       callOp = genCollectiveSubroutine(builder, loc, op.getA(), resultImage,
                                        op.getStat(), op.getErrmsg(),
-                                       PRIFNAME_SUB("co_min_character"));
+                                       getPRIFProcName("co_min_character"));
     else
       callOp = genCollectiveSubroutine(builder, loc, op.getA(), resultImage,
                                        op.getStat(), op.getErrmsg(),
-                                       PRIFNAME_SUB("co_min"));
+                                       getPRIFProcName("co_min"));
     rewriter.replaceOp(op, callOp);
     return mlir::success();
   }
@@ -438,7 +461,7 @@ struct MIFCoSumOpConversion : public mlir::OpRewritePattern<mif::CoSumOp> {
 
     fir::CallOp callOp = genCollectiveSubroutine(
         builder, loc, op.getA(), resultImage, op.getStat(), op.getErrmsg(),
-        PRIFNAME_SUB("co_sum"));
+        getPRIFProcName("co_sum"));
     rewriter.replaceOp(op, callOp);
     return mlir::success();
   }
@@ -451,17 +474,7 @@ class MIFOpConversion : public fir::impl::MIFOpConversionBase<MIFOpConversion> {
     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);
+    mif::populateMIFOpConversionPatterns(patterns);
 
     target.addLegalDialect<fir::FIROpsDialect>();
     target.addLegalOp<mlir::ModuleOp>();
@@ -476,8 +489,7 @@ class MIFOpConversion : public fir::impl::MIFOpConversionBase<MIFOpConversion> {
 };
 } // namespace
 
-void mif::populateMIFOpConversionPatterns(fir::LLVMTypeConverter &converter,
-                                          mlir::RewritePatternSet &patterns) {
+void mif::populateMIFOpConversionPatterns(mlir::RewritePatternSet &patterns) {
   patterns.insert<MIFInitOpConversion, MIFThisImageOpConversion,
                   MIFNumImagesOpConversion, MIFSyncAllOpConversion,
                   MIFSyncImagesOpConversion, MIFSyncMemoryOpConversion,
diff --git a/flang/test/Fir/MIF/co_broadcast.mlir b/flang/test/Fir/MIF/co_broadcast.mlir
index de622a474c4e1..2862ca08de5c5 100644
--- a/flang/test/Fir/MIF/co_broadcast.mlir
+++ b/flang/test/Fir/MIF/co_broadcast.mlir
@@ -1,4 +1,4 @@
-// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+// RUN: fir-opt --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"} {
@@ -65,17 +65,6 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     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
diff --git a/flang/test/Fir/MIF/co_max.mlir b/flang/test/Fir/MIF/co_max.mlir
index 6c36714fcf2a1..d2b50cb4276fc 100644
--- a/flang/test/Fir/MIF/co_max.mlir
+++ b/flang/test/Fir/MIF/co_max.mlir
@@ -1,4 +1,4 @@
-// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+// RUN: fir-opt --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"} {
@@ -71,17 +71,6 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     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>
diff --git a/flang/test/Fir/MIF/co_min.mlir b/flang/test/Fir/MIF/co_min.mlir
index 00b89f4a30a0d..db0e71dc05fff 100644
--- a/flang/test/Fir/MIF/co_min.mlir
+++ b/flang/test/Fir/MIF/co_min.mlir
@@ -1,4 +1,4 @@
-// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+// RUN: fir-opt --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"} {
@@ -71,17 +71,6 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     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>
diff --git a/flang/test/Fir/MIF/co_sum.mlir b/flang/test/Fir/MIF/co_sum.mlir
index 11f8e213fa4e7..82b1cc12a1b4c 100644
--- a/flang/test/Fir/MIF/co_sum.mlir
+++ b/flang/test/Fir/MIF/co_sum.mlir
@@ -1,4 +1,4 @@
-// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+// RUN: fir-opt --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"} {
@@ -65,17 +65,6 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     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>
diff --git a/flang/test/Fir/MIF/num_images.mlir b/flang/test/Fir/MIF/num_images.mlir
index 8a337a09a2c72..0db3c17ed92ee 100644
--- a/flang/test/Fir/MIF/num_images.mlir
+++ b/flang/test/Fir/MIF/num_images.mlir
@@ -1,4 +1,4 @@
-// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+// RUN: fir-opt --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"} {
@@ -14,17 +14,6 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     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
-  }
 }
 
 
diff --git a/flang/test/Fir/MIF/sync_all.mlir b/flang/test/Fir/MIF/sync_all.mlir
index 76f88dc39c9d0..80e5604aeeab0 100644
--- a/flang/test/Fir/MIF/sync_all.mlir
+++ b/flang/test/Fir/MIF/sync_all.mlir
@@ -1,4 +1,4 @@
-// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+// RUN: fir-opt --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"} {
@@ -20,17 +20,6 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %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
-  }
 }
 
 
diff --git a/flang/test/Fir/MIF/sync_images.mlir b/flang/test/Fir/MIF/sync_images.mlir
index 41719c2c88127..cb6f77414d956 100644
--- a/flang/test/Fir/MIF/sync_images.mlir
+++ b/flang/test/Fir/MIF/sync_images.mlir
@@ -1,4 +1,4 @@
-// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+// RUN: fir-opt --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"} {
@@ -39,18 +39,6 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %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>>)
diff --git a/flang/test/Fir/MIF/sync_memory.mlir b/flang/test/Fir/MIF/sync_memory.mlir
index b3d21d814107f..99963f205846c 100644
--- a/flang/test/Fir/MIF/sync_memory.mlir
+++ b/flang/test/Fir/MIF/sync_memory.mlir
@@ -1,4 +1,4 @@
-// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+// RUN: fir-opt --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"} {
@@ -20,17 +20,6 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %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
-  }
 }
 
 
diff --git a/flang/test/Fir/MIF/this_image.mlir b/flang/test/Fir/MIF/this_image.mlir
index e9c5e89cd0093..835bff02daab1 100644
--- a/flang/test/Fir/MIF/this_image.mlir
+++ b/flang/test/Fir/MIF/this_image.mlir
@@ -1,4 +1,4 @@
-// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+// RUN: fir-opt --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"} {
@@ -9,17 +9,6 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     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
-  }
 }
 
 

>From 1856d355b5c2b09380cc98d634b8d78035e15fb2 Mon Sep 17 00:00:00 2001
From: Jean-Didier PAILLEUX <jean-di.pailleux at outlook.com>
Date: Thu, 2 Oct 2025 14:11:15 +0200
Subject: [PATCH 07/11] Update
 flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Valentin Clement (バレンタイン クレメン) <clementval at gmail.com>
---
 flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
index f862d9175a6ae..effcb42257fcc 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef FORTRAN_OPTIMIZER_DIALECT_MIF_MIF_H
-#define FORTRAN_OPTIMIZER_DIALECT_MIF_MIF_H
+#ifndef FORTRAN_OPTIMIZER_DIALECT_MIF_MIFDIALECT_H
+#define FORTRAN_OPTIMIZER_DIALECT_MIF_MIFDIALECT_H
 
 #include "mlir/Bytecode/BytecodeOpInterface.h"
 #include "mlir/IR/Dialect.h"

>From 415642b99f33280f46f69257958f66a05a4e8d65 Mon Sep 17 00:00:00 2001
From: Jean-Didier PAILLEUX <jean-di.pailleux at outlook.com>
Date: Thu, 2 Oct 2025 14:11:24 +0200
Subject: [PATCH 08/11] Update
 flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Valentin Clement (バレンタイン クレメン) <clementval at gmail.com>
---
 flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
index effcb42257fcc..3ec2dd7b65daf 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
@@ -28,4 +28,4 @@
 
 #include "flang/Optimizer/Dialect/MIF/MIFDialect.h.inc"
 
-#endif // FORTRAN_OPTIMIZER_DIALECT_MIF_MIF_H
+#endif // FORTRAN_OPTIMIZER_DIALECT_MIF_MIFDIALECT_H

>From 59a8c9fc0ef34cb84f36cf1b3a94a312489bc6d5 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Fri, 3 Oct 2025 11:05:04 +0200
Subject: [PATCH 09/11] Update assemblyFormat

---
 .../flang/Optimizer/Dialect/MIF/MIFDialect.h  |  2 +-
 .../flang/Optimizer/Dialect/MIF/MIFOps.td     | 72 +++++++-------
 flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp    |  2 +-
 flang/test/Fir/MIF/co_broadcast.mlir          | 16 +--
 flang/test/Fir/MIF/co_max.mlir                | 22 ++---
 flang/test/Fir/MIF/co_min.mlir                | 22 ++---
 flang/test/Fir/MIF/co_sum.mlir                | 98 +++++++++----------
 flang/test/Fir/MIF/num_images.mlir            |  4 +-
 flang/test/Fir/MIF/sync_all.mlir              |  8 +-
 flang/test/Fir/MIF/sync_images.mlir           | 12 +--
 flang/test/Fir/MIF/sync_memory.mlir           |  8 +-
 flang/test/Fir/MIF/this_image.mlir            |  2 +-
 flang/test/Lower/MIF/co_broadcast.f90         | 16 +--
 flang/test/Lower/MIF/co_max.f90               | 24 ++---
 flang/test/Lower/MIF/co_min.f90               | 24 ++---
 flang/test/Lower/MIF/co_sum.f90               | 22 ++---
 flang/test/Lower/MIF/num_images.f90           |  6 +-
 flang/test/Lower/MIF/sync_all.f90             |  8 +-
 flang/test/Lower/MIF/sync_images.f90          | 12 +--
 flang/test/Lower/MIF/sync_memory.f90          |  8 +-
 flang/test/Lower/MIF/this_image.f90           |  4 +-
 21 files changed, 190 insertions(+), 202 deletions(-)

diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
index 3ec2dd7b65daf..48d28cf75f002 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
@@ -1,4 +1,4 @@
-//===- MIF.h - MIF dialect --------------------------------*- C++-*-==//
+//===-- 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.
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
index ca0dfd27df339..fcad5f41df615 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -1,4 +1,4 @@
-//===-- MIFOps.td - MIF operation definitions ------*- tablegen -*-===//
+//===-- 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.
@@ -64,9 +64,9 @@ def mif_NumImagesOp : mif_Op<"num_images", [AttrSizedOperandSegments]> {
 
   let hasVerifier = 1;
   let assemblyFormat = [{
-    ( `team_number` `(` $team_number^ `:` type($team_number) `)` )? 
-    ( `team` `(` $team^ `:` type($team) `)` )? 
-    attr-dict `->` type($res)
+    ( `team_number` $team_number^ )? 
+    ( `team` $team^ )? 
+    attr-dict `:` functional-type(operands, results)
   }];
 }
 
@@ -106,10 +106,10 @@ def mif_ThisImageOp : mif_Op<"this_image", [AttrSizedOperandSegments]> {
 
   let hasVerifier = 1;
   let assemblyFormat = [{
-    ( `coarray` `(` $coarray^ `:` type($coarray) `)` )? 
-    ( `team` `(` $team^ `:` type($team) `)` )? 
-    ( `dim` `(` $dim^ `:` type($dim) `)` )? 
-    attr-dict `->` type($res)
+    ( `coarray` $coarray^ )? 
+    ( `team` $team^ )? 
+    ( `dim` $dim^ )? 
+    attr-dict `:` functional-type(operands, results)
   }];
 }
 
@@ -125,9 +125,9 @@ def mif_SyncAllOp : mif_Op<"sync_all", [AttrSizedOperandSegments,
   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
+    (`stat` $stat^ )?
+    (`errmsg` $errmsg^ )? 
+    attr-dict `:` functional-type(operands, results)
   }];
 }
 
@@ -146,10 +146,10 @@ def mif_SyncImagesOp : mif_Op<"sync_images", [AttrSizedOperandSegments,
                        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
+    (`image_set` $image_set^ )? 
+    (`stat` $stat^ )?
+    (`errmsg` $errmsg^ )? 
+    attr-dict `:` functional-type(operands, results)
   }];
 }
 
@@ -164,9 +164,9 @@ def mif_SyncMemoryOp : mif_Op<"sync_memory", [AttrSizedOperandSegments,
   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
+    (`stat` $stat^ )?
+    (`errmsg` $errmsg^ )? 
+    attr-dict `:` functional-type(operands, results)
   }];
 }
 
@@ -187,11 +187,10 @@ def mif_CoBroadcastOp : mif_Op<"co_broadcast", [AttrSizedOperandSegments,
       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
+    $a `source` $source_image
+    (`stat`  $stat^ )?
+    (`errmsg` $errmsg^ )? 
+    attr-dict `:` `(` type(operands) `)`
   }];
 }
 
@@ -210,11 +209,10 @@ def mif_CoMaxOp
 
   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
+    $a (`result` $result_image^ )? 
+    (`stat` $stat^ )?
+    (`errmsg` $errmsg^ )? 
+    attr-dict `:` `(` type(operands) `)`
   }];
 }
 
@@ -233,11 +231,10 @@ def mif_CoMinOp
 
   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
+    $a (`result` $result_image^ )? 
+    (`stat` $stat^ )?
+    (`errmsg` $errmsg^ )? 
+    attr-dict `:` `(` type(operands) `)`
   }];
 }
 
@@ -256,11 +253,10 @@ def mif_CoSumOp
 
   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
+    $a (`result` $result_image^ )? 
+    (`stat` $stat^ )?
+    (`errmsg` $errmsg^ )? 
+    attr-dict `:` `(` type(operands) `)`
   }];
 }
 
diff --git a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
index 66c7c757a1fe0..1c17ab495bc02 100644
--- a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
+++ b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
@@ -1,4 +1,4 @@
-//===- MIFOps.cpp - MIF dialect ops implementation ----------------===//
+//===-- 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.
diff --git a/flang/test/Fir/MIF/co_broadcast.mlir b/flang/test/Fir/MIF/co_broadcast.mlir
index 2862ca08de5c5..2f5782b2a825a 100644
--- a/flang/test/Fir/MIF/co_broadcast.mlir
+++ b/flang/test/Fir/MIF/co_broadcast.mlir
@@ -34,35 +34,35 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %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)
+    mif.co_broadcast %25 source %c1_i32 : (!fir.box<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>)
+    mif.co_broadcast %26 source %c1_i32_3 stat %24#0 : (!fir.box<complex<f32>>, i32, !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>>)
+    mif.co_broadcast %27 source %c1_i32_4 stat %24#0 errmsg %28 : (!fir.box<f64>, i32, !fir.ref<i32>, !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>>)
+    mif.co_broadcast %29 source %c1_i32_5 stat %24#0 errmsg %30 : (!fir.box<f32>, i32, !fir.ref<i32>, !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)
+    mif.co_broadcast %32 source %c1_i32_6 : (!fir.box<!fir.array<2xi32>>, 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)
+    mif.co_broadcast %34 source %c1_i32_7 : (!fir.box<!fir.array<2xcomplex<f32>>>, 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>)
+    mif.co_broadcast %36 source %c1_i32_8 stat %24#0 : (!fir.box<!fir.array<2xf64>>, i32, !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>>)
+    mif.co_broadcast %38 source %c1_i32_9 stat %24#0 errmsg %39 : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
     return
   }
 }
diff --git a/flang/test/Fir/MIF/co_max.mlir b/flang/test/Fir/MIF/co_max.mlir
index d2b50cb4276fc..f74513d862ebf 100644
--- a/flang/test/Fir/MIF/co_max.mlir
+++ b/flang/test/Fir/MIF/co_max.mlir
@@ -35,40 +35,40 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %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>
+    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>>
+    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>
+    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>
+    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)
+    mif.co_max %29 result %c1_i32 : (!fir.box<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>>)
+    mif.co_max %30 result %c1_i32_5 stat %24#0 errmsg %31 : (!fir.box<f64>, i32, !fir.ref<i32>, !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>>)
+    mif.co_max %32 result %c1_i32_6 stat %24#0 errmsg %33 : (!fir.box<f32>, i32, !fir.ref<i32>, !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>>
+    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)
+    mif.co_max %37 result %c1_i32_7 : (!fir.box<!fir.array<2x!fir.char<1>>>, 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>)
+    mif.co_max %39 result %c1_i32_8 stat %24#0 : (!fir.box<!fir.array<2xf64>>, i32, !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>>)
+    mif.co_max %41 result %c1_i32_9 stat %24#0 errmsg %42 : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
     return
   }
 }
diff --git a/flang/test/Fir/MIF/co_min.mlir b/flang/test/Fir/MIF/co_min.mlir
index db0e71dc05fff..97806bb376d38 100644
--- a/flang/test/Fir/MIF/co_min.mlir
+++ b/flang/test/Fir/MIF/co_min.mlir
@@ -35,40 +35,40 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %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>
+    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>>
+    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>
+    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>
+    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)
+    mif.co_min %29 result %c1_i32 : (!fir.box<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>>)
+    mif.co_min %30 result %c1_i32_5 stat %24#0 errmsg %31 : (!fir.box<f64>, i32, !fir.ref<i32>, !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>>)
+    mif.co_min %32 result %c1_i32_6 stat %24#0 errmsg %33 : (!fir.box<f32>, i32, !fir.ref<i32>, !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>>
+    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)
+    mif.co_min %37 result %c1_i32_7 : (!fir.box<!fir.array<2x!fir.char<1>>>, 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>)
+    mif.co_min %39 result %c1_i32_8 stat %24#0 : (!fir.box<!fir.array<2xf64>>, i32, !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>>)
+    mif.co_min %41 result %c1_i32_9 stat %24#0 errmsg %42 : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
     return
   }
 }
diff --git a/flang/test/Fir/MIF/co_sum.mlir b/flang/test/Fir/MIF/co_sum.mlir
index 82b1cc12a1b4c..8afce3582a97f 100644
--- a/flang/test/Fir/MIF/co_sum.mlir
+++ b/flang/test/Fir/MIF/co_sum.mlir
@@ -1,68 +1,60 @@
 // RUN: fir-opt --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"} {
+   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"}
+    %1 = fir.alloca !fir.array<2xf64> {bindc_name = "array_d", uniq_name = "_QFEarray_d"}
     %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>>>)
+    %3:2 = hlfir.declare %1(%2) {uniq_name = "_QFEarray_d"} : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf64>>, !fir.ref<!fir.array<2xf64>>)
     %c2_0 = arith.constant 2 : index
-    %4 = fir.alloca !fir.array<2xf64> {bindc_name = "array_d", uniq_name = "_QFEarray_d"}
+    %4 = fir.alloca !fir.array<2xi32> {bindc_name = "array_i", uniq_name = "_QFEarray_i"}
     %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>>)
+    %6:2 = hlfir.declare %4(%5) {uniq_name = "_QFEarray_i"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>)
     %c2_1 = arith.constant 2 : index
-    %7 = fir.alloca !fir.array<2xi32> {bindc_name = "array_i", uniq_name = "_QFEarray_i"}
+    %7 = fir.alloca !fir.array<2xf32> {bindc_name = "array_r", uniq_name = "_QFEarray_r"}
     %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>
+    %9:2 = hlfir.declare %7(%8) {uniq_name = "_QFEarray_r"} : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf32>>, !fir.ref<!fir.array<2xf32>>)
+    %10 = fir.alloca f64 {bindc_name = "d", uniq_name = "_QFEd"}
+    %11:2 = hlfir.declare %10 {uniq_name = "_QFEd"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
+    %12 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+    %13:2 = hlfir.declare %12 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    %c1 = arith.constant 1 : index
+    %14 = fir.alloca !fir.char<1> {bindc_name = "message", uniq_name = "_QFEmessage"}
+    %15:2 = hlfir.declare %14 typeparams %c1 {uniq_name = "_QFEmessage"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+    %16 = fir.alloca f32 {bindc_name = "r", uniq_name = "_QFEr"}
+    %17:2 = hlfir.declare %16 {uniq_name = "_QFEr"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+    %18 = fir.alloca i32 {bindc_name = "status", uniq_name = "_QFEstatus"}
+    %19:2 = hlfir.declare %18 {uniq_name = "_QFEstatus"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    %20 = fir.embox %13#0 : (!fir.ref<i32>) -> !fir.box<i32>
+    mif.co_sum %20 : (!fir.box<i32>)
+    %21 = fir.embox %11#0 : (!fir.ref<f64>) -> !fir.box<f64>
+    mif.co_sum %21 : (!fir.box<f64>)
+    %22 = fir.embox %17#0 : (!fir.ref<f32>) -> !fir.box<f32>
+    mif.co_sum %22 : (!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)
+    %23 = fir.embox %13#0 : (!fir.ref<i32>) -> !fir.box<i32>
+    mif.co_sum %23 result %c1_i32 : (!fir.box<i32>, i32)
+    %c1_i32_2 = arith.constant 1 : i32
+    %24 = fir.embox %11#0 : (!fir.ref<f64>) -> !fir.box<f64>
+    %25 = fir.embox %15#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+    mif.co_sum %24 result %c1_i32_2 stat %19#0 errmsg %25 : (!fir.box<f64>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+    %c1_i32_3 = arith.constant 1 : i32
+    %26 = fir.embox %17#0 : (!fir.ref<f32>) -> !fir.box<f32>
+    %27 = fir.embox %15#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+    mif.co_sum %26 result %c1_i32_3 stat %19#0 errmsg %27 : (!fir.box<f32>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+    %28 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+    %29 = fir.embox %6#0(%28) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+    mif.co_sum %29 : (!fir.box<!fir.array<2xi32>>)
+    %c1_i32_4 = arith.constant 1 : i32
+    %30 = fir.shape %c2 : (index) -> !fir.shape<1>
+    %31 = fir.embox %3#0(%30) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+    mif.co_sum %31 result %c1_i32_4 stat %19#0 : (!fir.box<!fir.array<2xf64>>, i32, !fir.ref<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>>)
+    %32 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+    %33 = fir.embox %9#0(%32) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+    %34 = fir.embox %15#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+    mif.co_sum %33 result %c1_i32_5 stat %19#0 errmsg %34 : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
     return
   }
 }
diff --git a/flang/test/Fir/MIF/num_images.mlir b/flang/test/Fir/MIF/num_images.mlir
index 0db3c17ed92ee..afa33a9063c3d 100644
--- a/flang/test/Fir/MIF/num_images.mlir
+++ b/flang/test/Fir/MIF/num_images.mlir
@@ -7,10 +7,10 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %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
+    %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
+    %7 = mif.num_images team_number %6 : (i32) -> i32
     hlfir.assign %7 to %2#0 : i32, !fir.ref<i32>
     return
   }
diff --git a/flang/test/Fir/MIF/sync_all.mlir b/flang/test/Fir/MIF/sync_all.mlir
index 80e5604aeeab0..b2b98b9aae9e8 100644
--- a/flang/test/Fir/MIF/sync_all.mlir
+++ b/flang/test/Fir/MIF/sync_all.mlir
@@ -8,12 +8,12 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %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>)
+    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>>)
+    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>>)
+    mif.sync_all stat %4#0 errmsg %6 : (!fir.ref<i32>, !fir.box<!fir.char<1,128>>) -> ()
     return
   }
   fir.global internal @_QFEerror_message : !fir.char<1,128> {
diff --git a/flang/test/Fir/MIF/sync_images.mlir b/flang/test/Fir/MIF/sync_images.mlir
index cb6f77414d956..e38fdaa5a4c14 100644
--- a/flang/test/Fir/MIF/sync_images.mlir
+++ b/flang/test/Fir/MIF/sync_images.mlir
@@ -11,10 +11,10 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %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>>)
+    mif.sync_images stat %6#0 errmsg %7 : (!fir.ref<i32>, !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>>)
+    mif.sync_images image_set %9 stat %6#0 errmsg %8 : (!fir.box<i32>, !fir.ref<i32>, !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
@@ -22,17 +22,17 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %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
+    mif.sync_images image_set %15 stat %6#0 errmsg %10 : (!fir.box<!fir.array<1xi32>>, !fir.ref<i32>, !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>)
+    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>>)
+    mif.sync_images image_set %21 : (!fir.box<!fir.array<1xi32>>) -> ()
     return
   }
   fir.global internal @_QFEerror_message : !fir.char<1,128> {
diff --git a/flang/test/Fir/MIF/sync_memory.mlir b/flang/test/Fir/MIF/sync_memory.mlir
index 99963f205846c..d6f24416bc61c 100644
--- a/flang/test/Fir/MIF/sync_memory.mlir
+++ b/flang/test/Fir/MIF/sync_memory.mlir
@@ -8,12 +8,12 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %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>)
+    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>>)
+    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>>)
+    mif.sync_memory stat %4#0 errmsg %6 : (!fir.ref<i32>, !fir.box<!fir.char<1,128>>) -> ()
     return
   }
   fir.global internal @_QFEerror_message : !fir.char<1,128> {
diff --git a/flang/test/Fir/MIF/this_image.mlir b/flang/test/Fir/MIF/this_image.mlir
index 835bff02daab1..25eafc09ef58c 100644
--- a/flang/test/Fir/MIF/this_image.mlir
+++ b/flang/test/Fir/MIF/this_image.mlir
@@ -5,7 +5,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %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
+    %3 = mif.this_image : () -> i32
     hlfir.assign %3 to %2#0 : i32, !fir.ref<i32>
     return
   }
diff --git a/flang/test/Lower/MIF/co_broadcast.f90 b/flang/test/Lower/MIF/co_broadcast.f90
index 5a2860cf9ce18..25e4330ade704 100644
--- a/flang/test/Lower/MIF/co_broadcast.f90
+++ b/flang/test/Lower/MIF/co_broadcast.f90
@@ -9,49 +9,49 @@ program test_co_broadcast
 
   ! 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)
+  ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] : (!fir.box<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>)
+  ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 : (!fir.box<complex<f32>>,  i32, !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>>)
+  ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] stat %[[STATUS]]#0 errmsg %[[V2]] : (!fir.box<f64>, i32, !fir.ref<i32>, !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>>)
+  ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] stat %[[STATUS]]#0 errmsg %[[V2]] : (!fir.box<f32>, i32, !fir.ref<i32>, !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)
+  ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] : (!fir.box<!fir.array<2xi32>>, 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)
+  ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] : (!fir.box<!fir.array<2xcomplex<f32>>>, 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>)
+  ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 : (!fir.box<!fir.array<2xf64>>, i32, !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>>)
+  ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !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
index 77d063148dc43..19e65626b50f2 100644
--- a/flang/test/Lower/MIF/co_max.f90
+++ b/flang/test/Lower/MIF/co_max.f90
@@ -7,54 +7,54 @@ program test_co_max
   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>
+  ! 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>>
+  ! 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>
+  ! 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>
+  ! 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)
+  ! CHECK: mif.co_max %[[V1]] result %[[C1_i32:.*]] : (!fir.box<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>>)
+  ! CHECK: mif.co_max %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<f64>, i32, !fir.ref<i32>, !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>>)
+  ! CHECK: mif.co_max %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<f32>, i32, !fir.ref<i32>, !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>> 
+  ! 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)
+  ! CHECK: mif.co_max %[[V1]] result %[[C1_i32:.*]] : (!fir.box<!fir.array<2x!fir.char<1>>>, 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>)
+  ! CHECK: mif.co_max %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 : (!fir.box<!fir.array<2xf64>>, i32, !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: %[[V1:.*]] = fir.embox %[[ARRAY_R:.*]]#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>>)
+  ! CHECK: mif.co_max %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !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
index b1dd3b3f12b51..a7adc6b540147 100644
--- a/flang/test/Lower/MIF/co_min.f90
+++ b/flang/test/Lower/MIF/co_min.f90
@@ -7,54 +7,54 @@ program test_co_min
   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>
+  ! 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>>
+  ! 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>
+  ! 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>
+  ! 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)
+  ! CHECK: mif.co_min %[[V1]] result %[[C1_i32:.*]] : (!fir.box<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>>)
+  ! CHECK: mif.co_min %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<f64>, i32, !fir.ref<i32>, !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>>)
+  ! CHECK: mif.co_min %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<f32>, i32, !fir.ref<i32>, !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>> 
+  ! 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)
+  ! CHECK: mif.co_min %[[V1]] result %[[C1_i32:.*]] : (!fir.box<!fir.array<2x!fir.char<1>>>, 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>)
+  ! CHECK: mif.co_min %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 : (!fir.box<!fir.array<2xf64>>, i32, !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: %[[V1:.*]] = fir.embox %[[ARRAY_R:.*]]#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>>)
+  ! CHECK: mif.co_min %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !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
index 5c76ea54b66fa..0d8a25850ad5f 100644
--- a/flang/test/Lower/MIF/co_sum.f90
+++ b/flang/test/Lower/MIF/co_sum.f90
@@ -4,48 +4,48 @@ 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
+  character(len=1) :: message
 
   ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
-  ! CHECK: mif.co_sum %[[V1]] : !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>
+  ! 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>
+  ! 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)
+  ! CHECK: mif.co_sum %[[V1]] result %[[C1_i32:.*]] : (!fir.box<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>>)
+  ! CHECK: mif.co_sum %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<f64>, i32, !fir.ref<i32>, !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>>)
+  ! CHECK: mif.co_sum %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<f32>, i32, !fir.ref<i32>, !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>> 
+  ! 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>)
+  ! CHECK: mif.co_sum %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 : (!fir.box<!fir.array<2xf64>>, i32, !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: %[[V1:.*]] = fir.embox %[[ARRAY_R:.*]]#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>>)
+  ! CHECK: mif.co_sum %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !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/MIF/num_images.f90 b/flang/test/Lower/MIF/num_images.f90
index ba28fdf56793f..a673b6e8120f8 100644
--- a/flang/test/Lower/MIF/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: mif.num_images -> i32
+  ! CHECK: mif.num_images : () -> i32
   i = num_images()
 
-  ! CHECK: mif.num_images team_number(%[[TEAM_NUMBER:.*]] : {{.*}}) -> i32
+  ! CHECK: mif.num_images team_number %[[TEAM_NUMBER:.*]] : (i32) -> i32
   i = num_images(TEAM_NUMBER=team_number)
 
-  ! CHECK: mif.num_images team(%[[TEAM:.*]]#0 : {{.*}}) -> i32
+  ! 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
index c2c2a41186da2..2b1997c8cc0b8 100644
--- a/flang/test/Lower/MIF/sync_all.f90
+++ b/flang/test/Lower/MIF/sync_all.f90
@@ -10,18 +10,18 @@ program test_sync_all
   integer sync_status
   character(len=128) :: error_message
 
-  ! COARRAY: mif.sync_all
+  ! COARRAY: mif.sync_all : ()
   sync all
 
-  ! COARRAY: mif.sync_all stat(%[[STAT]]#0 : !fir.ref<i32>)
+  ! 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>>)
+  ! 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>>)
+  ! COARRAY: mif.sync_all stat %[[STAT]]#0 errmsg %[[VAL_2]] : (!fir.ref<i32>, !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
index b9a901568dfc3..7ee5936131750 100644
--- a/flang/test/Lower/MIF/sync_images.f90
+++ b/flang/test/Lower/MIF/sync_images.f90
@@ -12,28 +12,28 @@ program test_sync_images
   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>>)
+  ! COARRAY: mif.sync_images stat %[[STAT]]#0 errmsg %[[VAL_1]] : (!fir.ref<i32>, !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>>)
+  ! COARRAY: mif.sync_images image_set %[[VAL_3]] stat %[[STAT]]#0 errmsg %[[VAL_2]] : (!fir.box<i32>, !fir.ref<i32>, !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>>)
+  ! COARRAY: mif.sync_images image_set %[[VAL_5]] stat %[[STAT]]#0 errmsg %[[VAL_4]] : (!fir.box<!fir.array<1xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,128>>)
   sync images([1],  stat=sync_status, errmsg=error_message)
   
-  ! COARRAY: mif.sync_images
+  ! 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>)
+  ! 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>>)
+  ! 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
index 3d44256cfb2c2..e6e0fa1e7fdf3 100644
--- a/flang/test/Lower/MIF/sync_memory.f90
+++ b/flang/test/Lower/MIF/sync_memory.f90
@@ -10,18 +10,18 @@ program test_sync_memory
   integer sync_status
   character(len=128) :: error_message
 
-  ! COARRAY: mif.sync_memory 
+  ! COARRAY: mif.sync_memory : () 
   sync memory
 
-  ! COARRAY: mif.sync_memory stat(%[[STAT]]#0 : !fir.ref<i32>)
+  ! 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>>)
+  ! 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>>)
+  ! COARRAY: mif.sync_memory stat %[[STAT]]#0 errmsg %[[VAL_2]] : (!fir.ref<i32>, !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/MIF/this_image.f90 b/flang/test/Lower/MIF/this_image.f90
index 57d169aad280e..ce729b349e6cf 100644
--- a/flang/test/Lower/MIF/this_image.f90
+++ b/flang/test/Lower/MIF/this_image.f90
@@ -5,10 +5,10 @@ program test
   integer :: i
   type(team_type) :: team
 
-  ! CHECK: mif.this_image -> i32 
+  ! CHECK: mif.this_image : () -> i32 
   i = this_image()
 
-  ! CHECK: mif.this_image team(%[[TEAM:.*]] : {{.*}}) -> i32
+  ! CHECK: mif.this_image team %[[TEAM:.*]] : ({{.*}}) -> i32
   i = this_image(TEAM=team)
 
 end program

>From 5df29696f1b399fc9cfac77d24461a8420dfb9b3 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Fri, 3 Oct 2025 11:07:51 +0200
Subject: [PATCH 10/11] Remove useless comments header

---
 flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
index 48d28cf75f002..2f3ab9c81705b 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
@@ -19,9 +19,6 @@
 #include "mlir/Interfaces/SideEffectInterfaces.h"
 #include "mlir/Interfaces/VectorInterfaces.h"
 
-// #include "flang/Optimizer/Dialect/FIRAttr.h"
-// #include "flang/Optimizer/Dialect/FIRType.h"
-
 //===----------------------------------------------------------------------===//
 // MIFDialect
 //===----------------------------------------------------------------------===//

>From 2e3f353492a0d24abe9b51ad8f440431b1a5bafe Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Thu, 9 Oct 2025 10:53:57 +0200
Subject: [PATCH 11/11] Adding MemRead memory effect + add verifier to
 CoBroadcastOp + code factorization

---
 .../flang/Optimizer/Dialect/MIF/MIFOps.td     |  3 +-
 flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp    | 20 ++++
 .../Optimizer/Transforms/MIFOpConversion.cpp  | 93 ++++++-------------
 3 files changed, 51 insertions(+), 65 deletions(-)

diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
index fcad5f41df615..98609a8251121 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -141,7 +141,7 @@ def mif_SyncImagesOp : mif_Op<"sync_images", [AttrSizedOperandSegments,
     adopt the behavior of the Fortran statement `SYNC IMAGES(*)`.
   }];
 
-  let arguments = (ins Optional<AnyRefOrBoxType>:$image_set,
+  let arguments = (ins Arg<Optional<AnyRefOrBoxType>, "", [MemRead]>:$image_set,
                        Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
                        Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
   let hasVerifier = 1;
@@ -186,6 +186,7 @@ def mif_CoBroadcastOp : mif_Op<"co_broadcast", [AttrSizedOperandSegments,
       Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
       Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
 
+  let hasVerifier = 1;
   let assemblyFormat = [{
     $a `source` $source_image
     (`stat`  $stat^ )?
diff --git a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
index 1c17ab495bc02..c6cc2e855ff35 100644
--- a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
+++ b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "flang/Optimizer/Dialect/MIF/MIFOps.h"
+#include "flang/Optimizer/Builder/Todo.h"
 #include "flang/Optimizer/Dialect/FIRAttr.h"
 #include "flang/Optimizer/Dialect/FIRType.h"
 #include "flang/Optimizer/Dialect/MIF/MIFDialect.h"
@@ -84,6 +85,25 @@ llvm::LogicalResult mif::SyncImagesOp::verify() {
   return mlir::success();
 }
 
+//===----------------------------------------------------------------------===//
+// CoBroadcastOp
+//===----------------------------------------------------------------------===//
+
+llvm::LogicalResult mif::CoBroadcastOp::verify() {
+  fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType());
+
+  if (fir::isPolymorphicType(boxTy))
+    return emitOpError("`A` cannot be polymorphic.");
+  else if (auto recTy =
+               mlir::dyn_cast<fir::RecordType>(boxTy.getElementType())) {
+    for (auto component : recTy.getTypeList()) {
+      if (fir::isPolymorphicType(component.second))
+        TODO(getLoc(), "`A` with polymorphic subobject component.");
+    }
+  }
+  return mlir::success();
+}
+
 //===----------------------------------------------------------------------===//
 // CoMaxOp
 //===----------------------------------------------------------------------===//
diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
index 1d917a7b406ae..206cb9be0574f 100644
--- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
@@ -307,9 +307,20 @@ struct MIFSyncMemoryOpConversion
 /// 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,
+                                           mlir::Value image, mlir::Value stat,
+                                           mlir::Value errmsg,
                                            std::string coName) {
+  mlir::Value rootImage;
+  mlir::Type i32Ty = builder.getI32Type();
+  if (!image)
+    rootImage = fir::AbsentOp::create(builder, loc, builder.getRefType(i32Ty));
+  else {
+    rootImage = builder.createTemporary(loc, i32Ty);
+    if (image.getType() != i32Ty)
+      image = fir::ConvertOp::create(builder, loc, i32Ty, image);
+    fir::StoreOp::create(builder, loc, image, rootImage);
+  }
+
   mlir::Type errmsgTy = getPRIFErrmsgType(builder);
   mlir::Type boxTy = fir::BoxType::get(builder.getNoneType());
   mlir::FunctionType ftype =
@@ -340,16 +351,9 @@ struct MIFCoBroadcastOpConversion
     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(),
-        getPRIFProcName("co_broadcast"));
+        builder, loc, op.getA(), op.getSourceImage(), op.getStat(),
+        op.getErrmsg(), getPRIFProcName("co_broadcast"));
     rewriter.replaceOp(op, callOp);
     return mlir::success();
   }
@@ -366,30 +370,17 @@ struct MIFCoMaxOpConversion : public mlir::OpRewritePattern<mif::CoMaxOp> {
     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(),
-                                       getPRIFProcName("co_max_character"));
+      callOp = genCollectiveSubroutine(
+          builder, loc, op.getA(), op.getResultImage(), op.getStat(),
+          op.getErrmsg(), getPRIFProcName("co_max_character"));
     else
-      callOp = genCollectiveSubroutine(builder, loc, op.getA(), resultImage,
-                                       op.getStat(), op.getErrmsg(),
-                                       getPRIFProcName("co_max"));
+      callOp = genCollectiveSubroutine(
+          builder, loc, op.getA(), op.getResultImage(), op.getStat(),
+          op.getErrmsg(), getPRIFProcName("co_max"));
     rewriter.replaceOp(op, callOp);
     return mlir::success();
   }
@@ -406,30 +397,17 @@ struct MIFCoMinOpConversion : public mlir::OpRewritePattern<mif::CoMinOp> {
     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(),
-                                       getPRIFProcName("co_min_character"));
+      callOp = genCollectiveSubroutine(
+          builder, loc, op.getA(), op.getResultImage(), op.getStat(),
+          op.getErrmsg(), getPRIFProcName("co_min_character"));
     else
-      callOp = genCollectiveSubroutine(builder, loc, op.getA(), resultImage,
-                                       op.getStat(), op.getErrmsg(),
-                                       getPRIFProcName("co_min"));
+      callOp = genCollectiveSubroutine(
+          builder, loc, op.getA(), op.getResultImage(), op.getStat(),
+          op.getErrmsg(), getPRIFProcName("co_min"));
     rewriter.replaceOp(op, callOp);
     return mlir::success();
   }
@@ -446,22 +424,9 @@ struct MIFCoSumOpConversion : public mlir::OpRewritePattern<mif::CoSumOp> {
     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(),
-        getPRIFProcName("co_sum"));
+        builder, loc, op.getA(), op.getResultImage(), op.getStat(),
+        op.getErrmsg(), getPRIFProcName("co_sum"));
     rewriter.replaceOp(op, callOp);
     return mlir::success();
   }



More information about the flang-commits mailing list