From 0ff137c1ef606a9c221980dfc41880daa10f429b Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Wed, 12 Oct 2022 16:18:18 +0200 Subject: [PATCH] [flang] Use fir.rebox for tbp fir.dispatch call with allocatable or pointer Polymorphic entities with allocatable or pointer attribute cannot be passed directly as passed-object when the type-bound procedure is expecting a simply dummy polymorphic entity. Use fir.rebox to adapt the fir.class box to the tbp type. Depends on D135649 Reviewed By: jeanPerier Differential Revision: https://reviews.llvm.org/D135654 --- flang/include/flang/Optimizer/Dialect/FIROps.td | 4 ++-- flang/lib/Optimizer/Builder/FIRBuilder.cpp | 5 +++++ flang/test/Fir/invalid.fir | 4 ++-- flang/test/Lower/dispatch.f90 | 22 ++++++++++++++++++++++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td index 8fb78ea..dcdc4d2 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -822,12 +822,12 @@ def fir_ReboxOp : fir_Op<"rebox", [NoSideEffect, AttrSizedOperandSegments]> { }]; let arguments = (ins - fir_BoxType:$box, + BoxOrClassType:$box, Optional:$shape, Optional:$slice ); - let results = (outs fir_BoxType); + let results = (outs BoxOrClassType); let assemblyFormat = [{ $box (`(` $shape^ `)`)? (`[` $slice^ `]`)? attr-dict `:` functional-type(operands, results) diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp index baf5c9c..e4b3b91e 100644 --- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -325,6 +325,11 @@ fir::FirOpBuilder::convertWithSemantics(mlir::Location loc, mlir::Type toTy, return create(loc, toTy, val); } + if (fir::isPolymorphicType(fromTy) && fir::isPolymorphicType(toTy)) { + return create(loc, toTy, val, mlir::Value{}, + /*slice=*/mlir::Value{}); + } + return createConvert(loc, toTy, val); } diff --git a/flang/test/Fir/invalid.fir b/flang/test/Fir/invalid.fir index 05adc07..e27862b 100644 --- a/flang/test/Fir/invalid.fir +++ b/flang/test/Fir/invalid.fir @@ -20,7 +20,7 @@ func.func @bad_rebox_1(%arg0: !fir.ref>) { %c10 = arith.constant 10 : index %0 = fir.shape %c10 : (index) -> !fir.shape<1> - // expected-error@+1{{op operand #0 must be The type of a Fortran descriptor, but got '!fir.ref>'}} + // expected-error@+1{{op operand #0 must be box or class, but got '!fir.ref>'}} %1 = fir.rebox %arg0(%0) : (!fir.ref>, !fir.shape<1>) -> !fir.box> return } @@ -30,7 +30,7 @@ func.func @bad_rebox_1(%arg0: !fir.ref>) { func.func @bad_rebox_2(%arg0: !fir.box>) { %c10 = arith.constant 10 : index %0 = fir.shape %c10 : (index) -> !fir.shape<1> - // expected-error@+1{{op result #0 must be The type of a Fortran descriptor, but got '!fir.ref>'}} + // expected-error@+1{{op result #0 must be box or class, but got '!fir.ref>'}} %1 = fir.rebox %arg0(%0) : (!fir.box>, !fir.shape<1>) -> !fir.ref> return } diff --git a/flang/test/Lower/dispatch.f90 b/flang/test/Lower/dispatch.f90 index f081717..65077c7 100644 --- a/flang/test/Lower/dispatch.f90 +++ b/flang/test/Lower/dispatch.f90 @@ -155,6 +155,28 @@ module call_dispatch ! CHECK-SAME: %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "x"}) { ! CHECK: fir.dispatch "nopassd"(%[[ARG0]] : !fir.class>) (%[[ARG1]] : !fir.box>) + subroutine check_dispatch_scalar_allocatable(p) + class(p1), allocatable :: p + call p%tbp_pass() + end subroutine + +! CHECK-LABEL: func.func @_QMcall_dispatchPcheck_dispatch_scalar_allocatable( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref>>> {fir.bindc_name = "p"}) { +! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0]] : !fir.ref>>> +! CHECK: %[[REBOX:.*]] = fir.rebox %[[LOAD]] : (!fir.class>>) -> !fir.class> +! CHECK: fir.dispatch "tbp_pass"(%[[REBOX]] : !fir.class>) (%1 : !fir.class>) {pass_arg_pos = 0 : i32} + + subroutine check_dispatch_scalar_pointer(p) + class(p1), pointer :: p + call p%tbp_pass() + end subroutine + +! CHECK-LABEL: func.func @_QMcall_dispatchPcheck_dispatch_scalar_pointer( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref>>> {fir.bindc_name = "p"}) { +! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0]] : !fir.ref>>> +! CHECK: %[[REBOX:.*]] = fir.rebox %[[LOAD]] : (!fir.class>>) -> !fir.class> +! CHECK: fir.dispatch "tbp_pass"(%[[REBOX]] : !fir.class>) (%1 : !fir.class>) {pass_arg_pos = 0 : i32} + ! ------------------------------------------------------------------------------ ! Test that direct call is emitted when the type is known ! ------------------------------------------------------------------------------ -- 2.7.4