[flang-commits] [flang] [llvm] [flang][MIF] Adding lowering for EVENT POST/WAIT statements (PR #210283)

Jean-Didier PAILLEUX via flang-commits flang-commits at lists.llvm.org
Wed Sep 23 05:03:45 PDT 2026


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

>From 7a2caa86715132cc1943d0faddbd71898ee70f13 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Mon, 20 Apr 2026 14:15:08 +0200
Subject: [PATCH 1/7] [flang][MIF] Adding lowering for EVENT POST/WAIT
 statements

---
 flang-rt/lib/runtime/__fortran_builtins.f90   |   4 +-
 flang/include/flang/Lower/MultiImageFortran.h |  13 +
 flang/include/flang/Lower/Runtime.h           |   4 -
 .../flang/Optimizer/Dialect/MIF/MIFOps.td     |  52 ++++
 flang/lib/Lower/ConvertExprToHLFIR.cpp        |   5 +-
 flang/lib/Lower/MultiImageFortran.cpp         |  88 +++++++
 flang/lib/Lower/Runtime.cpp                   |  18 --
 flang/lib/Optimizer/Builder/MIFCommon.cpp     |   4 +
 .../Optimizer/Transforms/MIFOpConversion.cpp  | 227 ++++++++++++++++--
 flang/test/Fir/MIF/events.mlir                |  45 ++++
 flang/test/Lower/MIF/events.f90               |  56 +++++
 11 files changed, 478 insertions(+), 38 deletions(-)
 create mode 100644 flang/test/Fir/MIF/events.mlir
 create mode 100644 flang/test/Lower/MIF/events.f90

diff --git a/flang-rt/lib/runtime/__fortran_builtins.f90 b/flang-rt/lib/runtime/__fortran_builtins.f90
index 8c3983f38dd311..773b5679cfd714 100644
--- a/flang-rt/lib/runtime/__fortran_builtins.f90
+++ b/flang-rt/lib/runtime/__fortran_builtins.f90
@@ -52,7 +52,9 @@
   end type
 
   type, public :: __builtin_event_type
-    integer(kind=int64), private :: __count = -1
+    integer(kind=int64), private :: & ! 64-bytes of opaque zero-initialized data
+       __m1 = 0, __m2 = 0, __m3 = 0, __m4 = 0, &
+       __m5 = 0, __m6 = 0, __m7 = 0, __m8 = 0
   end type
 
   type, public :: __builtin_notify_type
diff --git a/flang/include/flang/Lower/MultiImageFortran.h b/flang/include/flang/Lower/MultiImageFortran.h
index 1f247ee46c3a96..a04740a5ec3418 100644
--- a/flang/include/flang/Lower/MultiImageFortran.h
+++ b/flang/include/flang/Lower/MultiImageFortran.h
@@ -34,6 +34,10 @@ namespace pft {
 struct Evaluation;
 } // namespace pft
 
+mlir::SmallVector<mlir::Value>
+getCosubscripts(AbstractConverter &converter, mlir::Location loc,
+                const Fortran::evaluate::CoarrayRef &expr);
+
 //===----------------------------------------------------------------------===//
 // Synchronization statements
 //===----------------------------------------------------------------------===//
@@ -85,6 +89,15 @@ void genAllocateNonAllocatableSaveCoarray(AbstractConverter &converter,
                                           const semantics::Symbol &sym,
                                           mlir::Value addr);
 
+//===----------------------------------------------------------------------===//
+// EVENT and NOTIFY statements
+//===----------------------------------------------------------------------===//
+
+void genNotifyWaitStatement(AbstractConverter &,
+                            const parser::NotifyWaitStmt &);
+void genEventPostStatement(AbstractConverter &, const parser::EventPostStmt &);
+void genEventWaitStatement(AbstractConverter &, const parser::EventWaitStmt &);
+
 //===----------------------------------------------------------------------===//
 // COARRAY expressions
 //===----------------------------------------------------------------------===//
diff --git a/flang/include/flang/Lower/Runtime.h b/flang/include/flang/Lower/Runtime.h
index 514345d9a89f14..fa139546d86758 100644
--- a/flang/include/flang/Lower/Runtime.h
+++ b/flang/include/flang/Lower/Runtime.h
@@ -48,10 +48,6 @@ class AbstractConverter;
 
 // Lowering of Fortran statement related runtime (other than IO and maths)
 
-void genNotifyWaitStatement(AbstractConverter &,
-                            const parser::NotifyWaitStmt &);
-void genEventPostStatement(AbstractConverter &, const parser::EventPostStmt &);
-void genEventWaitStatement(AbstractConverter &, const parser::EventWaitStmt &);
 void genLockStatement(AbstractConverter &, const parser::LockStmt &);
 void genFailImageStatement(AbstractConverter &);
 void genStopStatement(AbstractConverter &, const parser::StopStmt &);
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
index cdc81ab1b97648..df158290b5b15e 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -592,4 +592,56 @@ def mif_DeallocCoarrayOp
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// Events 
+//===----------------------------------------------------------------------===//
+
+def mif_EventPostOp : mif_Op<"event_post", [AttrSizedOperandSegments,
+                                            MemoryEffects<[MemWrite]>]> {
+  let summary = "Posts an event.";
+  let description = [{
+    This is a post-event operation.
+    Arguments: 
+      - `image_num`: Shall be an integer that correspond to the image index of 
+        the event variable.
+      - `event_var`: Shall be a coarray or be part of a coarray of 
+        type EVENT_TYPE from the intrinsic module ISO_FORTRAN_ENV.
+  }];
+
+  let arguments = (ins AnyRefOrBoxType:$event,
+      Variadic<AnyInteger>:$cosubscripts,
+      Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+      Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+
+  let assemblyFormat = [{
+    $event (`[` $cosubscripts^ `]` )? 
+    (`stat` $stat^ )?  (`errmsg` $errmsg^ )?
+    attr-dict `:` functional-type(operands, results)
+  }];
+}
+
+def mif_EventWaitOp : mif_Op<"event_wait", [AttrSizedOperandSegments,
+                                            MemoryEffects<[MemWrite]>]> {
+  let summary = "Waits until an event is posted.";
+  let description = [{
+    Arguments: 
+      - `event`: Shall be a reference of type EVENT_TYPE from the intrinsic
+        module ISO_FORTRAN_ENV.
+      - `until_count`(optional) : Shall be an integer scalar and indicate the count of 
+        the given event variable to be waited for.
+  }];
+
+  let arguments = (ins fir_ReferenceType:$event,
+      Optional<AnyIntegerType>:$until_count,
+      Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+      Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+
+  let assemblyFormat = [{
+    $event 
+    (`until_count` $until_count^ )?
+    (`stat` $stat^ )?  (`errmsg` $errmsg^ )?
+    attr-dict `:` functional-type(operands, results)
+  }];
+}
+
 #endif // FORTRAN_DIALECT_MIF_MIF_OPS
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index 24c990141be552..9c239ae01670aa 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -2366,8 +2366,11 @@ fir::ExtendedValue Fortran::lower::convertExprToBox(
     Fortran::lower::StatementContext &stmtCtx) {
   hlfir::EntityWithAttributes loweredExpr =
       HlfirBuilder(loc, converter, symMap, stmtCtx).gen(expr);
+  unsigned corank = 0;
+  if (auto coarray{evaluate::ExtractCoarrayRef(expr)})
+    corank = coarray->GetLastSymbol().Corank();
   return convertToBox(loc, converter, loweredExpr, stmtCtx,
-                      converter.genType(expr));
+                      converter.genType(expr), corank);
 }
 
 fir::ExtendedValue Fortran::lower::convertToAddress(
diff --git a/flang/lib/Lower/MultiImageFortran.cpp b/flang/lib/Lower/MultiImageFortran.cpp
index 931bc5e66b3cfe..ea2d00c7252cba 100644
--- a/flang/lib/Lower/MultiImageFortran.cpp
+++ b/flang/lib/Lower/MultiImageFortran.cpp
@@ -520,3 +520,91 @@ fir::ExtendedValue Fortran::lower::CoarrayExprHelper::genValue(
     const Fortran::evaluate::CoarrayRef &expr) {
   TODO(converter.getCurrentLocation(), "coarray: coarray value");
 }
+
+//===----------------------------------------------------------------------===//
+// EVENT and NOTIFY statements
+//===----------------------------------------------------------------------===//
+
+void Fortran::lower::genNotifyWaitStatement(
+    Fortran::lower::AbstractConverter &converter,
+    const Fortran::parser::NotifyWaitStmt &) {
+  TODO(converter.getCurrentLocation(), "coarray: NOTIFY WAIT runtime");
+}
+
+void Fortran::lower::genEventPostStatement(
+    Fortran::lower::AbstractConverter &converter,
+    const Fortran::parser::EventPostStmt &stmt) {
+  converter.checkCoarrayEnabled();
+  mlir::Location loc = converter.getCurrentLocation();
+  fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+  Fortran::lower::StatementContext stmtCtx;
+
+  // Handle STAT and ERRMSG values
+  const std::list<Fortran::parser::StatOrErrmsg> &statOrErrList =
+      std::get<std::list<Fortran::parser::StatOrErrmsg>>(stmt.t);
+  auto [statAddr, errMsgAddr] = converter.genStatAndErrmsg(loc, statOrErrList);
+
+  // Handle EVENT-VAR and IMAGE_NUMBER
+  auto eventExpr = Fortran::semantics::GetExpr(
+      std::get<Fortran::parser::EventVariable>(stmt.t));
+  mlir::Value eventAddr =
+      fir::getBase(converter.genExprBox(loc, *eventExpr, stmtCtx));
+  llvm::SmallVector<mlir::Value> cosubscripts;
+  if (auto coref{evaluate::ExtractCoarrayRef(eventExpr)}) {
+    cosubscripts =
+        Fortran::lower::getCosubscripts(converter, loc, coref.value());
+  }
+
+  mif::EventPostOp::create(builder, loc, eventAddr, cosubscripts, statAddr,
+                           errMsgAddr);
+}
+
+void Fortran::lower::genEventWaitStatement(
+    Fortran::lower::AbstractConverter &converter,
+    const Fortran::parser::EventWaitStmt &stmt) {
+  converter.checkCoarrayEnabled();
+  fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+  mlir::Location loc = converter.getCurrentLocation();
+  Fortran::lower::StatementContext stmtCtx;
+
+  // Handle STAT ,ERRMSG and UNTIL_COUNT
+  mlir::Value statAddr, errMsgAddr, untilCount;
+  const auto &eventSpecList =
+      std::get<std::list<Fortran::parser::EventWaitSpec>>(stmt.t);
+  for (const Fortran::parser::EventWaitSpec &eventSpec : eventSpecList) {
+    std::visit(
+        Fortran::common::visitors{
+            [&](const Fortran::parser::StatOrErrmsg &statOrErr) {
+              std::visit(
+                  Fortran::common::visitors{
+                      [&](const Fortran::parser::StatVariable &statVar) {
+                        statAddr = fir::getBase(converter.genExprAddr(
+                            loc, Fortran::semantics::GetExpr(statVar),
+                            stmtCtx));
+                      },
+                      [&](const Fortran::parser::MsgVariable &errMsgVar) {
+                        errMsgAddr = fir::getBase(converter.genExprAddr(
+                            loc, Fortran::semantics::GetExpr(errMsgVar),
+                            stmtCtx));
+                      },
+                  },
+                  statOrErr.u);
+            },
+            [&](const Fortran::parser::ScalarIntExpr &untilCountVar) {
+              untilCount = fir::getBase(converter.genExprValue(
+                  loc, Fortran::semantics::GetExpr(untilCountVar), stmtCtx));
+            },
+        },
+        eventSpec.u);
+  }
+
+  // Handle EVENT-VAR
+  mlir::Value eventVarAddr = fir::getBase(converter.genExprAddr(
+      loc,
+      Fortran::semantics::GetExpr(
+          std::get<Fortran::parser::EventVariable>(stmt.t)),
+      stmtCtx));
+
+  mif::EventWaitOp::create(builder, loc, eventVarAddr, untilCount, statAddr,
+                           errMsgAddr);
+}
diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp
index ebbb9e3f74f032..09475a881844ef 100644
--- a/flang/lib/Lower/Runtime.cpp
+++ b/flang/lib/Lower/Runtime.cpp
@@ -136,24 +136,6 @@ void Fortran::lower::genFailImageStatement(
   genUnreachable(builder, loc);
 }
 
-void Fortran::lower::genNotifyWaitStatement(
-    Fortran::lower::AbstractConverter &converter,
-    const Fortran::parser::NotifyWaitStmt &) {
-  TODO(converter.getCurrentLocation(), "coarray: NOTIFY WAIT runtime");
-}
-
-void Fortran::lower::genEventPostStatement(
-    Fortran::lower::AbstractConverter &converter,
-    const Fortran::parser::EventPostStmt &) {
-  TODO(converter.getCurrentLocation(), "coarray: EVENT POST runtime");
-}
-
-void Fortran::lower::genEventWaitStatement(
-    Fortran::lower::AbstractConverter &converter,
-    const Fortran::parser::EventWaitStmt &) {
-  TODO(converter.getCurrentLocation(), "coarray: EVENT WAIT runtime");
-}
-
 void Fortran::lower::genLockStatement(
     Fortran::lower::AbstractConverter &converter,
     const Fortran::parser::LockStmt &) {
diff --git a/flang/lib/Optimizer/Builder/MIFCommon.cpp b/flang/lib/Optimizer/Builder/MIFCommon.cpp
index 84da0ab2f275f3..913dba4960276d 100644
--- a/flang/lib/Optimizer/Builder/MIFCommon.cpp
+++ b/flang/lib/Optimizer/Builder/MIFCommon.cpp
@@ -31,6 +31,10 @@ std::string mif::getFullUniqName(mlir::Value addr) {
     return getFullUniqName(rb.getBox());
   else if (auto eb = mlir::dyn_cast<fir::EmboxOp>(op))
     return getFullUniqName(eb.getMemref());
+  else if (auto ac = mlir::dyn_cast<fir::ArrayCoorOp>(op))
+    return getFullUniqName(ac.getMemref());
+  else if (auto c = mlir::dyn_cast<fir::CoordinateOp>(op))
+    return getFullUniqName(c.getRef());
   else if (auto ebc = mlir::dyn_cast<fir::EmboxCharOp>(op))
     return getFullUniqName(ebc.getMemref());
   else if (auto c = mlir::dyn_cast<fir::CoordinateOp>(op)) {
diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
index 1a392c0b16a9ab..f6cbb3f7c372cb 100644
--- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
@@ -128,6 +128,8 @@ std::int64_t getCorank(mlir::Value coarray) {
 
 static int computeElementByteSize(mlir::Location loc, mlir::Type type,
                                   fir::KindMapping &kindMap,
+                                  mlir::DataLayout *dl,
+                                  const fir::LLVMTypeConverter *typeConverter,
                                   bool emitErrorOnFailure = true) {
   auto eleTy = fir::unwrapSequenceType(type);
   if (auto t{mlir::dyn_cast<mlir::IntegerType>(eleTy)})
@@ -143,6 +145,10 @@ static int computeElementByteSize(mlir::Location loc, mlir::Type type,
   }
   if (auto t{mlir::dyn_cast<fir::CharacterType>(eleTy)})
     return kindMap.getCharacterBitsize(t.getFKind()) / 8;
+  if (fir::isa_derived(eleTy)) {
+    mlir::Type structTy = typeConverter->convertType(eleTy);
+    return dl->getTypeSizeInBits(structTy) / 8;
+  }
   if (emitErrorOnFailure)
     mlir::emitError(loc, "unsupported type");
   return 0;
@@ -163,7 +169,8 @@ static mlir::Value getSizeInBytes(fir::FirOpBuilder &builder,
   mlir::Value bytes;
   if (!mlir::dyn_cast_or_null<fir::BaseBoxType>(baseTy)) {
     if (fir::isa_trivial(baseTy)) {
-      int width = computeElementByteSize(loc, baseTy, kindMap);
+      int width =
+          computeElementByteSize(loc, baseTy, kindMap, dl, typeConverter);
       bytes = builder.createIntegerConstant(loc, builder.getI64Type(), width);
     } else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(baseTy)) {
       std::size_t size = 0;
@@ -171,7 +178,8 @@ static mlir::Value getSizeInBytes(fir::FirOpBuilder &builder,
         mlir::Type structTy = typeConverter->convertType(seqTy.getEleTy());
         size = dl->getTypeSizeInBits(structTy) / 8;
       } else {
-        size = computeElementByteSize(loc, seqTy.getEleTy(), kindMap);
+        size = computeElementByteSize(loc, seqTy.getEleTy(), kindMap, dl,
+                                      typeConverter);
       }
       mlir::Value width =
           builder.createIntegerConstant(loc, builder.getI64Type(), size);
@@ -213,6 +221,86 @@ static mlir::Value getSizeInBytes(fir::FirOpBuilder &builder,
   return sizeInBytes;
 }
 
+/// Compute an offset in bytes from the beginning of the elements provided in
+/// "val". Basically, if it is not a memory access operation for an array such
+/// as fir::ArrayCoorOp or fir::CoordinateOp, then the element's offset is zero.
+static mlir::Value
+computeOffsetInBytes(fir::FirOpBuilder &builder, mlir::Location loc,
+                     mlir::ModuleOp module, mlir::DataLayout *dl,
+                     const fir::LLVMTypeConverter *typeConverter,
+                     mlir::Value val) {
+  fir::KindMapping kindMap{fir::getKindMapping(module)};
+  auto i64Ty = builder.getI64Type();
+  auto idxTy = builder.getIndexType();
+  auto zero = [&]() { return builder.createIntegerConstant(loc, i64Ty, 0); };
+  auto one = [&]() { return builder.createIntegerConstant(loc, i64Ty, 1); };
+
+  if (auto convert = val.getDefiningOp<fir::ConvertOp>())
+    return computeOffsetInBytes(builder, loc, module, dl, typeConverter,
+                                convert.getValue());
+
+  if (auto coor = val.getDefiningOp<fir::ArrayCoorOp>()) {
+    mlir::Value base = computeOffsetInBytes(builder, loc, module, dl,
+                                            typeConverter, coor.getMemref());
+    mlir::Type eleTy = fir::unwrapSequenceType(
+        fir::unwrapPassByRefType(coor.getMemref().getType()));
+    mlir::Value offset = zero();
+
+    llvm::SmallVector<mlir::Value> extents;
+    llvm::SmallVector<mlir::Value> origins;
+    if (mlir::Value shape = coor.getShape()) {
+      if (auto shapeOp = shape.getDefiningOp<fir::ShapeOp>()) {
+        extents.append(shapeOp.getExtents().begin(),
+                       shapeOp.getExtents().end());
+      } else if (auto shapeShiftOp = shape.getDefiningOp<fir::ShapeShiftOp>()) {
+        auto pairs = shapeShiftOp.getPairs();
+        for (size_t i = 0; i < pairs.size(); i += 2) {
+          origins.push_back(pairs[i]);
+          extents.push_back(pairs[i + 1]);
+        }
+      } else if (auto shiftOp = shape.getDefiningOp<fir::ShiftOp>())
+        origins.assign(shiftOp.getOrigins().begin(),
+                       shiftOp.getOrigins().end());
+    }
+
+    mlir::Value currentStride = builder.createIntegerConstant(
+        loc, i64Ty,
+        computeElementByteSize(loc, eleTy, kindMap, dl, typeConverter));
+
+    auto indices = coor.getIndices();
+    for (auto [dim, idx] : llvm::enumerate(indices)) {
+      mlir::Value lb, stride;
+      if (dim < origins.size())
+        lb = builder.createConvert(loc, i64Ty, origins[dim]);
+      else
+        lb = one();
+
+      idx = builder.createConvert(loc, i64Ty, idx);
+      idx = mlir::arith::SubIOp::create(builder, loc, idx, lb);
+      if (mlir::isa<fir::BaseBoxType>(
+              fir::unwrapRefType(coor.getMemref().getType()))) {
+        auto dims = fir::BoxDimsOp::create(
+            builder, loc, idxTy, idxTy, idxTy, coor.getMemref(),
+            builder.createIntegerConstant(loc, idxTy, dim));
+        stride = builder.createConvert(loc, i64Ty, dims.getByteStride());
+      } else {
+        stride = currentStride;
+        if (dim < extents.size()) {
+          mlir::Value ext = builder.createConvert(loc, i64Ty, extents[dim]);
+          currentStride =
+              mlir::arith::MulIOp::create(builder, loc, currentStride, ext);
+        }
+      }
+
+      mlir::Value delta =
+          mlir::arith::MulIOp::create(builder, loc, idx, stride);
+      offset = mlir::arith::AddIOp::create(builder, loc, offset, delta);
+    }
+    return mlir::arith::AddIOp::create(builder, loc, base, offset);
+  }
+  return zero();
+}
+
 // Most PRIF functions take `errmsg` and `errmsg_alloc` as two optional
 // arguments of intent (out). One is allocatable, the other is not.
 // It is the responsibility of the compiler to ensure that the appropriate
@@ -1407,6 +1495,117 @@ struct MIFImageIndexOpConversion
   }
 };
 
+/// Convert mif.event_wait operation to runtime call of 'prif_event_wait*'
+struct MIFEventWaitOpConversion
+    : public mlir::OpRewritePattern<mif::EventWaitOp> {
+  using OpRewritePattern::OpRewritePattern;
+
+  mlir::LogicalResult
+  matchAndRewrite(mif::EventWaitOp 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 ptrTy = fir::PointerType::get(builder.getNoneType());
+    mlir::Type i64Ty = builder.getI64Type();
+    mlir::Type errmsgTy = getPRIFErrmsgType(builder);
+    mlir::FunctionType ftype =
+        mlir::FunctionType::get(builder.getContext(),
+                                /*inputs*/
+                                {ptrTy, builder.getRefType(i64Ty),
+                                 getPRIFStatType(builder), errmsgTy, errmsgTy},
+                                /*results*/ {});
+    mlir::func::FuncOp funcOp =
+        builder.createFunction(loc, getPRIFProcName("event_wait"), ftype);
+
+    mlir::Value untilCount = builder.createTemporary(loc, i64Ty);
+    if (!op.getUntilCount())
+      untilCount =
+          fir::AbsentOp::create(builder, loc, builder.getRefType(i64Ty));
+    else {
+      untilCount = builder.createTemporary(loc, i64Ty);
+      mlir::Value u = builder.createConvert(loc, i64Ty, op.getUntilCount());
+      fir::StoreOp::create(builder, loc, u, untilCount);
+    }
+
+    mlir::Value stat = op.getStat();
+    if (!stat)
+      stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder));
+    auto [errmsgArg, errmsgAllocArg] =
+        genErrmsgPRIF(builder, loc, op.getErrmsg());
+    llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+        builder, loc, ftype, op.getEvent(), untilCount, stat, errmsgArg,
+        errmsgAllocArg);
+    fir::CallOp callOp = fir::CallOp::create(builder, loc, funcOp, args);
+    rewriter.replaceOp(op, callOp);
+    return mlir::success();
+  }
+};
+
+/// Convert mif.event_post operation to runtime call of 'prif_event_post'
+struct MIFEventPostOpConversion
+    : public mlir::OpRewritePattern<mif::EventPostOp> {
+  using OpRewritePattern::OpRewritePattern;
+
+  MIFEventPostOpConversion(mlir::MLIRContext *context, mlir::DataLayout *dl,
+                           const fir::LLVMTypeConverter *typeConverter)
+      : OpRewritePattern(context), dl{dl}, typeConverter{typeConverter} {}
+
+  mlir::LogicalResult
+  matchAndRewrite(mif::EventPostOp 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 ptrTy = fir::PointerType::get(builder.getNoneType());
+    mlir::Type i32Ty = builder.getI32Type();
+    mlir::Type i64Ty = builder.getI64Type();
+    mlir::Type errmsgTy = getPRIFErrmsgType(builder);
+    mlir::FunctionType ftype = mlir::FunctionType::get(
+        builder.getContext(),
+        /*inputs*/
+        {builder.getRefType(i32Ty), ptrTy, builder.getRefType(i64Ty),
+         getPRIFStatType(builder), errmsgTy, errmsgTy},
+        /*results*/ {});
+    mlir::func::FuncOp funcOp =
+        builder.createFunction(loc, getPRIFProcName("event_post"), ftype);
+
+    mlir::Type eventType = fir::unwrapRefType(op.getEvent().getType());
+    bool isCoarray = false;
+    if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(eventType))
+      isCoarray = boxTy.isCoarray();
+    if (!isCoarray)
+      TODO(loc, "coarray: mif.event_post with event_var which is an "
+                "allocatable or pointer component of a coarray.");
+
+    mlir::Value offset = builder.createTemporary(loc, i64Ty);
+    mlir::Value zero = computeOffsetInBytes(builder, loc, mod, dl,
+                                            typeConverter, op.getEvent());
+    fir::StoreOp::create(builder, loc, zero, offset);
+
+    mlir::Value coarrayHandle = getCoarrayHandle(builder, loc, op.getEvent());
+    mlir::Value imageNum =
+        getInitialTeamIndex(builder, loc, coarrayHandle, op.getCosubscripts());
+    mlir::Value stat = op.getStat();
+    if (!stat)
+      stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder));
+    auto [errmsgArg, errmsgAllocArg] =
+        genErrmsgPRIF(builder, loc, op.getErrmsg());
+    llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+        builder, loc, ftype, imageNum, coarrayHandle, offset, stat, errmsgArg,
+        errmsgAllocArg);
+    fir::CallOp callOp = fir::CallOp::create(builder, loc, funcOp, args);
+    rewriter.replaceOp(op, callOp);
+    return mlir::success();
+  }
+
+private:
+  mlir::DataLayout *dl;
+  const fir::LLVMTypeConverter *typeConverter;
+};
+
 static void genCoarrayHandle(fir::FirOpBuilder &builder, mlir::ModuleOp mod,
                              fir::DeclareOp op) {
   builder.setInsertionPointAfter(op);
@@ -1480,17 +1679,17 @@ class MIFOpConversion : public fir::impl::MIFOpConversionBase<MIFOpConversion> {
 void mif::populateMIFOpConversionPatterns(
     const fir::LLVMTypeConverter &converter, mlir::DataLayout &dl,
     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.insert<MIFAllocCoarrayOpConversion, MIFEventPostOpConversion>(
+      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, MIFEventWaitOpConversion>(
       patterns.getContext());
 }
diff --git a/flang/test/Fir/MIF/events.mlir b/flang/test/Fir/MIF/events.mlir
new file mode 100644
index 00000000000000..0fa8cd91a19d2f
--- /dev/null
+++ b/flang/test/Fir/MIF/events.mlir
@@ -0,0 +1,45 @@
+// RUN: fir-opt --mif-convert %s | FileCheck %s
+
+func.func @_QQmain() attributes {fir.bindc_name = "EVENT_TEST"} {
+  %0 = fir.alloca !fir.array<0xi64>
+  %1 = fir.alloca !fir.array<1xi64>
+  %2 = fir.dummy_scope : !fir.dscope
+  %3 = fir.address_of(@_QFEdata_ready) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>
+  %c1_i64 = arith.constant 1 : i64
+  %c0 = arith.constant 0 : index
+  %4 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
+  fir.store %c1_i64 to %4 : !fir.ref<i64>
+  %5 = fir.embox %1 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
+  %6 = fir.embox %0 : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
+  mif.alloc_coarray %3 lcobounds %5 ucobounds %6 {uniq_name = "_QFEdata_ready"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
+  %7:2 = hlfir.declare %3 {uniq_name = "_QFEdata_ready"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>) -> (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>)
+  %8 = fir.alloca i32 {bindc_name = "me", uniq_name = "_QFEme"}
+  %9:2 = hlfir.declare %8 {uniq_name = "_QFEme"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %10 = mif.this_image : () -> i32
+  hlfir.assign %10 to %9#0 : i32, !fir.ref<i32>
+  %11 = fir.load %9#0 : !fir.ref<i32>
+  %c2_i32 = arith.constant 2 : i32
+  %12 = arith.cmpi eq, %11, %c2_i32 : i32
+  fir.if %12 {
+    %13 = hlfir.designate %7#0   : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>
+    %14 = fir.embox %13 : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>) -> !fir.box<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>, corank:1>
+    %c1_i64_0 = arith.constant 1 : i64
+    mif.event_post %14[%c1_i64_0] : (!fir.box<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>, corank:1>, i64) -> ()
+  } else {
+    %13 = fir.load %9#0 : !fir.ref<i32>
+    %c1_i32 = arith.constant 1 : i32
+    %14 = arith.cmpi eq, %13, %c1_i32 : i32
+    fir.if %14 {
+      %c1_i32_0 = arith.constant 1 : i32
+      mif.event_wait %7#0 until_count %c1_i32_0 : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, i32) -> ()
+    }
+  }
+  return
+}
+
+// CHECK: fir.call @_QMprifPprif_initial_team_index(
+// CHECK: fir.call @_QMprifPprif_event_post(%[[IMAGE_INDEX:.*]], %[[EVENT_PTR:.*]], %[[OFFSET:.*]], %[[STAT:.*]], %[[ERRMSG:.*]], %[[ERRMSG2:.*]]) : (!fir.ref<i32>, !fir.ptr<none>, !fir.ref<i64>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+
+// CHECK: fir.call @_QMprifPprif_event_wait(%[[EVENT_PTR:.*]], %[[UNTIL_COUNT:.*]], %[[STAT:.*]], %[[ERRMSG:.*]], %[[ERRMSG2:.*]]) : (!fir.ptr<none>, !fir.ref<i64>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
diff --git a/flang/test/Lower/MIF/events.f90 b/flang/test/Lower/MIF/events.f90
new file mode 100644
index 00000000000000..9ebf1130730aeb
--- /dev/null
+++ b/flang/test/Lower/MIF/events.f90
@@ -0,0 +1,56 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY
+! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY
+
+! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable.
+
+
+program event_test
+  use iso_fortran_env, only: event_type
+  implicit none
+  
+  type(event_type)  :: data_ready[*]
+  integer :: me
+
+  me = this_image()
+
+  if (me == 2) then
+     event post(data_ready[1])
+  else if (me == 1) then
+     event wait(data_ready, UNTIL_COUNT=1)
+  end if
+end program
+
+! COARRAY: %[[VAL_0:.*]] = fir.alloca !fir.array<0xi64>
+! COARRAY: %[[VAL_1:.*]] = fir.alloca !fir.array<1xi64>
+! COARRAY: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
+! COARRAY: %[[VAL_3:.*]] = fir.address_of(@_QFEdata_ready) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>
+! COARRAY: %c1_i64 = arith.constant 1 : i64
+! COARRAY: %c0 = arith.constant 0 : index
+! COARRAY: %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_1]], %c0 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
+! COARRAY: fir.store %c1_i64 to %[[VAL_4]] : !fir.ref<i64>
+! COARRAY: %[[VAL_5:.*]] = fir.embox %[[VAL_1]] : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
+! COARRAY: %[[VAL_6:.*]] = fir.embox %[[VAL_0]] : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
+! COARRAY: mif.alloc_coarray %[[VAL_3]] lcobounds %[[VAL_5]] ucobounds %[[VAL_6]] {uniq_name = "_QFEdata_ready"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
+! COARRAY: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_3]] {uniq_name = "_QFEdata_ready"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>) -> (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>)
+! COARRAY: %[[VAL_8:.*]] = fir.alloca i32 {bindc_name = "me", uniq_name = "_QFEme"}
+! COARRAY: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_8]] {uniq_name = "_QFEme"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! COARRAY: %[[VAL_10:.*]] = mif.this_image : () -> i32
+! COARRAY: hlfir.assign %[[VAL_10]] to %[[VAL_9]]#0 : i32, !fir.ref<i32>
+! COARRAY: %[[VAL_11:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref<i32>
+! COARRAY: %c2_i32 = arith.constant 2 : i32
+! COARRAY: %[[VAL_12:.*]] = arith.cmpi eq, %[[VAL_11]], %c2_i32 : i32
+! COARRAY: fir.if %[[VAL_12]] {
+! COARRAY:   %[[VAL_13:.*]] = hlfir.designate %[[VAL_7]]#0   : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>
+! COARRAY:   %[[VAL_14:.*]] = fir.embox %[[VAL_13]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>) -> !fir.box<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>, corank:1>
+! COARRAY:   %c1_i64_0 = arith.constant 1 : i64
+! COARRAY:   mif.event_post %[[VAL_14]][%c1_i64_0] : (!fir.box<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>, corank:1>, i64) -> ()
+! COARRAY: } else {
+! COARRAY:   %[[VAL_15:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref<i32>
+! COARRAY:   %c1_i32 = arith.constant 1 : i32
+! COARRAY:   %[[VAL_16:.*]] = arith.cmpi eq, %[[VAL_15]], %c1_i32 : i32
+! COARRAY:   fir.if %[[VAL_16]] {
+! COARRAY:     %c1_i32_0 = arith.constant 1 : i32
+! COARRAY:     mif.event_wait %[[VAL_7]]#0 until_count %c1_i32_0 : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, i32) -> ()
+! COARRAY:   }
+! COARRAY: }
+! COARRAY: return

>From cadc05c4e0e000d5c2596e8ec06776f6d6321a75 Mon Sep 17 00:00:00 2001
From: Jean-Didier PAILLEUX <jean-di.pailleux at outlook.com>
Date: Wed, 29 Jul 2026 15:44:33 +0200
Subject: [PATCH 2/7] Update flang/lib/Optimizer/Transforms/MIFOpConversion.cpp

Co-authored-by: Dan Bonachea <dobonachea at lbl.gov>
---
 flang/lib/Optimizer/Transforms/MIFOpConversion.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
index f6cbb3f7c372cb..84976e3b7941f3 100644
--- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
@@ -1581,9 +1581,9 @@ struct MIFEventPostOpConversion
                 "allocatable or pointer component of a coarray.");
 
     mlir::Value offset = builder.createTemporary(loc, i64Ty);
-    mlir::Value zero = computeOffsetInBytes(builder, loc, mod, dl,
+    mlir::Value offset_val = computeOffsetInBytes(builder, loc, mod, dl,
                                             typeConverter, op.getEvent());
-    fir::StoreOp::create(builder, loc, zero, offset);
+    fir::StoreOp::create(builder, loc, offset_val, offset);
 
     mlir::Value coarrayHandle = getCoarrayHandle(builder, loc, op.getEvent());
     mlir::Value imageNum =

>From 0d502a07f1e538f0419048e800bbc4ac3b1d3739 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Fri, 14 Aug 2026 14:48:33 +0200
Subject: [PATCH 3/7] [flang][MIF] fix getInitialImageIndex function

---
 .../Optimizer/Transforms/MIFOpConversion.cpp  | 82 +++++++++++--------
 1 file changed, 46 insertions(+), 36 deletions(-)

diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
index 84976e3b7941f3..5c786ef2cf2ade 100644
--- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
@@ -434,6 +434,35 @@ mlir::Value genTerminationOperationWrapper(fir::FirOpBuilder &builder,
   return fir::AddrOfOp::create(builder, loc, funcType, symbolRef);
 }
 
+mlir::Value getTeam(fir::FirOpBuilder &builder, mlir::Location loc,
+                    mlir::Type resultType, mlir::Value level) {
+  mlir::Type refTy = builder.getRefType(builder.getNoneType());
+  mlir::Type lvlTy = builder.getRefType(builder.getI32Type());
+  mlir::FunctionType ftype = mlir::FunctionType::get(builder.getContext(),
+                                                     /*inputs*/ {lvlTy, refTy},
+                                                     /*results*/ {});
+  mlir::func::FuncOp funcOp =
+      builder.createFunction(loc, getPRIFProcName("get_team"), ftype);
+
+  if (!level)
+    level = fir::AbsentOp::create(builder, loc, lvlTy);
+  else {
+    mlir::Value cst = level;
+    mlir::Type i32Ty = builder.getI32Type();
+    level = builder.createTemporary(loc, i32Ty);
+    if (cst.getType() != i32Ty)
+      cst = builder.createConvert(loc, i32Ty, cst);
+    fir::StoreOp::create(builder, loc, cst, level);
+  }
+  mlir::Type baseTy = fir::unwrapRefType(resultType);
+  mlir::Value team = builder.createTemporary(loc, baseTy);
+
+  llvm::SmallVector<mlir::Value> args =
+      fir::runtime::createArguments(builder, loc, ftype, level, team);
+  fir::CallOp::create(builder, loc, funcOp, args);
+  return team;
+}
+
 // Generates the image index relative to the initial team, regardless of which
 // team is selected. Generates a call to the `prif_initial_team_index` function
 // (analogous to `prif_image_index`) if `cosubcripts` contains at least one
@@ -442,29 +471,36 @@ mlir::Value genTerminationOperationWrapper(fir::FirOpBuilder &builder,
 getInitialTeamIndex(fir::FirOpBuilder &builder, mlir::Location loc,
                     mlir::Value coarrayHandle,
                     llvm::SmallVector<mlir::Value> cosubscripts) {
-  mlir::Type boxTy = fir::BoxType::get(builder.getNoneType());
+  mlir::Type refTy = builder.getRefType(builder.getNoneType());
   mlir::Type i32Ty = builder.getI32Type();
   mlir::Type i64Ty = builder.getI64Type();
   mlir::Type boxArrTy = genBoxedSequenceType(i64Ty);
-  mlir::Value index = builder.createTemporary(loc, i32Ty);
 
   // If there are no subscripts, the current image index is used.
   if (cosubscripts.size() == 0) {
-    mlir::Value res = builder.createTemporary(loc, i32Ty);
     // In iso_fortran_env.f90, INITIAL_TEAM is -2
     mlir::Value initialTeam =
         builder.createIntegerConstant(loc, builder.getI32Type(), -2);
-    mlir::Value team = mif::GetTeamOp::create(
+    mlir::Value team = getTeam(
         builder, loc, builder.getRefType(builder.getNoneType()), initialTeam);
-    mlir::Value thisImage = mif::ThisImageOp::create(builder, loc, team);
-    fir::StoreOp::create(builder, loc, thisImage, res);
-    return res;
+    mlir::Value thisImage = builder.createTemporary(loc, i32Ty);
+    mlir::FunctionType ftype = mlir::FunctionType::get(
+        builder.getContext(),
+        /*inputs*/ {refTy, builder.getRefType(i32Ty)}, /*results*/ {});
+    mlir::func::FuncOp funcOp = builder.createFunction(
+        loc, getPRIFProcName("this_image_no_coarray"), ftype);
+
+    llvm::SmallVector<mlir::Value> args =
+        fir::runtime::createArguments(builder, loc, ftype, team, thisImage);
+    fir::CallOp::create(builder, loc, funcOp, args);
+    return thisImage;
   }
 
+  mlir::Value index = builder.createTemporary(loc, i32Ty);
   mlir::FunctionType ftype = mlir::FunctionType::get(
       builder.getContext(),
       /*inputs*/
-      {boxTy, boxArrTy, builder.getRefType(i32Ty), builder.getRefType(i32Ty)},
+      {refTy, boxArrTy, builder.getRefType(i32Ty), builder.getRefType(i32Ty)},
       /*results*/ {});
   mlir::func::FuncOp funcOp =
       builder.createFunction(loc, getPRIFProcName("initial_team_index"), ftype);
@@ -1149,34 +1185,8 @@ struct MIFGetTeamOpConversion : public mlir::OpRewritePattern<mif::GetTeamOp> {
     fir::FirOpBuilder builder(rewriter, mod);
     mlir::Location loc = op.getLoc();
 
-    mlir::Type refTy = builder.getRefType(builder.getNoneType());
-    mlir::Type lvlTy = builder.getRefType(builder.getI32Type());
-    mlir::FunctionType ftype =
-        mlir::FunctionType::get(builder.getContext(),
-                                /*inputs*/ {lvlTy, refTy},
-                                /*results*/ {});
-    mlir::func::FuncOp funcOp =
-        builder.createFunction(loc, getPRIFProcName("get_team"), ftype);
-
-    mlir::Value level = op.getLevel();
-    if (!level)
-      level = fir::AbsentOp::create(builder, loc, lvlTy);
-    else {
-      mlir::Value cst = op.getLevel();
-      mlir::Type i32Ty = builder.getI32Type();
-      level = builder.createTemporary(loc, i32Ty);
-      if (cst.getType() != i32Ty)
-        cst = builder.createConvert(loc, i32Ty, cst);
-      fir::StoreOp::create(builder, loc, cst, level);
-    }
-    mlir::Type resultType = op.getResult().getType();
-    mlir::Type baseTy = fir::unwrapRefType(resultType);
-    mlir::Value team = builder.createTemporary(loc, baseTy);
-
-    llvm::SmallVector<mlir::Value> args =
-        fir::runtime::createArguments(builder, loc, ftype, level, team);
-    fir::CallOp::create(builder, loc, funcOp, args);
-
+    mlir::Value team =
+        getTeam(builder, loc, op.getResult().getType(), op.getLevel());
     rewriter.replaceOp(op, team);
     return mlir::success();
   }

>From dd115473ec787145029dc50a367fe966befb036d Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Mon, 17 Aug 2026 15:52:43 +0200
Subject: [PATCH 4/7] Applying some fix with EventWait and EventPost + Fix
 offset computation

---
 .../flang/Optimizer/Dialect/MIF/MIFOps.td     |   6 +-
 flang/lib/Lower/Bridge.cpp                    |   6 -
 flang/lib/Lower/ConvertExprToHLFIR.cpp        |   4 +-
 flang/lib/Lower/MultiImageFortran.cpp         |  15 ++-
 .../Optimizer/Transforms/MIFOpConversion.cpp  | 117 ++++++++++++------
 flang/test/Fir/MIF/events.mlir                |   3 +-
 6 files changed, 95 insertions(+), 56 deletions(-)

diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
index df158290b5b15e..d52856b5c75e99 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -602,8 +602,8 @@ def mif_EventPostOp : mif_Op<"event_post", [AttrSizedOperandSegments,
   let description = [{
     This is a post-event operation.
     Arguments: 
-      - `image_num`: Shall be an integer that correspond to the image index of 
-        the event variable.
+      - `cosubscripts`: Shall be a list of integer cosubscripts to determine the 
+        image_num to be communicated.
       - `event_var`: Shall be a coarray or be part of a coarray of 
         type EVENT_TYPE from the intrinsic module ISO_FORTRAN_ENV.
   }];
@@ -631,7 +631,7 @@ def mif_EventWaitOp : mif_Op<"event_wait", [AttrSizedOperandSegments,
         the given event variable to be waited for.
   }];
 
-  let arguments = (ins fir_ReferenceType:$event,
+  let arguments = (ins AnyRefOrBoxType:$event,
       Optional<AnyIntegerType>:$until_count,
       Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
       Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 784a87cc619979..ca373bef590bcd 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -839,9 +839,6 @@ class FirConverter : public Fortran::lower::AbstractConverter {
               Fortran::lower::StatementContext &context,
               mlir::Location *locPtr = nullptr) override final {
     mlir::Location loc = locPtr ? *locPtr : toLocation();
-    auto coarrayRef = Fortran::evaluate::ExtractCoarrayRef(expr);
-    if (coarrayRef.has_value())
-      TODO(loc, "coarray: genExprAddr of coarray reference.");
     return Fortran::lower::convertExprToAddress(loc, *this, expr, localSymbols,
                                                 context);
   }
@@ -861,9 +858,6 @@ class FirConverter : public Fortran::lower::AbstractConverter {
   fir::ExtendedValue
   genExprBox(mlir::Location loc, const Fortran::lower::SomeExpr &expr,
              Fortran::lower::StatementContext &stmtCtx) override final {
-    auto coarrayRef = Fortran::evaluate::ExtractCoarrayRef(expr);
-    if (coarrayRef.has_value())
-      TODO(loc, "coarray: genExprBox of coarray reference.");
     return Fortran::lower::convertExprToBox(loc, *this, expr, localSymbols,
                                             stmtCtx);
   }
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index 9c239ae01670aa..e74ca985afe6e6 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -2367,8 +2367,8 @@ fir::ExtendedValue Fortran::lower::convertExprToBox(
   hlfir::EntityWithAttributes loweredExpr =
       HlfirBuilder(loc, converter, symMap, stmtCtx).gen(expr);
   unsigned corank = 0;
-  if (auto coarray{evaluate::ExtractCoarrayRef(expr)})
-    corank = coarray->GetLastSymbol().Corank();
+  if (auto ref{evaluate::ExtractDataRef(expr)})
+    corank = ref->GetLastSymbol().Corank();
   return convertToBox(loc, converter, loweredExpr, stmtCtx,
                       converter.genType(expr), corank);
 }
diff --git a/flang/lib/Lower/MultiImageFortran.cpp b/flang/lib/Lower/MultiImageFortran.cpp
index ea2d00c7252cba..8607660820602d 100644
--- a/flang/lib/Lower/MultiImageFortran.cpp
+++ b/flang/lib/Lower/MultiImageFortran.cpp
@@ -547,7 +547,7 @@ void Fortran::lower::genEventPostStatement(
   // Handle EVENT-VAR and IMAGE_NUMBER
   auto eventExpr = Fortran::semantics::GetExpr(
       std::get<Fortran::parser::EventVariable>(stmt.t));
-  mlir::Value eventAddr =
+  mlir::Value event =
       fir::getBase(converter.genExprBox(loc, *eventExpr, stmtCtx));
   llvm::SmallVector<mlir::Value> cosubscripts;
   if (auto coref{evaluate::ExtractCoarrayRef(eventExpr)}) {
@@ -555,7 +555,7 @@ void Fortran::lower::genEventPostStatement(
         Fortran::lower::getCosubscripts(converter, loc, coref.value());
   }
 
-  mif::EventPostOp::create(builder, loc, eventAddr, cosubscripts, statAddr,
+  mif::EventPostOp::create(builder, loc, event, cosubscripts, statAddr,
                            errMsgAddr);
 }
 
@@ -599,12 +599,11 @@ void Fortran::lower::genEventWaitStatement(
   }
 
   // Handle EVENT-VAR
-  mlir::Value eventVarAddr = fir::getBase(converter.genExprAddr(
-      loc,
-      Fortran::semantics::GetExpr(
-          std::get<Fortran::parser::EventVariable>(stmt.t)),
-      stmtCtx));
+  auto eventExpr = Fortran::semantics::GetExpr(
+      std::get<Fortran::parser::EventVariable>(stmt.t));
+  mlir::Value eventVar =
+      fir::getBase(converter.genExprAddr(loc, *eventExpr, stmtCtx));
 
-  mif::EventWaitOp::create(builder, loc, eventVarAddr, untilCount, statAddr,
+  mif::EventWaitOp::create(builder, loc, eventVar, untilCount, statAddr,
                            errMsgAddr);
 }
diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
index 5c786ef2cf2ade..12b58f15d58d03 100644
--- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
@@ -154,6 +154,28 @@ static int computeElementByteSize(mlir::Location loc, mlir::Type type,
   return 0;
 }
 
+static mlir::Value getLocalDataPointer(fir::FirOpBuilder &builder,
+                                       mlir::Location loc,
+                                       mlir::Value coarrayHandle) {
+  mlir::Type ptrTy = fir::PointerType::get(builder.getNoneType());
+  mlir::Type refTy = builder.getRefType(builder.getNoneType());
+  mlir::FunctionType ftype = mlir::FunctionType::get(builder.getContext(),
+                                                     /*inputs*/ {refTy, ptrTy},
+                                                     /*results*/ {});
+  // BIND(C) procedure
+  mlir::func::FuncOp funcOp =
+      builder.createFunction(loc, "_QMprifPprif_local_data_pointer", ftype);
+
+  mlir::Value localPtr = builder.createTemporary(loc, ptrTy);
+  mlir::Value nullPtr = fir::ZeroOp::create(builder, loc, ptrTy);
+  fir::StoreOp::create(builder, loc, nullPtr, localPtr);
+
+  llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+      builder, loc, ftype, coarrayHandle, localPtr);
+  fir::CallOp::create(builder, loc, funcOp, args);
+  return fir::LoadOp::create(builder, loc, localPtr);
+}
+
 // Function used to compute the size in bytes of an entity. This function
 // is used during an allocation of a coarray (or a component of a coarray),
 // as it's a required argument in some PRIF procedures.
@@ -235,9 +257,16 @@ computeOffsetInBytes(fir::FirOpBuilder &builder, mlir::Location loc,
   auto zero = [&]() { return builder.createIntegerConstant(loc, i64Ty, 0); };
   auto one = [&]() { return builder.createIntegerConstant(loc, i64Ty, 1); };
 
-  if (auto convert = val.getDefiningOp<fir::ConvertOp>())
-    return computeOffsetInBytes(builder, loc, module, dl, typeConverter,
-                                convert.getValue());
+  mlir::Operation *defOp = val.getDefiningOp();
+  if (mlir::isa<fir::ConvertOp, fir::EmboxOp>(defOp)) {
+    llvm::TypeSwitch<mlir::Operation *>(defOp)
+        .Case<fir::ConvertOp>(
+            [&](fir::ConvertOp convertOp) { val = convertOp.getValue(); })
+        .Case<fir::EmboxOp>(
+            [&](fir::EmboxOp emboxOp) { val = emboxOp.getMemref(); })
+        .Default([](mlir::Operation *op) {});
+    return computeOffsetInBytes(builder, loc, module, dl, typeConverter, val);
+  }
 
   if (auto coor = val.getDefiningOp<fir::ArrayCoorOp>()) {
     mlir::Value base = computeOffsetInBytes(builder, loc, module, dl,
@@ -467,7 +496,7 @@ mlir::Value getTeam(fir::FirOpBuilder &builder, mlir::Location loc,
 // team is selected. Generates a call to the `prif_initial_team_index` function
 // (analogous to `prif_image_index`) if `cosubcripts` contains at least one
 // value; otherwise, it takes `this_image` from the initial team.
-[[maybe_unused]] static mlir::Value
+static mlir::Value
 getInitialTeamIndex(fir::FirOpBuilder &builder, mlir::Location loc,
                     mlir::Value coarrayHandle,
                     llvm::SmallVector<mlir::Value> cosubscripts) {
@@ -1529,7 +1558,7 @@ struct MIFEventWaitOpConversion
     mlir::func::FuncOp funcOp =
         builder.createFunction(loc, getPRIFProcName("event_wait"), ftype);
 
-    mlir::Value untilCount = builder.createTemporary(loc, i64Ty);
+    mlir::Value untilCount;
     if (!op.getUntilCount())
       untilCount =
           fir::AbsentOp::create(builder, loc, builder.getRefType(i64Ty));
@@ -1544,9 +1573,20 @@ struct MIFEventWaitOpConversion
       stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder));
     auto [errmsgArg, errmsgAllocArg] =
         genErrmsgPRIF(builder, loc, op.getErrmsg());
-    llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
-        builder, loc, ftype, op.getEvent(), untilCount, stat, errmsgArg,
-        errmsgAllocArg);
+
+    mlir::Value eventPtr = op.getEvent();
+    mlir::Type eventType = fir::unwrapRefType(op.getEvent().getType());
+    if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(eventType)) {
+      if (boxTy.isCoarray()) {
+        mlir::Value coarrayHandle = getCoarrayHandle(builder, loc, eventPtr);
+        eventPtr = getLocalDataPointer(builder, loc, coarrayHandle);
+      } else
+        eventPtr = fir::BoxAddrOp::create(builder, loc, ptrTy, eventPtr);
+    }
+
+    llvm::SmallVector<mlir::Value> args =
+        fir::runtime::createArguments(builder, loc, ftype, eventPtr, untilCount,
+                                      stat, errmsgArg, errmsgAllocArg);
     fir::CallOp callOp = fir::CallOp::create(builder, loc, funcOp, args);
     rewriter.replaceOp(op, callOp);
     return mlir::success();
@@ -1569,43 +1609,50 @@ struct MIFEventPostOpConversion
     fir::FirOpBuilder builder(rewriter, mod);
     mlir::Location loc = op.getLoc();
 
-    mlir::Type ptrTy = fir::PointerType::get(builder.getNoneType());
+    mlir::Type ptrTy = builder.getRefType(builder.getNoneType());
     mlir::Type i32Ty = builder.getI32Type();
     mlir::Type i64Ty = builder.getI64Type();
     mlir::Type errmsgTy = getPRIFErrmsgType(builder);
-    mlir::FunctionType ftype = mlir::FunctionType::get(
-        builder.getContext(),
-        /*inputs*/
-        {builder.getRefType(i32Ty), ptrTy, builder.getRefType(i64Ty),
-         getPRIFStatType(builder), errmsgTy, errmsgTy},
-        /*results*/ {});
-    mlir::func::FuncOp funcOp =
-        builder.createFunction(loc, getPRIFProcName("event_post"), ftype);
-
+    mlir::Type statTy = getPRIFStatType(builder);
     mlir::Type eventType = fir::unwrapRefType(op.getEvent().getType());
-    bool isCoarray = false;
-    if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(eventType))
-      isCoarray = boxTy.isCoarray();
-    if (!isCoarray)
-      TODO(loc, "coarray: mif.event_post with event_var which is an "
-                "allocatable or pointer component of a coarray.");
-
-    mlir::Value offset = builder.createTemporary(loc, i64Ty);
-    mlir::Value offset_val = computeOffsetInBytes(builder, loc, mod, dl,
-                                            typeConverter, op.getEvent());
-    fir::StoreOp::create(builder, loc, offset_val, offset);
+    mlir::FunctionType ftype;
+    mlir::func::FuncOp funcOp;
+    llvm::SmallVector<mlir::Value> args;
 
-    mlir::Value coarrayHandle = getCoarrayHandle(builder, loc, op.getEvent());
-    mlir::Value imageNum =
-        getInitialTeamIndex(builder, loc, coarrayHandle, op.getCosubscripts());
     mlir::Value stat = op.getStat();
     if (!stat)
       stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder));
     auto [errmsgArg, errmsgAllocArg] =
         genErrmsgPRIF(builder, loc, op.getErrmsg());
-    llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
-        builder, loc, ftype, imageNum, coarrayHandle, offset, stat, errmsgArg,
-        errmsgAllocArg);
+
+    bool isCoarray = false;
+    if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(eventType))
+      isCoarray = boxTy.isCoarray();
+
+    if (isCoarray) {
+      ftype = mlir::FunctionType::get(builder.getContext(),
+                                      /*inputs*/
+                                      {builder.getRefType(i32Ty), ptrTy,
+                                       builder.getRefType(i64Ty), statTy,
+                                       errmsgTy, errmsgTy},
+                                      /*results*/ {});
+      funcOp =
+          builder.createFunction(loc, getPRIFProcName("event_post"), ftype);
+
+      mlir::Value offset = builder.createTemporary(loc, i64Ty);
+      mlir::Value offset_val = computeOffsetInBytes(
+          builder, loc, mod, dl, typeConverter, op.getEvent());
+      fir::StoreOp::create(builder, loc, offset_val, offset);
+      mlir::Value coarrayHandle = getCoarrayHandle(builder, loc, op.getEvent());
+      mlir::Value imageNum = getInitialTeamIndex(builder, loc, coarrayHandle,
+                                                 op.getCosubscripts());
+      args = fir::runtime::createArguments(builder, loc, ftype, imageNum,
+                                           coarrayHandle, offset, stat,
+                                           errmsgArg, errmsgAllocArg);
+    } else
+      TODO(loc, "coarray: mif.event_post with event_var which is an "
+                "allocatable or pointer component of a coarray.");
+
     fir::CallOp callOp = fir::CallOp::create(builder, loc, funcOp, args);
     rewriter.replaceOp(op, callOp);
     return mlir::success();
diff --git a/flang/test/Fir/MIF/events.mlir b/flang/test/Fir/MIF/events.mlir
index 0fa8cd91a19d2f..91132a8b0a2934 100644
--- a/flang/test/Fir/MIF/events.mlir
+++ b/flang/test/Fir/MIF/events.mlir
@@ -38,8 +38,7 @@ func.func @_QQmain() attributes {fir.bindc_name = "EVENT_TEST"} {
 }
 
 // CHECK: fir.call @_QMprifPprif_initial_team_index(
-// CHECK: fir.call @_QMprifPprif_event_post(%[[IMAGE_INDEX:.*]], %[[EVENT_PTR:.*]], %[[OFFSET:.*]], %[[STAT:.*]], %[[ERRMSG:.*]], %[[ERRMSG2:.*]]) : (!fir.ref<i32>, !fir.ptr<none>, !fir.ref<i64>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+// CHECK: fir.call @_QMprifPprif_event_post(%[[IMAGE_INDEX:.*]], %[[EVENT_PTR:.*]], %[[OFFSET:.*]], %[[STAT:.*]], %[[ERRMSG:.*]], %[[ERRMSG2:.*]]) : (!fir.ref<i32>, !fir.ref<none>, !fir.ref<i64>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
 
 
 // CHECK: fir.call @_QMprifPprif_event_wait(%[[EVENT_PTR:.*]], %[[UNTIL_COUNT:.*]], %[[STAT:.*]], %[[ERRMSG:.*]], %[[ERRMSG2:.*]]) : (!fir.ptr<none>, !fir.ref<i64>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-

>From c496190a293afd477442e104cbb5ba439efefe63 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Tue, 28 Jul 2026 09:03:11 +0200
Subject: [PATCH 5/7] [flang][MIF] Update allocation for coarrays

---
 flang/lib/Lower/ConvertType.cpp               |  3 +-
 flang/lib/Lower/ConvertVariable.cpp           | 52 +++++++++++++++++++
 .../Integration/MIF/coarray_allocation4.f90   | 30 +++++------
 .../Integration/MIF/coarray_allocation5.f90   |  4 +-
 flang/test/Lower/MIF/coarray_allocation.f90   | 12 ++---
 flang/test/Lower/MIF/coshape.f90              |  6 +--
 flang/test/Lower/MIF/image_index.f90          |  8 +--
 flang/test/Lower/MIF/this_image.f90           |  4 +-
 8 files changed, 86 insertions(+), 33 deletions(-)

diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp
index 0fdbdfcc744243..fdde2683e980d5 100644
--- a/flang/lib/Lower/ConvertType.cpp
+++ b/flang/lib/Lower/ConvertType.cpp
@@ -297,7 +297,8 @@ struct TypeBuilderImpl {
     if (Fortran::semantics::IsPointer(symbol))
       return fir::wrapInClassOrBoxType(fir::PointerType::get(ty), isPolymorphic,
                                        isAssumedType, symbol.Corank());
-    if (Fortran::semantics::IsAllocatable(symbol))
+    if (Fortran::semantics::IsAllocatable(symbol) ||
+        Fortran::evaluate::IsCoarray(symbol))
       return fir::wrapInClassOrBoxType(fir::HeapType::get(ty), isPolymorphic,
                                        isAssumedType, symbol.Corank());
     // isPtr and isAlloc are variable that were promoted to be on the
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index d763c47c7c72ea..dfcc1ab0b584db 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -341,6 +341,33 @@ mlir::Value Fortran::lower::genInitialDataTarget(
                               /*slice=*/mlir::Value{});
 }
 
+static mlir::Value
+genCoarrayDefaultInitializerValue(Fortran::lower::AbstractConverter &converter,
+                                  mlir::Location loc, mlir::Type boxType,
+                                  unsigned allocator) {
+  fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+  auto baseBoxType = mlir::cast<fir::BaseBoxType>(boxType);
+  auto baseAddrType = baseBoxType.getBaseAddressType();
+  auto type = fir::unwrapRefType(baseAddrType);
+  auto eleTy = fir::unwrapSequenceType(type);
+  auto nullAddr = builder.createNullConstant(loc, baseAddrType);
+  mlir::Value shape, slice;
+  if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(type)) {
+    llvm::SmallVector<mlir::Value> extents;
+    for (int64_t extent : seqTy.getShape())
+      extents.push_back(
+          builder.createIntegerConstant(loc, builder.getIndexType(), extent));
+    shape = builder.createShape(
+        loc, fir::ArrayBoxValue{nullAddr, extents, /*lbounds=*/{}});
+  }
+  auto embox =
+      fir::EmboxOp::create(builder, loc, baseBoxType, nullAddr, shape, slice,
+                           /*lenParams=*/{}, /*typeSourceBox=*/{});
+  if (allocator != 0)
+    embox.setAllocatorIdx(allocator);
+  return embox;
+}
+
 /// Generate default initial value for a derived type object \p sym with mlir
 /// type \p symTy.
 static mlir::Value genDefaultInitializerValue(
@@ -571,6 +598,22 @@ fir::GlobalOp Fortran::lower::defineGlobal(
         fir::HasValueOp::create(b, loc, box);
       });
     }
+  } else if (Fortran::evaluate::IsCoarray(sym)) {
+    if (oeDetails && oeDetails->init()) {
+      auto expr = *oeDetails->init();
+      createGlobalInitialization(builder, global, [&](fir::FirOpBuilder &b) {
+        mlir::Value box =
+            Fortran::lower::genInitialDataTarget(converter, loc, symTy, expr);
+        fir::HasValueOp::create(b, loc, box);
+      });
+    } else {
+      createGlobalInitialization(builder, global, [&](fir::FirOpBuilder &b) {
+        unsigned allocatorIdx = Fortran::lower::getAllocatorIdx(sym);
+        mlir::Value box = genCoarrayDefaultInitializerValue(
+            converter, loc, symTy, allocatorIdx);
+        fir::HasValueOp::create(b, loc, box);
+      });
+    }
   } else if (oeDetails) {
     if (oeDetails->init()) {
       createGlobalInitialization(
@@ -2150,6 +2193,15 @@ static void genDeclareSymbol(Fortran::lower::AbstractConverter &converter,
       argNo = converter.getDummyArgPosition(sym);
     }
     auto [storage, storageOffset] = converter.getSymbolStorage(sym);
+
+    if (Fortran::evaluate::IsCoarray(sym) &&
+        !Fortran::semantics::IsAllocatableOrPointer(sym)) {
+      auto newBase = hlfir::DeclareOp::create(
+          builder, loc, base, name, /*shape=*/nullptr, lenParams, dummyScope,
+          storage, storageOffset, attributes, dataAttr, argNo);
+      symMap.addVariableDefinition(sym, newBase, force);
+      return;
+    }
     auto newBase = hlfir::DeclareOp::create(
         builder, loc, base, name, shapeOrShift, lenParams, dummyScope, storage,
         storageOffset, attributes, dataAttr, argNo);
diff --git a/flang/test/Integration/MIF/coarray_allocation4.f90 b/flang/test/Integration/MIF/coarray_allocation4.f90
index c98ae9dd016121..41a66eef847881 100644
--- a/flang/test/Integration/MIF/coarray_allocation4.f90
+++ b/flang/test/Integration/MIF/coarray_allocation4.f90
@@ -24,12 +24,12 @@ program main
 
 ! CHECK-LABEL: func.func @_QPtest_coarray_save()
 ! CHECK:   %0 = fir.dummy_scope : !fir.dscope
-! CHECK:   %1 = fir.address_of(@_QFtest_coarray_saveEm) : !fir.ref<f32>
-! CHECK:   %2:2 = hlfir.declare %1 {uniq_name = "_QFtest_coarray_saveEm"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
-! CHECK:   %3 = fir.address_of(@_QFtest_coarray_saveEn) : !fir.ref<f32>
-! CHECK:   %4:2 = hlfir.declare %3 {uniq_name = "_QFtest_coarray_saveEn"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
-! CHECK:   %5 = fir.address_of(@_QFtest_coarray_saveEp) : !fir.ref<f32>
-! CHECK:   %6:2 = hlfir.declare %5 {uniq_name = "_QFtest_coarray_saveEp"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK:   %1 = fir.address_of(@_QFtest_coarray_saveEm) : !fir.ref<!fir.box<!fir.heap<f32>, corank:1>>
+! CHECK:   %2:2 = hlfir.declare %1 {uniq_name = "_QFtest_coarray_saveEm"} : (!fir.ref<!fir.box<!fir.heap<f32>, corank:1>>) -> (!fir.ref<!fir.box<!fir.heap<f32>, corank:1>>, !fir.ref<!fir.box<!fir.heap<f32>, corank:1>>)
+! CHECK:   %3 = fir.address_of(@_QFtest_coarray_saveEn) : !fir.ref<!fir.box<!fir.heap<f32>, corank:1>>
+! CHECK:   %4:2 = hlfir.declare %3 {uniq_name = "_QFtest_coarray_saveEn"} : (!fir.ref<!fir.box<!fir.heap<f32>, corank:1>>) -> (!fir.ref<!fir.box<!fir.heap<f32>, corank:1>>, !fir.ref<!fir.box<!fir.heap<f32>, corank:1>>)
+! CHECK:   %5 = fir.address_of(@_QFtest_coarray_saveEp) : !fir.ref<!fir.box<!fir.heap<f32>, corank:1>>
+! CHECK:   %6:2 = hlfir.declare %5 {uniq_name = "_QFtest_coarray_saveEp"} : (!fir.ref<!fir.box<!fir.heap<f32>, corank:1>>) -> (!fir.ref<!fir.box<!fir.heap<f32>, corank:1>>, !fir.ref<!fir.box<!fir.heap<f32>, corank:1>>)
 ! CHECK:   return
 
 ! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "MAIN"}
@@ -37,7 +37,7 @@ program main
 ! CHECK:   fir.call @_QPtest_coarray_save() fastmath<contract> : () -> ()
 ! CHECK:   return
 
-! CHECK: fir.global internal @_QFtest_coarray_saveEm : f32
+! CHECK: fir.global internal @_QFtest_coarray_saveEm : !fir.box<!fir.heap<f32>, corank:1>
 
 ! CHECK-LABEL: func.func @__mif_save_coarrays_allocate()
 ! CHECK:   %[[VAL_0:.*]] = fir.alloca !fir.array<0xi64>
@@ -47,7 +47,7 @@ program main
 ! CHECK:   %[[VAL_4:.*]] = fir.alloca !fir.array<0xi64>
 ! CHECK:   %[[VAL_5:.*]] = fir.alloca !fir.array<1xi64>
 ! CHECK:   %[[INIT_STAT:.*]] = mif.init -> i32
-! CHECK:   %[[VAL_6:.*]] = fir.address_of(@_QFtest_coarray_saveEm) : !fir.ref<f32>
+! CHECK:   %[[VAL_6:.*]] = fir.address_of(@_QFtest_coarray_saveEm) : !fir.ref<!fir.box<!fir.heap<f32>, corank:1>>
 ! CHECK:   %[[C1_I64:.*]] = arith.constant 1 : i64
 ! CHECK:   %[[C1_I64_0:.*]] = arith.constant 1 : i64
 ! CHECK:   %[[C0:.*]] = arith.constant 0 : index
@@ -56,8 +56,8 @@ program main
 ! CHECK:   %[[VAL_8:.*]] = fir.embox %[[VAL_5]] : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
 ! CHECK:   %[[C1_I64_1:.*]] = arith.constant 1 : i64
 ! CHECK:   %[[VAL_9:.*]] = fir.embox %[[VAL_4]] : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
-! CHECK:   mif.alloc_coarray %[[VAL_6]] lcobounds %[[VAL_8]] ucobounds %[[VAL_9]] {uniq_name = "_QFtest_coarray_saveEm"} : (!fir.ref<f32>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
-! CHECK:   %[[VAL_10:.*]] = fir.address_of(@_QFtest_coarray_saveEn) : !fir.ref<f32>
+! CHECK:   mif.alloc_coarray %[[VAL_6]] lcobounds %[[VAL_8]] ucobounds %[[VAL_9]] {uniq_name = "_QFtest_coarray_saveEm"} : (!fir.ref<!fir.box<!fir.heap<f32>, corank:1>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
+! CHECK:   %[[VAL_10:.*]] = fir.address_of(@_QFtest_coarray_saveEn) : !fir.ref<!fir.box<!fir.heap<f32>, corank:1>>
 ! CHECK:   %[[C1_I64_2:.*]] = arith.constant 1 : i64
 ! CHECK:   %[[C1_I64_3:.*]] = arith.constant 1 : i64
 ! CHECK:   %[[C0_4:.*]] = arith.constant 0 : index
@@ -66,8 +66,8 @@ program main
 ! CHECK:   %[[VAL_12:.*]] = fir.embox %[[VAL_3]] : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
 ! CHECK:   %[[C1_I64_5:.*]] = arith.constant 1 : i64
 ! CHECK:   %[[VAL_13:.*]] = fir.embox %[[VAL_2]] : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
-! CHECK:   mif.alloc_coarray %[[VAL_10]] lcobounds %[[VAL_12]] ucobounds %[[VAL_13]] {uniq_name = "_QFtest_coarray_saveEn"} : (!fir.ref<f32>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
-! CHECK:   %[[VAL_14:.*]] = fir.address_of(@_QFtest_coarray_saveEp) : !fir.ref<f32>
+! CHECK:   mif.alloc_coarray %[[VAL_10]] lcobounds %[[VAL_12]] ucobounds %[[VAL_13]] {uniq_name = "_QFtest_coarray_saveEn"} : (!fir.ref<!fir.box<!fir.heap<f32>, corank:1>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
+! CHECK:   %[[VAL_14:.*]] = fir.address_of(@_QFtest_coarray_saveEp) : !fir.ref<!fir.box<!fir.heap<f32>, corank:1>>
 ! CHECK:   %[[C1_I64_6:.*]] = arith.constant 1 : i64
 ! CHECK:   %[[C1_I64_7:.*]] = arith.constant 1 : i64
 ! CHECK:   %[[C0_8:.*]] = arith.constant 0 : index
@@ -76,8 +76,8 @@ program main
 ! CHECK:   %[[VAL_16:.*]] = fir.embox %[[VAL_1]] : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
 ! CHECK:   %[[VAL_C1_I64_9:.*]] = arith.constant 1 : i64
 ! CHECK:   %[[VAL_17:.*]] = fir.embox %[[VAL_0]] : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
-! CHECK:   mif.alloc_coarray %[[VAL_14:.*]] lcobounds %[[VAL_16]] ucobounds %[[VAL_17]] {uniq_name = "_QFtest_coarray_saveEp"} : (!fir.ref<f32>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
+! CHECK:   mif.alloc_coarray %[[VAL_14:.*]] lcobounds %[[VAL_16]] ucobounds %[[VAL_17]] {uniq_name = "_QFtest_coarray_saveEp"} : (!fir.ref<!fir.box<!fir.heap<f32>, corank:1>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
 ! CHECK:   return
 
-! CHECK:  fir.global internal @_QFtest_coarray_saveEn : f32
-! CHECK:  fir.global internal @_QFtest_coarray_saveEp : f32
+! CHECK:  fir.global internal @_QFtest_coarray_saveEn : !fir.box<!fir.heap<f32>, corank:1>
+! CHECK:  fir.global internal @_QFtest_coarray_saveEp : !fir.box<!fir.heap<f32>, corank:1>
diff --git a/flang/test/Integration/MIF/coarray_allocation5.f90 b/flang/test/Integration/MIF/coarray_allocation5.f90
index 03b37768759d4b..61fed5d9f8d4ce 100644
--- a/flang/test/Integration/MIF/coarray_allocation5.f90
+++ b/flang/test/Integration/MIF/coarray_allocation5.f90
@@ -24,7 +24,7 @@ program test
 ! CHECK:  %[[VAL_0:.*]] = fir.alloca !fir.array<0xi64>
 ! CHECK:  %[[VAL_1:.*]] = fir.alloca !fir.array<1xi64>
 ! CHECK:  %[[INIT_STAT:.*]] = mif.init -> i32
-! CHECK:  %[[VAL_2:.*]] = fir.address_of(@_QMm_coarray_testEmodule_coarray) : !fir.ref<f32>
+! CHECK:  %[[VAL_2:.*]] = fir.address_of(@_QMm_coarray_testEmodule_coarray) : !fir.ref<!fir.box<!fir.heap<f32>, corank:1>>
 ! CHECK:  %c1_i64 = arith.constant 1 : i64
 ! CHECK:  %c1_i64_0 = arith.constant 1 : i64
 ! CHECK:  %c0 = arith.constant 0 : index
@@ -33,5 +33,5 @@ program test
 ! CHECK:  %[[VAL_4:.*]] = fir.embox %[[VAL_1]] : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
 ! CHECK:  %c1_i64_1 = arith.constant 1 : i64
 ! CHECK:  %[[VAL_5:.*]] = fir.embox %[[VAL_0]] : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
-! CHECK:  mif.alloc_coarray %[[VAL_2]] lcobounds %[[VAL_4]] ucobounds %[[VAL_5]] {uniq_name = "_QMm_coarray_testEmodule_coarray"} : (!fir.ref<f32>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
+! CHECK:  mif.alloc_coarray %[[VAL_2]] lcobounds %[[VAL_4]] ucobounds %[[VAL_5]] {uniq_name = "_QMm_coarray_testEmodule_coarray"} : (!fir.ref<!fir.box<!fir.heap<f32>, corank:1>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
 ! CHECK:  return
diff --git a/flang/test/Lower/MIF/coarray_allocation.f90 b/flang/test/Lower/MIF/coarray_allocation.f90
index 8b918e30ade751..789c3e2fd1a6dd 100644
--- a/flang/test/Lower/MIF/coarray_allocation.f90
+++ b/flang/test/Lower/MIF/coarray_allocation.f90
@@ -11,20 +11,20 @@ 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.box<!fir.heap<i32>, corank:2>>
+  ! CHECK: mif.alloc_coarray %[[VAL_1]] lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] {uniq_name = "_QFEa"} : (!fir.ref<!fir.box<!fir.heap<i32>, corank: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>, corank:2>>) -> (!fir.ref<!fir.box<!fir.heap<i32>, corank:2>>, !fir.ref<!fir.box<!fir.heap<i32>, corank: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.box<!fir.heap<f32>, corank:3>>
+  ! CHECK: mif.alloc_coarray %[[VAL_2]] lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] {uniq_name = "_QFEb"} : (!fir.ref<!fir.box<!fir.heap<f32>, corank: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>, corank:3>>) -> (!fir.ref<!fir.box<!fir.heap<f32>, corank:3>>, !fir.ref<!fir.box<!fir.heap<f32>, corank: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.box<!fir.heap<!fir.char<1,10>>, corank:1>>
+  ! CHECK: mif.alloc_coarray %[[VAL_3]] lcobounds %[[LCOBOUNDS:.*]] ucobounds %[[UCOBOUNDS:.*]] {uniq_name = "_QFEc"} : (!fir.ref<!fir.box<!fir.heap<!fir.char<1,10>>, corank: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,?>>>, corank:1>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>, corank:1>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>, corank:1>>)
   character(len=10) :: c[*]
diff --git a/flang/test/Lower/MIF/coshape.f90 b/flang/test/Lower/MIF/coshape.f90
index c7ba488bf70dd5..65e3489f076ecc 100644
--- a/flang/test/Lower/MIF/coshape.f90
+++ b/flang/test/Lower/MIF/coshape.f90
@@ -7,15 +7,15 @@ program test
   integer :: a[2,3:5,*]
 
   ! COSHAPE without KIND returns default integer kind (4 = i32).
-  ! CHECK: mif.coshape coarray %[[COARRAY:.*]] : (!fir.box<i32, corank:3>) -> !fir.box<!fir.array<?xi32>>
+  ! CHECK: mif.coshape coarray %[[COARRAY:.*]] : (!fir.box<!fir.heap<i32>, corank:3>) -> !fir.box<!fir.array<?xi32>>
   res = coshape(a)
 
   ! Assignment to integer(kind=8) widens; COSHAPE result type is still i32.
-  ! CHECK: mif.coshape coarray %[[COARRAY:.*]] : (!fir.box<i32, corank:3>) -> !fir.box<!fir.array<?xi32>>
+  ! CHECK: mif.coshape coarray %[[COARRAY:.*]] : (!fir.box<!fir.heap<i32>, corank:3>) -> !fir.box<!fir.array<?xi32>>
   res2 = coshape(a)
 
   ! Explicit KIND=8 yields i64 elements.
-  ! CHECK: mif.coshape coarray %[[COARRAY:.*]] : (!fir.box<i32, corank:3>) -> !fir.box<!fir.array<?xi64>>
+  ! CHECK: mif.coshape coarray %[[COARRAY:.*]] : (!fir.box<!fir.heap<i32>, corank:3>) -> !fir.box<!fir.array<?xi64>>
   res3 = coshape(a, kind=8)
 
 end program
diff --git a/flang/test/Lower/MIF/image_index.f90 b/flang/test/Lower/MIF/image_index.f90
index 4da1452fcfa1c7..923e2b4a291b7e 100644
--- a/flang/test/Lower/MIF/image_index.f90
+++ b/flang/test/Lower/MIF/image_index.f90
@@ -8,17 +8,17 @@ program test
   type(team_type) :: team
   integer :: team_number
 
-  ! CHECK: mif.image_index coarray %[[COARRAY:.*]] sub %[[SUB:.*]] : (!fir.box<i32, corank:3>, !fir.box<!fir.array<3xi64>>) -> i32
+  ! CHECK: mif.image_index coarray %[[COARRAY:.*]] sub %[[SUB:.*]] : (!fir.box<!fir.heap<i32>, corank:3>, !fir.box<!fir.array<3xi64>>) -> i32
   idx = image_index(a, SUB=sub)
 
-  ! CHECK: mif.image_index coarray %[[COARRAY:.*]] sub %[[SUB2:.*]] : (!fir.box<i32, corank:3>, !fir.box<!fir.array<3xi64>>) -> i32
+  ! CHECK: mif.image_index coarray %[[COARRAY:.*]] sub %[[SUB2:.*]] : (!fir.box<!fir.heap<i32>, corank:3>, !fir.box<!fir.array<3xi64>>) -> i32
   idx = image_index(a, SUB=sub2)
 
-  ! CHECK: mif.image_index coarray %[[COARRAY:.*]] sub %[[SUB:.*]] team %[[TEAM:.*]]#0 : (!fir.box<i32, corank:3>,
+  ! CHECK: mif.image_index coarray %[[COARRAY:.*]] sub %[[SUB:.*]] team %[[TEAM:.*]]#0 : (!fir.box<!fir.heap<i32>, corank:3>,
   ! !fir.box<!fir.array<3xi64>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_team_type{{.*}}>>) -> i32
   idx = image_index(a, SUB=sub, TEAM=team)
 
-  ! CHECK: mif.image_index coarray %[[COARRAY:.*]] sub %[[SUB:.*]] team_number %[[TEAM_NUMBER:.*]]: (!fir.box<i32, corank:3>, !fir.box<!fir.array<3xi64>>, i32) -> i32
+  ! CHECK: mif.image_index coarray %[[COARRAY:.*]] sub %[[SUB:.*]] team_number %[[TEAM_NUMBER:.*]]: (!fir.box<!fir.heap<i32>, corank:3>, !fir.box<!fir.array<3xi64>>, i32) -> i32
   idx = image_index(a, SUB=sub, TEAM_NUMBER=team_number)
 
 end program
diff --git a/flang/test/Lower/MIF/this_image.f90 b/flang/test/Lower/MIF/this_image.f90
index b026300876b7b8..aae13c11a819be 100644
--- a/flang/test/Lower/MIF/this_image.f90
+++ b/flang/test/Lower/MIF/this_image.f90
@@ -12,9 +12,9 @@ program test
   ! CHECK: mif.this_image team %[[TEAM:.*]] : ({{.*}}) -> i32
   i = this_image(TEAM=team)
 
-  ! CHECK: mif.this_image coarray %[[A:.*]] : (!fir.box<i32, corank:2>) -> !fir.box<!fir.array<?xi32>>
+  ! CHECK: mif.this_image coarray %[[A:.*]] : (!fir.box<!fir.heap<i32>, corank:2>) -> !fir.box<!fir.array<?xi32>>
   j = this_image(COARRAY=a)
   
-  ! CHECK: mif.this_image coarray %[[A:.*]] dim %[[DIM:.*]] : (!fir.box<i32, corank:2>, i32) -> i64
+  ! CHECK: mif.this_image coarray %[[A:.*]] dim %[[DIM:.*]] : (!fir.box<!fir.heap<i32>, corank:2>, i32) -> i64
   j = this_image(COARRAY=a, DIM=1)
 end program

>From 7f88b0f36eb77b587f987bf6fc77b6b074ec19fa Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Mon, 14 Sep 2026 10:53:29 +0200
Subject: [PATCH 6/7] Update EventPosOp conversion + update offset computation
 func

---
 flang-rt/lib/runtime/allocatable.cpp          |   5 +
 flang/include/flang/Lower/AbstractConverter.h |  16 +-
 .../include/flang/Optimizer/Dialect/FIRType.h |   7 +
 .../flang/Optimizer/Dialect/MIF/MIFOps.td     |   6 +-
 flang/include/flang/Runtime/allocatable.h     |   4 +
 flang/lib/Lower/Bridge.cpp                    |  23 +-
 flang/lib/Lower/ConvertVariable.cpp           |  11 +-
 flang/lib/Lower/MultiImageFortran.cpp         |   8 +-
 flang/lib/Optimizer/Builder/MIFCommon.cpp     |   4 +-
 .../Optimizer/Transforms/MIFOpConversion.cpp  | 285 ++++++++----------
 flang/test/Fir/MIF/coarray-alloc.mlir         |  18 +-
 .../Fir/MIF/coarray_alloc_many_declare.mlir   |  24 +-
 flang/test/Fir/MIF/events.mlir                | 132 +++++---
 flang/test/Lower/MIF/events.f90               |  18 +-
 14 files changed, 321 insertions(+), 240 deletions(-)

diff --git a/flang-rt/lib/runtime/allocatable.cpp b/flang-rt/lib/runtime/allocatable.cpp
index 5b3db1e47238b7..42d715f9b2bdcc 100644
--- a/flang-rt/lib/runtime/allocatable.cpp
+++ b/flang-rt/lib/runtime/allocatable.cpp
@@ -239,6 +239,11 @@ void RTDEF(AllocatableDeallocateNoFinal)(
   }
 }
 
+void RTDEF(AllocatableSetBaseAddr)(Descriptor &desc, void *new_base_addr) {
+  desc.set_base_addr(new_base_addr);
+  desc.SetByteStrides();
+}
+
 // TODO: AllocatableCheckLengthParameter
 
 RT_EXT_API_GROUP_END
diff --git a/flang/include/flang/Lower/AbstractConverter.h b/flang/include/flang/Lower/AbstractConverter.h
index ae246d3188bd88..c2d4090894743c 100644
--- a/flang/include/flang/Lower/AbstractConverter.h
+++ b/flang/include/flang/Lower/AbstractConverter.h
@@ -209,16 +209,19 @@ class AbstractConverter {
   /// expression value. The clean-up for this temporary is added to \p context.
   virtual fir::ExtendedValue genExprAddr(const SomeExpr &expr,
                                          StatementContext &context,
-                                         mlir::Location *locPtr = nullptr) = 0;
+                                         mlir::Location *locPtr = nullptr,
+                                         bool allowCoarray = false) = 0;
 
   /// Generate the address of the location holding the expression, \p expr.
   fir::ExtendedValue genExprAddr(mlir::Location loc, const SomeExpr *expr,
-                                 StatementContext &stmtCtx) {
-    return genExprAddr(*expr, stmtCtx, &loc);
+                                 StatementContext &stmtCtx,
+                                 bool allowCoarray = false) {
+    return genExprAddr(*expr, stmtCtx, &loc, allowCoarray);
   }
   fir::ExtendedValue genExprAddr(mlir::Location loc, const SomeExpr &expr,
-                                 StatementContext &stmtCtx) {
-    return genExprAddr(expr, stmtCtx, &loc);
+                                 StatementContext &stmtCtx,
+                                 bool allowCoarray = false) {
+    return genExprAddr(expr, stmtCtx, &loc, allowCoarray);
   }
 
   /// Generate the computations of the expression to produce a value.
@@ -241,7 +244,8 @@ class AbstractConverter {
   /// storage without making a temporary.
   virtual fir::ExtendedValue genExprBox(mlir::Location loc,
                                         const SomeExpr &expr,
-                                        StatementContext &stmtCtx) = 0;
+                                        StatementContext &stmtCtx,
+                                        bool allowCoarray = false) = 0;
 
   /// Generate the address of the box describing the variable designated
   /// by the expression. The expression must be an allocatable or pointer
diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h
index 4fd9638e60d465..438a83805182dc 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRType.h
+++ b/flang/include/flang/Optimizer/Dialect/FIRType.h
@@ -160,6 +160,13 @@ inline bool conformsWithPassByRef(mlir::Type t) {
 /// Is `t` a derived (record) type?
 inline bool isa_derived(mlir::Type t) { return mlir::isa<fir::RecordType>(t); }
 
+/// Is `t` type(event_type) type?
+inline bool isa_builtin_event_type(mlir::Type t) {
+  if (auto recTy = mlir::dyn_cast_or_null<fir::RecordType>(t))
+    return recTy.getName().ends_with("T__builtin_event_type");
+  return false;
+}
+
 /// Is `t` type(c_ptr), type(c_funptr), or type(c_devptr)?
 inline bool isa_builtin_cptr_type(mlir::Type t) {
   if (auto recTy = mlir::dyn_cast_or_null<fir::RecordType>(t))
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
index d52856b5c75e99..64939f4ab877d5 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -554,7 +554,7 @@ def mif_AllocCoarrayOp
   }];
 
   let arguments = (ins StrAttr:$uniq_name,
-      Arg<fir_ReferenceType, "", [MemRead, MemWrite]>:$box,
+      Arg<AnyReferenceLike, "", [MemRead, MemWrite]>:$box,
       AnyBoxedArray:$lcobounds, AnyBoxedArray:$ucobounds,
       Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
       Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
@@ -608,7 +608,7 @@ def mif_EventPostOp : mif_Op<"event_post", [AttrSizedOperandSegments,
         type EVENT_TYPE from the intrinsic module ISO_FORTRAN_ENV.
   }];
 
-  let arguments = (ins AnyRefOrBoxType:$event,
+  let arguments = (ins Arg<AnyRefOrBoxType, "", [MemRead]>:$event,
       Variadic<AnyInteger>:$cosubscripts,
       Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
       Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
@@ -631,7 +631,7 @@ def mif_EventWaitOp : mif_Op<"event_wait", [AttrSizedOperandSegments,
         the given event variable to be waited for.
   }];
 
-  let arguments = (ins AnyRefOrBoxType:$event,
+  let arguments = (ins Arg<AnyRefOrBoxType, "", [MemRead]>:$event,
       Optional<AnyIntegerType>:$until_count,
       Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
       Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
diff --git a/flang/include/flang/Runtime/allocatable.h b/flang/include/flang/Runtime/allocatable.h
index ba065331e39229..f7300408379be3 100644
--- a/flang/include/flang/Runtime/allocatable.h
+++ b/flang/include/flang/Runtime/allocatable.h
@@ -136,6 +136,10 @@ int RTDECL(AllocatableDeallocatePolymorphic)(Descriptor &,
 // Variant of above that does not finalize; for intermediate results
 void RTDECL(AllocatableDeallocateNoFinal)(
     Descriptor &, const char *sourceFile = nullptr, int sourceLine = 0);
+
+// For an existing descriptor, set a new base_addr
+void RTDECL(AllocatableSetBaseAddr)(Descriptor &, void *);
+
 } // extern "C"
 } // namespace Fortran::runtime
 #endif // FORTRAN_RUNTIME_ALLOCATABLE_H_
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index ca373bef590bcd..1e02436c174c62 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -834,11 +834,15 @@ class FirConverter : public Fortran::lower::AbstractConverter {
     return owningProc.labelEvaluationMap.lookup(label);
   }
 
-  fir::ExtendedValue
-  genExprAddr(const Fortran::lower::SomeExpr &expr,
-              Fortran::lower::StatementContext &context,
-              mlir::Location *locPtr = nullptr) override final {
+  fir::ExtendedValue genExprAddr(const Fortran::lower::SomeExpr &expr,
+                                 Fortran::lower::StatementContext &context,
+                                 mlir::Location *locPtr = nullptr,
+                                 bool allowCoarray = false) override final {
     mlir::Location loc = locPtr ? *locPtr : toLocation();
+    auto coarrayRef = Fortran::evaluate::ExtractCoarrayRef(expr);
+    expr.dump();
+    if (coarrayRef.has_value() && !allowCoarray)
+      TODO(loc, "coarray: genExprAddr of coarray reference.");
     return Fortran::lower::convertExprToAddress(loc, *this, expr, localSymbols,
                                                 context);
   }
@@ -855,9 +859,14 @@ class FirConverter : public Fortran::lower::AbstractConverter {
                                               context);
   }
 
-  fir::ExtendedValue
-  genExprBox(mlir::Location loc, const Fortran::lower::SomeExpr &expr,
-             Fortran::lower::StatementContext &stmtCtx) override final {
+  fir::ExtendedValue genExprBox(mlir::Location loc,
+                                const Fortran::lower::SomeExpr &expr,
+                                Fortran::lower::StatementContext &stmtCtx,
+                                bool allowCoarray = false) override final {
+    auto coarrayRef = Fortran::evaluate::ExtractCoarrayRef(expr);
+    expr.dump();
+    if (coarrayRef.has_value() && !allowCoarray)
+      TODO(loc, "coarray: genExprBox of coarray reference.");
     return Fortran::lower::convertExprToBox(loc, *this, expr, localSymbols,
                                             stmtCtx);
   }
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index dfcc1ab0b584db..8fac642be0d7e5 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -343,13 +343,11 @@ mlir::Value Fortran::lower::genInitialDataTarget(
 
 static mlir::Value
 genCoarrayDefaultInitializerValue(Fortran::lower::AbstractConverter &converter,
-                                  mlir::Location loc, mlir::Type boxType,
-                                  unsigned allocator) {
+                                  mlir::Location loc, mlir::Type boxType) {
   fir::FirOpBuilder &builder = converter.getFirOpBuilder();
   auto baseBoxType = mlir::cast<fir::BaseBoxType>(boxType);
   auto baseAddrType = baseBoxType.getBaseAddressType();
   auto type = fir::unwrapRefType(baseAddrType);
-  auto eleTy = fir::unwrapSequenceType(type);
   auto nullAddr = builder.createNullConstant(loc, baseAddrType);
   mlir::Value shape, slice;
   if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(type)) {
@@ -363,8 +361,6 @@ genCoarrayDefaultInitializerValue(Fortran::lower::AbstractConverter &converter,
   auto embox =
       fir::EmboxOp::create(builder, loc, baseBoxType, nullAddr, shape, slice,
                            /*lenParams=*/{}, /*typeSourceBox=*/{});
-  if (allocator != 0)
-    embox.setAllocatorIdx(allocator);
   return embox;
 }
 
@@ -608,9 +604,8 @@ fir::GlobalOp Fortran::lower::defineGlobal(
       });
     } else {
       createGlobalInitialization(builder, global, [&](fir::FirOpBuilder &b) {
-        unsigned allocatorIdx = Fortran::lower::getAllocatorIdx(sym);
-        mlir::Value box = genCoarrayDefaultInitializerValue(
-            converter, loc, symTy, allocatorIdx);
+        mlir::Value box =
+            genCoarrayDefaultInitializerValue(converter, loc, symTy);
         fir::HasValueOp::create(b, loc, box);
       });
     }
diff --git a/flang/lib/Lower/MultiImageFortran.cpp b/flang/lib/Lower/MultiImageFortran.cpp
index 8607660820602d..dba6e8987be788 100644
--- a/flang/lib/Lower/MultiImageFortran.cpp
+++ b/flang/lib/Lower/MultiImageFortran.cpp
@@ -547,8 +547,8 @@ void Fortran::lower::genEventPostStatement(
   // Handle EVENT-VAR and IMAGE_NUMBER
   auto eventExpr = Fortran::semantics::GetExpr(
       std::get<Fortran::parser::EventVariable>(stmt.t));
-  mlir::Value event =
-      fir::getBase(converter.genExprBox(loc, *eventExpr, stmtCtx));
+  mlir::Value event = fir::getBase(
+      converter.genExprBox(loc, *eventExpr, stmtCtx, /*allowCoarray=*/true));
   llvm::SmallVector<mlir::Value> cosubscripts;
   if (auto coref{evaluate::ExtractCoarrayRef(eventExpr)}) {
     cosubscripts =
@@ -601,8 +601,8 @@ void Fortran::lower::genEventWaitStatement(
   // Handle EVENT-VAR
   auto eventExpr = Fortran::semantics::GetExpr(
       std::get<Fortran::parser::EventVariable>(stmt.t));
-  mlir::Value eventVar =
-      fir::getBase(converter.genExprAddr(loc, *eventExpr, stmtCtx));
+  mlir::Value eventVar = fir::getBase(
+      converter.genExprAddr(loc, *eventExpr, stmtCtx, /*allowCoarray=*/true));
 
   mif::EventWaitOp::create(builder, loc, eventVar, untilCount, statAddr,
                            errMsgAddr);
diff --git a/flang/lib/Optimizer/Builder/MIFCommon.cpp b/flang/lib/Optimizer/Builder/MIFCommon.cpp
index 913dba4960276d..16ed076d5c974d 100644
--- a/flang/lib/Optimizer/Builder/MIFCommon.cpp
+++ b/flang/lib/Optimizer/Builder/MIFCommon.cpp
@@ -27,14 +27,14 @@ std::string mif::getFullUniqName(mlir::Value addr) {
     return getFullUniqName(load.getMemref());
   else if (auto ba = mlir::dyn_cast<fir::BoxAddrOp>(op))
     return getFullUniqName(ba.getVal());
+  else if (auto c = mlir::dyn_cast<fir::ConvertOp>(op))
+    return getFullUniqName(c.getValue());
   else if (auto rb = mlir::dyn_cast<fir::ReboxOp>(op))
     return getFullUniqName(rb.getBox());
   else if (auto eb = mlir::dyn_cast<fir::EmboxOp>(op))
     return getFullUniqName(eb.getMemref());
   else if (auto ac = mlir::dyn_cast<fir::ArrayCoorOp>(op))
     return getFullUniqName(ac.getMemref());
-  else if (auto c = mlir::dyn_cast<fir::CoordinateOp>(op))
-    return getFullUniqName(c.getRef());
   else if (auto ebc = mlir::dyn_cast<fir::EmboxCharOp>(op))
     return getFullUniqName(ebc.getMemref());
   else if (auto c = mlir::dyn_cast<fir::CoordinateOp>(op)) {
diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
index 12b58f15d58d03..13a33ec9186596 100644
--- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
@@ -7,11 +7,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "flang/Optimizer/Transforms/MIFOpConversion.h"
+#include "flang/Lower/BuiltinModules.h"
 #include "flang/Optimizer/Builder/BoxValue.h"
 #include "flang/Optimizer/Builder/Character.h"
 #include "flang/Optimizer/Builder/HLFIRTools.h"
 #include "flang/Optimizer/Builder/MIFCommon.h"
 #include "flang/Optimizer/Builder/MutableBox.h"
+#include "flang/Optimizer/Builder/Runtime/Derived.h"
 #include "flang/Optimizer/Builder/Runtime/Inquiry.h"
 #include "flang/Optimizer/Builder/Runtime/Pointer.h"
 #include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
@@ -21,6 +23,7 @@
 #include "flang/Optimizer/Dialect/MIF/MIFOps.h"
 #include "flang/Optimizer/Support/DataLayout.h"
 #include "flang/Optimizer/Support/InternalNames.h"
+#include "flang/Runtime/allocatable.h"
 #include "flang/Runtime/stop.h"
 #include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
 #include "mlir/Dialect/DLTI/DLTI.h"
@@ -61,6 +64,28 @@ genBoxedSequenceType(mlir::Type eleTy,
       fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, eleTy));
 }
 
+static mlir::Type getBuiltinTeamType(fir::FirOpBuilder &builder,
+                                     mlir::Location loc) {
+  std::string typeName = fir::NameUniquer::doType({"__fortran_builtins"}, {}, 0,
+                                                  "__builtin_team_type", {});
+  fir::RecordType teamType =
+      fir::RecordType::get(builder.getContext(), typeName);
+  mlir::Type fieldTy = fir::BoxType::get(fir::PointerType::get(
+      fir::RecordType::get(builder.getContext(), "dummy_desc_type")));
+  teamType.finalize({}, {{"info", fieldTy}});
+  return teamType;
+}
+
+static mlir::Type getBuiltinCptrType(fir::FirOpBuilder &builder,
+                                       mlir::Location loc) {
+  std::string cPtrTypeName = fir::NameUniquer::doType(
+      {"__fortran_builtins"}, {}, 0, "__builtin_c_ptr", {});
+  fir::RecordType cPtrType =
+      fir::RecordType::get(builder.getContext(), cPtrTypeName);
+  cPtrType.finalize({}, {{Fortran::lower::builtin::cptrFieldName, builder.getI64Type()}});
+  return cPtrType;
+}
+
 static mlir::Type getCoarrayHandleType(fir::FirOpBuilder &builder,
                                        mlir::Location loc) {
   // Defining the coarray handle type
@@ -68,16 +93,23 @@ static mlir::Type getCoarrayHandleType(fir::FirOpBuilder &builder,
       {"__fortran_builtins"}, {}, 0, "__builtin_prif_coarray_handle_type", {});
   fir::RecordType handleTy =
       fir::RecordType::get(builder.getContext(), handleDTName);
-
-  std::string cPtrTypeName = fir::NameUniquer::doType(
-      {"__fortran_builtins"}, {}, 0, "__builtin_c_ptr", {});
-  fir::RecordType cPtrType =
-      fir::RecordType::get(builder.getContext(), cPtrTypeName);
-  cPtrType.finalize({}, {{"__c_ptr_c_address", builder.getI64Type()}});
-  handleTy.finalize({}, {{"info", cPtrType}});
+  handleTy.finalize({}, {{"info", getBuiltinCptrType(builder, loc)}});
   return handleTy;
 }
 
+static mlir::Value convertRefTypeToCPtrType(fir::FirOpBuilder &builder,
+                                            mlir::Location loc,
+                                            mlir::Value ref) {
+  mlir::Type cptrType = getBuiltinCptrType(builder, loc);
+  mlir::Value cptr = builder.createTemporary(loc, cptrType);
+
+  mlir::Value addrI64 = builder.createConvert(loc, builder.getI64Type(), ref);
+  mlir::Value addrRef =
+      fir::factory::genCPtrOrCFunptrAddr(builder, loc, cptr, cptrType);
+  fir::StoreOp::create(builder, loc, addrI64, addrRef);
+  return cptr;
+}
+
 mlir::Value getCoarrayHandle(fir::FirOpBuilder &builder, mlir::Location loc,
                              mlir::Value coarray) {
   mlir::Type handleTy = getCoarrayHandleType(builder, loc);
@@ -154,28 +186,6 @@ static int computeElementByteSize(mlir::Location loc, mlir::Type type,
   return 0;
 }
 
-static mlir::Value getLocalDataPointer(fir::FirOpBuilder &builder,
-                                       mlir::Location loc,
-                                       mlir::Value coarrayHandle) {
-  mlir::Type ptrTy = fir::PointerType::get(builder.getNoneType());
-  mlir::Type refTy = builder.getRefType(builder.getNoneType());
-  mlir::FunctionType ftype = mlir::FunctionType::get(builder.getContext(),
-                                                     /*inputs*/ {refTy, ptrTy},
-                                                     /*results*/ {});
-  // BIND(C) procedure
-  mlir::func::FuncOp funcOp =
-      builder.createFunction(loc, "_QMprifPprif_local_data_pointer", ftype);
-
-  mlir::Value localPtr = builder.createTemporary(loc, ptrTy);
-  mlir::Value nullPtr = fir::ZeroOp::create(builder, loc, ptrTy);
-  fir::StoreOp::create(builder, loc, nullPtr, localPtr);
-
-  llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
-      builder, loc, ftype, coarrayHandle, localPtr);
-  fir::CallOp::create(builder, loc, funcOp, args);
-  return fir::LoadOp::create(builder, loc, localPtr);
-}
-
 // Function used to compute the size in bytes of an entity. This function
 // is used during an allocation of a coarray (or a component of a coarray),
 // as it's a required argument in some PRIF procedures.
@@ -246,88 +256,64 @@ static mlir::Value getSizeInBytes(fir::FirOpBuilder &builder,
 /// Compute an offset in bytes from the beginning of the elements provided in
 /// "val". Basically, if it is not a memory access operation for an array such
 /// as fir::ArrayCoorOp or fir::CoordinateOp, then the element's offset is zero.
-static mlir::Value
-computeOffsetInBytes(fir::FirOpBuilder &builder, mlir::Location loc,
-                     mlir::ModuleOp module, mlir::DataLayout *dl,
-                     const fir::LLVMTypeConverter *typeConverter,
-                     mlir::Value val) {
-  fir::KindMapping kindMap{fir::getKindMapping(module)};
-  auto i64Ty = builder.getI64Type();
-  auto idxTy = builder.getIndexType();
-  auto zero = [&]() { return builder.createIntegerConstant(loc, i64Ty, 0); };
-  auto one = [&]() { return builder.createIntegerConstant(loc, i64Ty, 1); };
-
-  mlir::Operation *defOp = val.getDefiningOp();
+static mlir::Value computeOffsetInBytes(fir::FirOpBuilder &builder,
+                                        mlir::Location loc, mlir::Value box) {
+  mlir::Operation *defOp = box.getDefiningOp();
   if (mlir::isa<fir::ConvertOp, fir::EmboxOp>(defOp)) {
     llvm::TypeSwitch<mlir::Operation *>(defOp)
         .Case<fir::ConvertOp>(
-            [&](fir::ConvertOp convertOp) { val = convertOp.getValue(); })
+            [&](fir::ConvertOp convertOp) { box = convertOp.getValue(); })
         .Case<fir::EmboxOp>(
-            [&](fir::EmboxOp emboxOp) { val = emboxOp.getMemref(); })
+            [&](fir::EmboxOp emboxOp) { box = emboxOp.getMemref(); })
         .Default([](mlir::Operation *op) {});
-    return computeOffsetInBytes(builder, loc, module, dl, typeConverter, val);
+    return computeOffsetInBytes(builder, loc, box);
   }
 
-  if (auto coor = val.getDefiningOp<fir::ArrayCoorOp>()) {
-    mlir::Value base = computeOffsetInBytes(builder, loc, module, dl,
-                                            typeConverter, coor.getMemref());
-    mlir::Type eleTy = fir::unwrapSequenceType(
-        fir::unwrapPassByRefType(coor.getMemref().getType()));
-    mlir::Value offset = zero();
-
-    llvm::SmallVector<mlir::Value> extents;
-    llvm::SmallVector<mlir::Value> origins;
-    if (mlir::Value shape = coor.getShape()) {
-      if (auto shapeOp = shape.getDefiningOp<fir::ShapeOp>()) {
-        extents.append(shapeOp.getExtents().begin(),
-                       shapeOp.getExtents().end());
-      } else if (auto shapeShiftOp = shape.getDefiningOp<fir::ShapeShiftOp>()) {
-        auto pairs = shapeShiftOp.getPairs();
-        for (size_t i = 0; i < pairs.size(); i += 2) {
-          origins.push_back(pairs[i]);
-          extents.push_back(pairs[i + 1]);
-        }
-      } else if (auto shiftOp = shape.getDefiningOp<fir::ShiftOp>())
-        origins.assign(shiftOp.getOrigins().begin(),
-                       shiftOp.getOrigins().end());
-    }
-
-    mlir::Value currentStride = builder.createIntegerConstant(
-        loc, i64Ty,
-        computeElementByteSize(loc, eleTy, kindMap, dl, typeConverter));
-
-    auto indices = coor.getIndices();
-    for (auto [dim, idx] : llvm::enumerate(indices)) {
-      mlir::Value lb, stride;
-      if (dim < origins.size())
-        lb = builder.createConvert(loc, i64Ty, origins[dim]);
-      else
-        lb = one();
-
-      idx = builder.createConvert(loc, i64Ty, idx);
-      idx = mlir::arith::SubIOp::create(builder, loc, idx, lb);
-      if (mlir::isa<fir::BaseBoxType>(
-              fir::unwrapRefType(coor.getMemref().getType()))) {
-        auto dims = fir::BoxDimsOp::create(
-            builder, loc, idxTy, idxTy, idxTy, coor.getMemref(),
-            builder.createIntegerConstant(loc, idxTy, dim));
-        stride = builder.createConvert(loc, i64Ty, dims.getByteStride());
-      } else {
-        stride = currentStride;
-        if (dim < extents.size()) {
-          mlir::Value ext = builder.createConvert(loc, i64Ty, extents[dim]);
-          currentStride =
-              mlir::arith::MulIOp::create(builder, loc, currentStride, ext);
-        }
-      }
+  fir::SequenceType seqTy;
+  auto i64Ty = builder.getI64Type();
+  llvm::SmallVector<mlir::Value> subscripts;
+  if (auto arrayCoor = box.getDefiningOp<fir::ArrayCoorOp>()) {
+    subscripts = arrayCoor.getIndices();
+    seqTy = fir::unwrapUntilSeqType(arrayCoor.getMemref().getType());
+    box = arrayCoor.getMemref();
+  } else if (auto coordOf = box.getDefiningOp<fir::CoordinateOp>()) {
+    subscripts = coordOf.getCoor();
+    seqTy = fir::unwrapUntilSeqType(coordOf.getRef().getType());
+    box = coordOf.getRef();
+  } else {
+    return builder.createIntegerConstant(loc, i64Ty, 0);
+  }
+  if (auto boxOp = box.getDefiningOp<fir::BoxAddrOp>())
+    box = boxOp.getVal();
+  else
+    box = builder.createBox(loc, box);
+
+  if (!seqTy || seqTy.getDimension() == 0) {
+    assert(subscripts.empty() &&
+           "subscripts isn't empty, but this is a scalar");
+    return builder.createIntegerConstant(loc, i64Ty, 0);
+  }
+  assert(subscripts.size() == seqTy.getDimension() && "invalid subscripts.");
 
-      mlir::Value delta =
-          mlir::arith::MulIOp::create(builder, loc, idx, stride);
-      offset = mlir::arith::AddIOp::create(builder, loc, offset, delta);
-    }
-    return mlir::arith::AddIOp::create(builder, loc, base, offset);
+  auto idxTy = builder.getIndexType();
+  mlir::Value offset = builder.createIntegerConstant(loc, i64Ty, 0);
+  for (unsigned dim = 0, rank = seqTy.getDimension(); dim < rank; ++dim) {
+    mlir::Value dimIdx = builder.createIntegerConstant(loc, idxTy, dim);
+    auto dimInfo =
+        fir::BoxDimsOp::create(builder, loc, idxTy, idxTy, idxTy, box, dimIdx);
+    mlir::Value byteStride =
+        builder.createConvert(loc, i64Ty, dimInfo.getResult(2));
+
+    mlir::Value idx = builder.createConvert(loc, idxTy, subscripts[dim]);
+    mlir::Value based =
+        mlir::arith::SubIOp::create(builder, loc, idx, dimInfo.getResult(0));
+    based = builder.createConvert(loc, i64Ty, based);
+
+    mlir::Value term =
+        mlir::arith::MulIOp::create(builder, loc, based, byteStride);
+    offset = mlir::arith::AddIOp::create(builder, loc, offset, term);
   }
-  return zero();
+  return offset;
 }
 
 // Most PRIF functions take `errmsg` and `errmsg_alloc` as two optional
@@ -510,8 +496,9 @@ getInitialTeamIndex(fir::FirOpBuilder &builder, mlir::Location loc,
     // In iso_fortran_env.f90, INITIAL_TEAM is -2
     mlir::Value initialTeam =
         builder.createIntegerConstant(loc, builder.getI32Type(), -2);
-    mlir::Value team = getTeam(
-        builder, loc, builder.getRefType(builder.getNoneType()), initialTeam);
+    mlir::Type teamType = getBuiltinTeamType(builder, loc);
+    mlir::Value team =
+        getTeam(builder, loc, builder.getRefType(teamType), initialTeam);
     mlir::Value thisImage = builder.createTemporary(loc, i32Ty);
     mlir::FunctionType ftype = mlir::FunctionType::get(
         builder.getContext(),
@@ -1273,7 +1260,7 @@ struct MIFAllocCoarrayOpConversion
     mlir::Location loc = op.getLoc();
 
     mlir::Type i64Ty = builder.getI64Type();
-    mlir::Type ptrTy = fir::PointerType::get(builder.getNoneType());
+    mlir::Type ptrTy = getBuiltinCptrType(builder, loc);
     mlir::Type refTy = builder.getRefType(builder.getNoneType());
     mlir::Type errmsgTy = getPRIFErrmsgType(builder);
     mlir::Type coboundsTy = genBoxedSequenceType(i64Ty);
@@ -1286,7 +1273,7 @@ struct MIFAllocCoarrayOpConversion
     mlir::FunctionType ftype = mlir::FunctionType::get(
         builder.getContext(),
         /*inputs*/
-        {coboundsTy, coboundsTy, builder.getRefType(i64Ty), refTy, refTy, ptrTy,
+        {coboundsTy, coboundsTy, builder.getRefType(i64Ty), refTy, refTy, builder.getRefType(ptrTy),
          getPRIFStatType(builder), errmsgTy, errmsgTy},
         /*results*/ {});
     mlir::func::FuncOp funcOp =
@@ -1302,8 +1289,7 @@ struct MIFAllocCoarrayOpConversion
     mlir::Type handleTy = getCoarrayHandleType(builder, loc);
     mlir::Value coarrayHandle = builder.createTemporary(loc, handleTy);
 
-    mlir::Value allocMem =
-        fir::ConvertOp::create(builder, loc, ptrTy, op.getBox());
+    mlir::Value allocMem = builder.createTemporary(loc, ptrTy);
 
     mlir::Value sizeInBytes =
         getSizeInBytes(builder, loc, mod, dl, typeConverter, op.getBox());
@@ -1317,9 +1303,21 @@ struct MIFAllocCoarrayOpConversion
         builder, loc, ftype, op.getLcobounds(), op.getUcobounds(), sizeInBytes,
         finalFunc, coarrayHandle, allocMem, stat, errmsgArg, errmsgAllocArg);
     fir::CallOp callOp = fir::CallOp::create(builder, loc, funcOp, args);
-
     storeCoarrayHandle(builder, loc, coarrayHandle, op.getUniqName().str());
 
+    // Set new base_addr for the coarray descriptor
+    mlir::Value addrRef =
+        fir::factory::genCPtrOrCFunptrAddr(builder, loc, allocMem, ptrTy);
+    allocMem = fir::LoadOp::create(builder, loc, addrRef);
+    mlir::func::FuncOp sbaFunc =
+        fir::runtime::getRuntimeFunc<mkRTKey(AllocatableSetBaseAddr)>(loc,
+                                                                      builder);
+    llvm::SmallVector<mlir::Value> args2{fir::runtime::createArguments(
+        builder, loc, sbaFunc.getFunctionType(), op.getBox(), allocMem)};
+    fir::CallOp::create(builder, loc, sbaFunc, args2);
+    if (fir::isa_builtin_event_type(
+            fir::getFortranElementType(op.getBox().getType())))
+      fir::runtime::genDerivedTypeInitialize(builder, loc, op.getBox());
     rewriter.replaceOp(op, callOp);
     return mlir::success();
   }
@@ -1546,15 +1544,15 @@ struct MIFEventWaitOpConversion
     fir::FirOpBuilder builder(rewriter, mod);
     mlir::Location loc = op.getLoc();
 
-    mlir::Type ptrTy = fir::PointerType::get(builder.getNoneType());
+    mlir::Type ptrTy = getBuiltinCptrType(builder, loc);
     mlir::Type i64Ty = builder.getI64Type();
     mlir::Type errmsgTy = getPRIFErrmsgType(builder);
-    mlir::FunctionType ftype =
-        mlir::FunctionType::get(builder.getContext(),
-                                /*inputs*/
-                                {ptrTy, builder.getRefType(i64Ty),
-                                 getPRIFStatType(builder), errmsgTy, errmsgTy},
-                                /*results*/ {});
+    mlir::FunctionType ftype = mlir::FunctionType::get(
+        builder.getContext(),
+        /*inputs*/
+        {builder.getRefType(ptrTy), builder.getRefType(i64Ty),
+         getPRIFStatType(builder), errmsgTy, errmsgTy},
+        /*results*/ {});
     mlir::func::FuncOp funcOp =
         builder.createFunction(loc, getPRIFProcName("event_wait"), ftype);
 
@@ -1574,19 +1572,11 @@ struct MIFEventWaitOpConversion
     auto [errmsgArg, errmsgAllocArg] =
         genErrmsgPRIF(builder, loc, op.getErrmsg());
 
-    mlir::Value eventPtr = op.getEvent();
-    mlir::Type eventType = fir::unwrapRefType(op.getEvent().getType());
-    if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(eventType)) {
-      if (boxTy.isCoarray()) {
-        mlir::Value coarrayHandle = getCoarrayHandle(builder, loc, eventPtr);
-        eventPtr = getLocalDataPointer(builder, loc, coarrayHandle);
-      } else
-        eventPtr = fir::BoxAddrOp::create(builder, loc, ptrTy, eventPtr);
-    }
-
-    llvm::SmallVector<mlir::Value> args =
-        fir::runtime::createArguments(builder, loc, ftype, eventPtr, untilCount,
-                                      stat, errmsgArg, errmsgAllocArg);
+    mlir::Value cptrEvent =
+        convertRefTypeToCPtrType(builder, loc, op.getEvent());
+    llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+        builder, loc, ftype, cptrEvent, untilCount, stat, errmsgArg,
+        errmsgAllocArg);
     fir::CallOp callOp = fir::CallOp::create(builder, loc, funcOp, args);
     rewriter.replaceOp(op, callOp);
     return mlir::success();
@@ -1598,10 +1588,6 @@ struct MIFEventPostOpConversion
     : public mlir::OpRewritePattern<mif::EventPostOp> {
   using OpRewritePattern::OpRewritePattern;
 
-  MIFEventPostOpConversion(mlir::MLIRContext *context, mlir::DataLayout *dl,
-                           const fir::LLVMTypeConverter *typeConverter)
-      : OpRewritePattern(context), dl{dl}, typeConverter{typeConverter} {}
-
   mlir::LogicalResult
   matchAndRewrite(mif::EventPostOp op,
                   mlir::PatternRewriter &rewriter) const override {
@@ -1640,8 +1626,8 @@ struct MIFEventPostOpConversion
           builder.createFunction(loc, getPRIFProcName("event_post"), ftype);
 
       mlir::Value offset = builder.createTemporary(loc, i64Ty);
-      mlir::Value offset_val = computeOffsetInBytes(
-          builder, loc, mod, dl, typeConverter, op.getEvent());
+      mlir::Value offset_val =
+          computeOffsetInBytes(builder, loc, op.getEvent());
       fir::StoreOp::create(builder, loc, offset_val, offset);
       mlir::Value coarrayHandle = getCoarrayHandle(builder, loc, op.getEvent());
       mlir::Value imageNum = getInitialTeamIndex(builder, loc, coarrayHandle,
@@ -1657,10 +1643,6 @@ struct MIFEventPostOpConversion
     rewriter.replaceOp(op, callOp);
     return mlir::success();
   }
-
-private:
-  mlir::DataLayout *dl;
-  const fir::LLVMTypeConverter *typeConverter;
 };
 
 static void genCoarrayHandle(fir::FirOpBuilder &builder, mlir::ModuleOp mod,
@@ -1736,17 +1718,18 @@ class MIFOpConversion : public fir::impl::MIFOpConversionBase<MIFOpConversion> {
 void mif::populateMIFOpConversionPatterns(
     const fir::LLVMTypeConverter &converter, mlir::DataLayout &dl,
     mlir::RewritePatternSet &patterns) {
-  patterns.insert<MIFAllocCoarrayOpConversion, MIFEventPostOpConversion>(
-      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, MIFEventWaitOpConversion>(
+  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,
+                  MIFEventPostOpConversion, MIFEventWaitOpConversion>(
       patterns.getContext());
 }
diff --git a/flang/test/Fir/MIF/coarray-alloc.mlir b/flang/test/Fir/MIF/coarray-alloc.mlir
index c32f80c8866b49..0c0ebb0a53bb78 100644
--- a/flang/test/Fir/MIF/coarray-alloc.mlir
+++ b/flang/test/Fir/MIF/coarray-alloc.mlir
@@ -58,7 +58,7 @@ func.func @_QQmain() attributes {fir.bindc_name = "ALLOC_TEST"} {
   fir.store %c2_i64 to %31 : !fir.ref<i64>
   %32 = fir.embox %12 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
   mif.alloc_coarray %27 lcobounds %30 ucobounds %32 {uniq_name = "_QFEa"} : (!fir.ref<i32>, !fir.box<!fir.array<2xi64>>, !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.ref<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+// CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
   %33 = fir.declare %27 {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> !fir.ref<i32>
   %34 = fir.address_of(@_QFEa2) : !fir.ref<!fir.box<!fir.heap<i32>, corank:2>>
   %35 = fir.declare %34 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEa2"} : (!fir.ref<!fir.box<!fir.heap<i32>, corank:2>>) -> !fir.ref<!fir.box<!fir.heap<i32>, corank:2>>
@@ -76,7 +76,7 @@ func.func @_QQmain() attributes {fir.bindc_name = "ALLOC_TEST"} {
   fir.store %c5_i64 to %42 : !fir.ref<i64>
   %43 = fir.embox %10 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
   mif.alloc_coarray %36 lcobounds %40 ucobounds %43 {uniq_name = "_QFEb"} : (!fir.ref<f32>, !fir.box<!fir.array<3xi64>>, !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.ref<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+// CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
   %44 = fir.declare %36 {uniq_name = "_QFEb"} : (!fir.ref<f32>) -> !fir.ref<f32>
   %45 = fir.address_of(@_QFEb2) : !fir.ref<!fir.box<!fir.heap<f32>, corank:3>>
   %46 = fir.declare %45 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEb2"} : (!fir.ref<!fir.box<!fir.heap<f32>, corank:3>>) -> !fir.ref<!fir.box<!fir.heap<f32>, corank:3>>
@@ -86,7 +86,7 @@ func.func @_QQmain() attributes {fir.bindc_name = "ALLOC_TEST"} {
   %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>>
   mif.alloc_coarray %47 lcobounds %49 ucobounds %50 {uniq_name = "_QFEc"} : (!fir.ref<!fir.char<1,10>>, !fir.box<!fir.array<1xi64>>, !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.ref<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+// CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
   %51 = fir.declare %47 typeparams %c10 {uniq_name = "_QFEc"} : (!fir.ref<!fir.char<1,10>>, index) -> !fir.ref<!fir.char<1,10>>
   %52 = fir.address_of(@_QFEc2) : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>, corank:1>>
   %53 = fir.declare %52 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEc2"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>, corank:1>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>, corank:1>>
@@ -115,7 +115,7 @@ func.func @_QQmain() attributes {fir.bindc_name = "ALLOC_TEST"} {
   %73 = fir.embox %7 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
   %74 = fir.embox %6 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
   mif.alloc_coarray %35 lcobounds %73 ucobounds %74 errmsg %68 {uniq_name = "_QFEa2"} : (!fir.ref<!fir.box<!fir.heap<i32>, corank:2>>, !fir.box<!fir.array<2xi64>>, !fir.box<!fir.array<1xi64>>, !fir.box<none>) -> ()
-// CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+// CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
   %75 = fir.absent !fir.box<none>
   %76 = fir.convert %c3_i32 : (i32) -> i64
   %77 = fir.convert %c4_i32 : (i32) -> i64
@@ -133,7 +133,7 @@ func.func @_QQmain() attributes {fir.bindc_name = "ALLOC_TEST"} {
   %84 = fir.embox %5 : (!fir.ref<!fir.array<3xi64>>) -> !fir.box<!fir.array<3xi64>>
   %85 = fir.embox %4 : (!fir.ref<!fir.array<2xi64>>) -> !fir.box<!fir.array<2xi64>>
   mif.alloc_coarray %46 lcobounds %84 ucobounds %85 errmsg %75 {uniq_name = "_QFEb2"} : (!fir.ref<!fir.box<!fir.heap<f32>, corank:3>>, !fir.box<!fir.array<3xi64>>, !fir.box<!fir.array<2xi64>>, !fir.box<none>) -> ()
-// CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+// CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
   %86 = fir.absent !fir.box<none>
   %87 = fir.convert %53 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>, corank:1>>) -> !fir.ref<!fir.box<none>>
   %88 = fir.convert %c100_i32 : (i32) -> i64
@@ -147,7 +147,7 @@ func.func @_QQmain() attributes {fir.bindc_name = "ALLOC_TEST"} {
   %93 = fir.embox %3 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
   %94 = fir.embox %2 : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
   mif.alloc_coarray %53 lcobounds %93 ucobounds %94 errmsg %86 {uniq_name = "_QFEc2"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>, corank:1>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>, !fir.box<none>) -> ()
-// CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+// CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
   %95 = fir.absent !fir.box<none>
   %96 = fir.field_index z, !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>, corank:1>}>}>
   %97 = fir.coordinate_of %55, 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>, corank:1>}>}>>) -> !fir.ref<!fir.type<_QFTmy_type2{co:!fir.box<!fir.heap<i32>, corank:1>}>>
@@ -158,7 +158,7 @@ func.func @_QQmain() attributes {fir.bindc_name = "ALLOC_TEST"} {
   %101 = fir.embox %1 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
   %102 = fir.embox %0 : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
   mif.alloc_coarray %99 lcobounds %101 ucobounds %102 errmsg %95 {uniq_name = "_QFEd.z.co"} : (!fir.ref<!fir.box<!fir.heap<i32>, corank:1>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>, !fir.box<none>) -> ()
-// CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+// CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
   %103 = fir.absent !fir.box<none>
   %104 = fir.absent !fir.ref<i32>
   mif.dealloc_coarray %35 stat %104 errmsg %103 : (!fir.ref<!fir.box<!fir.heap<i32>, corank:2>>, !fir.ref<i32>, !fir.box<none>) -> ()
@@ -215,7 +215,7 @@ func.func @_QPtest_alloc2() {
   %20 = fir.embox %4 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
   %21 = fir.embox %3 : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
   mif.alloc_coarray %9 lcobounds %20 ucobounds %21 errmsg %16 {uniq_name = "_QFtest_alloc2Ea"} : (!fir.ref<!fir.class<!fir.heap<none>, corank:1>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>, !fir.box<none>) -> ()
-// CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+// CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
   %22 = fir.absent !fir.box<none>
   %23 = fir.convert %13 : (!fir.ref<!fir.class<!fir.heap<none>, corank:1>>) -> !fir.ref<!fir.box<none>>
   fir.call @_FortranAAllocatableInitIntrinsicForAllocate(%23, %c2_i32, %c4_i32, %c0_i32, %c0_i32) fastmath<contract> : (!fir.ref<!fir.box<none>>, i32, i32, i32, i32) -> ()
@@ -224,7 +224,7 @@ func.func @_QPtest_alloc2() {
   fir.store %24 to %25 : !fir.ref<i64>
   %26 = fir.embox %1 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
   %27 = 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.ref<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+// CHECK: fir.call @_QMprifPprif_allocate_coarray({{.*}}) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
   mif.alloc_coarray %13 lcobounds %26 ucobounds %27 stat %2 errmsg %22 {uniq_name = "_QFtest_alloc2Eb"} : (!fir.ref<!fir.class<!fir.heap<none>, corank:1>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>, !fir.ref<i32>, !fir.box<none>) -> ()
   %28 = fir.convert %2 : (!fir.ref<i32>) -> i32
   fir.store %28 to %15 : !fir.ref<i32>
diff --git a/flang/test/Fir/MIF/coarray_alloc_many_declare.mlir b/flang/test/Fir/MIF/coarray_alloc_many_declare.mlir
index 05d12b48be8fb7..7e7949ff51935a 100644
--- a/flang/test/Fir/MIF/coarray_alloc_many_declare.mlir
+++ b/flang/test/Fir/MIF/coarray_alloc_many_declare.mlir
@@ -37,7 +37,8 @@ fir.global internal @_QFEa : !fir.box<!fir.heap<i32>, corank:1> {
 
 //CHECK-LABEL: @_QQmain
 //CHECK-NEXT:  %[[VAL_0:.*]] = fir.alloca i64
-//CHECK-NEXT:  %[[VAL_1:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__c_ptr_c_address:i64}>}>
+//CHECK-NEXT:  %[[VAL_C_PTR:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+//CHECK-NEXT:  %[[VAL_1:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>
 //CHECK-NEXT:  %[[VAL_2:.*]] = fir.alloca !fir.boxproc<(!fir.ref<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>) -> ()>
 //CHECK-NEXT:  %[[VAL_3:.*]] = fir.alloca !fir.array<0xi64>
 //CHECK-NEXT:  %[[VAL_4:.*]] = fir.alloca !fir.array<1xi64>
@@ -54,7 +55,6 @@ fir.global internal @_QFEa : !fir.box<!fir.heap<i32>, corank:1> {
 //CHECK-NEXT:  %[[VAL_12:.*]] = fir.zero_bits (!fir.ref<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>) -> ()
 //CHECK-NEXT:  %[[VAL_13:.*]] = fir.emboxproc %[[VAL_12]] : ((!fir.ref<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>) -> ()) -> !fir.boxproc<(!fir.ref<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>) -> ()>
 //CHECK-NEXT:  fir.store %[[VAL_13]] to %[[VAL_2]] : !fir.ref<!fir.boxproc<(!fir.ref<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>) -> ()>>
-//CHECK-NEXT:  %[[VAL_14:.*]] = fir.convert %[[VAL_7]]#0 : (!fir.ref<!fir.box<!fir.heap<i32>, corank:1>>) -> !fir.ptr<none>
 //CHECK-NEXT:  %[[VAL_15:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.heap<i32>, corank:1>>
 //CHECK-NEXT:  %[[VAL_16:.*]] = fir.box_elesize %[[VAL_15]] : (!fir.box<!fir.heap<i32>, corank:1>) -> i64
 //CHECK-NEXT:  fir.store %[[VAL_16]] to %[[VAL_0]] : !fir.ref<i64>
@@ -63,11 +63,17 @@ fir.global internal @_QFEa : !fir.box<!fir.heap<i32>, corank:1> {
 //CHECK-NEXT:  %[[VAL_19:.*]] = fir.convert %[[VAL_10]] : (!fir.box<!fir.array<1xi64>>) -> !fir.box<!fir.array<?xi64>>
 //CHECK-NEXT:  %[[VAL_20:.*]] = fir.convert %[[VAL_11]] : (!fir.box<!fir.array<0xi64>>) -> !fir.box<!fir.array<?xi64>>
 //CHECK-NEXT:  %[[VAL_21:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.boxproc<(!fir.ref<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>) -> ()>>) -> !fir.ref<none>
-//CHECK-NEXT:  %[[VAL_22:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__c_ptr_c_address:i64}>}>>) -> !fir.ref<none>
+//CHECK-NEXT:  %[[VAL_22:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>) -> !fir.ref<none>
 //CHECK-NEXT:  %[[VAL_23:.*]] = fir.convert %[[VAL_8]] : (!fir.box<none>) -> !fir.box<!fir.char<1,?>>
-//CHECK-NEXT:  fir.call @_QMprifPprif_allocate_coarray(%[[VAL_19]], %[[VAL_20]], %[[VAL_0]], %[[VAL_21]], %[[VAL_22]], %[[VAL_14]], %[[VAL_17]], %[[VAL_23]], %[[VAL_18]]) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ptr<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
-//CHECK-NEXT:  %[[VAL_24:.*]] = fir.address_of(@_QFEa_coarray_handle) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__c_ptr_c_address:i64}>}>>
-//CHECK-NEXT:  fir.copy %[[VAL_1]] to %[[VAL_24]] : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__c_ptr_c_address:i64}>}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__c_ptr_c_address:i64}>}>>
+//CHECK-NEXT:  fir.call @_QMprifPprif_allocate_coarray(%[[VAL_19]], %[[VAL_20]], %[[VAL_0]], %[[VAL_21]], %[[VAL_22]], %[[VAL_C_PTR]], %[[VAL_17]], %[[VAL_23]], %[[VAL_18]]) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+//CHECK-NEXT:  %[[VAL_24:.*]] = fir.address_of(@_QFEa_coarray_handle) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>
+//CHECK-NEXT:  fir.copy %[[VAL_1]] to %[[VAL_24]] : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>
+//CHECK-NEXT:  %[[VAL_25:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+//CHECK-NEXT:   %[[VAL_26:.*]] = fir.coordinate_of %[[VAL_C_PTR]], __address : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> !fir.ref<i64>
+//CHECK-NEXT:   %[[VAL_27:.*]] = fir.load %[[VAL_26]] : !fir.ref<i64>
+//CHECK-NEXT:   %[[VAL_28:.*]] = fir.convert %[[VAL_7]]#0 : (!fir.ref<!fir.box<!fir.heap<i32>, corank:1>>) -> !fir.ref<!fir.box<none>>
+//CHECK-NEXT:   %[[VAL_29:.*]] = fir.convert %[[VAL_27]] : (i64) -> !fir.llvm_ptr<i8>
+//CHECK-NEXT:   fir.call @_FortranAAllocatableSetBaseAddr(%[[VAL_28]], %[[VAL_29]]) : (!fir.ref<!fir.box<none>>, !fir.llvm_ptr<i8>) -> ()
 //CHECK-NEXT:  fir.call @_QFPinner() fastmath<contract> : () -> ()
 
 //CHECK-LABEL: func.func private @_QFPinner() attributes {fir.host_symbol = @_QQmain, llvm.linkage = #llvm.linkage<internal>}
@@ -77,6 +83,6 @@ fir.global internal @_QFEa : !fir.box<!fir.heap<i32>, corank:1> {
 //CHECK-NEXT:  %c1_i32 = arith.constant 1 : i32
 //CHECK-NEXT:  hlfir.assign %c1_i32 to %[[VAL_2]]#0 realloc : i32, !fir.ref<!fir.box<!fir.heap<i32>, corank:1>>
 
-//CHECK-LABEL:  fir.global linkonce @_QFEa_coarray_handle : !fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__c_ptr_c_address:i64}>}>
-//CHECK:    %[[VAL_0:.*]] = fir.zero_bits !fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__c_ptr_c_address:i64}>}>
-//CHECK-NEXT:    fir.has_value %[[VAL_0]] : !fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__c_ptr_c_address:i64}>}>
+//CHECK-LABEL:  fir.global linkonce @_QFEa_coarray_handle : !fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>
+//CHECK:        %[[VAL_0]] = fir.zero_bits !fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>
+//CHECK-NEXT:   fir.has_value %[[VAL_0]] : !fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>
diff --git a/flang/test/Fir/MIF/events.mlir b/flang/test/Fir/MIF/events.mlir
index 91132a8b0a2934..ef5b81392a8e20 100644
--- a/flang/test/Fir/MIF/events.mlir
+++ b/flang/test/Fir/MIF/events.mlir
@@ -1,44 +1,108 @@
 // RUN: fir-opt --mif-convert %s | FileCheck %s
 
 func.func @_QQmain() attributes {fir.bindc_name = "EVENT_TEST"} {
-  %0 = fir.alloca !fir.array<0xi64>
-  %1 = fir.alloca !fir.array<1xi64>
-  %2 = fir.dummy_scope : !fir.dscope
-  %3 = fir.address_of(@_QFEdata_ready) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>
-  %c1_i64 = arith.constant 1 : i64
-  %c0 = arith.constant 0 : index
-  %4 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
-  fir.store %c1_i64 to %4 : !fir.ref<i64>
-  %5 = fir.embox %1 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
-  %6 = fir.embox %0 : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
-  mif.alloc_coarray %3 lcobounds %5 ucobounds %6 {uniq_name = "_QFEdata_ready"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
-  %7:2 = hlfir.declare %3 {uniq_name = "_QFEdata_ready"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>) -> (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>)
-  %8 = fir.alloca i32 {bindc_name = "me", uniq_name = "_QFEme"}
-  %9:2 = hlfir.declare %8 {uniq_name = "_QFEme"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-  %10 = mif.this_image : () -> i32
-  hlfir.assign %10 to %9#0 : i32, !fir.ref<i32>
-  %11 = fir.load %9#0 : !fir.ref<i32>
-  %c2_i32 = arith.constant 2 : i32
-  %12 = arith.cmpi eq, %11, %c2_i32 : i32
-  fir.if %12 {
-    %13 = hlfir.designate %7#0   : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>
-    %14 = fir.embox %13 : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>) -> !fir.box<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>, corank:1>
-    %c1_i64_0 = arith.constant 1 : i64
-    mif.event_post %14[%c1_i64_0] : (!fir.box<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>, corank:1>, i64) -> ()
-  } else {
-    %13 = fir.load %9#0 : !fir.ref<i32>
-    %c1_i32 = arith.constant 1 : i32
-    %14 = arith.cmpi eq, %13, %c1_i32 : i32
-    fir.if %14 {
-      %c1_i32_0 = arith.constant 1 : i32
-      mif.event_wait %7#0 until_count %c1_i32_0 : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, i32) -> ()
+    %0 = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+    %1 = fir.alloca i64
+    %2 = fir.alloca !fir.array<1xi64>
+    %3 = fir.alloca i32
+    %4 = fir.alloca i64
+    %5 = fir.alloca i32
+    %6 = fir.alloca i64
+    %7 = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+    %8 = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>
+    %9 = fir.alloca !fir.boxproc<(!fir.ref<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>) -> ()>
+    %10 = fir.alloca !fir.array<0xi64>
+    %11 = fir.alloca !fir.array<1xi64>
+    %12 = fir.dummy_scope : !fir.dscope
+    %13 = fir.address_of(@_QFEdata_ready) : !fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, corank:1>>
+    %c1_i64 = arith.constant 1 : i64
+    %c0 = arith.constant 0 : index
+    %14 = fir.coordinate_of %11, %c0 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
+    fir.store %c1_i64 to %14 : !fir.ref<i64>
+    %15 = fir.embox %11 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
+    %16 = fir.embox %10 : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
+    %17 = fir.zero_bits (!fir.ref<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>) -> ()
+    %18 = fir.emboxproc %17 : ((!fir.ref<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>) -> ()) -> !fir.boxproc<(!fir.ref<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>) -> ()>
+    fir.store %18 to %9 : !fir.ref<!fir.boxproc<(!fir.ref<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>) -> ()>>
+    %19 = fir.load %13 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, corank:1>>
+    %20 = fir.box_elesize %19 : (!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, corank:1>) -> i64
+    fir.store %20 to %6 : !fir.ref<i64>
+    %21 = fir.absent !fir.ref<i32>
+    %22 = fir.absent !fir.box<!fir.char<1,?>>
+    %23 = fir.convert %15 : (!fir.box<!fir.array<1xi64>>) -> !fir.box<!fir.array<?xi64>>
+    %24 = fir.convert %16 : (!fir.box<!fir.array<0xi64>>) -> !fir.box<!fir.array<?xi64>>
+    %25 = fir.convert %9 : (!fir.ref<!fir.boxproc<(!fir.ref<none>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>) -> ()>>) -> !fir.ref<none>
+    %26 = fir.convert %8 : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>) -> !fir.ref<none>
+    fir.call @_QMprifPprif_allocate_coarray(%23, %24, %6, %25, %26, %7, %21, %22, %22) : (!fir.box<!fir.array<?xi64>>, !fir.box<!fir.array<?xi64>>, !fir.ref<i64>, !fir.ref<none>, !fir.ref<none>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+    %27 = fir.address_of(@_QFEdata_ready_coarray_handle) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>
+    fir.copy %8 to %27 : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>
+    %28 = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+    %29 = fir.coordinate_of %7, __address : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> !fir.ref<i64>
+    %30 = fir.load %29 : !fir.ref<i64>
+    %31 = fir.convert %13 : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, corank:1>>) -> !fir.ref<!fir.box<none>>
+    %32 = fir.convert %30 : (i64) -> !fir.llvm_ptr<i8>
+    fir.call @_FortranAAllocatableSetBaseAddr(%31, %32) : (!fir.ref<!fir.box<none>>, !fir.llvm_ptr<i8>) -> ()
+    %33 = fir.address_of(@_QQclX746573742E6D6C697200) : !fir.ref<!fir.char<1,10>>
+    %c10 = arith.constant 10 : index
+    %c13_i32 = arith.constant 13 : i32
+    %34 = fir.convert %13 : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, corank:1>>) -> !fir.box<none>
+    %35 = fir.convert %33 : (!fir.ref<!fir.char<1,10>>) -> !fir.ref<i8>
+    fir.call @_FortranAInitialize(%34, %35, %c13_i32) : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
+    %36:2 = hlfir.declare %13 {uniq_name = "_QFEdata_ready"} : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, corank:1>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, corank:1>>, !fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, corank:1>>)
+    %37 = fir.alloca i32 {bindc_name = "me", uniq_name = "_QFEme"}
+    %38:2 = hlfir.declare %37 {uniq_name = "_QFEme"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    %39 = fir.absent !fir.ref<none>
+    fir.call @_QMprifPprif_this_image_no_coarray(%39, %5) : (!fir.ref<none>, !fir.ref<i32>) -> ()
+    %40 = fir.load %5 : !fir.ref<i32>
+    hlfir.assign %40 to %38#0 : i32, !fir.ref<i32>
+    %41 = fir.load %38#0 : !fir.ref<i32>
+    %c2_i32 = arith.constant 2 : i32
+    %42 = arith.cmpi eq, %41, %c2_i32 : i32
+    fir.if %42 {
+      %43 = fir.load %36#0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, corank:1>>
+      %44 = fir.box_addr %43 : (!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, corank:1>) -> !fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>
+      %45 = hlfir.designate %44   : (!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>
+      %46 = fir.embox %45 : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>) -> !fir.box<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>, corank:1>
+      %c1_i64_0 = arith.constant 1 : i64
+      %47 = fir.absent !fir.ref<i32>
+      %48 = fir.absent !fir.box<!fir.char<1,?>>
+      %c0_i64 = arith.constant 0 : i64
+      fir.store %c0_i64 to %4 : !fir.ref<i64>
+      %49 = fir.address_of(@_QFEdata_ready_coarray_handle) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>
+      %c0_1 = arith.constant 0 : index
+      %50 = fir.coordinate_of %2, %c0_1 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
+      fir.store %c1_i64_0 to %50 : !fir.ref<i64>
+      %51 = fir.embox %2 : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
+      %52 = fir.absent !fir.ref<i32>
+      %53 = fir.convert %49 : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>) -> !fir.ref<none>
+      %54 = fir.convert %51 : (!fir.box<!fir.array<1xi64>>) -> !fir.box<!fir.array<?xi64>>
+      fir.call @_QMprifPprif_initial_team_index(%53, %54, %3, %52) : (!fir.ref<none>, !fir.box<!fir.array<?xi64>>, !fir.ref<i32>, !fir.ref<i32>) -> ()
+      %55 = fir.convert %49 : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{info:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>) -> !fir.ref<none>
+      fir.call @_QMprifPprif_event_post(%3, %55, %4, %47, %48, %48) : (!fir.ref<i32>, !fir.ref<none>, !fir.ref<i64>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+    } else {
+      %43 = fir.load %38#0 : !fir.ref<i32>
+      %c1_i32 = arith.constant 1 : i32
+      %44 = arith.cmpi eq, %43, %c1_i32 : i32
+      fir.if %44 {
+        %c1_i32_0 = arith.constant 1 : i32
+        %45 = fir.load %36#0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, corank:1>>
+        %46 = fir.box_addr %45 : (!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>, corank:1>) -> !fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>
+        %47 = fir.convert %c1_i32_0 : (i32) -> i64
+        fir.store %47 to %1 : !fir.ref<i64>
+        %48 = fir.absent !fir.ref<i32>
+        %49 = fir.absent !fir.box<!fir.char<1,?>>
+        %50 = fir.convert %46 : (!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}>>) -> i64
+        %51 = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+        %52 = fir.coordinate_of %0, __address : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> !fir.ref<i64>
+        fir.store %50 to %52 : !fir.ref<i64>
+        fir.call @_QMprifPprif_event_wait(%0, %1, %48, %49, %49) : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<i64>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+      }
     }
-  }
-  return
+    return
 }
 
 // CHECK: fir.call @_QMprifPprif_initial_team_index(
 // CHECK: fir.call @_QMprifPprif_event_post(%[[IMAGE_INDEX:.*]], %[[EVENT_PTR:.*]], %[[OFFSET:.*]], %[[STAT:.*]], %[[ERRMSG:.*]], %[[ERRMSG2:.*]]) : (!fir.ref<i32>, !fir.ref<none>, !fir.ref<i64>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
 
 
-// CHECK: fir.call @_QMprifPprif_event_wait(%[[EVENT_PTR:.*]], %[[UNTIL_COUNT:.*]], %[[STAT:.*]], %[[ERRMSG:.*]], %[[ERRMSG2:.*]]) : (!fir.ptr<none>, !fir.ref<i64>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+// CHECK: fir.call @_QMprifPprif_event_wait(%[[EVENT_PTR:.*]], %[[UNTIL_COUNT:.*]], %[[STAT:.*]], %[[ERRMSG:.*]], %[[ERRMSG2:.*]]) : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<i64>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
diff --git a/flang/test/Lower/MIF/events.f90 b/flang/test/Lower/MIF/events.f90
index 9ebf1130730aeb..0a32570ab8fe1f 100644
--- a/flang/test/Lower/MIF/events.f90
+++ b/flang/test/Lower/MIF/events.f90
@@ -23,15 +23,15 @@ program event_test
 ! COARRAY: %[[VAL_0:.*]] = fir.alloca !fir.array<0xi64>
 ! COARRAY: %[[VAL_1:.*]] = fir.alloca !fir.array<1xi64>
 ! COARRAY: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
-! COARRAY: %[[VAL_3:.*]] = fir.address_of(@_QFEdata_ready) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>
+! COARRAY: %[[VAL_3:.*]] = fir.address_of(@_QFEdata_ready) : !fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, corank:1>>
 ! COARRAY: %c1_i64 = arith.constant 1 : i64
 ! COARRAY: %c0 = arith.constant 0 : index
 ! COARRAY: %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_1]], %c0 : (!fir.ref<!fir.array<1xi64>>, index) -> !fir.ref<i64>
 ! COARRAY: fir.store %c1_i64 to %[[VAL_4]] : !fir.ref<i64>
 ! COARRAY: %[[VAL_5:.*]] = fir.embox %[[VAL_1]] : (!fir.ref<!fir.array<1xi64>>) -> !fir.box<!fir.array<1xi64>>
 ! COARRAY: %[[VAL_6:.*]] = fir.embox %[[VAL_0]] : (!fir.ref<!fir.array<0xi64>>) -> !fir.box<!fir.array<0xi64>>
-! COARRAY: mif.alloc_coarray %[[VAL_3]] lcobounds %[[VAL_5]] ucobounds %[[VAL_6]] {uniq_name = "_QFEdata_ready"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
-! COARRAY: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_3]] {uniq_name = "_QFEdata_ready"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>) -> (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>)
+! COARRAY: mif.alloc_coarray %[[VAL_3]] lcobounds %[[VAL_5]] ucobounds %[[VAL_6]] {uniq_name = "_QFEdata_ready"} : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, corank:1>>, !fir.box<!fir.array<1xi64>>, !fir.box<!fir.array<0xi64>>) -> ()
+! COARRAY: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_3]] {uniq_name = "_QFEdata_ready"} : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, corank:1>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, corank:1>>, !fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, corank:1>>)
 ! COARRAY: %[[VAL_8:.*]] = fir.alloca i32 {bindc_name = "me", uniq_name = "_QFEme"}
 ! COARRAY: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_8]] {uniq_name = "_QFEme"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
 ! COARRAY: %[[VAL_10:.*]] = mif.this_image : () -> i32
@@ -40,17 +40,21 @@ program event_test
 ! COARRAY: %c2_i32 = arith.constant 2 : i32
 ! COARRAY: %[[VAL_12:.*]] = arith.cmpi eq, %[[VAL_11]], %c2_i32 : i32
 ! COARRAY: fir.if %[[VAL_12]] {
-! COARRAY:   %[[VAL_13:.*]] = hlfir.designate %[[VAL_7]]#0   : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>
-! COARRAY:   %[[VAL_14:.*]] = fir.embox %[[VAL_13]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>) -> !fir.box<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>, corank:1>
+! COARRAY:   %[[VAL_13:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, corank:1>>
+! COARRAY:   %[[VAL_14:.*]] = fir.box_addr %[[VAL_13]] : (!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, corank:1>) -> !fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>
+! COARRAY:   %[[VAL_15:.*]] = hlfir.designate %[[VAL_14]]   : (!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>
+! COARRAY:   %[[VAL_16:.*]] = fir.embox %[[VAL_15]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>) -> !fir.box<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>, corank:1>
 ! COARRAY:   %c1_i64_0 = arith.constant 1 : i64
-! COARRAY:   mif.event_post %[[VAL_14]][%c1_i64_0] : (!fir.box<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>, corank:1>, i64) -> ()
+! COARRAY:   mif.event_post %[[VAL_16:.*]][%c1_i64_0] : (!fir.box<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>, corank:1>, i64) -> ()
 ! COARRAY: } else {
 ! COARRAY:   %[[VAL_15:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref<i32>
 ! COARRAY:   %c1_i32 = arith.constant 1 : i32
 ! COARRAY:   %[[VAL_16:.*]] = arith.cmpi eq, %[[VAL_15]], %c1_i32 : i32
 ! COARRAY:   fir.if %[[VAL_16]] {
 ! COARRAY:     %c1_i32_0 = arith.constant 1 : i32
-! COARRAY:     mif.event_wait %[[VAL_7]]#0 until_count %c1_i32_0 : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, i32) -> ()
+! COARRAY:     %15 = fir.load %7#0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, corank:1>>
+! COARRAY:     %16 = fir.box_addr %15 : (!fir.box<!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, corank:1>) -> !fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>
+! COARRAY:     mif.event_wait %16 until_count %c1_i32_0 : (!fir.heap<!fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}>>, i32) -> ()
 ! COARRAY:   }
 ! COARRAY: }
 ! COARRAY: return

>From a428ceb6fac836559a166b0c3d495935dfc13f36 Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Fri, 18 Sep 2026 09:25:07 +0200
Subject: [PATCH 7/7] Cleanup dump + format

---
 flang/lib/Lower/Bridge.cpp                         |  2 --
 flang/lib/Optimizer/Transforms/MIFOpConversion.cpp | 10 ++++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 1e02436c174c62..79fdaa26dff5ac 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -840,7 +840,6 @@ class FirConverter : public Fortran::lower::AbstractConverter {
                                  bool allowCoarray = false) override final {
     mlir::Location loc = locPtr ? *locPtr : toLocation();
     auto coarrayRef = Fortran::evaluate::ExtractCoarrayRef(expr);
-    expr.dump();
     if (coarrayRef.has_value() && !allowCoarray)
       TODO(loc, "coarray: genExprAddr of coarray reference.");
     return Fortran::lower::convertExprToAddress(loc, *this, expr, localSymbols,
@@ -864,7 +863,6 @@ class FirConverter : public Fortran::lower::AbstractConverter {
                                 Fortran::lower::StatementContext &stmtCtx,
                                 bool allowCoarray = false) override final {
     auto coarrayRef = Fortran::evaluate::ExtractCoarrayRef(expr);
-    expr.dump();
     if (coarrayRef.has_value() && !allowCoarray)
       TODO(loc, "coarray: genExprBox of coarray reference.");
     return Fortran::lower::convertExprToBox(loc, *this, expr, localSymbols,
diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
index 13a33ec9186596..a1b6b0c9f5f853 100644
--- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
@@ -77,12 +77,13 @@ static mlir::Type getBuiltinTeamType(fir::FirOpBuilder &builder,
 }
 
 static mlir::Type getBuiltinCptrType(fir::FirOpBuilder &builder,
-                                       mlir::Location loc) {
+                                     mlir::Location loc) {
   std::string cPtrTypeName = fir::NameUniquer::doType(
       {"__fortran_builtins"}, {}, 0, "__builtin_c_ptr", {});
   fir::RecordType cPtrType =
       fir::RecordType::get(builder.getContext(), cPtrTypeName);
-  cPtrType.finalize({}, {{Fortran::lower::builtin::cptrFieldName, builder.getI64Type()}});
+  cPtrType.finalize(
+      {}, {{Fortran::lower::builtin::cptrFieldName, builder.getI64Type()}});
   return cPtrType;
 }
 
@@ -1273,8 +1274,9 @@ struct MIFAllocCoarrayOpConversion
     mlir::FunctionType ftype = mlir::FunctionType::get(
         builder.getContext(),
         /*inputs*/
-        {coboundsTy, coboundsTy, builder.getRefType(i64Ty), refTy, refTy, builder.getRefType(ptrTy),
-         getPRIFStatType(builder), errmsgTy, errmsgTy},
+        {coboundsTy, coboundsTy, builder.getRefType(i64Ty), refTy, refTy,
+         builder.getRefType(ptrTy), getPRIFStatType(builder), errmsgTy,
+         errmsgTy},
         /*results*/ {});
     mlir::func::FuncOp funcOp =
         builder.createFunction(loc, getPRIFProcName("allocate_coarray"), ftype);



More information about the flang-commits mailing list