[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