[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