[flang-commits] [flang] [Flang][MIF] Adding support of intrinsics with coarray argument (PR #192944)

Jean-Didier PAILLEUX via flang-commits flang-commits at lists.llvm.org
Thu May 28 03:02:14 PDT 2026


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

>From a5a05b8239e834e60bc925747a2c40dd1c50a9a7 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Thu, 5 Feb 2026 20:54:24 +0100
Subject: [PATCH 1/5] [Flang][MIF] Adding support of intrinsics with coarray
 argument

- Adding lowering and operation in MIF Dialect for UCOBOUND, LCOBOUND,
  COSHAPE and IMAGE_INDEX
- Adding support of coarray argument for THIS_IMAGE in MIF Dialect (and the lowering)
---
 .../flang/Optimizer/Builder/IntrinsicCall.h   |   7 +
 .../flang/Optimizer/Dialect/FIROpsSupport.h   |   3 +
 .../flang/Optimizer/Dialect/MIF/MIFOps.td     | 128 ++++++++-
 flang/lib/Lower/ConvertCall.cpp               |  57 +++-
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp |  98 ++++++-
 flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp    | 120 +++++++-
 .../Optimizer/Transforms/MIFOpConversion.cpp  | 271 ++++++++++++++++--
 flang/test/Fir/MIF/cobound.mlir               |  93 ++++++
 flang/test/Fir/MIF/coshape.mlir               |  78 +++++
 flang/test/Fir/MIF/image_index.mlir           |  67 +++++
 flang/test/Fir/MIF/this_image.mlir            |  63 +++-
 flang/test/Lower/MIF/cobound.f90              |  21 ++
 flang/test/Lower/MIF/coshape.f90              |  14 +
 flang/test/Lower/MIF/image_index.f90          |  20 ++
 flang/test/Lower/MIF/this_image.f90           |  10 +-
 15 files changed, 1004 insertions(+), 46 deletions(-)
 create mode 100644 flang/test/Fir/MIF/cobound.mlir
 create mode 100644 flang/test/Fir/MIF/coshape.mlir
 create mode 100644 flang/test/Fir/MIF/image_index.mlir
 create mode 100644 flang/test/Lower/MIF/cobound.f90
 create mode 100644 flang/test/Lower/MIF/coshape.f90
 create mode 100644 flang/test/Lower/MIF/image_index.f90

diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index ca9677a8cb2b1..adf05affecc41 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -176,6 +176,7 @@ struct IntrinsicLibrary {
                                          llvm::ArrayRef<fir::ExtendedValue>);
   mlir::Value genCmplx(mlir::Type, llvm::ArrayRef<mlir::Value>);
   mlir::Value genConjg(mlir::Type, llvm::ArrayRef<mlir::Value>);
+  fir::ExtendedValue genCoshape(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
   fir::ExtendedValue genCount(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
   void genCpuTime(llvm::ArrayRef<fir::ExtendedValue>);
   fir::ExtendedValue genCshift(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
@@ -295,6 +296,8 @@ struct IntrinsicLibrary {
   mlir::Value genIeeeUnordered(mlir::Type, llvm::ArrayRef<mlir::Value>);
   mlir::Value genIeeeValue(mlir::Type, llvm::ArrayRef<mlir::Value>);
   mlir::Value genIeor(mlir::Type, llvm::ArrayRef<mlir::Value>);
+  fir::ExtendedValue genImageIndex(mlir::Type,
+                                   llvm::ArrayRef<fir::ExtendedValue>);
   fir::ExtendedValue genIndex(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
   mlir::Value genIor(mlir::Type, llvm::ArrayRef<mlir::Value>);
   fir::ExtendedValue genIparity(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
@@ -309,6 +312,8 @@ struct IntrinsicLibrary {
   mlir::Value genIshft(mlir::Type, llvm::ArrayRef<mlir::Value>);
   mlir::Value genIshftc(mlir::Type, llvm::ArrayRef<mlir::Value>);
   fir::ExtendedValue genLbound(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
+  fir::ExtendedValue genLcobound(mlir::Type,
+                                 llvm::ArrayRef<fir::ExtendedValue>);
   mlir::Value genLeadz(mlir::Type, llvm::ArrayRef<mlir::Value>);
   fir::ExtendedValue genLen(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
   fir::ExtendedValue genLenTrim(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
@@ -415,6 +420,8 @@ struct IntrinsicLibrary {
                                   llvm::ArrayRef<fir::ExtendedValue>);
   fir::ExtendedValue genTrim(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
   fir::ExtendedValue genUbound(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
+  fir::ExtendedValue genUcobound(mlir::Type,
+                                 llvm::ArrayRef<fir::ExtendedValue>);
   fir::ExtendedValue genUnlink(std::optional<mlir::Type> resultType,
                                llvm::ArrayRef<fir::ExtendedValue> args);
   fir::ExtendedValue genUnpack(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
diff --git a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
index b014d925592cb..9e168ffe90d0d 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
+++ b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
@@ -136,6 +136,9 @@ static constexpr llvm::StringRef getAccessGroupsAttrName() {
   return "access_groups";
 }
 
+/// Attribute to mark coarray Fortran entities with the CORANK attribute.
+constexpr llvm::StringRef getCorankAttrName() { return "fir.corank"; }
+
 /// Does the function, \p func, have a host-associations tuple argument?
 /// Some internal procedures may have access to host procedure variables.
 bool hasHostAssociationArgument(mlir::func::FuncOp func);
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
index 7df274b5697f3..f39ea71e93ffd 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -102,11 +102,13 @@ def mif_ThisImageOp : mif_Op<"this_image", [AttrSizedOperandSegments]> {
     value 5, `this_image(A)` has the value [5, 0, 0].
   }];
 
-  let arguments = (ins Optional<fir_BoxType>:$coarray,
-      Optional<AnyInteger>:$dim, Optional<AnyRefOrBoxType>:$team);
-  let results = (outs I32:$res);
+  let arguments = (ins Optional<AnyType>:$coarray, Optional<AnyInteger>:$dim,
+      Optional<AnyRefOrBoxType>:$team);
+  let results = (outs AnyType:$res);
 
-  let builders = [OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$team)>,
+  let builders = [OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$dim,
+                      "mlir::Value":$team)>,
+                  OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$team)>,
                   OpBuilder<(ins "mlir::Value":$team)>];
 
   let hasVerifier = 1;
@@ -118,6 +120,124 @@ def mif_ThisImageOp : mif_Op<"this_image", [AttrSizedOperandSegments]> {
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// Coarray Queries
+//===----------------------------------------------------------------------===//
+
+def mif_ImageIndexOp : mif_Op<"image_index", [AttrSizedOperandSegments]> {
+  let summary = "Image index from cosubscripts.";
+  let description = [{
+    Arguments:
+      - `coarray`: Shall be a coarray of any type.
+      - `sub`: rank-one integer array of size equal to the corank of `coarray`.
+      - `team`: Shall be a scalar of type `team_type` from ISO_FORTRAN_ENV.
+      - `team_number`: It shall identify the initial team or a sibling team 
+        of the current team.
+
+    Usage:
+    - Case(1) : `call image_index(coarray, sub)`
+    - Case(2) : `call image_index(coarray, sub, team)`
+    - Case(3) : `call image_index(coarray, sub, team_number)`
+
+    Result: If the value of `sub` is a valid sequence of cosubscripts for `coarray` in the
+      team specified by `team` or `team_number`, or the current team if neither `team` nor
+      `team_number` appears, the result is the index of the corresponding image in that team.
+      Otherwise, the result is zero.
+  }];
+
+  let arguments = (ins AnyType:$coarray, fir_BoxType:$sub,
+      Optional<AnyRefOrBoxType>:$team, Optional<AnyInteger>:$team_number);
+  let builders = [OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$sub,
+      "mlir::Value":$team)>];
+
+  let results = (outs I32);
+
+  let hasVerifier = 1;
+  let assemblyFormat = [{
+    `coarray` $coarray `sub` $sub 
+    ( `team` $team^ )? 
+    ( `team_number` $team_number^ )? 
+    attr-dict `:` functional-type(operands, results)
+  }];
+}
+
+def mif_LcoboundOp : mif_Op<"lcobound", [NoMemoryEffect]> {
+  let summary = "Returns the lower cobound(s) associated with a coarray.";
+  let description = [{
+    This operation returns the lower cobound(s) associated with a coarray.
+    Arguments: 
+      - `coarray`: Shall be a coarray of any type.
+      - `dim`(optional) : Shall be an integer scalar. Its value shall be in the range of
+          `1 <= DIM <= N`, where `N` is the corank of the coarray.
+    Results:
+      - Case(1): If `dim` is present, the result is an integer scalar equal to
+        the lower cobound for codimension `dim`.
+      - Case(2): `dim` is absent, so the result is an array whose size matches
+        the corank of the indicated coarray.
+  }];
+
+  let arguments = (ins AnyType:$coarray, Optional<AnyInteger>:$dim);
+  let results = (outs AnyType);
+
+  let builders = [OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$dim)>,
+                  OpBuilder<(ins "mlir::Value":$coarray)>];
+
+  let hasVerifier = 1;
+  let assemblyFormat = [{
+    `coarray` $coarray 
+    ( `dim` $dim^ )? 
+    attr-dict `:` functional-type(operands, results)
+  }];
+}
+
+def mif_UcoboundOp : mif_Op<"ucobound", [NoMemoryEffect]> {
+  let summary = "Returns the upper cobound(s) associated with a coarray.";
+  let description = [{
+    This operation returns the upper cobound(s) associated with a coarray.
+    Arguments: 
+      - `coarray`: Shall be a coarray of any type.
+      - `dim`(optional) : Shall be an integer scalar. Its value shall be in the range of
+          `1 <= DIM <= N`, where `N` is the corank of the coarray.
+    Results:
+      - Case(1): If `dim` is present, the result is an integer scalar equal to
+        the upper cobound for codimension `dim`.
+      - Case(2): `dim` is absent, so the result is an array whose size matches
+        the corank of the indicated coarray.
+  }];
+
+  let arguments = (ins AnyType:$coarray, Optional<AnyInteger>:$dim);
+  let results = (outs AnyType);
+
+  let builders = [OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$dim)>,
+                  OpBuilder<(ins "mlir::Value":$coarray)>];
+
+  let hasVerifier = 1;
+  let assemblyFormat = [{
+    `coarray` $coarray 
+    ( `dim` $dim^ )? 
+    attr-dict `:` functional-type(operands, results)
+  }];
+}
+
+def mif_CoshapeOp : mif_Op<"coshape", [NoMemoryEffect]> {
+  let summary = "Return the sizes of codimensions of a coarray.";
+  let description = [{
+    Argument: `coarray`: Shall be a coarray of any type.
+    Result : Is an array whose size matches the corank of the indicated coarray and
+       returns `UCOBOUND - LCOBOUND + 1`.
+  }];
+
+  let arguments = (ins AnyType:$coarray);
+  let builders = [OpBuilder<(ins "mlir::Value":$coarray)>];
+  let results = (outs AnyBoxedArray);
+
+  let hasVerifier = 1;
+  let assemblyFormat = [{
+    `coarray` $coarray 
+    attr-dict `:` functional-type(operands, results)
+  }];
+}
+
 //===----------------------------------------------------------------------===//
 // Synchronization
 //===----------------------------------------------------------------------===//
diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index ea65a49355330..ada0708931b4e 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -2149,6 +2149,22 @@ static std::optional<hlfir::EntityWithAttributes> genCustomIntrinsicRefCore(
       loc, builder, result, ".tmp.custom_intrinsic_result")}};
 }
 
+static mlir::IntegerAttr
+getCorankFromExpr(fir::FirOpBuilder &builder,
+                  const Fortran::lower::SomeExpr &expr) {
+  mlir::IntegerAttr corankAttr;
+  if (auto dataRef{Fortran::evaluate::ExtractDataRef(expr)}) {
+    const Fortran::semantics::Symbol sym = dataRef->GetLastSymbol();
+    if (const auto *object =
+            sym.GetUltimate()
+                .detailsIf<Fortran::semantics::ObjectEntityDetails>())
+      if (object->coshape().size())
+        corankAttr = builder.getIntegerAttr(builder.getI32Type(),
+                                            object->coshape().size());
+  }
+  return corankAttr;
+}
+
 /// Lower calls to intrinsic procedures with actual arguments that have been
 /// pre-lowered but have not yet been prepared according to the interface.
 static std::optional<hlfir::EntityWithAttributes>
@@ -2172,6 +2188,11 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals,
   const fir::IntrinsicArgumentLoweringRules *argLowering =
       intrinsicEntry.getArgumentLoweringRules();
   for (auto arg : llvm::enumerate(loweredActuals)) {
+    // Trying to retrieve the corank of a variable if this is a coarray
+    mlir::IntegerAttr corankAttr;
+    if (const Fortran::lower::SomeExpr *expr =
+            callContext.procRef.UnwrapArgExpr(arg.index()))
+      corankAttr = getCorankFromExpr(builder, *expr);
     if (!arg.value()) {
       operands.emplace_back(fir::getAbsentIntrinsicArgument());
       continue;
@@ -2221,6 +2242,9 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals,
             genOptionalValue(builder, loc, getActualFortranElementType(),
                              getActualCb, isPresent);
         addToCleanups(std::move(cleanup));
+        if (corankAttr)
+          fir::getBase(exv).getDefiningOp()->setAttr(fir::getCorankAttrName(),
+                                                     corankAttr);
         operands.emplace_back(exv);
         continue;
       }
@@ -2228,6 +2252,9 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals,
         hlfir::Entity actual = arg.value()->getActual(loc, builder);
         auto [exv, cleanup] = genOptionalAddr(builder, loc, actual, isPresent);
         addToCleanups(std::move(cleanup));
+        if (corankAttr)
+          fir::getBase(exv).getDefiningOp()->setAttr(fir::getCorankAttrName(),
+                                                     corankAttr);
         operands.emplace_back(exv);
         continue;
       }
@@ -2235,6 +2262,9 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals,
         hlfir::Entity actual = arg.value()->getActual(loc, builder);
         auto [exv, cleanup] = genOptionalBox(builder, loc, actual, isPresent);
         addToCleanups(std::move(cleanup));
+        if (corankAttr)
+          fir::getBase(exv).getDefiningOp()->setAttr(fir::getCorankAttrName(),
+                                                     corankAttr);
         operands.emplace_back(exv);
         continue;
       }
@@ -2250,19 +2280,31 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals,
       llvm_unreachable("bad switch");
     }
 
+    fir::ExtendedValue exv;
     hlfir::Entity actual = arg.value()->getActual(loc, builder);
     switch (argRules.lowerAs) {
     case fir::LowerIntrinsicArgAs::Value:
-      operands.emplace_back(
-          Fortran::lower::convertToValue(loc, converter, actual, stmtCtx));
+      exv = Fortran::lower::convertToValue(loc, converter, actual, stmtCtx);
+      if (corankAttr)
+        fir::getBase(exv).getDefiningOp()->setAttr(fir::getCorankAttrName(),
+                                                   corankAttr);
+      operands.emplace_back(exv);
       continue;
     case fir::LowerIntrinsicArgAs::Addr:
-      operands.emplace_back(Fortran::lower::convertToAddress(
-          loc, converter, actual, stmtCtx, getActualFortranElementType()));
+      exv = Fortran::lower::convertToAddress(loc, converter, actual, stmtCtx,
+                                             getActualFortranElementType());
+      if (corankAttr)
+        fir::getBase(exv).getDefiningOp()->setAttr(fir::getCorankAttrName(),
+                                                   corankAttr);
+      operands.emplace_back(exv);
       continue;
     case fir::LowerIntrinsicArgAs::Box:
-      operands.emplace_back(Fortran::lower::convertToBox(
-          loc, converter, actual, stmtCtx, getActualFortranElementType()));
+      exv = Fortran::lower::convertToBox(loc, converter, actual, stmtCtx,
+                                         getActualFortranElementType());
+      if (corankAttr)
+        fir::getBase(exv).getDefiningOp()->setAttr(fir::getCorankAttrName(),
+                                                   corankAttr);
+      operands.emplace_back(exv);
       continue;
     case fir::LowerIntrinsicArgAs::Inquired:
       if (const Fortran::lower::SomeExpr *expr =
@@ -2977,6 +3019,9 @@ genCustomIntrinsicRef(const Fortran::evaluate::SpecificIntrinsic *intrinsic,
     }
     if (!exv)
       llvm_unreachable("bad switch");
+    if (mlir::IntegerAttr corankAttr = getCorankFromExpr(builder, expr))
+      fir::getBase(*exv).getDefiningOp()->setAttr(fir::getCorankAttrName(),
+                                                  corankAttr);
     actual = extendedValueToHlfirEntity(loc, builder, exv.value(),
                                         "tmp.custom_intrinsic_arg");
     loweredActuals.emplace_back(Fortran::lower::PreparedActualArgument{
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 8f75b94d2f7e7..dd1c0dcd6d069 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -243,6 +243,10 @@ static constexpr IntrinsicHandler handlers[]{
     {"command_argument_count", &I::genCommandArgumentCount},
     {"conjg", &I::genConjg},
     {"cosd", &I::genCosd},
+    {"coshape",
+     &I::genCoshape,
+     {{{"coarray", asAddr}, {"kind", asValue}}},
+     false},
     {"cospi", &I::genCospi},
     {"count",
      &I::genCount,
@@ -499,6 +503,13 @@ static constexpr IntrinsicHandler handlers[]{
     {"ieee_unordered", &I::genIeeeUnordered},
     {"ieee_value", &I::genIeeeValue},
     {"ieor", &I::genIeor},
+    {"image_index",
+     &I::genImageIndex,
+     {{{"coarray", asAddr},
+       {"sub", asBox},
+       {"team", asAddr},
+       {"team_number", asAddr}}},
+     /*isElemental*/ false},
     {"index",
      &I::genIndex,
      {{{"string", asAddr},
@@ -529,6 +540,10 @@ static constexpr IntrinsicHandler handlers[]{
      &I::genLbound,
      {{{"array", asInquired}, {"dim", asValue}, {"kind", asValue}}},
      /*isElemental=*/false},
+    {"lcobound",
+     &I::genLcobound,
+     {{{"coarray", asAddr}, {"dim", asValue}, {"kind", asValue}}},
+     /*isElemental=*/false},
     {"leadz", &I::genLeadz},
     {"len",
      &I::genLen,
@@ -801,8 +816,8 @@ static constexpr IntrinsicHandler handlers[]{
      /*isElemental=*/false},
     {"this_image",
      &I::genThisImage,
-     {{{"coarray", asBox},
-       {"dim", asAddr},
+     {{{"coarray", asAddr},
+       {"dim", asValue},
        {"team", asBox, handleDynamicOptional}}},
      /*isElemental=*/false},
     {"time", &I::genTime, {}, /*isElemental=*/false},
@@ -827,6 +842,10 @@ static constexpr IntrinsicHandler handlers[]{
      &I::genUbound,
      {{{"array", asBox}, {"dim", asValue}, {"kind", asValue}}},
      /*isElemental=*/false},
+    {"ucobound",
+     &I::genUcobound,
+     {{{"coarray", asAddr}, {"dim", asValue}, {"kind", asValue}}},
+     /*isElemental=*/false},
     {"umaskl", &I::genMask<mlir::arith::ShLIOp>},
     {"umaskr", &I::genMask<mlir::arith::ShRUIOp>},
     {"unlink",
@@ -3568,6 +3587,17 @@ mlir::Value IntrinsicLibrary::genCospi(mlir::Type resultType,
   return getRuntimeCallGenerator("cos", ftype)(builder, loc, {arg});
 }
 
+// COSHAPE
+fir::ExtendedValue
+IntrinsicLibrary::genCoshape(mlir::Type,
+                             llvm::ArrayRef<fir::ExtendedValue> args) {
+  converter->checkCoarrayEnabled();
+  assert(args.size() == 2);
+
+  return mif::CoshapeOp::create(builder, loc,
+                                /*coarray*/ fir::getBase(args[0]));
+}
+
 // COUNT
 fir::ExtendedValue
 IntrinsicLibrary::genCount(mlir::Type resultType,
@@ -6243,6 +6273,22 @@ mlir::Value IntrinsicLibrary::genIeor(mlir::Type resultType,
                                                      args[1]);
 }
 
+// IMAGE_INDEX
+fir::ExtendedValue
+IntrinsicLibrary::genImageIndex(mlir::Type resultType,
+                                llvm::ArrayRef<fir::ExtendedValue> args) {
+  converter->checkCoarrayEnabled();
+  assert(args.size() == 2 || args.size() == 3);
+
+  mlir::Value team;
+  if (args.size() > 2) {
+    team = fir::getBase(args[2]);
+  }
+  return mif::ImageIndexOp::create(builder, loc,
+                                   /*coarray*/ fir::getBase(args[0]),
+                                   /*sub*/ fir::getBase(args[1]), team);
+}
+
 // INDEX
 fir::ExtendedValue
 IntrinsicLibrary::genIndex(mlir::Type resultType,
@@ -8257,11 +8303,21 @@ IntrinsicLibrary::genThisImage(mlir::Type resultType,
   converter->checkCoarrayEnabled();
   assert(args.size() >= 1 && args.size() <= 3);
   const bool coarrayIsAbsent = args.size() == 1;
+  const bool dimIsAbsent = args.size() < 3;
   mlir::Value team = fir::getBase(args[args.size() - 1]);
 
-  if (!coarrayIsAbsent)
-    TODO(loc, "this_image with coarray argument.");
-  mlir::Value res = mif::ThisImageOp::create(builder, loc, team);
+  if (!coarrayIsAbsent && dimIsAbsent) {
+    mlir::Value res =
+        mif::ThisImageOp::create(builder, loc, fir::getBase(args[0]), team);
+    return res;
+  }
+  mlir::Value res;
+  if (!dimIsAbsent) {
+    mlir::Value coarray = fir::getBase(args[0]);
+    mlir::Value dim = fir::getBase(args[1]);
+    res = mif::ThisImageOp::create(builder, loc, coarray, dim, team);
+  } else
+    res = mif::ThisImageOp::create(builder, loc, team);
   return builder.createConvert(loc, resultType, res);
 }
 
@@ -8366,6 +8422,22 @@ IntrinsicLibrary::genLbound(mlir::Type resultType,
       fir::runtime::genLboundDim(builder, loc, fir::getBase(box), dim));
 }
 
+// LCOBOUND
+fir::ExtendedValue
+IntrinsicLibrary::genLcobound(mlir::Type resultType,
+                              llvm::ArrayRef<fir::ExtendedValue> args) {
+  converter->checkCoarrayEnabled();
+  assert(args.size() == 2 || args.size() == 3);
+
+  mlir::Value coarray = fir::getBase(args[0]);
+  const bool dimIsAbsent = args.size() == 2 || isStaticallyAbsent(args, 1);
+  if (!dimIsAbsent) {
+    mlir::Value dim = fir::getBase(args[1]);
+    return mif::LcoboundOp::create(builder, loc, resultType, coarray, dim);
+  }
+  return mif::LcoboundOp::create(builder, loc, coarray);
+}
+
 // UBOUND
 fir::ExtendedValue
 IntrinsicLibrary::genUbound(mlir::Type resultType,
@@ -8388,6 +8460,22 @@ IntrinsicLibrary::genUbound(mlir::Type resultType,
                          /*needAccurateLowerBound=*/true);
 }
 
+// UCOBOUND
+fir::ExtendedValue
+IntrinsicLibrary::genUcobound(mlir::Type resultType,
+                              llvm::ArrayRef<fir::ExtendedValue> args) {
+  converter->checkCoarrayEnabled();
+  assert(args.size() == 2 || args.size() == 3);
+
+  mlir::Value coarray = fir::getBase(args[0]);
+  const bool dimIsAbsent = args.size() == 2 || isStaticallyAbsent(args, 1);
+  if (!dimIsAbsent) {
+    mlir::Value dim = fir::getBase(args[1]);
+    return mif::UcoboundOp::create(builder, loc, resultType, coarray, dim);
+  }
+  return mif::UcoboundOp::create(builder, loc, coarray);
+}
+
 // SPACING
 mlir::Value IntrinsicLibrary::genSpacing(mlir::Type resultType,
                                          llvm::ArrayRef<mlir::Value> args) {
diff --git a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
index ebeba9aa51494..5620353a58f3d 100644
--- a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
+++ b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
@@ -10,6 +10,7 @@
 #include "flang/Optimizer/Builder/Todo.h"
 #include "flang/Optimizer/Dialect/FIRAttr.h"
 #include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/FIROpsSupport.h"
 #include "flang/Optimizer/Dialect/FIRType.h"
 #include "flang/Optimizer/Dialect/MIF/MIFDialect.h"
 #include "flang/Optimizer/HLFIR/HLFIROps.h"
@@ -18,6 +19,14 @@
 #include "llvm/ADT/SmallVector.h"
 #include <tuple>
 
+template <class T>
+static llvm::LogicalResult checkCorankAttr(T op) {
+  mlir::Value coarray = op.getCoarray();
+  if (!coarray.getDefiningOp()->hasAttr(fir::getCorankAttrName()))
+    return op.emitOpError("`coarray` must have a corank integer attribute.");
+  return mlir::success();
+}
+
 // Function used to check if a type has POINTER or ALLOCATABLE component.
 // Currently an allocation of coarray with this kind of component are not yet
 // supported.
@@ -64,22 +73,35 @@ llvm::LogicalResult mif::NumImagesOp::verify() {
 // ThisImageOp
 //===----------------------------------------------------------------------===//
 
+void mif::ThisImageOp::build(mlir::OpBuilder &builder,
+                             mlir::OperationState &result, mlir::Value coarray,
+                             mlir::Value dim, mlir::Value team) {
+  mlir::Type resultTy = builder.getI32Type();
+  build(builder, result, resultTy, coarray, dim, team);
+}
+
 void mif::ThisImageOp::build(mlir::OpBuilder &builder,
                              mlir::OperationState &result, mlir::Value coarray,
                              mlir::Value team) {
-  build(builder, result, coarray, /*dim*/ mlir::Value{}, team);
+  mlir::Type i64Ty = builder.getI64Type();
+  mlir::Type resultTy = fir::BoxType::get(
+      fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, i64Ty));
+  build(builder, result, resultTy, 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);
+  mlir::Type resultTy = builder.getI32Type();
+  build(builder, result, resultTy, /*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.");
+  if (getCoarray())
+    return checkCorankAttr(*this);
   return mlir::success();
 }
 
@@ -269,5 +291,97 @@ llvm::LogicalResult mif::AllocCoarrayOp::verify() {
   return mlir::success();
 }
 
+//===----------------------------------------------------------------------===//
+// LcoboundOp
+//===----------------------------------------------------------------------===//
+
+void mif::LcoboundOp::build(mlir::OpBuilder &builder,
+                            mlir::OperationState &result, mlir::Value coarray,
+                            mlir::Value dim) {
+  // By default the result type is an I64
+  mlir::Type resultTy = builder.getI64Type();
+  build(builder, result, resultTy, coarray, dim);
+}
+
+void mif::LcoboundOp::build(mlir::OpBuilder &builder,
+                            mlir::OperationState &result, mlir::Value coarray) {
+  mlir::Type i64Ty = builder.getI64Type();
+  mlir::Type resultTy = fir::BoxType::get(
+      fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, i64Ty));
+  build(builder, result, resultTy, coarray, /*dim*/ mlir::Value{});
+}
+
+llvm::LogicalResult mif::LcoboundOp::verify() {
+  if (getCoarray())
+    return checkCorankAttr(*this);
+  return mlir::success();
+}
+
+//===----------------------------------------------------------------------===//
+// UcoboundOp
+//===----------------------------------------------------------------------===//
+
+void mif::UcoboundOp::build(mlir::OpBuilder &builder,
+                            mlir::OperationState &result, mlir::Value coarray,
+                            mlir::Value dim) {
+  // By default the result type is an I64
+  mlir::Type resultTy = builder.getI64Type();
+  build(builder, result, resultTy, coarray, dim);
+}
+
+void mif::UcoboundOp::build(mlir::OpBuilder &builder,
+                            mlir::OperationState &result, mlir::Value coarray) {
+  mlir::Type i64Ty = builder.getI64Type();
+  mlir::Type resultTy = fir::BoxType::get(
+      fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, i64Ty));
+  build(builder, result, resultTy, coarray, /*dim*/ mlir::Value{});
+}
+
+llvm::LogicalResult mif::UcoboundOp::verify() {
+  if (getCoarray())
+    return checkCorankAttr(*this);
+  return mlir::success();
+}
+
+//===----------------------------------------------------------------------===//
+// CoshapeOp
+//===----------------------------------------------------------------------===//
+
+void mif::CoshapeOp::build(mlir::OpBuilder &builder,
+                           mlir::OperationState &result, mlir::Value coarray) {
+  mlir::Type i64Ty = builder.getI64Type();
+  mlir::Type resultTy = fir::BoxType::get(
+      fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, i64Ty));
+  build(builder, result, resultTy, coarray);
+}
+
+llvm::LogicalResult mif::CoshapeOp::verify() {
+  if (getCoarray())
+    return checkCorankAttr(*this);
+  return mlir::success();
+}
+
+//===----------------------------------------------------------------------===//
+// ImageIndexOp
+//===----------------------------------------------------------------------===//
+
+void mif::ImageIndexOp::build(mlir::OpBuilder &builder,
+                              mlir::OperationState &result, mlir::Value coarray,
+                              mlir::Value sub, mlir::Value teamArg) {
+  bool isTeamNumber =
+      teamArg && fir::unwrapPassByRefType(teamArg.getType()).isInteger();
+  if (!isTeamNumber)
+    build(builder, result, coarray, sub, teamArg, /*team*/ mlir::Value{});
+  else
+    build(builder, result, coarray, sub, /*team_number*/ mlir::Value{},
+          teamArg);
+}
+
+llvm::LogicalResult mif::ImageIndexOp::verify() {
+  if (getCoarray())
+    return checkCorankAttr(*this);
+  return mlir::success();
+}
+
 #define GET_OP_CLASSES
 #include "flang/Optimizer/Dialect/MIF/MIFOps.cpp.inc"
diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
index 28e6dda7721e8..ba6a0a91d3d9b 100644
--- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
@@ -139,6 +139,15 @@ void storeCoarrayHandle(fir::FirOpBuilder &builder, mlir::Location loc,
   fir::StoreOp::create(builder, loc, coarrayHandle, addrOf);
 }
 
+std::int64_t getCorankFromAttr(fir::FirOpBuilder &builder, mlir::Location loc,
+                               mlir::Value coarray) {
+  std::int64_t corank = 0;
+  if (auto intAttr = coarray.getDefiningOp()->getAttrOfType<mlir::IntegerAttr>(
+          fir::getCorankAttrName()))
+    corank = intAttr.getInt();
+  return corank;
+}
+
 static int computeElementByteSize(mlir::Location loc, mlir::Type type,
                                   fir::KindMapping &kindMap,
                                   bool emitErrorOnFailure = true) {
@@ -430,27 +439,74 @@ struct MIFThisImageOpConversion
     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::Type i64Ty = builder.getI64Type();
+    mlir::Type i32Ty = builder.getI32Type();
+    mlir::Type boxTy = fir::BoxType::get(rewriter.getNoneType());
+
+    mlir::Value teamArg = op.getTeam();
+    if (!op.getTeam())
+      teamArg = fir::AbsentOp::create(builder, loc, boxTy);
+    else
+      teamArg = builder.createBox(loc, teamArg);
+
+    if (op.getCoarray()) {
+      llvm::SmallVector<mlir::Value> args;
+      mlir::FunctionType ftype;
+      mlir::func::FuncOp funcOp;
+      mlir::Value result;
+      mlir::Value coarrayHandle =
+          getCoarrayHandle(builder, loc, op.getCoarray());
+      if (mlir::Value d = op.getDim()) {
+        mlir::Value dim = builder.createTemporary(loc, i32Ty);
+        if (d.getType() != i32Ty)
+          d = fir::ConvertOp::create(builder, loc, i32Ty, d);
+        fir::StoreOp::create(builder, loc, d, dim);
+        result = builder.createTemporary(loc, i64Ty);
+        ftype = mlir::FunctionType::get(builder.getContext(),
+                                        /*inputs*/
+                                        {boxTy, builder.getRefType(i32Ty),
+                                         boxTy, builder.getRefType(i64Ty)},
+                                        /*results*/ {});
+        funcOp = builder.createFunction(
+            loc, getPRIFProcName("this_image_with_dim"), ftype);
+        args = fir::runtime::createArguments(builder, loc, ftype, coarrayHandle,
+                                             dim, teamArg, result);
+        fir::CallOp::create(builder, loc, funcOp, args);
+        result = fir::LoadOp::create(builder, loc, result).getResult();
+        if (result.getType() != op.getType())
+          result = builder.createConvert(loc, op.getType(), result);
+      } else {
+        std::int64_t corank = getCorankFromAttr(builder, loc, op.getCoarray());
+        mlir::Type resTy = fir::SequenceType::get({corank}, i64Ty);
+        // Need to embox the array
+        result = builder.createBox(loc, builder.createTemporary(loc, resTy));
+        ftype = mlir::FunctionType::get(
+            builder.getContext(),
+            /*inputs*/ {boxTy, boxTy, fir::BoxType::get(resTy)},
+            /*results*/ {});
+        funcOp = builder.createFunction(
+            loc, getPRIFProcName("this_image_with_coarray"), ftype);
+        args = fir::runtime::createArguments(builder, loc, ftype, coarrayHandle,
+                                             teamArg, result);
+        fir::CallOp::create(builder, loc, funcOp, args);
+        result = fir::ConvertOp::create(builder, loc,
+                                        genBoxedSequenceType(i64Ty), result);
+      }
+      rewriter.replaceOp(op, result);
+    } else {
       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, 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);
       rewriter.replaceOpWithNewOp<fir::LoadOp>(op, result);
-      return mlir::success();
     }
+    return mlir::success();
   }
 };
 
@@ -1114,6 +1170,182 @@ struct MIFDeallocCoarrayOpConversion
   }
 };
 
+/// Convert mif.coshape operation to runtime call of 'prif_coshape'
+struct MIFCoshapeOpConversion : public mlir::OpRewritePattern<mif::CoshapeOp> {
+  using OpRewritePattern::OpRewritePattern;
+
+  mlir::LogicalResult
+  matchAndRewrite(mif::CoshapeOp 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 i64Ty = builder.getI64Type();
+    mlir::Type boxTy = fir::BoxType::get(builder.getNoneType());
+
+    mlir::FunctionType ftype =
+        mlir::FunctionType::get(builder.getContext(),
+                                /*inputs*/ {boxTy, genBoxedSequenceType(i64Ty)},
+                                /*results*/ {});
+    mlir::func::FuncOp funcOp =
+        builder.createFunction(loc, getPRIFProcName("coshape"), ftype);
+
+    mlir::Value coarrayHandle = getCoarrayHandle(builder, loc, op.getCoarray());
+    std::int64_t corank = getCorankFromAttr(builder, loc, op.getCoarray());
+    mlir::Type resultType = fir::SequenceType::get(
+        static_cast<fir::SequenceType::Extent>(corank), i64Ty);
+    mlir::Value result =
+        builder.createBox(loc, builder.createTemporary(loc, resultType));
+
+    llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+        builder, loc, ftype, coarrayHandle, result);
+    fir::CallOp::create(builder, loc, funcOp, args);
+    result = fir::ConvertOp::create(builder, loc, genBoxedSequenceType(i64Ty),
+                                    result);
+    rewriter.replaceOp(op, result);
+    return mlir::success();
+  }
+};
+
+template <class T>
+mlir::LogicalResult CoboundOpConversion(T op, mlir::PatternRewriter &rewriter,
+                                        const std::string &prefix) {
+  auto mod = op->template getParentOfType<mlir::ModuleOp>();
+  fir::FirOpBuilder builder(rewriter, mod);
+  mlir::Location loc = op.getLoc();
+  mlir::Type i64Ty = builder.getI64Type();
+  mlir::Type boxTy = fir::BoxType::get(builder.getNoneType());
+
+  mlir::Value coarrayHandle = getCoarrayHandle(builder, loc, op.getCoarray());
+  if (mlir::Value d = op.getDim()) {
+    mlir::Type i32Ty = builder.getI32Type();
+    mlir::FunctionType ftype = mlir::FunctionType::get(
+        builder.getContext(),
+        /*inputs*/
+        {boxTy, builder.getRefType(i32Ty), builder.getRefType(i64Ty)},
+        /*results*/ {});
+    mlir::func::FuncOp funcOp = builder.createFunction(
+        loc, getPRIFProcName(prefix + "_with_dim"), ftype);
+
+    mlir::Value result = builder.createTemporary(loc, i64Ty);
+    mlir::Value dim = builder.createTemporary(loc, i32Ty);
+    if (d.getType() != i32Ty)
+      d = fir::ConvertOp::create(builder, loc, i32Ty, d);
+    fir::StoreOp::create(builder, loc, d, dim);
+
+    llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+        builder, loc, ftype, coarrayHandle, dim, result);
+    fir::CallOp::create(builder, loc, funcOp, args);
+    result = fir::LoadOp::create(builder, loc, result).getResult();
+    if (result.getType() != op.getType())
+      result = builder.createConvert(loc, op.getType(), result);
+    rewriter.replaceOp(op, result);
+  } else {
+    mlir::FunctionType ftype =
+        mlir::FunctionType::get(builder.getContext(),
+                                /*inputs*/ {boxTy, genBoxedSequenceType(i64Ty)},
+                                /*results*/ {});
+    mlir::func::FuncOp funcOp =
+        builder.createFunction(loc, getPRIFProcName(prefix + "_no_dim"), ftype);
+
+    std::int64_t corank = getCorankFromAttr(builder, loc, op.getCoarray());
+    mlir::Type resultType = fir::SequenceType::get(
+        static_cast<fir::SequenceType::Extent>(corank), i64Ty);
+    mlir::Value result =
+        builder.createBox(loc, builder.createTemporary(loc, resultType));
+    llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+        builder, loc, ftype, coarrayHandle, result);
+    fir::CallOp::create(builder, loc, funcOp, args);
+    result = fir::ConvertOp::create(builder, loc, genBoxedSequenceType(i64Ty),
+                                    result);
+    rewriter.replaceOp(op, result);
+  }
+  return mlir::success();
+}
+
+/// Convert mif.lcobound operation to runtime call of
+/// 'prif_lcobound_{with|no}_dim'
+struct MIFLcoboundOpConversion
+    : public mlir::OpRewritePattern<mif::LcoboundOp> {
+  using OpRewritePattern::OpRewritePattern;
+
+  mlir::LogicalResult
+  matchAndRewrite(mif::LcoboundOp op,
+                  mlir::PatternRewriter &rewriter) const override {
+    return CoboundOpConversion(op, rewriter, "lcobound");
+  }
+};
+
+/// Convert mif.ucobound operation to runtime call of
+/// 'prif_ucobound_{with|no}_dim'
+struct MIFUcoboundOpConversion
+    : public mlir::OpRewritePattern<mif::UcoboundOp> {
+  using OpRewritePattern::OpRewritePattern;
+
+  mlir::LogicalResult
+  matchAndRewrite(mif::UcoboundOp op,
+                  mlir::PatternRewriter &rewriter) const override {
+    return CoboundOpConversion(op, rewriter, "ucobound");
+  }
+};
+
+/// Convert mif.image_index operation to runtime call of
+/// 'prif_image_index[_with_team[_number]]'
+struct MIFImageIndexOpConversion
+    : public mlir::OpRewritePattern<mif::ImageIndexOp> {
+  using OpRewritePattern::OpRewritePattern;
+
+  mlir::LogicalResult
+  matchAndRewrite(mif::ImageIndexOp 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 i64Ty = builder.getI64Type();
+    mlir::Type i32Ty = builder.getI32Type();
+    mlir::Type resTy = builder.getRefType(i32Ty);
+    mlir::Type boxTy = fir::BoxType::get(builder.getNoneType());
+    mlir::Value result = builder.createTemporary(loc, i32Ty);
+
+    mlir::func::FuncOp funcOp;
+    mlir::FunctionType ftype;
+    llvm::SmallVector<mlir::Value> args;
+    mlir::Value coarrayHandle = getCoarrayHandle(builder, loc, op.getCoarray());
+    if (!op.getTeam()) {
+      mlir::FunctionType ftype = mlir::FunctionType::get(
+          builder.getContext(),
+          /*inputs*/ {boxTy, genBoxedSequenceType(i64Ty), resTy},
+          /*results*/ {});
+      funcOp =
+          builder.createFunction(loc, getPRIFProcName("image_index"), ftype);
+      args = fir::runtime::createArguments(builder, loc, ftype, coarrayHandle,
+                                           op.getSub(), result);
+    } else {
+      mlir::Value team = op.getTeam();
+      std::string imageIndexName =
+          fir::unwrapPassByRefType(team.getType()).isInteger()
+              ? getPRIFProcName("image_index_with_team")
+              : getPRIFProcName("image_index_with_team_number");
+      mlir::Type teamTy = fir::unwrapPassByRefType(team.getType()).isInteger()
+                              ? builder.getRefType(i64Ty)
+                              : boxTy;
+      mlir::FunctionType ftype = mlir::FunctionType::get(
+          builder.getContext(),
+          /*inputs*/ {boxTy, genBoxedSequenceType(i64Ty), teamTy, resTy},
+          /*results*/ {});
+      funcOp = builder.createFunction(loc, imageIndexName, ftype);
+
+      if (fir::isa_ref_type(team.getType()))
+        team = builder.createBox(loc, team);
+      args = fir::runtime::createArguments(builder, loc, ftype, coarrayHandle,
+                                           op.getSub(), team, result);
+    }
+    fir::CallOp::create(builder, loc, funcOp, args);
+    rewriter.replaceOpWithNewOp<fir::LoadOp>(op, result);
+    return mlir::success();
+  }
+};
+
 class MIFOpConversion : public fir::impl::MIFOpConversionBase<MIFOpConversion> {
 public:
   void runOnOperation() override {
@@ -1158,13 +1390,14 @@ void mif::populateMIFOpConversionPatterns(
     mlir::RewritePatternSet &patterns) {
   patterns.insert<MIFAllocCoarrayOpConversion>(patterns.getContext(), &dl,
                                                &converter);
-  patterns.insert<MIFInitOpConversion, MIFThisImageOpConversion,
-                  MIFNumImagesOpConversion, MIFSyncAllOpConversion,
-                  MIFSyncImagesOpConversion, MIFSyncMemoryOpConversion,
-                  MIFSyncTeamOpConversion, MIFCoBroadcastOpConversion,
-                  MIFCoMaxOpConversion, MIFCoMinOpConversion,
-                  MIFCoSumOpConversion, MIFFormTeamOpConversion,
-                  MIFChangeTeamOpConversion, MIFGetTeamOpConversion,
-                  MIFTeamNumberOpConversion, MIFDeallocCoarrayOpConversion>(
-      patterns.getContext());
+  patterns.insert<
+      MIFInitOpConversion, MIFThisImageOpConversion, MIFNumImagesOpConversion,
+      MIFSyncAllOpConversion, MIFSyncImagesOpConversion,
+      MIFSyncMemoryOpConversion, MIFSyncTeamOpConversion,
+      MIFCoBroadcastOpConversion, MIFCoMaxOpConversion, MIFCoMinOpConversion,
+      MIFCoSumOpConversion, MIFFormTeamOpConversion, MIFChangeTeamOpConversion,
+      MIFGetTeamOpConversion, MIFTeamNumberOpConversion,
+      MIFDeallocCoarrayOpConversion, MIFCoshapeOpConversion,
+      MIFLcoboundOpConversion, MIFUcoboundOpConversion,
+      MIFImageIndexOpConversion>(patterns.getContext());
 }
diff --git a/flang/test/Fir/MIF/cobound.mlir b/flang/test/Fir/MIF/cobound.mlir
new file mode 100644
index 0000000000000..e5072632e6b49
--- /dev/null
+++ b/flang/test/Fir/MIF/cobound.mlir
@@ -0,0 +1,93 @@
+// 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 23.0.0 (git at github.com:SiPearl/llvm-project.git d31a4730513391710d91c5ad33bb8ea3d68db3cb)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+// CHECK-LABEL: func.func @_QQmain
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST"} {
+    %0 = fir.alloca !fir.array<2xi64>
+    %1 = fir.alloca !fir.array<3xi64>
+    %2 = fir.dummy_scope : !fir.dscope
+    %3 = fir.address_of(@_QFEa) : !fir.ref<!fir.box<!fir.heap<i32>>>
+    %4:2 = hlfir.declare %3 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEa"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)
+    %c3 = arith.constant 3 : index
+    %5 = fir.alloca !fir.array<3xi32> {bindc_name = "res1", uniq_name = "_QFEres1"}
+    %6 = fir.shape %c3 : (index) -> !fir.shape<1>
+    %7:2 = hlfir.declare %5(%6) {uniq_name = "_QFEres1"} : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<3xi32>>, !fir.ref<!fir.array<3xi32>>)
+    %8 = fir.alloca i32 {bindc_name = "res2", uniq_name = "_QFEres2"}
+    %9:2 = hlfir.declare %8 {uniq_name = "_QFEres2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    %10 = fir.absent !fir.box<none>
+    %c1_i64 = arith.constant 1 : i64
+    %c2_i32 = arith.constant 2 : i32
+    %11 = fir.convert %c2_i32 : (i32) -> i64
+    %c0 = arith.constant 0 : index
+    %12 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64 to %12 : !fir.ref<i64>
+    %13 = fir.coordinate_of %0, %c0 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
+    fir.store %11 to %13 : !fir.ref<i64>
+    %c3_i32 = arith.constant 3 : i32
+    %14 = fir.convert %c3_i32 : (i32) -> i64
+    %c5_i32 = arith.constant 5 : i32
+    %15 = fir.convert %c5_i32 : (i32) -> i64
+    %c1 = arith.constant 1 : index
+    %16 = fir.coordinate_of %1, %c1 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
+    fir.store %14 to %16 : !fir.ref<i64>
+    %17 = fir.coordinate_of %0, %c1 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
+    fir.store %15 to %17 : !fir.ref<i64>
+    %c2 = arith.constant 2 : index
+    %18 = fir.coordinate_of %1, %c2 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64 to %18 : !fir.ref<i64>
+    %19 = fir.embox %1 : (!fir.ref<!fir.array<3xi64>>) -> !fir.box<!fir.array<3xi64>>
+    %20 = fir.embox %0 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
+    mif.alloc_coarray %4#0 lcobounds %19 ucobounds %20 errmsg %10 {uniq_name = "_QFEa"} : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>, !fir.box<none>) -> ()
+    %21 = fir.load %4#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
+    %22 = fir.box_addr %21 {fir.corank = 3 : i32} : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+// CHECK: fir.call @_QMprifPprif_lcobound_no_dim
+    %23 = mif.lcobound coarray %22 : (!fir.heap<i32>) -> !fir.box<!fir.array<?xi64>>
+    %24:2 = hlfir.declare %23 {uniq_name = ".tmp.intrinsic_result"} : (!fir.box<!fir.array<?xi64>>) -> (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>)
+    %false = arith.constant false
+    %25 = hlfir.as_expr %24#0 move %false : (!fir.box<!fir.array<?xi64>>, i1) -> !hlfir.expr<?xi64>
+    %c0_0 = arith.constant 0 : index
+    %26:3 = fir.box_dims %24#0, %c0_0 : (!fir.box<!fir.array<?xi64>>, index) -> (index, index, index)
+    %27 = fir.shape %26#1 : (index) -> !fir.shape<1>
+    %28 = hlfir.elemental %27 unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
+    ^bb0(%arg0: index):
+      %43 = hlfir.apply %25, %arg0 : (!hlfir.expr<?xi64>, index) -> i64
+      %44 = fir.convert %43 : (i64) -> i32
+      hlfir.yield_element %44 : i32
+    }
+    hlfir.assign %28 to %7#0 : !hlfir.expr<?xi32>, !fir.ref<!fir.array<3xi32>>
+    hlfir.destroy %28 : !hlfir.expr<?xi32>
+    hlfir.destroy %25 : !hlfir.expr<?xi64>
+    %c2_i32_1 = arith.constant 2 : i32
+    %29 = fir.load %4#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
+    %30 = fir.box_addr %29 {fir.corank = 3 : i32} : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+// CHECK: fir.call @_QMprifPprif_lcobound_with_dim
+    %31 = mif.lcobound coarray %30 dim %c2_i32_1 : (!fir.heap<i32>, i32) -> i32
+    hlfir.assign %31 to %9#0 : i32, !fir.ref<i32>
+    %32 = fir.load %4#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
+    %33 = fir.box_addr %32 {fir.corank = 3 : i32} : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+    %34 = mif.ucobound coarray %33 : (!fir.heap<i32>) -> !fir.box<!fir.array<?xi64>>
+// CHECK: fir.call @_QMprifPprif_ucobound_no_dim
+    %35:2 = hlfir.declare %34 {uniq_name = ".tmp.intrinsic_result"} : (!fir.box<!fir.array<?xi64>>) -> (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>)
+    %false_2 = arith.constant false
+    %36 = hlfir.as_expr %35#0 move %false_2 : (!fir.box<!fir.array<?xi64>>, i1) -> !hlfir.expr<?xi64>
+    %c0_3 = arith.constant 0 : index
+    %37:3 = fir.box_dims %35#0, %c0_3 : (!fir.box<!fir.array<?xi64>>, index) -> (index, index, index)
+    %38 = fir.shape %37#1 : (index) -> !fir.shape<1>
+    %39 = hlfir.elemental %38 unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
+    ^bb0(%arg0: index):
+      %43 = hlfir.apply %36, %arg0 : (!hlfir.expr<?xi64>, index) -> i64
+      %44 = fir.convert %43 : (i64) -> i32
+      hlfir.yield_element %44 : i32
+    }
+    hlfir.assign %39 to %7#0 : !hlfir.expr<?xi32>, !fir.ref<!fir.array<3xi32>>
+    hlfir.destroy %39 : !hlfir.expr<?xi32>
+    hlfir.destroy %36 : !hlfir.expr<?xi64>
+    %c2_i32_4 = arith.constant 2 : i32
+    %40 = fir.load %4#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
+    %41 = fir.box_addr %40 {fir.corank = 3 : i32} : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+// CHECK: fir.call @_QMprifPprif_ucobound_with_dim
+    %42 = mif.ucobound coarray %41 dim %c2_i32_4 : (!fir.heap<i32>, i32) -> i32
+    hlfir.assign %42 to %9#0 : i32, !fir.ref<i32>
+    return
+  }
+}
diff --git a/flang/test/Fir/MIF/coshape.mlir b/flang/test/Fir/MIF/coshape.mlir
new file mode 100644
index 0000000000000..1a019117cf8f1
--- /dev/null
+++ b/flang/test/Fir/MIF/coshape.mlir
@@ -0,0 +1,78 @@
+// 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 23.0.0 (git at github.com:SiPearl/llvm-project.git d31a4730513391710d91c5ad33bb8ea3d68db3cb)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+  func.func @_QQmain() attributes {fir.bindc_name = "TEST"} {
+    %0 = fir.alloca !fir.array<2xi64>
+    %1 = fir.alloca !fir.array<3xi64>
+    %2 = fir.dummy_scope : !fir.dscope
+    %3 = fir.address_of(@_QFEa) : !fir.ref<i32>
+    %c1_i64 = arith.constant 1 : i64
+    %c0 = arith.constant 0 : index
+    %4 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64 to %4 : !fir.ref<i64>
+    %c3_i64 = arith.constant 3 : i64
+    %c1 = arith.constant 1 : index
+    %5 = fir.coordinate_of %1, %c1 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
+    fir.store %c3_i64 to %5 : !fir.ref<i64>
+    %c1_i64_0 = arith.constant 1 : i64
+    %c2 = arith.constant 2 : index
+    %6 = fir.coordinate_of %1, %c2 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64_0 to %6 : !fir.ref<i64>
+    %7 = fir.embox %1 : (!fir.ref<!fir.array<3xi64>>) -> !fir.box<!fir.array<3xi64>>
+    %c1_i64_1 = arith.constant 1 : i64
+    %c0_2 = arith.constant 0 : index
+    %8 = fir.coordinate_of %0, %c0_2 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64_1 to %8 : !fir.ref<i64>
+    %c3_i64_3 = arith.constant 3 : i64
+    %c1_4 = arith.constant 1 : index
+    %9 = fir.coordinate_of %0, %c1_4 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
+    fir.store %c3_i64_3 to %9 : !fir.ref<i64>
+    %10 = fir.embox %0 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
+    mif.alloc_coarray %3 lcobounds %7 ucobounds %10 {uniq_name = "_QFEa"} : (!fir.ref<i32>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>) -> ()
+    %11:2 = hlfir.declare %3 {fir.corank = 3 : i32, uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    %c3 = arith.constant 3 : index
+    %12 = fir.alloca !fir.array<3xi32> {bindc_name = "res", uniq_name = "_QFEres"}
+    %13 = fir.shape %c3 : (index) -> !fir.shape<1>
+    %14:2 = hlfir.declare %12(%13) {uniq_name = "_QFEres"} : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<3xi32>>, !fir.ref<!fir.array<3xi32>>)
+    %c3_5 = arith.constant 3 : index
+    %15 = fir.alloca !fir.array<3xi64> {bindc_name = "res2", uniq_name = "_QFEres2"}
+    %16 = fir.shape %c3_5 : (index) -> !fir.shape<1>
+    %17:2 = hlfir.declare %15(%16) {uniq_name = "_QFEres2"} : (!fir.ref<!fir.array<3xi64>>, !fir.shape<1>) -> (!fir.ref<!fir.array<3xi64>>, !fir.ref<!fir.array<3xi64>>)
+    %18 = mif.coshape coarray %11#0 : (!fir.ref<i32>) -> !fir.box<!fir.array<?xi64>>
+    %19:2 = hlfir.declare %18 {uniq_name = ".tmp.intrinsic_result"} : (!fir.box<!fir.array<?xi64>>) -> (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>)
+    %false = arith.constant false
+    %20 = hlfir.as_expr %19#0 move %false : (!fir.box<!fir.array<?xi64>>, i1) -> !hlfir.expr<?xi64>
+    %c0_6 = arith.constant 0 : index
+    %21:3 = fir.box_dims %19#0, %c0_6 : (!fir.box<!fir.array<?xi64>>, index) -> (index, index, index)
+    %22 = fir.shape %21#1 : (index) -> !fir.shape<1>
+    %23 = hlfir.elemental %22 unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
+    ^bb0(%arg0: index):
+      %30 = hlfir.apply %20, %arg0 : (!hlfir.expr<?xi64>, index) -> i64
+      %31 = fir.convert %30 : (i64) -> i32
+      hlfir.yield_element %31 : i32
+    }
+    hlfir.assign %23 to %14#0 : !hlfir.expr<?xi32>, !fir.ref<!fir.array<3xi32>>
+    hlfir.destroy %23 : !hlfir.expr<?xi32>
+    hlfir.destroy %20 : !hlfir.expr<?xi64>
+    %24 = mif.coshape coarray %11#0 : (!fir.ref<i32>) -> !fir.box<!fir.array<?xi64>>
+    %25:2 = hlfir.declare %24 {uniq_name = ".tmp.intrinsic_result"} : (!fir.box<!fir.array<?xi64>>) -> (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>)
+    %false_7 = arith.constant false
+    %26 = hlfir.as_expr %25#0 move %false_7 : (!fir.box<!fir.array<?xi64>>, i1) -> !hlfir.expr<?xi64>
+    %c0_8 = arith.constant 0 : index
+    %27:3 = fir.box_dims %25#0, %c0_8 : (!fir.box<!fir.array<?xi64>>, index) -> (index, index, index)
+    %28 = fir.shape %27#1 : (index) -> !fir.shape<1>
+    %29 = hlfir.elemental %28 unordered : (!fir.shape<1>) -> !hlfir.expr<?xi64> {
+    ^bb0(%arg0: index):
+      %30 = hlfir.apply %26, %arg0 : (!hlfir.expr<?xi64>, index) -> i64
+      hlfir.yield_element %30 : i64
+    }
+    hlfir.assign %29 to %17#0 : !hlfir.expr<?xi64>, !fir.ref<!fir.array<3xi64>>
+    hlfir.destroy %29 : !hlfir.expr<?xi64>
+    hlfir.destroy %26 : !hlfir.expr<?xi64>
+    return
+  }
+}
+
+// CHECK-LABEL: func.func @_QQmain
+// CHECK: fir.call @_QMprifPprif_coshape
+// CHECK: fir.call @_QMprifPprif_coshape
diff --git a/flang/test/Fir/MIF/image_index.mlir b/flang/test/Fir/MIF/image_index.mlir
new file mode 100644
index 0000000000000..608dca26e8a6f
--- /dev/null
+++ b/flang/test/Fir/MIF/image_index.mlir
@@ -0,0 +1,67 @@
+// 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 23.0.0 (git at github.com:SiPearl/llvm-project.git d31a4730513391710d91c5ad33bb8ea3d68db3cb)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+// CHECK-LABEL: func.func @_QQmain
+  func.func @_QQmain() attributes {fir.bindc_name = "TEST"} {
+    %0 = fir.alloca !fir.array<2xi64>
+    %1 = fir.alloca !fir.array<3xi64>
+    %2 = fir.dummy_scope : !fir.dscope
+    %3 = fir.address_of(@_QFEa) : !fir.ref<i32>
+    %c1_i64 = arith.constant 1 : i64
+    %c0 = arith.constant 0 : index
+    %4 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64 to %4 : !fir.ref<i64>
+    %c3_i64 = arith.constant 3 : i64
+    %c1 = arith.constant 1 : index
+    %5 = fir.coordinate_of %1, %c1 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
+    fir.store %c3_i64 to %5 : !fir.ref<i64>
+    %c1_i64_0 = arith.constant 1 : i64
+    %c2 = arith.constant 2 : index
+    %6 = fir.coordinate_of %1, %c2 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64_0 to %6 : !fir.ref<i64>
+    %7 = fir.embox %1 : (!fir.ref<!fir.array<3xi64>>) -> !fir.box<!fir.array<3xi64>>
+    %c1_i64_1 = arith.constant 1 : i64
+    %c0_2 = arith.constant 0 : index
+    %8 = fir.coordinate_of %0, %c0_2 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64_1 to %8 : !fir.ref<i64>
+    %c3_i64_3 = arith.constant 3 : i64
+    %c1_4 = arith.constant 1 : index
+    %9 = fir.coordinate_of %0, %c1_4 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
+    fir.store %c3_i64_3 to %9 : !fir.ref<i64>
+    %10 = fir.embox %0 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
+    mif.alloc_coarray %3 lcobounds %7 ucobounds %10 {uniq_name = "_QFEa"} : (!fir.ref<i32>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>) -> ()
+    %11:2 = hlfir.declare %3 {fir.corank = 3 : i32, uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    %12 = fir.alloca i32 {bindc_name = "idx", uniq_name = "_QFEidx"}
+    %13:2 = hlfir.declare %12 {uniq_name = "_QFEidx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    %14 = fir.address_of(@_QFEsub) : !fir.ref<!fir.array<3xi32>>
+    %c3 = arith.constant 3 : index
+    %15 = fir.shape %c3 : (index) -> !fir.shape<1>
+    %16:2 = hlfir.declare %14(%15) {uniq_name = "_QFEsub"} : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<3xi32>>, !fir.ref<!fir.array<3xi32>>)
+    %17 = fir.address_of(@_QFEsub2) : !fir.ref<!fir.array<3xi64>>
+    %c3_5 = arith.constant 3 : index
+    %18 = fir.shape %c3_5 : (index) -> !fir.shape<1>
+    %19:2 = hlfir.declare %17(%18) {uniq_name = "_QFEsub2"} : (!fir.ref<!fir.array<3xi64>>, !fir.shape<1>) -> (!fir.ref<!fir.array<3xi64>>, !fir.ref<!fir.array<3xi64>>)
+    %20 = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}> {bindc_name = "team", uniq_name = "_QFEteam"}
+    %21:2 = hlfir.declare %20 {uniq_name = "_QFEteam"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>) -> (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>)
+    %22 = fir.address_of(@_QQ_QM__fortran_builtinsT__builtin_team_type.DerivedInit) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>
+    fir.copy %22 to %21#0 no_overlap : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>
+    %23 = fir.alloca i32 {bindc_name = "team_number", uniq_name = "_QFEteam_number"}
+    %24:2 = hlfir.declare %23 {uniq_name = "_QFEteam_number"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    %25 = fir.shape %c3 : (index) -> !fir.shape<1>
+    %26 = fir.embox %16#0(%25) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>>
+// CHECK: fir.call @_QMprifPprif_image_index
+    %27 = mif.image_index coarray %11#0 sub %26 : (!fir.ref<i32>, !fir.box<!fir.array<3xi32>>) -> i32
+    hlfir.assign %27 to %13#0 : i32, !fir.ref<i32>
+    %28 = fir.shape %c3_5 : (index) -> !fir.shape<1>
+    %29 = fir.embox %19#0(%28) : (!fir.ref<!fir.array<3xi64>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi64>>
+// CHECK: fir.call @_QMprifPprif_image_index
+    %30 = mif.image_index coarray %11#0 sub %29 : (!fir.ref<i32>, !fir.box<!fir.array<3xi64>>) -> i32
+    hlfir.assign %30 to %13#0 : i32, !fir.ref<i32>
+    %31 = fir.shape %c3 : (index) -> !fir.shape<1>
+    %32 = fir.embox %16#0(%31) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>>
+// CHECK: fir.call @_QMprifPprif_image_index_with_team
+    %33 = mif.image_index coarray %11#0 sub %32 team %21#0 : (!fir.ref<i32>, !fir.box<!fir.array<3xi32>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>) -> i32
+    hlfir.assign %33 to %13#0 : i32, !fir.ref<i32>
+    return
+  }
+}
diff --git a/flang/test/Fir/MIF/this_image.mlir b/flang/test/Fir/MIF/this_image.mlir
index 25eafc09ef58c..d68827c7cf9ba 100644
--- a/flang/test/Fir/MIF/this_image.mlir
+++ b/flang/test/Fir/MIF/this_image.mlir
@@ -2,15 +2,64 @@
 
 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>
+    %0 = fir.alloca !fir.array<1xi64>
+    %1 = fir.alloca !fir.array<2xi64>
+    %2 = fir.dummy_scope : !fir.dscope
+    %3 = fir.address_of(@_QFEa) : !fir.ref<i32>
+    %c1_i64 = arith.constant 1 : i64
+    %c0 = arith.constant 0 : index
+    %4 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64 to %4 : !fir.ref<i64>
+    %c1_i64_0 = arith.constant 1 : i64
+    %c1 = arith.constant 1 : index
+    %5 = fir.coordinate_of %1, %c1 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64_0 to %5 : !fir.ref<i64>
+    %6 = fir.embox %1 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
+    %c1_i64_1 = arith.constant 1 : i64
+    %c0_2 = arith.constant 0 : index
+    %7 = fir.coordinate_of %0, %c0_2 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64_1 to %7 : !fir.ref<i64>
+    %8 = fir.embox %0 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
+    mif.alloc_coarray %3 lcobounds %6 ucobounds %8 {uniq_name = "_QFEa"} : (!fir.ref<i32>, !fir.box<!fir.array<2xi64>>, !fir.box<!fir.array<1xi64>>) -> ()
+    %9:2 = hlfir.declare %3 {fir.corank = 2 : i32, uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    %10 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+    %11:2 = hlfir.declare %10 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    %c2 = arith.constant 2 : index
+    %12 = fir.alloca !fir.array<2xi32> {bindc_name = "j", uniq_name = "_QFEj"}
+    %13 = fir.shape %c2 : (index) -> !fir.shape<1>
+    %14:2 = hlfir.declare %12(%13) {uniq_name = "_QFEj"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>)
+    %15 = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}> {bindc_name = "team", uniq_name = "_QFEteam"}
+    %16:2 = hlfir.declare %15 {uniq_name = "_QFEteam"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>) -> (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>)
+    %17 = fir.address_of(@_QQ_QM__fortran_builtinsT__builtin_team_type.DerivedInit) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>
+    fir.copy %17 to %16#0 no_overlap : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>
+    %18 = mif.this_image : () -> i32
+    hlfir.assign %18 to %11#0 : i32, !fir.ref<i32>
+    %19 = mif.this_image team %16#0 : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>) -> i32
+    hlfir.assign %19 to %11#0 : i32, !fir.ref<i32>
+    %20 = mif.this_image coarray %9#0 : (!fir.ref<i32>) -> !fir.box<!fir.array<?xi64>>
+    %21:2 = hlfir.declare %20 {uniq_name = ".tmp.intrinsic_result"} : (!fir.box<!fir.array<?xi64>>) -> (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>)
+    %false = arith.constant false
+    %22 = hlfir.as_expr %21#0 move %false : (!fir.box<!fir.array<?xi64>>, i1) -> !hlfir.expr<?xi64>
+    %c0_3 = arith.constant 0 : index
+    %23:3 = fir.box_dims %21#0, %c0_3 : (!fir.box<!fir.array<?xi64>>, index) -> (index, index, index)
+    %24 = fir.shape %23#1 : (index) -> !fir.shape<1>
+    %25 = hlfir.elemental %24 unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
+    ^bb0(%arg0: index):
+      %27 = hlfir.apply %22, %arg0 : (!hlfir.expr<?xi64>, index) -> i64
+      %28 = fir.convert %27 : (i64) -> i32
+      hlfir.yield_element %28 : i32
+    }
+    hlfir.assign %25 to %14#0 : !hlfir.expr<?xi32>, !fir.ref<!fir.array<2xi32>>
+    hlfir.destroy %25 : !hlfir.expr<?xi32>
+    hlfir.destroy %22 : !hlfir.expr<?xi64>
+    %c1_i32 = arith.constant 1 : i32
+    %26 = mif.this_image coarray %9#0 dim %c1_i32 : (!fir.ref<i32>, i32) -> i32
+    hlfir.assign %26 to %14#0 : i32, !fir.ref<!fir.array<2xi32>>
     return
   }
 }
 
-
 // CHECK-LABEL: func.func @_QQmain
-// CHECK: fir.call @_QMprifPprif_this_image_no_coarray(
+// CHECK: fir.call @_QMprifPprif_this_image_no_coarray
+// CHECK: fir.call @_QMprifPprif_this_image_with_coarray
+// CHECK: fir.call @_QMprifPprif_this_image_with_dim
diff --git a/flang/test/Lower/MIF/cobound.f90 b/flang/test/Lower/MIF/cobound.f90
new file mode 100644
index 0000000000000..e5ad3f94d4beb
--- /dev/null
+++ b/flang/test/Lower/MIF/cobound.f90
@@ -0,0 +1,21 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
+
+program test
+  integer :: res1(3), res2
+  integer, allocatable :: a[:,:,:]
+
+  allocate(a[2,3:5,*])
+
+  ! CHECK: mif.lcobound coarray %[[COARRAY:.*]] : (!fir.heap<i32>) -> !fir.box<!fir.array<?xi64>>
+  res1 = lcobound(a)
+
+  ! CHECK: mif.lcobound coarray %[[COARRAY:.*]] dim %[[C2:.*]] : (!fir.heap<i32>, i32) -> i32
+  res2 = lcobound(a, DIM=2)
+
+  ! CHECK: mif.ucobound coarray %[[COARRAY:.*]] : (!fir.heap<i32>) -> !fir.box<!fir.array<?xi64>>
+  res1 = ucobound(a)
+
+  ! CHECK: mif.ucobound coarray %[[COARRAY:.*]] dim %[[C2:.*]] : (!fir.heap<i32>, i32) -> i32
+  res2 = ucobound(a, DIM=2)
+
+end program
diff --git a/flang/test/Lower/MIF/coshape.f90 b/flang/test/Lower/MIF/coshape.f90
new file mode 100644
index 0000000000000..da1360d26b3a6
--- /dev/null
+++ b/flang/test/Lower/MIF/coshape.f90
@@ -0,0 +1,14 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
+
+program test
+  integer :: res(3)
+  integer(kind=8) :: res2(3)
+  integer :: a[2,3:5,*]
+
+  ! CHECK: mif.coshape coarray %[[COARRAY:.*]]#0 : (!fir.ref<i32>) -> !fir.box<!fir.array<?xi64>>
+  res = coshape(a)
+
+  ! CHECK: mif.coshape coarray %[[COARRAY:.*]]#0 : (!fir.ref<i32>) -> !fir.box<!fir.array<?xi64>>
+  res2 = coshape(a)
+
+end program
diff --git a/flang/test/Lower/MIF/image_index.f90 b/flang/test/Lower/MIF/image_index.f90
new file mode 100644
index 0000000000000..88eb711679e6d
--- /dev/null
+++ b/flang/test/Lower/MIF/image_index.f90
@@ -0,0 +1,20 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
+
+program test
+  use iso_fortran_env, only: team_type
+  integer(kind=4) :: sub(3) = (/1, 4, 2/) 
+  integer(kind=8) :: sub2(3) = (/1, 4, 2/) 
+  integer(kind=4) :: a[2,3:5,*], idx
+  type(team_type) :: team
+  integer :: team_number
+
+  ! CHECK: mif.image_index coarray %[[COARRAY:.*]]#0 sub %[[SUB:.*]] : (!fir.ref<i32>, !fir.box<!fir.array<3xi32>>) -> i32
+  idx = image_index(a, SUB=sub)
+
+  ! CHECK: mif.image_index coarray %[[COARRAY:.*]]#0 sub %[[SUB2:.*]] : (!fir.ref<i32>, !fir.box<!fir.array<3xi64>>) -> i32
+  idx = image_index(a, SUB=sub2)
+
+  ! CHECK: mif.image_index coarray %[[COARRAY:.*]]#0 sub %[[SUB2:.*]] team %[[TEAM:.*]]#0 : (!fir.ref<i32>, !fir.box<!fir.array<3xi32>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>)
+  idx = image_index(a, SUB=sub, TEAM=team)
+
+end program
diff --git a/flang/test/Lower/MIF/this_image.f90 b/flang/test/Lower/MIF/this_image.f90
index c6674c309f3f4..1d33646155d18 100644
--- a/flang/test/Lower/MIF/this_image.f90
+++ b/flang/test/Lower/MIF/this_image.f90
@@ -1,9 +1,10 @@
 ! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
 
 program test
-  use iso_fortran_env
-  integer :: i
+  use iso_fortran_env, only: team_type
+  integer :: i, j(2)
   type(team_type) :: team
+  integer :: a[2,*]
 
   ! CHECK: mif.this_image : () -> i32
   i = this_image()
@@ -11,4 +12,9 @@ program test
   ! CHECK: mif.this_image team %[[TEAM:.*]] : ({{.*}}) -> i32
   i = this_image(TEAM=team)
 
+  ! CHECK: mif.this_image coarray %[[A:.*]] : ({{.*}}) -> !fir.box<!fir.array<?xi64>>
+  j = this_image(COARRAY=a)
+  
+  ! CHECK: mif.this_image coarray %[[A:.*]]#0 dim %[[DIM:.*]] : ({{.*}}) -> i32
+  j = this_image(COARRAY=a, DIM=1)
 end program

>From 50b73eb49c2828becc9d7a078543119c2cac904f Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Mon, 20 Apr 2026 13:25:19 +0200
Subject: [PATCH 2/5] Fix formating issue

---
 .../Optimizer/Transforms/MIFOpConversion.cpp  | 21 ++++++++++---------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
index ba6a0a91d3d9b..db25941a269a0 100644
--- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
@@ -1390,14 +1390,15 @@ void mif::populateMIFOpConversionPatterns(
     mlir::RewritePatternSet &patterns) {
   patterns.insert<MIFAllocCoarrayOpConversion>(patterns.getContext(), &dl,
                                                &converter);
-  patterns.insert<
-      MIFInitOpConversion, MIFThisImageOpConversion, MIFNumImagesOpConversion,
-      MIFSyncAllOpConversion, MIFSyncImagesOpConversion,
-      MIFSyncMemoryOpConversion, MIFSyncTeamOpConversion,
-      MIFCoBroadcastOpConversion, MIFCoMaxOpConversion, MIFCoMinOpConversion,
-      MIFCoSumOpConversion, MIFFormTeamOpConversion, MIFChangeTeamOpConversion,
-      MIFGetTeamOpConversion, MIFTeamNumberOpConversion,
-      MIFDeallocCoarrayOpConversion, MIFCoshapeOpConversion,
-      MIFLcoboundOpConversion, MIFUcoboundOpConversion,
-      MIFImageIndexOpConversion>(patterns.getContext());
+  patterns.insert<MIFInitOpConversion, MIFThisImageOpConversion,
+                  MIFNumImagesOpConversion, MIFSyncAllOpConversion,
+                  MIFSyncImagesOpConversion, MIFSyncMemoryOpConversion,
+                  MIFSyncTeamOpConversion, MIFCoBroadcastOpConversion,
+                  MIFCoMaxOpConversion, MIFCoMinOpConversion,
+                  MIFCoSumOpConversion, MIFFormTeamOpConversion,
+                  MIFChangeTeamOpConversion, MIFGetTeamOpConversion,
+                  MIFTeamNumberOpConversion, MIFDeallocCoarrayOpConversion,
+                  MIFCoshapeOpConversion, MIFLcoboundOpConversion,
+                  MIFUcoboundOpConversion, MIFImageIndexOpConversion>(
+      patterns.getContext());
 }

>From 547d7d5805fdf4cb459be056f04e6cf2633bf236 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Mon, 20 Apr 2026 14:19:16 +0200
Subject: [PATCH 3/5] Remove useless variable

---
 flang/lib/Optimizer/Transforms/MIFOpConversion.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
index db25941a269a0..c8318cd1827d2 100644
--- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
@@ -1308,7 +1308,6 @@ struct MIFImageIndexOpConversion
     mlir::Value result = builder.createTemporary(loc, i32Ty);
 
     mlir::func::FuncOp funcOp;
-    mlir::FunctionType ftype;
     llvm::SmallVector<mlir::Value> args;
     mlir::Value coarrayHandle = getCoarrayHandle(builder, loc, op.getCoarray());
     if (!op.getTeam()) {

>From 178f1c9464b6d7c57c6a74b6a7fc8ff33771e946 Mon Sep 17 00:00:00 2001
From: Jean-Didier PAILLEUX <jean-di.pailleux at outlook.com>
Date: Mon, 4 May 2026 11:22:24 +0200
Subject: [PATCH 4/5] Apply suggestions from code review

Co-authored-by: Dan Bonachea <dobonachea at lbl.gov>
---
 flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td | 6 +++---
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp       | 4 ++--
 flang/lib/Optimizer/Transforms/MIFOpConversion.cpp  | 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
index f39ea71e93ffd..5342b2b42d8a2 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -135,9 +135,9 @@ def mif_ImageIndexOp : mif_Op<"image_index", [AttrSizedOperandSegments]> {
         of the current team.
 
     Usage:
-    - Case(1) : `call image_index(coarray, sub)`
-    - Case(2) : `call image_index(coarray, sub, team)`
-    - Case(3) : `call image_index(coarray, sub, team_number)`
+    - Case(1) : `image_index(coarray, sub)`
+    - Case(2) : `image_index(coarray, sub, team)`
+    - Case(3) : `image_index(coarray, sub, team_number)`
 
     Result: If the value of `sub` is a valid sequence of cosubscripts for `coarray` in the
       team specified by `team` or `team_number`, or the current team if neither `team` nor
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index dd1c0dcd6d069..a4d386798d87a 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -246,7 +246,7 @@ static constexpr IntrinsicHandler handlers[]{
     {"coshape",
      &I::genCoshape,
      {{{"coarray", asAddr}, {"kind", asValue}}},
-     false},
+     /*isElemental=*/false},
     {"cospi", &I::genCospi},
     {"count",
      &I::genCount,
@@ -508,7 +508,7 @@ static constexpr IntrinsicHandler handlers[]{
      {{{"coarray", asAddr},
        {"sub", asBox},
        {"team", asAddr},
-       {"team_number", asAddr}}},
+       {"team_number", asValue}}},
      /*isElemental*/ false},
     {"index",
      &I::genIndex,
diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
index c8318cd1827d2..88f20180e6fa1 100644
--- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
@@ -1323,8 +1323,8 @@ struct MIFImageIndexOpConversion
       mlir::Value team = op.getTeam();
       std::string imageIndexName =
           fir::unwrapPassByRefType(team.getType()).isInteger()
-              ? getPRIFProcName("image_index_with_team")
-              : getPRIFProcName("image_index_with_team_number");
+              ? getPRIFProcName("image_index_with_team_number")
+              : getPRIFProcName("image_index_with_team");
       mlir::Type teamTy = fir::unwrapPassByRefType(team.getType()).isInteger()
                               ? builder.getRefType(i64Ty)
                               : boxTy;

>From 3c87111ef3137f9cc30c24ec3b94d8fb5cff8fa7 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Tue, 19 May 2026 14:37:37 +0200
Subject: [PATCH 5/5] [Flang][MIF] Adding fir::CoarrayType and update
 mif.lcobound and mif.ucobound with dim as a non optional

- DIM isn't optional anymore related to @jeanPerier feedback on theses
  operations
- Ensure that fir.coarray don't break what already exists
- Update tests
---
 .../flang/Optimizer/Builder/BoxValue.h        |   2 +-
 .../include/flang/Optimizer/Dialect/FIRType.h |  39 ++-
 .../flang/Optimizer/Dialect/FIRTypes.td       |  31 ++
 .../Dialect/FortranVariableInterface.td       |   6 +-
 .../flang/Optimizer/Dialect/MIF/MIFOps.td     |  59 ++--
 .../flang/Optimizer/HLFIR/HLFIRDialect.h      |   4 +-
 flang/lib/Lower/Allocatable.cpp               |   2 +
 flang/lib/Lower/ConvertType.cpp               |   2 +
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp |  44 ++-
 flang/lib/Optimizer/Builder/MutableBox.cpp    |   2 +-
 flang/lib/Optimizer/CodeGen/CodeGen.cpp       |   8 +-
 flang/lib/Optimizer/CodeGen/TypeConverter.cpp |  11 +-
 flang/lib/Optimizer/Dialect/FIRCG/CGOps.cpp   |   8 +-
 flang/lib/Optimizer/Dialect/FIROps.cpp        |  15 +-
 flang/lib/Optimizer/Dialect/FIRType.cpp       |  49 ++-
 flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp    |  60 +---
 .../Optimizer/Transforms/MIFOpConversion.cpp  |  67 ++--
 flang/test/Fir/MIF/coarray-alloc.mlir         | 316 ++++++++----------
 flang/test/Fir/MIF/cobound.mlir               | 116 ++++---
 flang/test/Fir/MIF/coshape.mlir               |  10 +-
 flang/test/Fir/MIF/image_index.mlir           |  12 +-
 flang/test/Fir/MIF/this_image.mlir            |  19 +-
 flang/test/Lower/MIF/coarray_allocation.f90   |  34 +-
 flang/test/Lower/MIF/coarray_allocation2.f90  |  22 +-
 flang/test/Lower/MIF/cobound.f90              |  12 +-
 flang/test/Lower/MIF/coshape.f90              |   4 +-
 flang/test/Lower/MIF/image_index.f90          |   6 +-
 flang/test/Lower/MIF/this_image.f90           |   7 +-
 28 files changed, 502 insertions(+), 465 deletions(-)

diff --git a/flang/include/flang/Optimizer/Builder/BoxValue.h b/flang/include/flang/Optimizer/Builder/BoxValue.h
index 43b70943aced6..7441ae71c1c84 100644
--- a/flang/include/flang/Optimizer/Builder/BoxValue.h
+++ b/flang/include/flang/Optimizer/Builder/BoxValue.h
@@ -241,7 +241,7 @@ class AbstractIrBox : public AbstractBox, public AbstractArrayBox {
 
   /// Get the scalar type related to the described entity
   mlir::Type getEleTy() const {
-    auto type = getBaseTy();
+    auto type = fir::unwrapCoarrayType(getBaseTy());
     if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(type))
       return seqTy.getEleTy();
     return type;
diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h
index f67cc3ed5db34..8ba8d1203584d 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRType.h
+++ b/flang/include/flang/Optimizer/Dialect/FIRType.h
@@ -154,8 +154,17 @@ inline bool conformsWithPassByRef(mlir::Type t) {
   return isa_ref_type(t) || isa_box_type(t) || mlir::isa<mlir::FunctionType>(t);
 }
 
+/// Unwrap a coarray type by returning the element type.
+/// e.g.,
+///   !fir.coarray<T, N>  ->  T
+/// otherwise
+///   T -> T
+mlir::Type unwrapCoarrayType(mlir::Type ty);
+
 /// Is `t` a derived (record) type?
-inline bool isa_derived(mlir::Type t) { return mlir::isa<fir::RecordType>(t); }
+inline bool isa_derived(mlir::Type t) {
+  return mlir::isa<fir::RecordType>(fir::unwrapCoarrayType(t));
+}
 
 /// Is `t` type(c_ptr) or type(c_funptr)?
 inline bool isa_builtin_cptr_type(mlir::Type t) {
@@ -193,11 +202,14 @@ mlir::Type dyn_cast_ptrEleTy(mlir::Type t);
 mlir::Type dyn_cast_ptrOrBoxEleTy(mlir::Type t);
 
 /// Is `t` a real type?
-inline bool isa_real(mlir::Type t) { return mlir::isa<mlir::FloatType>(t); }
+inline bool isa_real(mlir::Type t) {
+  return mlir::isa<mlir::FloatType>(fir::unwrapCoarrayType(t));
+}
 
 /// Is `t` an integral type?
 inline bool isa_integer(mlir::Type t) {
-  return mlir::isa<mlir::IndexType, mlir::IntegerType, fir::IntegerType>(t);
+  return mlir::isa<mlir::IndexType, mlir::IntegerType, fir::IntegerType>(
+      fir::unwrapCoarrayType(t));
 }
 
 /// Is `t` a vector type?
@@ -215,13 +227,16 @@ void verifyIntegralType(mlir::Type type);
 
 /// Is `t` a floating point complex type?
 inline bool isa_complex(mlir::Type t) {
+  t = fir::unwrapCoarrayType(t);
   return mlir::isa<mlir::ComplexType>(t) &&
          mlir::isa<mlir::FloatType>(
              mlir::cast<mlir::ComplexType>(t).getElementType());
 }
 
 /// Is `t` a CHARACTER type? Does not check the length.
-inline bool isa_char(mlir::Type t) { return mlir::isa<fir::CharacterType>(t); }
+inline bool isa_char(mlir::Type t) {
+  return mlir::isa<fir::CharacterType>(fir::unwrapCoarrayType(t));
+}
 
 /// Is `t` a trivial intrinsic type? CHARACTER is <em>excluded</em> because it
 /// is a dependent type.
@@ -343,6 +358,19 @@ inline fir::SequenceType unwrapUntilSeqType(mlir::Type t) {
   }
 }
 
+/// Unwrap all pointer and box types and return the element type.
+inline mlir::Type unwrapUntilElemType(mlir::Type t) {
+  while (true) {
+    if (!t)
+      return {};
+    if (auto ty = dyn_cast_ptrOrBoxEleTy(t)) {
+      t = ty;
+      continue;
+    }
+    break;
+  }
+  return t;
+}
 /// Unwrap the referential and sequential outer types (if any). Returns the
 /// the element if type is fir::RecordType
 inline fir::RecordType unwrapIfDerived(fir::BaseBoxType boxTy) {
@@ -406,6 +434,9 @@ bool isUnlimitedPolymorphicType(mlir::Type ty);
 /// Return true if CLASS(*)
 bool isClassStarType(mlir::Type ty);
 
+/// Return true iff `ty` is the type of an coarray entity or value.
+bool isCoarrayType(mlir::Type ty);
+
 /// Return true iff `ty` is the type of an assumed type. In FIR,
 /// assumed types are of the form `[fir.ref|ptr|heap]fir.box<[fir.array]none>`,
 /// or `fir.ref|ptr|heap<[fir.array]none>`.
diff --git a/flang/include/flang/Optimizer/Dialect/FIRTypes.td b/flang/include/flang/Optimizer/Dialect/FIRTypes.td
index c58d75851349e..939b8d88bcf1c 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRTypes.td
+++ b/flang/include/flang/Optimizer/Dialect/FIRTypes.td
@@ -588,6 +588,21 @@ def fir_DummyScopeType : FIR_Type<"DummyScope", "dscope"> {
   }];
 }
 
+def fir_CoarrayType : FIR_Type<"Coarray", "coarray"> {
+  let summary = "FIR coarray wrapper type";
+  let description = [{
+    Wraps any FIR/builtin type to indicate it is a coarray variable.
+    `fir.coarray<i32, 2>` = coarray of i32 with corank 2.
+  }];
+
+  let parameters = (ins "mlir::Type":$eleTy, "unsigned":$corank);
+  let extraClassDeclaration = [{
+    mlir::Type getElementType() const { return getEleTy(); }
+  }];
+  let assemblyFormat = "`<` $eleTy `,` $corank `>`";
+  let genVerifyDecl = 0;
+}
+
 // Whether a type is a BaseBoxType
 def IsBaseBoxTypePred
         : CPred<"mlir::isa<::fir::BaseBoxType>($_self)">;
@@ -688,4 +703,20 @@ def AnyBoxedArray
     : TypeConstraint<And<[BoxOrClassType.predicate, IsArrayBoxPred]>,
                      "any boxed array">;
 
+def AnyRefCoarrayLike
+    : TypeConstraint<And<[AnyReferenceLike.predicate,
+                          CPred<"mlir::isa<fir::CoarrayType>("
+                                "::fir::unwrapUntilElemType($_self))">]>,
+                     "any reference coarray">;
+def AnyRefCoarrayType
+    : Type<AnyRefCoarrayLike.predicate, "any reference coarray type">;
+
+def AnyRefOrBoxCoarrayLike
+    : TypeConstraint<And<[AnyRefOrBoxLike.predicate,
+                          CPred<"mlir::isa<fir::CoarrayType>("
+                                "::fir::unwrapUntilElemType($_self))">]>,
+                     "any reference or box coarray">;
+def AnyRefOrBoxCoarrayType : Type<AnyRefOrBoxCoarrayLike.predicate,
+                                  "any reference or box coarray type">;
+
 #endif // FIR_DIALECT_FIR_TYPES
diff --git a/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td b/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td
index 4bdb13fb54708..69696285c0660 100644
--- a/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td
+++ b/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td
@@ -80,7 +80,7 @@ def fir_FortranVariableOpInterface : OpInterface<"FortranVariableOpInterface"> {
     /// Get the sequence type or scalar value type corresponding to this
     /// variable.
     mlir::Type getElementOrSequenceType() {
-      mlir::Type type = fir::unwrapPassByRefType(fir::unwrapRefType(getBase().getType()));
+      mlir::Type type = fir::unwrapCoarrayType(fir::unwrapPassByRefType(fir::unwrapRefType(getBase().getType())));
       if (auto boxCharType = mlir::dyn_cast<fir::BoxCharType>(type))
         return boxCharType.getEleTy();
       return type;
@@ -88,12 +88,12 @@ def fir_FortranVariableOpInterface : OpInterface<"FortranVariableOpInterface"> {
 
     /// Get the scalar value type corresponding to this variable.
     mlir::Type getElementType() {
-      return fir::unwrapSequenceType(getElementOrSequenceType());
+      return fir::unwrapCoarrayType(fir::unwrapSequenceType(getElementOrSequenceType()));
     }
 
     /// Is the variable an array?
     bool isArray() {
-      return mlir::isa<fir::SequenceType>(getElementOrSequenceType());
+      return mlir::isa<fir::SequenceType>(fir::unwrapCoarrayType(getElementOrSequenceType()));
     }
 
     /// Return the rank of the entity if it is known at compile time.
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
index 5342b2b42d8a2..c762057a26962 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -162,59 +162,43 @@ def mif_ImageIndexOp : mif_Op<"image_index", [AttrSizedOperandSegments]> {
 }
 
 def mif_LcoboundOp : mif_Op<"lcobound", [NoMemoryEffect]> {
-  let summary = "Returns the lower cobound(s) associated with a coarray.";
+  let summary =
+      "Returns the lower cobound for a given codimension of a coarray.";
   let description = [{
-    This operation returns the lower cobound(s) associated with a coarray.
+    This operation returns the lower cobound for a given codimension of a coarray.
     Arguments: 
-      - `coarray`: Shall be a coarray of any type.
-      - `dim`(optional) : Shall be an integer scalar. Its value shall be in the range of
+      - `coarray`: Shall be a reference or a boxed 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.
-    Results:
-      - Case(1): If `dim` is present, the result is an integer scalar equal to
-        the lower cobound for codimension `dim`.
-      - Case(2): `dim` is absent, so the result is an array whose size matches
-        the corank of the indicated coarray.
+    The result is an integer scalar equal to the lower cobound for codimension `dim`.
   }];
 
-  let arguments = (ins AnyType:$coarray, Optional<AnyInteger>:$dim);
-  let results = (outs AnyType);
-
-  let builders = [OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$dim)>,
-                  OpBuilder<(ins "mlir::Value":$coarray)>];
+  let arguments = (ins AnyRefOrBoxCoarrayType:$coarray, AnyInteger:$dim);
+  let results = (outs AnyInteger);
 
-  let hasVerifier = 1;
   let assemblyFormat = [{
-    `coarray` $coarray 
-    ( `dim` $dim^ )? 
+    `coarray` $coarray `dim` $dim 
     attr-dict `:` functional-type(operands, results)
   }];
 }
 
 def mif_UcoboundOp : mif_Op<"ucobound", [NoMemoryEffect]> {
-  let summary = "Returns the upper cobound(s) associated with a coarray.";
+  let summary =
+      "Returns the upper cobound for a given codimension of a coarray.";
   let description = [{
-    This operation returns the upper cobound(s) associated with a coarray.
+    This operation returns the upper cobound for a given codimension of a coarray.
     Arguments: 
-      - `coarray`: Shall be a coarray of any type.
-      - `dim`(optional) : Shall be an integer scalar. Its value shall be in the range of
+      - `coarray`: Shall be a reference or a boxed 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.
-    Results:
-      - Case(1): If `dim` is present, the result is an integer scalar equal to
-        the upper cobound for codimension `dim`.
-      - Case(2): `dim` is absent, so the result is an array whose size matches
-        the corank of the indicated coarray.
+    The result is an integer scalar equal to the upper cobound for codimension `dim`.
   }];
 
-  let arguments = (ins AnyType:$coarray, Optional<AnyInteger>:$dim);
-  let results = (outs AnyType);
+  let arguments = (ins AnyRefOrBoxCoarrayType:$coarray, AnyInteger:$dim);
+  let results = (outs AnyInteger);
 
-  let builders = [OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$dim)>,
-                  OpBuilder<(ins "mlir::Value":$coarray)>];
-
-  let hasVerifier = 1;
   let assemblyFormat = [{
-    `coarray` $coarray 
-    ( `dim` $dim^ )? 
+    `coarray` $coarray `dim` $dim
     attr-dict `:` functional-type(operands, results)
   }];
 }
@@ -227,11 +211,10 @@ def mif_CoshapeOp : mif_Op<"coshape", [NoMemoryEffect]> {
        returns `UCOBOUND - LCOBOUND + 1`.
   }];
 
-  let arguments = (ins AnyType:$coarray);
+  let arguments = (ins AnyRefOrBoxCoarrayType:$coarray);
   let builders = [OpBuilder<(ins "mlir::Value":$coarray)>];
   let results = (outs AnyBoxedArray);
 
-  let hasVerifier = 1;
   let assemblyFormat = [{
     `coarray` $coarray 
     attr-dict `:` functional-type(operands, results)
@@ -564,7 +547,7 @@ def mif_AllocCoarrayOp
   }];
 
   let arguments = (ins StrAttr:$uniq_name,
-      Arg<fir_ReferenceType, "", [MemRead, MemWrite]>:$box,
+      Arg<AnyRefCoarrayType, "", [MemRead, MemWrite]>:$box,
       AnyBoxedArray:$lcobounds, AnyBoxedArray:$ucobounds,
       Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
       Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
@@ -592,7 +575,7 @@ def mif_DeallocCoarrayOp
   let description = [{
     This call releases memory allocated by `mif_AllocCoarrayOp` for a coarray.
   }];
-  let arguments = (ins Arg<fir_ReferenceType, "", [MemFree]>:$coarray,
+  let arguments = (ins Arg<AnyRefCoarrayType, "", [MemFree]>:$coarray,
       Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
       Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
 
diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h b/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h
index 5152dee14ad65..291168dc521da 100644
--- a/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h
+++ b/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h
@@ -38,8 +38,8 @@ bool isFortranArrayCharacterExprType(mlir::Type);
 namespace hlfir {
 /// Get the element type of a Fortran entity type.
 inline mlir::Type getFortranElementType(mlir::Type type) {
-  type = fir::unwrapSequenceType(
-      fir::unwrapPassByRefType(fir::unwrapRefType(type)));
+  type = fir::unwrapCoarrayType(fir::unwrapSequenceType(
+      fir::unwrapPassByRefType(fir::unwrapRefType(type))));
   if (auto exprType = mlir::dyn_cast<hlfir::ExprType>(type))
     return exprType.getEleTy();
   if (auto boxCharType = mlir::dyn_cast<fir::BoxCharType>(type))
diff --git a/flang/lib/Lower/Allocatable.cpp b/flang/lib/Lower/Allocatable.cpp
index 5cbfba23cffdf..338214223ab57 100644
--- a/flang/lib/Lower/Allocatable.cpp
+++ b/flang/lib/Lower/Allocatable.cpp
@@ -1113,6 +1113,8 @@ createMutableProperties(Fortran::lower::AbstractConverter &converter,
   mlir::Type eleTy = baseAddrTy;
   if (auto newTy = fir::dyn_cast_ptrEleTy(eleTy))
     eleTy = newTy;
+  if (auto coarrayTy = mlir::dyn_cast<fir::CoarrayType>(eleTy))
+    eleTy = coarrayTy.getEleTy();
   if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(eleTy))
     eleTy = seqTy.getEleTy();
   if (auto record = mlir::dyn_cast<fir::RecordType>(eleTy))
diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp
index 0d343968374f0..50c29cca718dc 100644
--- a/flang/lib/Lower/ConvertType.cpp
+++ b/flang/lib/Lower/ConvertType.cpp
@@ -293,6 +293,8 @@ struct TypeBuilderImpl {
     bool isPolymorphic = (Fortran::semantics::IsPolymorphic(symbol) ||
                           Fortran::semantics::IsUnlimitedPolymorphic(symbol)) &&
                          !Fortran::semantics::IsAssumedType(symbol);
+    if (Fortran::evaluate::IsCoarray(symbol))
+      ty = fir::CoarrayType::get(context, ty, symbol.Corank());
     if (Fortran::semantics::IsPointer(symbol))
       return fir::wrapInClassOrBoxType(fir::PointerType::get(ty),
                                        isPolymorphic);
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index a4d386798d87a..88e4400eb696f 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -8435,7 +8435,27 @@ IntrinsicLibrary::genLcobound(mlir::Type resultType,
     mlir::Value dim = fir::getBase(args[1]);
     return mif::LcoboundOp::create(builder, loc, resultType, coarray, dim);
   }
-  return mif::LcoboundOp::create(builder, loc, coarray);
+
+  fir::CoarrayType coType = mlir::dyn_cast<fir::CoarrayType>(
+      fir::unwrapPassByRefType(coarray.getType()));
+  int corank = coType.getCorank();
+  mlir::Type arrTy = fir::SequenceType::get(
+      {static_cast<fir::SequenceType::Extent>(corank)}, resultType);
+  mlir::Value lcobound = fir::AllocaOp::create(builder, loc, arrTy);
+
+  mlir::Type idxTy = builder.getIndexType();
+  for (int d = 1; d <= corank; ++d) {
+    mlir::Value dim = builder.createIntegerConstant(loc, resultType, d);
+    mlir::Value lcb =
+        mif::LcoboundOp::create(builder, loc, resultType, coarray, dim);
+
+    mlir::Value idx = builder.createIntegerConstant(loc, idxTy, d - 1);
+    mlir::Value gep = fir::CoordinateOp::create(
+        builder, loc, fir::ReferenceType::get(resultType), lcobound,
+        mlir::ValueRange{idx});
+    fir::StoreOp::create(builder, loc, lcb, gep);
+  }
+  return builder.createBox(loc, lcobound);
 }
 
 // UBOUND
@@ -8473,7 +8493,27 @@ IntrinsicLibrary::genUcobound(mlir::Type resultType,
     mlir::Value dim = fir::getBase(args[1]);
     return mif::UcoboundOp::create(builder, loc, resultType, coarray, dim);
   }
-  return mif::UcoboundOp::create(builder, loc, coarray);
+
+  fir::CoarrayType coType = mlir::dyn_cast<fir::CoarrayType>(
+      fir::unwrapPassByRefType(coarray.getType()));
+  int corank = coType.getCorank();
+  mlir::Type arrTy = fir::SequenceType::get(
+      {static_cast<fir::SequenceType::Extent>(corank)}, resultType);
+  mlir::Value ucobound = fir::AllocaOp::create(builder, loc, arrTy);
+
+  mlir::Type idxTy = builder.getIndexType();
+  for (int d = 1; d <= corank; ++d) {
+    mlir::Value dim = builder.createIntegerConstant(loc, resultType, d);
+    mlir::Value ucb =
+        mif::UcoboundOp::create(builder, loc, resultType, coarray, dim);
+
+    mlir::Value idx = builder.createIntegerConstant(loc, idxTy, d - 1);
+    mlir::Value gep = fir::CoordinateOp::create(
+        builder, loc, fir::ReferenceType::get(resultType), ucobound,
+        mlir::ValueRange{idx});
+    fir::StoreOp::create(builder, loc, ucb, gep);
+  }
+  return builder.createBox(loc, ucobound);
 }
 
 // SPACING
diff --git a/flang/lib/Optimizer/Builder/MutableBox.cpp b/flang/lib/Optimizer/Builder/MutableBox.cpp
index bcec49b3e3c8e..929d93e9f3677 100644
--- a/flang/lib/Optimizer/Builder/MutableBox.cpp
+++ b/flang/lib/Optimizer/Builder/MutableBox.cpp
@@ -351,7 +351,7 @@ mlir::Value fir::factory::createUnallocatedBox(
   if (isAssumedRank)
     baseBoxType = baseBoxType.getBoxTypeWithNewShape(/*rank=*/0);
   auto baseAddrType = baseBoxType.getBaseAddressType();
-  auto type = fir::unwrapRefType(baseAddrType);
+  auto type = fir::unwrapCoarrayType(fir::unwrapRefType(baseAddrType));
   auto eleTy = fir::unwrapSequenceType(type);
   if (auto recTy = mlir::dyn_cast<fir::RecordType>(eleTy))
     if (recTy.getNumLenParams() > 0)
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index b03b169e0af4f..1a49ae7ca6773 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -1657,6 +1657,8 @@ struct EmboxCommonConversion : public fir::FIROpConversion<OP> {
     auto i64Ty = mlir::IntegerType::get(rewriter.getContext(), 64);
     if (auto eleTy = fir::dyn_cast_ptrEleTy(boxEleTy))
       boxEleTy = eleTy;
+    if (auto coarrayTy = mlir::dyn_cast<fir::CoarrayType>(boxEleTy))
+      return getSizeAndTypeCode(loc, rewriter, coarrayTy.getEleTy(), lenParams);
     if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(boxEleTy))
       return getSizeAndTypeCode(loc, rewriter, seqTy.getEleTy(), lenParams);
     if (mlir::isa<mlir::NoneType>(
@@ -2175,7 +2177,8 @@ struct XEmboxOpConversion : public EmboxCommonConversion<fir::cg::XEmboxOp> {
     llvm::SmallVector<mlir::Value> cstInteriorIndices;
     unsigned constRows = 0;
     mlir::Value ptrOffset = zero;
-    mlir::Type memEleTy = fir::dyn_cast_ptrEleTy(xbox.getMemref().getType());
+    mlir::Type memEleTy = fir::unwrapCoarrayType(
+        fir::dyn_cast_ptrEleTy(xbox.getMemref().getType()));
     assert(mlir::isa<fir::SequenceType>(memEleTy));
     auto seqTy = mlir::cast<fir::SequenceType>(memEleTy);
     mlir::Type seqEleTy = seqTy.getEleTy();
@@ -2579,7 +2582,8 @@ struct XReboxOpConversion : public EmboxCommonConversion<fir::cg::XReboxOp> {
 
   /// Return scalar element type of the input box.
   static mlir::Type getInputEleTy(fir::cg::XReboxOp rebox) {
-    auto ty = fir::dyn_cast_ptrOrBoxEleTy(rebox.getBox().getType());
+    auto ty = fir::unwrapCoarrayType(
+        fir::dyn_cast_ptrOrBoxEleTy(rebox.getBox().getType()));
     if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(ty))
       return seqTy.getEleTy();
     return ty;
diff --git a/flang/lib/Optimizer/CodeGen/TypeConverter.cpp b/flang/lib/Optimizer/CodeGen/TypeConverter.cpp
index 3c4162c4d8298..af4f2c85990bf 100644
--- a/flang/lib/Optimizer/CodeGen/TypeConverter.cpp
+++ b/flang/lib/Optimizer/CodeGen/TypeConverter.cpp
@@ -60,6 +60,9 @@ LLVMTypeConverter::LLVMTypeConverter(mlir::ModuleOp module, bool applyTBAA,
   LLVM_DEBUG(llvm::dbgs() << "FIR type converter\n");
 
   // Each conversion should return a value of type mlir::Type.
+  addConversion([&](fir::CoarrayType coarray) {
+    return convertType(coarray.getEleTy());
+  });
   addConversion([&](BoxType box) { return convertBoxType(box); });
   addConversion([&](BoxCharType boxchar) {
     LLVM_DEBUG(llvm::dbgs() << "type convert: " << boxchar << '\n');
@@ -184,7 +187,7 @@ LLVMTypeConverter::convertRecordType(fir::RecordType derived,
 // Is an extended descriptor needed given the element type of a fir.box type ?
 // Extended descriptors are required for derived types.
 bool LLVMTypeConverter::requiresExtendedDesc(mlir::Type boxElementType) const {
-  auto eleTy = fir::unwrapSequenceType(boxElementType);
+  auto eleTy = fir::unwrapSequenceType(fir::unwrapCoarrayType(boxElementType));
   return mlir::isa<fir::RecordType>(eleTy);
 }
 
@@ -198,6 +201,8 @@ mlir::Type LLVMTypeConverter::convertBoxTypeAsStruct(BaseBoxType box,
   // remove fir.heap/fir.ref/fir.ptr
   if (auto removeIndirection = fir::dyn_cast_ptrEleTy(ele))
     ele = removeIndirection;
+  // remove fir.coarray
+  ele = fir::unwrapCoarrayType(ele);
   auto eleTy = convertType(ele);
   // base_addr*
   if (mlir::isa<SequenceType>(ele) &&
@@ -245,8 +250,8 @@ mlir::Type LLVMTypeConverter::convertBoxTypeAsStruct(BaseBoxType box,
     auto rowTy =
         getExtendedDescFieldTypeModel<kOptRowTypePosInBox>()(&getContext());
     dataDescFields.push_back(mlir::LLVM::LLVMArrayType::get(rowTy, 1));
-    if (auto recTy =
-            mlir::dyn_cast<fir::RecordType>(fir::unwrapSequenceType(ele)))
+    if (auto recTy = mlir::dyn_cast<fir::RecordType>(
+            fir::unwrapSequenceType(fir::unwrapCoarrayType(ele))))
       if (recTy.getNumLenParams() > 0) {
         // The descriptor design needs to be clarified regarding the number of
         // length parameters in the addendum. Since it can change for
diff --git a/flang/lib/Optimizer/Dialect/FIRCG/CGOps.cpp b/flang/lib/Optimizer/Dialect/FIRCG/CGOps.cpp
index 19ad6bed512c7..67dbc20ee86a4 100644
--- a/flang/lib/Optimizer/Dialect/FIRCG/CGOps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRCG/CGOps.cpp
@@ -42,14 +42,14 @@ unsigned fir::cg::XEmboxOp::getOutRank() {
 
 unsigned fir::cg::XReboxOp::getOutRank() {
   if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(
-          fir::dyn_cast_ptrOrBoxEleTy(getType())))
+          fir::unwrapCoarrayType(fir::dyn_cast_ptrOrBoxEleTy(getType()))))
     return seqTy.getDimension();
   return 0;
 }
 
 unsigned fir::cg::XReboxOp::getRank() {
-  if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(
-          fir::dyn_cast_ptrOrBoxEleTy(getBox().getType())))
+  if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(fir::unwrapCoarrayType(
+          fir::dyn_cast_ptrOrBoxEleTy(getBox().getType()))))
     return seqTy.getDimension();
   return 0;
 }
@@ -58,7 +58,7 @@ unsigned fir::cg::XArrayCoorOp::getRank() {
   auto memrefTy = getMemref().getType();
   if (mlir::isa<fir::BaseBoxType>(memrefTy))
     if (auto seqty = mlir::dyn_cast<fir::SequenceType>(
-            fir::dyn_cast_ptrOrBoxEleTy(memrefTy)))
+            fir::unwrapCoarrayType(fir::dyn_cast_ptrOrBoxEleTy(memrefTy))))
       return seqty.getDimension();
   return getShape().size();
 }
diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index 405ada36a0037..1a09ba71c2a63 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -1887,6 +1887,16 @@ static bool areRecordsCompatible(mlir::Type inTy, mlir::Type outTy) {
 bool fir::ConvertOp::canBeConverted(mlir::Type inType, mlir::Type outType) {
   if (inType == outType)
     return true;
+  if (mlir::isa<fir::CoarrayType>(inType) &&
+      mlir::isa<fir::CoarrayType>(outType)) {
+    fir::CoarrayType coOutType = mlir::dyn_cast<fir::CoarrayType>(outType);
+    fir::CoarrayType coInType = mlir::dyn_cast<fir::CoarrayType>(inType);
+    if (coInType.getCorank() != coOutType.getCorank())
+      return false;
+    inType = fir::unwrapCoarrayType(inType);
+  }
+  outType = fir::unwrapCoarrayType(outType);
+
   return (isPointerCompatible(inType) && isPointerCompatible(outType)) ||
          (isIntegerCompatible(inType) && isIntegerCompatible(outType)) ||
          (isInteger(inType) && isFloatCompatible(outType)) ||
@@ -2310,7 +2320,8 @@ verifyEmboxOpVolatilityInvariants(mlir::Type memrefType,
 }
 
 llvm::LogicalResult fir::EmboxOp::verify() {
-  auto eleTy = fir::dyn_cast_ptrEleTy(getMemref().getType());
+  auto eleTy =
+      fir::unwrapCoarrayType(fir::dyn_cast_ptrEleTy(getMemref().getType()));
   bool isArray = false;
   if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(eleTy)) {
     eleTy = seqTy.getEleTy();
@@ -3704,7 +3715,7 @@ static bool areCompatibleCharacterTypes(mlir::Type t1, mlir::Type t2) {
 }
 
 llvm::LogicalResult fir::ReboxOp::verify() {
-  auto inputBoxTy = getBox().getType();
+  auto inputBoxTy = fir::unwrapCoarrayType(getBox().getType());
   if (fir::isa_unknown_size_box(inputBoxTy))
     return emitOpError("box operand must not have unknown rank or type");
   auto outBoxTy = getType();
diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp
index 8477048d18863..77110c2062a09 100644
--- a/flang/lib/Optimizer/Dialect/FIRType.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -301,6 +301,8 @@ mlir::Type extractSequenceType(mlir::Type ty) {
     return extractSequenceType(heapTy.getEleTy());
   if (auto ptrTy = mlir::dyn_cast<fir::PointerType>(ty))
     return extractSequenceType(ptrTy.getEleTy());
+  if (auto coarrayTy = mlir::dyn_cast<fir::CoarrayType>(ty))
+    return extractSequenceType(coarrayTy.getEleTy());
   return mlir::Type{};
 }
 
@@ -330,16 +332,18 @@ bool isBoxedRecordType(mlir::Type ty) {
   if (auto refTy = fir::dyn_cast_ptrEleTy(ty))
     ty = refTy;
   if (auto boxTy = mlir::dyn_cast<fir::BoxType>(ty)) {
-    if (mlir::isa<fir::RecordType>(boxTy.getEleTy()))
+    if (mlir::isa<fir::RecordType>(fir::unwrapCoarrayType(boxTy.getEleTy())))
       return true;
-    return mlir::isa<fir::RecordType>(boxTy.unwrapInnerType());
+    return mlir::isa<fir::RecordType>(
+        fir::unwrapCoarrayType(boxTy.unwrapInnerType()));
   }
   return false;
 }
 
 // CLASS(*)
 bool isClassStarType(mlir::Type ty) {
-  if (auto clTy = mlir::dyn_cast<fir::ClassType>(fir::unwrapRefType(ty))) {
+  if (auto clTy = mlir::dyn_cast<fir::ClassType>(
+          fir::unwrapCoarrayType(fir::unwrapRefType(ty)))) {
     if (mlir::isa<mlir::NoneType>(clTy.getEleTy()))
       return true;
     return mlir::isa<mlir::NoneType>(clTy.unwrapInnerType());
@@ -351,12 +355,14 @@ bool isScalarBoxedRecordType(mlir::Type ty) {
   if (auto refTy = fir::dyn_cast_ptrEleTy(ty))
     ty = refTy;
   if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(ty)) {
-    if (mlir::isa<fir::RecordType>(boxTy.getEleTy()))
+    if (mlir::isa<fir::RecordType>(fir::unwrapCoarrayType(boxTy.getEleTy())))
       return true;
     if (auto heapTy = mlir::dyn_cast<fir::HeapType>(boxTy.getEleTy()))
-      return mlir::isa<fir::RecordType>(heapTy.getEleTy());
+      return mlir::isa<fir::RecordType>(
+          fir::unwrapCoarrayType(heapTy.getEleTy()));
     if (auto ptrTy = mlir::dyn_cast<fir::PointerType>(boxTy.getEleTy()))
-      return mlir::isa<fir::RecordType>(ptrTy.getEleTy());
+      return mlir::isa<fir::RecordType>(
+          fir::unwrapCoarrayType(ptrTy.getEleTy()));
   }
   return false;
 }
@@ -365,7 +371,8 @@ bool isAssumedType(mlir::Type ty) {
   // Rule out CLASS(*) which are `fir.class<[fir.array] none>`.
   if (mlir::isa<fir::ClassType>(ty))
     return false;
-  mlir::Type valueType = fir::unwrapPassByRefType(fir::unwrapRefType(ty));
+  mlir::Type valueType =
+      fir::unwrapCoarrayType(fir::unwrapPassByRefType(fir::unwrapRefType(ty)));
   // Refuse raw `none` or `fir.array<none>` since assumed type
   // should be in memory variables.
   if (valueType == ty)
@@ -376,7 +383,8 @@ bool isAssumedType(mlir::Type ty) {
 
 bool isAssumedShape(mlir::Type ty) {
   if (auto boxTy = mlir::dyn_cast<fir::BoxType>(ty))
-    if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(boxTy.getEleTy()))
+    if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(
+            fir::unwrapCoarrayType(boxTy.getEleTy())))
       return seqTy.hasDynamicExtents();
   return false;
 }
@@ -386,9 +394,11 @@ bool isAllocatableOrPointerArray(mlir::Type ty) {
     ty = refTy;
   if (auto boxTy = mlir::dyn_cast<fir::BoxType>(ty)) {
     if (auto heapTy = mlir::dyn_cast<fir::HeapType>(boxTy.getEleTy()))
-      return mlir::isa<fir::SequenceType>(heapTy.getEleTy());
+      return mlir::isa<fir::SequenceType>(
+          fir::unwrapCoarrayType(heapTy.getEleTy()));
     if (auto ptrTy = mlir::dyn_cast<fir::PointerType>(boxTy.getEleTy()))
-      return mlir::isa<fir::SequenceType>(ptrTy.getEleTy());
+      return mlir::isa<fir::SequenceType>(
+          fir::unwrapCoarrayType(ptrTy.getEleTy()));
   }
   return false;
 }
@@ -401,7 +411,7 @@ bool isTypeWithDescriptor(mlir::Type ty) {
 
 bool isPolymorphicType(mlir::Type ty) {
   // CLASS(T) or CLASS(*)
-  if (mlir::isa<fir::ClassType>(fir::unwrapRefType(ty)))
+  if (mlir::isa<fir::ClassType>(fir::unwrapCoarrayType(fir::unwrapRefType(ty))))
     return true;
   // assumed type are polymorphic.
   return isAssumedType(ty);
@@ -415,6 +425,8 @@ bool isUnlimitedPolymorphicType(mlir::Type ty) {
   return isAssumedType(ty);
 }
 
+bool isCoarrayType(mlir::Type ty) { return mlir::isa<fir::CoarrayType>(ty); }
+
 bool isRecordWithAllocatableMember(mlir::Type ty) {
   if (auto recTy = mlir::dyn_cast<fir::RecordType>(ty))
     for (auto [field, memTy] : recTy.getTypeList()) {
@@ -455,8 +467,8 @@ mlir::Type unwrapAllRefAndSeqType(mlir::Type ty) {
 }
 
 mlir::Type getFortranElementType(mlir::Type ty) {
-  return fir::unwrapSequenceType(
-      fir::unwrapPassByRefType(fir::unwrapRefType(ty)));
+  return fir::unwrapCoarrayType(fir::unwrapSequenceType(
+      fir::unwrapPassByRefType(fir::unwrapRefType(ty))));
 }
 
 mlir::Type unwrapSeqOrBoxedSeqType(mlir::Type ty) {
@@ -470,6 +482,12 @@ mlir::Type unwrapSeqOrBoxedSeqType(mlir::Type ty) {
   return ty;
 }
 
+mlir::Type unwrapCoarrayType(mlir::Type ty) {
+  if (auto coarray = mlir::dyn_cast<fir::CoarrayType>(ty))
+    return coarray.getElementType();
+  return ty;
+}
+
 unsigned getBoxRank(mlir::Type boxTy) {
   auto eleTy = fir::dyn_cast_ptrOrBoxEleTy(boxTy);
   if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(eleTy))
@@ -1442,7 +1460,8 @@ mlir::Type BaseBoxType::getBaseAddressType(bool dropHeapOrPtr) const {
 
 mlir::Type BaseBoxType::unwrapInnerType() const {
   return llvm::TypeSwitch<mlir::Type, mlir::Type>(getEleTy())
-      .Case<fir::PointerType, fir::HeapType, fir::SequenceType>([](auto t) {
+      .Case<fir::PointerType, fir::HeapType, fir::SequenceType,
+            fir::CoarrayType>([](auto t) {
         mlir::Type eleTy = t.getEleTy();
         if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(eleTy))
           return seqTy.getEleTy();
@@ -1568,7 +1587,7 @@ void FIROpsDialect::registerTypes() {
            FieldType, HeapType, fir::IntegerType, LenType, LogicalType,
            LLVMPointerType, PointerType, RecordType, ReferenceType,
            SequenceType, ShapeType, ShapeShiftType, ShiftType, SliceType,
-           TypeDescType, fir::VectorType, fir::DummyScopeType>();
+           TypeDescType, fir::VectorType, fir::DummyScopeType, CoarrayType>();
   fir::ReferenceType::attachInterface<
       OpenMPPointerLikeModel<fir::ReferenceType>>(*getContext());
   fir::PointerType::attachInterface<OpenMPPointerLikeModel<fir::PointerType>>(
diff --git a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
index 5620353a58f3d..dc2d6d0688359 100644
--- a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
+++ b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
@@ -76,7 +76,7 @@ llvm::LogicalResult mif::NumImagesOp::verify() {
 void mif::ThisImageOp::build(mlir::OpBuilder &builder,
                              mlir::OperationState &result, mlir::Value coarray,
                              mlir::Value dim, mlir::Value team) {
-  mlir::Type resultTy = builder.getI32Type();
+  mlir::Type resultTy = builder.getI64Type();
   build(builder, result, resultTy, coarray, dim, team);
 }
 
@@ -291,58 +291,6 @@ llvm::LogicalResult mif::AllocCoarrayOp::verify() {
   return mlir::success();
 }
 
-//===----------------------------------------------------------------------===//
-// LcoboundOp
-//===----------------------------------------------------------------------===//
-
-void mif::LcoboundOp::build(mlir::OpBuilder &builder,
-                            mlir::OperationState &result, mlir::Value coarray,
-                            mlir::Value dim) {
-  // By default the result type is an I64
-  mlir::Type resultTy = builder.getI64Type();
-  build(builder, result, resultTy, coarray, dim);
-}
-
-void mif::LcoboundOp::build(mlir::OpBuilder &builder,
-                            mlir::OperationState &result, mlir::Value coarray) {
-  mlir::Type i64Ty = builder.getI64Type();
-  mlir::Type resultTy = fir::BoxType::get(
-      fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, i64Ty));
-  build(builder, result, resultTy, coarray, /*dim*/ mlir::Value{});
-}
-
-llvm::LogicalResult mif::LcoboundOp::verify() {
-  if (getCoarray())
-    return checkCorankAttr(*this);
-  return mlir::success();
-}
-
-//===----------------------------------------------------------------------===//
-// UcoboundOp
-//===----------------------------------------------------------------------===//
-
-void mif::UcoboundOp::build(mlir::OpBuilder &builder,
-                            mlir::OperationState &result, mlir::Value coarray,
-                            mlir::Value dim) {
-  // By default the result type is an I64
-  mlir::Type resultTy = builder.getI64Type();
-  build(builder, result, resultTy, coarray, dim);
-}
-
-void mif::UcoboundOp::build(mlir::OpBuilder &builder,
-                            mlir::OperationState &result, mlir::Value coarray) {
-  mlir::Type i64Ty = builder.getI64Type();
-  mlir::Type resultTy = fir::BoxType::get(
-      fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, i64Ty));
-  build(builder, result, resultTy, coarray, /*dim*/ mlir::Value{});
-}
-
-llvm::LogicalResult mif::UcoboundOp::verify() {
-  if (getCoarray())
-    return checkCorankAttr(*this);
-  return mlir::success();
-}
-
 //===----------------------------------------------------------------------===//
 // CoshapeOp
 //===----------------------------------------------------------------------===//
@@ -355,12 +303,6 @@ void mif::CoshapeOp::build(mlir::OpBuilder &builder,
   build(builder, result, resultTy, coarray);
 }
 
-llvm::LogicalResult mif::CoshapeOp::verify() {
-  if (getCoarray())
-    return checkCorankAttr(*this);
-  return mlir::success();
-}
-
 //===----------------------------------------------------------------------===//
 // ImageIndexOp
 //===----------------------------------------------------------------------===//
diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
index 88f20180e6fa1..86289bb7cafb1 100644
--- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
@@ -179,7 +179,8 @@ static mlir::Value getSizeInBytes(fir::FirOpBuilder &builder,
                                   const fir::LLVMTypeConverter *typeConverter,
                                   mlir::Value box) {
   fir::KindMapping kindMap{fir::getKindMapping(module)};
-  mlir::Type baseTy = fir::unwrapPassByRefType(box.getType());
+  mlir::Type baseTy =
+      fir::unwrapCoarrayType(fir::unwrapPassByRefType(box.getType()));
 
   mlir::Value sizeInBytes = builder.createTemporary(loc, builder.getI64Type());
   mlir::Value bytes;
@@ -221,7 +222,7 @@ static mlir::Value getSizeInBytes(fir::FirOpBuilder &builder,
       mlir::emitError(loc, "unsupported type in mif allocation\n");
     }
   } else {
-    if (fir::isa_ref_type(box.getType()))
+    if (fir::isa_ref_type(fir::unwrapCoarrayType(box.getType())))
       box = fir::LoadOp::create(builder, loc, box);
     bytes = fir::BoxEleSizeOp::create(builder, loc, builder.getI64Type(), box);
     auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(baseTy);
@@ -1217,49 +1218,29 @@ mlir::LogicalResult CoboundOpConversion(T op, mlir::PatternRewriter &rewriter,
   mlir::Type boxTy = fir::BoxType::get(builder.getNoneType());
 
   mlir::Value coarrayHandle = getCoarrayHandle(builder, loc, op.getCoarray());
-  if (mlir::Value d = op.getDim()) {
-    mlir::Type i32Ty = builder.getI32Type();
-    mlir::FunctionType ftype = mlir::FunctionType::get(
-        builder.getContext(),
-        /*inputs*/
-        {boxTy, builder.getRefType(i32Ty), builder.getRefType(i64Ty)},
-        /*results*/ {});
-    mlir::func::FuncOp funcOp = builder.createFunction(
-        loc, getPRIFProcName(prefix + "_with_dim"), ftype);
-
-    mlir::Value result = builder.createTemporary(loc, i64Ty);
-    mlir::Value dim = builder.createTemporary(loc, i32Ty);
-    if (d.getType() != i32Ty)
-      d = fir::ConvertOp::create(builder, loc, i32Ty, d);
-    fir::StoreOp::create(builder, loc, d, dim);
+  mlir::Type i32Ty = builder.getI32Type();
+  mlir::FunctionType ftype = mlir::FunctionType::get(
+      builder.getContext(),
+      /*inputs*/
+      {boxTy, builder.getRefType(i32Ty), builder.getRefType(i64Ty)},
+      /*results*/ {});
+  mlir::func::FuncOp funcOp =
+      builder.createFunction(loc, getPRIFProcName(prefix + "_with_dim"), ftype);
 
-    llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
-        builder, loc, ftype, coarrayHandle, dim, result);
-    fir::CallOp::create(builder, loc, funcOp, args);
-    result = fir::LoadOp::create(builder, loc, result).getResult();
-    if (result.getType() != op.getType())
-      result = builder.createConvert(loc, op.getType(), result);
-    rewriter.replaceOp(op, result);
-  } else {
-    mlir::FunctionType ftype =
-        mlir::FunctionType::get(builder.getContext(),
-                                /*inputs*/ {boxTy, genBoxedSequenceType(i64Ty)},
-                                /*results*/ {});
-    mlir::func::FuncOp funcOp =
-        builder.createFunction(loc, getPRIFProcName(prefix + "_no_dim"), ftype);
+  mlir::Value result = builder.createTemporary(loc, i64Ty);
+  mlir::Value dim = builder.createTemporary(loc, i32Ty);
+  mlir::Value d = op.getDim();
+  if (d.getType() != i32Ty)
+    d = fir::ConvertOp::create(builder, loc, i32Ty, d);
+  fir::StoreOp::create(builder, loc, d, dim);
 
-    std::int64_t corank = getCorankFromAttr(builder, loc, op.getCoarray());
-    mlir::Type resultType = fir::SequenceType::get(
-        static_cast<fir::SequenceType::Extent>(corank), i64Ty);
-    mlir::Value result =
-        builder.createBox(loc, builder.createTemporary(loc, resultType));
-    llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
-        builder, loc, ftype, coarrayHandle, result);
-    fir::CallOp::create(builder, loc, funcOp, args);
-    result = fir::ConvertOp::create(builder, loc, genBoxedSequenceType(i64Ty),
-                                    result);
-    rewriter.replaceOp(op, result);
-  }
+  llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+      builder, loc, ftype, coarrayHandle, dim, result);
+  fir::CallOp::create(builder, loc, funcOp, args);
+  result = fir::LoadOp::create(builder, loc, result).getResult();
+  if (result.getType() != op.getType())
+    result = builder.createConvert(loc, op.getType(), result);
+  rewriter.replaceOp(op, result);
   return mlir::success();
 }
 
diff --git a/flang/test/Fir/MIF/coarray-alloc.mlir b/flang/test/Fir/MIF/coarray-alloc.mlir
index 7596ffc61a00f..4dd94136100ae 100644
--- a/flang/test/Fir/MIF/coarray-alloc.mlir
+++ b/flang/test/Fir/MIF/coarray-alloc.mlir
@@ -2,19 +2,19 @@
 
 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 23.0.0 (git at github.com:SiPearl/llvm-project.git 3d6a6306c5cd826a2306fd17b1f65de34bcf866b)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
   func.func @_QQmain() attributes {fir.bindc_name = "ALLOC_TEST"} {
-    %0 = fir.alloca !fir.array<1xi64>
+    %0 = fir.alloca !fir.array<0xi64>
     %1 = fir.alloca !fir.array<1xi64>
-    %2 = fir.alloca !fir.array<1xi64>
+    %2 = fir.alloca !fir.array<0xi64>
     %3 = fir.alloca !fir.array<1xi64>
-    %4 = fir.alloca !fir.array<3xi64>
+    %4 = fir.alloca !fir.array<2xi64>
     %5 = fir.alloca !fir.array<3xi64>
-    %6 = fir.alloca !fir.array<2xi64>
+    %6 = fir.alloca !fir.array<1xi64>
     %7 = fir.alloca !fir.array<2xi64>
-    %8 = fir.alloca !fir.array<1xi64>
+    %8 = fir.alloca !fir.array<0xi64>
     %9 = fir.alloca !fir.array<1xi64>
-    %10 = fir.alloca !fir.array<3xi64>
+    %10 = fir.alloca !fir.array<2xi64>
     %11 = fir.alloca !fir.array<3xi64>
-    %12 = fir.alloca !fir.array<2xi64>
+    %12 = fir.alloca !fir.array<1xi64>
     %13 = fir.alloca !fir.array<2xi64>
     %14 = fir.dummy_scope : !fir.dscope
     %15 = fir.address_of(@_QFE.n.my_type2) : !fir.ref<!fir.char<1,8>>
@@ -35,7 +35,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %25 = fir.address_of(@_QFE.n.my_type) : !fir.ref<!fir.char<1,7>>
     %c7 = arith.constant 7 : index
     %26:2 = hlfir.declare %25 typeparams %c7 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFE.n.my_type"} : (!fir.ref<!fir.char<1,7>>, index) -> (!fir.ref<!fir.char<1,7>>, !fir.ref<!fir.char<1,7>>)
-    %27 = fir.address_of(@_QFEa) : !fir.ref<i32>
+    %27 = fir.address_of(@_QFEa) : !fir.ref<!fir.coarray<i32, 2>>
     %c1_i64 = arith.constant 1 : i64
     %c0 = arith.constant 0 : index
     %28 = fir.coordinate_of %13, %c0 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
@@ -47,198 +47,162 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %30 = fir.embox %13 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
     %c1_i64_4 = arith.constant 1 : i64
     %c0_5 = arith.constant 0 : index
-    %31 = fir.coordinate_of %12, %c0_5 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
+    %31 = fir.coordinate_of %12, %c0_5 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
     fir.store %c1_i64_4 to %31 : !fir.ref<i64>
-    %c1_i64_6 = arith.constant 1 : i64
-    %c1_7 = arith.constant 1 : index
-    %32 = fir.coordinate_of %12, %c1_7 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
-    fir.store %c1_i64_6 to %32 : !fir.ref<i64>
-    %33 = fir.embox %12 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
+    %32 = fir.embox %12 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
 // CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.box<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-    mif.alloc_coarray %27 lcobounds %30 ucobounds %33 {uniq_name = "_QFEa"} : (!fir.ref<i32>, !fir.box<!fir.array<2xi64>>, !fir.box<!fir.array<2xi64>>) -> ()
-    %34:2 = hlfir.declare %27 {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-    %35 = fir.address_of(@_QFEa2) : !fir.ref<!fir.box<!fir.heap<i32>>>
-    %36:2 = hlfir.declare %35 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEa2"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)
-    %37 = fir.address_of(@_QFEb) : !fir.ref<f32>
+    mif.alloc_coarray %27 lcobounds %30 ucobounds %32 {uniq_name = "_QFEa"} : (!fir.ref<!fir.coarray<i32, 2>>, !fir.box<!fir.array<2xi64>>, !fir.box<!fir.array<1xi64>>) -> ()
+    %33:2 = hlfir.declare %27 {uniq_name = "_QFEa"} : (!fir.ref<!fir.coarray<i32, 2>>) -> (!fir.ref<!fir.coarray<i32, 2>>, !fir.ref<!fir.coarray<i32, 2>>)
+    %34 = fir.address_of(@_QFEa2) : !fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 2>>>>
+    %35:2 = hlfir.declare %34 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEa2"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 2>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 2>>>>, !fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 2>>>>)
+    %36 = fir.address_of(@_QFEb) : !fir.ref<!fir.coarray<f32, 3>>
     %c3_i64 = arith.constant 3 : i64
-    %c0_8 = arith.constant 0 : index
-    %38 = fir.coordinate_of %11, %c0_8 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
-    fir.store %c3_i64 to %38 : !fir.ref<i64>
+    %c0_6 = arith.constant 0 : index
+    %37 = fir.coordinate_of %11, %c0_6 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
+    fir.store %c3_i64 to %37 : !fir.ref<i64>
+    %c1_i64_7 = arith.constant 1 : i64
+    %c1_8 = arith.constant 1 : index
+    %38 = fir.coordinate_of %11, %c1_8 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64_7 to %38 : !fir.ref<i64>
     %c1_i64_9 = arith.constant 1 : i64
-    %c1_10 = arith.constant 1 : index
-    %39 = fir.coordinate_of %11, %c1_10 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
+    %c2_10 = arith.constant 2 : index
+    %39 = fir.coordinate_of %11, %c2_10 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
     fir.store %c1_i64_9 to %39 : !fir.ref<i64>
-    %c1_i64_11 = arith.constant 1 : i64
-    %c2_12 = arith.constant 2 : index
-    %40 = fir.coordinate_of %11, %c2_12 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
-    fir.store %c1_i64_11 to %40 : !fir.ref<i64>
-    %41 = fir.embox %11 : (!fir.ref<!fir.array<3xi64>>) -> !fir.box<!fir.array<3xi64>>
-    %c3_i64_13 = arith.constant 3 : i64
-    %c0_14 = arith.constant 0 : index
-    %42 = fir.coordinate_of %10, %c0_14 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
-    fir.store %c3_i64_13 to %42 : !fir.ref<i64>
-    %c1_i64_15 = arith.constant 1 : i64
-    %c1_16 = arith.constant 1 : index
-    %43 = fir.coordinate_of %10, %c1_16 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
-    fir.store %c1_i64_15 to %43 : !fir.ref<i64>
-    %c1_i64_17 = arith.constant 1 : i64
-    %c2_18 = arith.constant 2 : index
-    %44 = fir.coordinate_of %10, %c2_18 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
-    fir.store %c1_i64_17 to %44 : !fir.ref<i64>
-    %45 = fir.embox %10 : (!fir.ref<!fir.array<3xi64>>) -> !fir.box<!fir.array<3xi64>>
+    %40 = fir.embox %11 : (!fir.ref<!fir.array<3xi64>>) -> !fir.box<!fir.array<3xi64>>
+    %c3_i64_11 = arith.constant 3 : i64
+    %c0_12 = arith.constant 0 : index
+    %41 = fir.coordinate_of %10, %c0_12 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
+    fir.store %c3_i64_11 to %41 : !fir.ref<i64>
+    %c1_i64_13 = arith.constant 1 : i64
+    %c1_14 = arith.constant 1 : index
+    %42 = fir.coordinate_of %10, %c1_14 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64_13 to %42 : !fir.ref<i64>
+    %43 = fir.embox %10 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
 // CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.box<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-    mif.alloc_coarray %37 lcobounds %41 ucobounds %45 {uniq_name = "_QFEb"} : (!fir.ref<f32>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<3xi64>>) -> ()
-    %46:2 = hlfir.declare %37 {uniq_name = "_QFEb"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
-    %47 = fir.address_of(@_QFEb2) : !fir.ref<!fir.box<!fir.heap<f32>>>
-    %48:2 = hlfir.declare %47 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEb2"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>)
-    %49 = fir.address_of(@_QFEc) : !fir.ref<!fir.char<1,10>>
+    mif.alloc_coarray %36 lcobounds %40 ucobounds %43 {uniq_name = "_QFEb"} : (!fir.ref<!fir.coarray<f32, 3>>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>) -> ()
+    %44:2 = hlfir.declare %36 {uniq_name = "_QFEb"} : (!fir.ref<!fir.coarray<f32, 3>>) -> (!fir.ref<!fir.coarray<f32, 3>>, !fir.ref<!fir.coarray<f32, 3>>)
+    %45 = fir.address_of(@_QFEb2) : !fir.ref<!fir.box<!fir.heap<!fir.coarray<f32, 3>>>>
+    %46:2 = hlfir.declare %45 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEb2"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<f32, 3>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.coarray<f32, 3>>>>, !fir.ref<!fir.box<!fir.heap<!fir.coarray<f32, 3>>>>)
+    %47 = fir.address_of(@_QFEc) : !fir.ref<!fir.coarray<!fir.char<1,10>, 1>>
     %c10 = arith.constant 10 : index
-    %c1_i64_19 = arith.constant 1 : i64
-    %c0_20 = arith.constant 0 : index
-    %50 = fir.coordinate_of %9, %c0_20 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
-    fir.store %c1_i64_19 to %50 : !fir.ref<i64>
-    %51 = fir.embox %9 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
-    %c1_i64_21 = arith.constant 1 : i64
-    %c0_22 = arith.constant 0 : index
-    %52 = fir.coordinate_of %8, %c0_22 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
-    fir.store %c1_i64_21 to %52 : !fir.ref<i64>
-    %53 = fir.embox %8 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
+    %c1_i64_15 = arith.constant 1 : i64
+    %c0_16 = arith.constant 0 : index
+    %48 = fir.coordinate_of %9, %c0_16 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64_15 to %48 : !fir.ref<i64>
+    %49 = fir.embox %9 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
+    %50 = fir.embox %8 : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
 // CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.box<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-    mif.alloc_coarray %49 lcobounds %51 ucobounds %53 {uniq_name = "_QFEc"} : (!fir.ref<!fir.char<1,10>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<1xi64>>) -> ()
-    %54:2 = hlfir.declare %49 typeparams %c10 {uniq_name = "_QFEc"} : (!fir.ref<!fir.char<1,10>>, index) -> (!fir.ref<!fir.char<1,10>>, !fir.ref<!fir.char<1,10>>)
-    %55 = fir.address_of(@_QFEc2) : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>
-    %56:2 = hlfir.declare %55 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEc2"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>)
-    %57 = fir.address_of(@_QFEd) : !fir.ref<!fir.type<_QFTmy_type{x:i32,y:!fir.box<!fir.heap<!fir.array<?xi32>>>,z:!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<i32>>}>}>>
-    %58:2 = hlfir.declare %57 {uniq_name = "_QFEd"} : (!fir.ref<!fir.type<_QFTmy_type{x:i32,y:!fir.box<!fir.heap<!fir.array<?xi32>>>,z:!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<i32>>}>}>>) -> (!fir.ref<!fir.type<_QFTmy_type{x:i32,y:!fir.box<!fir.heap<!fir.array<?xi32>>>,z:!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<i32>>}>}>>, !fir.ref<!fir.type<_QFTmy_type{x:i32,y:!fir.box<!fir.heap<!fir.array<?xi32>>>,z:!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<i32>>}>}>>)
-    %59 = fir.address_of(@_QFE.c.my_type2) : !fir.ref<!fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>
-    %c0_23 = arith.constant 0 : index
-    %c1_24 = arith.constant 1 : index
-    %60 = fir.shape_shift %c0_23, %c1_24 : (index, index) -> !fir.shapeshift<1>
-    %61:2 = hlfir.declare %59(%60) {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFE.c.my_type2"} : (!fir.ref<!fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>, !fir.shapeshift<1>) -> (!fir.box<!fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>, !fir.ref<!fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>)
-    %62 = fir.address_of(@_QFE.dt.my_type) : !fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>
-    %63:2 = hlfir.declare %62 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFE.dt.my_type"} : (!fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>) -> (!fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>, !fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>)
-    %64 = fir.address_of(@_QFE.dt.my_type2) : !fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>
-    %65:2 = hlfir.declare %64 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFE.dt.my_type2"} : (!fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>) -> (!fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>, !fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>)
-    %66 = fir.address_of(@_QFE.c.my_type) : !fir.ref<!fir.array<3x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>
-    %c0_25 = arith.constant 0 : index
+    mif.alloc_coarray %47 lcobounds %49 ucobounds %50 {uniq_name = "_QFEc"} : (!fir.ref<!fir.coarray<!fir.char<1,10>, 1>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
+    %51:2 = hlfir.declare %47 typeparams %c10 {uniq_name = "_QFEc"} : (!fir.ref<!fir.coarray<!fir.char<1,10>, 1>>, index) -> (!fir.ref<!fir.coarray<!fir.char<1,10>, 1>>, !fir.ref<!fir.coarray<!fir.char<1,10>, 1>>)
+    %52 = fir.address_of(@_QFEc2) : !fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?x!fir.char<1,?>>, 1>>>>
+    %53:2 = hlfir.declare %52 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEc2"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?x!fir.char<1,?>>, 1>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?x!fir.char<1,?>>, 1>>>>, !fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?x!fir.char<1,?>>, 1>>>>)
+    %54 = fir.address_of(@_QFEd) : !fir.ref<!fir.type<_QFTmy_type{x:i32,y:!fir.box<!fir.heap<!fir.array<?xi32>>>,z:!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<!fir.coarray<i32, 1>>>}>}>>
+    %55:2 = hlfir.declare %54 {uniq_name = "_QFEd"} : (!fir.ref<!fir.type<_QFTmy_type{x:i32,y:!fir.box<!fir.heap<!fir.array<?xi32>>>,z:!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<!fir.coarray<i32, 1>>>}>}>>) -> (!fir.ref<!fir.type<_QFTmy_type{x:i32,y:!fir.box<!fir.heap<!fir.array<?xi32>>>,z:!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<!fir.coarray<i32, 1>>>}>}>>, !fir.ref<!fir.type<_QFTmy_type{x:i32,y:!fir.box<!fir.heap<!fir.array<?xi32>>>,z:!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<!fir.coarray<i32, 1>>>}>}>>)
+    %56 = fir.address_of(@_QFE.c.my_type2) : !fir.ref<!fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>
+    %c0_17 = arith.constant 0 : index
+    %c1_18 = arith.constant 1 : index
+    %57 = fir.shape_shift %c0_17, %c1_18 : (index, index) -> !fir.shapeshift<1>
+    %58:2 = hlfir.declare %56(%57) {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFE.c.my_type2"} : (!fir.ref<!fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>, !fir.shapeshift<1>) -> (!fir.box<!fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>, !fir.ref<!fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>)
+    %59 = fir.address_of(@_QFE.dt.my_type) : !fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>
+    %60:2 = hlfir.declare %59 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFE.dt.my_type"} : (!fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>) -> (!fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>, !fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>)
+    %61 = fir.address_of(@_QFE.dt.my_type2) : !fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>
+    %62:2 = hlfir.declare %61 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFE.dt.my_type2"} : (!fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>) -> (!fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>, !fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>)
+    %63 = fir.address_of(@_QFE.c.my_type) : !fir.ref<!fir.array<3x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>
+    %c0_19 = arith.constant 0 : index
     %c3 = arith.constant 3 : index
-    %67 = fir.shape_shift %c0_25, %c3 : (index, index) -> !fir.shapeshift<1>
-    %68:2 = hlfir.declare %66(%67) {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFE.c.my_type"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>, !fir.shapeshift<1>) -> (!fir.box<!fir.array<3x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>, !fir.ref<!fir.array<3x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>)
-    %69 = fir.absent !fir.box<none>
-    %c1_i64_26 = arith.constant 1 : i64
+    %64 = fir.shape_shift %c0_19, %c3 : (index, index) -> !fir.shapeshift<1>
+    %65:2 = hlfir.declare %63(%64) {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFE.c.my_type"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>, !fir.shapeshift<1>) -> (!fir.box<!fir.array<3x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>, !fir.ref<!fir.array<3x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>)
+    %66 = fir.absent !fir.box<none>
+    %c1_i64_20 = arith.constant 1 : i64
     %c2_i32 = arith.constant 2 : i32
-    %70 = fir.convert %c2_i32 : (i32) -> i64
-    %c0_27 = arith.constant 0 : index
-    %71 = fir.coordinate_of %7, %c0_27 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
-    fir.store %c1_i64_26 to %71 : !fir.ref<i64>
-    %72 = fir.coordinate_of %6, %c0_27 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
-    fir.store %70 to %72 : !fir.ref<i64>
-    %c1_28 = arith.constant 1 : index
-    %73 = fir.coordinate_of %7, %c1_28 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
-    %74 = fir.coordinate_of %6, %c1_28 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
-    fir.store %c1_i64_26 to %73 : !fir.ref<i64>
-    fir.store %c1_i64_26 to %74 : !fir.ref<i64>
-    %75 = fir.embox %7 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
-    %76 = fir.embox %6 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
+    %67 = fir.convert %c2_i32 : (i32) -> i64
+    %c0_21 = arith.constant 0 : index
+    %68 = fir.coordinate_of %7, %c0_21 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64_20 to %68 : !fir.ref<i64>
+    %69 = fir.coordinate_of %6, %c0_21 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
+    fir.store %67 to %69 : !fir.ref<i64>
+    %c1_22 = arith.constant 1 : index
+    %70 = fir.coordinate_of %7, %c1_22 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64_20 to %70 : !fir.ref<i64>
+    %71 = fir.embox %7 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
+    %72 = fir.embox %6 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
 // CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.box<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-    mif.alloc_coarray %36#0 lcobounds %75 ucobounds %76 errmsg %69 {uniq_name = "_QFEa2"} : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.array<2xi64>>, !fir.box<!fir.array<2xi64>>, !fir.box<none>) -> ()
-    %77 = fir.absent !fir.box<none>
-    %c1_i64_29 = arith.constant 1 : i64
+    mif.alloc_coarray %35#0 lcobounds %71 ucobounds %72 errmsg %66 {uniq_name = "_QFEa2"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 2>>>>, !fir.box<!fir.array<2xi64>>, !fir.box<!fir.array<1xi64>>, !fir.box<none>) -> ()
+    %73 = fir.absent !fir.box<none>
+    %c1_i64_23 = arith.constant 1 : i64
     %c3_i32 = arith.constant 3 : i32
-    %78 = fir.convert %c3_i32 : (i32) -> i64
+    %74 = fir.convert %c3_i32 : (i32) -> i64
     %c4_i32 = arith.constant 4 : i32
-    %79 = fir.convert %c4_i32 : (i32) -> i64
-    %c0_30 = arith.constant 0 : index
-    %80 = fir.coordinate_of %5, %c0_30 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
-    fir.store %78 to %80 : !fir.ref<i64>
-    %81 = fir.coordinate_of %4, %c0_30 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
-    fir.store %79 to %81 : !fir.ref<i64>
+    %75 = fir.convert %c4_i32 : (i32) -> i64
+    %c0_24 = arith.constant 0 : index
+    %76 = fir.coordinate_of %5, %c0_24 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
+    fir.store %74 to %76 : !fir.ref<i64>
+    %77 = fir.coordinate_of %4, %c0_24 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
+    fir.store %75 to %77 : !fir.ref<i64>
     %c5_i32 = arith.constant 5 : i32
-    %82 = fir.convert %c5_i32 : (i32) -> i64
-    %c1_31 = arith.constant 1 : index
-    %83 = fir.coordinate_of %5, %c1_31 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
-    fir.store %c1_i64_29 to %83 : !fir.ref<i64>
-    %84 = fir.coordinate_of %4, %c1_31 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
-    fir.store %82 to %84 : !fir.ref<i64>
-    %c2_32 = arith.constant 2 : index
-    %85 = fir.coordinate_of %5, %c2_32 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
-    %86 = fir.coordinate_of %4, %c2_32 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
-    fir.store %c1_i64_29 to %85 : !fir.ref<i64>
-    fir.store %c1_i64_29 to %86 : !fir.ref<i64>
-    %87 = fir.embox %5 : (!fir.ref<!fir.array<3xi64>>) -> !fir.box<!fir.array<3xi64>>
-    %88 = fir.embox %4 : (!fir.ref<!fir.array<3xi64>>) -> !fir.box<!fir.array<3xi64>>
+    %78 = fir.convert %c5_i32 : (i32) -> i64
+    %c1_25 = arith.constant 1 : index
+    %79 = fir.coordinate_of %5, %c1_25 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64_23 to %79 : !fir.ref<i64>
+    %80 = fir.coordinate_of %4, %c1_25 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
+    fir.store %78 to %80 : !fir.ref<i64>
+    %c2_26 = arith.constant 2 : index
+    %81 = fir.coordinate_of %5, %c2_26 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64_23 to %81 : !fir.ref<i64>
+    %82 = fir.embox %5 : (!fir.ref<!fir.array<3xi64>>) -> !fir.box<!fir.array<3xi64>>
+    %83 = fir.embox %4 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
 // CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.box<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-    mif.alloc_coarray %48#0 lcobounds %87 ucobounds %88 errmsg %77 {uniq_name = "_QFEb2"} : (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<3xi64>>, !fir.box<none>) -> ()
+    mif.alloc_coarray %46#0 lcobounds %82 ucobounds %83 errmsg %73 {uniq_name = "_QFEb2"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<f32, 3>>>>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>, !fir.box<none>) -> ()
     %c100_i32 = arith.constant 100 : i32
-    %89 = fir.absent !fir.box<none>
+    %84 = fir.absent !fir.box<none>
     %c1_i32 = arith.constant 1 : i32
-    %c1_i32_33 = arith.constant 1 : i32
     %c0_i32 = arith.constant 0 : i32
-    %90 = fir.convert %56#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>) -> !fir.ref<!fir.box<none>>
-    %91 = fir.convert %c100_i32 : (i32) -> i64
-    fir.call @_FortranAAllocatableInitCharacterForAllocate(%90, %91, %c1_i32, %c1_i32_33, %c0_i32) fastmath<contract> : (!fir.ref<!fir.box<none>>, i64, i32, i32, i32) -> ()
-    %c1_34 = arith.constant 1 : index
-    %c5_i32_35 = arith.constant 5 : i32
-    %c0_i32_36 = arith.constant 0 : i32
-    %92 = fir.convert %56#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>) -> !fir.ref<!fir.box<none>>
-    %93 = fir.convert %c1_34 : (index) -> i64
-    %94 = fir.convert %c5_i32_35 : (i32) -> i64
-    fir.call @_FortranAAllocatableSetBounds(%92, %c0_i32_36, %93, %94) fastmath<contract> : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
-    %c1_i64_37 = arith.constant 1 : i64
-    %c0_38 = arith.constant 0 : index
-    %95 = fir.coordinate_of %3, %c0_38 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
-    %96 = fir.coordinate_of %2, %c0_38 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
-    fir.store %c1_i64_37 to %95 : !fir.ref<i64>
-    fir.store %c1_i64_37 to %96 : !fir.ref<i64>
-    %97 = fir.embox %3 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
-    %98 = fir.embox %2 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
+    %c0_i32_27 = arith.constant 0 : i32
+    %85 = fir.convert %53#0 : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?x!fir.char<1,?>>, 1>>>>) -> !fir.ref<!fir.box<none>>
+    %86 = fir.convert %c100_i32 : (i32) -> i64
+    fir.call @_FortranAAllocatableInitCharacterForAllocate(%85, %86, %c1_i32, %c0_i32, %c0_i32_27) fastmath<contract> : (!fir.ref<!fir.box<none>>, i64, i32, i32, i32) -> ()
+    %c1_28 = arith.constant 1 : index
+    %c5_i32_29 = arith.constant 5 : i32
+    %c0_i32_30 = arith.constant 0 : i32
+    %87 = fir.convert %53#0 : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?x!fir.char<1,?>>, 1>>>>) -> !fir.ref<!fir.box<none>>
+    %88 = fir.convert %c1_28 : (index) -> i64
+    %89 = fir.convert %c5_i32_29 : (i32) -> i64
+    fir.call @_FortranAAllocatableSetBounds(%87, %c0_i32_30, %88, %89) fastmath<contract> : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+    %c1_i64_31 = arith.constant 1 : i64
+    %c0_32 = arith.constant 0 : index
+    %90 = fir.coordinate_of %3, %c0_32 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64_31 to %90 : !fir.ref<i64>
+    %91 = fir.embox %3 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
+    %92 = fir.embox %2 : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
 // CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.box<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-    mif.alloc_coarray %56#0 lcobounds %97 ucobounds %98 errmsg %89 {uniq_name = "_QFEc2"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<1xi64>>, !fir.box<none>) -> ()
-    %99 = fir.absent !fir.box<none>
-    %100 = hlfir.designate %58#0{"z"}   : (!fir.ref<!fir.type<_QFTmy_type{x:i32,y:!fir.box<!fir.heap<!fir.array<?xi32>>>,z:!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<i32>>}>}>>) -> !fir.ref<!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<i32>>}>>
-    %101 = hlfir.designate %100{"co"}   {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<i32>>}>>) -> !fir.ref<!fir.box<!fir.heap<i32>>>
-    %c1_i64_39 = arith.constant 1 : i64
-    %c0_40 = arith.constant 0 : index
-    %102 = fir.coordinate_of %1, %c0_40 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
-    %103 = fir.coordinate_of %0, %c0_40 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
-    fir.store %c1_i64_39 to %102 : !fir.ref<i64>
-    fir.store %c1_i64_39 to %103 : !fir.ref<i64>
-    %104 = fir.embox %1 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
-    %105 = fir.embox %0 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
+    mif.alloc_coarray %53#0 lcobounds %91 ucobounds %92 errmsg %84 {uniq_name = "_QFEc2"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?x!fir.char<1,?>>, 1>>>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>, !fir.box<none>) -> ()
+    %93 = fir.absent !fir.box<none>
+    %94 = hlfir.designate %55#0{"z"}   : (!fir.ref<!fir.type<_QFTmy_type{x:i32,y:!fir.box<!fir.heap<!fir.array<?xi32>>>,z:!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<!fir.coarray<i32, 1>>>}>}>>) -> !fir.ref<!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<!fir.coarray<i32, 1>>>}>>
+    %95 = hlfir.designate %94{"co"}   {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<!fir.coarray<i32, 1>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 1>>>>
+    %c1_i64_33 = arith.constant 1 : i64
+    %c0_34 = arith.constant 0 : index
+    %96 = fir.coordinate_of %1, %c0_34 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64_33 to %96 : !fir.ref<i64>
+    %97 = fir.embox %1 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
+    %98 = fir.embox %0 : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
 // CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.box<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-    mif.alloc_coarray %101 lcobounds %104 ucobounds %105 errmsg %99 {uniq_name = "_QFEd.z.co"} : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<1xi64>>, !fir.box<none>) -> ()
-    %106 = fir.absent !fir.box<none>
-    %107 = fir.absent !fir.ref<i32>
-// CHECK: fir.call @_QMprifPprif_deallocate_coarray({{.*}}) : (!fir.box<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-    mif.dealloc_coarray %36#0 stat %107 errmsg %106 : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<i32>, !fir.box<none>) -> ()
-    %108 = fir.absent !fir.ref<i32>
-// CHECK: fir.call @_QMprifPprif_deallocate_coarray({{.*}}) : (!fir.box<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-    mif.dealloc_coarray %48#0 stat %108 errmsg %106 : (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<i32>, !fir.box<none>) -> ()
-    %109 = fir.absent !fir.ref<i32>
-// CHECK: fir.call @_QMprifPprif_deallocate_coarray({{.*}}) : (!fir.box<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-    mif.dealloc_coarray %56#0 stat %109 errmsg %106 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>, !fir.ref<i32>, !fir.box<none>) -> ()
-    %110 = fir.absent !fir.box<none>
-    %111 = hlfir.designate %58#0{"z"}   : (!fir.ref<!fir.type<_QFTmy_type{x:i32,y:!fir.box<!fir.heap<!fir.array<?xi32>>>,z:!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<i32>>}>}>>) -> !fir.ref<!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<i32>>}>>
-    %112 = hlfir.designate %111{"co"}   {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<i32>>}>>) -> !fir.ref<!fir.box<!fir.heap<i32>>>
-    %113 = fir.absent !fir.ref<i32>
+    mif.alloc_coarray %95 lcobounds %97 ucobounds %98 errmsg %93 {uniq_name = "_QFEd.z.co"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 1>>>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>, !fir.box<none>) -> ()
+    %99 = fir.absent !fir.box<none>
+    %100 = fir.absent !fir.ref<i32>
 // CHECK: fir.call @_QMprifPprif_deallocate_coarray({{.*}}) : (!fir.box<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-    mif.dealloc_coarray %112 stat %113 errmsg %110 : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<i32>, !fir.box<none>) -> ()
+    mif.dealloc_coarray %35#0 stat %100 errmsg %99 : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 2>>>>, !fir.ref<i32>, !fir.box<none>) -> ()
+    %101 = fir.absent !fir.ref<i32>
 // CHECK: fir.call @_QMprifPprif_deallocate_coarray({{.*}}) : (!fir.box<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-    mif.dealloc_coarray %54#0 : (!fir.ref<!fir.char<1,10>>) -> ()
+    mif.dealloc_coarray %46#0 stat %101 errmsg %99 : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<f32, 3>>>>, !fir.ref<i32>, !fir.box<none>) -> ()
+    %102 = fir.absent !fir.ref<i32>
 // CHECK: fir.call @_QMprifPprif_deallocate_coarray({{.*}}) : (!fir.box<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-    mif.dealloc_coarray %46#0 : (!fir.ref<f32>) -> ()
+    mif.dealloc_coarray %53#0 stat %102 errmsg %99 : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?x!fir.char<1,?>>, 1>>>>, !fir.ref<i32>, !fir.box<none>) -> ()
+    %103 = fir.absent !fir.box<none>
+    %104 = hlfir.designate %55#0{"z"}   : (!fir.ref<!fir.type<_QFTmy_type{x:i32,y:!fir.box<!fir.heap<!fir.array<?xi32>>>,z:!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<!fir.coarray<i32, 1>>>}>}>>) -> !fir.ref<!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<!fir.coarray<i32, 1>>>}>>
+    %105 = hlfir.designate %104{"co"}   {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<!fir.coarray<i32, 1>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 1>>>>
+    %106 = fir.absent !fir.ref<i32>
 // CHECK: fir.call @_QMprifPprif_deallocate_coarray({{.*}}) : (!fir.box<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-    mif.dealloc_coarray %34#0 : (!fir.ref<i32>) -> ()
+    mif.dealloc_coarray %105 stat %106 errmsg %103 : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 1>>>>, !fir.ref<i32>, !fir.box<none>) -> ()
     return
   }
 }
-
-// CHECK: fir.global linkonce_odr @_QMprifE.dt.prif_coarray_handle : !fir.type<_QMprifTprif_coarray_handle{info:!fir.box<!fir.ptr<none>>}>
-// CHECK: fir.global linkonce @_QFEa_coarray_handle : !fir.box<!fir.type<_QMprifTprif_coarray_handle{info:!fir.box<!fir.ptr<none>>}>>
-// CHECK: fir.global linkonce @_QFEb_coarray_handle : !fir.box<!fir.type<_QMprifTprif_coarray_handle{info:!fir.box<!fir.ptr<none>>}>>
-// CHECK: fir.global linkonce @_QFEc_coarray_handle : !fir.box<!fir.type<_QMprifTprif_coarray_handle{info:!fir.box<!fir.ptr<none>>}>>
-// CHECK: fir.global linkonce @_QFEa2_coarray_handle : !fir.box<!fir.type<_QMprifTprif_coarray_handle{info:!fir.box<!fir.ptr<none>>}>>
-// CHECK: fir.global linkonce @_QFEb2_coarray_handle : !fir.box<!fir.type<_QMprifTprif_coarray_handle{info:!fir.box<!fir.ptr<none>>}>>
-// CHECK: fir.global linkonce @_QFEc2_coarray_handle : !fir.box<!fir.type<_QMprifTprif_coarray_handle{info:!fir.box<!fir.ptr<none>>}>>
-// CHECK: fir.global linkonce @_QFEd.z.co_coarray_handle : !fir.box<!fir.type<_QMprifTprif_coarray_handle{info:!fir.box<!fir.ptr<none>>}>>
-
diff --git a/flang/test/Fir/MIF/cobound.mlir b/flang/test/Fir/MIF/cobound.mlir
index e5072632e6b49..39dadeb5747c7 100644
--- a/flang/test/Fir/MIF/cobound.mlir
+++ b/flang/test/Fir/MIF/cobound.mlir
@@ -2,12 +2,12 @@
 
 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 23.0.0 (git at github.com:SiPearl/llvm-project.git d31a4730513391710d91c5ad33bb8ea3d68db3cb)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
 // CHECK-LABEL: func.func @_QQmain
- func.func @_QQmain() attributes {fir.bindc_name = "TEST"} {
+  func.func @_QQmain() attributes {fir.bindc_name = "TEST"} {
     %0 = fir.alloca !fir.array<2xi64>
     %1 = fir.alloca !fir.array<3xi64>
     %2 = fir.dummy_scope : !fir.dscope
-    %3 = fir.address_of(@_QFEa) : !fir.ref<!fir.box<!fir.heap<i32>>>
-    %4:2 = hlfir.declare %3 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEa"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)
+    %3 = fir.address_of(@_QFEa) : !fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 3>>>>
+    %4:2 = hlfir.declare %3 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEa"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 3>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 3>>>>, !fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 3>>>>)
     %c3 = arith.constant 3 : index
     %5 = fir.alloca !fir.array<3xi32> {bindc_name = "res1", uniq_name = "_QFEres1"}
     %6 = fir.shape %c3 : (index) -> !fir.shape<1>
@@ -37,57 +37,73 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     fir.store %c1_i64 to %18 : !fir.ref<i64>
     %19 = fir.embox %1 : (!fir.ref<!fir.array<3xi64>>) -> !fir.box<!fir.array<3xi64>>
     %20 = fir.embox %0 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
-    mif.alloc_coarray %4#0 lcobounds %19 ucobounds %20 errmsg %10 {uniq_name = "_QFEa"} : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>, !fir.box<none>) -> ()
-    %21 = fir.load %4#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
-    %22 = fir.box_addr %21 {fir.corank = 3 : i32} : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
-// CHECK: fir.call @_QMprifPprif_lcobound_no_dim
-    %23 = mif.lcobound coarray %22 : (!fir.heap<i32>) -> !fir.box<!fir.array<?xi64>>
-    %24:2 = hlfir.declare %23 {uniq_name = ".tmp.intrinsic_result"} : (!fir.box<!fir.array<?xi64>>) -> (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>)
-    %false = arith.constant false
-    %25 = hlfir.as_expr %24#0 move %false : (!fir.box<!fir.array<?xi64>>, i1) -> !hlfir.expr<?xi64>
+    mif.alloc_coarray %4#0 lcobounds %19 ucobounds %20 errmsg %10 {uniq_name = "_QFEa"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 3>>>>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>, !fir.box<none>) -> ()
+    %21 = fir.load %4#0 : !fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 3>>>>
+    %22 = fir.box_addr %21 {fir.corank = 3 : i32} : (!fir.box<!fir.heap<!fir.coarray<i32, 3>>>) -> !fir.heap<!fir.coarray<i32, 3>>
+    %23 = fir.alloca !fir.array<3xi32>
+    %c1_i32 = arith.constant 1 : i32
+// CHECK: fir.call @_QMprifPprif_lcobound_with_dim
+    %24 = mif.lcobound coarray %22 dim %c1_i32 : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32
     %c0_0 = arith.constant 0 : index
-    %26:3 = fir.box_dims %24#0, %c0_0 : (!fir.box<!fir.array<?xi64>>, index) -> (index, index, index)
-    %27 = fir.shape %26#1 : (index) -> !fir.shape<1>
-    %28 = hlfir.elemental %27 unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
-    ^bb0(%arg0: index):
-      %43 = hlfir.apply %25, %arg0 : (!hlfir.expr<?xi64>, index) -> i64
-      %44 = fir.convert %43 : (i64) -> i32
-      hlfir.yield_element %44 : i32
-    }
-    hlfir.assign %28 to %7#0 : !hlfir.expr<?xi32>, !fir.ref<!fir.array<3xi32>>
-    hlfir.destroy %28 : !hlfir.expr<?xi32>
-    hlfir.destroy %25 : !hlfir.expr<?xi64>
+    %25 = fir.coordinate_of %23, %c0_0 : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+    fir.store %24 to %25 : !fir.ref<i32>
     %c2_i32_1 = arith.constant 2 : i32
-    %29 = fir.load %4#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
-    %30 = fir.box_addr %29 {fir.corank = 3 : i32} : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
 // CHECK: fir.call @_QMprifPprif_lcobound_with_dim
-    %31 = mif.lcobound coarray %30 dim %c2_i32_1 : (!fir.heap<i32>, i32) -> i32
-    hlfir.assign %31 to %9#0 : i32, !fir.ref<i32>
-    %32 = fir.load %4#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
-    %33 = fir.box_addr %32 {fir.corank = 3 : i32} : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
-    %34 = mif.ucobound coarray %33 : (!fir.heap<i32>) -> !fir.box<!fir.array<?xi64>>
-// CHECK: fir.call @_QMprifPprif_ucobound_no_dim
-    %35:2 = hlfir.declare %34 {uniq_name = ".tmp.intrinsic_result"} : (!fir.box<!fir.array<?xi64>>) -> (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>)
-    %false_2 = arith.constant false
-    %36 = hlfir.as_expr %35#0 move %false_2 : (!fir.box<!fir.array<?xi64>>, i1) -> !hlfir.expr<?xi64>
-    %c0_3 = arith.constant 0 : index
-    %37:3 = fir.box_dims %35#0, %c0_3 : (!fir.box<!fir.array<?xi64>>, index) -> (index, index, index)
-    %38 = fir.shape %37#1 : (index) -> !fir.shape<1>
-    %39 = hlfir.elemental %38 unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
-    ^bb0(%arg0: index):
-      %43 = hlfir.apply %36, %arg0 : (!hlfir.expr<?xi64>, index) -> i64
-      %44 = fir.convert %43 : (i64) -> i32
-      hlfir.yield_element %44 : i32
-    }
-    hlfir.assign %39 to %7#0 : !hlfir.expr<?xi32>, !fir.ref<!fir.array<3xi32>>
-    hlfir.destroy %39 : !hlfir.expr<?xi32>
-    hlfir.destroy %36 : !hlfir.expr<?xi64>
-    %c2_i32_4 = arith.constant 2 : i32
-    %40 = fir.load %4#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
-    %41 = fir.box_addr %40 {fir.corank = 3 : i32} : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+    %26 = mif.lcobound coarray %22 dim %c2_i32_1 : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32
+    %c1_2 = arith.constant 1 : index
+    %27 = fir.coordinate_of %23, %c1_2 : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+    fir.store %26 to %27 : !fir.ref<i32>
+    %c3_i32_3 = arith.constant 3 : i32
+// CHECK: fir.call @_QMprifPprif_lcobound_with_dim
+    %28 = mif.lcobound coarray %22 dim %c3_i32_3 : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32
+    %c2_4 = arith.constant 2 : index
+    %29 = fir.coordinate_of %23, %c2_4 : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+    fir.store %28 to %29 : !fir.ref<i32>
+    %30 = fir.embox %23 : (!fir.ref<!fir.array<3xi32>>) -> !fir.box<!fir.array<3xi32>>
+    %31:2 = hlfir.declare %30 {uniq_name = ".tmp.intrinsic_result"} : (!fir.box<!fir.array<3xi32>>) -> (!fir.box<!fir.array<3xi32>>, !fir.box<!fir.array<3xi32>>)
+    %false = arith.constant false
+    %32 = hlfir.as_expr %31#0 move %false : (!fir.box<!fir.array<3xi32>>, i1) -> !hlfir.expr<3xi32>
+    hlfir.assign %32 to %7#0 : !hlfir.expr<3xi32>, !fir.ref<!fir.array<3xi32>>
+    hlfir.destroy %32 : !hlfir.expr<3xi32>
+    %c2_i32_5 = arith.constant 2 : i32
+    %33 = fir.load %4#0 : !fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 3>>>>
+    %34 = fir.box_addr %33 {fir.corank = 3 : i32} : (!fir.box<!fir.heap<!fir.coarray<i32, 3>>>) -> !fir.heap<!fir.coarray<i32, 3>>
+// CHECK: fir.call @_QMprifPprif_lcobound_with_dim
+    %35 = mif.lcobound coarray %34 dim %c2_i32_5 : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32
+    hlfir.assign %35 to %9#0 : i32, !fir.ref<i32>
+    %36 = fir.load %4#0 : !fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 3>>>>
+    %37 = fir.box_addr %36 {fir.corank = 3 : i32} : (!fir.box<!fir.heap<!fir.coarray<i32, 3>>>) -> !fir.heap<!fir.coarray<i32, 3>>
+    %38 = fir.alloca !fir.array<3xi32>
+    %c1_i32_6 = arith.constant 1 : i32
+// CHECK: fir.call @_QMprifPprif_ucobound_with_dim
+    %39 = mif.ucobound coarray %37 dim %c1_i32_6 : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32
+    %c0_7 = arith.constant 0 : index
+    %40 = fir.coordinate_of %38, %c0_7 : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+    fir.store %39 to %40 : !fir.ref<i32>
+    %c2_i32_8 = arith.constant 2 : i32
+// CHECK: fir.call @_QMprifPprif_ucobound_with_dim
+    %41 = mif.ucobound coarray %37 dim %c2_i32_8 : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32
+    %c1_9 = arith.constant 1 : index
+    %42 = fir.coordinate_of %38, %c1_9 : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+    fir.store %41 to %42 : !fir.ref<i32>
+    %c3_i32_10 = arith.constant 3 : i32
+// CHECK: fir.call @_QMprifPprif_ucobound_with_dim
+    %43 = mif.ucobound coarray %37 dim %c3_i32_10 : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32
+    %c2_11 = arith.constant 2 : index
+    %44 = fir.coordinate_of %38, %c2_11 : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+    fir.store %43 to %44 : !fir.ref<i32>
+    %45 = fir.embox %38 : (!fir.ref<!fir.array<3xi32>>) -> !fir.box<!fir.array<3xi32>>
+    %46:2 = hlfir.declare %45 {uniq_name = ".tmp.intrinsic_result"} : (!fir.box<!fir.array<3xi32>>) -> (!fir.box<!fir.array<3xi32>>, !fir.box<!fir.array<3xi32>>)
+    %false_12 = arith.constant false
+    %47 = hlfir.as_expr %46#0 move %false_12 : (!fir.box<!fir.array<3xi32>>, i1) -> !hlfir.expr<3xi32>
+    hlfir.assign %47 to %7#0 : !hlfir.expr<3xi32>, !fir.ref<!fir.array<3xi32>>
+    hlfir.destroy %47 : !hlfir.expr<3xi32>
+    %c2_i32_13 = arith.constant 2 : i32
+    %48 = fir.load %4#0 : !fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 3>>>>
+    %49 = fir.box_addr %48 {fir.corank = 3 : i32} : (!fir.box<!fir.heap<!fir.coarray<i32, 3>>>) -> !fir.heap<!fir.coarray<i32, 3>>
 // CHECK: fir.call @_QMprifPprif_ucobound_with_dim
-    %42 = mif.ucobound coarray %41 dim %c2_i32_4 : (!fir.heap<i32>, i32) -> i32
-    hlfir.assign %42 to %9#0 : i32, !fir.ref<i32>
+    %50 = mif.ucobound coarray %49 dim %c2_i32_13 : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32
+    hlfir.assign %50 to %9#0 : i32, !fir.ref<i32>
     return
   }
 }
diff --git a/flang/test/Fir/MIF/coshape.mlir b/flang/test/Fir/MIF/coshape.mlir
index 1a019117cf8f1..f68a3801b5e6d 100644
--- a/flang/test/Fir/MIF/coshape.mlir
+++ b/flang/test/Fir/MIF/coshape.mlir
@@ -5,7 +5,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %0 = fir.alloca !fir.array<2xi64>
     %1 = fir.alloca !fir.array<3xi64>
     %2 = fir.dummy_scope : !fir.dscope
-    %3 = fir.address_of(@_QFEa) : !fir.ref<i32>
+    %3 = fir.address_of(@_QFEa) : !fir.ref<!fir.coarray<i32, 3>>
     %c1_i64 = arith.constant 1 : i64
     %c0 = arith.constant 0 : index
     %4 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
@@ -28,8 +28,8 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %9 = fir.coordinate_of %0, %c1_4 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
     fir.store %c3_i64_3 to %9 : !fir.ref<i64>
     %10 = fir.embox %0 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
-    mif.alloc_coarray %3 lcobounds %7 ucobounds %10 {uniq_name = "_QFEa"} : (!fir.ref<i32>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>) -> ()
-    %11:2 = hlfir.declare %3 {fir.corank = 3 : i32, uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    mif.alloc_coarray %3 lcobounds %7 ucobounds %10 {uniq_name = "_QFEa"} : (!fir.ref<!fir.coarray<i32, 3>>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>) -> ()
+    %11:2 = hlfir.declare %3 {fir.corank = 3 : i32, uniq_name = "_QFEa"} : (!fir.ref<!fir.coarray<i32, 3>>) -> (!fir.ref<!fir.coarray<i32, 3>>, !fir.ref<!fir.coarray<i32, 3>>)
     %c3 = arith.constant 3 : index
     %12 = fir.alloca !fir.array<3xi32> {bindc_name = "res", uniq_name = "_QFEres"}
     %13 = fir.shape %c3 : (index) -> !fir.shape<1>
@@ -38,7 +38,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %15 = fir.alloca !fir.array<3xi64> {bindc_name = "res2", uniq_name = "_QFEres2"}
     %16 = fir.shape %c3_5 : (index) -> !fir.shape<1>
     %17:2 = hlfir.declare %15(%16) {uniq_name = "_QFEres2"} : (!fir.ref<!fir.array<3xi64>>, !fir.shape<1>) -> (!fir.ref<!fir.array<3xi64>>, !fir.ref<!fir.array<3xi64>>)
-    %18 = mif.coshape coarray %11#0 : (!fir.ref<i32>) -> !fir.box<!fir.array<?xi64>>
+    %18 = mif.coshape coarray %11#0 : (!fir.ref<!fir.coarray<i32, 3>>) -> !fir.box<!fir.array<?xi64>>
     %19:2 = hlfir.declare %18 {uniq_name = ".tmp.intrinsic_result"} : (!fir.box<!fir.array<?xi64>>) -> (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>)
     %false = arith.constant false
     %20 = hlfir.as_expr %19#0 move %false : (!fir.box<!fir.array<?xi64>>, i1) -> !hlfir.expr<?xi64>
@@ -54,7 +54,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     hlfir.assign %23 to %14#0 : !hlfir.expr<?xi32>, !fir.ref<!fir.array<3xi32>>
     hlfir.destroy %23 : !hlfir.expr<?xi32>
     hlfir.destroy %20 : !hlfir.expr<?xi64>
-    %24 = mif.coshape coarray %11#0 : (!fir.ref<i32>) -> !fir.box<!fir.array<?xi64>>
+    %24 = mif.coshape coarray %11#0 : (!fir.ref<!fir.coarray<i32, 3>>) -> !fir.box<!fir.array<?xi64>>
     %25:2 = hlfir.declare %24 {uniq_name = ".tmp.intrinsic_result"} : (!fir.box<!fir.array<?xi64>>) -> (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>)
     %false_7 = arith.constant false
     %26 = hlfir.as_expr %25#0 move %false_7 : (!fir.box<!fir.array<?xi64>>, i1) -> !hlfir.expr<?xi64>
diff --git a/flang/test/Fir/MIF/image_index.mlir b/flang/test/Fir/MIF/image_index.mlir
index 608dca26e8a6f..7298a59dd1fe7 100644
--- a/flang/test/Fir/MIF/image_index.mlir
+++ b/flang/test/Fir/MIF/image_index.mlir
@@ -6,7 +6,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %0 = fir.alloca !fir.array<2xi64>
     %1 = fir.alloca !fir.array<3xi64>
     %2 = fir.dummy_scope : !fir.dscope
-    %3 = fir.address_of(@_QFEa) : !fir.ref<i32>
+    %3 = fir.address_of(@_QFEa) : !fir.ref<!fir.coarray<i32, 3>>
     %c1_i64 = arith.constant 1 : i64
     %c0 = arith.constant 0 : index
     %4 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<3xi64>>, index) -> !fir.ref<i64>
@@ -29,8 +29,8 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %9 = fir.coordinate_of %0, %c1_4 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
     fir.store %c3_i64_3 to %9 : !fir.ref<i64>
     %10 = fir.embox %0 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
-    mif.alloc_coarray %3 lcobounds %7 ucobounds %10 {uniq_name = "_QFEa"} : (!fir.ref<i32>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>) -> ()
-    %11:2 = hlfir.declare %3 {fir.corank = 3 : i32, uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    mif.alloc_coarray %3 lcobounds %7 ucobounds %10 {uniq_name = "_QFEa"} : (!fir.ref<!fir.coarray<i32, 3>>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>) -> ()
+    %11:2 = hlfir.declare %3 {fir.corank = 3 : i32, uniq_name = "_QFEa"} : (!fir.ref<!fir.coarray<i32, 3>>) -> (!fir.ref<!fir.coarray<i32, 3>>, !fir.ref<!fir.coarray<i32, 3>>)
     %12 = fir.alloca i32 {bindc_name = "idx", uniq_name = "_QFEidx"}
     %13:2 = hlfir.declare %12 {uniq_name = "_QFEidx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
     %14 = fir.address_of(@_QFEsub) : !fir.ref<!fir.array<3xi32>>
@@ -50,17 +50,17 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %25 = fir.shape %c3 : (index) -> !fir.shape<1>
     %26 = fir.embox %16#0(%25) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>>
 // CHECK: fir.call @_QMprifPprif_image_index
-    %27 = mif.image_index coarray %11#0 sub %26 : (!fir.ref<i32>, !fir.box<!fir.array<3xi32>>) -> i32
+    %27 = mif.image_index coarray %11#0 sub %26 : (!fir.ref<!fir.coarray<i32, 3>>, !fir.box<!fir.array<3xi32>>) -> i32
     hlfir.assign %27 to %13#0 : i32, !fir.ref<i32>
     %28 = fir.shape %c3_5 : (index) -> !fir.shape<1>
     %29 = fir.embox %19#0(%28) : (!fir.ref<!fir.array<3xi64>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi64>>
 // CHECK: fir.call @_QMprifPprif_image_index
-    %30 = mif.image_index coarray %11#0 sub %29 : (!fir.ref<i32>, !fir.box<!fir.array<3xi64>>) -> i32
+    %30 = mif.image_index coarray %11#0 sub %29 : (!fir.ref<!fir.coarray<i32, 3>>, !fir.box<!fir.array<3xi64>>) -> i32
     hlfir.assign %30 to %13#0 : i32, !fir.ref<i32>
     %31 = fir.shape %c3 : (index) -> !fir.shape<1>
     %32 = fir.embox %16#0(%31) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>>
 // CHECK: fir.call @_QMprifPprif_image_index_with_team
-    %33 = mif.image_index coarray %11#0 sub %32 team %21#0 : (!fir.ref<i32>, !fir.box<!fir.array<3xi32>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>) -> i32
+    %33 = mif.image_index coarray %11#0 sub %32 team %21#0 : (!fir.ref<!fir.coarray<i32, 3>>, !fir.box<!fir.array<3xi32>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>) -> i32
     hlfir.assign %33 to %13#0 : i32, !fir.ref<i32>
     return
   }
diff --git a/flang/test/Fir/MIF/this_image.mlir b/flang/test/Fir/MIF/this_image.mlir
index d68827c7cf9ba..33896d2ccc262 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.alloca !fir.array<1xi64>
     %1 = fir.alloca !fir.array<2xi64>
     %2 = fir.dummy_scope : !fir.dscope
-    %3 = fir.address_of(@_QFEa) : !fir.ref<i32>
+    %3 = fir.address_of(@_QFEa) : !fir.ref<!fir.coarray<i32, 2>>
     %c1_i64 = arith.constant 1 : i64
     %c0 = arith.constant 0 : index
     %4 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<2xi64>>, index) -> !fir.ref<i64>
@@ -20,8 +20,8 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %7 = fir.coordinate_of %0, %c0_2 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
     fir.store %c1_i64_1 to %7 : !fir.ref<i64>
     %8 = fir.embox %0 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
-    mif.alloc_coarray %3 lcobounds %6 ucobounds %8 {uniq_name = "_QFEa"} : (!fir.ref<i32>, !fir.box<!fir.array<2xi64>>, !fir.box<!fir.array<1xi64>>) -> ()
-    %9:2 = hlfir.declare %3 {fir.corank = 2 : i32, uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    mif.alloc_coarray %3 lcobounds %6 ucobounds %8 {uniq_name = "_QFEa"} : (!fir.ref<!fir.coarray<i32, 2>>, !fir.box<!fir.array<2xi64>>, !fir.box<!fir.array<1xi64>>) -> ()
+    %9:2 = hlfir.declare %3 {fir.corank = 2 : i32, uniq_name = "_QFEa"} : (!fir.ref<!fir.coarray<i32, 2>>) -> (!fir.ref<!fir.coarray<i32, 2>>, !fir.ref<!fir.coarray<i32, 2>>)
     %10 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
     %11:2 = hlfir.declare %10 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
     %c2 = arith.constant 2 : index
@@ -36,7 +36,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     hlfir.assign %18 to %11#0 : i32, !fir.ref<i32>
     %19 = mif.this_image team %16#0 : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>) -> i32
     hlfir.assign %19 to %11#0 : i32, !fir.ref<i32>
-    %20 = mif.this_image coarray %9#0 : (!fir.ref<i32>) -> !fir.box<!fir.array<?xi64>>
+    %20 = mif.this_image coarray %9#0 : (!fir.ref<!fir.coarray<i32, 2>>) -> !fir.box<!fir.array<?xi64>>
     %21:2 = hlfir.declare %20 {uniq_name = ".tmp.intrinsic_result"} : (!fir.box<!fir.array<?xi64>>) -> (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>)
     %false = arith.constant false
     %22 = hlfir.as_expr %21#0 move %false : (!fir.box<!fir.array<?xi64>>, i1) -> !hlfir.expr<?xi64>
@@ -45,16 +45,17 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %24 = fir.shape %23#1 : (index) -> !fir.shape<1>
     %25 = hlfir.elemental %24 unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
     ^bb0(%arg0: index):
-      %27 = hlfir.apply %22, %arg0 : (!hlfir.expr<?xi64>, index) -> i64
-      %28 = fir.convert %27 : (i64) -> i32
-      hlfir.yield_element %28 : i32
+      %28 = hlfir.apply %22, %arg0 : (!hlfir.expr<?xi64>, index) -> i64
+      %29 = fir.convert %28 : (i64) -> i32
+      hlfir.yield_element %29 : i32
     }
     hlfir.assign %25 to %14#0 : !hlfir.expr<?xi32>, !fir.ref<!fir.array<2xi32>>
     hlfir.destroy %25 : !hlfir.expr<?xi32>
     hlfir.destroy %22 : !hlfir.expr<?xi64>
     %c1_i32 = arith.constant 1 : i32
-    %26 = mif.this_image coarray %9#0 dim %c1_i32 : (!fir.ref<i32>, i32) -> i32
-    hlfir.assign %26 to %14#0 : i32, !fir.ref<!fir.array<2xi32>>
+    %26 = mif.this_image coarray %9#0 dim %c1_i32 : (!fir.ref<!fir.coarray<i32, 2>>, i32) -> i64
+    %27 = fir.convert %26 : (i64) -> i32
+    hlfir.assign %27 to %14#0 : i32, !fir.ref<!fir.array<2xi32>>
     return
   }
 }
diff --git a/flang/test/Lower/MIF/coarray_allocation.f90 b/flang/test/Lower/MIF/coarray_allocation.f90
index 64122aa21d582..3b3c39586e7fe 100644
--- a/flang/test/Lower/MIF/coarray_allocation.f90
+++ b/flang/test/Lower/MIF/coarray_allocation.f90
@@ -11,22 +11,22 @@ program alloc_test
     type(my_type2) :: z
   end type
   
-  ! CHECK: %[[VAL_1:.*]] = fir.address_of(@_QFEa) : !fir.ref<i32>
-  ! CHECK: mif.alloc_coarray %[[VAL_1]] lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] {uniq_name = "_QFEa"} : (!fir.ref<i32>, !fir.box<!fir.array<2xi64>>, !fir.box<!fir.array<1xi64>>) -> ()
+  ! CHECK: %[[VAL_1:.*]] = fir.address_of(@_QFEa) : !fir.ref<!fir.coarray<i32, 2>>
+  ! CHECK: mif.alloc_coarray %[[VAL_1]] lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] {uniq_name = "_QFEa"} : (!fir.ref<!fir.coarray<i32, 2>>, !fir.box<!fir.array<2xi64>>, !fir.box<!fir.array<1xi64>>) -> ()
   
-  ! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[ADDR_1:.*]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEa2"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)
+  ! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[ADDR_1:.*]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEa2"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 2>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 2>>>>, !fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 2>>>>)
   
   integer :: a[2, *]
-  ! CHECK: %[[VAL_2:.*]] = fir.address_of(@_QFEb) : !fir.ref<f32>
-  ! CHECK: mif.alloc_coarray %[[VAL_2]] lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] {uniq_name = "_QFEb"} : (!fir.ref<f32>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>) -> ()
+  ! CHECK: %[[VAL_2:.*]] = fir.address_of(@_QFEb) : !fir.ref<!fir.coarray<f32, 3>>
+  ! CHECK: mif.alloc_coarray %[[VAL_2]] lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] {uniq_name = "_QFEb"} : (!fir.ref<!fir.coarray<f32, 3>>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>) -> ()
   
-  ! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[ADDR_2:.*]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEb2"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>)
+  ! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[ADDR_2:.*]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEb2"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<f32, 3>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.coarray<f32, 3>>>>, !fir.ref<!fir.box<!fir.heap<!fir.coarray<f32, 3>>>>)
   
   real :: b[3:4, 5, *]
-  ! CHECK: %[[VAL_3:.*]] = fir.address_of(@_QFEc) : !fir.ref<!fir.char<1,10>>
-  ! CHECK: mif.alloc_coarray %[[VAL_3]] lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] {uniq_name = "_QFEc"} : (!fir.ref<!fir.char<1,10>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
+  ! CHECK: %[[VAL_3:.*]] = fir.address_of(@_QFEc) : !fir.ref<!fir.coarray<!fir.char<1,10>, 1>>
+  ! CHECK: mif.alloc_coarray %[[VAL_3]] lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] {uniq_name = "_QFEc"} : (!fir.ref<!fir.coarray<!fir.char<1,10>, 1>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
   
-  ! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[ADDR_3:.*]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEc2"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>)
+  ! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[ADDR_3:.*]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEc2"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?x!fir.char<1,?>>, 1>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?x!fir.char<1,?>>, 1>>>>, !fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?x!fir.char<1,?>>, 1>>>>)
   character(len=10) :: c[*]
   type(my_type) :: d
 
@@ -35,29 +35,29 @@ program alloc_test
   integer, allocatable :: a2[:,:]
   
   ! CHECK: %[[VAL_7:.*]] = fir.absent !fir.box<none>
-  ! CHECK: mif.alloc_coarray %[[VAL_4]]#0 lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] errmsg %[[VAL_7]] {uniq_name = "_QFEa2"} : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.array<2xi64>>, !fir.box<!fir.array<1xi64>>, !fir.box<none>) -> ()
+  ! CHECK: mif.alloc_coarray %[[VAL_4]]#0 lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] errmsg %[[VAL_7]] {uniq_name = "_QFEa2"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 2>>>>, !fir.box<!fir.array<2xi64>>, !fir.box<!fir.array<1xi64>>, !fir.box<none>) -> ()
   allocate(a2[2,*])
   
   ! CHECK: %[[VAL_8:.*]] = fir.absent !fir.box<none>
-  ! CHECK: mif.alloc_coarray %[[VAL_5]]#0 lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] errmsg %[[VAL_8]] {uniq_name = "_QFEb2"} : (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>, !fir.box<none>) -> ()
+  ! CHECK: mif.alloc_coarray %[[VAL_5]]#0 lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] errmsg %[[VAL_8]] {uniq_name = "_QFEb2"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<f32, 3>>>>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>, !fir.box<none>) -> ()
   allocate(b2[3:4, 5, *])
   
   ! CHECK: %[[VAL_9:.*]] = fir.absent !fir.box<none>
-  ! CHECK: mif.alloc_coarray %[[VAL_6]]#0 lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] errmsg %[[VAL_9]] {uniq_name = "_QFEc2"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>, !fir.box<none>) -> ()
+  ! CHECK: mif.alloc_coarray %[[VAL_6]]#0 lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] errmsg %[[VAL_9]] {uniq_name = "_QFEc2"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?x!fir.char<1,?>>, 1>>>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>, !fir.box<none>) -> ()
   allocate(character(100) :: c2(5)[*])
   
   ! CHECK: %[[VAL_10:.*]] = fir.absent !fir.box<none>
   ! CHECK: %[[VAL_12:.*]] = hlfir.designate %[[VAL_11:.*]]{"co"}
-  ! CHECK:  mif.alloc_coarray %[[VAL_12]] lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] errmsg %[[VAL_10]] {uniq_name = "_QFEd.z.co"} : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>, !fir.box<none>) -> ()
+  ! CHECK:  mif.alloc_coarray %[[VAL_12]] lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] errmsg %[[VAL_10]] {uniq_name = "_QFEd.z.co"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 1>>>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>, !fir.box<none>) -> ()
   allocate(d%z%co[*])
 
-  ! CHECK: mif.dealloc_coarray %[[VAL_4]]#0 stat %[[STAT:.*]] errmsg %[[ERRMSG:.*]] : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<i32>, !fir.box<none>) -> ()
-  ! CHECK: mif.dealloc_coarray %[[VAL_5]]#0 stat %[[STAT:.*]] errmsg %[[ERRMSG:.*]] : (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<i32>, !fir.box<none>) -> ()
-  ! CHECK: mif.dealloc_coarray %[[VAL_6]]#0 stat %[[STAT:.*]] errmsg %[[ERRMSG:.*]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>, !fir.ref<i32>, !fir.box<none>) -> ()
+  ! CHECK: mif.dealloc_coarray %[[VAL_4]]#0 stat %[[STAT:.*]] errmsg %[[ERRMSG:.*]] : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 2>>>>, !fir.ref<i32>, !fir.box<none>) -> ()
+  ! CHECK: mif.dealloc_coarray %[[VAL_5]]#0 stat %[[STAT:.*]] errmsg %[[ERRMSG:.*]] : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<f32, 3>>>>, !fir.ref<i32>, !fir.box<none>) -> ()
+  ! CHECK: mif.dealloc_coarray %[[VAL_6]]#0 stat %[[STAT:.*]] errmsg %[[ERRMSG:.*]] : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?x!fir.char<1,?>>, 1>>>>, !fir.ref<i32>, !fir.box<none>) -> ()
   deallocate(a2, b2, c2)
   
   ! CHECK: %[[VAL_14:.*]] = hlfir.designate %[[VAL_13:.*]]{"co"} {{.*}}
-  ! CHECK: mif.dealloc_coarray %[[VAL_14]] stat %[[STAT:.*]] errmsg %[[ERRMSG:.*]] : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<i32>, !fir.box<none>) -> ()
+  ! CHECK: mif.dealloc_coarray %[[VAL_14]] stat %[[STAT:.*]] errmsg %[[ERRMSG:.*]] : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<i32, 1>>>>, !fir.ref<i32>, !fir.box<none>) -> ()
   deallocate(d%z%co)
   
 end program 
diff --git a/flang/test/Lower/MIF/coarray_allocation2.f90 b/flang/test/Lower/MIF/coarray_allocation2.f90
index 89000203925d8..72c106b613c20 100644
--- a/flang/test/Lower/MIF/coarray_allocation2.f90
+++ b/flang/test/Lower/MIF/coarray_allocation2.f90
@@ -12,18 +12,18 @@ end subroutine test_coarray_cleanup
 !CHECK:  %[[VAL_0:.*]] = fir.alloca !fir.array<0xi64>
 !CHECK:  %[[VAL_1:.*]] = fir.alloca !fir.array<1xi64>
 !CHECK:  %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
-!CHECK:  %[[VAL_3:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "n", uniq_name = "_QFtest_coarray_cleanupEn"}
-!CHECK:  %[[VAL_4:.*]] = fir.zero_bits !fir.heap<!fir.array<?xf32>>
+!CHECK:  %[[VAL_3:.*]] = fir.alloca !fir.box<!fir.heap<!fir.coarray<!fir.array<?xf32>, 1>>> {bindc_name = "n", uniq_name = "_QFtest_coarray_cleanupEn"}
+!CHECK:  %[[VAL_4:.*]] = fir.zero_bits !fir.heap<!fir.coarray<!fir.array<?xf32>, 1>>
 !CHECK:  %[[C0:.*]] = arith.constant 0 : index
 !CHECK:  %[[VAL_5:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>
-!CHECK:  %[[VAL_6:.*]] = fir.embox %[[VAL_4]](%[[VAL_5]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
-!CHECK:  fir.store %[[VAL_6]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-!CHECK:  %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_3]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_coarray_cleanupEn"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
+!CHECK:  %[[VAL_6:.*]] = fir.embox %[[VAL_4]](%[[VAL_5]]) : (!fir.heap<!fir.coarray<!fir.array<?xf32>, 1>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.coarray<!fir.array<?xf32>, 1>>>
+!CHECK:  fir.store %[[VAL_6]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?xf32>, 1>>>>
+!CHECK:  %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_3]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_coarray_cleanupEn"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?xf32>, 1>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?xf32>, 1>>>>, !fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?xf32>, 1>>>>)
 !CHECK:  %[[VAL_8:.*]] = fir.absent !fir.box<none>
 !CHECK:  %[[C1:.*]] = arith.constant 1 : index
 !CHECK:  %[[C10_i32:.*]] = arith.constant 10 : i32
 !CHECK:  %[[C0_i32:.*]] = arith.constant 0 : i32
-!CHECK:  %[[VAL_9:.*]] = fir.convert %[[VAL_7]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
+!CHECK:  %[[VAL_9:.*]] = fir.convert %[[VAL_7]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?xf32>, 1>>>>) -> !fir.ref<!fir.box<none>>
 !CHECK:  %[[VAL_10:.*]] = fir.convert %[[C1]] : (index) -> i64
 !CHECK:  %[[VAL_11:.*]] = fir.convert %[[C10_i32]] : (i32) -> i64
 !CHECK:  fir.call @_FortranAAllocatableSetBounds(%[[VAL_9:.*]], %[[C0_i32]], %[[VAL_10]], %[[VAL_11]]) fastmath<contract> : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
@@ -33,17 +33,17 @@ end subroutine test_coarray_cleanup
 !CHECK:  fir.store %[[C1_i64]] to %[[VAL_12]] : !fir.ref<i64>
 !CHECK:  %[[VAL_13:.*]] = fir.embox %[[VAL_1]] : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
 !CHECK:  %[[VAL_14:.*]] = fir.embox %[[VAL_0]] : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
-!CHECK:  mif.alloc_coarray %[[VAL_7]]#0 lcobounds %[[VAL_13]] ucobounds %[[VAL_14]] errmsg %[[VAL_8]] {uniq_name = "_QFtest_coarray_cleanupEn"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>, !fir.box<none>) -> ()
+!CHECK:  mif.alloc_coarray %[[VAL_7]]#0 lcobounds %[[VAL_13]] ucobounds %[[VAL_14]] errmsg %[[VAL_8]] {uniq_name = "_QFtest_coarray_cleanupEn"} : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?xf32>, 1>>>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>, !fir.box<none>) -> ()
 !CHECK:  mif.sync_all : () -> ()
-!CHECK:  %[[VAL_15:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-!CHECK:  %[[VAL_16:.*]] = fir.box_addr %[[VAL_15]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
-!CHECK:  %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (!fir.heap<!fir.array<?xf32>>) -> i64
+!CHECK:  %[[VAL_15:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?xf32>, 1>>>>
+!CHECK:  %[[VAL_16:.*]] = fir.box_addr %[[VAL_15]] : (!fir.box<!fir.heap<!fir.coarray<!fir.array<?xf32>, 1>>>) -> !fir.heap<!fir.coarray<!fir.array<?xf32>, 1>>
+!CHECK:  %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (!fir.heap<!fir.coarray<!fir.array<?xf32>, 1>>) -> i64
 !CHECK:  %[[C0_i64:.*]] = arith.constant 0 : i64
 !CHECK:  %[[VAL_18:.*]] = arith.cmpi ne, %[[VAL_17]], %[[C0_i64]] : i64
 !CHECK:  fir.if %[[VAL_18]] {
 !CHECK:    %[[VAL_19:.*]] = fir.absent !fir.box<none>
 !CHECK:    %[[VAL_20:.*]] = fir.absent !fir.ref<i32>
-!CHECK:    mif.dealloc_coarray %[[VAL_7]]#0 stat %[[VAL_20]] errmsg %[[VAL_19]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<i32>, !fir.box<none>) -> ()
+!CHECK:    mif.dealloc_coarray %[[VAL_7]]#0 stat %[[VAL_20]] errmsg %[[VAL_19]] : (!fir.ref<!fir.box<!fir.heap<!fir.coarray<!fir.array<?xf32>, 1>>>>, !fir.ref<i32>, !fir.box<none>) -> ()
 !CHECK:  }
 !CHECK:  return
 
diff --git a/flang/test/Lower/MIF/cobound.f90 b/flang/test/Lower/MIF/cobound.f90
index e5ad3f94d4beb..3e9328e794bdc 100644
--- a/flang/test/Lower/MIF/cobound.f90
+++ b/flang/test/Lower/MIF/cobound.f90
@@ -6,16 +6,20 @@ program test
 
   allocate(a[2,3:5,*])
 
-  ! CHECK: mif.lcobound coarray %[[COARRAY:.*]] : (!fir.heap<i32>) -> !fir.box<!fir.array<?xi64>>
+  ! CHECK: mif.lcobound coarray %[[COARRAY:.*]] dim %[[C1_I32:.*]] : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32 
+  ! CHECK: mif.lcobound coarray %[[COARRAY]] dim %[[C2_I32:.*]] : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32 
+  ! CHECK: mif.lcobound coarray %[[COARRAY]] dim %[[C3_I32:.*]] : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32 
   res1 = lcobound(a)
 
-  ! CHECK: mif.lcobound coarray %[[COARRAY:.*]] dim %[[C2:.*]] : (!fir.heap<i32>, i32) -> i32
+  ! CHECK: mif.lcobound coarray %[[COARRAY:.*]] dim %[[C2_I32:.*]] : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32
   res2 = lcobound(a, DIM=2)
 
-  ! CHECK: mif.ucobound coarray %[[COARRAY:.*]] : (!fir.heap<i32>) -> !fir.box<!fir.array<?xi64>>
+  ! CHECK: mif.ucobound coarray %[[COARRAY:.*]] dim %[[C1_I32:.*]] : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32 
+  ! CHECK: mif.ucobound coarray %[[COARRAY]] dim %[[C2_I32:.*]] : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32 
+  ! CHECK: mif.ucobound coarray %[[COARRAY]] dim %[[C3_I32:.*]] : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32 
   res1 = ucobound(a)
 
-  ! CHECK: mif.ucobound coarray %[[COARRAY:.*]] dim %[[C2:.*]] : (!fir.heap<i32>, i32) -> i32
+  ! CHECK: mif.ucobound coarray %[[COARRAY:.*]] dim %[[C2_I32:.*]] : (!fir.heap<!fir.coarray<i32, 3>>, i32) -> i32
   res2 = ucobound(a, DIM=2)
 
 end program
diff --git a/flang/test/Lower/MIF/coshape.f90 b/flang/test/Lower/MIF/coshape.f90
index da1360d26b3a6..985f2952da80d 100644
--- a/flang/test/Lower/MIF/coshape.f90
+++ b/flang/test/Lower/MIF/coshape.f90
@@ -5,10 +5,10 @@ program test
   integer(kind=8) :: res2(3)
   integer :: a[2,3:5,*]
 
-  ! CHECK: mif.coshape coarray %[[COARRAY:.*]]#0 : (!fir.ref<i32>) -> !fir.box<!fir.array<?xi64>>
+  ! CHECK: mif.coshape coarray %[[COARRAY:.*]]#0 : (!fir.ref<!fir.coarray<i32, 3>>) -> !fir.box<!fir.array<?xi64>>
   res = coshape(a)
 
-  ! CHECK: mif.coshape coarray %[[COARRAY:.*]]#0 : (!fir.ref<i32>) -> !fir.box<!fir.array<?xi64>>
+  ! CHECK: mif.coshape coarray %[[COARRAY:.*]]#0 : (!fir.ref<!fir.coarray<i32, 3>>) -> !fir.box<!fir.array<?xi64>>
   res2 = coshape(a)
 
 end program
diff --git a/flang/test/Lower/MIF/image_index.f90 b/flang/test/Lower/MIF/image_index.f90
index 88eb711679e6d..2fe606655531f 100644
--- a/flang/test/Lower/MIF/image_index.f90
+++ b/flang/test/Lower/MIF/image_index.f90
@@ -8,13 +8,13 @@ program test
   type(team_type) :: team
   integer :: team_number
 
-  ! CHECK: mif.image_index coarray %[[COARRAY:.*]]#0 sub %[[SUB:.*]] : (!fir.ref<i32>, !fir.box<!fir.array<3xi32>>) -> i32
+  ! CHECK: mif.image_index coarray %[[COARRAY:.*]]#0 sub %[[SUB:.*]] : (!fir.ref<!fir.coarray<i32, 3>>, !fir.box<!fir.array<3xi32>>) -> i32
   idx = image_index(a, SUB=sub)
 
-  ! CHECK: mif.image_index coarray %[[COARRAY:.*]]#0 sub %[[SUB2:.*]] : (!fir.ref<i32>, !fir.box<!fir.array<3xi64>>) -> i32
+  ! CHECK: mif.image_index coarray %[[COARRAY:.*]]#0 sub %[[SUB2:.*]] : (!fir.ref<!fir.coarray<i32, 3>>, !fir.box<!fir.array<3xi64>>) -> i32
   idx = image_index(a, SUB=sub2)
 
-  ! CHECK: mif.image_index coarray %[[COARRAY:.*]]#0 sub %[[SUB2:.*]] team %[[TEAM:.*]]#0 : (!fir.ref<i32>, !fir.box<!fir.array<3xi32>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>)
+  ! CHECK: mif.image_index coarray %[[COARRAY:.*]]#0 sub %[[SUB2:.*]] team %[[TEAM:.*]]#0 : (!fir.ref<!fir.coarray<i32, 3>>, !fir.box<!fir.array<3xi32>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{_QM__fortran_builtinsT__builtin_team_type.__id:i64}>>)
   idx = image_index(a, SUB=sub, TEAM=team)
 
 end program
diff --git a/flang/test/Lower/MIF/this_image.f90 b/flang/test/Lower/MIF/this_image.f90
index 1d33646155d18..041443432e0e9 100644
--- a/flang/test/Lower/MIF/this_image.f90
+++ b/flang/test/Lower/MIF/this_image.f90
@@ -9,12 +9,13 @@ program test
   ! CHECK: mif.this_image : () -> i32
   i = this_image()
 
-  ! CHECK: mif.this_image team %[[TEAM:.*]] : ({{.*}}) -> i32
+  ! CHECK: mif.this_image team %[[TEAM:.*]]#0 : ({{.*}}) -> i32
   i = this_image(TEAM=team)
 
-  ! CHECK: mif.this_image coarray %[[A:.*]] : ({{.*}}) -> !fir.box<!fir.array<?xi64>>
+  ! CHECK: mif.this_image coarray %[[A:.*]]#0 : ({{.*}}) -> !fir.box<!fir.array<?xi64>>
   j = this_image(COARRAY=a)
   
-  ! CHECK: mif.this_image coarray %[[A:.*]]#0 dim %[[DIM:.*]] : ({{.*}}) -> i32
+  ! CHECK: %[[VAL:.*]] = mif.this_image coarray %[[A:.*]]#0 dim %[[DIM:.*]] : (!fir.ref<!fir.coarray<i32, 2>>, i32) -> i64
+  ! CHECK: %[[VAL2:.*]] = fir.convert %[[VAL]] : (i64) -> i32
   j = this_image(COARRAY=a, DIM=1)
 end program



More information about the flang-commits mailing list