aboutsummaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
Diffstat (limited to 'flang')
-rw-r--r--flang/include/flang/Optimizer/Dialect/FIROps.td1
-rw-r--r--flang/lib/Optimizer/Dialect/FIROps.cpp377
-rw-r--r--flang/test/Fir/array-coor-canonicalization.fir592
3 files changed, 970 insertions, 0 deletions
diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index d46e997c..37fbd1f 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -1711,6 +1711,7 @@ def fir_ArrayCoorOp : fir_Op<"array_coor",
}];
let hasVerifier = 1;
+ let hasCanonicalizer = 1;
}
def fir_CoordinateOp : fir_Op<"coordinate_of", [NoMemoryEffect]> {
diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index 5809b78..ece156a 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -394,11 +394,17 @@ mlir::LogicalResult fir::ArrayCoorOp::verify() {
} else {
auto s = mlir::cast<fir::ShiftType>(shapeTy);
shapeTyRank = s.getRank();
+ // TODO: it looks like PreCGRewrite and CodeGen can support
+ // fir.shift with plain array reference, so we may consider
+ // removing this check.
if (!mlir::isa<fir::BaseBoxType>(getMemref().getType()))
return emitOpError("shift can only be provided with fir.box memref");
}
if (arrDim && arrDim != shapeTyRank)
return emitOpError("rank of dimension mismatched");
+ // TODO: support slicing with changing the number of dimensions,
+ // e.g. when array_coor represents an element access to array(:,1,:)
+ // slice: the shape is 3D and the number of indices is 2 in this case.
if (shapeTyRank != getIndices().size())
return emitOpError("number of indices do not match dim rank");
}
@@ -417,6 +423,377 @@ mlir::LogicalResult fir::ArrayCoorOp::verify() {
return mlir::success();
}
+// Pull in fir.embox and fir.rebox into fir.array_coor when possible.
+struct SimplifyArrayCoorOp : public mlir::OpRewritePattern<fir::ArrayCoorOp> {
+ using mlir::OpRewritePattern<fir::ArrayCoorOp>::OpRewritePattern;
+ mlir::LogicalResult
+ matchAndRewrite(fir::ArrayCoorOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ mlir::Value memref = op.getMemref();
+ if (!mlir::isa<fir::BaseBoxType>(memref.getType()))
+ return mlir::failure();
+
+ mlir::Value boxedMemref, boxedShape, boxedSlice;
+ if (auto emboxOp =
+ mlir::dyn_cast_or_null<fir::EmboxOp>(memref.getDefiningOp())) {
+ boxedMemref = emboxOp.getMemref();
+ boxedShape = emboxOp.getShape();
+ boxedSlice = emboxOp.getSlice();
+ // If any of operands, that are not currently supported for migration
+ // to ArrayCoorOp, is present, don't rewrite.
+ if (!emboxOp.getTypeparams().empty() || emboxOp.getSourceBox() ||
+ emboxOp.getAccessMap())
+ return mlir::failure();
+ } else if (auto reboxOp = mlir::dyn_cast_or_null<fir::ReboxOp>(
+ memref.getDefiningOp())) {
+ boxedMemref = reboxOp.getBox();
+ boxedShape = reboxOp.getShape();
+ // Avoid pulling in rebox that performs reshaping.
+ // There is no way to represent box reshaping with array_coor.
+ if (boxedShape && !mlir::isa<fir::ShiftType>(boxedShape.getType()))
+ return mlir::failure();
+ boxedSlice = reboxOp.getSlice();
+ } else {
+ return mlir::failure();
+ }
+
+ bool boxedShapeIsShift =
+ boxedShape && mlir::isa<fir::ShiftType>(boxedShape.getType());
+ bool boxedShapeIsShape =
+ boxedShape && mlir::isa<fir::ShapeType>(boxedShape.getType());
+ bool boxedShapeIsShapeShift =
+ boxedShape && mlir::isa<fir::ShapeShiftType>(boxedShape.getType());
+
+ // Slices changing the number of dimensions are not supported
+ // for array_coor yet.
+ unsigned origBoxRank;
+ if (mlir::isa<fir::BaseBoxType>(boxedMemref.getType()))
+ origBoxRank = fir::getBoxRank(boxedMemref.getType());
+ else if (auto arrTy = mlir::dyn_cast<fir::SequenceType>(
+ fir::unwrapRefType(boxedMemref.getType())))
+ origBoxRank = arrTy.getDimension();
+ else
+ return mlir::failure();
+
+ if (fir::getBoxRank(memref.getType()) != origBoxRank)
+ return mlir::failure();
+
+ // Slices with substring are not supported by array_coor.
+ if (boxedSlice)
+ if (auto sliceOp =
+ mlir::dyn_cast_or_null<fir::SliceOp>(boxedSlice.getDefiningOp()))
+ if (!sliceOp.getSubstr().empty())
+ return mlir::failure();
+
+ // If embox/rebox and array_coor have conflicting shapes or slices,
+ // do nothing.
+ if (op.getShape() && boxedShape && boxedShape != op.getShape())
+ return mlir::failure();
+ if (op.getSlice() && boxedSlice && boxedSlice != op.getSlice())
+ return mlir::failure();
+
+ std::optional<IndicesVectorTy> shiftedIndices;
+ // The embox/rebox and array_coor either have compatible
+ // shape/slice at this point or shape/slice is null
+ // in one of them but not in the other.
+ // The compatibility means they are equal or both null.
+ if (!op.getShape()) {
+ if (boxedShape) {
+ if (op.getSlice()) {
+ if (!boxedSlice) {
+ if (boxedShapeIsShift) {
+ // %0 = fir.rebox %arg(%shift)
+ // %1 = fir.array_coor %0 [%slice] %idx
+ // Both the slice indices and %idx are 1-based, so the rebox
+ // may be pulled in as:
+ // %1 = fir.array_coor %arg [%slice] %idx
+ boxedShape = nullptr;
+ } else if (boxedShapeIsShape) {
+ // %0 = fir.embox %arg(%shape)
+ // %1 = fir.array_coor %0 [%slice] %idx
+ // Pull in as:
+ // %1 = fir.array_coor %arg(%shape) [%slice] %idx
+ } else if (boxedShapeIsShapeShift) {
+ // %0 = fir.embox %arg(%shapeshift)
+ // %1 = fir.array_coor %0 [%slice] %idx
+ // Pull in as:
+ // %shape = fir.shape <extents from the %shapeshift>
+ // %1 = fir.array_coor %arg(%shape) [%slice] %idx
+ boxedShape = getShapeFromShapeShift(boxedShape, rewriter);
+ if (!boxedShape)
+ return mlir::failure();
+ } else {
+ return mlir::failure();
+ }
+ } else {
+ if (boxedShapeIsShift) {
+ // %0 = fir.rebox %arg(%shift) [%slice]
+ // %1 = fir.array_coor %0 [%slice] %idx
+ // This FIR may only be valid if the shape specifies
+ // that all lower bounds are 1s and the slice's start indices
+ // and strides are all 1s.
+ // We could pull in the rebox as:
+ // %1 = fir.array_coor %arg [%slice] %idx
+ // Do not do anything for the time being.
+ return mlir::failure();
+ } else if (boxedShapeIsShape) {
+ // %0 = fir.embox %arg(%shape) [%slice]
+ // %1 = fir.array_coor %0 [%slice] %idx
+ // This FIR may only be valid if the slice's start indices
+ // and strides are all 1s.
+ // We could pull in the embox as:
+ // %1 = fir.array_coor %arg(%shape) [%slice] %idx
+ return mlir::failure();
+ } else if (boxedShapeIsShapeShift) {
+ // %0 = fir.embox %arg(%shapeshift) [%slice]
+ // %1 = fir.array_coor %0 [%slice] %idx
+ // This FIR may only be valid if the shape specifies
+ // that all lower bounds are 1s and the slice's start indices
+ // and strides are all 1s.
+ // We could pull in the embox as:
+ // %shape = fir.shape <extents from the %shapeshift>
+ // %1 = fir.array_coor %arg(%shape) [%slice] %idx
+ return mlir::failure();
+ } else {
+ return mlir::failure();
+ }
+ }
+ } else { // !op.getSlice()
+ if (!boxedSlice) {
+ if (boxedShapeIsShift) {
+ // %0 = fir.rebox %arg(%shift)
+ // %1 = fir.array_coor %0 %idx
+ // Pull in as:
+ // %1 = fir.array_coor %arg %idx
+ boxedShape = nullptr;
+ } else if (boxedShapeIsShape) {
+ // %0 = fir.embox %arg(%shape)
+ // %1 = fir.array_coor %0 %idx
+ // Pull in as:
+ // %1 = fir.array_coor %arg(%shape) %idx
+ } else if (boxedShapeIsShapeShift) {
+ // %0 = fir.embox %arg(%shapeshift)
+ // %1 = fir.array_coor %0 %idx
+ // Pull in as:
+ // %shape = fir.shape <extents from the %shapeshift>
+ // %1 = fir.array_coor %arg(%shape) %idx
+ boxedShape = getShapeFromShapeShift(boxedShape, rewriter);
+ if (!boxedShape)
+ return mlir::failure();
+ } else {
+ return mlir::failure();
+ }
+ } else {
+ if (boxedShapeIsShift) {
+ // %0 = fir.embox %arg(%shift) [%slice]
+ // %1 = fir.array_coor %0 %idx
+ // Pull in as:
+ // %tmp = arith.addi %idx, %shift.origin
+ // %idx_shifted = arith.subi %tmp, 1
+ // %1 = fir.array_coor %arg(%shift) %[slice] %idx_shifted
+ shiftedIndices =
+ getShiftedIndices(boxedShape, op.getIndices(), rewriter);
+ if (!shiftedIndices)
+ return mlir::failure();
+ } else if (boxedShapeIsShape) {
+ // %0 = fir.embox %arg(%shape) [%slice]
+ // %1 = fir.array_coor %0 %idx
+ // Pull in as:
+ // %1 = fir.array_coor %arg(%shape) %[slice] %idx
+ } else if (boxedShapeIsShapeShift) {
+ // %0 = fir.embox %arg(%shapeshift) [%slice]
+ // %1 = fir.array_coor %0 %idx
+ // Pull in as:
+ // %tmp = arith.addi %idx, %shapeshift.lb
+ // %idx_shifted = arith.subi %tmp, 1
+ // %1 = fir.array_coor %arg(%shapeshift) %[slice] %idx_shifted
+ shiftedIndices =
+ getShiftedIndices(boxedShape, op.getIndices(), rewriter);
+ if (!shiftedIndices)
+ return mlir::failure();
+ } else {
+ return mlir::failure();
+ }
+ }
+ }
+ } else { // !boxedShape
+ if (op.getSlice()) {
+ if (!boxedSlice) {
+ // %0 = fir.rebox %arg
+ // %1 = fir.array_coor %0 [%slice] %idx
+ // Pull in as:
+ // %1 = fir.array_coor %arg [%slice] %idx
+ } else {
+ // %0 = fir.rebox %arg [%slice]
+ // %1 = fir.array_coor %0 [%slice] %idx
+ // This is a valid FIR iff the slice's lower bounds
+ // and strides are all 1s.
+ // Pull in as:
+ // %1 = fir.array_coor %arg [%slice] %idx
+ }
+ } else { // !op.getSlice()
+ if (!boxedSlice) {
+ // %0 = fir.rebox %arg
+ // %1 = fir.array_coor %0 %idx
+ // Pull in as:
+ // %1 = fir.array_coor %arg %idx
+ } else {
+ // %0 = fir.rebox %arg [%slice]
+ // %1 = fir.array_coor %0 %idx
+ // Pull in as:
+ // %1 = fir.array_coor %arg [%slice] %idx
+ }
+ }
+ }
+ } else { // op.getShape()
+ if (boxedShape) {
+ // Check if pulling in non-default shape is correct.
+ if (op.getSlice()) {
+ if (!boxedSlice) {
+ // %0 = fir.embox %arg(%shape)
+ // %1 = fir.array_coor %0(%shape) [%slice] %idx
+ // Pull in as:
+ // %1 = fir.array_coor %arg(%shape) [%slice] %idx
+ } else {
+ // %0 = fir.embox %arg(%shape) [%slice]
+ // %1 = fir.array_coor %0(%shape) [%slice] %idx
+ // Pull in as:
+ // %1 = fir.array_coor %arg(%shape) [%slice] %idx
+ }
+ } else { // !op.getSlice()
+ if (!boxedSlice) {
+ // %0 = fir.embox %arg(%shape)
+ // %1 = fir.array_coor %0(%shape) %idx
+ // Pull in as:
+ // %1 = fir.array_coor %arg(%shape) %idx
+ } else {
+ // %0 = fir.embox %arg(%shape) [%slice]
+ // %1 = fir.array_coor %0(%shape) %idx
+ // Pull in as:
+ // %1 = fir.array_coor %arg(%shape) [%slice] %idx
+ }
+ }
+ } else { // !boxedShape
+ if (op.getSlice()) {
+ if (!boxedSlice) {
+ // %0 = fir.rebox %arg
+ // %1 = fir.array_coor %0(%shape) [%slice] %idx
+ // Pull in as:
+ // %1 = fir.array_coor %arg(%shape) [%slice] %idx
+ } else {
+ // %0 = fir.rebox %arg [%slice]
+ // %1 = fir.array_coor %0(%shape) [%slice] %idx
+ return mlir::failure();
+ }
+ } else { // !op.getSlice()
+ if (!boxedSlice) {
+ // %0 = fir.rebox %arg
+ // %1 = fir.array_coor %0(%shape) %idx
+ // Pull in as:
+ // %1 = fir.array_coor %arg(%shape) %idx
+ } else {
+ // %0 = fir.rebox %arg [%slice]
+ // %1 = fir.array_coor %0(%shape) %idx
+ // Cannot pull in without adjusting the slice indices.
+ return mlir::failure();
+ }
+ }
+ }
+ }
+
+ // TODO: temporarily avoid producing array_coor with the shape shift
+ // and plain array reference (it seems to be a limitation of
+ // ArrayCoorOp verifier).
+ if (!mlir::isa<fir::BaseBoxType>(boxedMemref.getType())) {
+ if (boxedShape) {
+ if (mlir::isa<fir::ShiftType>(boxedShape.getType()))
+ return mlir::failure();
+ } else if (op.getShape() &&
+ mlir::isa<fir::ShiftType>(op.getShape().getType())) {
+ return mlir::failure();
+ }
+ }
+
+ rewriter.modifyOpInPlace(op, [&]() {
+ op.getMemrefMutable().assign(boxedMemref);
+ if (boxedShape)
+ op.getShapeMutable().assign(boxedShape);
+ if (boxedSlice)
+ op.getSliceMutable().assign(boxedSlice);
+ if (shiftedIndices)
+ op.getIndicesMutable().assign(*shiftedIndices);
+ });
+ return mlir::success();
+ }
+
+private:
+ using IndicesVectorTy = std::vector<mlir::Value>;
+
+ // If v is a shape_shift operation:
+ // fir.shape_shift %l1, %e1, %l2, %e2, ...
+ // create:
+ // fir.shape %e1, %e2, ...
+ static mlir::Value getShapeFromShapeShift(mlir::Value v,
+ mlir::PatternRewriter &rewriter) {
+ auto shapeShiftOp =
+ mlir::dyn_cast_or_null<fir::ShapeShiftOp>(v.getDefiningOp());
+ if (!shapeShiftOp)
+ return nullptr;
+ mlir::OpBuilder::InsertionGuard guard(rewriter);
+ rewriter.setInsertionPoint(shapeShiftOp);
+ return rewriter.create<fir::ShapeOp>(shapeShiftOp.getLoc(),
+ shapeShiftOp.getExtents());
+ }
+
+ static std::optional<IndicesVectorTy>
+ getShiftedIndices(mlir::Value v, mlir::ValueRange indices,
+ mlir::PatternRewriter &rewriter) {
+ auto insertAdjustments = [&](mlir::Operation *op, mlir::ValueRange lbs) {
+ // Compute the shifted indices using the extended type.
+ // Note that this can probably result in less efficient
+ // MLIR and further LLVM IR due to the extra conversions.
+ mlir::OpBuilder::InsertPoint savedIP = rewriter.saveInsertionPoint();
+ rewriter.setInsertionPoint(op);
+ mlir::Location loc = op->getLoc();
+ mlir::Type idxTy = rewriter.getIndexType();
+ mlir::Value one = rewriter.create<mlir::arith::ConstantOp>(
+ loc, idxTy, rewriter.getIndexAttr(1));
+ rewriter.restoreInsertionPoint(savedIP);
+ auto nsw = mlir::arith::IntegerOverflowFlags::nsw;
+
+ IndicesVectorTy shiftedIndices;
+ for (auto [lb, idx] : llvm::zip(lbs, indices)) {
+ mlir::Value extLb = rewriter.create<fir::ConvertOp>(loc, idxTy, lb);
+ mlir::Value extIdx = rewriter.create<fir::ConvertOp>(loc, idxTy, idx);
+ mlir::Value add =
+ rewriter.create<mlir::arith::AddIOp>(loc, extIdx, extLb, nsw);
+ mlir::Value sub =
+ rewriter.create<mlir::arith::SubIOp>(loc, add, one, nsw);
+ shiftedIndices.push_back(sub);
+ }
+
+ return std::move(shiftedIndices);
+ };
+
+ if (auto shiftOp =
+ mlir::dyn_cast_or_null<fir::ShiftOp>(v.getDefiningOp())) {
+ return insertAdjustments(shiftOp.getOperation(), shiftOp.getOrigins());
+ } else if (auto shapeShiftOp = mlir::dyn_cast_or_null<fir::ShapeShiftOp>(
+ v.getDefiningOp())) {
+ return insertAdjustments(shapeShiftOp.getOperation(),
+ shapeShiftOp.getOrigins());
+ }
+
+ return std::nullopt;
+ }
+};
+
+void fir::ArrayCoorOp::getCanonicalizationPatterns(
+ mlir::RewritePatternSet &patterns, mlir::MLIRContext *context) {
+ // TODO: !fir.shape<1> operand may be removed from array_coor always.
+ patterns.add<SimplifyArrayCoorOp>(context);
+}
+
//===----------------------------------------------------------------------===//
// ArrayLoadOp
//===----------------------------------------------------------------------===//
diff --git a/flang/test/Fir/array-coor-canonicalization.fir b/flang/test/Fir/array-coor-canonicalization.fir
new file mode 100644
index 0000000..bc58347
--- /dev/null
+++ b/flang/test/Fir/array-coor-canonicalization.fir
@@ -0,0 +1,592 @@
+// RUN: fir-opt --canonicalize %s | FileCheck %s
+
+// CHECK-LABEL: func.func @_QPtest1(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<120x2xi32>> {fir.bindc_name = "u"}) {
+// CHECK: %[[VAL_6:.*]] = fir.shape
+// CHECK: %[[VAL_7:.*]] = fir.declare %[[VAL_0]](%[[VAL_6]])
+// CHECK: %[[VAL_8:.*]] = fir.slice
+// CHECK: fir.do_loop
+// CHECK: fir.do_loop
+// CHECK: %[[VAL_11:.*]] = fir.array_coor %[[VAL_7]](%[[VAL_6]]) {{\[}}%[[VAL_8]]]
+func.func @_QPtest1(%arg0: !fir.ref<!fir.array<120x2xi32>> {fir.bindc_name = "u"}) {
+ %c1 = arith.constant 1 : index
+ %c2_i32 = arith.constant 2 : i32
+ %c2 = arith.constant 2 : index
+ %c120 = arith.constant 120 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.shape %c120, %c2 : (index, index) -> !fir.shape<2>
+ %2 = fir.declare %arg0(%1) dummy_scope %0 {uniq_name = "_QFtest1Eu"} : (!fir.ref<!fir.array<120x2xi32>>, !fir.shape<2>, !fir.dscope) -> !fir.ref<!fir.array<120x2xi32>>
+ %3 = fir.slice %c1, %c120, %c1, %c1, %c2, %c1 : (index, index, index, index, index, index) -> !fir.slice<2>
+ %4 = fir.embox %2(%1) [%3] : (!fir.ref<!fir.array<120x2xi32>>, !fir.shape<2>, !fir.slice<2>) -> !fir.box<!fir.array<120x2xi32>>
+ fir.do_loop %arg1 = %c1 to %c2 step %c1 unordered {
+ fir.do_loop %arg2 = %c1 to %c120 step %c1 unordered {
+ %5 = fir.array_coor %4 %arg2, %arg1 : (!fir.box<!fir.array<120x2xi32>>, index, index) -> !fir.ref<i32>
+ fir.store %c2_i32 to %5 : !fir.ref<i32>
+ }
+ }
+ return
+}
+
+// CHECK-LABEL: func.func @_QPtest2(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x?xi32>> {fir.bindc_name = "u"}) {
+// CHECK: %[[VAL_8:.*]] = fir.shift
+// CHECK: %[[VAL_9:.*]] = fir.declare %[[VAL_0]](%[[VAL_8]])
+// CHECK: fir.do_loop
+// CHECK: fir.do_loop
+// CHECK: %[[VAL_17:.*]] = fir.array_coor %[[VAL_9]](%[[VAL_8]])
+func.func @_QPtest2(%arg0: !fir.box<!fir.array<?x?xi32>> {fir.bindc_name = "u"}) {
+ %c9 = arith.constant 9 : index
+ %c1 = arith.constant 1 : index
+ %c0 = arith.constant 0 : index
+ %c11 = arith.constant 11 : index
+ %c10 = arith.constant 10 : index
+ %c2_i32 = arith.constant 2 : i32
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.shift %c10, %c11 : (index, index) -> !fir.shift<2>
+ %2 = fir.declare %arg0(%1) dummy_scope %0 {uniq_name = "_QFtest2Eu"} : (!fir.box<!fir.array<?x?xi32>>, !fir.shift<2>, !fir.dscope) -> !fir.box<!fir.array<?x?xi32>>
+ %3 = fir.rebox %2(%1) : (!fir.box<!fir.array<?x?xi32>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?xi32>>
+ %4:3 = fir.box_dims %3, %c0 : (!fir.box<!fir.array<?x?xi32>>, index) -> (index, index, index)
+ %5:3 = fir.box_dims %3, %c1 : (!fir.box<!fir.array<?x?xi32>>, index) -> (index, index, index)
+ fir.do_loop %arg1 = %c1 to %5#1 step %c1 unordered {
+ fir.do_loop %arg2 = %c1 to %4#1 step %c1 unordered {
+ %6 = arith.addi %arg2, %c9 : index
+ %7 = arith.addi %arg1, %c10 : index
+ %8 = fir.array_coor %3(%1) %6, %7 : (!fir.box<!fir.array<?x?xi32>>, !fir.shift<2>, index, index) -> !fir.ref<i32>
+ fir.store %c2_i32 to %8 : !fir.ref<i32>
+ }
+ }
+ return
+}
+
+// CHECK-LABEL: func.func @_QPtest3(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x?xi32>> {fir.bindc_name = "u"}) {
+// CHECK: %[[VAL_10:.*]] = fir.shift
+// CHECK: %[[VAL_11:.*]] = fir.declare %[[VAL_0]](%[[VAL_10]])
+// CHECK: %[[VAL_12:.*]] = fir.slice
+// CHECK: fir.do_loop
+// CHECK: fir.do_loop
+// CHECK: %[[VAL_15:.*]] = fir.array_coor %[[VAL_11]](%[[VAL_10]]) {{\[}}%[[VAL_12]]]
+func.func @_QPtest3(%arg0: !fir.box<!fir.array<?x?xi32>> {fir.bindc_name = "u"}) {
+ %c2 = arith.constant 2 : index
+ %c12 = arith.constant 12 : index
+ %c11 = arith.constant 11 : index
+ %c111 = arith.constant 111 : index
+ %c1 = arith.constant 1 : index
+ %c120 = arith.constant 120 : index
+ %c10 = arith.constant 10 : index
+ %c2_i32 = arith.constant 2 : i32
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.shift %c10, %c11 : (index, index) -> !fir.shift<2>
+ %2 = fir.declare %arg0(%1) dummy_scope %0 {uniq_name = "_QFtest3Eu"} : (!fir.box<!fir.array<?x?xi32>>, !fir.shift<2>, !fir.dscope) -> !fir.box<!fir.array<?x?xi32>>
+ %3 = fir.rebox %2(%1) : (!fir.box<!fir.array<?x?xi32>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?xi32>>
+ %4 = fir.slice %c10, %c120, %c1, %c11, %c12, %c1 : (index, index, index, index, index, index) -> !fir.slice<2>
+ %5 = fir.rebox %3(%1) [%4] : (!fir.box<!fir.array<?x?xi32>>, !fir.shift<2>, !fir.slice<2>) -> !fir.box<!fir.array<111x2xi32>>
+ fir.do_loop %arg1 = %c1 to %c2 step %c1 unordered {
+ fir.do_loop %arg2 = %c1 to %c111 step %c1 unordered {
+ %6 = fir.array_coor %5 %arg2, %arg1 : (!fir.box<!fir.array<111x2xi32>>, index, index) -> !fir.ref<i32>
+ fir.store %c2_i32 to %6 : !fir.ref<i32>
+ }
+ }
+ return
+}
+
+// TODO: fir.array_coor with slices changing the number of dimensions
+// is not supported yet.
+// CHECK-LABEL: func.func @_QPtest4() {
+// CHECK: %[[VAL_3:.*]] = fir.alloca !fir.array<100x100x100xi32> {bindc_name = "u", uniq_name = "_QFtest4Eu"}
+// CHECK: %[[VAL_4:.*]] = fir.shape
+// CHECK: %[[VAL_5:.*]] = fir.declare %[[VAL_3]](%[[VAL_4]]) {uniq_name = "_QFtest4Eu"} : (!fir.ref<!fir.array<100x100x100xi32>>, !fir.shape<3>) -> !fir.ref<!fir.array<100x100x100xi32>>
+// CHECK: %[[VAL_7:.*]] = fir.slice
+// CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_5]](%[[VAL_4]]) {{\[}}%[[VAL_7]]] : (!fir.ref<!fir.array<100x100x100xi32>>, !fir.shape<3>, !fir.slice<3>) -> !fir.box<!fir.array<100x100xi32>>
+// CHECK: fir.do_loop
+// CHECK: fir.do_loop
+// CHECK: %[[VAL_11:.*]] = fir.array_coor %[[VAL_8]]
+func.func @_QPtest4() {
+ %c1 = arith.constant 1 : index
+ %c2_i32 = arith.constant 2 : i32
+ %c100 = arith.constant 100 : index
+ %0 = fir.alloca !fir.array<100x100x100xi32> {bindc_name = "u", uniq_name = "_QFtest4Eu"}
+ %1 = fir.shape %c100, %c100, %c100 : (index, index, index) -> !fir.shape<3>
+ %2 = fir.declare %0(%1) {uniq_name = "_QFtest4Eu"} : (!fir.ref<!fir.array<100x100x100xi32>>, !fir.shape<3>) -> !fir.ref<!fir.array<100x100x100xi32>>
+ %3 = fir.undefined index
+ %4 = fir.slice %c1, %c100, %c1, %c1, %3, %3, %c1, %c100, %c1 : (index, index, index, index, index, index, index, index, index) -> !fir.slice<3>
+ %5 = fir.embox %2(%1) [%4] : (!fir.ref<!fir.array<100x100x100xi32>>, !fir.shape<3>, !fir.slice<3>) -> !fir.box<!fir.array<100x100xi32>>
+ fir.do_loop %arg0 = %c1 to %c100 step %c1 unordered {
+ fir.do_loop %arg1 = %c1 to %c100 step %c1 unordered {
+ %6 = fir.array_coor %5 %arg1, %arg0 : (!fir.box<!fir.array<100x100xi32>>, index, index) -> !fir.ref<i32>
+ fir.store %c2_i32 to %6 : !fir.ref<i32>
+ }
+ }
+ return
+}
+
+// CHECK-LABEL: func.func @test5_1(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 9 : index
+// CHECK: %[[VAL_3:.*]] = fir.slice %[[VAL_1]], %[[VAL_2]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_4:.*]] = fir.array_coor %[[VAL_0]] {{\[}}%[[VAL_3]]] %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_4]] : !fir.ref<i32>
+// CHECK: }
+func.func @test5_1(%arg0: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c9 = arith.constant 9 : index
+ %sh = fir.shift %c10 : (index) -> !fir.shift<1>
+ %2 = fir.rebox %arg0(%sh) : (!fir.box<!fir.array<?xi32>>, !fir.shift<1>) -> !fir.box<!fir.array<?xi32>>
+ %s = fir.slice %c1, %c9, %c1 : (index, index, index) -> !fir.slice<1>
+ %3 = fir.array_coor %2 [%s] %c1 : (!fir.box<!fir.array<?xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test5_2(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_4:.*]] = fir.slice %[[VAL_1]], %[[VAL_2]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_5:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_3]]) {{\[}}%[[VAL_4]]] %[[VAL_1]] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_5]] : !fir.ref<i32>
+// CHECK: }
+func.func @test5_2(%arg0: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %1 = fir.shape %c10 : (index) -> !fir.shape<1>
+ %s = fir.slice %c1, %c10, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.embox %arg0(%1) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<10xi32>>
+ %3 = fir.array_coor %2 [%s] %c1 : (!fir.box<!fir.array<10xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test5_3(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_4:.*]] = fir.slice %[[VAL_1]], %[[VAL_2]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_5:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_3]]) {{\[}}%[[VAL_4]]] %[[VAL_1]] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_5]] : !fir.ref<i32>
+// CHECK: }
+func.func @test5_3(%arg0: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %1 = fir.shape_shift %c10, %c10 : (index, index) -> !fir.shapeshift<1>
+ %s = fir.slice %c1, %c10, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.embox %arg0(%1) : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<10xi32>>
+ %3 = fir.array_coor %2 [%s] %c1 : (!fir.box<!fir.array<10xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test6_1(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 9 : index
+// CHECK: %[[VAL_3:.*]] = fir.shift %[[VAL_1]] : (index) -> !fir.shift<1>
+// CHECK: %[[VAL_4:.*]] = fir.slice %[[VAL_1]], %[[VAL_2]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_5:.*]] = fir.rebox %[[VAL_0]](%[[VAL_3]]) {{\[}}%[[VAL_4]]] : (!fir.box<!fir.array<?xi32>>, !fir.shift<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xi32>>
+// CHECK: %[[VAL_6:.*]] = fir.array_coor %[[VAL_5]] {{\[}}%[[VAL_4]]] %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_6]] : !fir.ref<i32>
+// CHECK: }
+func.func @test6_1(%arg0: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c9 = arith.constant 9 : index
+ %sh = fir.shift %c1 : (index) -> !fir.shift<1>
+ %s = fir.slice %c1, %c9, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.rebox %arg0(%sh) [%s] : (!fir.box<!fir.array<?xi32>>, !fir.shift<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xi32>>
+ %3 = fir.array_coor %2 [%s] %c1 : (!fir.box<!fir.array<?xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test6_2(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant 19 : index
+// CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_5:.*]] = fir.slice %[[VAL_2]], %[[VAL_3]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_0]](%[[VAL_4]]) {{\[}}%[[VAL_5]]] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<10xi32>>
+// CHECK: %[[VAL_7:.*]] = fir.array_coor %[[VAL_6]] {{\[}}%[[VAL_5]]] %[[VAL_1]] : (!fir.box<!fir.array<10xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_7]] : !fir.ref<i32>
+// CHECK: }
+func.func @test6_2(%arg0: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c19 = arith.constant 19 : index
+ %1 = fir.shape %c10 : (index) -> !fir.shape<1>
+ %s = fir.slice %c10, %c19, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.embox %arg0(%1) [%s] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<10xi32>>
+ %3 = fir.array_coor %2 [%s] %c1 : (!fir.box<!fir.array<10xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test6_3(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant 19 : index
+// CHECK: %[[VAL_4:.*]] = fir.shape_shift %[[VAL_2]], %[[VAL_2]] : (index, index) -> !fir.shapeshift<1>
+// CHECK: %[[VAL_5:.*]] = fir.slice %[[VAL_2]], %[[VAL_3]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_0]](%[[VAL_4]]) {{\[}}%[[VAL_5]]] : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box<!fir.array<10xi32>>
+// CHECK: %[[VAL_7:.*]] = fir.array_coor %[[VAL_6]] {{\[}}%[[VAL_5]]] %[[VAL_1]] : (!fir.box<!fir.array<10xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_7]] : !fir.ref<i32>
+// CHECK: }
+func.func @test6_3(%arg0: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c19 = arith.constant 19 : index
+ %1 = fir.shape_shift %c10, %c10 : (index, index) -> !fir.shapeshift<1>
+ %s = fir.slice %c10, %c19, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.embox %arg0(%1) [%s] : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box<!fir.array<10xi32>>
+ %3 = fir.array_coor %2 [%s] %c1 : (!fir.box<!fir.array<10xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test7_1(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = fir.array_coor %[[VAL_0]] %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_2]] : !fir.ref<i32>
+// CHECK: }
+func.func @test7_1(%arg0: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c9 = arith.constant 9 : index
+ %sh = fir.shift %c10 : (index) -> !fir.shift<1>
+ %2 = fir.rebox %arg0(%sh) : (!fir.box<!fir.array<?xi32>>, !fir.shift<1>) -> !fir.box<!fir.array<?xi32>>
+ %3 = fir.array_coor %2 %c1 : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test7_2(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_4:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_3]]) %[[VAL_1]] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_4]] : !fir.ref<i32>
+// CHECK: }
+func.func @test7_2(%arg0: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %1 = fir.shape %c10 : (index) -> !fir.shape<1>
+ %2 = fir.embox %arg0(%1) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<10xi32>>
+ %3 = fir.array_coor %2 %c1 : (!fir.box<!fir.array<10xi32>>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test7_3(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_4:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_3]]) %[[VAL_1]] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_4]] : !fir.ref<i32>
+// CHECK: }
+func.func @test7_3(%arg0: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %1 = fir.shape_shift %c10, %c10 : (index, index) -> !fir.shapeshift<1>
+ %2 = fir.embox %arg0(%1) : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<10xi32>>
+ %3 = fir.array_coor %2 %c1 : (!fir.box<!fir.array<10xi32>>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test8_1(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>,
+// CHECK-SAME: %[[VAL_1:.*]]: index,
+// CHECK-SAME: %[[VAL_2:.*]]: index) -> !fir.ref<i32> {
+// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant 19 : index
+// CHECK: %[[VAL_6:.*]] = fir.shift %[[VAL_1]] : (index) -> !fir.shift<1>
+// CHECK: %[[VAL_7:.*]] = fir.slice %[[VAL_4]], %[[VAL_5]], %[[VAL_3]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_8:.*]] = arith.addi %[[VAL_2]], %[[VAL_1]] overflow<nsw> : index
+// CHECK: %[[VAL_9:.*]] = arith.subi %[[VAL_8]], %[[VAL_3]] overflow<nsw> : index
+// CHECK: %[[VAL_10:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_6]]) {{\[}}%[[VAL_7]]] %[[VAL_9]] : (!fir.box<!fir.array<?xi32>>, !fir.shift<1>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_10]] : !fir.ref<i32>
+// CHECK: }
+func.func @test8_1(%arg0: !fir.box<!fir.array<?xi32>>, %lb: index, %idx: index) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c19 = arith.constant 19 : index
+ %sh = fir.shift %lb : (index) -> !fir.shift<1>
+ %s = fir.slice %c10, %c19, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.rebox %arg0(%sh) [%s] : (!fir.box<!fir.array<?xi32>>, !fir.shift<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xi32>>
+ %3 = fir.array_coor %2 %idx : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test8_2(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant 9 : index
+// CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_5:.*]] = fir.slice %[[VAL_1]], %[[VAL_3]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_6:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_4]]) {{\[}}%[[VAL_5]]] %[[VAL_1]] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_6]] : !fir.ref<i32>
+// CHECK: }
+func.func @test8_2(%arg0: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c9 = arith.constant 9 : index
+ %1 = fir.shape %c10 : (index) -> !fir.shape<1>
+ %s = fir.slice %c1, %c9, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.embox %arg0(%1) [%s] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<10xi32>>
+ %3 = fir.array_coor %2 %c1 : (!fir.box<!fir.array<10xi32>>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test8_3(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>,
+// CHECK-SAME: %[[VAL_1:.*]]: index,
+// CHECK-SAME: %[[VAL_2:.*]]: index) -> !fir.ref<i32> {
+// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant 19 : index
+// CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_1]], %[[VAL_4]] : (index, index) -> !fir.shapeshift<1>
+// CHECK: %[[VAL_7:.*]] = fir.slice %[[VAL_4]], %[[VAL_5]], %[[VAL_3]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_8:.*]] = arith.addi %[[VAL_2]], %[[VAL_1]] overflow<nsw> : index
+// CHECK: %[[VAL_9:.*]] = arith.subi %[[VAL_8]], %[[VAL_3]] overflow<nsw> : index
+// CHECK: %[[VAL_10:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_6]]) {{\[}}%[[VAL_7]]] %[[VAL_9]] : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_10]] : !fir.ref<i32>
+// CHECK: }
+func.func @test8_3(%arg0: !fir.ref<!fir.array<10xi32>>, %lb: index, %idx: index) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c19 = arith.constant 19 : index
+ %1 = fir.shape_shift %lb, %c10 : (index, index) -> !fir.shapeshift<1>
+ %s = fir.slice %c10, %c19, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.embox %arg0(%1) [%s] : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box<!fir.array<10xi32>>
+ %3 = fir.array_coor %2 %idx : (!fir.box<!fir.array<10xi32>>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test9(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 9 : index
+// CHECK: %[[VAL_3:.*]] = fir.slice %[[VAL_1]], %[[VAL_2]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_4:.*]] = fir.array_coor %[[VAL_0]] {{\[}}%[[VAL_3]]] %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_4]] : !fir.ref<i32>
+// CHECK: }
+func.func @test9(%arg0: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c9 = arith.constant 9 : index
+ %s = fir.slice %c1, %c9, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.rebox %arg0 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
+ %3 = fir.array_coor %2 [%s] %c1 : (!fir.box<!fir.array<?xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test10(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 9 : index
+// CHECK: %[[VAL_3:.*]] = fir.slice %[[VAL_1]], %[[VAL_2]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_4:.*]] = fir.array_coor %[[VAL_0]] {{\[}}%[[VAL_3]]] %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_4]] : !fir.ref<i32>
+// CHECK: }
+func.func @test10(%arg0: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c9 = arith.constant 9 : index
+ %s = fir.slice %c1, %c9, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.rebox %arg0[%s] : (!fir.box<!fir.array<?xi32>>, !fir.slice<1>) -> !fir.box<!fir.array<?xi32>>
+ %3 = fir.array_coor %2 [%s] %c1 : (!fir.box<!fir.array<?xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test11(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = fir.array_coor %[[VAL_0]] %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_2]] : !fir.ref<i32>
+// CHECK: }
+func.func @test11(%arg0: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %2 = fir.rebox %arg0 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
+ %3 = fir.array_coor %2 %c1 : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test12(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 9 : index
+// CHECK: %[[VAL_3:.*]] = fir.slice %[[VAL_1]], %[[VAL_2]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_4:.*]] = fir.array_coor %[[VAL_0]] {{\[}}%[[VAL_3]]] %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_4]] : !fir.ref<i32>
+// CHECK: }
+func.func @test12(%arg0: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c9 = arith.constant 9 : index
+ %s = fir.slice %c1, %c9, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.rebox %arg0[%s] : (!fir.box<!fir.array<?xi32>>, !fir.slice<1>) -> !fir.box<!fir.array<?xi32>>
+ %3 = fir.array_coor %2 %c1 : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test13(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant 19 : index
+// CHECK: %[[VAL_4:.*]] = fir.shape_shift %[[VAL_2]], %[[VAL_2]] : (index, index) -> !fir.shapeshift<1>
+// CHECK: %[[VAL_5:.*]] = fir.slice %[[VAL_2]], %[[VAL_3]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_6:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_4]]) {{\[}}%[[VAL_5]]] %[[VAL_1]] : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_6]] : !fir.ref<i32>
+// CHECK: }
+func.func @test13(%arg0: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c19 = arith.constant 19 : index
+ %1 = fir.shape_shift %c10, %c10 : (index, index) -> !fir.shapeshift<1>
+ %s = fir.slice %c10, %c19, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.embox %arg0(%1) : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<10xi32>>
+ %3 = fir.array_coor %2(%1) [%s] %c1 : (!fir.box<!fir.array<10xi32>>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test14(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant 19 : index
+// CHECK: %[[VAL_4:.*]] = fir.shape_shift %[[VAL_2]], %[[VAL_2]] : (index, index) -> !fir.shapeshift<1>
+// CHECK: %[[VAL_5:.*]] = fir.slice %[[VAL_2]], %[[VAL_3]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_6:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_4]]) {{\[}}%[[VAL_5]]] %[[VAL_1]] : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_6]] : !fir.ref<i32>
+// CHECK: }
+func.func @test14(%arg0: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c19 = arith.constant 19 : index
+ %1 = fir.shape_shift %c10, %c10 : (index, index) -> !fir.shapeshift<1>
+ %s = fir.slice %c10, %c19, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.embox %arg0(%1) [%s] : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box<!fir.array<10xi32>>
+ %3 = fir.array_coor %2(%1) [%s] %c1 : (!fir.box<!fir.array<10xi32>>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test15(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_2:.*]] = fir.shape_shift %[[VAL_1]], %[[VAL_1]] : (index, index) -> !fir.shapeshift<1>
+// CHECK: %[[VAL_3:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_2]]) %[[VAL_1]] : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_3]] : !fir.ref<i32>
+// CHECK: }
+func.func @test15(%arg0: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+ %c10 = arith.constant 10 : index
+ %1 = fir.shape_shift %c10, %c10 : (index, index) -> !fir.shapeshift<1>
+ %2 = fir.embox %arg0(%1) : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<10xi32>>
+ %3 = fir.array_coor %2(%1) %c10 : (!fir.box<!fir.array<10xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test16(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant 19 : index
+// CHECK: %[[VAL_4:.*]] = fir.shape_shift %[[VAL_2]], %[[VAL_2]] : (index, index) -> !fir.shapeshift<1>
+// CHECK: %[[VAL_5:.*]] = fir.slice %[[VAL_2]], %[[VAL_3]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_6:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_4]]) {{\[}}%[[VAL_5]]] %[[VAL_2]] : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_6]] : !fir.ref<i32>
+// CHECK: }
+func.func @test16(%arg0: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c19 = arith.constant 19 : index
+ %1 = fir.shape_shift %c10, %c10 : (index, index) -> !fir.shapeshift<1>
+ %s = fir.slice %c10, %c19, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.embox %arg0(%1) [%s] : (!fir.ref<!fir.array<10xi32>>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box<!fir.array<10xi32>>
+ %3 = fir.array_coor %2(%1) %c10 : (!fir.box<!fir.array<10xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test17(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant 19 : index
+// CHECK: %[[VAL_4:.*]] = fir.shape_shift %[[VAL_2]], %[[VAL_2]] : (index, index) -> !fir.shapeshift<1>
+// CHECK: %[[VAL_5:.*]] = fir.slice %[[VAL_2]], %[[VAL_3]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_6:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_4]]) {{\[}}%[[VAL_5]]] %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_6]] : !fir.ref<i32>
+// CHECK: }
+func.func @test17(%arg0: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c19 = arith.constant 19 : index
+ %1 = fir.shape_shift %c10, %c10 : (index, index) -> !fir.shapeshift<1>
+ %s = fir.slice %c10, %c19, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.rebox %arg0 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
+ %3 = fir.array_coor %2(%1) [%s] %c1 : (!fir.box<!fir.array<?xi32>>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test18(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant 9 : index
+// CHECK: %[[VAL_4:.*]] = fir.shape_shift %[[VAL_1]], %[[VAL_2]] : (index, index) -> !fir.shapeshift<1>
+// CHECK: %[[VAL_5:.*]] = fir.slice %[[VAL_1]], %[[VAL_3]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_0]] {{\[}}%[[VAL_5]]] : (!fir.ref<!fir.array<10xi32>>, !fir.slice<1>) -> !fir.box<!fir.array<10xi32>>
+// CHECK: %[[VAL_7:.*]] = fir.array_coor %[[VAL_6]](%[[VAL_4]]) {{\[}}%[[VAL_5]]] %[[VAL_1]] : (!fir.box<!fir.array<10xi32>>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_7]] : !fir.ref<i32>
+// CHECK: }
+func.func @test18(%arg0: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c9 = arith.constant 9 : index
+ %1 = fir.shape_shift %c1, %c10 : (index, index) -> !fir.shapeshift<1>
+ %s = fir.slice %c1, %c9, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.embox %arg0 [%s] : (!fir.ref<!fir.array<10xi32>>, !fir.slice<1>) -> !fir.box<!fir.array<10xi32>>
+ %3 = fir.array_coor %2(%1) [%s] %c1 : (!fir.box<!fir.array<10xi32>>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test19(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_2:.*]] = fir.shape_shift %[[VAL_1]], %[[VAL_1]] : (index, index) -> !fir.shapeshift<1>
+// CHECK: %[[VAL_3:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_2]]) %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_3]] : !fir.ref<i32>
+// CHECK: }
+func.func @test19(%arg0: !fir.box<!fir.array<?xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c19 = arith.constant 19 : index
+ %1 = fir.shape_shift %c10, %c10 : (index, index) -> !fir.shapeshift<1>
+ %s = fir.slice %c10, %c19, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.rebox %arg0 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>
+ %3 = fir.array_coor %2(%1) %c10 : (!fir.box<!fir.array<?xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}
+
+// CHECK-LABEL: func.func @test20(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant 9 : index
+// CHECK: %[[VAL_4:.*]] = fir.shape_shift %[[VAL_2]], %[[VAL_2]] : (index, index) -> !fir.shapeshift<1>
+// CHECK: %[[VAL_5:.*]] = fir.slice %[[VAL_1]], %[[VAL_3]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1>
+// CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_0]] {{\[}}%[[VAL_5]]] : (!fir.ref<!fir.array<10xi32>>, !fir.slice<1>) -> !fir.box<!fir.array<10xi32>>
+// CHECK: %[[VAL_7:.*]] = fir.array_coor %[[VAL_6]](%[[VAL_4]]) %[[VAL_2]] : (!fir.box<!fir.array<10xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+// CHECK: return %[[VAL_7]] : !fir.ref<i32>
+// CHECK: }
+func.func @test20(%arg0: !fir.ref<!fir.array<10xi32>>) -> !fir.ref<i32> {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %c9 = arith.constant 9 : index
+ %1 = fir.shape_shift %c10, %c10 : (index, index) -> !fir.shapeshift<1>
+ %s = fir.slice %c1, %c9, %c1 : (index, index, index) -> !fir.slice<1>
+ %2 = fir.embox %arg0 [%s] : (!fir.ref<!fir.array<10xi32>>, !fir.slice<1>) -> !fir.box<!fir.array<10xi32>>
+ %3 = fir.array_coor %2(%1) %c10 : (!fir.box<!fir.array<10xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+ return %3 : !fir.ref<i32>
+}