diff --git a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp --- a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp @@ -294,20 +294,31 @@ matchAndRewrite(hlfir::AssociateOp associate, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const override { mlir::Location loc = associate->getLoc(); - // If this is the last use of the expression value and this is an hlfir.expr - // that was bufferized, re-use the storage. - // Otherwise, create a temp and assign the storage to it. + auto module = associate->getParentOfType(); + fir::FirOpBuilder builder(rewriter, fir::getKindMapping(module)); mlir::Value bufferizedExpr = getBufferizedExprStorage(adaptor.getSource()); const bool isTrivialValue = fir::isa_trivial(bufferizedExpr.getType()); auto replaceWith = [&](mlir::Value hlfirVar, mlir::Value firVar, mlir::Value flag) { + hlfirVar = + builder.createConvert(loc, associate.getResultTypes()[0], hlfirVar); associate.getResult(0).replaceAllUsesWith(hlfirVar); + mlir::Type associateFirVarType = associate.getResultTypes()[1]; + if (firVar.getType().isa() && + !associateFirVarType.isa()) + firVar = + builder.create(loc, associateFirVarType, firVar); + else + firVar = builder.createConvert(loc, associateFirVarType, firVar); associate.getResult(1).replaceAllUsesWith(firVar); associate.getResult(2).replaceAllUsesWith(flag); rewriter.replaceOp(associate, {hlfirVar, firVar, flag}); }; + // If this is the last use of the expression value and this is an hlfir.expr + // that was bufferized, re-use the storage. + // Otherwise, create a temp and assign the storage to it. if (!isTrivialValue && allOtherUsesAreDestroys(associate.getSource(), associate.getOperation())) { // Re-use hlfir.expr buffer if this is the only use of the hlfir.expr @@ -321,8 +332,6 @@ return mlir::success(); } if (isTrivialValue) { - auto module = associate->getParentOfType(); - fir::FirOpBuilder builder(rewriter, fir::getKindMapping(module)); auto temp = builder.createTemporary(loc, bufferizedExpr.getType(), associate.getUniqName()); builder.create(loc, bufferizedExpr, temp); diff --git a/flang/test/HLFIR/associate-codegen.fir b/flang/test/HLFIR/associate-codegen.fir --- a/flang/test/HLFIR/associate-codegen.fir +++ b/flang/test/HLFIR/associate-codegen.fir @@ -115,6 +115,33 @@ // CHECK: fir.freemem %[[VAL_2]] : !fir.heap> // CHECK: } +func.func private @bar(!fir.ref>) -> () +func.func @test_result_box_addr(%x : !fir.box>) { + %true = arith.constant 1 : i1 + %expr = hlfir.as_expr %x move %true : (!fir.box>, i1) -> !hlfir.expr + %y:3 = hlfir.associate %expr {uniq_name = "y"}: (!hlfir.expr) -> (!fir.box>, !fir.ref>, i1) + fir.call @bar(%y#1) : (!fir.ref>) -> () + return +} +// CHECK-LABEL: func.func @test_result_box_addr( +// CHECK-SAME: %[[X:.*]]: !fir.box>) { +// CHECK: %[[ADDR:.*]] = fir.box_addr %[[X]] : (!fir.box>) -> !fir.ref> +// CHECK: fir.call @bar(%[[ADDR]]) : (!fir.ref>) -> () + +func.func private @bar2(!fir.ref>) -> () +func.func @test_result_convert(%x : !fir.heap>) { + %true = arith.constant 1 : i1 + %expr = hlfir.as_expr %x move %true : (!fir.heap>, i1) -> !hlfir.expr<10xi32> + %y:3 = hlfir.associate %expr {uniq_name = "y"}: (!hlfir.expr<10xi32>) -> (!fir.ref>, !fir.ref>, i1) + fir.call @bar2(%y#1) : (!fir.ref>) -> () + return +} +// CHECK-LABEL: func.func @test_result_convert( +// CHECK-SAME: %[[X:.*]]: !fir.heap>) { +// CHECK: fir.convert +// CHECK: %[[ADDR:.*]] = fir.convert %[[X]] : (!fir.heap>) -> !fir.ref> +// CHECK: fir.call @bar2(%[[ADDR]]) : (!fir.ref>) -> () + func.func private @take_i4(!fir.ref) func.func private @take_r4(!fir.ref)