[flang-commits] [flang] e1dd984 - [flang][FIRToMemRef] fix stride calculation for complex lowering (#200035)

via flang-commits flang-commits at lists.llvm.org
Wed May 27 14:48:06 PDT 2026


Author: Susan Tan (ス-ザン タン)
Date: 2026-05-27T17:48:01-04:00
New Revision: e1dd984a809c9c7b8cc3731e3b8eeb8d01fbc8c1

URL: https://github.com/llvm/llvm-project/commit/e1dd984a809c9c7b8cc3731e3b8eeb8d01fbc8c1
DIFF: https://github.com/llvm/llvm-project/commit/e1dd984a809c9c7b8cc3731e3b8eeb8d01fbc8c1.diff

LOG: [flang][FIRToMemRef] fix stride calculation for complex lowering (#200035)

**Summary**
When `fir.array_coor` targets a projected slice of a complex array (path
0 = real, 1 = imag), FIRToMemRef must not treat the result as a dense
memref.

**Bug:** The pass stopped after fir.convert to `memref<…×complex>` (or
static-shape fast path) and used default/dense strides. Loads/stores
then stepped by sizeof(complex) instead of sizeof(re)/sizeof(im).

**Fix:** For constant `%re/%im` on `complex<T>` storage:

`fir.convert` storage to `memref<…×2×T>` and index the component (0 or
1).
Read layout from `fir.box_dims` on the box (even if the memref shape is
static).
Set each memref stride to `box_dims_byte_stride / sizeof(T)`.

Advised by Cursor

Added: 
    

Modified: 
    flang/lib/Optimizer/Transforms/FIRToMemRef.cpp
    flang/test/Transforms/FIRToMemRef/slice-projected.mlir

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp b/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp
index f679f01bc3241..26289c388fd3e 100644
--- a/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp
+++ b/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp
@@ -655,7 +655,6 @@ FIRToMemRef::convertArrayCoorOp(Operation *memOp, fir::ArrayCoorOp arrayCoorOp,
   Value convertedVal = *converted;
   MemRefType memRefTy = dyn_cast<MemRefType>(convertedVal.getType());
 
-  bool isRebox = firMemref.getDefiningOp<fir::ReboxOp>() != nullptr;
   bool isDescriptor = mlir::isa<fir::BaseBoxType>(firMemref.getType()) ||
                       firMemref.getDefiningOp<fir::BoxAddrOp>() != nullptr;
 
@@ -669,6 +668,7 @@ FIRToMemRef::convertArrayCoorOp(Operation *memOp, fir::ArrayCoorOp arrayCoorOp,
   else if (auto rebox = firMemref.getDefiningOp<fir::ReboxOp>())
     collectSliceInfoFrom(rebox, sliceInfo);
   auto srcTy = cast<MemRefType>((*converted).getType());
+  std::optional<int64_t> complexPartIdx;
   if (sliceInfo.hasProjectedSlice) {
     if (auto complexTy = dyn_cast<mlir::ComplexType>(srcTy.getElementType())) {
       if (!sliceInfo.projectedSliceStart ||
@@ -680,24 +680,25 @@ FIRToMemRef::convertArrayCoorOp(Operation *memOp, fir::ArrayCoorOp arrayCoorOp,
                "0 (real) or 1 (imaginary), bailing out of conversion\n");
         return failure();
       }
-      auto projection = *sliceInfo.projectedSliceStart;
+      complexPartIdx = *sliceInfo.projectedSliceStart;
       SmallVector<int64_t> shape(srcTy.getShape());
       shape.push_back(2);
-      Value compMemref =
+      convertedVal =
           fir::ConvertOp::create(
               rewriter, loc, MemRefType::get(shape, complexTy.getElementType()),
               *converted)
               .getResult();
+      memRefTy = cast<MemRefType>(convertedVal.getType());
       indices.push_back(
-          arith::ConstantIndexOp::create(rewriter, loc, projection));
-      return std::pair{compMemref, indices};
+          arith::ConstantIndexOp::create(rewriter, loc, *complexPartIdx));
     }
   }
 
   // Static shape does not imply contiguous layout for descriptor-backed
-  // entities (e.g. boxed array sections with non-unit stride). Keep the
-  // reinterpret-cast path so descriptor strides are preserved.
-  if (memRefTy.hasStaticShape() && !isRebox && !isDescriptor)
+  // entities (e.g. boxed array sections with non-unit stride). Projected
+  // complex %re/%im also need reinterpret_cast even when the converted type
+  // is statically shaped (e.g. memref<Nx2xT>).
+  if (!complexPartIdx && memRefTy.hasStaticShape() && !isDescriptor)
     return std::pair{*converted, indices};
 
   unsigned rank = arrayCoorOp.getIndices().size();
@@ -736,11 +737,14 @@ FIRToMemRef::convertArrayCoorOp(Operation *memOp, fir::ArrayCoorOp arrayCoorOp,
                                     shapeVec.empty() ||
                                     (firMemrefIsBox && !firMemrefIsEmbox);
   if (descriptorOwnsLayout) {
-    // Rebuild the MemRef view from descriptor metadata instead of from slice
-    // triplets. Reached only when firMemref is a fir.box value (case b/c), or
-    // for projected slices (case a) where the source remains the box.
-    auto boxElementSize =
-        fir::BoxEleSizeOp::create(rewriter, loc, indexTy, firMemref);
+    // Complex %re/%im: memref_stride = box_dims_byte_stride / sizeof(T),
+    Value boxElementSize =
+        complexPartIdx
+            ? arith::ConstantIndexOp::create(
+                  rewriter, loc,
+                  memRefTy.getElementType().getIntOrFloatBitWidth() / 8)
+            : fir::BoxEleSizeOp::create(rewriter, loc, indexTy, firMemref)
+                  .getResult();
 
     for (unsigned i = 0; i < rank; ++i) {
       Value dim = arith::ConstantIndexOp::create(rewriter, loc, rank - i - 1);
@@ -779,7 +783,11 @@ FIRToMemRef::convertArrayCoorOp(Operation *memOp, fir::ArrayCoorOp arrayCoorOp,
     strides.push_back(oneIdx);
   }
 
-  assert(strides.size() == sizes.size() && sizes.size() == rank);
+  if (complexPartIdx) {
+    sizes.push_back(arith::ConstantIndexOp::create(rewriter, loc, 2));
+    strides.push_back(arith::ConstantIndexOp::create(rewriter, loc, 1));
+    ++rank;
+  }
 
   int64_t dynamicOffset = ShapedType::kDynamic;
   SmallVector<int64_t> dynamicStrides(rank, ShapedType::kDynamic);
@@ -793,7 +801,7 @@ FIRToMemRef::convertArrayCoorOp(Operation *memOp, fir::ArrayCoorOp arrayCoorOp,
   Value offset = arith::ConstantIndexOp::create(rewriter, loc, 0);
 
   auto reinterpret = memref::ReinterpretCastOp::create(
-      rewriter, loc, memRefTy, *converted, offset, sizes, strides);
+      rewriter, loc, memRefTy, convertedVal, offset, sizes, strides);
 
   Value result = reinterpret->getResult(0);
   return std::pair{result, indices};

diff  --git a/flang/test/Transforms/FIRToMemRef/slice-projected.mlir b/flang/test/Transforms/FIRToMemRef/slice-projected.mlir
index 17af59086122c..920b0b2185d45 100644
--- a/flang/test/Transforms/FIRToMemRef/slice-projected.mlir
+++ b/flang/test/Transforms/FIRToMemRef/slice-projected.mlir
@@ -1,10 +1,15 @@
 // RUN: fir-opt %s --fir-to-memref --allow-unregistered-dialect | FileCheck %s
 
 // Tests for fir.slice with a path component (projected component slice).
-// A projected slice changes the element type of the boxed view, e.g.
-// z%re projects complex<f32> -> f32.  The pass bypasses the box descriptor
-// and reinterprets the underlying complex array as memref<...x2xf32>, then
-// appends the component index (0=re, 1=im) as the final memref index.
+// A projected slice changes the logical element type of the boxed view, e.g.
+// z%re maps complex<f32> -> f32 in the box type.
+//
+// FIRToMemRef only lowers array_coor through this path when storage is
+// complex<T> and the slice path is constant 0 (%re) or 1 (%im).  It then
+// fir.convert's storage to memref<...x2xT>, appends that component index,
+// and memref.reinterpret_cast's a strided memref<...xT> using fir.box_dims
+// byte strides divided by sizeof(T) (not sizeof(complex<T>) from box_elesize).
+// Derived-type component projections (e.g. a%x) are left for FIR codegen.
 //
 // Derived from:
 //   complex, target :: z(4) = 0.
@@ -23,9 +28,23 @@
 // CHECK:       fir.do_loop [[I:%.*]] =
 // CHECK:         [[MEMREF:%.*]] = fir.convert %arg0 : (!fir.ref<!fir.array<4xcomplex<f32>>>) -> memref<4xcomplex<f32>>
 // CHECK:         [[IDX:%.*]] = arith.addi
-// CHECK:         [[COMP:%.*]] = fir.convert [[MEMREF]] : (memref<4xcomplex<f32>>) -> memref<4x2xf32>
-// CHECK:         arith.constant 0
-// CHECK:         memref.load [[COMP]][[[IDX]], {{%.*}}] : memref<4x2xf32>
+// CHECK:         [[COMP:%[0-9]+]] = fir.convert [[MEMREF]] : (memref<4xcomplex<f32>>) -> memref<4x2xf32>
+// CHECK:         %[[FWD_C_RE:.*]] = arith.constant 0 : index
+// CHECK:         %[[FWD_C_SZF32:.*]] = arith.constant 4 : index
+// CHECK:         %[[FWD_C_DIM0:.*]] = arith.constant 0 : index
+// CHECK:         [[BD:%[0-9]+]]:3 = fir.box_dims %2, %[[FWD_C_DIM0]] : (!fir.box<!fir.array<4xf32>>, index) -> (index, index, index)
+// CHECK:         [[STRIDE:%[0-9]+]] = arith.divsi [[BD]]#2, %[[FWD_C_SZF32]] : index
+// Reinterpret applies the embox descriptor layout onto the scalar view:
+//   sizes[0]   = box extent (section length in f32 slots)
+//   sizes[1]   = 2 for the (re, im) pair exposed by memref<4x2xf32>
+//   strides[0] = box_dims byte_stride / sizeof(f32) (not box_elesize)
+//   strides[1] = 1 between adjacent real/imag scalars
+// Without this, memref.load would use dense strides from fir.convert only.
+// CHECK:         %[[FWD_C_PAIR:.*]] = arith.constant 2 : index
+// CHECK:         %[[FWD_C_COMP_STRIDE:.*]] = arith.constant 1 : index
+// CHECK:         %[[FWD_C_OFF:.*]] = arith.constant 0 : index
+// CHECK:         [[VIEW:%.*]] = memref.reinterpret_cast [[COMP]] to offset: [%[[FWD_C_OFF]]], sizes: [[[BD]]#1, %[[FWD_C_PAIR]]], strides: [[[STRIDE]], %[[FWD_C_COMP_STRIDE]]] : memref<4x2xf32> to memref<?x?xf32, strided<
+// CHECK:         [[LOAD:%[0-9]+]] = memref.load [[VIEW]][[[IDX]], %[[FWD_C_RE]]] : memref<?x?xf32, strided<
 func.func @projected_slice_fwd(%arg0: !fir.ref<!fir.array<4xcomplex<f32>>>) {
   %c1 = arith.constant 1 : index
   %c4 = arith.constant 4 : index
@@ -48,9 +67,18 @@ func.func @projected_slice_fwd(%arg0: !fir.ref<!fir.array<4xcomplex<f32>>>) {
 // CHECK:       fir.do_loop [[I:%.*]] =
 // CHECK:         [[MEMREF:%.*]] = fir.convert %arg0 : (!fir.ref<!fir.array<4xcomplex<f32>>>) -> memref<4xcomplex<f32>>
 // CHECK:         [[IDX:%.*]] = arith.addi
-// CHECK:         [[COMP:%.*]] = fir.convert [[MEMREF]] : (memref<4xcomplex<f32>>) -> memref<4x2xf32>
-// CHECK:         arith.constant 0
-// CHECK:         memref.load [[COMP]][[[IDX]], {{%.*}}] : memref<4x2xf32>
+// CHECK:         [[COMP:%[0-9]+]] = fir.convert [[MEMREF]] : (memref<4xcomplex<f32>>) -> memref<4x2xf32>
+// CHECK:         %[[BWD_C_RE:.*]] = arith.constant 0 : index
+// CHECK:         %[[BWD_C_SZF32:.*]] = arith.constant 4 : index
+// CHECK:         %[[BWD_C_DIM0:.*]] = arith.constant 0 : index
+// CHECK:         [[BD:%[0-9]+]]:3 = fir.box_dims %2, %[[BWD_C_DIM0]] : (!fir.box<!fir.array<4xf32>>, index) -> (index, index, index)
+// CHECK:         [[STRIDE:%[0-9]+]] = arith.divsi [[BD]]#2, %[[BWD_C_SZF32]] : index
+// Same reinterpret as forward; slice triple only changes [[IDX]], not strides.
+// CHECK:         %[[BWD_C_PAIR:.*]] = arith.constant 2 : index
+// CHECK:         %[[BWD_C_COMP_STRIDE:.*]] = arith.constant 1 : index
+// CHECK:         %[[BWD_C_OFF:.*]] = arith.constant 0 : index
+// CHECK:         [[VIEW:%.*]] = memref.reinterpret_cast [[COMP]] to offset: [%[[BWD_C_OFF]]], sizes: [[[BD]]#1, %[[BWD_C_PAIR]]], strides: [[[STRIDE]], %[[BWD_C_COMP_STRIDE]]] : memref<4x2xf32> to memref<?x?xf32, strided<
+// CHECK:         [[LOAD:%[0-9]+]] = memref.load [[VIEW]][[[IDX]], %[[BWD_C_RE]]] : memref<?x?xf32, strided<
 func.func @projected_slice_bwd(%arg0: !fir.ref<!fir.array<4xcomplex<f32>>>) {
   %c1 = arith.constant 1 : index
   %c4 = arith.constant 4 : index
@@ -74,9 +102,18 @@ func.func @projected_slice_bwd(%arg0: !fir.ref<!fir.array<4xcomplex<f32>>>) {
 // CHECK:       fir.do_loop [[I:%.*]] =
 // CHECK:         [[MEMREF:%.*]] = fir.convert %arg0 : (!fir.ref<!fir.array<4xcomplex<f32>>>) -> memref<4xcomplex<f32>>
 // CHECK:         [[IDX:%.*]] = arith.addi
-// CHECK:         [[COMP:%.*]] = fir.convert [[MEMREF]] : (memref<4xcomplex<f32>>) -> memref<4x2xf32>
-// CHECK:         arith.constant 1
-// CHECK:         memref.store %arg1, [[COMP]][[[IDX]], {{%.*}}] : memref<4x2xf32>
+// CHECK:         [[COMP:%[0-9]+]] = fir.convert [[MEMREF]] : (memref<4xcomplex<f32>>) -> memref<4x2xf32>
+// CHECK:         %[[IM_C_IM:.*]] = arith.constant 1 : index
+// CHECK:         %[[IM_C_SZF32:.*]] = arith.constant 4 : index
+// CHECK:         %[[IM_C_DIM0:.*]] = arith.constant 0 : index
+// CHECK:         [[BD:%[0-9]+]]:3 = fir.box_dims %2, %[[IM_C_DIM0]] : (!fir.box<!fir.array<4xf32>>, index) -> (index, index, index)
+// CHECK:         [[STRIDE:%[0-9]+]] = arith.divsi [[BD]]#2, %[[IM_C_SZF32]] : index
+// Same layout as %re; store uses component index 1 for imaginary.
+// CHECK:         %[[IM_C_PAIR:.*]] = arith.constant 2 : index
+// CHECK:         %[[IM_C_COMP_STRIDE:.*]] = arith.constant 1 : index
+// CHECK:         %[[IM_C_OFF:.*]] = arith.constant 0 : index
+// CHECK:         [[VIEW:%.*]] = memref.reinterpret_cast [[COMP]] to offset: [%[[IM_C_OFF]]], sizes: [[[BD]]#1, %[[IM_C_PAIR]]], strides: [[[STRIDE]], %[[IM_C_COMP_STRIDE]]] : memref<4x2xf32> to memref<?x?xf32, strided<
+// CHECK:         memref.store %arg1, [[VIEW]][[[IDX]], %[[IM_C_IM]]] : memref<?x?xf32, strided<
 func.func @projected_slice_store_im(%arg0: !fir.ref<!fir.array<4xcomplex<f32>>>,
                                     %arg1: f32) {
   %c1 = arith.constant 1 : index
@@ -114,9 +151,22 @@ func.func @projected_slice_store_im(%arg0: !fir.ref<!fir.array<4xcomplex<f32>>>,
 // CHECK:           [[MEMREF:%.*]] = fir.convert %arg0 : (!fir.ref<!fir.array<2x3xcomplex<f32>>>) -> memref<3x2xcomplex<f32>>
 // CHECK:           [[IDX_I:%.*]] = arith.addi
 // CHECK:           [[IDX_J:%.*]] = arith.addi
-// CHECK:           [[COMP:%.*]] = fir.convert [[MEMREF]] : (memref<3x2xcomplex<f32>>) -> memref<3x2x2xf32>
-// CHECK:           arith.constant 0
-// CHECK:           memref.load [[COMP]][[[IDX_J]], [[IDX_I]], {{%.*}}] : memref<3x2x2xf32>
+// CHECK:           [[COMP:%[0-9]+]] = fir.convert [[MEMREF]] : (memref<3x2xcomplex<f32>>) -> memref<3x2x2xf32>
+// CHECK:           %[[D2_C_RE:.*]] = arith.constant 0 : index
+// CHECK:           %[[D2_C_SZF32:.*]] = arith.constant 4 : index
+// CHECK:           %[[D2_C_DIM1:.*]] = arith.constant 1 : index
+// CHECK:           [[BD0:%[0-9]+]]:3 = fir.box_dims %2, %[[D2_C_DIM1]] : (!fir.box<!fir.array<2x3xf32>>, index) -> (index, index, index)
+// CHECK:           [[STR0:%[0-9]+]] = arith.divsi [[BD0]]#2, %[[D2_C_SZF32]] : index
+// CHECK:           %[[D2_C_DIM0:.*]] = arith.constant 0 : index
+// CHECK:           [[BD1:%[0-9]+]]:3 = fir.box_dims %2, %[[D2_C_DIM0]] : (!fir.box<!fir.array<2x3xf32>>, index) -> (index, index, index)
+// CHECK:           [[STR1:%[0-9]+]] = arith.divsi [[BD1]]#2, %[[D2_C_SZF32]] : index
+// 2-D embox: two box_dims strides (both / sizeof(f32)), plus pair dim (2, 1).
+// Row-major memref indices are [j, i, 0] after Fortran dim reversal.
+// CHECK:           %[[D2_C_PAIR:.*]] = arith.constant 2 : index
+// CHECK:           %[[D2_C_COMP_STRIDE:.*]] = arith.constant 1 : index
+// CHECK:           %[[D2_C_OFF:.*]] = arith.constant 0 : index
+// CHECK:           [[VIEW:%.*]] = memref.reinterpret_cast [[COMP]] to offset: [%[[D2_C_OFF]]], sizes: [[[BD0]]#1, [[BD1]]#1, %[[D2_C_PAIR]]], strides: [[[STR0]], [[STR1]], %[[D2_C_COMP_STRIDE]]] : memref<3x2x2xf32> to memref<?x?x?xf32, strided<
+// CHECK:           [[LOAD:%[0-9]+]] = memref.load [[VIEW]][[[IDX_J]], [[IDX_I]], %[[D2_C_RE]]] : memref<?x?x?xf32, strided<
 func.func @projected_slice_2d(%arg0: !fir.ref<!fir.array<2x3xcomplex<f32>>>) {
   %c1 = arith.constant 1 : index
   %c2 = arith.constant 2 : index
@@ -134,6 +184,51 @@ func.func @projected_slice_2d(%arg0: !fir.ref<!fir.array<2x3xcomplex<f32>>>) {
   return
 }
 
+// ----------------------------------------------------------------------------
+// Projected slice on a complex descriptor (no embox): array_coor %box[%slice]
+// path %c0 for %re.  Strides must be scaled by sizeof(f32), not
+// sizeof(complex<f32>) from fir.box_elesize on the complex box.
+// ----------------------------------------------------------------------------
+// CHECK-LABEL: func.func @projected_slice_complex_box
+// CHECK:         fir.do_loop
+// CHECK:           fir.do_loop
+// CHECK:             [[CB_BOX:%[0-9]+]] = fir.box_addr %arg0 : (!fir.box<!fir.array<?x?xcomplex<f32>>>) -> !fir.ref<!fir.array<?x?xcomplex<f32>>>
+// CHECK:             [[CB_REF:%[0-9]+]] = fir.convert [[CB_BOX]] : (!fir.ref<!fir.array<?x?xcomplex<f32>>>) -> memref<?x?xcomplex<f32>>
+// CHECK:             [[CB_I:%[0-9]+]] = arith.addi
+// CHECK:             [[CB_J:%[0-9]+]] = arith.addi
+// CHECK:             [[CB_COMP:%[0-9]+]] = fir.convert [[CB_REF]] : (memref<?x?xcomplex<f32>>) -> memref<?x?x2xf32>
+// CHECK:             %[[CB_C_RE:.*]] = arith.constant 0 : index
+// CHECK:             %[[CB_C_SZF32:.*]] = arith.constant 4 : index
+// CHECK:             %[[CB_C_DIM1:.*]] = arith.constant 1 : index
+// CHECK:             [[CB_BD0:%[0-9]+]]:3 = fir.box_dims %arg0, %[[CB_C_DIM1]] : (!fir.box<!fir.array<?x?xcomplex<f32>>>, index) -> (index, index, index)
+// CHECK:             [[CB_STR0:%[0-9]+]] = arith.divsi [[CB_BD0]]#2, %[[CB_C_SZF32]] : index
+// CHECK:             %[[CB_C_DIM0:.*]] = arith.constant 0 : index
+// CHECK:             [[CB_BD1:%[0-9]+]]:3 = fir.box_dims %arg0, %[[CB_C_DIM0]] : (!fir.box<!fir.array<?x?xcomplex<f32>>>, index) -> (index, index, index)
+// CHECK:             [[CB_STR1:%[0-9]+]] = arith.divsi [[CB_BD1]]#2, %[[CB_C_SZF32]] : index
+// CHECK-NOT:         fir.box_elesize %arg0
+// Complex box (not embox): strides from fir.box_dims on %arg0; divisor sizeof(f32).
+// CHECK:             %[[CB_C_PAIR:.*]] = arith.constant 2 : index
+// CHECK:             %[[CB_C_COMP_STRIDE:.*]] = arith.constant 1 : index
+// CHECK:             %[[CB_C_OFF:.*]] = arith.constant 0 : index
+// CHECK:             [[CB_VIEW:%.*]] = memref.reinterpret_cast [[CB_COMP]] to offset: [%[[CB_C_OFF]]], sizes: [[[CB_BD0]]#1, [[CB_BD1]]#1, %[[CB_C_PAIR]]], strides: [[[CB_STR0]], [[CB_STR1]], %[[CB_C_COMP_STRIDE]]] : memref<?x?x2xf32> to memref<?x?x?xf32, strided<
+// Row-major memref indices are [j, i, 0] (see projected_slice_2d).
+// CHECK:             [[CB_LOAD:%[0-9]+]] = memref.load [[CB_VIEW]][[[CB_J]], [[CB_I]], %[[CB_C_RE]]] : memref<?x?x?xf32, strided<
+func.func @projected_slice_complex_box(%arg0: !fir.box<!fir.array<?x?xcomplex<f32>>>) {
+  %c0 = arith.constant 0 : index
+  %c1 = arith.constant 1 : index
+  %dim0:3 = fir.box_dims %arg0, %c0 : (!fir.box<!fir.array<?x?xcomplex<f32>>>, index) -> (index, index, index)
+  %dim1:3 = fir.box_dims %arg0, %c1 : (!fir.box<!fir.array<?x?xcomplex<f32>>>, index) -> (index, index, index)
+  %shape = fir.shape %dim0#1, %dim1#1 : (index, index) -> !fir.shape<2>
+  %slice = fir.slice %c1, %dim0#1, %c1, %c1, %dim1#1, %c1 path %c0 : (index, index, index, index, index, index, index) -> !fir.slice<2>
+  fir.do_loop %i = %c1 to %dim0#1 step %c1 unordered {
+    fir.do_loop %j = %c1 to %dim1#1 step %c1 unordered {
+      %coor = fir.array_coor %arg0 [%slice] %i, %j : (!fir.box<!fir.array<?x?xcomplex<f32>>>, !fir.slice<2>, index, index) -> !fir.ref<f32>
+      %val = fir.load %coor : !fir.ref<f32>
+    }
+  }
+  return
+}
+
 // ----------------------------------------------------------------------------
 // Derived-type component projection: a%x where a : TYPE{x:f64, y:complex<f64>}
 //


        


More information about the flang-commits mailing list