[flang-commits] [flang] [flang][MIF] Starting adding coarray access support (PR #212777)
via flang-commits
flang-commits at lists.llvm.org
Wed Jul 29 06:58:39 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Jean-Didier PAILLEUX (JDPailleux)
<details>
<summary>Changes</summary>
This PR introduces support for coarrays access with MIF and PRIF.
- 2 new operations have been added: `mif::GetCoarrayOp` and `mif::PutCoarrayOp`
- Intrinsic types are supported for these operations.
- Strides and notify are not supported
- It is now assumed that all allocations for coarrays are made on the heap. (This was not the case before).
---
Patch is 99.29 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/212777.diff
23 Files Affected:
- (modified) flang/include/flang/Lower/ConvertCall.h (+6)
- (modified) flang/include/flang/Lower/MultiImageFortran.h (+4)
- (modified) flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td (+37)
- (modified) flang/lib/Lower/Bridge.cpp (+133)
- (modified) flang/lib/Lower/ConvertCall.cpp (+18-15)
- (modified) flang/lib/Lower/ConvertExprToHLFIR.cpp (+109-3)
- (modified) flang/lib/Lower/ConvertType.cpp (+2-1)
- (modified) flang/lib/Lower/ConvertVariable.cpp (+52)
- (modified) flang/lib/Lower/MultiImageFortran.cpp (+32)
- (modified) flang/lib/Optimizer/Builder/MIFCommon.cpp (+4)
- (modified) flang/lib/Optimizer/Transforms/MIFOpConversion.cpp (+359-20)
- (added) flang/test/Fir/MIF/coarray_get.mlir (+55)
- (added) flang/test/Fir/MIF/coarray_get2.mlir (+53)
- (added) flang/test/Fir/MIF/coarray_put.mlir (+186)
- (added) flang/test/Fir/MIF/coarray_put2.mlir (+53)
- (modified) flang/test/Lower/MIF/coarray_allocation.f90 (+6-6)
- (modified) flang/test/Lower/MIF/coarray_allocation4.f90 (+15-15)
- (modified) flang/test/Lower/MIF/coarray_allocation5.f90 (+2-2)
- (added) flang/test/Lower/MIF/coarray_get.f90 (+82)
- (added) flang/test/Lower/MIF/coarray_put.f90 (+65)
- (modified) flang/test/Lower/MIF/coshape.f90 (+3-3)
- (modified) flang/test/Lower/MIF/image_index.f90 (+4-4)
- (modified) flang/test/Lower/MIF/this_image.f90 (+2-2)
``````````diff
diff --git a/flang/include/flang/Lower/ConvertCall.h b/flang/include/flang/Lower/ConvertCall.h
index 6de0b3cbd11f5..19d6664fe46bc 100644
--- a/flang/include/flang/Lower/ConvertCall.h
+++ b/flang/include/flang/Lower/ConvertCall.h
@@ -65,5 +65,11 @@ void convertUserDefinedAssignmentToHLFIR(
mlir::Location loc, Fortran::lower::AbstractConverter &converter,
const evaluate::ProcedureRef &procRef, hlfir::Entity lhs, hlfir::Entity rhs,
Fortran::lower::SymMap &symMap);
+
+// Helper to transform a fir::ExtendedValue to an hlfir::EntityWithAttributes.
+hlfir::EntityWithAttributes
+extendedValueToHlfirEntity(mlir::Location loc, fir::FirOpBuilder &builder,
+ const fir::ExtendedValue &exv, llvm::StringRef name,
+ mlir::Operation *insertBefore = nullptr);
} // namespace Fortran::lower
#endif // FORTRAN_LOWER_CONVERTCALL_H
diff --git a/flang/include/flang/Lower/MultiImageFortran.h b/flang/include/flang/Lower/MultiImageFortran.h
index c9b9e9f17cf39..1f247ee46c3a9 100644
--- a/flang/include/flang/Lower/MultiImageFortran.h
+++ b/flang/include/flang/Lower/MultiImageFortran.h
@@ -63,6 +63,10 @@ void genFormTeamStatement(AbstractConverter &, pft::Evaluation &eval,
// COARRAY utils
//===----------------------------------------------------------------------===//
+mlir::SmallVector<mlir::Value>
+getCosubscripts(AbstractConverter &converter, mlir::Location loc,
+ const evaluate::CoarrayRef &expr);
+
mlir::Value genLowerCoBounds(AbstractConverter &converter, mlir::Location loc,
const semantics::Symbol &sym);
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
index 337a9eab0b087..49f2ef2a9e388 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -592,4 +592,41 @@ def mif_DeallocCoarrayOp
}];
}
+//===----------------------------------------------------------------------===//
+// Coarray Access
+//===----------------------------------------------------------------------===//
+
+def mif_GetCoarrayOp : mif_Op<"get_coarray", [AttrSizedOperandSegments]> {
+ let summary = "Fetch data in a coarray from an image number";
+
+ let arguments = (ins Arg<AnyRefOrBoxType, "", [MemRead]>:$coarray,
+ Variadic<AnyIntegerType>:$cosubscripts,
+ Arg<AnyRefOrBoxType, "", [MemWrite]>:$dest,
+ Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+ Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+
+ let assemblyFormat = [{
+ `from` $coarray (`[` $cosubscripts^ `]`)?
+ `to` $dest (`stat` $stat^ )? (`errmsg` $errmsg^ )?
+ attr-dict `:` functional-type(operands, results)
+ }];
+}
+
+def mif_PutCoarrayOp : mif_Op<"put_coarray", [AttrSizedOperandSegments]> {
+ let summary = "Assign data to a coarray to an image number";
+
+ let arguments = (ins Arg<AnyRefOrBoxType, "", [MemWrite]>:$coarray,
+ Variadic<AnyIntegerType>:$cosubscripts,
+ Arg<AnyRefOrBoxType, "", [MemRead]>:$src,
+ Optional<AnyRefOrBoxType>:$notify,
+ Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+ Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+
+ let assemblyFormat = [{
+ `from` $src `to` $coarray (`[` $cosubscripts^ `]`)?
+ (`notify` $notify^ )?
+ (`stat` $stat^ )? (`errmsg` $errmsg^ )?
+ attr-dict `:` functional-type(operands, results)
+ }];
+}
#endif // FORTRAN_DIALECT_MIF_MIF_OPS
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index ed8b256f47fd4..65be7490cda46 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -49,6 +49,7 @@
#include "flang/Optimizer/Dialect/CUF/CUFOps.h"
#include "flang/Optimizer/Dialect/FIRAttr.h"
#include "flang/Optimizer/Dialect/FIROps.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/DataLayout.h"
@@ -815,11 +816,63 @@ class FirConverter : public Fortran::lower::AbstractConverter {
return owningProc.labelEvaluationMap.lookup(label);
}
+ /// Gen coarray expression from a CoarrayRef.
+ fir::ExtendedValue
+ genCoarrayExpr(const Fortran::lower::SomeExpr &expr,
+ const Fortran::evaluate::CoarrayRef &coarrayRef,
+ Fortran::lower::StatementContext &context,
+ mlir::Location loc) {
+ hlfir::Entity coarray = Fortran::lower::convertExprToHLFIR(
+ loc, *this, expr, localSymbols, context);
+ auto [dest, cleanup] = hlfir::createTempFromMold(loc, *builder, coarray);
+ if (cleanup)
+ context.attachCleanup(
+ [&]() { fir::FreeMemOp::create(*builder, loc, dest.getBase()); });
+
+ // Image number computation
+ auto cosubscripts = Fortran::lower::getCosubscripts(*this, loc, coarrayRef);
+
+ // handle STAT from the CoarrayRef
+ mlir::Value stat = mlir::Value{}, errmsg = mlir::Value{};
+ auto statExpr = coarrayRef.stat();
+ if (statExpr.has_value()) {
+ if (auto statRef{Fortran::evaluate::ExtractDataRef(statExpr.value())}) {
+ stat = fir::getBase(
+ getSymbolExtendedValue(statRef->GetLastSymbol(), nullptr));
+ }
+ }
+
+ mif::GetCoarrayOp::create(*builder, loc, coarray, cosubscripts, dest, stat,
+ errmsg);
+ return dest;
+ }
+
+ fir::ExtendedValue
+ genCoarrayExprValue(const Fortran::lower::SomeExpr &expr,
+ const Fortran::evaluate::CoarrayRef &coarrayRef,
+ Fortran::lower::StatementContext &context,
+ mlir::Location loc) {
+ fir::ExtendedValue exv = genCoarrayExpr(expr, coarrayRef, context, loc);
+ return fir::LoadOp::create(*builder, loc, fir::getBase(exv));
+ }
+
+ fir::ExtendedValue
+ genCoarrayExprBox(const Fortran::lower::SomeExpr &expr,
+ const Fortran::evaluate::CoarrayRef &coarrayRef,
+ Fortran::lower::StatementContext &context,
+ mlir::Location loc) {
+ fir::ExtendedValue exv = genCoarrayExpr(expr, coarrayRef, context, loc);
+ return fir::factory::createBoxValue(*builder, loc, exv);
+ }
+
fir::ExtendedValue
genExprAddr(const Fortran::lower::SomeExpr &expr,
Fortran::lower::StatementContext &context,
mlir::Location *locPtr = nullptr) override final {
mlir::Location loc = locPtr ? *locPtr : toLocation();
+ auto coarrayRef = Fortran::evaluate::ExtractCoarrayRef(expr);
+ if (coarrayRef.has_value())
+ return genCoarrayExpr(expr, coarrayRef.value(), context, loc);
return Fortran::lower::convertExprToAddress(loc, *this, expr, localSymbols,
context);
}
@@ -829,6 +882,9 @@ class FirConverter : public Fortran::lower::AbstractConverter {
Fortran::lower::StatementContext &context,
mlir::Location *locPtr = nullptr) override final {
mlir::Location loc = locPtr ? *locPtr : toLocation();
+ auto coarrayRef = Fortran::evaluate::ExtractCoarrayRef(expr);
+ if (coarrayRef.has_value())
+ return genCoarrayExprValue(expr, coarrayRef.value(), context, loc);
return Fortran::lower::convertExprToValue(loc, *this, expr, localSymbols,
context);
}
@@ -836,6 +892,9 @@ class FirConverter : public Fortran::lower::AbstractConverter {
fir::ExtendedValue
genExprBox(mlir::Location loc, const Fortran::lower::SomeExpr &expr,
Fortran::lower::StatementContext &stmtCtx) override final {
+ auto coarrayRef = Fortran::evaluate::ExtractCoarrayRef(expr);
+ if (coarrayRef.has_value())
+ return genCoarrayExprBox(expr, coarrayRef.value(), stmtCtx, loc);
return Fortran::lower::convertExprToBox(loc, *this, expr, localSymbols,
stmtCtx);
}
@@ -5477,6 +5536,68 @@ class FirConverter : public Fortran::lower::AbstractConverter {
return temps;
}
+ /// Generate an coarray assignment.
+ /// This is an assignment expression with corank > 0.
+ void genCoarrayAssignment(fir::FirOpBuilder &builder, mlir::Location loc,
+ const Fortran::evaluate::Assignment &assign) {
+ Fortran::lower::StatementContext stmtCtx;
+ auto rhsCoarrayRef = Fortran::evaluate::ExtractCoarrayRef(assign.rhs);
+ auto lhsCoarrayRef = Fortran::evaluate::ExtractCoarrayRef(assign.lhs);
+ int lhsCorank = 0;
+ if (auto lhsRef{Fortran::evaluate::ExtractDataRef(assign.lhs)})
+ lhsCorank = lhsRef->GetLastSymbol().Corank();
+
+ // handle STAT from the CoarrayRef
+ mlir::Value stat;
+ if (lhsCoarrayRef.has_value() || rhsCoarrayRef.has_value()) {
+ auto statExpr = lhsCoarrayRef.has_value() ? lhsCoarrayRef.value().stat()
+ : rhsCoarrayRef.value().stat();
+ if (statExpr.has_value()) {
+ if (auto statRef{Fortran::evaluate::ExtractDataRef(statExpr.value())}) {
+ stat = fir::getBase(
+ getSymbolExtendedValue(statRef->GetLastSymbol(), nullptr));
+ }
+ }
+ }
+
+ if (lhsCoarrayRef.has_value() || lhsCorank) {
+ hlfir::Entity lhsEntity = Fortran::lower::convertExprToHLFIR(
+ loc, *this, assign.lhs, localSymbols, stmtCtx);
+ mlir::Value rhs = fir::getBase(Fortran::lower::convertExprToAddress(
+ loc, *this, assign.rhs, localSymbols, stmtCtx));
+ auto cosubscripts =
+ lhsCoarrayRef.has_value()
+ ? Fortran::lower::getCosubscripts(*this, loc, *lhsCoarrayRef)
+ : llvm::SmallVector<mlir::Value>{};
+ // PUT operation if lhs is a coarray.
+ // Retrieving NOTIFY variable from lhsCoarrayRef if he's passed as
+ // argument on the image selector.
+ mlir::Value notifyPtr;
+ if (lhsCoarrayRef.has_value()) {
+ if (auto notifyExpr = lhsCoarrayRef.value().notify()) {
+ notifyPtr = fir::getBase(Fortran::lower::convertExprToAddress(
+ loc, *this, notifyExpr.value(), localSymbols, stmtCtx));
+ }
+ }
+ mif::PutCoarrayOp::create(builder, loc, /*coarray*/ lhsEntity,
+ cosubscripts, /*src*/ rhs, notifyPtr, stat,
+ /*errmsg*/ mlir::Value{});
+ } else {
+ // GET operation because rhs is a coarray.
+ hlfir::Entity rhsEntity = Fortran::lower::convertExprToHLFIR(
+ loc, *this, assign.rhs, localSymbols, stmtCtx);
+ mlir::Value lhs = fir::getBase(Fortran::lower::convertExprToAddress(
+ loc, *this, assign.lhs, localSymbols, stmtCtx));
+ auto cosubscripts =
+ rhsCoarrayRef.has_value()
+ ? Fortran::lower::getCosubscripts(*this, loc, *rhsCoarrayRef)
+ : llvm::SmallVector<mlir::Value>{};
+ mif::GetCoarrayOp::create(builder, loc, /*coarray*/ rhsEntity,
+ cosubscripts, /*dest*/ lhs, stat,
+ /*errmsg*/ mlir::Value{});
+ }
+ }
+
void genDataAssignment(
const Fortran::evaluate::Assignment &assign,
const Fortran::evaluate::ProcedureRef *userDefinedAssignment,
@@ -5501,6 +5622,18 @@ class FirConverter : public Fortran::lower::AbstractConverter {
if (hasCUDAImplicitTransfer && !isInDeviceContext)
implicitTemps = genCUDAImplicitDataTransfer(builder, loc, assign);
+ // Coarray Assignment
+ bool lhsIsCoarray = false, rhsIsCoarray = false;
+ if (auto lhsRef{Fortran::evaluate::ExtractDataRef(assign.lhs)})
+ lhsIsCoarray = lhsRef->GetLastSymbol().Corank() > 0;
+ if (auto rhsRef{Fortran::evaluate::ExtractDataRef(assign.rhs)})
+ rhsIsCoarray = rhsRef->GetLastSymbol().Corank() > 0;
+
+ if (lhsIsCoarray || rhsIsCoarray) {
+ genCoarrayAssignment(builder, loc, assign);
+ return;
+ }
+
// Gather some information about the assignment that will impact how it is
// lowered.
const bool lhsIsWholeAllocatable =
diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index 19678e429249b..0681facbb1d9f 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -1049,10 +1049,10 @@ using ExvAndCleanup =
} // namespace
// Helper to transform a fir::ExtendedValue to an hlfir::EntityWithAttributes.
-static hlfir::EntityWithAttributes
-extendedValueToHlfirEntity(mlir::Location loc, fir::FirOpBuilder &builder,
- const fir::ExtendedValue &exv, llvm::StringRef name,
- mlir::Operation *insertBefore = nullptr) {
+hlfir::EntityWithAttributes Fortran::lower::extendedValueToHlfirEntity(
+ mlir::Location loc, fir::FirOpBuilder &builder,
+ const fir::ExtendedValue &exv, llvm::StringRef name,
+ mlir::Operation *insertBefore) {
mlir::Value firBase = fir::getBase(exv);
mlir::Type firBaseTy = firBase.getType();
if (fir::isa_trivial(firBaseTy))
@@ -1965,10 +1965,11 @@ genUserCall(Fortran::lower::PreparedActualArguments &loweredActuals,
return std::nullopt; // subroutine call.
if (fir::isPointerType(fir::getBase(result).getType()))
- return extendedValueToHlfirEntity(loc, builder, result, tempResultName);
+ return Fortran::lower::extendedValueToHlfirEntity(loc, builder, result,
+ tempResultName);
if (!resultIsFinalized) {
- hlfir::Entity resultEntity = extendedValueToHlfirEntity(
+ hlfir::Entity resultEntity = Fortran::lower::extendedValueToHlfirEntity(
loc, builder, result, tempResultName, /*insertBefore=*/callOp);
// Allocatable result must be freed, other results are stack allocated.
const auto *allocatable = result.getBoxOf<fir::MutableBoxValue>();
@@ -2031,7 +2032,7 @@ genUserCall(Fortran::lower::PreparedActualArguments &loweredActuals,
/*mayBePolymorphic=*/true,
/*preserveLowerBounds=*/false)
: result;
- return extendedValueToHlfirEntity(
+ return Fortran::lower::extendedValueToHlfirEntity(
loc, builder, loadedResult, tempResultName,
/*insertBefore=*/!allocatable ? callOp : nullptr);
}
@@ -2159,8 +2160,9 @@ static std::optional<hlfir::EntityWithAttributes> genCustomIntrinsicRefCore(
builder, loc, callContext.getProcedureName(), resTy, isPresent,
getArgument, loweredActuals.size(), callContext.stmtCtx);
- return {hlfir::EntityWithAttributes{extendedValueToHlfirEntity(
- loc, builder, result, ".tmp.custom_intrinsic_result")}};
+ return {
+ hlfir::EntityWithAttributes{Fortran::lower::extendedValueToHlfirEntity(
+ loc, builder, result, ".tmp.custom_intrinsic_result")}};
}
static unsigned getCorank(const Fortran::lower::SomeExpr &expr) {
@@ -2312,8 +2314,8 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals,
mlir::Value boxStorage =
fir::factory::genNullBoxStorage(builder, loc, boxTy);
hlfir::EntityWithAttributes nullBoxEntity =
- extendedValueToHlfirEntity(loc, builder, boxStorage,
- ".tmp.null_box");
+ Fortran::lower::extendedValueToHlfirEntity(
+ loc, builder, boxStorage, ".tmp.null_box");
operands.emplace_back(Fortran::lower::translateToExtendedValue(
loc, builder, nullBoxEntity, stmtCtx));
continue;
@@ -2346,8 +2348,9 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals,
fn();
if (!fir::getBase(resultExv))
return std::nullopt;
- hlfir::EntityWithAttributes resultEntity = extendedValueToHlfirEntity(
- loc, builder, resultExv, ".tmp.intrinsic_result");
+ hlfir::EntityWithAttributes resultEntity =
+ Fortran::lower::extendedValueToHlfirEntity(loc, builder, resultExv,
+ ".tmp.intrinsic_result");
// Move result into memory into an hlfir.expr since they are immutable from
// that point, and the result storage is some temp. "Null" is special: it
// returns a null pointer variable that should not be transformed into a value
@@ -3021,8 +3024,8 @@ genCustomIntrinsicRef(const Fortran::evaluate::SpecificIntrinsic *intrinsic,
}
if (!exv)
llvm_unreachable("bad switch");
- actual = extendedValueToHlfirEntity(loc, builder, exv.value(),
- "tmp.custom_intrinsic_arg");
+ actual = Fortran::lower::extendedValueToHlfirEntity(
+ loc, builder, exv.value(), "tmp.custom_intrinsic_arg");
loweredActuals.emplace_back(Fortran::lower::PreparedActualArgument{
actual, /*isPresent=*/std::nullopt});
};
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index b30a2dfcba90e..009725fff9c33 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -402,11 +402,117 @@ class HlfirDesignatorBuilder {
fir::FortranVariableOpInterface
gen(const Fortran::evaluate::CoarrayRef &coarrayRef) {
- TODO(getLoc(), "coarray: lowering a reference to a coarray object");
+ PartInfo partInfo;
+ mlir::Type resultType = visit(coarrayRef, partInfo);
+ return genDesignate(resultType, partInfo, coarrayRef);
}
- mlir::Type visit(const Fortran::evaluate::CoarrayRef &, PartInfo &) {
- TODO(getLoc(), "coarray: lowering a reference to a coarray object");
+ mlir::Type visit(const Fortran::evaluate::CoarrayRef &coarrayRef,
+ PartInfo &partInfo) {
+ // Coarray is a data entity with corank > 0 that must be scalar
+ // or array.
+ mlir::Type baseType = visit(coarrayRef.base().GetLastSymbol(), partInfo);
+ if (auto seqType = mlir::dyn_cast<fir::SequenceType>(baseType)) {
+ fir::FirOpBuilder &builder = getBuilder();
+ mlir::Location loc = getLoc();
+ mlir::Type idxTy = builder.getIndexType();
+ llvm::SmallVector<std::pair<mlir::Value, mlir::Value>> bounds;
+ auto getBaseBounds = [&](unsigned i) {
+ if (bounds.empty()) {
+ bounds = hlfir::genBounds(loc, builder, partInfo.base.value());
+ assert(!bounds.empty() &&
+ "failed to compute implicit array section bounds");
+ }
+ return bounds[i];
+ };
+
+ auto frontEndResultShape = Fortran::evaluate::GetShape(
+ converter.getFoldingContext(), coarrayRef);
+ auto tryGettingExtentFromFrontEnd = [&](unsigned dim)
+ -> std::pair<mlir::Value, fir::SequenceType::Extent> {
+ // Use constant extent if possible. The main advantage to do this now
+ // is to get the best FIR array types as possible while lowering.
+ if (frontEndResultShape)
+ if (auto maybeI64 =
+ Fortran::evaluate::ToInt64(frontEndResultShape->at(dim)))
+ return {builder.createIntegerConstant(loc, idxTy, *maybeI64),
+ *maybeI64};
+ return {mlir::Value{}, fir::SequenceType::getUnknownExtent()};
+ };
+
+ llvm::SmallVector<mlir::Value> resultExtents;
+ fir::SequenceType::Shape resultTypeShape;
+ bool sawVectorSubscripts = false;
+ if (auto *arrayRef{
+ std::get_if<Fortran::evaluate::ArrayRef>(&coarrayRef.base().u)}) {
+ for (auto subscript : llvm::enumerate(arrayRef->subscript())) {
+ if (const auto *triplet = std::get_if<Fortran::evaluate::Triplet>(
+ &subscript.value().u)) {
+ mlir::Value lb, ub;
+ if (const auto &lbExpr = triplet->lower())
+ lb = genSubscript(*lbExpr);
+ else
+ lb = getBaseBounds(subscript.index()).first;
+ if (const auto &ubExpr = triplet->upper())
+ ub = genSubscript(*ubExpr);
+ else
+ ub = getBaseBounds(subscript.index()).second;
+ lb = builder.createConvert(loc, idxTy, lb);
+ ub = builder.createConvert(loc, idxTy, ub);
+ mlir::Value stride = genSubscript(triplet->stride());
+ stride = builder.createConvert(loc, idxT...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/212777
More information about the flang-commits
mailing list