[flang-commits] [flang] [Flang] - Add optional inlining of allocatable assignments with hlfir.expr RHS (PR #186880)

Eugene Epshteyn via flang-commits flang-commits at lists.llvm.org
Fri Mar 20 07:44:34 PDT 2026


================
@@ -125,9 +136,158 @@ class InlineHLFIRAssignConversion
   }
 };
 
+/// Expand hlfir.assign of hlfir.expr RHS to allocatable LHS.
+/// When RHS is an hlfir.expr (e.g., from hlfir.elemental), there is no
+/// aliasing concern because expressions don't represent memory locations.
+/// This allows us to inline the assignment even for allocatables.
+///
+/// The generated code:
+/// 1. Gets the shape from the RHS expression
+/// 2. Uses genReallocIfNeeded to handle allocation/reallocation properly
+/// 3. Generates a loop nest to assign elements (via storage handler callback)
+/// 4. Finalizes the reallocation
+///
+/// Example transformation for: allocatable_array = elemental_expr
+///   hlfir.assign %expr to %alloc realloc : !hlfir.expr<?xf64>,
+///                                          !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
+/// into:
+///   // Check allocation status and reallocate if needed
+///   // ... (genReallocIfNeeded handles this) ...
+///   // Loop over elements
+///   fir.do_loop %i = %c1 to %extent step %c1 unordered {
+///     %rhs_val = hlfir.apply %expr, %i : ...
+///     %lhs_elem = hlfir.designate %lhs_box (%i) : ...
+///     hlfir.assign %rhs_val to %lhs_elem : f64, !fir.ref<f64>
+///   }
+class InlineAllocatableExprAssignConversion
+    : public mlir::OpRewritePattern<hlfir::AssignOp> {
+public:
+  using mlir::OpRewritePattern<hlfir::AssignOp>::OpRewritePattern;
+
+  llvm::LogicalResult
+  matchAndRewrite(hlfir::AssignOp assign,
+                  mlir::PatternRewriter &rewriter) const override {
+    // This pattern only handles allocatable assignments
+    if (!assign.isAllocatableAssignment())
+      return rewriter.notifyMatchFailure(
+          assign, "AssignOp is not an allocatable assignment");
+
+    hlfir::Entity rhs{assign.getRhs()};
+    hlfir::Entity lhs{assign.getLhs()};
+
+    // RHS must be an hlfir.expr (this is the key condition - no aliasing)
+    if (!mlir::isa<hlfir::ExprType>(rhs.getType()))
+      return rewriter.notifyMatchFailure(
+          assign,
+          "RHS is not an hlfir.expr - cannot inline allocatable assign");
+
+    // RHS must be an array
+    if (!rhs.isArray())
+      return rewriter.notifyMatchFailure(assign,
+                                         "AssignOp's RHS is not an array");
+
+    // Check element types are trivial and match
+    mlir::Type rhsEleTy = rhs.getFortranElementType();
+    if (!fir::isa_trivial(rhsEleTy))
+      return rewriter.notifyMatchFailure(
+          assign, "AssignOp's RHS data type is not trivial");
+
+    mlir::Type lhsEleTy = lhs.getFortranElementType();
+    if (!fir::isa_trivial(lhsEleTy))
+      return rewriter.notifyMatchFailure(
+          assign, "AssignOp's LHS data type is not trivial");
+
+    if (lhsEleTy != rhsEleTy)
+      return rewriter.notifyMatchFailure(assign,
+                                         "RHS/LHS element types mismatch");
+
+    // LHS must be a reference to a box (allocatable)
+    mlir::Type lhsType = lhs.getType();
+    if (!fir::isBoxAddress(lhsType))
+      return rewriter.notifyMatchFailure(assign,
+                                         "LHS is not a reference to a box");
+
+    LLVM_DEBUG(llvm::dbgs()
+               << "InlineHLFIRAssign: inlining allocatable expr assignment\n");
+
+    mlir::Location loc = assign->getLoc();
+    fir::FirOpBuilder builder(rewriter, assign.getOperation());
+    builder.setInsertionPoint(assign);
+
+    // Get the shape of the RHS expression
+    mlir::Value rhsShape = hlfir::genShape(loc, builder, rhs);
+    llvm::SmallVector<mlir::Value> rhsExtents =
+        hlfir::getIndexExtents(loc, builder, rhsShape);
+
+    // Create a MutableBoxValue for the LHS allocatable
+    mlir::Value lhsBoxRef = lhs.getFirBase();
+
+    // Create MutableBoxValue - for trivial types, no length params needed
+    fir::MutableBoxValue mutableBox(lhsBoxRef, /*lenParamaters=*/{},
----------------
eugeneepshteyn wrote:

Small typo fix

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


More information about the flang-commits mailing list