diff --git a/flang/lib/Optimizer/Transforms/AbstractResult.cpp b/flang/lib/Optimizer/Transforms/AbstractResult.cpp index 2c0576eaa5cc4..7fcdb4d5650be 100644 --- a/flang/lib/Optimizer/Transforms/AbstractResult.cpp +++ b/flang/lib/Optimizer/Transforms/AbstractResult.cpp @@ -217,6 +217,10 @@ class ReturnOpConversion : public mlir::OpRewritePattern { if (auto *op = returnedValue.getDefiningOp()) if (auto load = mlir::dyn_cast(op)) { auto resultStorage = load.getMemref(); + // The result alloca may be behind a fir.declare, if any. + if (auto declare = mlir::dyn_cast_or_null( + resultStorage.getDefiningOp())) + resultStorage = declare.getMemref(); // TODO: This should be generalized for derived types, and it is // architecture and OS dependent. if (fir::isa_builtin_cptr_type(returnedValue.getType())) { @@ -232,7 +236,7 @@ class ReturnOpConversion : public mlir::OpRewritePattern { ret, mlir::ValueRange{retValue}); return mlir::success(); } - load.getMemref().replaceAllUsesWith(newArg); + resultStorage.replaceAllUsesWith(newArg); replacedStorage = true; if (auto *alloc = resultStorage.getDefiningOp()) if (alloc->use_empty()) diff --git a/flang/test/Fir/abstract-results.fir b/flang/test/Fir/abstract-results.fir index 374c0d18753bb..42ff2a5c8eb2a 100644 --- a/flang/test/Fir/abstract-results.fir +++ b/flang/test/Fir/abstract-results.fir @@ -106,6 +106,33 @@ func.func @retcptr() -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__addres // FUNC-BOX: return %[[VAL]] : i64 } +// FUNC-REF-LABEL: func private @arrayfunc_callee_declare( +// FUNC-REF-SAME: %[[buffer:.*]]: !fir.ref>, %[[n:.*]]: index) { +// FUNC-BOX-LABEL: func private @arrayfunc_callee_declare( +// FUNC-BOX-SAME: %[[box:.*]]: !fir.box>, %[[n:.*]]: index) { +func.func private @arrayfunc_callee_declare(%n : index) -> !fir.array { + %buffer_alloc = fir.alloca !fir.array, %n + %shape = fir.shape %n : (index) -> !fir.shape<1> + %buffer = fir.declare %buffer_alloc(%shape) {uniq_name = "x"}: (!fir.ref>, !fir.shape<1>) -> !fir.ref> + // Do something with result (res(4) = 42.) + %c4 = arith.constant 4 : i64 + %coor = fir.coordinate_of %buffer, %c4 : (!fir.ref>, i64) -> !fir.ref + %cst = arith.constant 4.200000e+01 : f32 + fir.store %cst to %coor : !fir.ref + %res = fir.load %buffer : !fir.ref> + return %res : !fir.array + + // FUNC-REF-DAG: %[[buffer_declare:.*]] = fir.declare %[[buffer]](%{{.*}}) {uniq_name = "x"} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> + // FUNC-REF-DAG: %[[coor:.*]] = fir.coordinate_of %[[buffer_declare]], %{{.*}} : (!fir.ref>, i64) -> !fir.ref + // FUNC-REF-DAG: fir.store %{{.*}} to %[[coor]] : !fir.ref + // FUNC-REF: return + + // FUNC-BOX: %[[buffer:.*]] = fir.box_addr %[[box]] : (!fir.box>) -> !fir.ref> + // FUNC-BOX-DAG: %[[buffer_declare:.*]] = fir.declare %[[buffer]](%{{.*}}) {uniq_name = "x"} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> + // FUNC-BOX-DAG: %[[coor:.*]] = fir.coordinate_of %[[buffer_declare]], %{{.*}} : (!fir.ref>, i64) -> !fir.ref + // FUNC-BOX-DAG: fir.store %{{.*}} to %[[coor]] : !fir.ref + // FUNC-BOX: return +} // ------------------------ Test caller rewrite --------------------------------