[flang][Lower] Add lowering to SYNC ALL, SYNC MEMORY and SYNC IMAGES to PRIF#154166
Conversation
|
@llvm/pr-subscribers-flang-fir-hlfir Author: Jean-Didier PAILLEUX (JDPailleux) ChangesIn relation to the approval and merge of the #76088 specification about multi-image features in Flang. Patch is 21.24 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/154166.diff 6 Files Affected:
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h b/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h
index f2c76c9e8d978..ae9eedb0c8dc7 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h
@@ -34,8 +34,23 @@ namespace fir::runtime {
return fir::NameUniquer::doProcedure({"prif"}, {}, oss.str()); \
}()
+#define PRIF_STAT_TYPE builder.getRefType(builder.getI32Type())
+#define PRIF_ERRMSG_TYPE \
+ fir::BoxType::get(fir::CharacterType::get(builder.getContext(), 1, \
+ fir::CharacterType::unknownLen()))
+
/// Generate Call to runtime prif_init
mlir::Value genInitCoarray(fir::FirOpBuilder &builder, mlir::Location loc);
+/// Generate call to runtime 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 fc59a2414d539..159a8eaefd990 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"
@@ -48,6 +49,51 @@ 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<mlir::Value, mlir::Value> getStatAndErrmsg(
+ Fortran::lower::AbstractConverter &converter, mlir::Location loc,
+ const std::list<Fortran::parser::StatOrErrmsg> &statOrErrList) {
+ fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+ Fortran::lower::StatementContext stmtCtx;
+ fir::ExtendedValue errMsgExpr, statExpr;
+
+ mlir::Value statAddr, errMsgAddr;
+ for (const Fortran::parser::StatOrErrmsg &statOrErr : statOrErrList) {
+ std::visit(Fortran::common::visitors{
+ [&](const Fortran::parser::StatVariable &statVar) {
+ statExpr = converter.genExprAddr(
+ loc, Fortran::semantics::GetExpr(statVar), stmtCtx);
+ statAddr = fir::getBase(statExpr);
+ },
+ [&](const Fortran::parser::MsgVariable &errMsgVar) {
+ fir::ExtendedValue errMsgExpr = converter.genExprAddr(
+ loc, Fortran::semantics::GetExpr(errMsgVar), stmtCtx);
+ errMsgAddr = builder.createBox(loc, errMsgExpr);
+ }},
+ statOrErr.u);
+ }
+
+ if (!statAddr) {
+ statAddr = builder.create<fir::AbsentOp>(
+ loc, builder.getRefType(builder.getI32Type()));
+ }
+ if (!errMsgAddr) {
+ errMsgAddr = builder.create<fir::AbsentOp>(
+ loc, fir::BoxType::get(fir::CharacterType::get(
+ builder.getContext(), 1, fir::CharacterType::unknownLen())));
+ }
+ return {statAddr, errMsgAddr};
+}
+
//===----------------------------------------------------------------------===//
// Misc. Fortran statements that lower to runtime calls
//===----------------------------------------------------------------------===//
@@ -170,20 +216,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<Fortran::parser::StatOrErrmsg> &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<Fortran::parser::StatOrErrmsg> &statOrErrList =
+ std::get<std::list<Fortran::parser::StatOrErrmsg>>(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<Fortran::parser::SyncImagesStmt::ImageSet>(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<fir::AbsentOp>(
+ 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<Fortran::parser::StatOrErrmsg> &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/Runtime/Coarray.cpp b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp
index eaff6c37ecdbf..eae04ff837a5e 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp
@@ -14,6 +14,24 @@
using namespace Fortran::runtime;
using namespace Fortran::semantics;
+// Most PRIF functions take `errmsg` and `errmsg_alloc` as two optional
+// arguments of intent (out). One is allocatable, the other is not.
+// It is the responsibility of the compiler to ensure that the appropriate
+// optional argument is passed, and at most one must be provided in a given
+// call.
+// Depending on the type of `errmsg`, this function will return the pair
+// corresponding to (`errmsg`, `errmsg_alloc`).
+static std::pair<mlir::Value, mlir::Value>
+genErrmsgPRIF(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value errmsg) {
+ bool isAllocatableErrmsg = fir::isAllocatableType(errmsg.getType());
+
+ mlir::Value absent = builder.create<fir::AbsentOp>(loc, PRIF_ERRMSG_TYPE);
+ mlir::Value errMsg = isAllocatableErrmsg ? absent : errmsg;
+ mlir::Value errMsgAlloc = isAllocatableErrmsg ? errmsg : absent;
+ return {errMsg, errMsgAlloc};
+}
+
/// Generate Call to runtime prif_init
mlir::Value fir::runtime::genInitCoarray(fir::FirOpBuilder &builder,
mlir::Location loc) {
@@ -27,3 +45,64 @@ mlir::Value fir::runtime::genInitCoarray(fir::FirOpBuilder &builder,
builder.create<fir::CallOp>(loc, funcOp, args);
return builder.create<fir::LoadOp>(loc, result);
}
+
+/// Generate call to runtime subroutine prif_sync_all
+void fir::runtime::genSyncAllStatement(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value stat,
+ mlir::Value errmsg) {
+ mlir::FunctionType ftype =
+ PRIF_FUNCTYPE(PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE);
+ mlir::func::FuncOp funcOp =
+ builder.createFunction(loc, PRIFNAME_SUB("sync_all"), ftype);
+
+ auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg);
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, ftype, stat, errmsgArg, errmsgAllocArg);
+ builder.create<fir::CallOp>(loc, funcOp, args);
+}
+
+/// Generate call to runtime subroutine prif_sync_memory
+void fir::runtime::genSyncMemoryStatement(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value stat,
+ mlir::Value errmsg) {
+ mlir::FunctionType ftype =
+ PRIF_FUNCTYPE(PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE);
+ mlir::func::FuncOp funcOp =
+ builder.createFunction(loc, PRIFNAME_SUB("sync_memory"), ftype);
+
+ auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg);
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, ftype, stat, errmsgArg, errmsgAllocArg);
+ builder.create<fir::CallOp>(loc, funcOp, args);
+}
+
+/// Generate call to runtime subroutine prif_sync_images
+void fir::runtime::genSyncImagesStatement(fir::FirOpBuilder &builder,
+ mlir::Location loc,
+ mlir::Value imageSet,
+ mlir::Value stat,
+ mlir::Value errmsg) {
+ mlir::Type imgSetTy = fir::BoxType::get(fir::SequenceType::get(
+ {fir::SequenceType::getUnknownExtent()}, builder.getI32Type()));
+ mlir::FunctionType ftype = PRIF_FUNCTYPE(imgSetTy, PRIF_STAT_TYPE,
+ PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE);
+ mlir::func::FuncOp funcOp =
+ builder.createFunction(loc, PRIFNAME_SUB("sync_images"), ftype);
+
+ // If imageSet is scalar, PRIF require to pass an array of size 1.
+ if (auto boxTy = mlir::dyn_cast<fir::BoxType>(imageSet.getType())) {
+ if (!mlir::isa<fir::SequenceType>(boxTy.getEleTy())) {
+ mlir::Value one =
+ builder.createIntegerConstant(loc, builder.getI32Type(), 1);
+ mlir::Value shape = fir::ShapeOp::create(builder, loc, one);
+ imageSet = fir::ReboxOp::create(
+ builder, loc,
+ fir::BoxType::get(fir::SequenceType::get({1}, builder.getI32Type())),
+ imageSet, shape, mlir::Value{});
+ }
+ }
+ auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg);
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, ftype, imageSet, stat, errmsgArg, errmsgAllocArg);
+ builder.create<fir::CallOp>(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..e63279add59a5
--- /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
+! RUN2: not %flang_fc1 -emit-hlfir %s -o - | FileCheck %s --check-prefixes=NOCOARRAY
+
+program test_sync_all
+ implicit none
+ ! NOCOARRAY: Coarrays disabled, use '-fcoarray' to enable.
+
+ ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ integer sync_status
+ character(len=128) :: error_message
+
+ ! COARRAY: %[[VAL_3:.*]] = fir.absent !fir.ref<i32>
+ ! COARRAY: %[[VAL_4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! COARRAY: %[[VAL_5:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ sync all
+
+ ! COARRAY: %[[VAL_6:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! COARRAY: %[[VAL_7:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[STAT]]#0, %[[VAL_6]], %[[VAL_7]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ sync all(stat=sync_status)
+
+ ! COARRAY: %[[VAL_8:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: %[[VAL_9:.*]] = fir.absent !fir.ref<i32>
+ ! COARRAY: %[[VAL_10:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! COARRAY: %[[VAL_11:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+ ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[VAL_9]], %[[VAL_11]], %[[VAL_10]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ sync all( errmsg=error_message)
+
+ ! COARRAY: %[[VAL_12:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: %[[VAL_13:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! COARRAY: %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+ ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[STAT]]#0, %[[VAL_14]], %[[VAL_13]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ sync all(stat=sync_status, errmsg=error_message)
+
+end program test_sync_all
diff --git a/flang/test/Lower/Coarray/sync_images.f90 b/flang/test/Lower/Coarray/sync_images.f90
new file mode 100644
index 0000000000000..0fd4d815c6580
--- /dev/null
+++ b/flang/test/Lower/Coarray/sync_images.f90
@@ -0,0 +1,37 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY
+! RUN2: not %flang_fc1 -emit-hlfir %s -o - | FileCheck %s --check-prefixes=NOCOARRAY
+
+program test_sync_images
+ implicit none
+ ! NOCOARRAY: Coarrays disabled, use '-fcoarray' to enable.
+
+ ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ ! COARRAY: %[[ME:.*]]:2 = hlfir.declare %[[VAL_3:.*]] {uniq_name = "_QFEme"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ integer sync_status, me
+ character(len=128) :: error_message
+
+ ! COARRAY: %[[VAL_1:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: %[[VAL_2:.*]] = fir.absent !fir.box<!fir.array<?xi32>>
+ ! COARRAY: %[[VAL_3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! COARRAY: %[[VAL_4:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+ ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_2]], %[[STAT]]#0, %[[VAL_4]], %[[VAL_3]]) fastmath<contract> : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ sync images(*, stat=sync_status, errmsg=error_message)
+
+ ! COARRAY: %[[VAL_5:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: %[[VAL_6:.*]] = fir.embox %[[ME]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! COARRAY: %[[VAL_7:.*]] = fir.rebox %[[VAL_6]](%[[SHAPE:.*]]) : (!fir.box<i32>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ ! COARRAY: %[[VAL_8:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! COARRAY: %[[VAL_9:.*]] = fir.convert %[[VAL_7]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
+ ! COARRAY: %[[VAL_10:.*]] = fir.convert %[[VAL_5]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+ ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_9]], %[[STAT]]#0, %[[VAL_10]], %[[VAL_8]]) fastmath<contract> : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ sync images(me, stat=sync_status, errmsg=error_message)
+
+ ! COARRAY: %[[VAL_11:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: %[[VAL_12:.*]] = fir.embox %[[IMG_SET:.*]]#0(%[[SHAPE_1:.*]]) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ ! COARRAY: %[[VAL_13:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! COARRAY: %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
+ ! COARRAY: %[[VAL_15:.*]] = fir.convert %[[VAL_11]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+ ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_14]], %[[STAT]]#0, %[[VAL_15]], %[[VAL_13]]) fastmath<contract> : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ sync images([1], stat=sync_status, errmsg=error_message)
+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..cf3d3398d0610
--- /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
+! RUN2: not %flang_fc1 -emit-hlfir %s -o - | FileCheck %s --check-prefixes=NOCOARRAY
+
+program test_sync_memory
+ implicit none
+ ! NOCOARRAY: Coarrays disabled, use '-fcoarray' to enable.
+
+ ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ integer sync_status
+ character(len=128) :: error_message
+
+ ! COARRAY: %[[VAL_3:.*]] = fir.absent !fir.ref<i32>
+ ! COARRAY: %[[VAL_4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! COARRAY: %[[VAL_5:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! COARRAY: fir.call @_QMprifPprif_sync_memory(%[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ sync memory
+
+ ! COARRAY: %[[VAL_6:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! COARRAY: %[[VAL_7:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! COARRAY: fir.call @_QMprifPprif_sync_memory(%[[STAT]]#0, %[[VAL_6]], %[[VAL_7]]) fastmath<contract>...
[truncated]
|
bonachea
left a comment
There was a problem hiding this comment.
This is very exciting progress!
I've added one minor request/suggestion on the new test code.
9bc2b7a to
a43b53c
Compare
ktras
left a comment
There was a problem hiding this comment.
Great start! I have some requested changes below, so please check them out.
a43b53c to
822c886
Compare
7416513 to
85377e1
Compare
ktras
left a comment
There was a problem hiding this comment.
I have one more small requested change in the code and please note my earlier comment from yesterday as well, in case there is need for another change. Thanks.
|
@ktras I moved the check function directly into the converter. This will effectively avoid redefinition. |
bonachea
left a comment
There was a problem hiding this comment.
@JDPailleux Thanks for all the improvements!
CI is currently failing because the tests need to be updated to reflect a minor change in error message string.
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
02db511 to
eadb0b7
Compare
ktras
left a comment
There was a problem hiding this comment.
Thank you for your updates responding to review comments. LGTM.
…178011) This PR updates flang's Fortran standard conformance documentation to reflect the recent addition of experimental support for multi-image features. PRs implementing that support include: * llvm#151675 * llvm#154081 * llvm#154770 * llvm#154166 * llvm#165573 (cherry picked from commit a580383)
…178011) This PR updates flang's Fortran standard conformance documentation to reflect the recent addition of experimental support for multi-image features. PRs implementing that support include: * llvm#151675 * llvm#154081 * llvm#154770 * llvm#154166 * llvm#165573
In relation to the approval and merge of the #76088 specification about multi-image features in Flang.
Here is a PR on adding support for SYNC ALL, SYNC MEMORY and SYNC IMAGES in conformance with the PRIF specification.