[flang-commits] [flang] 97cf8bf - [flang] materialize fir.box when it is from a block argument (#184898)

via flang-commits flang-commits at lists.llvm.org
Fri Mar 6 13:02:13 PST 2026


Author: Susan Tan (ス-ザン タン)
Date: 2026-03-06T16:02:09-05:00
New Revision: 97cf8bf220763a6a963d6229ab36dae1ed695ae3

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

LOG: [flang] materialize fir.box when it is from a block argument (#184898)

We have to materialize `fir.box` before adding a `fir.convert` to a
memref type. Otherwise we get:
`'fir.convert' op invalid type conversion'!fir.box<!fir.array<?xi32>>' /
'memref<?xi32, strided<[?], offset: ?>>'`

Added: 
    

Modified: 
    flang/lib/Optimizer/Transforms/FIRToMemRef.cpp
    flang/test/Transforms/FIRToMemRef/array-coor-block-arg.mlir

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp b/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp
index e8c30e62430c0..90b4b01e30f62 100644
--- a/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp
+++ b/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp
@@ -172,6 +172,9 @@ class FIRToMemRef : public fir::impl::FIRToMemRefBase<FIRToMemRef> {
   bool memrefIsDeviceData(Operation *memref) const;
 
   mlir::Attribute findCudaDataAttr(Value val) const;
+
+  Value materializeBoxAddressIfNeeded(Value basePtr, PatternRewriter &rewriter,
+                                      Location loc) const;
 };
 
 void FIRToMemRef::populateShapeAndShift(SmallVectorImpl<Value> &shapeVec,
@@ -251,6 +254,18 @@ mlir::Attribute FIRToMemRef::findCudaDataAttr(Value val) const {
   return nullptr;
 }
 
+Value FIRToMemRef::materializeBoxAddressIfNeeded(Value basePtr,
+                                                 PatternRewriter &rewriter,
+                                                 Location loc) const {
+  if (!isa<fir::BoxType>(basePtr.getType()))
+    return basePtr;
+
+  auto boxAddrOp = fir::BoxAddrOp::create(rewriter, loc, basePtr);
+  if (auto cudaAttr = findCudaDataAttr(basePtr))
+    boxAddrOp->setAttr(cuf::getDataAttrName(), cudaAttr);
+  return boxAddrOp.getResult();
+}
+
 void FIRToMemRef::populateShift(SmallVectorImpl<Value> &vec,
                                 fir::ShiftOp shift) const {
   vec.append(shift.getOrigins().begin(), shift.getOrigins().end());
@@ -468,9 +483,10 @@ FIRToMemRef::convertArrayCoorOp(Operation *memOp, fir::ArrayCoorOp arrayCoorOp,
   FailureOr<Value> converted;
   if (auto blockArg = dyn_cast<BlockArgument>(firMemref)) {
     rewriter.setInsertionPoint(arrayCoorOp);
-    Type memrefTy = typeConverter.convertMemrefType(blockArg.getType());
+    Value basePtr = materializeBoxAddressIfNeeded(blockArg, rewriter, loc);
+    Type memrefTy = typeConverter.convertMemrefType(basePtr.getType());
     converted =
-        fir::ConvertOp::create(rewriter, loc, memrefTy, blockArg).getResult();
+        fir::ConvertOp::create(rewriter, loc, memrefTy, basePtr).getResult();
     rewriter.setInsertionPointAfter(arrayCoorOp);
   } else if ((memref = firMemref.getDefiningOp()) &&
              enableFIRConvertOptimizations && isMarshalLike(memref) &&
@@ -639,12 +655,7 @@ FIRToMemRef::getFIRConvert(Operation *memOp, Operation *op,
 
   if (isa<fir::BoxType>(basePtr.getType())) {
     Operation *baseOp = basePtr.getDefiningOp();
-    auto boxAddrOp = fir::BoxAddrOp::create(rewriter, loc, basePtr);
-
-    if (auto cudaAttr = findCudaDataAttr(basePtr))
-      boxAddrOp->setAttr(cuf::getDataAttrName(), cudaAttr);
-
-    basePtr = boxAddrOp;
+    basePtr = materializeBoxAddressIfNeeded(basePtr, rewriter, loc);
     memrefTy = typeConverter.convertMemrefType(basePtr.getType());
 
     if (baseOp) {

diff  --git a/flang/test/Transforms/FIRToMemRef/array-coor-block-arg.mlir b/flang/test/Transforms/FIRToMemRef/array-coor-block-arg.mlir
index 7e0acbae78af4..e5b90323545f8 100644
--- a/flang/test/Transforms/FIRToMemRef/array-coor-block-arg.mlir
+++ b/flang/test/Transforms/FIRToMemRef/array-coor-block-arg.mlir
@@ -26,3 +26,21 @@ func.func @block_arg_memref(%arg0: !fir.ref<!fir.array<32xi32>>) {
 // CHECK:       memref.store {{%.+}}, [[BASE]][[[IDX]]] : memref<32xi32>
 // CHECK-NOT:   fir.array_coor
 
+// Verify fir.array_coor lowering when the base is a boxed function argument.
+// The pass must materialize fir.box_addr
+// first and must not emit an illegal direct box->memref fir.convert.
+func.func @block_arg_boxed_array(%arg0: !fir.box<!fir.array<?xi32>>) {
+  %c1_i32 = arith.constant 1 : i32
+  %c1_i64 = arith.constant 1 : i64
+  %elt = fir.array_coor %arg0 %c1_i64 : (!fir.box<!fir.array<?xi32>>, i64) -> !fir.ref<i32>
+  fir.store %c1_i32 to %elt : !fir.ref<i32>
+  return
+}
+
+// CHECK-LABEL: func.func @block_arg_boxed_array
+// CHECK:         [[BOXADDR:%.+]] = fir.box_addr %arg0
+// CHECK:           [[BASE:%.+]] = fir.convert [[BOXADDR]] : (!fir.ref<!fir.array<?xi32>>) -> memref<?xi32{{.*}}>
+// CHECK-NOT:       fir.convert %arg0 : (!fir.box<!fir.array<?xi32>>) -> memref
+// CHECK:           memref.store {{%.+}}, {{%.+}}[{{%.+}}] : memref<?xi32, strided<[?], offset: ?>>
+// CHECK-NOT:       fir.array_coor
+


        


More information about the flang-commits mailing list