[flang-commits] [flang] [Flang][MIF] Adding support of intrinsics with coarray argument (PR #192944)
via flang-commits
flang-commits at lists.llvm.org
Mon Apr 20 04:21:59 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Jean-Didier PAILLEUX (JDPailleux)
<details>
<summary>Changes</summary>
Added support for intrinsics that query the coarray in argument:
- Adding lowering and operation in MIF Dialect for UCOBOUND, LCOBOUND, COSHAPE and IMAGE_INDEX
- Adding support of coarray argument for THIS_IMAGE in MIF Dialect (and the lowering)
---
Patch is 69.85 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/192944.diff
15 Files Affected:
- (modified) flang/include/flang/Optimizer/Builder/IntrinsicCall.h (+7)
- (modified) flang/include/flang/Optimizer/Dialect/FIROpsSupport.h (+3)
- (modified) flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td (+124-4)
- (modified) flang/lib/Lower/ConvertCall.cpp (+51-6)
- (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+93-5)
- (modified) flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp (+117-3)
- (modified) flang/lib/Optimizer/Transforms/MIFOpConversion.cpp (+252-19)
- (added) flang/test/Fir/MIF/cobound.mlir (+93)
- (added) flang/test/Fir/MIF/coshape.mlir (+78)
- (added) flang/test/Fir/MIF/image_index.mlir (+67)
- (modified) flang/test/Fir/MIF/this_image.mlir (+56-7)
- (added) flang/test/Lower/MIF/cobound.f90 (+21)
- (added) flang/test/Lower/MIF/coshape.f90 (+14)
- (added) flang/test/Lower/MIF/image_index.f90 (+20)
- (modified) flang/test/Lower/MIF/this_image.f90 (+8-2)
``````````diff
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index ca9677a8cb2b1..adf05affecc41 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -176,6 +176,7 @@ struct IntrinsicLibrary {
llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genCmplx(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genConjg(mlir::Type, llvm::ArrayRef<mlir::Value>);
+ fir::ExtendedValue genCoshape(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genCount(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
void genCpuTime(llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genCshift(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
@@ -295,6 +296,8 @@ struct IntrinsicLibrary {
mlir::Value genIeeeUnordered(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genIeeeValue(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genIeor(mlir::Type, llvm::ArrayRef<mlir::Value>);
+ fir::ExtendedValue genImageIndex(mlir::Type,
+ llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genIndex(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genIor(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genIparity(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
@@ -309,6 +312,8 @@ struct IntrinsicLibrary {
mlir::Value genIshft(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genIshftc(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genLbound(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
+ fir::ExtendedValue genLcobound(mlir::Type,
+ llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genLeadz(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genLen(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genLenTrim(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
@@ -415,6 +420,8 @@ struct IntrinsicLibrary {
llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genTrim(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genUbound(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
+ fir::ExtendedValue genUcobound(mlir::Type,
+ llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genUnlink(std::optional<mlir::Type> resultType,
llvm::ArrayRef<fir::ExtendedValue> args);
fir::ExtendedValue genUnpack(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
diff --git a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
index b014d925592cb..9e168ffe90d0d 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
+++ b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
@@ -136,6 +136,9 @@ static constexpr llvm::StringRef getAccessGroupsAttrName() {
return "access_groups";
}
+/// Attribute to mark coarray Fortran entities with the CORANK attribute.
+constexpr llvm::StringRef getCorankAttrName() { return "fir.corank"; }
+
/// Does the function, \p func, have a host-associations tuple argument?
/// Some internal procedures may have access to host procedure variables.
bool hasHostAssociationArgument(mlir::func::FuncOp func);
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
index 7df274b5697f3..f39ea71e93ffd 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -102,11 +102,13 @@ def mif_ThisImageOp : mif_Op<"this_image", [AttrSizedOperandSegments]> {
value 5, `this_image(A)` has the value [5, 0, 0].
}];
- let arguments = (ins Optional<fir_BoxType>:$coarray,
- Optional<AnyInteger>:$dim, Optional<AnyRefOrBoxType>:$team);
- let results = (outs I32:$res);
+ let arguments = (ins Optional<AnyType>:$coarray, Optional<AnyInteger>:$dim,
+ Optional<AnyRefOrBoxType>:$team);
+ let results = (outs AnyType:$res);
- let builders = [OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$team)>,
+ let builders = [OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$dim,
+ "mlir::Value":$team)>,
+ OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$team)>,
OpBuilder<(ins "mlir::Value":$team)>];
let hasVerifier = 1;
@@ -118,6 +120,124 @@ def mif_ThisImageOp : mif_Op<"this_image", [AttrSizedOperandSegments]> {
}];
}
+//===----------------------------------------------------------------------===//
+// Coarray Queries
+//===----------------------------------------------------------------------===//
+
+def mif_ImageIndexOp : mif_Op<"image_index", [AttrSizedOperandSegments]> {
+ let summary = "Image index from cosubscripts.";
+ let description = [{
+ Arguments:
+ - `coarray`: Shall be a coarray of any type.
+ - `sub`: rank-one integer array of size equal to the corank of `coarray`.
+ - `team`: Shall be a scalar of type `team_type` from ISO_FORTRAN_ENV.
+ - `team_number`: It shall identify the initial team or a sibling team
+ of the current team.
+
+ Usage:
+ - Case(1) : `call image_index(coarray, sub)`
+ - Case(2) : `call image_index(coarray, sub, team)`
+ - Case(3) : `call image_index(coarray, sub, team_number)`
+
+ Result: If the value of `sub` is a valid sequence of cosubscripts for `coarray` in the
+ team specified by `team` or `team_number`, or the current team if neither `team` nor
+ `team_number` appears, the result is the index of the corresponding image in that team.
+ Otherwise, the result is zero.
+ }];
+
+ let arguments = (ins AnyType:$coarray, fir_BoxType:$sub,
+ Optional<AnyRefOrBoxType>:$team, Optional<AnyInteger>:$team_number);
+ let builders = [OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$sub,
+ "mlir::Value":$team)>];
+
+ let results = (outs I32);
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ `coarray` $coarray `sub` $sub
+ ( `team` $team^ )?
+ ( `team_number` $team_number^ )?
+ attr-dict `:` functional-type(operands, results)
+ }];
+}
+
+def mif_LcoboundOp : mif_Op<"lcobound", [NoMemoryEffect]> {
+ let summary = "Returns the lower cobound(s) associated with a coarray.";
+ let description = [{
+ This operation returns the lower cobound(s) associated with a coarray.
+ Arguments:
+ - `coarray`: Shall be a coarray of any type.
+ - `dim`(optional) : Shall be an integer scalar. Its value shall be in the range of
+ `1 <= DIM <= N`, where `N` is the corank of the coarray.
+ Results:
+ - Case(1): If `dim` is present, the result is an integer scalar equal to
+ the lower cobound for codimension `dim`.
+ - Case(2): `dim` is absent, so the result is an array whose size matches
+ the corank of the indicated coarray.
+ }];
+
+ let arguments = (ins AnyType:$coarray, Optional<AnyInteger>:$dim);
+ let results = (outs AnyType);
+
+ let builders = [OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$dim)>,
+ OpBuilder<(ins "mlir::Value":$coarray)>];
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ `coarray` $coarray
+ ( `dim` $dim^ )?
+ attr-dict `:` functional-type(operands, results)
+ }];
+}
+
+def mif_UcoboundOp : mif_Op<"ucobound", [NoMemoryEffect]> {
+ let summary = "Returns the upper cobound(s) associated with a coarray.";
+ let description = [{
+ This operation returns the upper cobound(s) associated with a coarray.
+ Arguments:
+ - `coarray`: Shall be a coarray of any type.
+ - `dim`(optional) : Shall be an integer scalar. Its value shall be in the range of
+ `1 <= DIM <= N`, where `N` is the corank of the coarray.
+ Results:
+ - Case(1): If `dim` is present, the result is an integer scalar equal to
+ the upper cobound for codimension `dim`.
+ - Case(2): `dim` is absent, so the result is an array whose size matches
+ the corank of the indicated coarray.
+ }];
+
+ let arguments = (ins AnyType:$coarray, Optional<AnyInteger>:$dim);
+ let results = (outs AnyType);
+
+ let builders = [OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$dim)>,
+ OpBuilder<(ins "mlir::Value":$coarray)>];
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ `coarray` $coarray
+ ( `dim` $dim^ )?
+ attr-dict `:` functional-type(operands, results)
+ }];
+}
+
+def mif_CoshapeOp : mif_Op<"coshape", [NoMemoryEffect]> {
+ let summary = "Return the sizes of codimensions of a coarray.";
+ let description = [{
+ Argument: `coarray`: Shall be a coarray of any type.
+ Result : Is an array whose size matches the corank of the indicated coarray and
+ returns `UCOBOUND - LCOBOUND + 1`.
+ }];
+
+ let arguments = (ins AnyType:$coarray);
+ let builders = [OpBuilder<(ins "mlir::Value":$coarray)>];
+ let results = (outs AnyBoxedArray);
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ `coarray` $coarray
+ attr-dict `:` functional-type(operands, results)
+ }];
+}
+
//===----------------------------------------------------------------------===//
// Synchronization
//===----------------------------------------------------------------------===//
diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index ea65a49355330..ada0708931b4e 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -2149,6 +2149,22 @@ static std::optional<hlfir::EntityWithAttributes> genCustomIntrinsicRefCore(
loc, builder, result, ".tmp.custom_intrinsic_result")}};
}
+static mlir::IntegerAttr
+getCorankFromExpr(fir::FirOpBuilder &builder,
+ const Fortran::lower::SomeExpr &expr) {
+ mlir::IntegerAttr corankAttr;
+ if (auto dataRef{Fortran::evaluate::ExtractDataRef(expr)}) {
+ const Fortran::semantics::Symbol sym = dataRef->GetLastSymbol();
+ if (const auto *object =
+ sym.GetUltimate()
+ .detailsIf<Fortran::semantics::ObjectEntityDetails>())
+ if (object->coshape().size())
+ corankAttr = builder.getIntegerAttr(builder.getI32Type(),
+ object->coshape().size());
+ }
+ return corankAttr;
+}
+
/// Lower calls to intrinsic procedures with actual arguments that have been
/// pre-lowered but have not yet been prepared according to the interface.
static std::optional<hlfir::EntityWithAttributes>
@@ -2172,6 +2188,11 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals,
const fir::IntrinsicArgumentLoweringRules *argLowering =
intrinsicEntry.getArgumentLoweringRules();
for (auto arg : llvm::enumerate(loweredActuals)) {
+ // Trying to retrieve the corank of a variable if this is a coarray
+ mlir::IntegerAttr corankAttr;
+ if (const Fortran::lower::SomeExpr *expr =
+ callContext.procRef.UnwrapArgExpr(arg.index()))
+ corankAttr = getCorankFromExpr(builder, *expr);
if (!arg.value()) {
operands.emplace_back(fir::getAbsentIntrinsicArgument());
continue;
@@ -2221,6 +2242,9 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals,
genOptionalValue(builder, loc, getActualFortranElementType(),
getActualCb, isPresent);
addToCleanups(std::move(cleanup));
+ if (corankAttr)
+ fir::getBase(exv).getDefiningOp()->setAttr(fir::getCorankAttrName(),
+ corankAttr);
operands.emplace_back(exv);
continue;
}
@@ -2228,6 +2252,9 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals,
hlfir::Entity actual = arg.value()->getActual(loc, builder);
auto [exv, cleanup] = genOptionalAddr(builder, loc, actual, isPresent);
addToCleanups(std::move(cleanup));
+ if (corankAttr)
+ fir::getBase(exv).getDefiningOp()->setAttr(fir::getCorankAttrName(),
+ corankAttr);
operands.emplace_back(exv);
continue;
}
@@ -2235,6 +2262,9 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals,
hlfir::Entity actual = arg.value()->getActual(loc, builder);
auto [exv, cleanup] = genOptionalBox(builder, loc, actual, isPresent);
addToCleanups(std::move(cleanup));
+ if (corankAttr)
+ fir::getBase(exv).getDefiningOp()->setAttr(fir::getCorankAttrName(),
+ corankAttr);
operands.emplace_back(exv);
continue;
}
@@ -2250,19 +2280,31 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals,
llvm_unreachable("bad switch");
}
+ fir::ExtendedValue exv;
hlfir::Entity actual = arg.value()->getActual(loc, builder);
switch (argRules.lowerAs) {
case fir::LowerIntrinsicArgAs::Value:
- operands.emplace_back(
- Fortran::lower::convertToValue(loc, converter, actual, stmtCtx));
+ exv = Fortran::lower::convertToValue(loc, converter, actual, stmtCtx);
+ if (corankAttr)
+ fir::getBase(exv).getDefiningOp()->setAttr(fir::getCorankAttrName(),
+ corankAttr);
+ operands.emplace_back(exv);
continue;
case fir::LowerIntrinsicArgAs::Addr:
- operands.emplace_back(Fortran::lower::convertToAddress(
- loc, converter, actual, stmtCtx, getActualFortranElementType()));
+ exv = Fortran::lower::convertToAddress(loc, converter, actual, stmtCtx,
+ getActualFortranElementType());
+ if (corankAttr)
+ fir::getBase(exv).getDefiningOp()->setAttr(fir::getCorankAttrName(),
+ corankAttr);
+ operands.emplace_back(exv);
continue;
case fir::LowerIntrinsicArgAs::Box:
- operands.emplace_back(Fortran::lower::convertToBox(
- loc, converter, actual, stmtCtx, getActualFortranElementType()));
+ exv = Fortran::lower::convertToBox(loc, converter, actual, stmtCtx,
+ getActualFortranElementType());
+ if (corankAttr)
+ fir::getBase(exv).getDefiningOp()->setAttr(fir::getCorankAttrName(),
+ corankAttr);
+ operands.emplace_back(exv);
continue;
case fir::LowerIntrinsicArgAs::Inquired:
if (const Fortran::lower::SomeExpr *expr =
@@ -2977,6 +3019,9 @@ genCustomIntrinsicRef(const Fortran::evaluate::SpecificIntrinsic *intrinsic,
}
if (!exv)
llvm_unreachable("bad switch");
+ if (mlir::IntegerAttr corankAttr = getCorankFromExpr(builder, expr))
+ fir::getBase(*exv).getDefiningOp()->setAttr(fir::getCorankAttrName(),
+ corankAttr);
actual = extendedValueToHlfirEntity(loc, builder, exv.value(),
"tmp.custom_intrinsic_arg");
loweredActuals.emplace_back(Fortran::lower::PreparedActualArgument{
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 8f75b94d2f7e7..dd1c0dcd6d069 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -243,6 +243,10 @@ static constexpr IntrinsicHandler handlers[]{
{"command_argument_count", &I::genCommandArgumentCount},
{"conjg", &I::genConjg},
{"cosd", &I::genCosd},
+ {"coshape",
+ &I::genCoshape,
+ {{{"coarray", asAddr}, {"kind", asValue}}},
+ false},
{"cospi", &I::genCospi},
{"count",
&I::genCount,
@@ -499,6 +503,13 @@ static constexpr IntrinsicHandler handlers[]{
{"ieee_unordered", &I::genIeeeUnordered},
{"ieee_value", &I::genIeeeValue},
{"ieor", &I::genIeor},
+ {"image_index",
+ &I::genImageIndex,
+ {{{"coarray", asAddr},
+ {"sub", asBox},
+ {"team", asAddr},
+ {"team_number", asAddr}}},
+ /*isElemental*/ false},
{"index",
&I::genIndex,
{{{"string", asAddr},
@@ -529,6 +540,10 @@ static constexpr IntrinsicHandler handlers[]{
&I::genLbound,
{{{"array", asInquired}, {"dim", asValue}, {"kind", asValue}}},
/*isElemental=*/false},
+ {"lcobound",
+ &I::genLcobound,
+ {{{"coarray", asAddr}, {"dim", asValue}, {"kind", asValue}}},
+ /*isElemental=*/false},
{"leadz", &I::genLeadz},
{"len",
&I::genLen,
@@ -801,8 +816,8 @@ static constexpr IntrinsicHandler handlers[]{
/*isElemental=*/false},
{"this_image",
&I::genThisImage,
- {{{"coarray", asBox},
- {"dim", asAddr},
+ {{{"coarray", asAddr},
+ {"dim", asValue},
{"team", asBox, handleDynamicOptional}}},
/*isElemental=*/false},
{"time", &I::genTime, {}, /*isElemental=*/false},
@@ -827,6 +842,10 @@ static constexpr IntrinsicHandler handlers[]{
&I::genUbound,
{{{"array", asBox}, {"dim", asValue}, {"kind", asValue}}},
/*isElemental=*/false},
+ {"ucobound",
+ &I::genUcobound,
+ {{{"coarray", asAddr}, {"dim", asValue}, {"kind", asValue}}},
+ /*isElemental=*/false},
{"umaskl", &I::genMask<mlir::arith::ShLIOp>},
{"umaskr", &I::genMask<mlir::arith::ShRUIOp>},
{"unlink",
@@ -3568,6 +3587,17 @@ mlir::Value IntrinsicLibrary::genCospi(mlir::Type resultType,
return getRuntimeCallGenerator("cos", ftype)(builder, loc, {arg});
}
+// COSHAPE
+fir::ExtendedValue
+IntrinsicLibrary::genCoshape(mlir::Type,
+ llvm::ArrayRef<fir::ExtendedValue> args) {
+ converter->checkCoarrayEnabled();
+ assert(args.size() == 2);
+
+ return mif::CoshapeOp::create(builder, loc,
+ /*coarray*/ fir::getBase(args[0]));
+}
+
// COUNT
fir::ExtendedValue
IntrinsicLibrary::genCount(mlir::Type resultType,
@@ -6243,6 +6273,22 @@ mlir::Value IntrinsicLibrary::genIeor(mlir::Type resultType,
args[1]);
}
+// IMAGE_INDEX
+fir::ExtendedValue
+IntrinsicLibrary::genImageIndex(mlir::Type resultType,
+ llvm::ArrayRef<fir::ExtendedValue> args) {
+ converter->checkCoarrayEnabled();
+ assert(args.size() == 2 || args.size() == 3);
+
+ mlir::Value team;
+ if (args.size() > 2) {
+ team = fir::getBase(args[2]);
+ }
+ return mif::ImageIndexOp::create(builder, loc,
+ /*coarray*/ fir::getBase(args[0]),
+ /*sub*/ fir::getBase(args[1]), team);
+}
+
// INDEX
fir::ExtendedValue
IntrinsicLibrary::genIndex(mlir::Type resultType,
@@ -8257,11 +8303,21 @@ IntrinsicLibrary::genThisImage(mlir::Type resultType,
converter->checkCoarrayEnabled();
assert(args.size() >= 1 && args.size() <= 3);
const bool coarrayIsAbsent = args.size() == 1;
+ const bool dimIsAbsent = args.size() < 3;
mlir::Value team = fir::getBase(args[args.size() - 1]);
- if (!coarrayIsAbsent)
- TODO(loc, "this_image with coarray argument.");
- mlir::Value res = mif::ThisImageOp::create(builder, loc, team);
+ if (!coarrayIsAbsent && dimIsAbsent) {
+ mlir::Value res =
+ mif::ThisImageOp::create(builder, loc, fir::getBase(args[0]), team);
+ return res;
+ }
+ mlir::Value res;
+ if (!dimIsAbsent) {
+ mlir::Value coarray = fir::getBase(args[0]);
+ mlir::Value dim = fir::getBase(args[1]);
+ res = mif::ThisImageOp::create(builder, loc, coarray, dim, team);
+ } else
+ res = mif::ThisImageOp::create(builder, loc, team);
return builder.createConvert(loc, resultType, res);
}
@@ -8366,6 +8422,22 @@ IntrinsicLibrary::genLbound(mlir::Type resultType,
fir::runtime::genLboundDim(builder, loc, fir::getBase(box), dim));
}
+// LCOBOUND
+fir::ExtendedValue
+IntrinsicLibrary::genLcobound(mlir::Type resultType,
+ llvm::ArrayRef<fir::ExtendedValue> args) {
+ converter->checkCoarrayEnabled();
+ assert(args.size() == 2 || args.size() == 3);
+
+ mlir::Value coarray = fir::getBase(args[0]);
+ const bool dimIsAbsent = args.size() == 2 || isStaticallyAbsent(...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/192944
More information about the flang-commits
mailing list