mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-26 05:18:46 +00:00
[flang] Deal with NULL() passed as actual arg to unlimited polymorphic dummy
NULL() passed as actual argument to a procedure with an optional dummy argument is represented with `fir.box<none>` type. When the dummy argument is polymoprhic or unlimited polymorphic, the SelectOp will complain if the types of the two arguments are not identical. Add a conversion from `fir.box<none>` to `fir.class<none>` in that case. Other situations with optional will require a fir.rebox and will be done in a follow up patch. Reviewed By: PeteSteinfeld Differential Revision: https://reviews.llvm.org/D142203
This commit is contained in:
parent
4dbf3f2e8e
commit
262dad4a81
@ -276,6 +276,9 @@ bool isPointerType(mlir::Type ty);
|
||||
/// Return true iff `ty` is the type of an ALLOCATABLE entity or value.
|
||||
bool isAllocatableType(mlir::Type ty);
|
||||
|
||||
/// Return true iff `ty` is !fir.box<none>.
|
||||
bool isBoxNone(mlir::Type ty);
|
||||
|
||||
/// Return true iff `ty` is the type of a boxed record type.
|
||||
/// e.g. !fir.box<!fir.type<derived>>
|
||||
bool isBoxedRecordType(mlir::Type ty);
|
||||
|
@ -2704,6 +2704,17 @@ public:
|
||||
/// has the dummy attributes in BIND(C) contexts.
|
||||
mlir::Value box = builder.createBox(
|
||||
loc, fir::factory::genMutableBoxRead(builder, loc, mutableBox));
|
||||
|
||||
// NULL() passed as argument is passed as a !fir.box<none>. Since
|
||||
// select op requires the same type for its two argument, convert
|
||||
// !fir.box<none> to !fir.class<none> when the argument is
|
||||
// polymorphic.
|
||||
if (fir::isBoxNone(box.getType()) && fir::isPolymorphicType(argTy))
|
||||
box = builder.createConvert(
|
||||
loc,
|
||||
fir::ClassType::get(mlir::NoneType::get(builder.getContext())),
|
||||
box);
|
||||
|
||||
// Need the box types to be exactly similar for the selectOp.
|
||||
mlir::Value convertedBox = builder.createConvert(loc, argTy, box);
|
||||
caller.placeInput(arg, builder.create<mlir::arith::SelectOp>(
|
||||
|
@ -272,6 +272,12 @@ bool isAllocatableType(mlir::Type ty) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isBoxNone(mlir::Type ty) {
|
||||
if (auto box = ty.dyn_cast<fir::BoxType>())
|
||||
return box.getEleTy().isa<mlir::NoneType>();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isBoxedRecordType(mlir::Type ty) {
|
||||
if (auto refTy = fir::dyn_cast_ptrEleTy(ty))
|
||||
ty = refTy;
|
||||
|
@ -767,6 +767,28 @@ module polymorphic_test
|
||||
! CHECK: %[[REBOX:.*]] = fir.rebox %[[LOAD_P]](%{{.*}}) : (!fir.class<!fir.heap<!fir.array<?x?xnone>>>, !fir.shift<2>) -> !fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QMpolymorphic_testTnon_extensible{d:i32}>>>>
|
||||
! CHECK: fir.store %[[REBOX]] to %[[T]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QMpolymorphic_testTnon_extensible{d:i32}>>>>>
|
||||
|
||||
subroutine sub_with_poly_optional(a)
|
||||
class(*), optional :: a
|
||||
end subroutine
|
||||
|
||||
subroutine test_call_with_null()
|
||||
call sub_with_poly_optional(null())
|
||||
end subroutine
|
||||
|
||||
! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_call_with_null() {
|
||||
! CHECK: %[[NULL_LLVM_PTR:.*]] = fir.alloca !fir.llvm_ptr<none>
|
||||
! CHECK: %[[NULL_BOX_NONE:.*]] = fir.convert %[[NULL_LLVM_PTR]] : (!fir.ref<!fir.llvm_ptr<none>>) -> !fir.ref<!fir.box<none>>
|
||||
! CHECK: %[[BOX_NONE:.*]] = fir.load %[[NULL_BOX_NONE]] : !fir.ref<!fir.box<none>>
|
||||
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX_NONE]] : (!fir.box<none>) -> !fir.ref<none>
|
||||
! CHECK: %[[BOX_ADDR_I64:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.ref<none>) -> i64
|
||||
! CHECK: %[[C0:.*]] = arith.constant 0 : i64
|
||||
! CHECK: %[[IS_ALLOCATED_OR_ASSOCIATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_I64]], %[[C0]] : i64
|
||||
! CHECK: %[[ABSENT:.*]] = fir.absent !fir.class<none>
|
||||
! CHECK: %[[BOX_NONE:.*]] = fir.load %[[NULL_BOX_NONE]] : !fir.ref<!fir.box<none>>
|
||||
! CHECK: %[[CLASS_NONE:.*]] = fir.convert %[[BOX_NONE]] : (!fir.box<none>) -> !fir.class<none>
|
||||
! CHECK: %[[ARG:.*]] = arith.select %[[IS_ALLOCATED_OR_ASSOCIATED]], %[[CLASS_NONE]], %[[ABSENT]] : !fir.class<none>
|
||||
! CHECK: fir.call @_QMpolymorphic_testPsub_with_poly_optional(%[[ARG]]) {{.*}} : (!fir.class<none>) -> ()
|
||||
|
||||
end module
|
||||
|
||||
program test
|
||||
|
Loading…
x
Reference in New Issue
Block a user