[flang-commits] [flang] [Flang] Add opt-in affine loop optimization pipeline (PR #191854)

Tom Eccles via flang-commits flang-commits at lists.llvm.org
Mon Apr 27 04:22:15 PDT 2026


================
@@ -60,12 +138,69 @@ class AffineLoadConversion
     if (!maybeExpandedMap)
       return failure();
 
-    auto coorOp = fir::CoordinateOp::create(
-        rewriter, op.getLoc(),
-        fir::ReferenceType::get(op.getResult().getType()), adaptor.getMemref(),
-        *maybeExpandedMap);
+    auto expandedIndices = *maybeExpandedMap;
 
-    rewriter.replaceOpWithNewOp<fir::LoadOp>(op, coorOp.getResult());
+    // AffinePromotion reverses dimension order (column-major FIR → row-major
+    // memref) and index order.  Reverse indices back for fir.coordinate_of
+    // which uses Fortran's column-major layout.
+    // ConvertConversion already strips the single fir.convert (FIR -> memref)
+    // that AffinePromotion created, so `base` is the original FIR value.
+    // Do NOT trace through any remaining fir.convert — those belong to the
+    // source IR (e.g. linearisation converts from -O2 whole-array lowering).
+    Value base = adaptor.getMemref();
+
+    auto hasSequenceType = [](mlir::Type ty) -> bool {
+      if (auto refTy = mlir::dyn_cast<fir::ReferenceType>(ty))
+        return mlir::isa<fir::SequenceType>(refTy.getEleTy());
+      if (auto heapTy = mlir::dyn_cast<fir::HeapType>(ty))
+        return mlir::isa<fir::SequenceType>(heapTy.getEleTy());
+      return false;
+    };
+
+    if (!hasSequenceType(base.getType()))
+      return op.emitError(
+          "unsupported memref base: expected !fir.ref<!fir.array<...>> or "
+          "!fir.heap<!fir.array<...>>; fir.box and plain memref bases "
+          "are not yet handled by AffineDemotion");
+
+    std::reverse(expandedIndices.begin(), expandedIndices.end());
+
+    auto resultRefTy = fir::ReferenceType::get(op.getResult().getType());
+
+    if (baseHasDynamicExtents(base)) {
+      mlir::Value boxBase;
+      mlir::Value shape = findShapeForBase(base, boxBase);
+
+      if (shape) {
+        auto fortranIndices =
+            toFortranIndices(shape, expandedIndices, op.getLoc(), rewriter);
+        auto arrayCoorOp = fir::ArrayCoorOp::create(
+            rewriter, op.getLoc(), resultRefTy, base, shape,
+            /*slice=*/mlir::Value{}, fortranIndices,
+            /*typeparams=*/mlir::ValueRange{});
+        rewriter.replaceOpWithNewOp<fir::LoadOp>(op, arrayCoorOp.getResult());
+      } else if (boxBase) {
+        // Case 3: box carries shape — use box directly; lb=1 assumed
----------------
tblah wrote:

I'm not sure it is always safe to assume lb=1. As we don't have a shape on this path, the only option is to read the lower bound out of the box using fir.box_dims.

https://github.com/llvm/llvm-project/pull/191854


More information about the flang-commits mailing list