[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