aboutsummaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
Diffstat (limited to 'flang')
-rw-r--r--flang/include/flang/Lower/OpenMP/Clauses.h1
-rw-r--r--flang/include/flang/Optimizer/Builder/Runtime/Coarray.h85
-rw-r--r--flang/include/flang/Optimizer/Dialect/CMakeLists.txt1
-rw-r--r--flang/include/flang/Optimizer/Dialect/FIRType.h3
-rw-r--r--flang/include/flang/Optimizer/Dialect/MIF/CMakeLists.txt9
-rw-r--r--flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h28
-rw-r--r--flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.td38
-rw-r--r--flang/include/flang/Optimizer/Dialect/MIF/MIFOps.h20
-rw-r--r--flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td268
-rw-r--r--flang/include/flang/Optimizer/Support/InitFIR.h3
-rw-r--r--flang/include/flang/Optimizer/Transforms/MIFOpConversion.h27
-rw-r--r--flang/include/flang/Optimizer/Transforms/Passes.td5
-rw-r--r--flang/include/flang/Parser/dump-parse-tree.h1
-rw-r--r--flang/include/flang/Parser/parse-tree.h8
-rw-r--r--flang/include/flang/Parser/tools.h2
-rw-r--r--flang/include/flang/Semantics/tools.h6
-rw-r--r--flang/lib/Frontend/CMakeLists.txt2
-rw-r--r--flang/lib/Lower/Bridge.cpp3
-rw-r--r--flang/lib/Lower/CMakeLists.txt2
-rw-r--r--flang/lib/Lower/OpenACC.cpp39
-rw-r--r--flang/lib/Lower/OpenMP/Clauses.cpp12
-rw-r--r--flang/lib/Lower/OpenMP/OpenMP.cpp3
-rw-r--r--flang/lib/Lower/Runtime.cpp27
-rw-r--r--flang/lib/Optimizer/Builder/CMakeLists.txt3
-rw-r--r--flang/lib/Optimizer/Builder/IntrinsicCall.cpp111
-rw-r--r--flang/lib/Optimizer/Builder/Runtime/Coarray.cpp228
-rw-r--r--flang/lib/Optimizer/Builder/Runtime/Main.cpp4
-rw-r--r--flang/lib/Optimizer/Dialect/CMakeLists.txt1
-rw-r--r--flang/lib/Optimizer/Dialect/FIRType.cpp7
-rw-r--r--flang/lib/Optimizer/Dialect/MIF/CMakeLists.txt20
-rw-r--r--flang/lib/Optimizer/Dialect/MIF/MIFDialect.cpp24
-rw-r--r--flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp153
-rw-r--r--flang/lib/Optimizer/OpenACC/Transforms/CMakeLists.txt4
-rw-r--r--flang/lib/Optimizer/Passes/Pipelines.cpp1
-rw-r--r--flang/lib/Optimizer/Transforms/CMakeLists.txt3
-rw-r--r--flang/lib/Optimizer/Transforms/MIFOpConversion.cpp464
-rw-r--r--flang/lib/Parser/openmp-parsers.cpp3
-rw-r--r--flang/lib/Parser/tools.cpp5
-rw-r--r--flang/lib/Semantics/check-acc-structure.cpp7
-rw-r--r--flang/lib/Semantics/check-omp-loop.cpp23
-rw-r--r--flang/lib/Semantics/check-omp-structure.cpp7
-rw-r--r--flang/lib/Semantics/resolve-directives.cpp7
-rw-r--r--flang/lib/Semantics/resolve-names.cpp6
-rw-r--r--flang/test/Driver/mlir-debug-pass-pipeline.f901
-rw-r--r--flang/test/Driver/mlir-pass-pipeline.f901
-rw-r--r--flang/test/Fir/MIF/co_broadcast.mlir137
-rw-r--r--flang/test/Fir/MIF/co_max.mlir163
-rw-r--r--flang/test/Fir/MIF/co_min.mlir163
-rw-r--r--flang/test/Fir/MIF/co_sum.mlir133
-rw-r--r--flang/test/Fir/MIF/init.mlir24
-rw-r--r--flang/test/Fir/MIF/num_images.mlir22
-rw-r--r--flang/test/Fir/MIF/sync_all.mlir45
-rw-r--r--flang/test/Fir/MIF/sync_images.mlir85
-rw-r--r--flang/test/Fir/MIF/sync_memory.mlir45
-rw-r--r--flang/test/Fir/MIF/this_image.mlir16
-rw-r--r--flang/test/Fir/basic-program.fir1
-rw-r--r--flang/test/Lower/CUDA/cuda-cloc.cuf19
-rw-r--r--flang/test/Lower/Coarray/co_broadcast.f9092
-rw-r--r--flang/test/Lower/Coarray/co_max.f90112
-rw-r--r--flang/test/Lower/Coarray/co_min.f90112
-rw-r--r--flang/test/Lower/Coarray/co_sum.f90122
-rw-r--r--flang/test/Lower/Coarray/sync_all.f9037
-rw-r--r--flang/test/Lower/Coarray/sync_images.f9062
-rw-r--r--flang/test/Lower/Coarray/sync_memory.f9037
-rw-r--r--flang/test/Lower/MIF/co_broadcast.f9057
-rw-r--r--flang/test/Lower/MIF/co_max.f9060
-rw-r--r--flang/test/Lower/MIF/co_min.f9060
-rw-r--r--flang/test/Lower/MIF/co_sum.f9051
-rw-r--r--flang/test/Lower/MIF/coarray-init.f90 (renamed from flang/test/Lower/Coarray/coarray-init.f90)4
-rw-r--r--flang/test/Lower/MIF/num_images.f90 (renamed from flang/test/Lower/Coarray/num_images.f90)6
-rw-r--r--flang/test/Lower/MIF/sync_all.f9027
-rw-r--r--flang/test/Lower/MIF/sync_images.f9039
-rw-r--r--flang/test/Lower/MIF/sync_memory.f9027
-rw-r--r--flang/test/Lower/MIF/this_image.f90 (renamed from flang/test/Lower/Coarray/this_image.f90)4
-rw-r--r--flang/test/Lower/OpenACC/acc-unstructured.f901
-rw-r--r--flang/test/Parser/OpenMP/requires.f9013
-rw-r--r--flang/test/Semantics/OpenMP/combined-constructs.f902
-rw-r--r--flang/test/Semantics/OpenMP/do05.f904
-rw-r--r--flang/test/Semantics/OpenMP/linear-iter.f906
-rw-r--r--flang/test/Semantics/OpenMP/nested-distribute.f9013
-rw-r--r--flang/tools/bbc/CMakeLists.txt1
-rw-r--r--flang/tools/fir-lsp-server/CMakeLists.txt3
-rw-r--r--flang/tools/fir-opt/CMakeLists.txt1
-rw-r--r--flang/tools/tco/CMakeLists.txt1
-rw-r--r--flang/unittests/Optimizer/CMakeLists.txt4
85 files changed, 2445 insertions, 1042 deletions
diff --git a/flang/include/flang/Lower/OpenMP/Clauses.h b/flang/include/flang/Lower/OpenMP/Clauses.h
index 273e611..7492466 100644
--- a/flang/include/flang/Lower/OpenMP/Clauses.h
+++ b/flang/include/flang/Lower/OpenMP/Clauses.h
@@ -214,6 +214,7 @@ using Depend = tomp::clause::DependT<TypeTy, IdTy, ExprTy>;
using Destroy = tomp::clause::DestroyT<TypeTy, IdTy, ExprTy>;
using Detach = tomp::clause::DetachT<TypeTy, IdTy, ExprTy>;
using Device = tomp::clause::DeviceT<TypeTy, IdTy, ExprTy>;
+using DeviceSafesync = tomp::clause::DeviceSafesyncT<TypeTy, IdTy, ExprTy>;
using DeviceType = tomp::clause::DeviceTypeT<TypeTy, IdTy, ExprTy>;
using DistSchedule = tomp::clause::DistScheduleT<TypeTy, IdTy, ExprTy>;
using Doacross = tomp::clause::DoacrossT<TypeTy, IdTy, ExprTy>;
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h b/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h
deleted file mode 100644
index 20bfb7c..0000000
--- a/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h
+++ /dev/null
@@ -1,85 +0,0 @@
-//===-- Coarray.h -- generate Coarray intrinsics runtime calls --*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COARRAY_H
-#define FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COARRAY_H
-
-#include "flang/Lower/AbstractConverter.h"
-#include "flang/Optimizer/Support/InternalNames.h"
-#include "mlir/Dialect/Func/IR/FuncOps.h"
-
-namespace fir {
-class ExtendedValue;
-class FirOpBuilder;
-} // namespace fir
-
-namespace fir::runtime {
-
-// Get the function type for a prif subroutine with a variable number of
-// arguments
-#define PRIF_FUNCTYPE(...) \
- mlir::FunctionType::get(builder.getContext(), /*inputs*/ {__VA_ARGS__}, \
- /*result*/ {})
-
-// Default prefix for subroutines of PRIF compiled with LLVM
-#define PRIFNAME_SUB(fmt) \
- []() { \
- std::ostringstream oss; \
- oss << "prif_" << fmt; \
- return fir::NameUniquer::doProcedure({"prif"}, {}, oss.str()); \
- }()
-
-#define PRIF_STAT_TYPE builder.getRefType(builder.getI32Type())
-#define PRIF_ERRMSG_TYPE \
- fir::BoxType::get(fir::CharacterType::get(builder.getContext(), 1, \
- fir::CharacterType::unknownLen()))
-
-/// Generate Call to runtime prif_init
-mlir::Value genInitCoarray(fir::FirOpBuilder &builder, mlir::Location loc);
-
-/// Generate Call to runtime prif_num_images
-mlir::Value getNumImages(fir::FirOpBuilder &builder, mlir::Location loc);
-
-/// Generate Call to runtime prif_num_images_with_team or
-/// prif_num_images_with_team_number
-mlir::Value getNumImagesWithTeam(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value team);
-
-/// Generate Call to runtime prif_this_image_no_coarray
-mlir::Value getThisImage(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value team = {});
-
-/// Generate call to runtime subroutine prif_co_broadcast
-void genCoBroadcast(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value A, mlir::Value sourceImage, mlir::Value stat,
- mlir::Value errmsg);
-
-/// Generate call to runtime subroutine prif_co_max and prif_co_max_character
-void genCoMax(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value A,
- mlir::Value resultImage, mlir::Value stat, mlir::Value errmsg);
-
-/// Generate call to runtime subroutine prif_co_min or prif_co_min_character
-void genCoMin(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value A,
- mlir::Value resultImage, mlir::Value stat, mlir::Value errmsg);
-
-/// Generate call to runtime subroutine prif_co_sum
-void genCoSum(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value A,
- mlir::Value resultImage, mlir::Value stat, mlir::Value errmsg);
-
-/// Generate call to runtime subroutine prif_sync_all
-void genSyncAllStatement(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value stat, mlir::Value errmsg);
-/// Generate call to runtime subroutine prif_sync_memory
-void genSyncMemoryStatement(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value stat, mlir::Value errmsg);
-/// Generate call to runtime subroutine prif_sync_images
-void genSyncImagesStatement(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value imageSet, mlir::Value stat,
- mlir::Value errmsg);
-} // namespace fir::runtime
-#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COARRAY_H
diff --git a/flang/include/flang/Optimizer/Dialect/CMakeLists.txt b/flang/include/flang/Optimizer/Dialect/CMakeLists.txt
index adefcfe..7b1a129 100644
--- a/flang/include/flang/Optimizer/Dialect/CMakeLists.txt
+++ b/flang/include/flang/Optimizer/Dialect/CMakeLists.txt
@@ -1,5 +1,6 @@
add_subdirectory(CUF)
add_subdirectory(FIRCG)
+add_subdirectory(MIF)
# This replicates part of the add_mlir_dialect cmake function from MLIR that
# cannot be used her because it expects to be run inside MLIR directory which
diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h
index ceee24a..a94842d 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRType.h
+++ b/flang/include/flang/Optimizer/Dialect/FIRType.h
@@ -53,6 +53,9 @@ public:
/// Unwrap element type from fir.heap, fir.ptr and fir.array.
mlir::Type unwrapInnerType() const;
+ // Get the element type or the fir.array
+ mlir::Type getElementOrSequenceType() const;
+
/// Is this the box for an assumed rank?
bool isAssumedRank() const;
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/CMakeLists.txt b/flang/include/flang/Optimizer/Dialect/MIF/CMakeLists.txt
new file mode 100644
index 0000000..27ba388
--- /dev/null
+++ b/flang/include/flang/Optimizer/Dialect/MIF/CMakeLists.txt
@@ -0,0 +1,9 @@
+set(LLVM_TARGET_DEFINITIONS MIFDialect.td)
+mlir_tablegen(MIFDialect.h.inc -gen-dialect-decls -dialect=mif)
+mlir_tablegen(MIFDialect.cpp.inc -gen-dialect-defs -dialect=mif)
+
+# Add Multi Image Fortran operations
+set(LLVM_TARGET_DEFINITIONS MIFOps.td)
+mlir_tablegen(MIFOps.h.inc -gen-op-decls)
+mlir_tablegen(MIFOps.cpp.inc -gen-op-defs)
+add_public_tablegen_target(MIFOpsIncGen)
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
new file mode 100644
index 0000000..2f3ab9c
--- /dev/null
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.h
@@ -0,0 +1,28 @@
+//===-- MIF.h - MIF dialect ---------------------------------------*- C++-*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_OPTIMIZER_DIALECT_MIF_MIFDIALECT_H
+#define FORTRAN_OPTIMIZER_DIALECT_MIF_MIFDIALECT_H
+
+#include "mlir/Bytecode/BytecodeOpInterface.h"
+#include "mlir/IR/Dialect.h"
+#include "mlir/IR/OpDefinition.h"
+#include "mlir/IR/OpImplementation.h"
+#include "mlir/IR/SymbolTable.h"
+#include "mlir/Interfaces/CallInterfaces.h"
+#include "mlir/Interfaces/InferTypeOpInterface.h"
+#include "mlir/Interfaces/SideEffectInterfaces.h"
+#include "mlir/Interfaces/VectorInterfaces.h"
+
+//===----------------------------------------------------------------------===//
+// MIFDialect
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Dialect/MIF/MIFDialect.h.inc"
+
+#endif // FORTRAN_OPTIMIZER_DIALECT_MIF_MIFDIALECT_H
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.td
new file mode 100644
index 0000000..f8be6a8
--- /dev/null
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.td
@@ -0,0 +1,38 @@
+//===-- MIFDialect.td - MIF dialect base definitions - tablegen ---------*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Definition of the Multi-Image Fortran (MIF) dialect
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_DIALECT_MIF_MIFDIALECT
+#define FORTRAN_DIALECT_MIF_MIFDIALECT
+
+include "mlir/IR/AttrTypeBase.td"
+include "mlir/IR/EnumAttr.td"
+include "mlir/IR/OpBase.td"
+
+def MIFDialect : Dialect {
+ let name = "mif";
+
+ let summary = "Multi-Image Fortran dialect";
+
+ let description = [{
+ The "MIF" dialect is designed to contain the basic coarray operations
+ in Fortran and all multi image operations as descibed in the standard.
+ This includes synchronization operations, atomic operations,
+ image queries, teams, criticals, etc. The MIF dialect operations use
+ the FIR types and are tightly coupled with FIR and HLFIR.
+ }];
+
+ let cppNamespace = "::mif";
+ let dependentDialects = ["fir::FIROpsDialect"];
+}
+
+#endif // FORTRAN_DIALECT_MIF_MIFDIALECT
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.h b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.h
new file mode 100644
index 0000000..a9e53c2
--- /dev/null
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.h
@@ -0,0 +1,20 @@
+//===-- Optimizer/Dialect/MIF/MIFOps.h - MIF operations ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_OPTIMIZER_DIALECT_MIF_MIFOPS_H
+#define FORTRAN_OPTIMIZER_DIALECT_MIF_MIFOPS_H
+
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Dialect/MIF/MIFDialect.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/IR/OpDefinition.h"
+
+#define GET_OP_CLASSES
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h.inc"
+
+#endif // FORTRAN_OPTIMIZER_DIALECT_MIF_MIFOPS_H
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
new file mode 100644
index 0000000..52471d3
--- /dev/null
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -0,0 +1,268 @@
+//===-- MIFOps.td - MIF operation definitions --------------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Definition of the MIF dialect operations
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_DIALECT_MIF_MIF_OPS
+#define FORTRAN_DIALECT_MIF_MIF_OPS
+
+include "flang/Optimizer/Dialect/MIF/MIFDialect.td"
+include "flang/Optimizer/Dialect/FIRTypes.td"
+include "flang/Optimizer/Dialect/FIRAttr.td"
+
+class mif_Op<string mnemonic, list<Trait> traits>
+ : Op<MIFDialect, mnemonic, traits>;
+
+//===----------------------------------------------------------------------===//
+// Initialization and Finalization
+//===----------------------------------------------------------------------===//
+
+def mif_InitOp : mif_Op<"init", []> {
+ let summary = "Initialize the parallel environment";
+ let description = [{This operation will initialize the parallel environment}];
+
+ let results = (outs I32:$stat);
+ let assemblyFormat = "`->` type($stat) attr-dict";
+}
+
+//===----------------------------------------------------------------------===//
+// Image Queries
+//===----------------------------------------------------------------------===//
+
+def mif_NumImagesOp : mif_Op<"num_images", [AttrSizedOperandSegments]> {
+ let summary = "Query the number of images in the specified or current team";
+ let description = [{
+ This operation query the number of images in the specified or current
+ team and can be called with 3 differents way :
+ - `num_images()`
+ - `num_images(team)`
+ - `num_images(team_number)`
+
+ Arguments:
+ - `team` : Shall be a scalar of type `team_type` from the `ISO_FORTRAN_ENV`
+ module with a value that identifies the current or ancestor team.
+ - `team_number` : Shall be an integer scalar. It shall identify the
+ initial team or a sibling team of the current team.
+
+ Result Value: The number of images in the specified team, or in the current
+ team if no team is specified.
+ }];
+
+ let arguments = (ins Optional<AnyInteger>:$team_number,
+ Optional<AnyRefOrBoxType>:$team);
+ let results = (outs I32:$res);
+
+ let builders = [OpBuilder<(ins CArg<"mlir::Value", "{}">:$teamArg)>];
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ ( `team_number` $team_number^ )?
+ ( `team` $team^ )?
+ attr-dict `:` functional-type(operands, results)
+ }];
+}
+
+def mif_ThisImageOp : mif_Op<"this_image", [AttrSizedOperandSegments]> {
+ let summary = "Determine the image index of the current image";
+ let description = [{
+ Arguments:
+ - `coarray` : Shall be a coarray of any type.
+ - `dim` : Shall be an integer scalar. Its value shall be in the range of
+ 1 <= DIM <= N, where N is the corank of the coarray.
+ - `team`(optional) : Shall be a scalar of type `team_type` from
+ ISO_FORTRAN_ENV. If the `coarray` is present, it shall be
+ established in that team.
+
+ Results:
+ - Case(1) : The result of `this_image([team])` is a scalar with a value
+ equal to the index of the image in the current or specified team.
+ - Case(2) : The result of `this_image(coarray [,team])` is the sequence of
+ cosubscript values for `coarray`.
+ - Case(3) : The result of `this_image(coarray, dim [,team])` is the value of
+ cosubscript `dim` in the sequence of cosubscript values for `coarray`.
+
+ Example:
+ ```fortran
+ REAL :: A[10, 0:9, 0:*]
+ ```
+ If we take a look on the example and we are on image 5, `this_image` has the
+ value 5, `this_image(A)` has the value [5, 0, 0].
+ }];
+
+ let arguments = (ins Optional<fir_BoxType>:$coarray,
+ Optional<AnyInteger>:$dim, Optional<AnyRefOrBoxType>:$team);
+ let results = (outs I32:$res);
+
+ let builders = [OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$team)>,
+ OpBuilder<(ins "mlir::Value":$team)>];
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ ( `coarray` $coarray^ )?
+ ( `team` $team^ )?
+ ( `dim` $dim^ )?
+ attr-dict `:` functional-type(operands, results)
+ }];
+}
+
+//===----------------------------------------------------------------------===//
+// Synchronization
+//===----------------------------------------------------------------------===//
+// NOTE: Every operation in this section corresponds to a Fortran
+// "image control statement" (F23 11.7.1). This means they end a Fortran
+// "segment" and start another (F23 11.7.2), which affects the memory
+// consistency semantics of surrounding accesses in the multi-image execution.
+// For now we've modeled this by *deliberately* omitting mlir::MemoryEffects
+// on these operations, to ensure analysis treats these ops conservatively.
+//===----------------------------------------------------------------------===//
+
+def mif_SyncAllOp : mif_Op<"sync_all", [AttrSizedOperandSegments]> {
+ let summary =
+ "Performs a collective synchronization of all images in the current team";
+
+ let arguments = (ins Optional<AnyReferenceLike>:$stat,
+ Optional<AnyRefOrBoxType>:$errmsg);
+ let assemblyFormat = [{
+ (`stat` $stat^ )?
+ (`errmsg` $errmsg^ )?
+ attr-dict `:` functional-type(operands, results)
+ }];
+}
+
+def mif_SyncImagesOp : mif_Op<"sync_images", [AttrSizedOperandSegments]> {
+ let summary = "Performs a synchronization of image with each of the other "
+ "images in the `image_set`";
+ let description = [{
+ This operation can take an optional argument `⁣image_set`, wich must be an integer expression
+ and must be scalar or rank one. If `image_set` is omitted from the call, this operation will
+ adopt the behavior of the Fortran statement `SYNC IMAGES(*)`.
+ }];
+
+ let arguments = (ins Optional<AnyRefOrBoxType>:$image_set,
+ Optional<AnyReferenceLike>:$stat,
+ Optional<AnyRefOrBoxType>:$errmsg);
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ (`image_set` $image_set^ )?
+ (`stat` $stat^ )?
+ (`errmsg` $errmsg^ )?
+ attr-dict `:` functional-type(operands, results)
+ }];
+}
+
+def mif_SyncMemoryOp : mif_Op<"sync_memory", [AttrSizedOperandSegments]> {
+ let summary = "Operation that ends one segment and begins another.";
+ let description = [{
+ Operation that ends one segment and begins another; Those two segments can
+ be ordered by user-defined way with respect to segments on other images.
+ }];
+
+ let arguments = (ins Optional<AnyReferenceLike>:$stat,
+ Optional<AnyRefOrBoxType>:$errmsg);
+ let assemblyFormat = [{
+ (`stat` $stat^ )?
+ (`errmsg` $errmsg^ )?
+ attr-dict `:` functional-type(operands, results)
+ }];
+}
+
+//===----------------------------------------------------------------------===//
+// Collective Operations
+//===----------------------------------------------------------------------===//
+
+def mif_CoBroadcastOp : mif_Op<"co_broadcast", [AttrSizedOperandSegments,
+ MemoryEffects<[MemWrite]>]> {
+ let summary = "Broadcast value to images.";
+ let description = [{
+ The co_broadcast operation broadcasts a value from one image to the other images.
+ }];
+
+ let arguments = (ins Arg<fir_BoxType, "", [MemRead, MemWrite]>:$a,
+ AnyIntegerType:$source_image,
+ Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+ Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ $a `source` $source_image
+ (`stat` $stat^ )?
+ (`errmsg` $errmsg^ )?
+ attr-dict `:` `(` type(operands) `)`
+ }];
+}
+
+def mif_CoMaxOp
+ : mif_Op<"co_max", [AttrSizedOperandSegments, MemoryEffects<[MemWrite]>]> {
+ let summary = "Compute maximum value across images.";
+ let description = [{
+ The co_max operation performs the computation of the maximum
+ across images.
+ }];
+
+ let arguments = (ins Arg<fir_BoxType, "", [MemRead, MemWrite]>:$a,
+ Optional<AnyIntegerType>:$result_image,
+ Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+ Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ $a (`result` $result_image^ )?
+ (`stat` $stat^ )?
+ (`errmsg` $errmsg^ )?
+ attr-dict `:` `(` type(operands) `)`
+ }];
+}
+
+def mif_CoMinOp
+ : mif_Op<"co_min", [AttrSizedOperandSegments, MemoryEffects<[MemWrite]>]> {
+ let summary = "Compute minimum value across images.";
+ let description = [{
+ The co_min operation performs the computation of the minimum
+ across images.
+ }];
+
+ let arguments = (ins Arg<fir_BoxType, "", [MemRead, MemWrite]>:$a,
+ Optional<AnyIntegerType>:$result_image,
+ Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+ Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ $a (`result` $result_image^ )?
+ (`stat` $stat^ )?
+ (`errmsg` $errmsg^ )?
+ attr-dict `:` `(` type(operands) `)`
+ }];
+}
+
+def mif_CoSumOp
+ : mif_Op<"co_sum", [AttrSizedOperandSegments, MemoryEffects<[MemWrite]>]> {
+ let summary = "Compute sum across images.";
+ let description = [{
+ The co_sum operation performs the computation of the sum
+ across images.
+ }];
+
+ let arguments = (ins Arg<fir_BoxType, "", [MemRead, MemWrite]>:$a,
+ Optional<AnyIntegerType>:$result_image,
+ Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+ Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ $a (`result` $result_image^ )?
+ (`stat` $stat^ )?
+ (`errmsg` $errmsg^ )?
+ attr-dict `:` `(` type(operands) `)`
+ }];
+}
+
+#endif // FORTRAN_DIALECT_MIF_MIF_OPS
diff --git a/flang/include/flang/Optimizer/Support/InitFIR.h b/flang/include/flang/Optimizer/Support/InitFIR.h
index 3e42ffd..67e9287 100644
--- a/flang/include/flang/Optimizer/Support/InitFIR.h
+++ b/flang/include/flang/Optimizer/Support/InitFIR.h
@@ -16,6 +16,7 @@
#include "flang/Optimizer/Dialect/CUF/CUFDialect.h"
#include "flang/Optimizer/Dialect/CUF/CUFToLLVMIRTranslation.h"
#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/MIF/MIFDialect.h"
#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
#include "flang/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.h"
#include "flang/Optimizer/OpenMP/Support/RegisterOpenMPExtensions.h"
@@ -51,7 +52,7 @@ namespace fir::support {
mlir::vector::VectorDialect, mlir::math::MathDialect, \
mlir::complex::ComplexDialect, mlir::DLTIDialect, cuf::CUFDialect, \
mlir::NVVM::NVVMDialect, mlir::gpu::GPUDialect, \
- mlir::index::IndexDialect
+ mlir::index::IndexDialect, mif::MIFDialect
#define FLANG_CODEGEN_DIALECT_LIST FIRCodeGenDialect, mlir::LLVM::LLVMDialect
diff --git a/flang/include/flang/Optimizer/Transforms/MIFOpConversion.h b/flang/include/flang/Optimizer/Transforms/MIFOpConversion.h
new file mode 100644
index 0000000..93c7247
--- /dev/null
+++ b/flang/include/flang/Optimizer/Transforms/MIFOpConversion.h
@@ -0,0 +1,27 @@
+//===------- Optimizer/Transforms/MIFOpToLLVMConversion.h -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_OPTIMIZER_TRANSFORMS_MIFOPCONVERSION_H_
+#define FORTRAN_OPTIMIZER_TRANSFORMS_MIFOPCONVERSION_H_
+
+#include "mlir/Conversion/LLVMCommon/Pattern.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Pass/PassRegistry.h"
+
+namespace fir {
+class LLVMTypeConverter;
+}
+
+namespace mif {
+
+/// Patterns that convert MIF operations to runtime calls.
+void populateMIFOpConversionPatterns(mlir::RewritePatternSet &patterns);
+
+} // namespace mif
+
+#endif // FORTRAN_OPTIMIZER_TRANSFORMS_MIFOPCONVERSION_H_
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td
index e2ba9c3..dcff078 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -580,4 +580,9 @@ def OptimizeArrayRepacking
}];
}
+def MIFOpConversion : Pass<"mif-convert", "mlir::ModuleOp"> {
+ let summary = "Convert some MIF operations to runtime calls";
+ let dependentDialects = ["fir::FIROpsDialect", "mlir::LLVM::LLVMDialect"];
+}
+
#endif // FLANG_OPTIMIZER_TRANSFORMS_PASSES
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 3501790..5677277 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -559,6 +559,7 @@ public:
NODE(OmpDeviceClause, Modifier)
NODE(parser, OmpDeviceModifier)
NODE_ENUM(OmpDeviceModifier, Value)
+ NODE(parser, OmpDeviceSafesyncClause)
NODE(parser, OmpDeviceTypeClause)
NODE_ENUM(OmpDeviceTypeClause, DeviceTypeDescription)
NODE(parser, OmpDirectiveName)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index bb3af9e..6dd4f249 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4418,6 +4418,14 @@ struct OmpDeviceClause {
std::tuple<MODIFIERS(), ScalarIntExpr> t;
};
+// Ref: [6.0:356-362]
+//
+// device-safesync-clause ->
+// DEVICE_SAFESYNC [(scalar-logical-const-expr)] // since 6.0
+struct OmpDeviceSafesyncClause {
+ WRAPPER_CLASS_BOILERPLATE(OmpDeviceSafesyncClause, ScalarLogicalConstantExpr);
+};
+
// Ref: [5.0:180-185], [5.1:210-216], [5.2:275]
//
// device-type-clause ->
diff --git a/flang/include/flang/Parser/tools.h b/flang/include/flang/Parser/tools.h
index a90c856..d105f03 100644
--- a/flang/include/flang/Parser/tools.h
+++ b/flang/include/flang/Parser/tools.h
@@ -259,5 +259,7 @@ template <typename A> std::optional<CharBlock> GetLastSource(A &x) {
// Checks whether the assignment statement has a single variable on the RHS.
bool CheckForSingleVariableOnRHS(const AssignmentStmt &);
+const Name *GetDesignatorNameIfDataRef(const Designator &);
+
} // namespace Fortran::parser
#endif // FORTRAN_PARSER_TOOLS_H_
diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h
index b977fb8..8a7b986 100644
--- a/flang/include/flang/Semantics/tools.h
+++ b/flang/include/flang/Semantics/tools.h
@@ -739,12 +739,6 @@ const DerivedTypeSpec *GetDtvArgDerivedType(const Symbol &);
void WarnOnDeferredLengthCharacterScalar(SemanticsContext &, const SomeExpr *,
parser::CharBlock at, const char *what);
-inline const parser::Name *getDesignatorNameIfDataRef(
- const parser::Designator &designator) {
- const auto *dataRef{std::get_if<parser::DataRef>(&designator.u)};
- return dataRef ? std::get_if<parser::Name>(&dataRef->u) : nullptr;
-}
-
bool CouldBeDataPointerValuedFunction(const Symbol *);
template <typename R, typename T>
diff --git a/flang/lib/Frontend/CMakeLists.txt b/flang/lib/Frontend/CMakeLists.txt
index fa0d5ec..2b3bc0e 100644
--- a/flang/lib/Frontend/CMakeLists.txt
+++ b/flang/lib/Frontend/CMakeLists.txt
@@ -19,6 +19,7 @@ add_flang_library(flangFrontend
FIROptCodeGenPassIncGen
FIROptTransformsPassIncGen
HLFIRDialect
+ MIFDialect
LINK_LIBS
CUFDialect
@@ -41,6 +42,7 @@ add_flang_library(flangFrontend
FIROpenACCSupport
FIROpenMPSupport
FlangOpenMPTransforms
+ MIFDialect
LINK_COMPONENTS
Passes
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 0595ca0..3b711cc 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -58,6 +58,7 @@
#include "flang/Optimizer/Support/InternalNames.h"
#include "flang/Optimizer/Transforms/Passes.h"
#include "flang/Parser/parse-tree.h"
+#include "flang/Parser/tools.h"
#include "flang/Runtime/iostat-consts.h"
#include "flang/Semantics/openmp-dsa.h"
#include "flang/Semantics/runtime-type-info.h"
@@ -3352,7 +3353,7 @@ private:
&var.u)) {
const Fortran::parser::Designator &designator = iDesignator->value();
if (const auto *name =
- Fortran::semantics::getDesignatorNameIfDataRef(designator)) {
+ Fortran::parser::GetDesignatorNameIfDataRef(designator)) {
auto val = getSymbolAddress(*name->symbol);
reduceOperands.push_back(val);
}
diff --git a/flang/lib/Lower/CMakeLists.txt b/flang/lib/Lower/CMakeLists.txt
index eb4d57d..3d0b4e4 100644
--- a/flang/lib/Lower/CMakeLists.txt
+++ b/flang/lib/Lower/CMakeLists.txt
@@ -45,6 +45,7 @@ add_flang_library(FortranLower
FIRDialect
FIRTransforms
HLFIRDialect
+ MIFDialect
LINK_LIBS
CUFAttrs
@@ -61,6 +62,7 @@ add_flang_library(FortranLower
FortranEvaluate
FortranSemantics
FortranUtils
+ MIFDialect
LINK_COMPONENTS
Support
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index cfb1891..b3e8b69 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -30,10 +30,12 @@
#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Parser/parse-tree-visitor.h"
#include "flang/Parser/parse-tree.h"
+#include "flang/Parser/tools.h"
#include "flang/Semantics/expression.h"
#include "flang/Semantics/scope.h"
#include "flang/Semantics/tools.h"
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
+#include "mlir/Dialect/OpenACC/OpenACCUtils.h"
#include "mlir/IR/IRMapping.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/Support/LLVM.h"
@@ -296,7 +298,7 @@ getSymbolFromAccObject(const Fortran::parser::AccObject &accObject) {
if (const auto *designator =
std::get_if<Fortran::parser::Designator>(&accObject.u)) {
if (const auto *name =
- Fortran::semantics::getDesignatorNameIfDataRef(*designator))
+ Fortran::parser::GetDesignatorNameIfDataRef(*designator))
return *name->symbol;
if (const auto *arrayElement =
Fortran::parser::Unwrap<Fortran::parser::ArrayElement>(
@@ -327,7 +329,8 @@ genAtomicCaptureStatement(Fortran::lower::AbstractConverter &converter,
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
mlir::acc::AtomicReadOp::create(firOpBuilder, loc, fromAddress, toAddress,
- mlir::TypeAttr::get(elementType));
+ mlir::TypeAttr::get(elementType),
+ /*ifCond=*/mlir::Value{});
}
/// Used to generate atomic.write operation which is created in existing
@@ -347,7 +350,8 @@ genAtomicWriteStatement(Fortran::lower::AbstractConverter &converter,
rhsExpr = firOpBuilder.createConvert(loc, varType, rhsExpr);
firOpBuilder.restoreInsertionPoint(insertionPoint);
- mlir::acc::AtomicWriteOp::create(firOpBuilder, loc, lhsAddr, rhsExpr);
+ mlir::acc::AtomicWriteOp::create(firOpBuilder, loc, lhsAddr, rhsExpr,
+ /*ifCond=*/mlir::Value{});
}
/// Used to generate atomic.update operation which is created in existing
@@ -463,7 +467,8 @@ static inline void genAtomicUpdateStatement(
mlir::Operation *atomicUpdateOp = nullptr;
atomicUpdateOp =
- mlir::acc::AtomicUpdateOp::create(firOpBuilder, currentLocation, lhsAddr);
+ mlir::acc::AtomicUpdateOp::create(firOpBuilder, currentLocation, lhsAddr,
+ /*ifCond=*/mlir::Value{});
llvm::SmallVector<mlir::Type> varTys = {varType};
llvm::SmallVector<mlir::Location> locs = {currentLocation};
@@ -588,7 +593,9 @@ void genAtomicCapture(Fortran::lower::AbstractConverter &converter,
fir::getBase(converter.genExprValue(assign2.lhs, stmtCtx)).getType();
mlir::Operation *atomicCaptureOp = nullptr;
- atomicCaptureOp = mlir::acc::AtomicCaptureOp::create(firOpBuilder, loc);
+ atomicCaptureOp =
+ mlir::acc::AtomicCaptureOp::create(firOpBuilder, loc,
+ /*ifCond=*/mlir::Value{});
firOpBuilder.createBlock(&(atomicCaptureOp->getRegion(0)));
mlir::Block &block = atomicCaptureOp->getRegion(0).back();
@@ -2712,12 +2719,19 @@ genACC(Fortran::lower::AbstractConverter &converter,
const auto &loopDirective =
std::get<Fortran::parser::AccLoopDirective>(beginLoopDirective.t);
+ mlir::Location currentLocation =
+ converter.genLocation(beginLoopDirective.source);
bool needEarlyExitHandling = false;
- if (eval.lowerAsUnstructured())
+ if (eval.lowerAsUnstructured()) {
needEarlyExitHandling = hasEarlyReturn(eval);
+ // If the loop is lowered in an unstructured fashion, lowering generates
+ // explicit control flow that duplicates the looping semantics of the
+ // loops.
+ if (!needEarlyExitHandling)
+ TODO(currentLocation,
+ "loop with early exit inside OpenACC loop construct");
+ }
- mlir::Location currentLocation =
- converter.genLocation(beginLoopDirective.source);
Fortran::lower::StatementContext stmtCtx;
assert(loopDirective.v == llvm::acc::ACCD_loop &&
@@ -2900,7 +2914,7 @@ static Op createComputeOp(
if (const auto *designator =
std::get_if<Fortran::parser::Designator>(&accObject.u)) {
if (const auto *name =
- Fortran::semantics::getDesignatorNameIfDataRef(
+ Fortran::parser::GetDesignatorNameIfDataRef(
*designator)) {
auto cond = converter.getSymbolAddress(*name->symbol);
selfCond = builder.createConvert(clauseLocation,
@@ -3516,6 +3530,10 @@ genACC(Fortran::lower::AbstractConverter &converter,
converter.genLocation(beginCombinedDirective.source);
Fortran::lower::StatementContext stmtCtx;
+ if (eval.lowerAsUnstructured())
+ TODO(currentLocation,
+ "loop with early exit inside OpenACC combined construct");
+
if (combinedDirective.v == llvm::acc::ACCD_kernels_loop) {
createComputeOp<mlir::acc::KernelsOp>(
converter, currentLocation, eval, semanticsContext, stmtCtx,
@@ -4261,8 +4279,7 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter,
Fortran::common::visitors{
[&](const Fortran::parser::Designator &designator) {
if (const auto *name =
- Fortran::semantics::getDesignatorNameIfDataRef(
- designator)) {
+ Fortran::parser::GetDesignatorNameIfDataRef(designator)) {
genCtors(operandLocation, *name->symbol);
}
},
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index ba34212..2a4ebf1 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -740,6 +740,18 @@ Device make(const parser::OmpClause::Device &inp,
/*DeviceDescription=*/makeExpr(t1, semaCtx)}};
}
+DeviceSafesync make(const parser::OmpClause::DeviceSafesync &inp,
+ semantics::SemanticsContext &semaCtx) {
+ // inp.v -> std::optional<parser::OmpDeviceSafesyncClause>
+ auto &&maybeRequired = maybeApply(
+ [&](const parser::OmpDeviceSafesyncClause &c) {
+ return makeExpr(c.v, semaCtx);
+ },
+ inp.v);
+
+ return DeviceSafesync{/*Required=*/std::move(maybeRequired)};
+}
+
DeviceType make(const parser::OmpClause::DeviceType &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> parser::OmpDeviceTypeClause
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index f86ee01..9495ea6 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -33,6 +33,7 @@
#include "flang/Parser/characters.h"
#include "flang/Parser/openmp-utils.h"
#include "flang/Parser/parse-tree.h"
+#include "flang/Parser/tools.h"
#include "flang/Semantics/openmp-directive-sets.h"
#include "flang/Semantics/openmp-utils.h"
#include "flang/Semantics/tools.h"
@@ -3884,7 +3885,7 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
assert(object && "Expecting object as argument");
auto *designator = semantics::omp::GetDesignatorFromObj(*object);
assert(designator && "Expecting desginator in argument");
- auto *name = semantics::getDesignatorNameIfDataRef(*designator);
+ auto *name = parser::GetDesignatorNameIfDataRef(*designator);
assert(name && "Expecting dataref in designator");
critName = *name;
}
diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp
index b19ca01..cb55524 100644
--- a/flang/lib/Lower/Runtime.cpp
+++ b/flang/lib/Lower/Runtime.cpp
@@ -12,10 +12,10 @@
#include "flang/Lower/OpenMP.h"
#include "flang/Lower/StatementContext.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
-#include "flang/Optimizer/Builder/Runtime/Coarray.h"
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Runtime/misc-intrinsic.h"
#include "flang/Runtime/pointer.h"
@@ -52,7 +52,6 @@ static void genUnreachable(fir::FirOpBuilder &builder, mlir::Location loc) {
static std::pair<mlir::Value, mlir::Value> getStatAndErrmsg(
Fortran::lower::AbstractConverter &converter, mlir::Location loc,
const std::list<Fortran::parser::StatOrErrmsg> &statOrErrList) {
- fir::FirOpBuilder &builder = converter.getFirOpBuilder();
Fortran::lower::StatementContext stmtCtx;
mlir::Value errMsgExpr, statExpr;
@@ -71,16 +70,6 @@ static std::pair<mlir::Value, mlir::Value> getStatAndErrmsg(
statOrErr.u);
}
- if (!statExpr) {
- statExpr = fir::AbsentOp::create(builder, loc,
- builder.getRefType(builder.getI32Type()));
- }
- if (!errMsgExpr) {
- errMsgExpr = fir::AbsentOp::create(
- builder, loc,
- fir::BoxType::get(fir::CharacterType::get(
- builder.getContext(), 1, fir::CharacterType::unknownLen())));
- }
return {statExpr, errMsgExpr};
}
@@ -215,7 +204,7 @@ void Fortran::lower::genSyncAllStatement(
auto [statAddr, errMsgAddr] = getStatAndErrmsg(converter, loc, statOrErrList);
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
- fir::runtime::genSyncAllStatement(builder, loc, statAddr, errMsgAddr);
+ mif::SyncAllOp::create(builder, loc, statAddr, errMsgAddr);
}
void Fortran::lower::genSyncImagesStatement(
@@ -244,16 +233,12 @@ void Fortran::lower::genSyncImagesStatement(
fir::getBase(converter.genExprBox(loc, *expr, stmtCtx));
},
[&](const Fortran::parser::Star &) {
- imageSet = fir::AbsentOp::create(
- builder, loc,
- fir::BoxType::get(fir::SequenceType::get(
- {fir::SequenceType::getUnknownExtent()},
- builder.getI32Type())));
+ // Image set is not set.
+ imageSet = mlir::Value{};
}},
imgSet.u);
- fir::runtime::genSyncImagesStatement(builder, loc, imageSet, statAddr,
- errMsgAddr);
+ mif::SyncImagesOp::create(builder, loc, imageSet, statAddr, errMsgAddr);
}
void Fortran::lower::genSyncMemoryStatement(
@@ -267,7 +252,7 @@ void Fortran::lower::genSyncMemoryStatement(
auto [statAddr, errMsgAddr] = getStatAndErrmsg(converter, loc, statOrErrList);
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
- fir::runtime::genSyncMemoryStatement(builder, loc, statAddr, errMsgAddr);
+ mif::SyncMemoryOp::create(builder, loc, statAddr, errMsgAddr);
}
void Fortran::lower::genSyncTeamStatement(
diff --git a/flang/lib/Optimizer/Builder/CMakeLists.txt b/flang/lib/Optimizer/Builder/CMakeLists.txt
index 404afd1..1f95259 100644
--- a/flang/lib/Optimizer/Builder/CMakeLists.txt
+++ b/flang/lib/Optimizer/Builder/CMakeLists.txt
@@ -16,7 +16,6 @@ add_flang_library(FIRBuilder
Runtime/Allocatable.cpp
Runtime/ArrayConstructor.cpp
Runtime/Assign.cpp
- Runtime/Coarray.cpp
Runtime/Character.cpp
Runtime/Command.cpp
Runtime/CUDA/Descriptor.cpp
@@ -42,6 +41,7 @@ add_flang_library(FIRBuilder
CUFDialect
FIRDialect
HLFIRDialect
+ MIFDialect
LINK_LIBS
CUFAttrs
@@ -52,6 +52,7 @@ add_flang_library(FIRBuilder
FortranEvaluate
FortranSupport
HLFIRDialect
+ MIFDialect
MLIR_DEPS
${dialect_libs}
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 0195178..29eedfb 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -25,7 +25,6 @@
#include "flang/Optimizer/Builder/Runtime/Allocatable.h"
#include "flang/Optimizer/Builder/Runtime/CUDA/Descriptor.h"
#include "flang/Optimizer/Builder/Runtime/Character.h"
-#include "flang/Optimizer/Builder/Runtime/Coarray.h"
#include "flang/Optimizer/Builder/Runtime/Command.h"
#include "flang/Optimizer/Builder/Runtime/Derived.h"
#include "flang/Optimizer/Builder/Runtime/Exceptions.h"
@@ -40,6 +39,7 @@
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "flang/Optimizer/Support/FatalError.h"
@@ -412,28 +412,28 @@ static constexpr IntrinsicHandler handlers[]{
{"co_broadcast",
&I::genCoBroadcast,
{{{"a", asBox},
- {"source_image", asAddr},
+ {"source_image", asValue},
{"stat", asAddr, handleDynamicOptional},
{"errmsg", asBox, handleDynamicOptional}}},
/*isElemental*/ false},
{"co_max",
&I::genCoMax,
{{{"a", asBox},
- {"result_image", asAddr, handleDynamicOptional},
+ {"result_image", asValue, handleDynamicOptional},
{"stat", asAddr, handleDynamicOptional},
{"errmsg", asBox, handleDynamicOptional}}},
/*isElemental*/ false},
{"co_min",
&I::genCoMin,
{{{"a", asBox},
- {"result_image", asAddr, handleDynamicOptional},
+ {"result_image", asValue, handleDynamicOptional},
{"stat", asAddr, handleDynamicOptional},
{"errmsg", asBox, handleDynamicOptional}}},
/*isElemental*/ false},
{"co_sum",
&I::genCoSum,
{{{"a", asBox},
- {"result_image", asAddr, handleDynamicOptional},
+ {"result_image", asValue, handleDynamicOptional},
{"stat", asAddr, handleDynamicOptional},
{"errmsg", asBox, handleDynamicOptional}}},
/*isElemental*/ false},
@@ -829,7 +829,7 @@ static constexpr IntrinsicHandler handlers[]{
{"null", &I::genNull, {{{"mold", asInquired}}}, /*isElemental=*/false},
{"num_images",
&I::genNumImages,
- {{{"team", asAddr}, {"team_number", asAddr}}},
+ {{{"team_number", asValue}, {"team", asBox}}},
/*isElemental*/ false},
{"pack",
&I::genPack,
@@ -3516,11 +3516,23 @@ static mlir::Value getAddrFromBox(fir::FirOpBuilder &builder,
return addr;
}
+static void clocDeviceArgRewrite(fir::ExtendedValue arg) {
+ // Special case for device address in c_loc.
+ if (auto emboxOp = mlir::dyn_cast_or_null<fir::EmboxOp>(
+ fir::getBase(arg).getDefiningOp()))
+ if (auto declareOp = mlir::dyn_cast_or_null<hlfir::DeclareOp>(
+ emboxOp.getMemref().getDefiningOp()))
+ if (declareOp.getDataAttr() &&
+ declareOp.getDataAttr() == cuf::DataAttribute::Device)
+ emboxOp.getMemrefMutable().assign(declareOp.getMemref());
+}
+
static fir::ExtendedValue
genCLocOrCFunLoc(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Type resultType, llvm::ArrayRef<fir::ExtendedValue> args,
bool isFunc = false, bool isDevLoc = false) {
assert(args.size() == 1);
+ clocDeviceArgRewrite(args[0]);
mlir::Value res = fir::AllocaOp::create(builder, loc, resultType);
mlir::Value resAddr;
if (isDevLoc)
@@ -3795,79 +3807,40 @@ mlir::Value IntrinsicLibrary::genCmplx(mlir::Type resultType,
void IntrinsicLibrary::genCoBroadcast(llvm::ArrayRef<fir::ExtendedValue> args) {
converter->checkCoarrayEnabled();
assert(args.size() == 4);
- mlir::Value sourceImage = fir::getBase(args[1]);
- mlir::Value status =
- isStaticallyAbsent(args[2])
- ? fir::AbsentOp::create(builder, loc,
- builder.getRefType(builder.getI32Type()))
- .getResult()
- : fir::getBase(args[2]);
- mlir::Value errmsg =
- isStaticallyAbsent(args[3])
- ? fir::AbsentOp::create(builder, loc, PRIF_ERRMSG_TYPE).getResult()
- : fir::getBase(args[3]);
- fir::runtime::genCoBroadcast(builder, loc, fir::getBase(args[0]), sourceImage,
- status, errmsg);
+ mif::CoBroadcastOp::create(builder, loc, fir::getBase(args[0]),
+ /*sourceImage*/ fir::getBase(args[1]),
+ /*status*/ fir::getBase(args[2]),
+ /*errmsg*/ fir::getBase(args[3]));
}
// CO_MAX
void IntrinsicLibrary::genCoMax(llvm::ArrayRef<fir::ExtendedValue> args) {
converter->checkCoarrayEnabled();
assert(args.size() == 4);
- mlir::Value refNone =
- fir::AbsentOp::create(builder, loc,
- builder.getRefType(builder.getI32Type()))
- .getResult();
- mlir::Value resultImage =
- isStaticallyAbsent(args[1]) ? refNone : fir::getBase(args[1]);
- mlir::Value status =
- isStaticallyAbsent(args[2]) ? refNone : fir::getBase(args[2]);
- mlir::Value errmsg =
- isStaticallyAbsent(args[3])
- ? fir::AbsentOp::create(builder, loc, PRIF_ERRMSG_TYPE).getResult()
- : fir::getBase(args[3]);
- fir::runtime::genCoMax(builder, loc, fir::getBase(args[0]), resultImage,
- status, errmsg);
+ mif::CoMaxOp::create(builder, loc, fir::getBase(args[0]),
+ /*resultImage*/ fir::getBase(args[1]),
+ /*status*/ fir::getBase(args[2]),
+ /*errmsg*/ fir::getBase(args[3]));
}
// CO_MIN
void IntrinsicLibrary::genCoMin(llvm::ArrayRef<fir::ExtendedValue> args) {
converter->checkCoarrayEnabled();
assert(args.size() == 4);
- mlir::Value refNone =
- fir::AbsentOp::create(builder, loc,
- builder.getRefType(builder.getI32Type()))
- .getResult();
- mlir::Value resultImage =
- isStaticallyAbsent(args[1]) ? refNone : fir::getBase(args[1]);
- mlir::Value status =
- isStaticallyAbsent(args[2]) ? refNone : fir::getBase(args[2]);
- mlir::Value errmsg =
- isStaticallyAbsent(args[3])
- ? fir::AbsentOp::create(builder, loc, PRIF_ERRMSG_TYPE).getResult()
- : fir::getBase(args[3]);
- fir::runtime::genCoMin(builder, loc, fir::getBase(args[0]), resultImage,
- status, errmsg);
+ mif::CoMinOp::create(builder, loc, fir::getBase(args[0]),
+ /*resultImage*/ fir::getBase(args[1]),
+ /*status*/ fir::getBase(args[2]),
+ /*errmsg*/ fir::getBase(args[3]));
}
// CO_SUM
void IntrinsicLibrary::genCoSum(llvm::ArrayRef<fir::ExtendedValue> args) {
converter->checkCoarrayEnabled();
assert(args.size() == 4);
- mlir::Value absentInt =
- fir::AbsentOp::create(builder, loc,
- builder.getRefType(builder.getI32Type()))
- .getResult();
- mlir::Value resultImage =
- isStaticallyAbsent(args[1]) ? absentInt : fir::getBase(args[1]);
- mlir::Value status =
- isStaticallyAbsent(args[2]) ? absentInt : fir::getBase(args[2]);
- mlir::Value errmsg =
- isStaticallyAbsent(args[3])
- ? fir::AbsentOp::create(builder, loc, PRIF_ERRMSG_TYPE).getResult()
- : fir::getBase(args[3]);
- fir::runtime::genCoSum(builder, loc, fir::getBase(args[0]), resultImage,
- status, errmsg);
+ mif::CoSumOp::create(builder, loc, fir::getBase(args[0]),
+ /*resultImage*/ fir::getBase(args[1]),
+ /*status*/ fir::getBase(args[2]),
+ /*errmsg*/ fir::getBase(args[3]));
}
// COMMAND_ARGUMENT_COUNT
@@ -7579,9 +7552,9 @@ IntrinsicLibrary::genNumImages(mlir::Type resultType,
assert(args.size() == 0 || args.size() == 1);
if (args.size())
- return fir::runtime::getNumImagesWithTeam(builder, loc,
- fir::getBase(args[0]));
- return fir::runtime::getNumImages(builder, loc);
+ return mif::NumImagesOp::create(builder, loc, fir::getBase(args[0]))
+ .getResult();
+ return mif::NumImagesOp::create(builder, loc).getResult();
}
// CLOCK, CLOCK64, GLOBALTIMER
@@ -8659,17 +8632,11 @@ IntrinsicLibrary::genThisImage(mlir::Type resultType,
converter->checkCoarrayEnabled();
assert(args.size() >= 1 && args.size() <= 3);
const bool coarrayIsAbsent = args.size() == 1;
- mlir::Value team =
- !isStaticallyAbsent(args, args.size() - 1)
- ? fir::getBase(args[args.size() - 1])
- : builder
- .create<fir::AbsentOp>(loc,
- fir::BoxType::get(builder.getNoneType()))
- .getResult();
+ mlir::Value team = fir::getBase(args[args.size() - 1]);
if (!coarrayIsAbsent)
TODO(loc, "this_image with coarray argument.");
- mlir::Value res = fir::runtime::getThisImage(builder, loc, team);
+ mlir::Value res = mif::ThisImageOp::create(builder, loc, team);
return builder.createConvert(loc, resultType, res);
}
diff --git a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp
deleted file mode 100644
index 364e7b7..0000000
--- a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-//===-- Coarray.cpp -- runtime API for coarray intrinsics -----------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "flang/Optimizer/Builder/Runtime/Coarray.h"
-#include "flang/Optimizer/Builder/FIRBuilder.h"
-#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
-#include "mlir/Dialect/Func/IR/FuncOps.h"
-
-using namespace Fortran::runtime;
-using namespace Fortran::semantics;
-
-// Most PRIF functions take `errmsg` and `errmsg_alloc` as two optional
-// arguments of intent (out). One is allocatable, the other is not.
-// It is the responsibility of the compiler to ensure that the appropriate
-// optional argument is passed, and at most one must be provided in a given
-// call.
-// Depending on the type of `errmsg`, this function will return the pair
-// corresponding to (`errmsg`, `errmsg_alloc`).
-static std::pair<mlir::Value, mlir::Value>
-genErrmsgPRIF(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value errmsg) {
- bool isAllocatableErrmsg = fir::isAllocatableType(errmsg.getType());
-
- mlir::Value absent = fir::AbsentOp::create(builder, loc, PRIF_ERRMSG_TYPE);
- mlir::Value errMsg = isAllocatableErrmsg ? absent : errmsg;
- mlir::Value errMsgAlloc = isAllocatableErrmsg ? errmsg : absent;
- return {errMsg, errMsgAlloc};
-}
-
-/// Generate Call to runtime prif_init
-mlir::Value fir::runtime::genInitCoarray(fir::FirOpBuilder &builder,
- mlir::Location loc) {
- mlir::Type i32Ty = builder.getI32Type();
- mlir::Value result = builder.createTemporary(loc, i32Ty);
- mlir::FunctionType ftype = PRIF_FUNCTYPE(builder.getRefType(i32Ty));
- mlir::func::FuncOp funcOp =
- builder.createFunction(loc, PRIFNAME_SUB("init"), ftype);
- llvm::SmallVector<mlir::Value> args =
- fir::runtime::createArguments(builder, loc, ftype, result);
- fir::CallOp::create(builder, loc, funcOp, args);
- return fir::LoadOp::create(builder, loc, result);
-}
-
-/// Generate Call to runtime prif_num_images
-mlir::Value fir::runtime::getNumImages(fir::FirOpBuilder &builder,
- mlir::Location loc) {
- mlir::Value result = builder.createTemporary(loc, builder.getI32Type());
- mlir::FunctionType ftype =
- PRIF_FUNCTYPE(builder.getRefType(builder.getI32Type()));
- mlir::func::FuncOp funcOp =
- builder.createFunction(loc, PRIFNAME_SUB("num_images"), ftype);
- llvm::SmallVector<mlir::Value> args =
- fir::runtime::createArguments(builder, loc, ftype, result);
- fir::CallOp::create(builder, loc, funcOp, args);
- return fir::LoadOp::create(builder, loc, result);
-}
-
-/// Generate Call to runtime prif_num_images_with_{team|team_number}
-mlir::Value fir::runtime::getNumImagesWithTeam(fir::FirOpBuilder &builder,
- mlir::Location loc,
- mlir::Value team) {
- bool isTeamNumber = fir::unwrapPassByRefType(team.getType()).isInteger();
- std::string numImagesName = isTeamNumber
- ? PRIFNAME_SUB("num_images_with_team_number")
- : PRIFNAME_SUB("num_images_with_team");
-
- mlir::Value result = builder.createTemporary(loc, builder.getI32Type());
- mlir::Type refTy = builder.getRefType(builder.getI32Type());
- mlir::FunctionType ftype =
- isTeamNumber
- ? PRIF_FUNCTYPE(builder.getRefType(builder.getI64Type()), refTy)
- : PRIF_FUNCTYPE(fir::BoxType::get(builder.getNoneType()), refTy);
- mlir::func::FuncOp funcOp = builder.createFunction(loc, numImagesName, ftype);
-
- if (!isTeamNumber)
- team = builder.createBox(loc, team);
- llvm::SmallVector<mlir::Value> args =
- fir::runtime::createArguments(builder, loc, ftype, team, result);
- fir::CallOp::create(builder, loc, funcOp, args);
- return fir::LoadOp::create(builder, loc, result);
-}
-
-/// Generate Call to runtime prif_this_image_no_coarray
-mlir::Value fir::runtime::getThisImage(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Value team) {
- mlir::Type refTy = builder.getRefType(builder.getI32Type());
- mlir::Type boxTy = fir::BoxType::get(builder.getNoneType());
- mlir::FunctionType ftype = PRIF_FUNCTYPE(boxTy, refTy);
- mlir::func::FuncOp funcOp =
- builder.createFunction(loc, PRIFNAME_SUB("this_image_no_coarray"), ftype);
-
- mlir::Value result = builder.createTemporary(loc, builder.getI32Type());
- mlir::Value teamArg =
- !team ? fir::AbsentOp::create(builder, loc, boxTy) : team;
- llvm::SmallVector<mlir::Value> args =
- fir::runtime::createArguments(builder, loc, ftype, teamArg, result);
- fir::CallOp::create(builder, loc, funcOp, args);
- return fir::LoadOp::create(builder, loc, result);
-}
-
-/// Generate call to collective subroutines except co_reduce
-/// A must be lowered as a box
-void genCollectiveSubroutine(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value A, mlir::Value rootImage,
- mlir::Value stat, mlir::Value errmsg,
- std::string coName) {
- mlir::Type boxTy = fir::BoxType::get(builder.getNoneType());
- mlir::FunctionType ftype =
- PRIF_FUNCTYPE(boxTy, builder.getRefType(builder.getI32Type()),
- PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE);
- mlir::func::FuncOp funcOp = builder.createFunction(loc, coName, ftype);
-
- auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg);
- llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
- builder, loc, ftype, A, rootImage, stat, errmsgArg, errmsgAllocArg);
- fir::CallOp::create(builder, loc, funcOp, args);
-}
-
-/// Generate call to runtime subroutine prif_co_broadcast
-void fir::runtime::genCoBroadcast(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Value A,
- mlir::Value sourceImage, mlir::Value stat,
- mlir::Value errmsg) {
- genCollectiveSubroutine(builder, loc, A, sourceImage, stat, errmsg,
- PRIFNAME_SUB("co_broadcast"));
-}
-
-/// Generate call to runtime subroutine prif_co_max or prif_co_max_character
-void fir::runtime::genCoMax(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value A, mlir::Value resultImage,
- mlir::Value stat, mlir::Value errmsg) {
- mlir::Type argTy =
- fir::unwrapSequenceType(fir::unwrapPassByRefType(A.getType()));
- if (mlir::isa<fir::CharacterType>(argTy))
- genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg,
- PRIFNAME_SUB("co_max_character"));
- else
- genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg,
- PRIFNAME_SUB("co_max"));
-}
-
-/// Generate call to runtime subroutine prif_co_min or prif_co_min_character
-void fir::runtime::genCoMin(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value A, mlir::Value resultImage,
- mlir::Value stat, mlir::Value errmsg) {
- mlir::Type argTy =
- fir::unwrapSequenceType(fir::unwrapPassByRefType(A.getType()));
- if (mlir::isa<fir::CharacterType>(argTy))
- genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg,
- PRIFNAME_SUB("co_min_character"));
- else
- genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg,
- PRIFNAME_SUB("co_min"));
-}
-
-/// Generate call to runtime subroutine prif_co_sum
-void fir::runtime::genCoSum(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value A, mlir::Value resultImage,
- mlir::Value stat, mlir::Value errmsg) {
- genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg,
- PRIFNAME_SUB("co_sum"));
-}
-
-/// Generate call to runtime subroutine prif_sync_all
-void fir::runtime::genSyncAllStatement(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Value stat,
- mlir::Value errmsg) {
- mlir::FunctionType ftype =
- PRIF_FUNCTYPE(PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE);
- mlir::func::FuncOp funcOp =
- builder.createFunction(loc, PRIFNAME_SUB("sync_all"), ftype);
-
- auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg);
- llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
- builder, loc, ftype, stat, errmsgArg, errmsgAllocArg);
- fir::CallOp::create(builder, loc, funcOp, args);
-}
-
-/// Generate call to runtime subroutine prif_sync_memory
-void fir::runtime::genSyncMemoryStatement(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Value stat,
- mlir::Value errmsg) {
- mlir::FunctionType ftype =
- PRIF_FUNCTYPE(PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE);
- mlir::func::FuncOp funcOp =
- builder.createFunction(loc, PRIFNAME_SUB("sync_memory"), ftype);
-
- auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg);
- llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
- builder, loc, ftype, stat, errmsgArg, errmsgAllocArg);
- fir::CallOp::create(builder, loc, funcOp, args);
-}
-
-/// Generate call to runtime subroutine prif_sync_images
-void fir::runtime::genSyncImagesStatement(fir::FirOpBuilder &builder,
- mlir::Location loc,
- mlir::Value imageSet,
- mlir::Value stat,
- mlir::Value errmsg) {
- mlir::Type imgSetTy = fir::BoxType::get(fir::SequenceType::get(
- {fir::SequenceType::getUnknownExtent()}, builder.getI32Type()));
- mlir::FunctionType ftype = PRIF_FUNCTYPE(imgSetTy, PRIF_STAT_TYPE,
- PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE);
- mlir::func::FuncOp funcOp =
- builder.createFunction(loc, PRIFNAME_SUB("sync_images"), ftype);
-
- // If imageSet is scalar, PRIF require to pass an array of size 1.
- if (auto boxTy = mlir::dyn_cast<fir::BoxType>(imageSet.getType())) {
- if (!mlir::isa<fir::SequenceType>(boxTy.getEleTy())) {
- mlir::Value one =
- builder.createIntegerConstant(loc, builder.getI32Type(), 1);
- mlir::Value shape = fir::ShapeOp::create(builder, loc, one);
- imageSet = fir::ReboxOp::create(
- builder, loc,
- fir::BoxType::get(fir::SequenceType::get({1}, builder.getI32Type())),
- imageSet, shape, mlir::Value{});
- }
- }
- auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg);
- llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
- builder, loc, ftype, imageSet, stat, errmsgArg, errmsgAllocArg);
- fir::CallOp::create(builder, loc, funcOp, args);
-}
diff --git a/flang/lib/Optimizer/Builder/Runtime/Main.cpp b/flang/lib/Optimizer/Builder/Runtime/Main.cpp
index d303e0a..9ce5e17 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Main.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Main.cpp
@@ -10,11 +10,11 @@
#include "flang/Lower/EnvironmentDefault.h"
#include "flang/Optimizer/Builder/BoxValue.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
-#include "flang/Optimizer/Builder/Runtime/Coarray.h"
#include "flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h"
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
#include "flang/Runtime/CUDA/init.h"
#include "flang/Runtime/main.h"
#include "flang/Runtime/stop.h"
@@ -71,7 +71,7 @@ void fir::runtime::genMain(
fir::CallOp::create(builder, loc, initFn);
}
if (initCoarrayEnv)
- fir::runtime::genInitCoarray(builder, loc);
+ mif::InitOp::create(builder, loc);
fir::CallOp::create(builder, loc, qqMainFn);
fir::CallOp::create(builder, loc, stopFn);
diff --git a/flang/lib/Optimizer/Dialect/CMakeLists.txt b/flang/lib/Optimizer/Dialect/CMakeLists.txt
index 4fd4d28..65d1f2c 100644
--- a/flang/lib/Optimizer/Dialect/CMakeLists.txt
+++ b/flang/lib/Optimizer/Dialect/CMakeLists.txt
@@ -1,6 +1,7 @@
add_subdirectory(Support)
add_subdirectory(CUF)
add_subdirectory(FIRCG)
+add_subdirectory(MIF)
add_flang_library(FIRDialect
FIRAttr.cpp
diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp
index 48e1622..fe35b08 100644
--- a/flang/lib/Optimizer/Dialect/FIRType.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -1427,6 +1427,13 @@ mlir::Type BaseBoxType::unwrapInnerType() const {
return fir::unwrapInnerType(getEleTy());
}
+mlir::Type BaseBoxType::getElementOrSequenceType() const {
+ mlir::Type eleTy = getEleTy();
+ if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(eleTy))
+ return seqTy;
+ return fir::unwrapRefType(eleTy);
+}
+
static mlir::Type
changeTypeShape(mlir::Type type,
std::optional<fir::SequenceType::ShapeRef> newShape) {
diff --git a/flang/lib/Optimizer/Dialect/MIF/CMakeLists.txt b/flang/lib/Optimizer/Dialect/MIF/CMakeLists.txt
new file mode 100644
index 0000000..d52ab09
--- /dev/null
+++ b/flang/lib/Optimizer/Dialect/MIF/CMakeLists.txt
@@ -0,0 +1,20 @@
+add_flang_library(MIFDialect
+ MIFDialect.cpp
+ MIFOps.cpp
+
+ DEPENDS
+ MLIRIR
+ MIFOpsIncGen
+
+ LINK_LIBS
+ FIRDialect
+ FIRDialectSupport
+ FIRSupport
+ MLIRIR
+ MLIRTargetLLVMIRExport
+
+ LINK_COMPONENTS
+ AsmParser
+ AsmPrinter
+ Remarks
+)
diff --git a/flang/lib/Optimizer/Dialect/MIF/MIFDialect.cpp b/flang/lib/Optimizer/Dialect/MIF/MIFDialect.cpp
new file mode 100644
index 0000000..edc723d
--- /dev/null
+++ b/flang/lib/Optimizer/Dialect/MIF/MIFDialect.cpp
@@ -0,0 +1,24 @@
+//===- MIFDialect.cpp - MIF dialect implementation ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+// C
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Dialect/MIF/MIFDialect.h"
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
+
+//===----------------------------------------------------------------------===//
+/// Tablegen Definitions
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Dialect/MIF/MIFDialect.cpp.inc"
+
+void mif::MIFDialect::initialize() {
+ addOperations<
+#define GET_OP_LIST
+#include "flang/Optimizer/Dialect/MIF/MIFOps.cpp.inc"
+ >();
+}
diff --git a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
new file mode 100644
index 0000000..c6cc2e8
--- /dev/null
+++ b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp
@@ -0,0 +1,153 @@
+//===-- MIFOps.cpp - MIF dialect ops implementation -----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
+#include "flang/Optimizer/Builder/Todo.h"
+#include "flang/Optimizer/Dialect/FIRAttr.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Dialect/MIF/MIFDialect.h"
+#include "mlir/IR/Matchers.h"
+#include "mlir/IR/PatternMatch.h"
+#include "llvm/ADT/SmallVector.h"
+
+#define GET_OP_CLASSES
+#include "flang/Optimizer/Dialect/MIF/MIFOps.cpp.inc"
+
+//===----------------------------------------------------------------------===//
+// NumImagesOp
+//===----------------------------------------------------------------------===//
+
+void mif::NumImagesOp::build(mlir::OpBuilder &builder,
+ mlir::OperationState &result,
+ mlir::Value teamArg) {
+ bool isTeamNumber =
+ teamArg && fir::unwrapPassByRefType(teamArg.getType()).isInteger();
+ if (isTeamNumber)
+ build(builder, result, teamArg, /*team*/ mlir::Value{});
+ else
+ build(builder, result, /*team_number*/ mlir::Value{}, teamArg);
+}
+
+llvm::LogicalResult mif::NumImagesOp::verify() {
+ if (getTeam() && getTeamNumber())
+ return emitOpError(
+ "team and team_number must not be provided at the same time");
+ return mlir::success();
+}
+
+//===----------------------------------------------------------------------===//
+// ThisImageOp
+//===----------------------------------------------------------------------===//
+
+void mif::ThisImageOp::build(mlir::OpBuilder &builder,
+ mlir::OperationState &result, mlir::Value coarray,
+ mlir::Value team) {
+ build(builder, result, coarray, /*dim*/ mlir::Value{}, team);
+}
+
+void mif::ThisImageOp::build(mlir::OpBuilder &builder,
+ mlir::OperationState &result, mlir::Value team) {
+ build(builder, result, /*coarray*/ mlir::Value{}, /*dim*/ mlir::Value{},
+ team);
+}
+
+llvm::LogicalResult mif::ThisImageOp::verify() {
+ if (getDim() && !getCoarray())
+ return emitOpError(
+ "`dim` must be provied at the same time as the `coarray` argument.");
+ return mlir::success();
+}
+
+//===----------------------------------------------------------------------===//
+// SyncImagesOp
+//===----------------------------------------------------------------------===//
+
+llvm::LogicalResult mif::SyncImagesOp::verify() {
+ if (getImageSet()) {
+ mlir::Type t = getImageSet().getType();
+ fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(t);
+ if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(
+ boxTy.getElementOrSequenceType())) {
+ if (seqTy.getDimension() != 0 && seqTy.getDimension() != 1)
+ return emitOpError(
+ "`image_set` must be a boxed integer expression of rank 1.");
+ if (!fir::isa_integer(seqTy.getElementType()))
+ return emitOpError("`image_set` must be a boxed array of integer.");
+ } else if (!fir::isa_integer(boxTy.getElementType()))
+ return emitOpError(
+ "`image_set` must be a boxed scalar integer expression.");
+ }
+ return mlir::success();
+}
+
+//===----------------------------------------------------------------------===//
+// CoBroadcastOp
+//===----------------------------------------------------------------------===//
+
+llvm::LogicalResult mif::CoBroadcastOp::verify() {
+ fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType());
+
+ if (fir::isPolymorphicType(boxTy))
+ return emitOpError("`A` cannot be polymorphic.");
+ else if (auto recTy =
+ mlir::dyn_cast<fir::RecordType>(boxTy.getElementType())) {
+ for (auto component : recTy.getTypeList()) {
+ if (fir::isPolymorphicType(component.second))
+ TODO(getLoc(), "`A` with polymorphic subobject component.");
+ }
+ }
+ return mlir::success();
+}
+
+//===----------------------------------------------------------------------===//
+// CoMaxOp
+//===----------------------------------------------------------------------===//
+
+llvm::LogicalResult mif::CoMaxOp::verify() {
+ fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType());
+ mlir::Type elemTy = boxTy.getElementOrSequenceType();
+ if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(elemTy))
+ elemTy = seqTy.getElementType();
+
+ if (!fir::isa_real(elemTy) && !fir::isa_integer(elemTy) &&
+ !fir::isa_char(elemTy))
+ return emitOpError("`A` shall be of type integer, real or character.");
+ return mlir::success();
+}
+
+//===----------------------------------------------------------------------===//
+// CoMinOp
+//===----------------------------------------------------------------------===//
+
+llvm::LogicalResult mif::CoMinOp::verify() {
+ fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType());
+ mlir::Type elemTy = boxTy.getElementOrSequenceType();
+ if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(elemTy))
+ elemTy = seqTy.getElementType();
+
+ if (!fir::isa_real(elemTy) && !fir::isa_integer(elemTy) &&
+ !fir::isa_char(elemTy))
+ return emitOpError("`A` shall be of type integer, real or character.");
+ return mlir::success();
+}
+
+//===----------------------------------------------------------------------===//
+// CoSumOp
+//===----------------------------------------------------------------------===//
+
+llvm::LogicalResult mif::CoSumOp::verify() {
+ fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType());
+ mlir::Type elemTy = boxTy.getElementOrSequenceType();
+ if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(elemTy))
+ elemTy = seqTy.getElementType();
+
+ if (!fir::isa_real(elemTy) && !fir::isa_integer(elemTy) &&
+ !fir::isa_complex(elemTy))
+ return emitOpError("`A` shall be of numeric type.");
+ return mlir::success();
+}
diff --git a/flang/lib/Optimizer/OpenACC/Transforms/CMakeLists.txt b/flang/lib/Optimizer/OpenACC/Transforms/CMakeLists.txt
index 2427da0..ed177ba 100644
--- a/flang/lib/Optimizer/OpenACC/Transforms/CMakeLists.txt
+++ b/flang/lib/Optimizer/OpenACC/Transforms/CMakeLists.txt
@@ -5,8 +5,10 @@ add_flang_library(FIROpenACCTransforms
FIROpenACCPassesIncGen
LINK_LIBS
+ FIRDialect
+
+ MLIR_LIBS
MLIRIR
MLIRPass
- FIRDialect
MLIROpenACCDialect
)
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp
index 1ecb6d3..6dae39b 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -354,6 +354,7 @@ void createDebugPasses(mlir::PassManager &pm,
void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
MLIRToLLVMPassPipelineConfig config,
llvm::StringRef inputFilename) {
+ pm.addPass(fir::createMIFOpConversion());
fir::addBoxedProcedurePass(pm);
if (config.OptLevel.isOptimizingForSpeed() && config.AliasAnalysis &&
!disableFirAliasTags && !useOldAliasTags)
diff --git a/flang/lib/Optimizer/Transforms/CMakeLists.txt b/flang/lib/Optimizer/Transforms/CMakeLists.txt
index 4ec1627..0388439 100644
--- a/flang/lib/Optimizer/Transforms/CMakeLists.txt
+++ b/flang/lib/Optimizer/Transforms/CMakeLists.txt
@@ -36,6 +36,7 @@ add_flang_library(FIRTransforms
SimplifyFIROperations.cpp
OptimizeArrayRepacking.cpp
ConvertComplexPow.cpp
+ MIFOpConversion.cpp
DEPENDS
CUFAttrs
@@ -43,6 +44,7 @@ add_flang_library(FIRTransforms
FIRDialect
FIROptTransformsPassIncGen
HLFIROpsIncGen
+ MIFDialect
LINK_LIBS
CUFAttrs
@@ -56,6 +58,7 @@ add_flang_library(FIRTransforms
FIRSupport
FortranSupport
HLFIRDialect
+ MIFDialect
MLIR_LIBS
MLIRAffineUtils
diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
new file mode 100644
index 0000000..206cb9b
--- /dev/null
+++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp
@@ -0,0 +1,464 @@
+//===-- MIFOpConversion.cpp -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Transforms/MIFOpConversion.h"
+#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
+#include "flang/Optimizer/Builder/Todo.h"
+#include "flang/Optimizer/CodeGen/TypeConverter.h"
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
+#include "flang/Optimizer/HLFIR/HLFIROps.h"
+#include "flang/Optimizer/Support/DataLayout.h"
+#include "flang/Optimizer/Support/InternalNames.h"
+#include "mlir/IR/Matchers.h"
+#include "mlir/Transforms/DialectConversion.h"
+#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
+
+namespace fir {
+#define GEN_PASS_DEF_MIFOPCONVERSION
+#include "flang/Optimizer/Transforms/Passes.h.inc"
+} // namespace fir
+
+using namespace mlir;
+using namespace Fortran::runtime;
+
+namespace {
+
+// Default prefix for subroutines of PRIF compiled with LLVM
+static std::string getPRIFProcName(std::string fmt) {
+ std::ostringstream oss;
+ oss << "prif_" << fmt;
+ return fir::NameUniquer::doProcedure({"prif"}, {}, oss.str());
+}
+
+static mlir::Type getPRIFStatType(fir::FirOpBuilder &builder) {
+ return builder.getRefType(builder.getI32Type());
+}
+
+static mlir::Type getPRIFErrmsgType(fir::FirOpBuilder &builder) {
+ return fir::BoxType::get(fir::CharacterType::get(
+ builder.getContext(), 1, fir::CharacterType::unknownLen()));
+}
+
+// Most PRIF functions take `errmsg` and `errmsg_alloc` as two optional
+// arguments of intent (out). One is allocatable, the other is not.
+// It is the responsibility of the compiler to ensure that the appropriate
+// optional argument is passed, and at most one must be provided in a given
+// call.
+// Depending on the type of `errmsg`, this function will return the pair
+// corresponding to (`errmsg`, `errmsg_alloc`).
+static std::pair<mlir::Value, mlir::Value>
+genErrmsgPRIF(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value errmsg) {
+ mlir::Value absent =
+ fir::AbsentOp::create(builder, loc, getPRIFErrmsgType(builder));
+ if (!errmsg)
+ return {absent, absent};
+
+ bool isAllocatableErrmsg = fir::isAllocatableType(errmsg.getType());
+ mlir::Value errMsg = isAllocatableErrmsg ? absent : errmsg;
+ mlir::Value errMsgAlloc = isAllocatableErrmsg ? errmsg : absent;
+ return {errMsg, errMsgAlloc};
+}
+
+/// Convert mif.init operation to runtime call of 'prif_init'
+struct MIFInitOpConversion : public mlir::OpRewritePattern<mif::InitOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::InitOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::Type i32Ty = builder.getI32Type();
+ mlir::Value result = builder.createTemporary(loc, i32Ty);
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/ {builder.getRefType(i32Ty)}, /*results*/ {});
+ mlir::func::FuncOp funcOp =
+ builder.createFunction(loc, getPRIFProcName("init"), ftype);
+ llvm::SmallVector<mlir::Value> args =
+ fir::runtime::createArguments(builder, loc, ftype, result);
+ fir::CallOp::create(builder, loc, funcOp, args);
+ rewriter.replaceOpWithNewOp<fir::LoadOp>(op, result);
+ return mlir::success();
+ }
+};
+
+/// Convert mif.this_image operation to PRIF runtime call
+struct MIFThisImageOpConversion
+ : public mlir::OpRewritePattern<mif::ThisImageOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::ThisImageOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ if (op.getCoarray())
+ TODO(loc, "mif.this_image op with coarray argument.");
+ else {
+ mlir::Type i32Ty = builder.getI32Type();
+ mlir::Type boxTy = fir::BoxType::get(rewriter.getNoneType());
+ mlir::Value result = builder.createTemporary(loc, i32Ty);
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/ {boxTy, builder.getRefType(i32Ty)}, /*results*/ {});
+ mlir::Value teamArg = op.getTeam();
+ if (!op.getTeam())
+ teamArg = fir::AbsentOp::create(builder, loc, boxTy);
+
+ mlir::func::FuncOp funcOp = builder.createFunction(
+ loc, getPRIFProcName("this_image_no_coarray"), ftype);
+ llvm::SmallVector<mlir::Value> args =
+ fir::runtime::createArguments(builder, loc, ftype, teamArg, result);
+ fir::CallOp::create(builder, loc, funcOp, args);
+ rewriter.replaceOpWithNewOp<fir::LoadOp>(op, result);
+ return mlir::success();
+ }
+ }
+};
+
+/// Convert mif.num_images operation to runtime call of
+/// prif_num_images_with_{team|team_number}
+struct MIFNumImagesOpConversion
+ : public mlir::OpRewritePattern<mif::NumImagesOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::NumImagesOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::Type i32Ty = builder.getI32Type();
+ mlir::Type i64Ty = builder.getI64Type();
+ mlir::Type boxTy = fir::BoxType::get(rewriter.getNoneType());
+ mlir::Value result = builder.createTemporary(loc, i32Ty);
+
+ mlir::func::FuncOp funcOp;
+ llvm::SmallVector<mlir::Value> args;
+ if (!op.getTeam() && !op.getTeamNumber()) {
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/ {builder.getRefType(i32Ty)}, /*results*/ {});
+ funcOp =
+ builder.createFunction(loc, getPRIFProcName("num_images"), ftype);
+ args = fir::runtime::createArguments(builder, loc, ftype, result);
+ } else {
+ if (op.getTeam()) {
+ mlir::FunctionType ftype =
+ mlir::FunctionType::get(builder.getContext(),
+ /*inputs*/
+ {boxTy, builder.getRefType(i32Ty)},
+ /*results*/ {});
+ funcOp = builder.createFunction(
+ loc, getPRIFProcName("num_images_with_team"), ftype);
+ args = fir::runtime::createArguments(builder, loc, ftype, op.getTeam(),
+ result);
+ } else {
+ mlir::Value teamNumber = builder.createTemporary(loc, i64Ty);
+ mlir::Value cst = op.getTeamNumber();
+ if (op.getTeamNumber().getType() != i64Ty)
+ cst = fir::ConvertOp::create(builder, loc, i64Ty, op.getTeamNumber());
+ fir::StoreOp::create(builder, loc, cst, teamNumber);
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/ {builder.getRefType(i64Ty), builder.getRefType(i32Ty)},
+ /*results*/ {});
+ funcOp = builder.createFunction(
+ loc, getPRIFProcName("num_images_with_team_number"), ftype);
+ args = fir::runtime::createArguments(builder, loc, ftype, teamNumber,
+ result);
+ }
+ }
+ fir::CallOp::create(builder, loc, funcOp, args);
+ rewriter.replaceOpWithNewOp<fir::LoadOp>(op, result);
+ return mlir::success();
+ }
+};
+
+/// Convert mif.sync_all operation to runtime call of 'prif_sync_all'
+struct MIFSyncAllOpConversion : public mlir::OpRewritePattern<mif::SyncAllOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::SyncAllOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::Type errmsgTy = getPRIFErrmsgType(builder);
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/ {getPRIFStatType(builder), errmsgTy, errmsgTy},
+ /*results*/ {});
+ mlir::func::FuncOp funcOp =
+ builder.createFunction(loc, getPRIFProcName("sync_all"), ftype);
+
+ auto [errmsgArg, errmsgAllocArg] =
+ genErrmsgPRIF(builder, loc, op.getErrmsg());
+ mlir::Value stat = op.getStat();
+ if (!stat)
+ stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder));
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, ftype, stat, errmsgArg, errmsgAllocArg);
+ rewriter.replaceOpWithNewOp<fir::CallOp>(op, funcOp, args);
+ return mlir::success();
+ }
+};
+
+/// Convert mif.sync_images operation to runtime call of 'prif_sync_images'
+struct MIFSyncImagesOpConversion
+ : public mlir::OpRewritePattern<mif::SyncImagesOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::SyncImagesOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::Type errmsgTy = getPRIFErrmsgType(builder);
+ mlir::Type imgSetTy = fir::BoxType::get(fir::SequenceType::get(
+ {fir::SequenceType::getUnknownExtent()}, builder.getI32Type()));
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/
+ {imgSetTy, getPRIFStatType(builder), errmsgTy, errmsgTy},
+ /*results*/ {});
+ mlir::func::FuncOp funcOp =
+ builder.createFunction(loc, getPRIFProcName("sync_images"), ftype);
+
+ // If imageSet is scalar, PRIF require to pass an array of size 1.
+ mlir::Value imageSet = op.getImageSet();
+ if (!imageSet)
+ imageSet = fir::AbsentOp::create(builder, loc, imgSetTy);
+ else if (auto boxTy = mlir::dyn_cast<fir::BoxType>(imageSet.getType())) {
+ if (!mlir::isa<fir::SequenceType>(boxTy.getEleTy())) {
+ mlir::Value one =
+ builder.createIntegerConstant(loc, builder.getI32Type(), 1);
+ mlir::Value shape = fir::ShapeOp::create(builder, loc, one);
+ imageSet =
+ fir::ReboxOp::create(builder, loc,
+ fir::BoxType::get(fir::SequenceType::get(
+ {1}, builder.getI32Type())),
+ imageSet, shape, mlir::Value{});
+ }
+ }
+ auto [errmsgArg, errmsgAllocArg] =
+ genErrmsgPRIF(builder, loc, op.getErrmsg());
+ mlir::Value stat = op.getStat();
+ if (!stat)
+ stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder));
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, ftype, imageSet, stat, errmsgArg, errmsgAllocArg);
+ rewriter.replaceOpWithNewOp<fir::CallOp>(op, funcOp, args);
+ return mlir::success();
+ }
+};
+
+/// Convert mif.sync_memory operation to runtime call of 'prif_sync_memory'
+struct MIFSyncMemoryOpConversion
+ : public mlir::OpRewritePattern<mif::SyncMemoryOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::SyncMemoryOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::Type errmsgTy = getPRIFErrmsgType(builder);
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/ {getPRIFStatType(builder), errmsgTy, errmsgTy},
+ /*results*/ {});
+ mlir::func::FuncOp funcOp =
+ builder.createFunction(loc, getPRIFProcName("sync_memory"), ftype);
+
+ auto [errmsgArg, errmsgAllocArg] =
+ genErrmsgPRIF(builder, loc, op.getErrmsg());
+ mlir::Value stat = op.getStat();
+ if (!stat)
+ stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder));
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, ftype, stat, errmsgArg, errmsgAllocArg);
+ rewriter.replaceOpWithNewOp<fir::CallOp>(op, funcOp, args);
+ return mlir::success();
+ }
+};
+
+/// Generate call to collective subroutines except co_reduce
+/// A must be lowered as a box
+static fir::CallOp genCollectiveSubroutine(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value A,
+ mlir::Value image, mlir::Value stat,
+ mlir::Value errmsg,
+ std::string coName) {
+ mlir::Value rootImage;
+ mlir::Type i32Ty = builder.getI32Type();
+ if (!image)
+ rootImage = fir::AbsentOp::create(builder, loc, builder.getRefType(i32Ty));
+ else {
+ rootImage = builder.createTemporary(loc, i32Ty);
+ if (image.getType() != i32Ty)
+ image = fir::ConvertOp::create(builder, loc, i32Ty, image);
+ fir::StoreOp::create(builder, loc, image, rootImage);
+ }
+
+ mlir::Type errmsgTy = getPRIFErrmsgType(builder);
+ mlir::Type boxTy = fir::BoxType::get(builder.getNoneType());
+ mlir::FunctionType ftype =
+ mlir::FunctionType::get(builder.getContext(),
+ /*inputs*/
+ {boxTy, builder.getRefType(builder.getI32Type()),
+ getPRIFStatType(builder), errmsgTy, errmsgTy},
+ /*results*/ {});
+ mlir::func::FuncOp funcOp = builder.createFunction(loc, coName, ftype);
+
+ auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg);
+ if (!stat)
+ stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder));
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, ftype, A, rootImage, stat, errmsgArg, errmsgAllocArg);
+ return fir::CallOp::create(builder, loc, funcOp, args);
+}
+
+/// Convert mif.co_broadcast operation to runtime call of 'prif_co_broadcast'
+struct MIFCoBroadcastOpConversion
+ : public mlir::OpRewritePattern<mif::CoBroadcastOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::CoBroadcastOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ fir::CallOp callOp = genCollectiveSubroutine(
+ builder, loc, op.getA(), op.getSourceImage(), op.getStat(),
+ op.getErrmsg(), getPRIFProcName("co_broadcast"));
+ rewriter.replaceOp(op, callOp);
+ return mlir::success();
+ }
+};
+
+/// Convert mif.co_max operation to runtime call of 'prif_co_max'
+struct MIFCoMaxOpConversion : public mlir::OpRewritePattern<mif::CoMaxOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::CoMaxOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ fir::CallOp callOp;
+ mlir::Type argTy =
+ fir::unwrapSequenceType(fir::unwrapPassByRefType(op.getA().getType()));
+ if (mlir::isa<fir::CharacterType>(argTy))
+ callOp = genCollectiveSubroutine(
+ builder, loc, op.getA(), op.getResultImage(), op.getStat(),
+ op.getErrmsg(), getPRIFProcName("co_max_character"));
+ else
+ callOp = genCollectiveSubroutine(
+ builder, loc, op.getA(), op.getResultImage(), op.getStat(),
+ op.getErrmsg(), getPRIFProcName("co_max"));
+ rewriter.replaceOp(op, callOp);
+ return mlir::success();
+ }
+};
+
+/// Convert mif.co_min operation to runtime call of 'prif_co_min'
+struct MIFCoMinOpConversion : public mlir::OpRewritePattern<mif::CoMinOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::CoMinOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ fir::CallOp callOp;
+ mlir::Type argTy =
+ fir::unwrapSequenceType(fir::unwrapPassByRefType(op.getA().getType()));
+ if (mlir::isa<fir::CharacterType>(argTy))
+ callOp = genCollectiveSubroutine(
+ builder, loc, op.getA(), op.getResultImage(), op.getStat(),
+ op.getErrmsg(), getPRIFProcName("co_min_character"));
+ else
+ callOp = genCollectiveSubroutine(
+ builder, loc, op.getA(), op.getResultImage(), op.getStat(),
+ op.getErrmsg(), getPRIFProcName("co_min"));
+ rewriter.replaceOp(op, callOp);
+ return mlir::success();
+ }
+};
+
+/// Convert mif.co_sum operation to runtime call of 'prif_co_sum'
+struct MIFCoSumOpConversion : public mlir::OpRewritePattern<mif::CoSumOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::CoSumOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ fir::CallOp callOp = genCollectiveSubroutine(
+ builder, loc, op.getA(), op.getResultImage(), op.getStat(),
+ op.getErrmsg(), getPRIFProcName("co_sum"));
+ rewriter.replaceOp(op, callOp);
+ return mlir::success();
+ }
+};
+
+class MIFOpConversion : public fir::impl::MIFOpConversionBase<MIFOpConversion> {
+public:
+ void runOnOperation() override {
+ auto *ctx = &getContext();
+ mlir::RewritePatternSet patterns(ctx);
+ mlir::ConversionTarget target(*ctx);
+
+ mif::populateMIFOpConversionPatterns(patterns);
+
+ target.addLegalDialect<fir::FIROpsDialect>();
+ target.addLegalOp<mlir::ModuleOp>();
+
+ if (mlir::failed(mlir::applyPartialConversion(getOperation(), target,
+ std::move(patterns)))) {
+ mlir::emitError(mlir::UnknownLoc::get(ctx),
+ "error in MIF op conversion\n");
+ return signalPassFailure();
+ }
+ }
+};
+} // namespace
+
+void mif::populateMIFOpConversionPatterns(mlir::RewritePatternSet &patterns) {
+ patterns.insert<MIFInitOpConversion, MIFThisImageOpConversion,
+ MIFNumImagesOpConversion, MIFSyncAllOpConversion,
+ MIFSyncImagesOpConversion, MIFSyncMemoryOpConversion,
+ MIFCoBroadcastOpConversion, MIFCoMaxOpConversion,
+ MIFCoMinOpConversion, MIFCoSumOpConversion>(
+ patterns.getContext());
+}
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index d677e14..56fcac3 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1159,6 +1159,9 @@ TYPE_PARSER( //
construct<OmpDestroyClause>(Parser<OmpObject>{}))))) ||
"DEVICE" >> construct<OmpClause>(construct<OmpClause::Device>(
parenthesized(Parser<OmpDeviceClause>{}))) ||
+ "DEVICE_SAFESYNC" >>
+ construct<OmpClause>(construct<OmpClause::DeviceSafesync>(
+ maybe(parenthesized(scalarLogicalConstantExpr)))) ||
"DEVICE_TYPE" >> construct<OmpClause>(construct<OmpClause::DeviceType>(
parenthesized(Parser<OmpDeviceTypeClause>{}))) ||
"DIST_SCHEDULE" >>
diff --git a/flang/lib/Parser/tools.cpp b/flang/lib/Parser/tools.cpp
index 264ca52..ed6d194 100644
--- a/flang/lib/Parser/tools.cpp
+++ b/flang/lib/Parser/tools.cpp
@@ -179,4 +179,9 @@ bool CheckForSingleVariableOnRHS(const AssignmentStmt &assignmentStmt) {
return Unwrap<Designator>(std::get<Expr>(assignmentStmt.t)) != nullptr;
}
+const Name *GetDesignatorNameIfDataRef(const Designator &designator) {
+ const auto *dataRef{std::get_if<DataRef>(&designator.u)};
+ return dataRef ? std::get_if<Name>(&dataRef->u) : nullptr;
+}
+
} // namespace Fortran::parser
diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp
index 3cd6d6b..5e87b83 100644
--- a/flang/lib/Semantics/check-acc-structure.cpp
+++ b/flang/lib/Semantics/check-acc-structure.cpp
@@ -10,6 +10,7 @@
#include "flang/Common/enum-set.h"
#include "flang/Evaluate/tools.h"
#include "flang/Parser/parse-tree.h"
+#include "flang/Parser/tools.h"
#include "flang/Semantics/symbol.h"
#include "flang/Semantics/tools.h"
#include "flang/Semantics/type.h"
@@ -709,7 +710,8 @@ void AccStructureChecker::CheckMultipleOccurrenceInDeclare(
common::visit(
common::visitors{
[&](const parser::Designator &designator) {
- if (const auto *name = getDesignatorNameIfDataRef(designator)) {
+ if (const auto *name =
+ parser::GetDesignatorNameIfDataRef(designator)) {
if (declareSymbols.contains(&name->symbol->GetUltimate())) {
if (declareSymbols[&name->symbol->GetUltimate()] == clause) {
context_.Warn(common::UsageWarning::OpenAccUsage,
@@ -982,7 +984,8 @@ void AccStructureChecker::Enter(const parser::AccClause::Reduction &reduction) {
common::visit(
common::visitors{
[&](const parser::Designator &designator) {
- if (const auto *name = getDesignatorNameIfDataRef(designator)) {
+ if (const auto *name =
+ parser::GetDesignatorNameIfDataRef(designator)) {
if (name->symbol) {
if (const auto *type{name->symbol->GetType()}) {
if (type->IsNumeric(TypeCategory::Integer) &&
diff --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index c9d0495..aaaa2d6 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -127,24 +127,23 @@ using namespace Fortran::semantics::omp;
void OmpStructureChecker::HasInvalidDistributeNesting(
const parser::OpenMPLoopConstruct &x) {
- bool violation{false};
const parser::OmpDirectiveName &beginName{x.BeginDir().DirName()};
if (llvm::omp::topDistributeSet.test(beginName.v)) {
// `distribute` region has to be nested
- if (!CurrentDirectiveIsNested()) {
- violation = true;
- } else {
+ if (CurrentDirectiveIsNested()) {
// `distribute` region has to be strictly nested inside `teams`
if (!llvm::omp::bottomTeamsSet.test(GetContextParent().directive)) {
- violation = true;
+ context_.Say(beginName.source,
+ "`DISTRIBUTE` region has to be strictly nested inside `TEAMS` "
+ "region."_err_en_US);
}
+ } else {
+ // If not lexically nested (orphaned), issue a warning.
+ context_.Say(beginName.source,
+ "`DISTRIBUTE` must be dynamically enclosed in a `TEAMS` "
+ "region."_warn_en_US);
}
}
- if (violation) {
- context_.Say(beginName.source,
- "`DISTRIBUTE` region has to be strictly nested inside `TEAMS` "
- "region."_err_en_US);
- }
}
void OmpStructureChecker::HasInvalidLoopBinding(
const parser::OpenMPLoopConstruct &x) {
@@ -486,8 +485,8 @@ void OmpStructureChecker::Leave(const parser::OpenMPLoopConstruct &x) {
common::visit(
common::visitors{
[&](const parser::Designator &designator) {
- if (const auto *name{semantics::getDesignatorNameIfDataRef(
- designator)}) {
+ if (const auto *name{
+ parser::GetDesignatorNameIfDataRef(designator)}) {
checkReductionSymbolInScan(name);
}
},
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index ea6fe43..e2f8796 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1535,6 +1535,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPRequiresConstruct &x) {
[&](auto &&s) {
using TypeS = llvm::remove_cvref_t<decltype(s)>;
if constexpr ( //
+ std::is_same_v<TypeS, parser::OmpClause::DeviceSafesync> ||
std::is_same_v<TypeS, parser::OmpClause::DynamicAllocators> ||
std::is_same_v<TypeS, parser::OmpClause::ReverseOffload> ||
std::is_same_v<TypeS, parser::OmpClause::SelfMaps> ||
@@ -2616,7 +2617,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPCriticalConstruct &x) {
auto getNameFromArg{[](const parser::OmpArgument &arg) {
if (auto *object{parser::Unwrap<parser::OmpObject>(arg.u)}) {
if (auto *designator{omp::GetDesignatorFromObj(*object)}) {
- return getDesignatorNameIfDataRef(*designator);
+ return parser::GetDesignatorNameIfDataRef(*designator);
}
}
return static_cast<const parser::Name *>(nullptr);
@@ -5194,6 +5195,10 @@ void OmpStructureChecker::Enter(
CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_atomic_default_mem_order);
}
+void OmpStructureChecker::Enter(const parser::OmpClause::DeviceSafesync &x) {
+ CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_device_safesync);
+}
+
void OmpStructureChecker::Enter(const parser::OmpClause::DynamicAllocators &x) {
CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_dynamic_allocators);
}
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 7067ed3..3bb586c 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -586,6 +586,7 @@ public:
[&](auto &&s) {
using TypeS = llvm::remove_cvref_t<decltype(s)>;
if constexpr ( //
+ std::is_same_v<TypeS, OmpClause::DeviceSafesync> ||
std::is_same_v<TypeS, OmpClause::DynamicAllocators> ||
std::is_same_v<TypeS, OmpClause::ReverseOffload> ||
std::is_same_v<TypeS, OmpClause::SelfMaps> ||
@@ -892,7 +893,7 @@ public:
common::visitors{
[&](const parser::Designator &designator) {
if (const auto *name{
- semantics::getDesignatorNameIfDataRef(designator)}) {
+ parser::GetDesignatorNameIfDataRef(designator)}) {
if (name->symbol) {
name->symbol->set(
ompFlag.value_or(Symbol::Flag::OmpMapStorage));
@@ -1758,7 +1759,7 @@ void AccAttributeVisitor::ResolveAccObject(
common::visitors{
[&](const parser::Designator &designator) {
if (const auto *name{
- semantics::getDesignatorNameIfDataRef(designator)}) {
+ parser::GetDesignatorNameIfDataRef(designator)}) {
if (auto *symbol{ResolveAcc(*name, accFlag, currScope())}) {
AddToContextObjectWithDSA(*symbol, accFlag);
if (dataSharingAttributeFlags.test(accFlag)) {
@@ -3064,7 +3065,7 @@ void OmpAttributeVisitor::ResolveOmpDesignator(
unsigned version{context_.langOptions().OpenMPVersion};
llvm::omp::Directive directive{GetContext().directive};
- const auto *name{semantics::getDesignatorNameIfDataRef(designator)};
+ const auto *name{parser::GetDesignatorNameIfDataRef(designator)};
if (!name) {
// Array sections to be changed to substrings as needed
if (AnalyzeExpr(context_, designator)) {
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 699de41..0af1c94 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1494,7 +1494,7 @@ bool AccVisitor::Pre(const parser::AccClause::UseDevice &x) {
common::visitors{
[&](const parser::Designator &designator) {
if (const auto *name{
- semantics::getDesignatorNameIfDataRef(designator)}) {
+ parser::GetDesignatorNameIfDataRef(designator)}) {
Symbol *prev{currScope().FindSymbol(name->source)};
if (prev != name->symbol) {
name->symbol = prev;
@@ -1648,7 +1648,7 @@ public:
common::visitors{
[&](const parser::Designator &designator) {
if (const auto *name{
- semantics::getDesignatorNameIfDataRef(designator)}) {
+ parser::GetDesignatorNameIfDataRef(designator)}) {
specPartState_.declareTargetNames.insert(name->source);
}
},
@@ -2016,7 +2016,7 @@ void OmpVisitor::ResolveCriticalName(const parser::OmpArgument &arg) {
if (auto *object{parser::Unwrap<parser::OmpObject>(arg.u)}) {
if (auto *desg{omp::GetDesignatorFromObj(*object)}) {
- if (auto *name{getDesignatorNameIfDataRef(*desg)}) {
+ if (auto *name{parser::GetDesignatorNameIfDataRef(*desg)}) {
if (auto *symbol{FindInScope(globalScope, *name)}) {
if (!symbol->test(Symbol::Flag::OmpCriticalLock)) {
SayWithDecl(*name, *symbol,
diff --git a/flang/test/Driver/mlir-debug-pass-pipeline.f90 b/flang/test/Driver/mlir-debug-pass-pipeline.f90
index 5943a3c..eb5165e 100644
--- a/flang/test/Driver/mlir-debug-pass-pipeline.f90
+++ b/flang/test/Driver/mlir-debug-pass-pipeline.f90
@@ -100,6 +100,7 @@ end program
! ALL-NEXT: CSE
! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd
! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
+! ALL-NEXT: MIFOpConversion
! ALL-NEXT: BoxedProcedurePass
! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private']
diff --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90
index df55839..3b6a9d7 100644
--- a/flang/test/Driver/mlir-pass-pipeline.f90
+++ b/flang/test/Driver/mlir-pass-pipeline.f90
@@ -142,6 +142,7 @@ end program
! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
! O2-NEXT: 'func.func' Pipeline
! O2-NEXT: SetRuntimeCallAttributes
+! ALL-NEXT: MIFOpConversion
! ALL-NEXT: BoxedProcedurePass
! O2-NEXT: AddAliasTags
diff --git a/flang/test/Fir/MIF/co_broadcast.mlir b/flang/test/Fir/MIF/co_broadcast.mlir
new file mode 100644
index 0000000..2f5782b
--- /dev/null
+++ b/flang/test/Fir/MIF/co_broadcast.mlir
@@ -0,0 +1,137 @@
+// RUN: fir-opt --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git@github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_CO_BROADCAST"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %c2 = arith.constant 2 : index
+ %1 = fir.alloca !fir.array<2xcomplex<f32>> {bindc_name = "array_c", uniq_name = "_QFEarray_c"}
+ %2 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %3:2 = hlfir.declare %1(%2) {uniq_name = "_QFEarray_c"} : (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.ref<!fir.array<2xcomplex<f32>>>)
+ %c2_0 = arith.constant 2 : index
+ %4 = fir.alloca !fir.array<2xf64> {bindc_name = "array_d", uniq_name = "_QFEarray_d"}
+ %5 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %6:2 = hlfir.declare %4(%5) {uniq_name = "_QFEarray_d"} : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf64>>, !fir.ref<!fir.array<2xf64>>)
+ %c2_1 = arith.constant 2 : index
+ %7 = fir.alloca !fir.array<2xi32> {bindc_name = "array_i", uniq_name = "_QFEarray_i"}
+ %8 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %9:2 = hlfir.declare %7(%8) {uniq_name = "_QFEarray_i"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>)
+ %c2_2 = arith.constant 2 : index
+ %10 = fir.alloca !fir.array<2xf32> {bindc_name = "array_r", uniq_name = "_QFEarray_r"}
+ %11 = fir.shape %c2_2 : (index) -> !fir.shape<1>
+ %12:2 = hlfir.declare %10(%11) {uniq_name = "_QFEarray_r"} : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf32>>, !fir.ref<!fir.array<2xf32>>)
+ %13 = fir.alloca complex<f32> {bindc_name = "c", uniq_name = "_QFEc"}
+ %14:2 = hlfir.declare %13 {uniq_name = "_QFEc"} : (!fir.ref<complex<f32>>) -> (!fir.ref<complex<f32>>, !fir.ref<complex<f32>>)
+ %15 = fir.alloca f64 {bindc_name = "d", uniq_name = "_QFEd"}
+ %16:2 = hlfir.declare %15 {uniq_name = "_QFEd"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
+ %17 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+ %18:2 = hlfir.declare %17 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %c1 = arith.constant 1 : index
+ %19 = fir.alloca !fir.char<1> {bindc_name = "message", uniq_name = "_QFEmessage"}
+ %20:2 = hlfir.declare %19 typeparams %c1 {uniq_name = "_QFEmessage"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+ %21 = fir.alloca f32 {bindc_name = "r", uniq_name = "_QFEr"}
+ %22:2 = hlfir.declare %21 {uniq_name = "_QFEr"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+ %23 = fir.alloca i32 {bindc_name = "status", uniq_name = "_QFEstatus"}
+ %24:2 = hlfir.declare %23 {uniq_name = "_QFEstatus"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %c1_i32 = arith.constant 1 : i32
+ %25 = fir.embox %18#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.co_broadcast %25 source %c1_i32 : (!fir.box<i32>, i32)
+ %c1_i32_3 = arith.constant 1 : i32
+ %26 = fir.embox %14#0 : (!fir.ref<complex<f32>>) -> !fir.box<complex<f32>>
+ mif.co_broadcast %26 source %c1_i32_3 stat %24#0 : (!fir.box<complex<f32>>, i32, !fir.ref<i32>)
+ %c1_i32_4 = arith.constant 1 : i32
+ %27 = fir.embox %16#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ %28 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_broadcast %27 source %c1_i32_4 stat %24#0 errmsg %28 : (!fir.box<f64>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ %c1_i32_5 = arith.constant 1 : i32
+ %29 = fir.embox %22#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ %30 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_broadcast %29 source %c1_i32_5 stat %24#0 errmsg %30 : (!fir.box<f32>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ %c1_i32_6 = arith.constant 1 : i32
+ %31 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %32 = fir.embox %9#0(%31) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ mif.co_broadcast %32 source %c1_i32_6 : (!fir.box<!fir.array<2xi32>>, i32)
+ %c1_i32_7 = arith.constant 1 : i32
+ %33 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %34 = fir.embox %3#0(%33) : (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.shape<1>) -> !fir.box<!fir.array<2xcomplex<f32>>>
+ mif.co_broadcast %34 source %c1_i32_7 : (!fir.box<!fir.array<2xcomplex<f32>>>, i32)
+ %c1_i32_8 = arith.constant 1 : i32
+ %35 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %36 = fir.embox %6#0(%35) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ mif.co_broadcast %36 source %c1_i32_8 stat %24#0 : (!fir.box<!fir.array<2xf64>>, i32, !fir.ref<i32>)
+ %c1_i32_9 = arith.constant 1 : i32
+ %37 = fir.shape %c2_2 : (index) -> !fir.shape<1>
+ %38 = fir.embox %12#0(%37) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ %39 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_broadcast %38 source %c1_i32_9 stat %24#0 errmsg %39 : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ return
+ }
+}
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<complex<f32>>) -> !fir.box<complex<f32>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.convert %[[V1]] : (!fir.box<complex<f32>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V3]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.shape<1>) -> !fir.box<!fir.array<2xcomplex<f32>>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xcomplex<f32>>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
diff --git a/flang/test/Fir/MIF/co_max.mlir b/flang/test/Fir/MIF/co_max.mlir
new file mode 100644
index 0000000..f74513d
--- /dev/null
+++ b/flang/test/Fir/MIF/co_max.mlir
@@ -0,0 +1,163 @@
+// RUN: fir-opt --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git@github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_CO_MAX"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %c1 = arith.constant 1 : index
+ %c2 = arith.constant 2 : index
+ %1 = fir.alloca !fir.array<2x!fir.char<1>> {bindc_name = "array_c", uniq_name = "_QFEarray_c"}
+ %2 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %3:2 = hlfir.declare %1(%2) typeparams %c1 {uniq_name = "_QFEarray_c"} : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>, index) -> (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.ref<!fir.array<2x!fir.char<1>>>)
+ %c2_0 = arith.constant 2 : index
+ %4 = fir.alloca !fir.array<2xf64> {bindc_name = "array_d", uniq_name = "_QFEarray_d"}
+ %5 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %6:2 = hlfir.declare %4(%5) {uniq_name = "_QFEarray_d"} : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf64>>, !fir.ref<!fir.array<2xf64>>)
+ %c2_1 = arith.constant 2 : index
+ %7 = fir.alloca !fir.array<2xi32> {bindc_name = "array_i", uniq_name = "_QFEarray_i"}
+ %8 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %9:2 = hlfir.declare %7(%8) {uniq_name = "_QFEarray_i"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>)
+ %c2_2 = arith.constant 2 : index
+ %10 = fir.alloca !fir.array<2xf32> {bindc_name = "array_r", uniq_name = "_QFEarray_r"}
+ %11 = fir.shape %c2_2 : (index) -> !fir.shape<1>
+ %12:2 = hlfir.declare %10(%11) {uniq_name = "_QFEarray_r"} : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf32>>, !fir.ref<!fir.array<2xf32>>)
+ %c1_3 = arith.constant 1 : index
+ %13 = fir.alloca !fir.char<1> {bindc_name = "c", uniq_name = "_QFEc"}
+ %14:2 = hlfir.declare %13 typeparams %c1_3 {uniq_name = "_QFEc"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+ %15 = fir.alloca f64 {bindc_name = "d", uniq_name = "_QFEd"}
+ %16:2 = hlfir.declare %15 {uniq_name = "_QFEd"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
+ %17 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+ %18:2 = hlfir.declare %17 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %c1_4 = arith.constant 1 : index
+ %19 = fir.alloca !fir.char<1> {bindc_name = "message", uniq_name = "_QFEmessage"}
+ %20:2 = hlfir.declare %19 typeparams %c1_4 {uniq_name = "_QFEmessage"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+ %21 = fir.alloca f32 {bindc_name = "r", uniq_name = "_QFEr"}
+ %22:2 = hlfir.declare %21 {uniq_name = "_QFEr"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+ %23 = fir.alloca i32 {bindc_name = "status", uniq_name = "_QFEstatus"}
+ %24:2 = hlfir.declare %23 {uniq_name = "_QFEstatus"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %25 = fir.embox %18#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.co_max %25 : (!fir.box<i32>)
+ %26 = fir.embox %14#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_max %26 : (!fir.box<!fir.char<1>>)
+ %27 = fir.embox %16#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ mif.co_max %27 : (!fir.box<f64>)
+ %28 = fir.embox %22#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ mif.co_max %28 : (!fir.box<f32>)
+ %c1_i32 = arith.constant 1 : i32
+ %29 = fir.embox %18#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.co_max %29 result %c1_i32 : (!fir.box<i32>, i32)
+ %c1_i32_5 = arith.constant 1 : i32
+ %30 = fir.embox %16#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ %31 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_max %30 result %c1_i32_5 stat %24#0 errmsg %31 : (!fir.box<f64>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ %c1_i32_6 = arith.constant 1 : i32
+ %32 = fir.embox %22#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ %33 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_max %32 result %c1_i32_6 stat %24#0 errmsg %33 : (!fir.box<f32>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ %34 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %35 = fir.embox %9#0(%34) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ mif.co_max %35 : (!fir.box<!fir.array<2xi32>>)
+ %c1_i32_7 = arith.constant 1 : i32
+ %36 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %37 = fir.embox %3#0(%36) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
+ mif.co_max %37 result %c1_i32_7 : (!fir.box<!fir.array<2x!fir.char<1>>>, i32)
+ %c1_i32_8 = arith.constant 1 : i32
+ %38 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %39 = fir.embox %6#0(%38) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ mif.co_max %39 result %c1_i32_8 stat %24#0 : (!fir.box<!fir.array<2xf64>>, i32, !fir.ref<i32>)
+ %c1_i32_9 = arith.constant 1 : i32
+ %40 = fir.shape %c2_2 : (index) -> !fir.shape<1>
+ %41 = fir.embox %12#0(%40) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ %42 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_max %41 result %c1_i32_9 stat %24#0 errmsg %42 : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ return
+ }
+}
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.char<1>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max_character(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2x!fir.char<1>>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max_character(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
diff --git a/flang/test/Fir/MIF/co_min.mlir b/flang/test/Fir/MIF/co_min.mlir
new file mode 100644
index 0000000..97806bb
--- /dev/null
+++ b/flang/test/Fir/MIF/co_min.mlir
@@ -0,0 +1,163 @@
+// RUN: fir-opt --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git@github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_CO_MIN"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %c1 = arith.constant 1 : index
+ %c2 = arith.constant 2 : index
+ %1 = fir.alloca !fir.array<2x!fir.char<1>> {bindc_name = "array_c", uniq_name = "_QFEarray_c"}
+ %2 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %3:2 = hlfir.declare %1(%2) typeparams %c1 {uniq_name = "_QFEarray_c"} : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>, index) -> (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.ref<!fir.array<2x!fir.char<1>>>)
+ %c2_0 = arith.constant 2 : index
+ %4 = fir.alloca !fir.array<2xf64> {bindc_name = "array_d", uniq_name = "_QFEarray_d"}
+ %5 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %6:2 = hlfir.declare %4(%5) {uniq_name = "_QFEarray_d"} : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf64>>, !fir.ref<!fir.array<2xf64>>)
+ %c2_1 = arith.constant 2 : index
+ %7 = fir.alloca !fir.array<2xi32> {bindc_name = "array_i", uniq_name = "_QFEarray_i"}
+ %8 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %9:2 = hlfir.declare %7(%8) {uniq_name = "_QFEarray_i"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>)
+ %c2_2 = arith.constant 2 : index
+ %10 = fir.alloca !fir.array<2xf32> {bindc_name = "array_r", uniq_name = "_QFEarray_r"}
+ %11 = fir.shape %c2_2 : (index) -> !fir.shape<1>
+ %12:2 = hlfir.declare %10(%11) {uniq_name = "_QFEarray_r"} : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf32>>, !fir.ref<!fir.array<2xf32>>)
+ %c1_3 = arith.constant 1 : index
+ %13 = fir.alloca !fir.char<1> {bindc_name = "c", uniq_name = "_QFEc"}
+ %14:2 = hlfir.declare %13 typeparams %c1_3 {uniq_name = "_QFEc"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+ %15 = fir.alloca f64 {bindc_name = "d", uniq_name = "_QFEd"}
+ %16:2 = hlfir.declare %15 {uniq_name = "_QFEd"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
+ %17 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+ %18:2 = hlfir.declare %17 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %c1_4 = arith.constant 1 : index
+ %19 = fir.alloca !fir.char<1> {bindc_name = "message", uniq_name = "_QFEmessage"}
+ %20:2 = hlfir.declare %19 typeparams %c1_4 {uniq_name = "_QFEmessage"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+ %21 = fir.alloca f32 {bindc_name = "r", uniq_name = "_QFEr"}
+ %22:2 = hlfir.declare %21 {uniq_name = "_QFEr"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+ %23 = fir.alloca i32 {bindc_name = "status", uniq_name = "_QFEstatus"}
+ %24:2 = hlfir.declare %23 {uniq_name = "_QFEstatus"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %25 = fir.embox %18#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.co_min %25 : (!fir.box<i32>)
+ %26 = fir.embox %14#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_min %26 : (!fir.box<!fir.char<1>>)
+ %27 = fir.embox %16#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ mif.co_min %27 : (!fir.box<f64>)
+ %28 = fir.embox %22#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ mif.co_min %28 : (!fir.box<f32>)
+ %c1_i32 = arith.constant 1 : i32
+ %29 = fir.embox %18#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.co_min %29 result %c1_i32 : (!fir.box<i32>, i32)
+ %c1_i32_5 = arith.constant 1 : i32
+ %30 = fir.embox %16#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ %31 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_min %30 result %c1_i32_5 stat %24#0 errmsg %31 : (!fir.box<f64>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ %c1_i32_6 = arith.constant 1 : i32
+ %32 = fir.embox %22#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ %33 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_min %32 result %c1_i32_6 stat %24#0 errmsg %33 : (!fir.box<f32>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ %34 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %35 = fir.embox %9#0(%34) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ mif.co_min %35 : (!fir.box<!fir.array<2xi32>>)
+ %c1_i32_7 = arith.constant 1 : i32
+ %36 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %37 = fir.embox %3#0(%36) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
+ mif.co_min %37 result %c1_i32_7 : (!fir.box<!fir.array<2x!fir.char<1>>>, i32)
+ %c1_i32_8 = arith.constant 1 : i32
+ %38 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %39 = fir.embox %6#0(%38) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ mif.co_min %39 result %c1_i32_8 stat %24#0 : (!fir.box<!fir.array<2xf64>>, i32, !fir.ref<i32>)
+ %c1_i32_9 = arith.constant 1 : i32
+ %40 = fir.shape %c2_2 : (index) -> !fir.shape<1>
+ %41 = fir.embox %12#0(%40) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ %42 = fir.embox %20#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_min %41 result %c1_i32_9 stat %24#0 errmsg %42 : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ return
+ }
+}
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.char<1>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min_character(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2x!fir.char<1>>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min_character(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
diff --git a/flang/test/Fir/MIF/co_sum.mlir b/flang/test/Fir/MIF/co_sum.mlir
new file mode 100644
index 0000000..8afce35
--- /dev/null
+++ b/flang/test/Fir/MIF/co_sum.mlir
@@ -0,0 +1,133 @@
+// RUN: fir-opt --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git@github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_CO_SUM"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %c2 = arith.constant 2 : index
+ %1 = fir.alloca !fir.array<2xf64> {bindc_name = "array_d", uniq_name = "_QFEarray_d"}
+ %2 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %3:2 = hlfir.declare %1(%2) {uniq_name = "_QFEarray_d"} : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf64>>, !fir.ref<!fir.array<2xf64>>)
+ %c2_0 = arith.constant 2 : index
+ %4 = fir.alloca !fir.array<2xi32> {bindc_name = "array_i", uniq_name = "_QFEarray_i"}
+ %5 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %6:2 = hlfir.declare %4(%5) {uniq_name = "_QFEarray_i"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>)
+ %c2_1 = arith.constant 2 : index
+ %7 = fir.alloca !fir.array<2xf32> {bindc_name = "array_r", uniq_name = "_QFEarray_r"}
+ %8 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %9:2 = hlfir.declare %7(%8) {uniq_name = "_QFEarray_r"} : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf32>>, !fir.ref<!fir.array<2xf32>>)
+ %10 = fir.alloca f64 {bindc_name = "d", uniq_name = "_QFEd"}
+ %11:2 = hlfir.declare %10 {uniq_name = "_QFEd"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
+ %12 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+ %13:2 = hlfir.declare %12 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %c1 = arith.constant 1 : index
+ %14 = fir.alloca !fir.char<1> {bindc_name = "message", uniq_name = "_QFEmessage"}
+ %15:2 = hlfir.declare %14 typeparams %c1 {uniq_name = "_QFEmessage"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+ %16 = fir.alloca f32 {bindc_name = "r", uniq_name = "_QFEr"}
+ %17:2 = hlfir.declare %16 {uniq_name = "_QFEr"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+ %18 = fir.alloca i32 {bindc_name = "status", uniq_name = "_QFEstatus"}
+ %19:2 = hlfir.declare %18 {uniq_name = "_QFEstatus"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %20 = fir.embox %13#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.co_sum %20 : (!fir.box<i32>)
+ %21 = fir.embox %11#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ mif.co_sum %21 : (!fir.box<f64>)
+ %22 = fir.embox %17#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ mif.co_sum %22 : (!fir.box<f32>)
+ %c1_i32 = arith.constant 1 : i32
+ %23 = fir.embox %13#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.co_sum %23 result %c1_i32 : (!fir.box<i32>, i32)
+ %c1_i32_2 = arith.constant 1 : i32
+ %24 = fir.embox %11#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ %25 = fir.embox %15#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_sum %24 result %c1_i32_2 stat %19#0 errmsg %25 : (!fir.box<f64>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ %c1_i32_3 = arith.constant 1 : i32
+ %26 = fir.embox %17#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ %27 = fir.embox %15#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_sum %26 result %c1_i32_3 stat %19#0 errmsg %27 : (!fir.box<f32>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ %28 = fir.shape %c2_0 : (index) -> !fir.shape<1>
+ %29 = fir.embox %6#0(%28) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ mif.co_sum %29 : (!fir.box<!fir.array<2xi32>>)
+ %c1_i32_4 = arith.constant 1 : i32
+ %30 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %31 = fir.embox %3#0(%30) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ mif.co_sum %31 result %c1_i32_4 stat %19#0 : (!fir.box<!fir.array<2xf64>>, i32, !fir.ref<i32>)
+ %c1_i32_5 = arith.constant 1 : i32
+ %32 = fir.shape %c2_1 : (index) -> !fir.shape<1>
+ %33 = fir.embox %9#0(%32) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ %34 = fir.embox %15#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ mif.co_sum %33 result %c1_i32_5 stat %19#0 errmsg %34 : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ return
+ }
+}
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[V3]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V4]], %[[V3]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V3:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V3]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V2]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ // CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ // CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ // CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ // CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ // CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
+ // CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
diff --git a/flang/test/Fir/MIF/init.mlir b/flang/test/Fir/MIF/init.mlir
new file mode 100644
index 0000000..0f1177f
--- /dev/null
+++ b/flang/test/Fir/MIF/init.mlir
@@ -0,0 +1,24 @@
+// RUN: fir-opt --split-input-file --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git@github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_INIT"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ return
+ }
+ func.func private @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, !llvm.ptr)
+ func.func private @_FortranAProgramEndStatement()
+ func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 {
+ %0 = fir.zero_bits !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
+ fir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) fastmath<contract> : (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>) -> ()
+ %1 = mif.init -> i32
+ fir.call @_QQmain() fastmath<contract> : () -> ()
+ fir.call @_FortranAProgramEndStatement() fastmath<contract> : () -> ()
+ %c0_i32 = arith.constant 0 : i32
+ return %c0_i32 : i32
+ }
+}
+
+
+// CHECK-LABEL: func.func @main
+// CHECK: %[[VAL_0:.*]] = fir.alloca i32
+// CHECK: fir.call @_QMprifPprif_init(%[[VAL_0]]) : (!fir.ref<i32>) -> ()
diff --git a/flang/test/Fir/MIF/num_images.mlir b/flang/test/Fir/MIF/num_images.mlir
new file mode 100644
index 0000000..afa33a9
--- /dev/null
+++ b/flang/test/Fir/MIF/num_images.mlir
@@ -0,0 +1,22 @@
+// RUN: fir-opt --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git@github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+ %2:2 = hlfir.declare %1 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %3 = fir.alloca i32 {bindc_name = "team_number", uniq_name = "_QFEteam_number"}
+ %4:2 = hlfir.declare %3 {uniq_name = "_QFEteam_number"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %5 = mif.num_images : () -> i32
+ hlfir.assign %5 to %2#0 : i32, !fir.ref<i32>
+ %6 = fir.load %4#0 : !fir.ref<i32>
+ %7 = mif.num_images team_number %6 : (i32) -> i32
+ hlfir.assign %7 to %2#0 : i32, !fir.ref<i32>
+ return
+ }
+}
+
+
+// CHECK-LABEL: func.func @_QQmain
+// CHECK: fir.call @_QMprifPprif_num_images(
+// CHECK: fir.call @_QMprifPprif_num_images_with_team_number(
diff --git a/flang/test/Fir/MIF/sync_all.mlir b/flang/test/Fir/MIF/sync_all.mlir
new file mode 100644
index 0000000..b2b98b9
--- /dev/null
+++ b/flang/test/Fir/MIF/sync_all.mlir
@@ -0,0 +1,45 @@
+// RUN: fir-opt --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git@github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_SYNC_ALL"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QFEerror_message) : !fir.ref<!fir.char<1,128>>
+ %c128 = arith.constant 128 : index
+ %2:2 = hlfir.declare %1 typeparams %c128 {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ %3 = fir.alloca i32 {bindc_name = "sync_status", uniq_name = "_QFEsync_status"}
+ %4:2 = hlfir.declare %3 {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ mif.sync_all : () -> ()
+ mif.sync_all stat %4#0 : (!fir.ref<i32>) -> ()
+ %5 = fir.embox %2#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ mif.sync_all errmsg %5 : (!fir.box<!fir.char<1,128>>) -> ()
+ %6 = fir.embox %2#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ mif.sync_all stat %4#0 errmsg %6 : (!fir.ref<i32>, !fir.box<!fir.char<1,128>>) -> ()
+ return
+ }
+ fir.global internal @_QFEerror_message : !fir.char<1,128> {
+ %0 = fir.zero_bits !fir.char<1,128>
+ fir.has_value %0 : !fir.char<1,128>
+ }
+}
+
+
+// CHECK: %[[ERRMSG:.*]]:2 = hlfir.declare %[[E:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+// CHECK: %[[STAT:.*]]:2 = hlfir.declare %[[S:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+
+// CHECK: %[[VAL_1:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: %[[VAL_2:.*]] = fir.absent !fir.ref<i32>
+// CHECK: fir.call @_QMprifPprif_sync_all(%[[VAL_2]], %[[VAL_1]], %[[VAL_1]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+// CHECK: %[[VAL_3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: fir.call @_QMprifPprif_sync_all(%[[STAT]]#0, %[[VAL_3]], %[[VAL_3]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+// CHECK: %[[VAL_4:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+// CHECK: %[[VAL_5:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: %[[VAL_6:.*]] = fir.absent !fir.ref<i32>
+// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+// CHECK: fir.call @_QMprifPprif_sync_all(%[[VAL_6]], %[[VAL_7]], %[[VAL_5]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+// CHECK: %[[VAL_8:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+// CHECK: %[[VAL_9:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+// CHECK: fir.call @_QMprifPprif_sync_all(%[[STAT]]#0, %[[VAL_10]], %[[VAL_9]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
diff --git a/flang/test/Fir/MIF/sync_images.mlir b/flang/test/Fir/MIF/sync_images.mlir
new file mode 100644
index 0000000..e38fdaa
--- /dev/null
+++ b/flang/test/Fir/MIF/sync_images.mlir
@@ -0,0 +1,85 @@
+// RUN: fir-opt --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git@github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_SYNC_IMAGES"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QFEerror_message) : !fir.ref<!fir.char<1,128>>
+ %c128 = arith.constant 128 : index
+ %2:2 = hlfir.declare %1 typeparams %c128 {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ %3 = fir.alloca i32 {bindc_name = "me", uniq_name = "_QFEme"}
+ %4:2 = hlfir.declare %3 {uniq_name = "_QFEme"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %5 = fir.alloca i32 {bindc_name = "sync_status", uniq_name = "_QFEsync_status"}
+ %6:2 = hlfir.declare %5 {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %7 = fir.embox %2#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ mif.sync_images stat %6#0 errmsg %7 : (!fir.ref<i32>, !fir.box<!fir.char<1,128>>) -> ()
+ %8 = fir.embox %2#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ %9 = fir.embox %4#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.sync_images image_set %9 stat %6#0 errmsg %8 : (!fir.box<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,128>>) -> ()
+ %10 = fir.embox %2#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ %11 = fir.address_of(@_QQro.1xi4.0) : !fir.ref<!fir.array<1xi32>>
+ %c1 = arith.constant 1 : index
+ %12 = fir.shape %c1 : (index) -> !fir.shape<1>
+ %13:2 = hlfir.declare %11(%12) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.1xi4.0"} : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<1xi32>>, !fir.ref<!fir.array<1xi32>>)
+ %14 = fir.shape %c1 : (index) -> !fir.shape<1>
+ %15 = fir.embox %13#0(%14) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ mif.sync_images image_set %15 stat %6#0 errmsg %10 : (!fir.box<!fir.array<1xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,128>>) -> ()
+ mif.sync_images : () -> ()
+ %16 = fir.embox %4#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ mif.sync_images image_set %16 : (!fir.box<i32>) -> ()
+ %17 = fir.address_of(@_QQro.1xi4.0) : !fir.ref<!fir.array<1xi32>>
+ %c1_0 = arith.constant 1 : index
+ %18 = fir.shape %c1_0 : (index) -> !fir.shape<1>
+ %19:2 = hlfir.declare %17(%18) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.1xi4.0"} : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<1xi32>>, !fir.ref<!fir.array<1xi32>>)
+ %20 = fir.shape %c1_0 : (index) -> !fir.shape<1>
+ %21 = fir.embox %19#0(%20) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ mif.sync_images image_set %21 : (!fir.box<!fir.array<1xi32>>) -> ()
+ return
+ }
+ fir.global internal @_QFEerror_message : !fir.char<1,128> {
+ %0 = fir.zero_bits !fir.char<1,128>
+ fir.has_value %0 : !fir.char<1,128>
+ }
+}
+
+ // CHECK: %[[ERRMSG:.*]]:2 = hlfir.declare %[[E:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ // CHECK: %[[ME:.*]]:2 = hlfir.declare %[[M:.*]] {uniq_name = "_QFEme"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ // CHECK: %[[STAT:.*]]:2 = hlfir.declare %[[S:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+
+ // CHECK: %[[VAL_1:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ // CHECK: %[[VAL_2:.*]] = fir.absent !fir.box<!fir.array<?xi32>>
+ // CHECK: %[[VAL_3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_sync_images(%[[VAL_2]], %[[STAT]]#0, %[[VAL_4]], %[[VAL_3]]) : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[VAL_5:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ // CHECK: %[[VAL_6:.*]] = fir.embox %[[ME]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: %[[VAL_7:.*]] = fir.rebox %[[VAL_6]](%[[SHAPE:.*]]) : (!fir.box<i32>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ // CHECK: %[[VAL_8:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_7]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
+ // CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_5]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_sync_images(%[[VAL_9]], %[[STAT]]#0, %[[VAL_10]], %[[VAL_8]]) : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[VAL_11:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ // CHECK: %[[VAL_12:.*]] = fir.embox %[[IMG_SET:.*]]#0(%[[SHAPE_1:.*]]) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ // CHECK: %[[VAL_13:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
+ // CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_11]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+ // CHECK: fir.call @_QMprifPprif_sync_images(%[[VAL_14]], %[[STAT]]#0, %[[VAL_15]], %[[VAL_13]]) : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[VAL_16:.*]] = fir.absent !fir.box<!fir.array<?xi32>>
+ // CHECK: %[[VAL_17:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[VAL_18:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: fir.call @_QMprifPprif_sync_images(%[[VAL_16]], %[[VAL_18]], %[[VAL_17]], %[[VAL_17]]) : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[VAL_19:.*]] = fir.embox %[[ME]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ // CHECK: %[[VAL_20:.*]] = fir.rebox %[[VAL_19]](%[[SHAPE_2:.*]]) : (!fir.box<i32>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ // CHECK: %[[VAL_21:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[VAL_22:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
+ // CHECK: fir.call @_QMprifPprif_sync_images(%[[VAL_23]], %[[VAL_22]], %[[VAL_21]], %[[VAL_21]]) : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+ // CHECK: %[[VAL_24:.*]] = fir.embox %[[IMG_SET:.*]]#0(%[[SHAPE_3:.*]]) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ // CHECK: %[[VAL_25:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ // CHECK: %[[VAL_26:.*]] = fir.absent !fir.ref<i32>
+ // CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_24]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
+ // CHECK: fir.call @_QMprifPprif_sync_images(%[[VAL_27]], %[[VAL_26]], %[[VAL_25]], %[[VAL_25]]) : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
diff --git a/flang/test/Fir/MIF/sync_memory.mlir b/flang/test/Fir/MIF/sync_memory.mlir
new file mode 100644
index 0000000..d6f2441
--- /dev/null
+++ b/flang/test/Fir/MIF/sync_memory.mlir
@@ -0,0 +1,45 @@
+// RUN: fir-opt --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git@github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST_sync_memory"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QFEerror_message) : !fir.ref<!fir.char<1,128>>
+ %c128 = arith.constant 128 : index
+ %2:2 = hlfir.declare %1 typeparams %c128 {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ %3 = fir.alloca i32 {bindc_name = "sync_status", uniq_name = "_QFEsync_status"}
+ %4:2 = hlfir.declare %3 {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ mif.sync_memory : () -> ()
+ mif.sync_memory stat %4#0 : (!fir.ref<i32>) -> ()
+ %5 = fir.embox %2#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ mif.sync_memory errmsg %5 : (!fir.box<!fir.char<1,128>>) -> ()
+ %6 = fir.embox %2#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ mif.sync_memory stat %4#0 errmsg %6 : (!fir.ref<i32>, !fir.box<!fir.char<1,128>>) -> ()
+ return
+ }
+ fir.global internal @_QFEerror_message : !fir.char<1,128> {
+ %0 = fir.zero_bits !fir.char<1,128>
+ fir.has_value %0 : !fir.char<1,128>
+ }
+}
+
+
+// CHECK: %[[ERRMSG:.*]]:2 = hlfir.declare %[[E:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+// CHECK: %[[STAT:.*]]:2 = hlfir.declare %[[S:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+
+// CHECK: %[[VAL_1:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: %[[VAL_2:.*]] = fir.absent !fir.ref<i32>
+// CHECK: fir.call @_QMprifPprif_sync_memory(%[[VAL_2]], %[[VAL_1]], %[[VAL_1]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+// CHECK: %[[VAL_3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: fir.call @_QMprifPprif_sync_memory(%[[STAT]]#0, %[[VAL_3]], %[[VAL_3]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+// CHECK: %[[VAL_4:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+// CHECK: %[[VAL_5:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: %[[VAL_6:.*]] = fir.absent !fir.ref<i32>
+// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+// CHECK: fir.call @_QMprifPprif_sync_memory(%[[VAL_6]], %[[VAL_7]], %[[VAL_5]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+
+// CHECK: %[[VAL_8:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+// CHECK: %[[VAL_9:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
+// CHECK: fir.call @_QMprifPprif_sync_memory(%[[STAT]]#0, %[[VAL_10]], %[[VAL_9]]) : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
diff --git a/flang/test/Fir/MIF/this_image.mlir b/flang/test/Fir/MIF/this_image.mlir
new file mode 100644
index 0000000..25eafc0
--- /dev/null
+++ b/flang/test/Fir/MIF/this_image.mlir
@@ -0,0 +1,16 @@
+// RUN: fir-opt --mif-convert %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (git@github.com:SiPearl/llvm-project.git 666e4313ebc03587f27774139ad8f780bac15c3e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QQmain() attributes {fir.bindc_name = "TEST"} {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+ %2:2 = hlfir.declare %1 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %3 = mif.this_image : () -> i32
+ hlfir.assign %3 to %2#0 : i32, !fir.ref<i32>
+ return
+ }
+}
+
+
+// CHECK-LABEL: func.func @_QQmain
+// CHECK: fir.call @_QMprifPprif_this_image_no_coarray(
diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir
index 59f6c73..5159c91 100644
--- a/flang/test/Fir/basic-program.fir
+++ b/flang/test/Fir/basic-program.fir
@@ -132,6 +132,7 @@ func.func @_QQmain() {
// PASSES-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
// PASSES-NEXT: 'func.func' Pipeline
// PASSES-NEXT: SetRuntimeCallAttributes
+// PASSES-NEXT: MIFOpConversion
// PASSES-NEXT: BoxedProcedurePass
// PASSES-NEXT: AddAliasTags
diff --git a/flang/test/Lower/CUDA/cuda-cloc.cuf b/flang/test/Lower/CUDA/cuda-cloc.cuf
new file mode 100644
index 0000000..87a98d4
--- /dev/null
+++ b/flang/test/Lower/CUDA/cuda-cloc.cuf
@@ -0,0 +1,19 @@
+! RUN: bbc -emit-hlfir -fcuda %s -o - | FileCheck %s
+
+module symbols
+ integer(4), device, target :: sdev(100)
+end module
+
+subroutine sub1
+ use iso_c_binding
+ use symbols
+ print*, c_loc(sdev)
+end subroutine
+
+! CHECK-LABEL: func.func @_QPsub1()
+! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMsymbolsEsdev) : !fir.ref<!fir.array<100xi32>>
+! CHECK: %[[EMBOX:.*]] = fir.embox %[[ADDR]](%{{.*}}) : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<100xi32>>
+! CHECK: %[[__ADDRESS:.*]] = fir.coordinate_of %{{.*}}, __address : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> !fir.ref<i64>
+! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[EMBOX]] : (!fir.box<!fir.array<100xi32>>) -> !fir.ref<!fir.array<100xi32>>
+! CHECK: %[[CONV:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.ref<!fir.array<100xi32>>) -> i64
+! CHECK: fir.store %[[CONV]] to %[[__ADDRESS]] : !fir.ref<i64>
diff --git a/flang/test/Lower/Coarray/co_broadcast.f90 b/flang/test/Lower/Coarray/co_broadcast.f90
deleted file mode 100644
index be7fdcb..0000000
--- a/flang/test/Lower/Coarray/co_broadcast.f90
+++ /dev/null
@@ -1,92 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
-
-program test_co_broadcast
- integer :: i, array_i(2), status
- real :: r, array_r(2)
- double precision :: d, array_d(2)
- complex :: c, array_c(2)
- character(len=1) :: message
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(i, source_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<complex<f32>>) -> !fir.box<complex<f32>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<complex<f32>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V2]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(c, source_image=1, stat=status)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(d, source_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(r, source_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(array_i, source_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.shape<1>) -> !fir.box<!fir.array<2xcomplex<f32>>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xcomplex<f32>>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(array_c, source_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(array_d, source_image=1, stat=status)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_broadcast(array_r, source_image=1, stat= status, errmsg=message)
-
-end program
diff --git a/flang/test/Lower/Coarray/co_max.f90 b/flang/test/Lower/Coarray/co_max.f90
deleted file mode 100644
index 56d8633..0000000
--- a/flang/test/Lower/Coarray/co_max.f90
+++ /dev/null
@@ -1,112 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
-
-program test_co_max
- integer :: i, array_i(2), status
- real :: r, array_r(2)
- double precision :: d, array_d(2)
- character(len=1) :: c, array_c(2), message
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(i)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.char<1>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max_character(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(c)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(d)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(r)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(i, result_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(d, result_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(r, result_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(array_i)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2x!fir.char<1>>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max_character(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(array_c, result_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(array_d, result_image=1, stat=status)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_max(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_max(array_r, result_image=1, stat= status, errmsg=message)
-
-end program
diff --git a/flang/test/Lower/Coarray/co_min.f90 b/flang/test/Lower/Coarray/co_min.f90
deleted file mode 100644
index dde878b..0000000
--- a/flang/test/Lower/Coarray/co_min.f90
+++ /dev/null
@@ -1,112 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
-
-program test_co_min
- integer :: i, array_i(2), status
- real :: r, array_r(2)
- double precision :: d, array_d(2)
- character(len=1) :: c, array_c(2), message
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(i)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.char<1>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min_character(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(c)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(d)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(r)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(i, result_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(d, result_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(r, result_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(array_i)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2x!fir.char<1>>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min_character(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(array_c, result_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(array_d, result_image=1, stat=status)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_min(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_min(array_r, result_image=1, stat= status, errmsg=message)
-
-end program
diff --git a/flang/test/Lower/Coarray/co_sum.f90 b/flang/test/Lower/Coarray/co_sum.f90
deleted file mode 100644
index 2932b54..0000000
--- a/flang/test/Lower/Coarray/co_sum.f90
+++ /dev/null
@@ -1,122 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
-
-program test_co_sum
- integer :: i, array_i(2), status
- real :: r, array_r(2)
- double precision :: d, array_d(2)
- complex :: c, array_c(2)
- character(len=1) :: message
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(i)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<complex<f32>>) -> !fir.box<complex<f32>>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<complex<f32>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(c)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(d)
-
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(r)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(i, result_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C]]#0 : (!fir.ref<complex<f32>>) -> !fir.box<complex<f32>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<complex<f32>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V2]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(c, result_image=1, stat=status)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(d, result_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(r, result_image=1, stat=status, errmsg=message)
-
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[V2]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(array_i)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.shape<1>) -> !fir.box<!fir.array<2xcomplex<f32>>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xcomplex<f32>>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(array_c, result_image=1)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(array_d, result_image=1, stat=status)
-
- ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
- ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
- ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
- ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
- ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
- ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
- ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
- ! CHECK: fir.call @_QMprifPprif_co_sum(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- call co_sum(array_r, result_image=1, stat= status, errmsg=message)
-
-end program
diff --git a/flang/test/Lower/Coarray/sync_all.f90 b/flang/test/Lower/Coarray/sync_all.f90
deleted file mode 100644
index c2c12d8..0000000
--- a/flang/test/Lower/Coarray/sync_all.f90
+++ /dev/null
@@ -1,37 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY
-! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY
-
-program test_sync_all
- implicit none
- ! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable.
-
- ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
- ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
- integer sync_status
- character(len=128) :: error_message
-
- ! COARRAY: %[[VAL_3:.*]] = fir.absent !fir.ref<i32>
- ! COARRAY: %[[VAL_4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_5:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync all
-
- ! COARRAY: %[[VAL_6:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_7:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[STAT]]#0, %[[VAL_6]], %[[VAL_7]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync all(stat=sync_status)
-
- ! COARRAY: %[[VAL_8:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
- ! COARRAY: %[[VAL_9:.*]] = fir.absent !fir.ref<i32>
- ! COARRAY: %[[VAL_10:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_11:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[VAL_9]], %[[VAL_11]], %[[VAL_10]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync all( errmsg=error_message)
-
- ! COARRAY: %[[VAL_12:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
- ! COARRAY: %[[VAL_13:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_all(%[[STAT]]#0, %[[VAL_14]], %[[VAL_13]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync all(stat=sync_status, errmsg=error_message)
-
-end program test_sync_all
diff --git a/flang/test/Lower/Coarray/sync_images.f90 b/flang/test/Lower/Coarray/sync_images.f90
deleted file mode 100644
index 0224bf2..0000000
--- a/flang/test/Lower/Coarray/sync_images.f90
+++ /dev/null
@@ -1,62 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY
-! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY
-
-program test_sync_images
- implicit none
- ! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable.
-
- ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
- ! COARRAY: %[[ME:.*]]:2 = hlfir.declare %[[VAL_3:.*]] {uniq_name = "_QFEme"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
- ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
- integer sync_status, me
- character(len=128) :: error_message
-
- ! COARRAY: %[[VAL_1:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
- ! COARRAY: %[[VAL_2:.*]] = fir.absent !fir.box<!fir.array<?xi32>>
- ! COARRAY: %[[VAL_3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_4:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_2]], %[[STAT]]#0, %[[VAL_4]], %[[VAL_3]]) fastmath<contract> : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync images(*, stat=sync_status, errmsg=error_message)
-
- ! COARRAY: %[[VAL_5:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
- ! COARRAY: %[[VAL_6:.*]] = fir.embox %[[ME]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! COARRAY: %[[VAL_7:.*]] = fir.rebox %[[VAL_6]](%[[SHAPE:.*]]) : (!fir.box<i32>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
- ! COARRAY: %[[VAL_8:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_9:.*]] = fir.convert %[[VAL_7]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
- ! COARRAY: %[[VAL_10:.*]] = fir.convert %[[VAL_5]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_9]], %[[STAT]]#0, %[[VAL_10]], %[[VAL_8]]) fastmath<contract> : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync images(me, stat=sync_status, errmsg=error_message)
-
- ! COARRAY: %[[VAL_11:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
- ! COARRAY: %[[VAL_12:.*]] = fir.embox %[[IMG_SET:.*]]#0(%[[SHAPE_1:.*]]) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
- ! COARRAY: %[[VAL_13:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
- ! COARRAY: %[[VAL_15:.*]] = fir.convert %[[VAL_11]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_14]], %[[STAT]]#0, %[[VAL_15]], %[[VAL_13]]) fastmath<contract> : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync images([1], stat=sync_status, errmsg=error_message)
-
- ! COARRAY: %[[VAL_17:.*]] = fir.absent !fir.ref<i32>
- ! COARRAY: %[[VAL_18:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_19:.*]] = fir.absent !fir.box<!fir.array<?xi32>>
- ! COARRAY: %[[VAL_20:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_19]], %[[VAL_17]], %[[VAL_18]], %[[VAL_20]]) fastmath<contract> : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync images(*)
-
- ! COARRAY: %[[VAL_23:.*]] = fir.absent !fir.ref<i32>
- ! COARRAY: %[[VAL_24:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_21:.*]] = fir.embox %[[ME]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
- ! COARRAY: %[[VAL_22:.*]] = fir.rebox %[[VAL_21]](%[[SHAPE_2:.*]]) : (!fir.box<i32>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
- ! COARRAY: %[[VAL_25:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_26:.*]] = fir.convert %[[VAL_22]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
- ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_26]], %[[VAL_23]], %[[VAL_24]], %[[VAL_25]]) fastmath<contract> : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync images(me)
-
- ! COARRAY: %[[VAL_28:.*]] = fir.absent !fir.ref<i32>
- ! COARRAY: %[[VAL_29:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_27:.*]] = fir.embox %[[IMG_SET:.*]]#0(%[[SHAPE_3:.*]]) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
- ! COARRAY: %[[VAL_30:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_31:.*]] = fir.convert %[[VAL_27]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<!fir.array<?xi32>>
- ! COARRAY: fir.call @_QMprifPprif_sync_images(%[[VAL_31]], %[[VAL_28]], %[[VAL_29]], %[[VAL_30]]) fastmath<contract> : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync images([1])
-
-end program test_sync_images
diff --git a/flang/test/Lower/Coarray/sync_memory.f90 b/flang/test/Lower/Coarray/sync_memory.f90
deleted file mode 100644
index 773cb6f..0000000
--- a/flang/test/Lower/Coarray/sync_memory.f90
+++ /dev/null
@@ -1,37 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY
-! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY
-
-program test_sync_memory
- implicit none
- ! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable.
-
- ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
- ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
- integer sync_status
- character(len=128) :: error_message
-
- ! COARRAY: %[[VAL_3:.*]] = fir.absent !fir.ref<i32>
- ! COARRAY: %[[VAL_4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_5:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_memory(%[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync memory
-
- ! COARRAY: %[[VAL_6:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_7:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_memory(%[[STAT]]#0, %[[VAL_6]], %[[VAL_7]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync memory(stat=sync_status)
-
- ! COARRAY: %[[VAL_8:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
- ! COARRAY: %[[VAL_9:.*]] = fir.absent !fir.ref<i32>
- ! COARRAY: %[[VAL_10:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_11:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_memory(%[[VAL_9]], %[[VAL_11]], %[[VAL_10]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync memory( errmsg=error_message)
-
- ! COARRAY: %[[VAL_12:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
- ! COARRAY: %[[VAL_13:.*]] = fir.absent !fir.box<!fir.char<1,?>>
- ! COARRAY: %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.char<1,128>>) -> !fir.box<!fir.char<1,?>>
- ! COARRAY: fir.call @_QMprifPprif_sync_memory(%[[STAT]]#0, %[[VAL_14]], %[[VAL_13]]) fastmath<contract> : (!fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
- sync memory(stat=sync_status, errmsg=error_message)
-
-end program test_sync_memory
diff --git a/flang/test/Lower/MIF/co_broadcast.f90 b/flang/test/Lower/MIF/co_broadcast.f90
new file mode 100644
index 0000000..25e4330
--- /dev/null
+++ b/flang/test/Lower/MIF/co_broadcast.f90
@@ -0,0 +1,57 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
+
+program test_co_broadcast
+ integer :: i, array_i(2), status
+ real :: r, array_r(2)
+ double precision :: d, array_d(2)
+ complex :: c, array_c(2)
+ character(len=1) :: message
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] : (!fir.box<i32>, i32)
+ call co_broadcast(i, source_image=1)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<complex<f32>>) -> !fir.box<complex<f32>>
+ ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 : (!fir.box<complex<f32>>, i32, !fir.ref<i32>)
+ call co_broadcast(c, source_image=1, stat=status)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] stat %[[STATUS]]#0 errmsg %[[V2]] : (!fir.box<f64>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ call co_broadcast(d, source_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] stat %[[STATUS]]#0 errmsg %[[V2]] : (!fir.box<f32>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ call co_broadcast(r, source_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] : (!fir.box<!fir.array<2xi32>>, i32)
+ call co_broadcast(array_i, source_image=1)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.shape<1>) -> !fir.box<!fir.array<2xcomplex<f32>>>
+ ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] : (!fir.box<!fir.array<2xcomplex<f32>>>, i32)
+ call co_broadcast(array_c, source_image=1)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 : (!fir.box<!fir.array<2xf64>>, i32, !fir.ref<i32>)
+ call co_broadcast(array_d, source_image=1, stat=status)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_broadcast %[[V1]] source %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ call co_broadcast(array_r, source_image=1, stat= status, errmsg=message)
+
+end program
diff --git a/flang/test/Lower/MIF/co_max.f90 b/flang/test/Lower/MIF/co_max.f90
new file mode 100644
index 0000000..19e6562
--- /dev/null
+++ b/flang/test/Lower/MIF/co_max.f90
@@ -0,0 +1,60 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
+
+program test_co_max
+ integer :: i, array_i(2), status
+ real :: r, array_r(2)
+ double precision :: d, array_d(2)
+ character(len=1) :: c, array_c(2), message
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: mif.co_max %[[V1]] : (!fir.box<i32>)
+ call co_max(i)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_max %[[V1]] : (!fir.box<!fir.char<1>>)
+ call co_max(c)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ ! CHECK: mif.co_max %[[V1]] : (!fir.box<f64>)
+ call co_max(d)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: mif.co_max %[[V1]] : (!fir.box<f32>)
+ call co_max(r)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: mif.co_max %[[V1]] result %[[C1_i32:.*]] : (!fir.box<i32>, i32)
+ call co_max(i, result_image=1)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_max %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<f64>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ call co_max(d, result_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_max %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<f32>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ call co_max(r, result_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ ! CHECK: mif.co_max %[[V1]] : (!fir.box<!fir.array<2xi32>>)
+ call co_max(array_i)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
+ ! CHECK: mif.co_max %[[V1]] result %[[C1_i32:.*]] : (!fir.box<!fir.array<2x!fir.char<1>>>, i32)
+ call co_max(array_c, result_image=1)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ ! CHECK: mif.co_max %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 : (!fir.box<!fir.array<2xf64>>, i32, !fir.ref<i32>)
+ call co_max(array_d, result_image=1, stat=status)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_R:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_max %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ call co_max(array_r, result_image=1, stat= status, errmsg=message)
+
+end program
diff --git a/flang/test/Lower/MIF/co_min.f90 b/flang/test/Lower/MIF/co_min.f90
new file mode 100644
index 0000000..a7adc6b
--- /dev/null
+++ b/flang/test/Lower/MIF/co_min.f90
@@ -0,0 +1,60 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
+
+program test_co_min
+ integer :: i, array_i(2), status
+ real :: r, array_r(2)
+ double precision :: d, array_d(2)
+ character(len=1) :: c, array_c(2), message
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: mif.co_min %[[V1]] : (!fir.box<i32>)
+ call co_min(i)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_min %[[V1]] : (!fir.box<!fir.char<1>>)
+ call co_min(c)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ ! CHECK: mif.co_min %[[V1]] : (!fir.box<f64>)
+ call co_min(d)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: mif.co_min %[[V1]] : (!fir.box<f32>)
+ call co_min(r)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: mif.co_min %[[V1]] result %[[C1_i32:.*]] : (!fir.box<i32>, i32)
+ call co_min(i, result_image=1)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_min %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<f64>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ call co_min(d, result_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_min %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<f32>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ call co_min(r, result_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ ! CHECK: mif.co_min %[[V1]] : (!fir.box<!fir.array<2xi32>>)
+ call co_min(array_i)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
+ ! CHECK: mif.co_min %[[V1]] result %[[C1_i32:.*]] : (!fir.box<!fir.array<2x!fir.char<1>>>, i32)
+ call co_min(array_c, result_image=1)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ ! CHECK: mif.co_min %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 : (!fir.box<!fir.array<2xf64>>, i32, !fir.ref<i32>)
+ call co_min(array_d, result_image=1, stat=status)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_R:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_min %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ call co_min(array_r, result_image=1, stat= status, errmsg=message)
+
+end program
diff --git a/flang/test/Lower/MIF/co_sum.f90 b/flang/test/Lower/MIF/co_sum.f90
new file mode 100644
index 0000000..0d8a2585
--- /dev/null
+++ b/flang/test/Lower/MIF/co_sum.f90
@@ -0,0 +1,51 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
+
+program test_co_sum
+ integer :: i, array_i(2), status
+ real :: r, array_r(2)
+ double precision :: d, array_d(2)
+ character(len=1) :: message
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: mif.co_sum %[[V1]] : (!fir.box<i32>)
+ call co_sum(i)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ ! CHECK: mif.co_sum %[[V1]] : (!fir.box<f64>)
+ call co_sum(d)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: mif.co_sum %[[V1]] : (!fir.box<f32>)
+ call co_sum(r)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: mif.co_sum %[[V1]] result %[[C1_i32:.*]] : (!fir.box<i32>, i32)
+ call co_sum(i, result_image=1)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_sum %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<f64>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ call co_sum(d, result_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_sum %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<f32>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ call co_sum(r, result_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ ! CHECK: mif.co_sum %[[V1]] : (!fir.box<!fir.array<2xi32>>)
+ call co_sum(array_i)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ ! CHECK: mif.co_sum %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 : (!fir.box<!fir.array<2xf64>>, i32, !fir.ref<i32>)
+ call co_sum(array_d, result_image=1, stat=status)
+
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_R:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: mif.co_sum %[[V1]] result %[[C1_i32:.*]] stat %[[STATUS:.*]]#0 errmsg %[[V2]] : (!fir.box<!fir.array<2xf32>>, i32, !fir.ref<i32>, !fir.box<!fir.char<1>>)
+ call co_sum(array_r, result_image=1, stat= status, errmsg=message)
+
+end program
diff --git a/flang/test/Lower/Coarray/coarray-init.f90 b/flang/test/Lower/MIF/coarray-init.f90
index 055bc0f..e354473 100644
--- a/flang/test/Lower/Coarray/coarray-init.f90
+++ b/flang/test/Lower/MIF/coarray-init.f90
@@ -7,5 +7,5 @@ end
! ALL-LABEL: func.func @main
! ALL: fir.call @_FortranAProgramStart
-! COARRAY: fir.call @_QMprifPprif_init(%[[ARG:.*]]) fastmath<contract> : (!fir.ref<i32>) -> ()
-! NOCOARRAY-NOT: fir.call @_QMprifPprif_init(%[[ARG:.*]]) fastmath<contract> : (!fir.ref<i32>) -> ()
+! COARRAY: mif.init -> i32
+! NOCOARRAY-NOT: mif.init
diff --git a/flang/test/Lower/Coarray/num_images.f90 b/flang/test/Lower/MIF/num_images.f90
index ebfce5d..a673b6e 100644
--- a/flang/test/Lower/Coarray/num_images.f90
+++ b/flang/test/Lower/MIF/num_images.f90
@@ -6,13 +6,13 @@ program test
integer :: team_number
type(team_type) :: team
- ! CHECK: fir.call @_QMprifPprif_num_images
+ ! CHECK: mif.num_images : () -> i32
i = num_images()
- ! CHECK: fir.call @_QMprifPprif_num_images_with_team_number
+ ! CHECK: mif.num_images team_number %[[TEAM_NUMBER:.*]] : (i32) -> i32
i = num_images(TEAM_NUMBER=team_number)
- ! CHECK: fir.call @_QMprifPprif_num_images_with_team
+ ! CHECK: mif.num_images team %[[TEAM:.*]]#0 : ({{.*}}) -> i32
i = num_images(TEAM=team)
end program
diff --git a/flang/test/Lower/MIF/sync_all.f90 b/flang/test/Lower/MIF/sync_all.f90
new file mode 100644
index 0000000..2b1997c
--- /dev/null
+++ b/flang/test/Lower/MIF/sync_all.f90
@@ -0,0 +1,27 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY
+! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY
+
+program test_sync_all
+ implicit none
+ ! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable.
+
+ ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ integer sync_status
+ character(len=128) :: error_message
+
+ ! COARRAY: mif.sync_all : ()
+ sync all
+
+ ! COARRAY: mif.sync_all stat %[[STAT]]#0 : (!fir.ref<i32>)
+ sync all(stat=sync_status)
+
+ ! COARRAY: %[[VAL_1:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: mif.sync_all errmsg %[[VAL_1]] : (!fir.box<!fir.char<1,128>>)
+ sync all( errmsg=error_message)
+
+ ! COARRAY: %[[VAL_2:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: mif.sync_all stat %[[STAT]]#0 errmsg %[[VAL_2]] : (!fir.ref<i32>, !fir.box<!fir.char<1,128>>)
+ sync all(stat=sync_status, errmsg=error_message)
+
+end program test_sync_all
diff --git a/flang/test/Lower/MIF/sync_images.f90 b/flang/test/Lower/MIF/sync_images.f90
new file mode 100644
index 0000000..7ee5936
--- /dev/null
+++ b/flang/test/Lower/MIF/sync_images.f90
@@ -0,0 +1,39 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY
+! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY
+
+program test_sync_images
+ implicit none
+ ! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable.
+
+ ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ ! COARRAY: %[[ME:.*]]:2 = hlfir.declare %[[VAL_3:.*]] {uniq_name = "_QFEme"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ integer sync_status, me
+ character(len=128) :: error_message
+
+ ! COARRAY: %[[VAL_1:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: mif.sync_images stat %[[STAT]]#0 errmsg %[[VAL_1]] : (!fir.ref<i32>, !fir.box<!fir.char<1,128>>)
+ sync images(*, stat=sync_status, errmsg=error_message)
+
+ ! COARRAY: %[[VAL_2:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: %[[VAL_3:.*]] = fir.embox %[[ME]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! COARRAY: mif.sync_images image_set %[[VAL_3]] stat %[[STAT]]#0 errmsg %[[VAL_2]] : (!fir.box<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,128>>)
+ sync images(me, stat=sync_status, errmsg=error_message)
+
+ ! COARRAY: %[[VAL_4:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: %[[VAL_5:.*]] = fir.embox %[[IMG_SET:.*]]#0(%[[SHAPE_1:.*]]) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ ! COARRAY: mif.sync_images image_set %[[VAL_5]] stat %[[STAT]]#0 errmsg %[[VAL_4]] : (!fir.box<!fir.array<1xi32>>, !fir.ref<i32>, !fir.box<!fir.char<1,128>>)
+ sync images([1], stat=sync_status, errmsg=error_message)
+
+ ! COARRAY: mif.sync_images : ()
+ sync images(*)
+
+ ! COARRAY: %[[VAL_6:.*]] = fir.embox %[[ME]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! COARRAY: mif.sync_images image_set %[[VAL_6]] : (!fir.box<i32>)
+ sync images(me)
+
+ ! COARRAY: %[[VAL_7:.*]] = fir.embox %[[IMG_SET:.*]]#0(%[[SHAPE_3:.*]]) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+ ! COARRAY: mif.sync_images image_set %[[VAL_7]] : (!fir.box<!fir.array<1xi32>>)
+ sync images([1])
+
+end program test_sync_images
diff --git a/flang/test/Lower/MIF/sync_memory.f90 b/flang/test/Lower/MIF/sync_memory.f90
new file mode 100644
index 0000000..e6e0fa1
--- /dev/null
+++ b/flang/test/Lower/MIF/sync_memory.f90
@@ -0,0 +1,27 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY
+! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY
+
+program test_sync_memory
+ implicit none
+ ! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable.
+
+ ! COARRAY: %[[ERRMSG:.*]]:2 = hlfir.declare %[[VAL_1:.*]] typeparams %[[C_128:.*]] {uniq_name = "_QFEerror_message"} : (!fir.ref<!fir.char<1,128>>, index) -> (!fir.ref<!fir.char<1,128>>, !fir.ref<!fir.char<1,128>>)
+ ! COARRAY: %[[STAT:.*]]:2 = hlfir.declare %[[VAL_2:.*]] {uniq_name = "_QFEsync_status"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ integer sync_status
+ character(len=128) :: error_message
+
+ ! COARRAY: mif.sync_memory : ()
+ sync memory
+
+ ! COARRAY: mif.sync_memory stat %[[STAT]]#0 : (!fir.ref<i32>)
+ sync memory(stat=sync_status)
+
+ ! COARRAY: %[[VAL_1:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: mif.sync_memory errmsg %[[VAL_1]] : (!fir.box<!fir.char<1,128>>)
+ sync memory( errmsg=error_message)
+
+ ! COARRAY: %[[VAL_2:.*]] = fir.embox %[[ERRMSG]]#0 : (!fir.ref<!fir.char<1,128>>) -> !fir.box<!fir.char<1,128>>
+ ! COARRAY: mif.sync_memory stat %[[STAT]]#0 errmsg %[[VAL_2]] : (!fir.ref<i32>, !fir.box<!fir.char<1,128>>)
+ sync memory(stat=sync_status, errmsg=error_message)
+
+end program test_sync_memory
diff --git a/flang/test/Lower/Coarray/this_image.f90 b/flang/test/Lower/MIF/this_image.f90
index 143504b..ce729b3 100644
--- a/flang/test/Lower/Coarray/this_image.f90
+++ b/flang/test/Lower/MIF/this_image.f90
@@ -5,10 +5,10 @@ program test
integer :: i
type(team_type) :: team
- ! CHECK: fir.call @_QMprifPprif_this_image_no_coarray
+ ! CHECK: mif.this_image : () -> i32
i = this_image()
- ! CHECK: fir.call @_QMprifPprif_this_image_no_coarray
+ ! CHECK: mif.this_image team %[[TEAM:.*]] : ({{.*}}) -> i32
i = this_image(TEAM=team)
end program
diff --git a/flang/test/Lower/OpenACC/acc-unstructured.f90 b/flang/test/Lower/OpenACC/acc-unstructured.f90
index c57af98..c42c7dd 100644
--- a/flang/test/Lower/OpenACC/acc-unstructured.f90
+++ b/flang/test/Lower/OpenACC/acc-unstructured.f90
@@ -1,4 +1,5 @@
! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
+! XFAIL: *
subroutine test_unstructured1(a, b, c)
integer :: i, j, k
diff --git a/flang/test/Parser/OpenMP/requires.f90 b/flang/test/Parser/OpenMP/requires.f90
index 8169403..ab4f437 100644
--- a/flang/test/Parser/OpenMP/requires.f90
+++ b/flang/test/Parser/OpenMP/requires.f90
@@ -1,5 +1,5 @@
-!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=50 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
-!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=50 %s | FileCheck --check-prefix="PARSE-TREE" %s
+!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=60 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
+!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=60 %s | FileCheck --check-prefix="PARSE-TREE" %s
!$omp requires atomic_default_mem_order(seq_cst)
@@ -44,4 +44,13 @@
!PARSE-TREE: | | | bool = 'false'
!PARSE-TREE: | Flags = None
+!$omp requires device_safesync
+
+!UNPARSE: !$OMP REQUIRES DEVICE_SAFESYNC
+
+!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPRequiresConstruct -> OmpDirectiveSpecification
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = requires
+!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceSafesync
+!PARSE-TREE: | Flags = None
+
end
diff --git a/flang/test/Semantics/OpenMP/combined-constructs.f90 b/flang/test/Semantics/OpenMP/combined-constructs.f90
index 49da562..3e9c654 100644
--- a/flang/test/Semantics/OpenMP/combined-constructs.f90
+++ b/flang/test/Semantics/OpenMP/combined-constructs.f90
@@ -7,7 +7,7 @@ program main
real(8) :: a(256), b(256)
N = 256
- !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !WARNING: `DISTRIBUTE` must be dynamically enclosed in a `TEAMS` region.
!$omp distribute simd
do i = 1, N
a(i) = 3.14d0
diff --git a/flang/test/Semantics/OpenMP/do05.f90 b/flang/test/Semantics/OpenMP/do05.f90
index 24844f9..d832052 100644
--- a/flang/test/Semantics/OpenMP/do05.f90
+++ b/flang/test/Semantics/OpenMP/do05.f90
@@ -49,7 +49,7 @@ program omp_do
end do
!$omp end parallel do simd
- !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !WARNING: `DISTRIBUTE` must be dynamically enclosed in a `TEAMS` region.
!$omp distribute parallel do
do i=1,10
if( i == 3 ) then
@@ -64,7 +64,7 @@ program omp_do
end do
!$omp end distribute parallel do
- !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !WARNING: `DISTRIBUTE` must be dynamically enclosed in a `TEAMS` region.
!$omp distribute parallel do simd
do i=1,10
if( i == 3 ) then
diff --git a/flang/test/Semantics/OpenMP/linear-iter.f90 b/flang/test/Semantics/OpenMP/linear-iter.f90
index 1f40228..5c9f2d5 100644
--- a/flang/test/Semantics/OpenMP/linear-iter.f90
+++ b/flang/test/Semantics/OpenMP/linear-iter.f90
@@ -53,7 +53,7 @@ SUBROUTINE LINEAR_BAD(N)
!$omp end teams
!$omp end target
- !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !WARNING: `DISTRIBUTE` must be dynamically enclosed in a `TEAMS` region.
!ERROR: Variable 'j' not allowed in LINEAR clause, only loop iterator can be specified in LINEAR clause of a construct combined with DISTRIBUTE
!$omp distribute simd linear(i,j)
do i = 1, N
@@ -63,7 +63,7 @@ SUBROUTINE LINEAR_BAD(N)
enddo
!$omp end distribute simd
- !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !WARNING: `DISTRIBUTE` must be dynamically enclosed in a `TEAMS` region.
!ERROR: Variable 'j' not allowed in LINEAR clause, only loop iterator can be specified in LINEAR clause of a construct combined with DISTRIBUTE
!$omp distribute simd linear(i,j) collapse(1)
do i = 1, N
@@ -73,7 +73,7 @@ SUBROUTINE LINEAR_BAD(N)
enddo
!$omp end distribute simd
- !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !WARNING: `DISTRIBUTE` must be dynamically enclosed in a `TEAMS` region.
!$omp distribute simd linear(i,j) collapse(2)
do i = 1, N
do j = 1, N
diff --git a/flang/test/Semantics/OpenMP/nested-distribute.f90 b/flang/test/Semantics/OpenMP/nested-distribute.f90
index cb4aea3..4134ced 100644
--- a/flang/test/Semantics/OpenMP/nested-distribute.f90
+++ b/flang/test/Semantics/OpenMP/nested-distribute.f90
@@ -1,6 +1,15 @@
! RUN: %python %S/../test_errors.py %s %flang -fopenmp
! Check OpenMP clause validity for the following directives:
! 2.10 Device constructs
+
+subroutine f
+ integer :: i
+ !WARNING: `DISTRIBUTE` must be dynamically enclosed in a `TEAMS` region.
+ !$omp distribute
+ do i = 1, 100
+ print *, "hello"
+ end do
+end subroutine
program main
real(8) :: arrayA(256), arrayB(256)
@@ -108,4 +117,8 @@ program main
end do
!$omp end distribute
!$omp end task
+
+ !$omp teams
+ call foo
+ !$omp end teams
end program main
diff --git a/flang/tools/bbc/CMakeLists.txt b/flang/tools/bbc/CMakeLists.txt
index 7516157..2d05214 100644
--- a/flang/tools/bbc/CMakeLists.txt
+++ b/flang/tools/bbc/CMakeLists.txt
@@ -35,6 +35,7 @@ target_link_libraries(bbc PRIVATE
FortranEvaluate
FortranSemantics
FortranLower
+ MIFDialect
)
mlir_target_link_libraries(bbc PRIVATE
diff --git a/flang/tools/fir-lsp-server/CMakeLists.txt b/flang/tools/fir-lsp-server/CMakeLists.txt
index 86cde79..17ed948 100644
--- a/flang/tools/fir-lsp-server/CMakeLists.txt
+++ b/flang/tools/fir-lsp-server/CMakeLists.txt
@@ -13,7 +13,8 @@ target_link_libraries(fir-lsp-server PRIVATE
FIRDialect
FIROpenACCSupport
FIROpenMPSupport
- HLFIRDialect)
+ HLFIRDialect
+ MIFDialect)
mlir_target_link_libraries(fir-lsp-server PRIVATE
MLIRLspServerLib
diff --git a/flang/tools/fir-opt/CMakeLists.txt b/flang/tools/fir-opt/CMakeLists.txt
index 82178c2..e735c2c 100644
--- a/flang/tools/fir-opt/CMakeLists.txt
+++ b/flang/tools/fir-opt/CMakeLists.txt
@@ -27,6 +27,7 @@ target_link_libraries(fir-opt PRIVATE
FIROpenMPSupport
FlangOpenMPTransforms
FIRAnalysis
+ MIFDialect
${test_libs}
)
diff --git a/flang/tools/tco/CMakeLists.txt b/flang/tools/tco/CMakeLists.txt
index ab2aab2..5ab8952 100644
--- a/flang/tools/tco/CMakeLists.txt
+++ b/flang/tools/tco/CMakeLists.txt
@@ -23,6 +23,7 @@ target_link_libraries(tco PRIVATE
FIROpenMPSupport
FlangOpenMPTransforms
FortranSupport
+ MIFDialect
)
mlir_target_link_libraries(tco PRIVATE
diff --git a/flang/unittests/Optimizer/CMakeLists.txt b/flang/unittests/Optimizer/CMakeLists.txt
index a84d54d..3a04008b 100644
--- a/flang/unittests/Optimizer/CMakeLists.txt
+++ b/flang/unittests/Optimizer/CMakeLists.txt
@@ -13,6 +13,7 @@ set(LIBS
FIRDialectSupport
FIRSupport
HLFIRDialect
+ MIFDialect
)
add_flang_unittest(FlangOptimizerTests
@@ -42,7 +43,8 @@ DEPENDS
CUFDialect
FIRDialect
FIRSupport
- HLFIRDialect)
+ HLFIRDialect
+ MIFDialect)
if(NOT FLANG_STANDALONE_BUILD)
add_dependencies(FlangOptimizerTests