[flang-commits] [flang] 0ff137c - [flang] Use fir.rebox for tbp fir.dispatch call with allocatable or pointer
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Wed Oct 12 07:19:17 PDT 2022
Author: Valentin Clement
Date: 2022-10-12T16:19:03+02:00
New Revision: 0ff137c1ef606a9c221980dfc41880daa10f429b
URL: https://github.com/llvm/llvm-project/commit/0ff137c1ef606a9c221980dfc41880daa10f429b
DIFF: https://github.com/llvm/llvm-project/commit/0ff137c1ef606a9c221980dfc41880daa10f429b.diff
LOG: [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
Added:
Modified:
flang/include/flang/Optimizer/Dialect/FIROps.td
flang/lib/Optimizer/Builder/FIRBuilder.cpp
flang/test/Fir/invalid.fir
flang/test/Lower/dispatch.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index 8fb78eaddec3..dcdc4d2c3784 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<AnyShapeOrShiftType>:$shape,
Optional<fir_SliceType>:$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 baf5c9c4cfe8..e4b3b91e1e1d 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<fir::BoxAddrOp>(loc, toTy, val);
}
+ if (fir::isPolymorphicType(fromTy) && fir::isPolymorphicType(toTy)) {
+ return create<fir::ReboxOp>(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 05adc07fb919..e27862b26840 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<!fir.array<?x?xf32>>) {
%c10 = arith.constant 10 : index
%0 = fir.shape %c10 : (index) -> !fir.shape<1>
- // expected-error at +1{{op operand #0 must be The type of a Fortran descriptor, but got '!fir.ref<!fir.array<?x?xf32>>'}}
+ // expected-error at +1{{op operand #0 must be box or class, but got '!fir.ref<!fir.array<?x?xf32>>'}}
%1 = fir.rebox %arg0(%0) : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
return
}
@@ -30,7 +30,7 @@ func.func @bad_rebox_1(%arg0: !fir.ref<!fir.array<?x?xf32>>) {
func.func @bad_rebox_2(%arg0: !fir.box<!fir.array<?x?xf32>>) {
%c10 = arith.constant 10 : index
%0 = fir.shape %c10 : (index) -> !fir.shape<1>
- // expected-error at +1{{op result #0 must be The type of a Fortran descriptor, but got '!fir.ref<!fir.array<?xf32>>'}}
+ // expected-error at +1{{op result #0 must be box or class, but got '!fir.ref<!fir.array<?xf32>>'}}
%1 = fir.rebox %arg0(%0) : (!fir.box<!fir.array<?x?xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<?xf32>>
return
}
diff --git a/flang/test/Lower/dispatch.f90 b/flang/test/Lower/dispatch.f90
index f081717a58b6..65077c7e13bc 100644
--- a/flang/test/Lower/dispatch.f90
+++ b/flang/test/Lower/dispatch.f90
@@ -155,6 +155,28 @@ subroutine check_dispatch_deferred(a, x)
! CHECK-SAME: %[[ARG1:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"}) {
! CHECK: fir.dispatch "nopassd"(%[[ARG0]] : !fir.class<!fir.type<_QMcall_dispatchTa1{a:f32,b:f32}>>) (%[[ARG1]] : !fir.box<!fir.array<?xf32>>)
+ 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.class<!fir.heap<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>> {fir.bindc_name = "p"}) {
+! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>
+! CHECK: %[[REBOX:.*]] = fir.rebox %[[LOAD]] : (!fir.class<!fir.heap<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>) -> !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>
+! CHECK: fir.dispatch "tbp_pass"(%[[REBOX]] : !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) (%1 : !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) {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.class<!fir.ptr<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>> {fir.bindc_name = "p"}) {
+! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>
+! CHECK: %[[REBOX:.*]] = fir.rebox %[[LOAD]] : (!fir.class<!fir.ptr<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>) -> !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>
+! CHECK: fir.dispatch "tbp_pass"(%[[REBOX]] : !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) (%1 : !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) {pass_arg_pos = 0 : i32}
+
! ------------------------------------------------------------------------------
! Test that direct call is emitted when the type is known
! ------------------------------------------------------------------------------
More information about the flang-commits
mailing list