From 66a9768c7b20c53617aaf5a04e662cbbcad80482 Mon Sep 17 00:00:00 2001 From: Jean-Didier Pailleux Date: Mon, 18 Aug 2025 19:39:04 +0200 Subject: [PATCH 01/10] [flang][Lower] Add lowering for SYNC ALL, SYNC MEMORY and SYNC IMAGES to PRIF --- .../flang/Optimizer/Builder/Runtime/Coarray.h | 10 ++ flang/lib/Lower/Runtime.cpp | 104 +++++++++++++++++- flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 8 +- .../lib/Optimizer/Builder/Runtime/Coarray.cpp | 61 ++++++++++ flang/test/Lower/Coarray/sync_all.f90 | 37 +++++++ flang/test/Lower/Coarray/sync_images.f90 | 62 +++++++++++ flang/test/Lower/Coarray/sync_memory.f90 | 37 +++++++ 7 files changed, 309 insertions(+), 10 deletions(-) create mode 100644 flang/test/Lower/Coarray/sync_all.f90 create mode 100644 flang/test/Lower/Coarray/sync_images.f90 create mode 100644 flang/test/Lower/Coarray/sync_memory.f90 diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h b/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h index 10ed503a485a3..20bfb7c124af2 100644 --- a/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h +++ b/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h @@ -71,5 +71,15 @@ void genCoMin(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value A, void genCoSum(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value A, mlir::Value resultImage, mlir::Value stat, mlir::Value errmsg); +/// Generate call to runtime subroutine prif_sync_all +void genSyncAllStatement(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::Value stat, mlir::Value errmsg); +/// Generate call to runtime subroutine prif_sync_memory +void genSyncMemoryStatement(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::Value stat, mlir::Value errmsg); +/// Generate call to runtime subroutine prif_sync_images +void genSyncImagesStatement(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::Value imageSet, mlir::Value stat, + mlir::Value errmsg); } // namespace fir::runtime #endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COARRAY_H diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp index 494dd49e961b0..c7d1c92df6aef 100644 --- a/flang/lib/Lower/Runtime.cpp +++ b/flang/lib/Lower/Runtime.cpp @@ -12,6 +12,7 @@ #include "flang/Lower/OpenMP.h" #include "flang/Lower/StatementContext.h" #include "flang/Optimizer/Builder/FIRBuilder.h" +#include "flang/Optimizer/Builder/Runtime/Coarray.h" #include "flang/Optimizer/Builder/Runtime/RTBuilder.h" #include "flang/Optimizer/Builder/Todo.h" #include "flang/Optimizer/Dialect/FIROpsSupport.h" @@ -47,6 +48,50 @@ static void genUnreachable(fir::FirOpBuilder &builder, mlir::Location loc) { builder.setInsertionPointToStart(newBlock); } +// Check support of Multi-image features if -fcoarray is provided +void checkCoarrayEnabled(Fortran::lower::AbstractConverter &converter, + mlir::Location loc) { + if (!converter.getFoldingContext().languageFeatures().IsEnabled( + Fortran::common::LanguageFeature::Coarray)) + fir::emitFatalError(loc, "Coarrays disabled, use '-fcoarray' to enable.", + false); +} + +/// Initializes values for STAT and ERRMSG +static std::pair getStatAndErrmsg( + Fortran::lower::AbstractConverter &converter, mlir::Location loc, + const std::list &statOrErrList) { + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + Fortran::lower::StatementContext stmtCtx; + + mlir::Value errMsgExpr, statExpr; + for (const Fortran::parser::StatOrErrmsg &statOrErr : statOrErrList) { + std::visit(Fortran::common::visitors{ + [&](const Fortran::parser::StatVariable &statVar) { + statExpr = fir::getBase(converter.genExprAddr( + loc, Fortran::semantics::GetExpr(statVar), stmtCtx)); + }, + [&](const Fortran::parser::MsgVariable &errMsgVar) { + const Fortran::semantics::SomeExpr *expr = + Fortran::semantics::GetExpr(errMsgVar); + errMsgExpr = fir::getBase( + converter.genExprBox(loc, *expr, stmtCtx)); + }}, + statOrErr.u); + } + + if (!statExpr) { + statExpr = builder.create( + loc, builder.getRefType(builder.getI32Type())); + } + if (!errMsgExpr) { + errMsgExpr = builder.create( + loc, fir::BoxType::get(fir::CharacterType::get( + builder.getContext(), 1, fir::CharacterType::unknownLen()))); + } + return {statExpr, errMsgExpr}; +} + //===----------------------------------------------------------------------===// // Misc. Fortran statements that lower to runtime calls //===----------------------------------------------------------------------===// @@ -169,20 +214,67 @@ void Fortran::lower::genUnlockStatement( void Fortran::lower::genSyncAllStatement( Fortran::lower::AbstractConverter &converter, - const Fortran::parser::SyncAllStmt &) { - TODO(converter.getCurrentLocation(), "coarray: SYNC ALL runtime"); + const Fortran::parser::SyncAllStmt &stmt) { + mlir::Location loc = converter.getCurrentLocation(); + checkCoarrayEnabled(converter, loc); + + // Handle STAT and ERRMSG values + const std::list &statOrErrList = stmt.v; + auto [statAddr, errMsgAddr] = getStatAndErrmsg(converter, loc, statOrErrList); + + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + fir::runtime::genSyncAllStatement(builder, loc, statAddr, errMsgAddr); } void Fortran::lower::genSyncImagesStatement( Fortran::lower::AbstractConverter &converter, - const Fortran::parser::SyncImagesStmt &) { - TODO(converter.getCurrentLocation(), "coarray: SYNC IMAGES runtime"); + const Fortran::parser::SyncImagesStmt &stmt) { + mlir::Location loc = converter.getCurrentLocation(); + checkCoarrayEnabled(converter, loc); + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + + // Handle STAT and ERRMSG values + const std::list &statOrErrList = + std::get>(stmt.t); + auto [statAddr, errMsgAddr] = getStatAndErrmsg(converter, loc, statOrErrList); + + // SYNC_IMAGES(*) is passed as count == -1 while SYNC IMAGES([]) hase count + // == 0. Note further that SYNC IMAGES(*) is not semantically equivalent to + // SYNC ALL. + Fortran::lower::StatementContext stmtCtx; + mlir::Value imageSet; + const Fortran::parser::SyncImagesStmt::ImageSet &imgSet = + std::get(stmt.t); + std::visit(Fortran::common::visitors{ + [&](const Fortran::parser::IntExpr &intExpr) { + const SomeExpr *expr = Fortran::semantics::GetExpr(intExpr); + imageSet = + fir::getBase(converter.genExprBox(loc, *expr, stmtCtx)); + }, + [&](const Fortran::parser::Star &) { + imageSet = builder.create( + loc, fir::BoxType::get(fir::SequenceType::get( + {fir::SequenceType::getUnknownExtent()}, + builder.getI32Type()))); + }}, + imgSet.u); + + fir::runtime::genSyncImagesStatement(builder, loc, imageSet, statAddr, + errMsgAddr); } void Fortran::lower::genSyncMemoryStatement( Fortran::lower::AbstractConverter &converter, - const Fortran::parser::SyncMemoryStmt &) { - TODO(converter.getCurrentLocation(), "coarray: SYNC MEMORY runtime"); + const Fortran::parser::SyncMemoryStmt &stmt) { + mlir::Location loc = converter.getCurrentLocation(); + checkCoarrayEnabled(converter, loc); + + // Handle STAT and ERRMSG values + const std::list &statOrErrList = stmt.v; + auto [statAddr, errMsgAddr] = getStatAndErrmsg(converter, loc, statOrErrList); + + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + fir::runtime::genSyncMemoryStatement(builder, loc, statAddr, errMsgAddr); } void Fortran::lower::genSyncTeamStatement( diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 6ae48c1d5d88b..01a3bbff2fc1c 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -3716,7 +3716,7 @@ mlir::Value IntrinsicLibrary::genCmplx(mlir::Type resultType, // CO_BROADCAST void IntrinsicLibrary::genCoBroadcast(llvm::ArrayRef args) { - checkCoarrayEnabled(); + converter->checkCoarrayEnabled(); assert(args.size() == 4); mlir::Value sourceImage = fir::getBase(args[1]); mlir::Value status = @@ -3735,7 +3735,7 @@ void IntrinsicLibrary::genCoBroadcast(llvm::ArrayRef args) { // CO_MAX void IntrinsicLibrary::genCoMax(llvm::ArrayRef args) { - checkCoarrayEnabled(); + converter->checkCoarrayEnabled(); assert(args.size() == 4); mlir::Value refNone = fir::AbsentOp::create(builder, loc, @@ -3755,7 +3755,7 @@ void IntrinsicLibrary::genCoMax(llvm::ArrayRef args) { // CO_MIN void IntrinsicLibrary::genCoMin(llvm::ArrayRef args) { - checkCoarrayEnabled(); + converter->checkCoarrayEnabled(); assert(args.size() == 4); mlir::Value refNone = fir::AbsentOp::create(builder, loc, @@ -3775,7 +3775,7 @@ void IntrinsicLibrary::genCoMin(llvm::ArrayRef args) { // CO_SUM void IntrinsicLibrary::genCoSum(llvm::ArrayRef args) { - checkCoarrayEnabled(); + converter->checkCoarrayEnabled(); assert(args.size() == 4); mlir::Value absentInt = fir::AbsentOp::create(builder, loc, diff --git a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp index 9a893d61122ac..be5894b674fc0 100644 --- a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp +++ b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp @@ -165,3 +165,64 @@ void fir::runtime::genCoSum(fir::FirOpBuilder &builder, mlir::Location loc, genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg, PRIFNAME_SUB("co_sum")); } + +/// Generate call to runtime subroutine prif_sync_all +void fir::runtime::genSyncAllStatement(fir::FirOpBuilder &builder, + mlir::Location loc, mlir::Value stat, + mlir::Value errmsg) { + mlir::FunctionType ftype = + PRIF_FUNCTYPE(PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE); + mlir::func::FuncOp funcOp = + builder.createFunction(loc, PRIFNAME_SUB("sync_all"), ftype); + + auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg); + llvm::SmallVector args = fir::runtime::createArguments( + builder, loc, ftype, stat, errmsgArg, errmsgAllocArg); + builder.create(loc, funcOp, args); +} + +/// Generate call to runtime subroutine prif_sync_memory +void fir::runtime::genSyncMemoryStatement(fir::FirOpBuilder &builder, + mlir::Location loc, mlir::Value stat, + mlir::Value errmsg) { + mlir::FunctionType ftype = + PRIF_FUNCTYPE(PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE); + mlir::func::FuncOp funcOp = + builder.createFunction(loc, PRIFNAME_SUB("sync_memory"), ftype); + + auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg); + llvm::SmallVector args = fir::runtime::createArguments( + builder, loc, ftype, stat, errmsgArg, errmsgAllocArg); + builder.create(loc, funcOp, args); +} + +/// Generate call to runtime subroutine prif_sync_images +void fir::runtime::genSyncImagesStatement(fir::FirOpBuilder &builder, + mlir::Location loc, + mlir::Value imageSet, + mlir::Value stat, + mlir::Value errmsg) { + mlir::Type imgSetTy = fir::BoxType::get(fir::SequenceType::get( + {fir::SequenceType::getUnknownExtent()}, builder.getI32Type())); + mlir::FunctionType ftype = PRIF_FUNCTYPE(imgSetTy, PRIF_STAT_TYPE, + PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE); + mlir::func::FuncOp funcOp = + builder.createFunction(loc, PRIFNAME_SUB("sync_images"), ftype); + + // If imageSet is scalar, PRIF require to pass an array of size 1. + if (auto boxTy = mlir::dyn_cast(imageSet.getType())) { + if (!mlir::isa(boxTy.getEleTy())) { + mlir::Value one = + builder.createIntegerConstant(loc, builder.getI32Type(), 1); + mlir::Value shape = fir::ShapeOp::create(builder, loc, one); + imageSet = fir::ReboxOp::create( + builder, loc, + fir::BoxType::get(fir::SequenceType::get({1}, builder.getI32Type())), + imageSet, shape, mlir::Value{}); + } + } + auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg); + llvm::SmallVector args = fir::runtime::createArguments( + builder, loc, ftype, imageSet, stat, errmsgArg, errmsgAllocArg); + builder.create(loc, funcOp, args); +} diff --git a/flang/test/Lower/Coarray/sync_all.f90 b/flang/test/Lower/Coarray/sync_all.f90 new file mode 100644 index 0000000000000..dbb41fddfa90c --- /dev/null +++ b/flang/test/Lower/Coarray/sync_all.f90 @@ -0,0 +1,37 @@ +! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY +! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY + +program test_sync_all + implicit none + ! NOCOARRAY: Multi-image features are disabled, use '-fcoarray' to enable. + + ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) + ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref) -> (!fir.ref, !fir.ref) + integer sync_status + character(len=128) :: error_message + + ! COARRAY: %[[VAL_3:.*]] = fir.absent !fir.ref + ! COARRAY: %[[VAL_4:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_5:.*]] = fir.absent !fir.box> + ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) fastmath : (!fir.ref, !fir.box>, !fir.box>) -> () + sync all + + ! COARRAY: %[[VAL_6:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_7:.*]] = fir.absent !fir.box> + ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[STAT]]#0, %[[VAL_6]], %[[VAL_7]]) fastmath : (!fir.ref, !fir.box>, !fir.box>) -> () + sync all(stat=sync_status) + + ! COARRAY: %[[VAL_8:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref>) -> !fir.box> + ! COARRAY: %[[VAL_9:.*]] = fir.absent !fir.ref + ! COARRAY: %[[VAL_10:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_11:.*]] = fir.convert %[[VAL_8]] : (!fir.box>) -> !fir.box> + ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[VAL_9]], %[[VAL_11]], %[[VAL_10]]) fastmath : (!fir.ref, !fir.box>, !fir.box>) -> () + sync all( errmsg=error_message) + + ! COARRAY: %[[VAL_12:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref>) -> !fir.box> + ! COARRAY: %[[VAL_13:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (!fir.box>) -> !fir.box> + ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[STAT]]#0, %[[VAL_14]], %[[VAL_13]]) fastmath : (!fir.ref, !fir.box>, !fir.box>) -> () + sync all(stat=sync_status, errmsg=error_message) + +end program test_sync_all diff --git a/flang/test/Lower/Coarray/sync_images.f90 b/flang/test/Lower/Coarray/sync_images.f90 new file mode 100644 index 0000000000000..438356f0cadea --- /dev/null +++ b/flang/test/Lower/Coarray/sync_images.f90 @@ -0,0 +1,62 @@ +! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY +! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY + +program test_sync_images + implicit none + ! NOCOARRAY: Multi-image features are disabled, use '-fcoarray' to enable. + + ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) + ! COARRAY: %[[ME:.*]]:2 = hlfir.declare %[[VAL_3:.*]] {uniq_name = "_QFEme"} : (!fir.ref) -> (!fir.ref, !fir.ref) + ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref) -> (!fir.ref, !fir.ref) + integer sync_status, me + character(len=128) :: error_message + + ! COARRAY: %[[VAL_1:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref>) -> !fir.box> + ! COARRAY: %[[VAL_2:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_3:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_4:.*]] = fir.convert %[[VAL_1]] : (!fir.box>) -> !fir.box> + ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_2]], %[[STAT]]#0, %[[VAL_4]], %[[VAL_3]]) fastmath : (!fir.box>, !fir.ref, !fir.box>, !fir.box>) -> () + sync images(*, stat=sync_status, errmsg=error_message) + + ! COARRAY: %[[VAL_5:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref>) -> !fir.box> + ! COARRAY: %[[VAL_6:.*]] = fir.embox %[[ME]]#0 : (!fir.ref) -> !fir.box + ! COARRAY: %[[VAL_7:.*]] = fir.rebox %[[VAL_6]](%[[SHAPE:.*]]) : (!fir.box, !fir.shape<1>) -> !fir.box> + ! COARRAY: %[[VAL_8:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_9:.*]] = fir.convert %[[VAL_7]] : (!fir.box>) -> !fir.box> + ! COARRAY: %[[VAL_10:.*]] = fir.convert %[[VAL_5]] : (!fir.box>) -> !fir.box> + ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_9]], %[[STAT]]#0, %[[VAL_10]], %[[VAL_8]]) fastmath : (!fir.box>, !fir.ref, !fir.box>, !fir.box>) -> () + sync images(me, stat=sync_status, errmsg=error_message) + + ! COARRAY: %[[VAL_11:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref>) -> !fir.box> + ! COARRAY: %[[VAL_12:.*]] = fir.embox %[[IMG_SET:.*]]#0(%[[SHAPE_1:.*]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> + ! COARRAY: %[[VAL_13:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (!fir.box>) -> !fir.box> + ! COARRAY: %[[VAL_15:.*]] = fir.convert %[[VAL_11]] : (!fir.box>) -> !fir.box> + ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_14]], %[[STAT]]#0, %[[VAL_15]], %[[VAL_13]]) fastmath : (!fir.box>, !fir.ref, !fir.box>, !fir.box>) -> () + sync images([1], stat=sync_status, errmsg=error_message) + + ! COARRAY: %[[VAL_17:.*]] = fir.absent !fir.ref + ! COARRAY: %[[VAL_18:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_19:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_20:.*]] = fir.absent !fir.box> + ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_19]], %[[VAL_17]], %[[VAL_18]], %[[VAL_20]]) fastmath : (!fir.box>, !fir.ref, !fir.box>, !fir.box>) -> () + sync images(*) + + ! COARRAY: %[[VAL_23:.*]] = fir.absent !fir.ref + ! COARRAY: %[[VAL_24:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_21:.*]] = fir.embox %[[ME]]#0 : (!fir.ref) -> !fir.box + ! COARRAY: %[[VAL_22:.*]] = fir.rebox %[[VAL_21]](%[[SHAPE_2:.*]]) : (!fir.box, !fir.shape<1>) -> !fir.box> + ! COARRAY: %[[VAL_25:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_26:.*]] = fir.convert %[[VAL_22]] : (!fir.box>) -> !fir.box> + ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_26]], %[[VAL_23]], %[[VAL_24]], %[[VAL_25]]) fastmath : (!fir.box>, !fir.ref, !fir.box>, !fir.box>) -> () + sync images(me) + + ! COARRAY: %[[VAL_28:.*]] = fir.absent !fir.ref + ! COARRAY: %[[VAL_29:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_27:.*]] = fir.embox %[[IMG_SET:.*]]#0(%[[SHAPE_3:.*]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> + ! COARRAY: %[[VAL_30:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_31:.*]] = fir.convert %[[VAL_27]] : (!fir.box>) -> !fir.box> + ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_31]], %[[VAL_28]], %[[VAL_29]], %[[VAL_30]]) fastmath : (!fir.box>, !fir.ref, !fir.box>, !fir.box>) -> () + sync images([1]) + +end program test_sync_images diff --git a/flang/test/Lower/Coarray/sync_memory.f90 b/flang/test/Lower/Coarray/sync_memory.f90 new file mode 100644 index 0000000000000..74f813d086823 --- /dev/null +++ b/flang/test/Lower/Coarray/sync_memory.f90 @@ -0,0 +1,37 @@ +! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY +! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY + +program test_sync_memory + implicit none + ! NOCOARRAY: Multi-image features are disabled, use '-fcoarray' to enable. + + ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) + ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref) -> (!fir.ref, !fir.ref) + integer sync_status + character(len=128) :: error_message + + ! COARRAY: %[[VAL_3:.*]] = fir.absent !fir.ref + ! COARRAY: %[[VAL_4:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_5:.*]] = fir.absent !fir.box> + ! COARRAY: fir.call @_QMprifPprif_sync_memory(%[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) fastmath : (!fir.ref, !fir.box>, !fir.box>) -> () + sync memory + + ! COARRAY: %[[VAL_6:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_7:.*]] = fir.absent !fir.box> + ! COARRAY: fir.call @_QMprifPprif_sync_memory(%[[STAT]]#0, %[[VAL_6]], %[[VAL_7]]) fastmath : (!fir.ref, !fir.box>, !fir.box>) -> () + sync memory(stat=sync_status) + + ! COARRAY: %[[VAL_8:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref>) -> !fir.box> + ! COARRAY: %[[VAL_9:.*]] = fir.absent !fir.ref + ! COARRAY: %[[VAL_10:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_11:.*]] = fir.convert %[[VAL_8]] : (!fir.box>) -> !fir.box> + ! COARRAY: fir.call @_QMprifPprif_sync_memory(%[[VAL_9]], %[[VAL_11]], %[[VAL_10]]) fastmath : (!fir.ref, !fir.box>, !fir.box>) -> () + sync memory( errmsg=error_message) + + ! COARRAY: %[[VAL_12:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref>) -> !fir.box> + ! COARRAY: %[[VAL_13:.*]] = fir.absent !fir.box> + ! COARRAY: %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (!fir.box>) -> !fir.box> + ! COARRAY: fir.call @_QMprifPprif_sync_memory(%[[STAT]]#0, %[[VAL_14]], %[[VAL_13]]) fastmath : (!fir.ref, !fir.box>, !fir.box>) -> () + sync memory(stat=sync_status, errmsg=error_message) + +end program test_sync_memory From 258155866049e82bb77942d60115983471e59e8e Mon Sep 17 00:00:00 2001 From: Jean-Didier PAILLEUX Date: Wed, 20 Aug 2025 15:08:05 +0200 Subject: [PATCH 02/10] Apply suggestions from code review Co-authored-by: Katherine Rasmussen --- flang/lib/Lower/Runtime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp index c7d1c92df6aef..25c293232f493 100644 --- a/flang/lib/Lower/Runtime.cpp +++ b/flang/lib/Lower/Runtime.cpp @@ -238,7 +238,7 @@ void Fortran::lower::genSyncImagesStatement( std::get>(stmt.t); auto [statAddr, errMsgAddr] = getStatAndErrmsg(converter, loc, statOrErrList); - // SYNC_IMAGES(*) is passed as count == -1 while SYNC IMAGES([]) hase count + // SYNC_IMAGES(*) is passed as count == -1 while SYNC IMAGES([]) has count // == 0. Note further that SYNC IMAGES(*) is not semantically equivalent to // SYNC ALL. Fortran::lower::StatementContext stmtCtx; From 56c024b41e68a5af53963f41b6ccd4792adee2a9 Mon Sep 17 00:00:00 2001 From: Jean-Didier Pailleux Date: Thu, 21 Aug 2025 21:06:20 +0200 Subject: [PATCH 03/10] [flang][Lower] Move checkCoarrayEnabled() into the AbstractConvert --- flang/include/flang/Lower/AbstractConverter.h | 3 +++ .../flang/Optimizer/Builder/IntrinsicCall.h | 9 --------- flang/lib/Lower/Bridge.cpp | 8 ++++++++ flang/lib/Lower/Runtime.cpp | 15 +++------------ flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 4 ++-- 5 files changed, 16 insertions(+), 23 deletions(-) diff --git a/flang/include/flang/Lower/AbstractConverter.h b/flang/include/flang/Lower/AbstractConverter.h index 8e9de418e1b7e..0ffe27ea038e8 100644 --- a/flang/include/flang/Lower/AbstractConverter.h +++ b/flang/include/flang/Lower/AbstractConverter.h @@ -271,6 +271,9 @@ class AbstractConverter { virtual const Fortran::lower::pft::FunctionLikeUnit * getCurrentFunctionUnit() const = 0; + /// Check support of Multi-image features if -fcoarray is provided + virtual void checkCoarrayEnabled() = 0; + //===--------------------------------------------------------------------===// // Types //===--------------------------------------------------------------------===// diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h index 3c020abd59417..d80ee9e861321 100644 --- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h +++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h @@ -573,15 +573,6 @@ struct IntrinsicLibrary { void setResultMustBeFreed() { resultMustBeFreed = true; } - // Check support of coarray features - void checkCoarrayEnabled() { - if (converter && - !converter->getFoldingContext().languageFeatures().IsEnabled( - Fortran::common::LanguageFeature::Coarray)) - fir::emitFatalError(loc, "Coarrays disabled, use '-fcoarray' to enable.", - false); - } - fir::FirOpBuilder &builder; mlir::Location loc; bool resultMustBeFreed = false; diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 6125ea9153662..3489d0f8d9da0 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -1131,6 +1131,14 @@ class FirConverter : public Fortran::lower::AbstractConverter { return currentFunctionUnit; } + void checkCoarrayEnabled() override final { + if (!getFoldingContext().languageFeatures().IsEnabled( + Fortran::common::LanguageFeature::Coarray)) + fir::emitFatalError(getCurrentLocation(), + "Coarrays disabled, use '-fcoarray' to enable.", + false); + } + void registerTypeInfo(mlir::Location loc, Fortran::lower::SymbolRef typeInfoSym, const Fortran::semantics::DerivedTypeSpec &typeSpec, diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp index 25c293232f493..81e577fb077f4 100644 --- a/flang/lib/Lower/Runtime.cpp +++ b/flang/lib/Lower/Runtime.cpp @@ -48,15 +48,6 @@ static void genUnreachable(fir::FirOpBuilder &builder, mlir::Location loc) { builder.setInsertionPointToStart(newBlock); } -// Check support of Multi-image features if -fcoarray is provided -void checkCoarrayEnabled(Fortran::lower::AbstractConverter &converter, - mlir::Location loc) { - if (!converter.getFoldingContext().languageFeatures().IsEnabled( - Fortran::common::LanguageFeature::Coarray)) - fir::emitFatalError(loc, "Coarrays disabled, use '-fcoarray' to enable.", - false); -} - /// Initializes values for STAT and ERRMSG static std::pair getStatAndErrmsg( Fortran::lower::AbstractConverter &converter, mlir::Location loc, @@ -216,7 +207,7 @@ void Fortran::lower::genSyncAllStatement( Fortran::lower::AbstractConverter &converter, const Fortran::parser::SyncAllStmt &stmt) { mlir::Location loc = converter.getCurrentLocation(); - checkCoarrayEnabled(converter, loc); + converter.checkCoarrayEnabled(); // Handle STAT and ERRMSG values const std::list &statOrErrList = stmt.v; @@ -230,7 +221,7 @@ void Fortran::lower::genSyncImagesStatement( Fortran::lower::AbstractConverter &converter, const Fortran::parser::SyncImagesStmt &stmt) { mlir::Location loc = converter.getCurrentLocation(); - checkCoarrayEnabled(converter, loc); + converter.checkCoarrayEnabled(); fir::FirOpBuilder &builder = converter.getFirOpBuilder(); // Handle STAT and ERRMSG values @@ -267,7 +258,7 @@ void Fortran::lower::genSyncMemoryStatement( Fortran::lower::AbstractConverter &converter, const Fortran::parser::SyncMemoryStmt &stmt) { mlir::Location loc = converter.getCurrentLocation(); - checkCoarrayEnabled(converter, loc); + converter.checkCoarrayEnabled(); // Handle STAT and ERRMSG values const std::list &statOrErrList = stmt.v; diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 01a3bbff2fc1c..aa12dbff5935b 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -7438,7 +7438,7 @@ IntrinsicLibrary::genNull(mlir::Type, llvm::ArrayRef args) { fir::ExtendedValue IntrinsicLibrary::genNumImages(mlir::Type resultType, llvm::ArrayRef args) { - checkCoarrayEnabled(); + converter->checkCoarrayEnabled(); assert(args.size() == 0 || args.size() == 1); if (args.size()) @@ -8519,7 +8519,7 @@ mlir::Value IntrinsicLibrary::genThisGrid(mlir::Type resultType, fir::ExtendedValue IntrinsicLibrary::genThisImage(mlir::Type resultType, llvm::ArrayRef args) { - checkCoarrayEnabled(); + converter->checkCoarrayEnabled(); assert(args.size() >= 1 && args.size() <= 3); const bool coarrayIsAbsent = args.size() == 1; mlir::Value team = From 1c98898e3b0c8a1e88483826940335b16197a0a5 Mon Sep 17 00:00:00 2001 From: Jean-Didier Pailleux Date: Thu, 21 Aug 2025 21:08:23 +0200 Subject: [PATCH 04/10] [flang] Update Message in checkCoarrayEnabled --- flang/lib/Lower/Bridge.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 3489d0f8d9da0..8c673ccf3bcdd 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -1134,9 +1134,10 @@ class FirConverter : public Fortran::lower::AbstractConverter { void checkCoarrayEnabled() override final { if (!getFoldingContext().languageFeatures().IsEnabled( Fortran::common::LanguageFeature::Coarray)) - fir::emitFatalError(getCurrentLocation(), - "Coarrays disabled, use '-fcoarray' to enable.", - false); + fir::emitFatalError( + getCurrentLocation(), + "Multi-image features are disabled, use '-fcoarray' to enable.", + false); } void registerTypeInfo(mlir::Location loc, From 027cdab5d92d4713e2ed4eb3746c782e04eb87a7 Mon Sep 17 00:00:00 2001 From: Jean-Didier Pailleux Date: Sun, 24 Aug 2025 21:22:02 +0200 Subject: [PATCH 05/10] Update builder.create into fir::CallOp::create --- flang/lib/Optimizer/Builder/Runtime/Coarray.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp index be5894b674fc0..364e7b753c6ee 100644 --- a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp +++ b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp @@ -178,7 +178,7 @@ void fir::runtime::genSyncAllStatement(fir::FirOpBuilder &builder, auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg); llvm::SmallVector args = fir::runtime::createArguments( builder, loc, ftype, stat, errmsgArg, errmsgAllocArg); - builder.create(loc, funcOp, args); + fir::CallOp::create(builder, loc, funcOp, args); } /// Generate call to runtime subroutine prif_sync_memory @@ -193,7 +193,7 @@ void fir::runtime::genSyncMemoryStatement(fir::FirOpBuilder &builder, auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg); llvm::SmallVector args = fir::runtime::createArguments( builder, loc, ftype, stat, errmsgArg, errmsgAllocArg); - builder.create(loc, funcOp, args); + fir::CallOp::create(builder, loc, funcOp, args); } /// Generate call to runtime subroutine prif_sync_images @@ -224,5 +224,5 @@ void fir::runtime::genSyncImagesStatement(fir::FirOpBuilder &builder, auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg); llvm::SmallVector args = fir::runtime::createArguments( builder, loc, ftype, imageSet, stat, errmsgArg, errmsgAllocArg); - builder.create(loc, funcOp, args); + fir::CallOp::create(builder, loc, funcOp, args); } From 37c311ed793bd5572eef9cb720c567e29e820a2c Mon Sep 17 00:00:00 2001 From: Katherine Rasmussen Date: Wed, 27 Aug 2025 14:29:43 -0700 Subject: [PATCH 06/10] Update builder.create into fir::OpTy::create calls --- flang/lib/Lower/Runtime.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp index 81e577fb077f4..b19ca0182b4b5 100644 --- a/flang/lib/Lower/Runtime.cpp +++ b/flang/lib/Lower/Runtime.cpp @@ -72,13 +72,14 @@ static std::pair getStatAndErrmsg( } if (!statExpr) { - statExpr = builder.create( - loc, builder.getRefType(builder.getI32Type())); + statExpr = fir::AbsentOp::create(builder, loc, + builder.getRefType(builder.getI32Type())); } if (!errMsgExpr) { - errMsgExpr = builder.create( - loc, fir::BoxType::get(fir::CharacterType::get( - builder.getContext(), 1, fir::CharacterType::unknownLen()))); + errMsgExpr = fir::AbsentOp::create( + builder, loc, + fir::BoxType::get(fir::CharacterType::get( + builder.getContext(), 1, fir::CharacterType::unknownLen()))); } return {statExpr, errMsgExpr}; } @@ -243,10 +244,11 @@ void Fortran::lower::genSyncImagesStatement( fir::getBase(converter.genExprBox(loc, *expr, stmtCtx)); }, [&](const Fortran::parser::Star &) { - imageSet = builder.create( - loc, fir::BoxType::get(fir::SequenceType::get( - {fir::SequenceType::getUnknownExtent()}, - builder.getI32Type()))); + imageSet = fir::AbsentOp::create( + builder, loc, + fir::BoxType::get(fir::SequenceType::get( + {fir::SequenceType::getUnknownExtent()}, + builder.getI32Type()))); }}, imgSet.u); From 807148c0db14252506c7d11b9390d6a989830e3b Mon Sep 17 00:00:00 2001 From: Jean-Didier PAILLEUX Date: Tue, 9 Sep 2025 17:37:37 +0200 Subject: [PATCH 07/10] Update flang/lib/Lower/Bridge.cpp Co-authored-by: Katherine Rasmussen --- flang/lib/Lower/Bridge.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 8c673ccf3bcdd..2f6990c9bf059 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -1136,7 +1136,7 @@ class FirConverter : public Fortran::lower::AbstractConverter { Fortran::common::LanguageFeature::Coarray)) fir::emitFatalError( getCurrentLocation(), - "Multi-image features are disabled, use '-fcoarray' to enable.", + "Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable.", false); } From 4f6a90a084bff1b39b0b1f37fb81bc301d137aa4 Mon Sep 17 00:00:00 2001 From: Jean-Didier Pailleux Date: Sun, 24 Aug 2025 21:22:02 +0200 Subject: [PATCH 08/10] Update builder.create into fir::CallOp::create --- flang/lib/Optimizer/Builder/Runtime/Coarray.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp index 364e7b753c6ee..b28352f1e43ec 100644 --- a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp +++ b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp @@ -164,6 +164,7 @@ void fir::runtime::genCoSum(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value stat, mlir::Value errmsg) { genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg, PRIFNAME_SUB("co_sum")); + return fir::LoadOp::create(builder, loc, result); } /// Generate call to runtime subroutine prif_sync_all From eadb0b750bde42aeb8b93d95b241da6a14511af1 Mon Sep 17 00:00:00 2001 From: Jean-Didier Pailleux Date: Wed, 10 Sep 2025 09:55:17 +0200 Subject: [PATCH 09/10] Update tests with the correct error message for Multi-image features --- flang/test/Lower/Coarray/sync_all.f90 | 2 +- flang/test/Lower/Coarray/sync_images.f90 | 2 +- flang/test/Lower/Coarray/sync_memory.f90 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/flang/test/Lower/Coarray/sync_all.f90 b/flang/test/Lower/Coarray/sync_all.f90 index dbb41fddfa90c..c2c12d8cdf237 100644 --- a/flang/test/Lower/Coarray/sync_all.f90 +++ b/flang/test/Lower/Coarray/sync_all.f90 @@ -3,7 +3,7 @@ program test_sync_all implicit none - ! NOCOARRAY: Multi-image features are disabled, use '-fcoarray' to enable. + ! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable. ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref) -> (!fir.ref, !fir.ref) diff --git a/flang/test/Lower/Coarray/sync_images.f90 b/flang/test/Lower/Coarray/sync_images.f90 index 438356f0cadea..0224bf235c36c 100644 --- a/flang/test/Lower/Coarray/sync_images.f90 +++ b/flang/test/Lower/Coarray/sync_images.f90 @@ -3,7 +3,7 @@ program test_sync_images implicit none - ! NOCOARRAY: Multi-image features are disabled, use '-fcoarray' to enable. + ! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable. ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) ! COARRAY: %[[ME:.*]]:2 = hlfir.declare %[[VAL_3:.*]] {uniq_name = "_QFEme"} : (!fir.ref) -> (!fir.ref, !fir.ref) diff --git a/flang/test/Lower/Coarray/sync_memory.f90 b/flang/test/Lower/Coarray/sync_memory.f90 index 74f813d086823..773cb6fe4efb7 100644 --- a/flang/test/Lower/Coarray/sync_memory.f90 +++ b/flang/test/Lower/Coarray/sync_memory.f90 @@ -3,7 +3,7 @@ program test_sync_memory implicit none - ! NOCOARRAY: Multi-image features are disabled, use '-fcoarray' to enable. + ! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable. ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref) -> (!fir.ref, !fir.ref) From 8e0a4b9795782a4406d2243716c6e774918deddd Mon Sep 17 00:00:00 2001 From: Jean-Didier Pailleux Date: Wed, 10 Sep 2025 10:26:43 +0200 Subject: [PATCH 10/10] Fix Clang formatting + rebase mistake --- flang/lib/Lower/Bridge.cpp | 3 ++- flang/lib/Optimizer/Builder/Runtime/Coarray.cpp | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 2f6990c9bf059..4a5b9885bb7c4 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -1136,7 +1136,8 @@ class FirConverter : public Fortran::lower::AbstractConverter { Fortran::common::LanguageFeature::Coarray)) fir::emitFatalError( getCurrentLocation(), - "Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable.", + "Not yet implemented: Multi-image features are experimental and are " + "disabled by default, use '-fcoarray' to enable.", false); } diff --git a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp index b28352f1e43ec..364e7b753c6ee 100644 --- a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp +++ b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp @@ -164,7 +164,6 @@ void fir::runtime::genCoSum(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value stat, mlir::Value errmsg) { genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg, PRIFNAME_SUB("co_sum")); - return fir::LoadOp::create(builder, loc, result); } /// Generate call to runtime subroutine prif_sync_all