diff --git a/flang/include/flang/Lower/ConvertExprToHLFIR.h b/flang/include/flang/Lower/ConvertExprToHLFIR.h index 42ce7b6edd747..dc0bde191354a 100644 --- a/flang/include/flang/Lower/ConvertExprToHLFIR.h +++ b/flang/include/flang/Lower/ConvertExprToHLFIR.h @@ -112,6 +112,12 @@ fir::ExtendedValue convertToValue(mlir::Location loc, hlfir::Entity entity, Fortran::lower::StatementContext &); +fir::ExtendedValue convertDataRefToValue(mlir::Location loc, + Fortran::lower::AbstractConverter &, + const Fortran::evaluate::DataRef &, + Fortran::lower::SymMap &, + Fortran::lower::StatementContext &); + /// Lower an evaluate::Expr to a fir::MutableBoxValue value. /// This can only be called if the Expr is a POINTER or ALLOCATABLE, /// otherwise, this will crash. diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp index b1420dcb25a11..1f41c3bec847e 100644 --- a/flang/lib/Lower/CallInterface.cpp +++ b/flang/lib/Lower/CallInterface.cpp @@ -91,7 +91,7 @@ bool Fortran::lower::CallerInterface::requireDispatchCall() const { // polymorphic. if (const Fortran::evaluate::Component *component = procRef.proc().GetComponent()) { - if (Fortran::semantics::IsPolymorphic(component->GetFirstSymbol())) + if (Fortran::semantics::IsPolymorphic(component->base().GetLastSymbol())) return true; } // calls with PASS attribute have the passed-object already set in its diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp index 0bdb4452e5eb2..81f4c0a2c6d2d 100644 --- a/flang/lib/Lower/ConvertCall.cpp +++ b/flang/lib/Lower/ConvertCall.cpp @@ -409,9 +409,11 @@ fir::ExtendedValue Fortran::lower::genCallOpAndResult( const Fortran::evaluate::Component *component = caller.getCallDescription().proc().GetComponent(); assert(component && "expect component for type-bound procedure call."); - fir::ExtendedValue pass = converter.getSymbolExtendedValue( - component->GetFirstSymbol(), &symMap); - mlir::Value passObject = fir::getBase(pass); + + fir::ExtendedValue dataRefValue = Fortran::lower::convertDataRefToValue( + loc, converter, component->base(), symMap, stmtCtx); + mlir::Value passObject = fir::getBase(dataRefValue); + if (fir::isa_ref_type(passObject.getType())) passObject = builder.create(loc, passObject); dispatch = builder.create( diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp index b114fbe1a13a2..7771b4a635f29 100644 --- a/flang/lib/Lower/ConvertExprToHLFIR.cpp +++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp @@ -166,6 +166,13 @@ class HlfirDesignatorBuilder { return builder.genShape(loc, lbounds, extents); } + fir::FortranVariableOpInterface + gen(const Fortran::evaluate::DataRef &dataRef) { + return std::visit( + Fortran::common::visitors{[&](const auto &x) { return gen(x); }}, + dataRef.u); + } + private: /// Struct that is filled while visiting a part-ref (in the "visit" member /// function) before the top level "gen" generates an hlfir.declare for the @@ -311,13 +318,6 @@ class HlfirDesignatorBuilder { return genDesignate(resultType, partInfo, component); } - fir::FortranVariableOpInterface - gen(const Fortran::evaluate::DataRef &dataRef) { - return std::visit( - Fortran::common::visitors{[&](const auto &x) { return gen(x); }}, - dataRef.u); - } - fir::FortranVariableOpInterface gen(const Fortran::evaluate::ArrayRef &arrayRef) { PartInfo partInfo; @@ -1926,6 +1926,15 @@ fir::ExtendedValue Fortran::lower::convertExprToValue( return convertToValue(loc, converter, loweredExpr, stmtCtx); } +fir::ExtendedValue Fortran::lower::convertDataRefToValue( + mlir::Location loc, Fortran::lower::AbstractConverter &converter, + const Fortran::evaluate::DataRef &dataRef, Fortran::lower::SymMap &symMap, + Fortran::lower::StatementContext &stmtCtx) { + fir::FortranVariableOpInterface loweredExpr = + HlfirDesignatorBuilder(loc, converter, symMap, stmtCtx).gen(dataRef); + return convertToValue(loc, converter, loweredExpr, stmtCtx); +} + fir::MutableBoxValue Fortran::lower::convertExprToMutableBox( mlir::Location loc, Fortran::lower::AbstractConverter &converter, const Fortran::lower::SomeExpr &expr, Fortran::lower::SymMap &symMap) { diff --git a/flang/test/Fir/dispatch.f90 b/flang/test/Fir/dispatch.f90 index 2c06377c99034..1dc71038813d8 100644 --- a/flang/test/Fir/dispatch.f90 +++ b/flang/test/Fir/dispatch.f90 @@ -1,5 +1,5 @@ -! RUN: bbc -polymorphic-type -emit-fir -hlfir=false %s -o - | fir-opt --fir-polymorphic-op | FileCheck %s -! RUN: bbc -polymorphic-type -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefix=BT +! RUN: bbc -polymorphic-type -emit-hlfir %s -o - | fir-opt --fir-polymorphic-op | FileCheck %s +! RUN: bbc -polymorphic-type -emit-hlfir %s -o - | FileCheck %s --check-prefix=BT ! Tests codegen of fir.dispatch operation. This test is intentionally run from ! Fortran through bbc and tco so we have all the binding tables lowered to FIR @@ -184,61 +184,58 @@ program test_type_to_class ! CHECK-LABEL: func.func @_QMdispatch1Pdisplay_class( ! CHECK-SAME: %[[ARG:.*]]: [[CLASS:!fir.class<.*>>]] - -! CHECK-DAG: %[[INT32:.*]] = fir.alloca i32 -! CHECK-DAG: %[[REAL:.*]] = fir.alloca f32 -! CHECK-DAG: %[[I:.*]] = fir.alloca i32 +! CHECK: %[[ARG_DECL:.*]]:2 = hlfir.declare %[[ARG]] {uniq_name = "_QMdispatch1Fdisplay_classEp"} : (!fir.class>) -> (!fir.class>, !fir.class>) ! Check dynamic dispatch equal to `call p%display2()` with binding index = 2. -! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG]] : ([[CLASS]]) -> !fir.tdesc +! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG_DECL]]#0 : ([[CLASS]]) -> !fir.tdesc ! CHECK: %[[TYPEDESCPTR:.*]] = fir.convert %[[BOXDESC]] : (!fir.tdesc) -> !fir.ref<[[TYPEINFO:!fir.type<_QM__fortran_type_infoTderivedtype{.*}>]]> ! CHECK: %[[BINDING_FIELD:.*]] = fir.field_index binding, [[TYPEINFO]] ! CHECK: %[[BINDING_BOX_ADDR:.*]] = fir.coordinate_of %[[TYPEDESCPTR]], %[[BINDING_FIELD]] : (!fir.ref<[[TYPEINFO]]>, !fir.field) -> !fir.ref<[[BINDING_BOX_TYPE:.*]]> ! CHECK: %[[BINDING_BOX:.*]] = fir.load %[[BINDING_BOX_ADDR]] : !fir.ref<[[BINDING_BOX_TYPE]]> ! CHECK: %[[BINDING_BASE_ADDR:.*]] = fir.box_addr %[[BINDING_BOX]] : ([[BINDING_BOX_TYPE]]) -> !fir.ptr<[[BINDINGSINFO:.*]]> -! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c2 : (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]> +! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c2{{.*}} : (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]> ! CHECK: %[[PROC_FIELD:.*]] = fir.field_index proc, [[BINDINGINFO]] ! CHECK: %[[BUILTIN_FUNC_PTR:.*]] = fir.coordinate_of %[[BINDING_PTR]], %[[PROC_FIELD]] : ({{.*}}) -> !fir.ref<[[BUILTIN_FUNC_TYPE:.*]]> ! CHECK: %[[ADDRESS_FIELD:.*]] = fir.field_index __address, [[BUILTIN_FUNC_TYPE]] ! CHECK: %[[FUNC_ADDR_PTR:.*]] = fir.coordinate_of %[[BUILTIN_FUNC_PTR]], %[[ADDRESS_FIELD]] ! CHECK: %[[FUNC_ADDR:.*]] = fir.load %[[FUNC_ADDR_PTR]] : !fir.ref ! CHECK: %[[FUNC_PTR:.*]] = fir.convert %[[FUNC_ADDR]] : (i64) -> (([[CLASS]]) -> ()) -! CHECK: fir.call %[[FUNC_PTR]](%[[ARG]]) : ([[CLASS]]) -> () +! CHECK: fir.call %[[FUNC_PTR]](%[[ARG_DECL]]#0) : (!fir.class>) -> () ! Check dynamic dispatch equal to `call p%display1()` with binding index = 1. -! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG]] : ([[CLASS]]) -> !fir.tdesc +! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG_DECL]]#0 : ([[CLASS]]) -> !fir.tdesc ! CHECK: %[[TYPEDESCPTR:.*]] = fir.convert %[[BOXDESC]] : (!fir.tdesc) -> !fir.ref<[[TYPEINFO:!fir.type<_QM__fortran_type_infoTderivedtype{.*}>]]> ! CHECK: %[[BINDING_FIELD:.*]] = fir.field_index binding, [[TYPEINFO]] ! CHECK: %[[BINDING_BOX_ADDR:.*]] = fir.coordinate_of %[[TYPEDESCPTR]], %[[BINDING_FIELD]] : (!fir.ref<[[TYPEINFO]]>, !fir.field) -> !fir.ref<[[BINDING_BOX_TYPE:.*]]> ! CHECK: %[[BINDING_BOX:.*]] = fir.load %[[BINDING_BOX_ADDR]] : !fir.ref<[[BINDING_BOX_TYPE]]> ! CHECK: %[[BINDING_BASE_ADDR:.*]] = fir.box_addr %[[BINDING_BOX]] : ([[BINDING_BOX_TYPE]]) -> !fir.ptr<[[BINDINGSINFO:.*]]> -! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c1 : (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]> +! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c1{{.*}} : (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]> ! CHECK: %[[PROC_FIELD:.*]] = fir.field_index proc, [[BINDINGINFO]] ! CHECK: %[[BUILTIN_FUNC_PTR:.*]] = fir.coordinate_of %[[BINDING_PTR]], %[[PROC_FIELD]] : ({{.*}}) -> !fir.ref<[[BUILTIN_FUNC_TYPE:.*]]> ! CHECK: %[[ADDRESS_FIELD:.*]] = fir.field_index __address, [[BUILTIN_FUNC_TYPE]] ! CHECK: %[[FUNC_ADDR_PTR:.*]] = fir.coordinate_of %[[BUILTIN_FUNC_PTR]], %[[ADDRESS_FIELD]] ! CHECK: %[[FUNC_ADDR:.*]] = fir.load %[[FUNC_ADDR_PTR]] : !fir.ref ! CHECK: %[[FUNC_PTR:.*]] = fir.convert %[[FUNC_ADDR]] : (i64) -> (([[CLASS]]) -> ()) -! CHECK: fir.call %[[FUNC_PTR]](%[[ARG]]) : ([[CLASS]]) -> () +! CHECK: fir.call %[[FUNC_PTR]](%[[ARG_DECL]]#0) : (!fir.class>) -> () ! Check dynamic dispatch equal to `call p%aproc()` with binding index = 0. -! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG]] : ([[CLASS]]) -> !fir.tdesc +! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG_DECL]]#0 : ([[CLASS]]) -> !fir.tdesc ! CHECK: %[[TYPEDESCPTR:.*]] = fir.convert %[[BOXDESC]] : (!fir.tdesc) -> !fir.ref<[[TYPEINFO:!fir.type<_QM__fortran_type_infoTderivedtype{.*}>]]> ! CHECK: %[[BINDING_FIELD:.*]] = fir.field_index binding, [[TYPEINFO]] ! CHECK: %[[BINDING_BOX_ADDR:.*]] = fir.coordinate_of %[[TYPEDESCPTR]], %[[BINDING_FIELD]] : (!fir.ref<[[TYPEINFO]]>, !fir.field) -> !fir.ref<[[BINDING_BOX_TYPE:.*]]> ! CHECK: %[[BINDING_BOX:.*]] = fir.load %[[BINDING_BOX_ADDR]] : !fir.ref<[[BINDING_BOX_TYPE]]> ! CHECK: %[[BINDING_BASE_ADDR:.*]] = fir.box_addr %[[BINDING_BOX]] : ([[BINDING_BOX_TYPE]]) -> !fir.ptr<[[BINDINGSINFO:.*]]> -! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c0 : (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]> +! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c0{{.*}}: (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]> ! CHECK: %[[PROC_FIELD:.*]] = fir.field_index proc, [[BINDINGINFO]] ! CHECK: %[[BUILTIN_FUNC_PTR:.*]] = fir.coordinate_of %[[BINDING_PTR]], %[[PROC_FIELD]] : ({{.*}}) -> !fir.ref<[[BUILTIN_FUNC_TYPE:.*]]> ! CHECK: %[[ADDRESS_FIELD:.*]] = fir.field_index __address, [[BUILTIN_FUNC_TYPE]] ! CHECK: %[[FUNC_ADDR_PTR:.*]] = fir.coordinate_of %[[BUILTIN_FUNC_PTR]], %[[ADDRESS_FIELD]] ! CHECK: %[[FUNC_ADDR:.*]] = fir.load %[[FUNC_ADDR_PTR]] : !fir.ref ! CHECK: %[[FUNC_PTR:.*]] = fir.convert %[[FUNC_ADDR]] : (i64) -> (([[CLASS]]) -> ()) -! CHECK: fir.call %[[FUNC_PTR]](%[[ARG]]) : ([[CLASS]]) -> () +! CHECK: fir.call %[[FUNC_PTR]](%[[ARG_DECL]]#0) : (!fir.class>) -> () ! Check dynamic dispatch of a function with result. -! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG]] : ([[CLASS]]) -> !fir.tdesc +! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG_DECL]]#0 : ([[CLASS]]) -> !fir.tdesc ! CHECK: %[[TYPEDESCPTR:.*]] = fir.convert %[[BOXDESC]] : (!fir.tdesc) -> !fir.ref<[[TYPEINFO:!fir.type<_QM__fortran_type_infoTderivedtype{.*}>]]> ! CHECK: %[[BINDING_FIELD:.*]] = fir.field_index binding, [[TYPEINFO]] ! CHECK: %[[BINDING_BOX_ADDR:.*]] = fir.coordinate_of %[[TYPEDESCPTR]], %[[BINDING_FIELD]] : (!fir.ref<[[TYPEINFO]]>, !fir.field) -> !fir.ref<[[BINDING_BOX_TYPE:.*]]> @@ -251,32 +248,32 @@ program test_type_to_class ! CHECK: %[[FUNC_ADDR_PTR:.*]] = fir.coordinate_of %[[BUILTIN_FUNC_PTR]], %[[ADDRESS_FIELD]] ! CHECK: %[[FUNC_ADDR:.*]] = fir.load %[[FUNC_ADDR_PTR]] : !fir.ref ! CHECK: %[[FUNC_PTR:.*]] = fir.convert %[[FUNC_ADDR]] : (i64) -> (([[CLASS]]) -> i32) -! CHECK: %[[RES:.*]] = fir.call %[[FUNC_PTR]](%[[ARG]]) : ([[CLASS]]) -> i32 +! CHECK: %[[RES:.*]] = fir.call %[[FUNC_PTR]](%[[ARG_DECL]]#0) : (!fir.class>) -> i32 ! Check dynamic dispatch of call with passed-object and additional argument -! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG]] : ([[CLASS]]) -> !fir.tdesc +! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG_DECL]]#0 : ([[CLASS]]) -> !fir.tdesc ! CHECK: %[[TYPEDESCPTR:.*]] = fir.convert %[[BOXDESC]] : (!fir.tdesc) -> !fir.ref<[[TYPEINFO:!fir.type<_QM__fortran_type_infoTderivedtype{.*}>]]> ! CHECK: %[[BINDING_FIELD:.*]] = fir.field_index binding, [[TYPEINFO]] ! CHECK: %[[BINDING_BOX_ADDR:.*]] = fir.coordinate_of %[[TYPEDESCPTR]], %[[BINDING_FIELD]] : (!fir.ref<[[TYPEINFO]]>, !fir.field) -> !fir.ref<[[BINDING_BOX_TYPE:.*]]> ! CHECK: %[[BINDING_BOX:.*]] = fir.load %[[BINDING_BOX_ADDR]] : !fir.ref<[[BINDING_BOX_TYPE]]> ! CHECK: %[[BINDING_BASE_ADDR:.*]] = fir.box_addr %[[BINDING_BOX]] : ([[BINDING_BOX_TYPE]]) -> !fir.ptr<[[BINDINGSINFO:.*]]> -! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c6 : (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]> +! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c6{{.*}} : (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]> ! CHECK: %[[PROC_FIELD:.*]] = fir.field_index proc, [[BINDINGINFO]] ! CHECK: %[[BUILTIN_FUNC_PTR:.*]] = fir.coordinate_of %[[BINDING_PTR]], %[[PROC_FIELD]] : ({{.*}}) -> !fir.ref<[[BUILTIN_FUNC_TYPE:.*]]> ! CHECK: %[[ADDRESS_FIELD:.*]] = fir.field_index __address, [[BUILTIN_FUNC_TYPE]] ! CHECK: %[[FUNC_ADDR_PTR:.*]] = fir.coordinate_of %[[BUILTIN_FUNC_PTR]], %[[ADDRESS_FIELD]] ! CHECK: %[[FUNC_ADDR:.*]] = fir.load %[[FUNC_ADDR_PTR]] : !fir.ref ! CHECK: %[[FUNC_PTR:.*]] = fir.convert %[[FUNC_ADDR]] : (i64) -> (([[CLASS]], !fir.ref) -> ()) -! CHECK: fir.call %[[FUNC_PTR]](%[[ARG]], %[[REAL]]) : ([[CLASS]], !fir.ref) -> () +! CHECK: fir.call %[[FUNC_PTR]](%[[ARG_DECL]]#0, %{{.*}}) : (!fir.class>, !fir.ref) -> () ! Check dynamic dispatch of a call with NOPASS -! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG]] : ([[CLASS]]) -> !fir.tdesc +! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG_DECL]]#1 : ([[CLASS]]) -> !fir.tdesc ! CHECK: %[[TYPEDESCPTR:.*]] = fir.convert %[[BOXDESC]] : (!fir.tdesc) -> !fir.ref<[[TYPEINFO:!fir.type<_QM__fortran_type_infoTderivedtype{.*}>]]> ! CHECK: %[[BINDING_FIELD:.*]] = fir.field_index binding, [[TYPEINFO]] ! CHECK: %[[BINDING_BOX_ADDR:.*]] = fir.coordinate_of %[[TYPEDESCPTR]], %[[BINDING_FIELD]] : (!fir.ref<[[TYPEINFO]]>, !fir.field) -> !fir.ref<[[BINDING_BOX_TYPE:.*]]> -! CHECK: %[[BINDING_BOX:.*]] = fir.load %[[BINDING_BOX_ADDR]] : !fir.ref<[[BINDING_BOX_TYPE]]> -! CHECK: %[[BINDING_BASE_ADDR:.*]] = fir.box_addr %[[BINDING_BOX]] : ([[BINDING_BOX_TYPE]]) -> !fir.ptr<[[BINDINGSINFO:.*]]> -! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c4 : (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]> +! CHECK: %[[BINDING_BOX:.*]] = fir.load %[[BINDING_BOX_ADDR]] : !fir.ref>>>> +! CHECK: %[[BINDING_BASE_ADDR:.*]] = fir.box_addr %[[BINDING_BOX]] : (!fir.box>> +! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c4{{.*}} : (!fir.ptr>>, index) -> !fir.ref> ! CHECK: %[[PROC_FIELD:.*]] = fir.field_index proc, [[BINDINGINFO]] ! CHECK: %[[BUILTIN_FUNC_PTR:.*]] = fir.coordinate_of %[[BINDING_PTR]], %[[PROC_FIELD]] : ({{.*}}) -> !fir.ref<[[BUILTIN_FUNC_TYPE:.*]]> ! CHECK: %[[ADDRESS_FIELD:.*]] = fir.field_index __address, [[BUILTIN_FUNC_TYPE]] @@ -285,20 +282,20 @@ program test_type_to_class ! CHECK: %[[FUNC_PTR:.*]] = fir.convert %[[FUNC_ADDR]] : (i64) -> (() -> ()) ! CHECK: fir.call %[[FUNC_PTR]]() : () -> () -! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG]] : ([[CLASS]]) -> !fir.tdesc +! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG_DECL]]#0 : ([[CLASS]]) -> !fir.tdesc ! CHECK: %[[TYPEDESCPTR:.*]] = fir.convert %[[BOXDESC]] : (!fir.tdesc) -> !fir.ref<[[TYPEINFO:!fir.type<_QM__fortran_type_infoTderivedtype{.*}>]]> ! CHECK: %[[BINDING_FIELD:.*]] = fir.field_index binding, [[TYPEINFO]] ! CHECK: %[[BINDING_BOX_ADDR:.*]] = fir.coordinate_of %[[TYPEDESCPTR]], %[[BINDING_FIELD]] : (!fir.ref<[[TYPEINFO]]>, !fir.field) -> !fir.ref<[[BINDING_BOX_TYPE:.*]]> ! CHECK: %[[BINDING_BOX:.*]] = fir.load %[[BINDING_BOX_ADDR]] : !fir.ref<[[BINDING_BOX_TYPE]]> ! CHECK: %[[BINDING_BASE_ADDR:.*]] = fir.box_addr %[[BINDING_BOX]] : ([[BINDING_BOX_TYPE]]) -> !fir.ptr<[[BINDINGSINFO:.*]]> -! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c5 : (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]> +! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c5{{.*}} : (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]> ! CHECK: %[[PROC_FIELD:.*]] = fir.field_index proc, [[BINDINGINFO]] ! CHECK: %[[BUILTIN_FUNC_PTR:.*]] = fir.coordinate_of %[[BINDING_PTR]], %[[PROC_FIELD]] : ({{.*}}) -> !fir.ref<[[BUILTIN_FUNC_TYPE:.*]]> ! CHECK: %[[ADDRESS_FIELD:.*]] = fir.field_index __address, [[BUILTIN_FUNC_TYPE]] ! CHECK: %[[FUNC_ADDR_PTR:.*]] = fir.coordinate_of %[[BUILTIN_FUNC_PTR]], %[[ADDRESS_FIELD]] ! CHECK: %[[FUNC_ADDR:.*]] = fir.load %[[FUNC_ADDR_PTR]] : !fir.ref ! CHECK: %[[FUNC_PTR:.*]] = fir.convert %[[FUNC_ADDR]] : (i64) -> ((!fir.ref, [[CLASS]]) -> ()) -! CHECK: fir.call %[[FUNC_PTR]](%[[INT32]], %[[ARG]]) : (!fir.ref, [[CLASS]]) -> () +! CHECK: fir.call %[[FUNC_PTR]](%{{.*}}, %[[ARG_DECL]]#0) : (!fir.ref, [[CLASS]]) -> () ! CHECK-LABEL: _QMdispatch1Pno_pass_array ! CHECK-LABEL: _QMdispatch1Pno_pass_array_allocatable diff --git a/flang/test/Lower/allocatable-polymorphic.f90 b/flang/test/Lower/allocatable-polymorphic.f90 index 75db99dee094d..a6a8c039880da 100644 --- a/flang/test/Lower/allocatable-polymorphic.f90 +++ b/flang/test/Lower/allocatable-polymorphic.f90 @@ -1,5 +1,5 @@ -! RUN: bbc --use-desc-for-alloc=false -polymorphic-type -emit-fir -hlfir=false %s -o - | FileCheck %s -! RUN: bbc --use-desc-for-alloc=false -polymorphic-type -emit-fir -hlfir=false %s -o - | tco | FileCheck %s --check-prefix=LLVM +! RUN: bbc --use-desc-for-alloc=false -polymorphic-type -emit-hlfir %s -o - | FileCheck %s +! RUN: bbc --use-desc-for-alloc=false -polymorphic-type -emit-hlfir %s -o - | tco | FileCheck %s --check-prefix=LLVM module poly type p1 @@ -40,7 +40,6 @@ subroutine proc2_p2(this) print*, 'call proc2_p2' end subroutine - ! ------------------------------------------------------------------------------ ! Test lowering of ALLOCATE statement for polymoprhic pointer ! ------------------------------------------------------------------------------ @@ -88,18 +87,23 @@ subroutine test_pointer() ! CHECK-LABEL: func.func @_QMpolyPtest_pointer() ! CHECK: %[[C1_DESC:.*]] = fir.alloca !fir.class>> {bindc_name = "c1", uniq_name = "_QMpolyFtest_pointerEc1"} +! CHECK: %[[C1_DECL:.*]]:2 = hlfir.declare %[[C1_DESC]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_pointerEc1"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: %[[C2_DESC:.*]] = fir.alloca !fir.class>> {bindc_name = "c2", uniq_name = "_QMpolyFtest_pointerEc2"} +! CHECK: %[[C2_DECL:.*]]:2 = hlfir.declare %[[C2_DESC]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_pointerEc2"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: %[[C3_DESC:.*]] = fir.alloca !fir.class>>> {bindc_name = "c3", uniq_name = "_QMpolyFtest_pointerEc3"} +! CHECK: %[[C3_DECL:.*]]:2 = hlfir.declare %[[C3_DESC]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_pointerEc3"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) ! CHECK: %[[C4_DESC:.*]] = fir.alloca !fir.class>>> {bindc_name = "c4", uniq_name = "_QMpolyFtest_pointerEc4"} +! CHECK: %[[C4_DECL:.*]]:2 = hlfir.declare %[[C4_DESC]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_pointerEc4"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) ! CHECK: %[[P_DESC:.*]] = fir.alloca !fir.class>> {bindc_name = "p", uniq_name = "_QMpolyFtest_pointerEp"} +! CHECK: %[[P_DECL:.*]]:2 = hlfir.declare %[[P_DESC]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_pointerEp"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[P_DESC_CAST:.*]] = fir.convert %[[P_DESC]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[P_DESC_CAST:.*]] = fir.convert %[[P_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 ! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: %{{.*}} = fir.call @_FortranAPointerNullifyDerived(%[[P_DESC_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[CORANK]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> none -! CHECK: %[[P_DESC_CAST:.*]] = fir.convert %[[P_DESC]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[P_DESC_CAST:.*]] = fir.convert %[[P_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[P_DESC_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! call p%proc1() @@ -107,98 +111,96 @@ subroutine test_pointer() ! CHECK: fir.dispatch "proc1"(%[[P_LOAD]] : !fir.class>>) ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C1_DESC_CAST:.*]] = fir.convert %[[C1_DESC:.*]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[C1_DESC_CAST:.*]] = fir.convert %[[C1_DECL:.*]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 ! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: %{{.*}} = fir.call @_FortranAPointerNullifyDerived(%[[C1_DESC_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[CORANK]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> none -! CHECK: %[[C1_DESC_CAST:.*]] = fir.convert %[[C1_DESC]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[C1_DESC_CAST:.*]] = fir.convert %[[C1_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[C1_DESC_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 -! CHECK: %[[TYPE_DESC_P2:.*]] = fir.type_desc !fir.type<_QMpolyTp2{a:i32,b:i32,c:i32}> -! CHECK: %[[C2_DESC_CAST:.*]] = fir.convert %[[C2_DESC]] : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc>) -> !fir.ref +! CHECK: %[[TYPE_DESC_P2:.*]] = fir.type_desc !fir.type<_QMpolyTp2{p1:!fir.type<_QMpolyTp1{a:i32,b:i32}>,c:i32}> +! CHECK: %[[C2_DESC_CAST:.*]] = fir.convert %[[C2_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc,c:i32}>>) -> !fir.ref ! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 ! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: %{{.*}} = fir.call @_FortranAPointerNullifyDerived(%[[C2_DESC_CAST]], %[[TYPE_DESC_P2_CAST]], %[[RANK]], %[[CORANK]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> none -! CHECK: %[[C2_DESC_CAST:.*]] = fir.convert %[[C2_DESC]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[C2_DESC_CAST:.*]] = fir.convert %[[C2_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[C2_DESC_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! call c1%proc1() -! CHECK: %[[C1_DESC_LOAD:.*]] = fir.load %[[C1_DESC]] : !fir.ref>>> +! CHECK: %[[C1_DESC_LOAD:.*]] = fir.load %[[C1_DECL]]#0 : !fir.ref>>> ! CHECK: fir.dispatch "proc1"(%[[C1_DESC_LOAD]] : !fir.class>>) ! call c2%proc1() -! CHECK: %[[C2_DESC_LOAD:.*]] = fir.load %[[C2_DESC]] : !fir.ref>>> +! CHECK: %[[C2_DESC_LOAD:.*]] = fir.load %[[C2_DECL]]#0 : !fir.ref>>> ! CHECK: fir.dispatch "proc1"(%[[C2_DESC_LOAD]] : !fir.class>>) ! call c1%proc2() -! CHECK: %[[C1_LOAD:.*]] = fir.load %[[C1_DESC]] : !fir.ref>>> +! CHECK: %[[C1_LOAD:.*]] = fir.load %[[C1_DECL]]#0 : !fir.ref>>> ! CHECK: %[[C1_REBOX:.*]] = fir.rebox %[[C1_LOAD]] : (!fir.class>>) -> !fir.class> -! CHECK: fir.dispatch "proc2"(%[[C1_LOAD]] : !fir.class>>) (%[[C1_REBOX]] : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: fir.dispatch "proc2"(%[[C1_REBOX]] : !fir.class>) (%[[C1_REBOX]] : !fir.class>) {pass_arg_pos = 0 : i32} ! call c2%proc2() -! CHECK: %[[C2_LOAD:.*]] = fir.load %[[C2_DESC]] : !fir.ref>>> +! CHECK: %[[C2_LOAD:.*]] = fir.load %[[C2_DECL]]#0 : !fir.ref>>> ! CHECK: %[[C2_REBOX:.*]] = fir.rebox %[[C2_LOAD]] : (!fir.class>>) -> !fir.class> -! CHECK: fir.dispatch "proc2"(%[[C2_LOAD]] : !fir.class>>) (%[[C2_REBOX]] : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: fir.dispatch "proc2"(%[[C2_REBOX]] : !fir.class>) (%[[C2_REBOX]] : !fir.class>) {pass_arg_pos = 0 : i32} ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DESC]] : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %[[RANK:.*]] = arith.constant 1 : i32 ! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: %{{.*}} = fir.call @_FortranAPointerNullifyDerived(%[[C3_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[CORANK]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> none -! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DESC]] : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerSetBounds(%[[C3_CAST]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i32, i64, i64) -> none -! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DESC]] : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[C3_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 -! CHECK: %[[TYPE_DESC_P2:.*]] = fir.type_desc !fir.type<_QMpolyTp2{a:i32,b:i32,c:i32}> -! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DESC]] : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc>) -> !fir.ref +! CHECK: %[[TYPE_DESC_P2:.*]] = fir.type_desc !fir.type<_QMpolyTp2{p1:!fir.type<_QMpolyTp1{a:i32,b:i32}>,c:i32}> +! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc,c:i32}>>) -> !fir.ref ! CHECK: %[[RANK:.*]] = arith.constant 1 : i32 ! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: %{{.*}} = fir.call @_FortranAPointerNullifyDerived(%[[C4_CAST]], %[[TYPE_DESC_P2_CAST]], %[[RANK]], %[[CORANK]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> none -! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DESC]] : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerSetBounds(%[[C4_CAST]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i32, i64, i64) -> none -! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DESC]] : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[C4_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK-LABEL: fir.do_loop -! CHECK: %[[C3_LOAD:.*]] = fir.load %[[C3_DESC]] : !fir.ref>>>> -! CHECK: %[[C3_COORD:.*]] = fir.coordinate_of %[[C3_LOAD]], %{{.*}} : (!fir.class>>>, i64) -> !fir.ref> -! CHECK: %[[C3_BOXED:.*]] = fir.embox %[[C3_COORD]] source_box %[[C3_LOAD]] : (!fir.ref>, !fir.class>>>) -> !fir.class> -! CHECK: fir.dispatch "proc2"(%[[C3_BOXED]] : !fir.class>) (%[[C3_BOXED]] : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: %[[C3_LOAD:.*]] = fir.load %[[C3_DECL]]#0 : !fir.ref>>>> +! CHECK: %[[DESIGNATE_C3:.*]] = hlfir.designate %[[C3_LOAD]] (%{{.*}}) : (!fir.class>>>, i64) -> !fir.class> +! CHECK: fir.dispatch "proc2"(%[[DESIGNATE_C3]] : !fir.class>) (%[[DESIGNATE_C3]] : !fir.class>) {pass_arg_pos = 0 : i32} ! CHECK-LABEL: fir.do_loop -! CHECK: %[[C4_LOAD:.*]] = fir.load %[[C4_DESC]] : !fir.ref>>>> -! CHECK: %[[C4_COORD:.*]] = fir.coordinate_of %[[C4_LOAD]], %{{.*}} : (!fir.class>>>, i64) -> !fir.ref> -! CHECK: %[[C4_BOXED:.*]] = fir.embox %[[C4_COORD]] source_box %[[C4_LOAD]] : (!fir.ref>, !fir.class>>>) -> !fir.class> -! CHECK: fir.dispatch "proc2"(%[[C4_BOXED]] : !fir.class>) (%[[C4_BOXED]] : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: %[[C4_LOAD:.*]] = fir.load %[[C4_DECL]]#0 : !fir.ref>>>> +! CHECK: %[[DESIGNATE_C4:.*]] = hlfir.designate %[[C4_LOAD]] (%{{.*}}) : (!fir.class>>>, i64) -> !fir.class> +! CHECK: fir.dispatch "proc2"(%[[DESIGNATE_C4]] : !fir.class>) (%[[DESIGNATE_C4]] : !fir.class>) {pass_arg_pos = 0 : i32} ! CHECK: %[[TYPE_DESC_ADDR:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[P_CAST:.*]] = fir.convert %[[P_DESC]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[P_CAST:.*]] = fir.convert %[[P_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC_ADDR]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %{{.*}} = fir.call @_FortranAPointerDeallocatePolymorphic(%[[P_CAST]], %[[TYPE_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_ADDR:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C1_DESC_CAST:.*]] = fir.convert %[[C1_DESC]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[C1_DESC_CAST:.*]] = fir.convert %[[C1_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC_ADDR]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %{{.*}} = fir.call @_FortranAPointerDeallocatePolymorphic(%[[C1_DESC_CAST]], %[[TYPE_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_ADDR:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C2_DESC_CAST:.*]] = fir.convert %[[C2_DESC]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[C2_DESC_CAST:.*]] = fir.convert %[[C2_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC_ADDR]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %{{.*}} = fir.call @_FortranAPointerDeallocatePolymorphic(%[[C2_DESC_CAST]], %[[TYPE_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_ADDR:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C3_DESC_CAST:.*]] = fir.convert %[[C3_DESC]] : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[C3_DESC_CAST:.*]] = fir.convert %[[C3_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC_ADDR]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %{{.*}} = fir.call @_FortranAPointerDeallocatePolymorphic(%[[C3_DESC_CAST]], %[[TYPE_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_ADDR:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C4_DESC_CAST:.*]] = fir.convert %[[C4_DESC]] : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[C4_DESC_CAST:.*]] = fir.convert %[[C4_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC_ADDR]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %{{.*}} = fir.call @_FortranAPointerDeallocatePolymorphic(%[[C4_DESC_CAST]], %[[TYPE_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 @@ -248,117 +250,120 @@ subroutine test_allocatable() ! CHECK-LABEL: func.func @_QMpolyPtest_allocatable() ! CHECK-DAG: %[[C1:.*]] = fir.alloca !fir.class>> {bindc_name = "c1", uniq_name = "_QMpolyFtest_allocatableEc1"} +! CHECK-DAG: %[[C1_DECL:.*]]:2 = hlfir.declare %[[C1]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_allocatableEc1"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK-DAG: %[[C2:.*]] = fir.alloca !fir.class>> {bindc_name = "c2", uniq_name = "_QMpolyFtest_allocatableEc2"} +! CHECK-DAG: %[[C2_DECL:.*]]:2 = hlfir.declare %[[C2]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_allocatableEc2"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK-DAG: %[[C3:.*]] = fir.alloca !fir.class>>> {bindc_name = "c3", uniq_name = "_QMpolyFtest_allocatableEc3"} +! CHECK-DAG: %[[C3_DECL:.*]]:2 = hlfir.declare %[[C3]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_allocatableEc3"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) ! CHECK-DAG: %[[C4:.*]] = fir.alloca !fir.class>>> {bindc_name = "c4", uniq_name = "_QMpolyFtest_allocatableEc4"} +! CHECK-DAG: %[[C4_DECL:.*]]:2 = hlfir.declare %[[C4]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_allocatableEc4"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) ! CHECK-DAG: %[[P:.*]] = fir.alloca !fir.class>> {bindc_name = "p", uniq_name = "_QMpolyFtest_allocatableEp"} +! CHECK-DAG: %[[P_DECL:.*]]:2 = hlfir.declare %[[P]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_allocatableEp"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[P_CAST:.*]] = fir.convert %[[P]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[P_CAST:.*]] = fir.convert %[[P_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 ! CHECK: %[[C0:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%[[P_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[C0]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> none -! CHECK: %[[P_CAST:.*]] = fir.convert %[[P]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[P_CAST:.*]] = fir.convert %[[P_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[P_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C1_CAST:.*]] = fir.convert %0 : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[C1_CAST:.*]] = fir.convert %[[C1_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 ! CHECK: %[[C0:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%[[C1_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[C0]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> none -! CHECK: %[[C1_CAST:.*]] = fir.convert %[[C1]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[C1_CAST:.*]] = fir.convert %[[C1_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C1_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 -! CHECK: %[[TYPE_DESC_P2:.*]] = fir.type_desc !fir.type<_QMpolyTp2{a:i32,b:i32,c:i32}> -! CHECK: %[[C2_CAST:.*]] = fir.convert %[[C2]] : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc>) -> !fir.ref +! CHECK: %[[TYPE_DESC_P2:.*]] = fir.type_desc !fir.type<_QMpolyTp2{p1:!fir.type<_QMpolyTp1{a:i32,b:i32}>,c:i32}> +! CHECK: %[[C2_CAST:.*]] = fir.convert %[[C2_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc,c:i32}>>) -> !fir.ref ! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 ! CHECK: %[[C0:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%[[C2_CAST]], %[[TYPE_DESC_P2_CAST]], %[[RANK]], %[[C0]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> none -! CHECK: %[[C2_CAST:.*]] = fir.convert %[[C2]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[C2_CAST:.*]] = fir.convert %[[C2_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C2_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3]] : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %[[RANK:.*]] = arith.constant 1 : i32 ! CHECK: %[[C0:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%[[C3_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[C0]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> none ! CHECK: %[[C10:.*]] = arith.constant 10 : i32 ! CHECK: %[[C0:.*]] = arith.constant 0 : i32 -! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3]] : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %[[C1_I64:.*]] = fir.convert %c1 : (index) -> i64 +! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[C1_I64:.*]] = fir.convert %c1{{.*}} : (index) -> i64 ! CHECK: %[[C10_I64:.*]] = fir.convert %[[C10]] : (i32) -> i64 ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableSetBounds(%[[C3_CAST]], %[[C0]], %[[C1_I64]], %[[C10_I64]]) {{.*}}: (!fir.ref>, i32, i64, i64) -> none -! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3]] : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C3_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 -! CHECK: %[[TYPE_DESC_P2:.*]] = fir.type_desc !fir.type<_QMpolyTp2{a:i32,b:i32,c:i32}> -! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4]] : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc>) -> !fir.ref +! CHECK: %[[TYPE_DESC_P2:.*]] = fir.type_desc !fir.type<_QMpolyTp2{p1:!fir.type<_QMpolyTp1{a:i32,b:i32}>,c:i32}> +! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc,c:i32}>>) -> !fir.ref ! CHECK: %[[RANK:.*]] = arith.constant 1 : i32 ! CHECK: %[[C0:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%[[C4_CAST]], %[[TYPE_DESC_P2_CAST]], %[[RANK]], %[[C0]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> none ! CHECK: %[[CST1:.*]] = arith.constant 1 : index ! CHECK: %[[C20:.*]] = arith.constant 20 : i32 ! CHECK: %[[C0:.*]] = arith.constant 0 : i32 -! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4]] : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %[[C1_I64:.*]] = fir.convert %[[CST1]] : (index) -> i64 ! CHECK: %[[C20_I64:.*]] = fir.convert %[[C20]] : (i32) -> i64 ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableSetBounds(%[[C4_CAST]], %[[C0]], %[[C1_I64]], %[[C20_I64]]) {{.*}}: (!fir.ref>, i32, i64, i64) -> none -! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4]] : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C4_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 -! CHECK: %[[C1_LOAD1:.*]] = fir.load %[[C1_DESC]] : !fir.ref>>> +! CHECK: %[[C1_LOAD1:.*]] = fir.load %[[C1_DECL]]#0 : !fir.ref>>> ! CHECK: fir.dispatch "proc1"(%[[C1_LOAD1]] : !fir.class>>) -! CHECK: %[[C2_LOAD1:.*]] = fir.load %[[C2_DESC]] : !fir.ref>>> +! CHECK: %[[C2_LOAD1:.*]] = fir.load %[[C2_DECL]]#0 : !fir.ref>>> ! CHECK: fir.dispatch "proc1"(%[[C2_LOAD1]] : !fir.class>>) -! CHECK: %[[C1_LOAD2:.*]] = fir.load %[[C1_DESC]] : !fir.ref>>> +! CHECK: %[[C1_LOAD2:.*]] = fir.load %[[C1_DECL]]#0 : !fir.ref>>> ! CHECK: %[[C1_REBOX:.*]] = fir.rebox %[[C1_LOAD2]] : (!fir.class>>) -> !fir.class> -! CHECK: fir.dispatch "proc2"(%[[C1_LOAD2]] : !fir.class>>) (%[[C1_REBOX]] : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: fir.dispatch "proc2"(%[[C1_REBOX]] : !fir.class>) (%[[C1_REBOX]] : !fir.class>) {pass_arg_pos = 0 : i32} -! CHECK: %[[C2_LOAD2:.*]] = fir.load %[[C2_DESC]] : !fir.ref>>> +! CHECK: %[[C2_LOAD2:.*]] = fir.load %[[C2_DECL]]#0 : !fir.ref>>> ! CHECK: %[[C2_REBOX:.*]] = fir.rebox %[[C2_LOAD2]] : (!fir.class>>) -> !fir.class> -! CHECK: fir.dispatch "proc2"(%[[C2_LOAD2]] : !fir.class>>) (%[[C2_REBOX]] : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: fir.dispatch "proc2"(%[[C2_REBOX]] : !fir.class>) (%[[C2_REBOX]] : !fir.class>) {pass_arg_pos = 0 : i32} ! CHECK-LABEL: %{{.*}} = fir.do_loop -! CHECK: %[[C3_LOAD:.*]] = fir.load %[[C3_DESC]] : !fir.ref>>>> -! CHECK: %[[C3_COORD:.*]] = fir.coordinate_of %[[C3_LOAD]], %{{.*}} : (!fir.class>>>, i64) -> !fir.ref> -! CHECK: %[[C3_EMBOX:.*]] = fir.embox %[[C3_COORD]] source_box %[[C3_LOAD]] : (!fir.ref>, !fir.class>>>) -> !fir.class> -! CHECK: fir.dispatch "proc2"(%[[C3_EMBOX]] : !fir.class>) (%[[C3_EMBOX]] : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: %[[C3_LOAD:.*]] = fir.load %[[C3_DECL]]#0 : !fir.ref>>>> +! CHECK: %[[DESIGNATE_C3:.*]] = hlfir.designate %[[C3_LOAD]] (%{{.*}}) : (!fir.class>>>, i64) -> !fir.class> +! CHECK: fir.dispatch "proc2"(%[[DESIGNATE_C3]] : !fir.class>) (%[[DESIGNATE_C3]] : !fir.class>) {pass_arg_pos = 0 : i32} ! CHECK-LABEL: %{{.*}} = fir.do_loop -! CHECK: %[[C4_LOAD:.*]] = fir.load %[[C4]] : !fir.ref>>>> -! CHECK: %[[C4_COORD:.*]] = fir.coordinate_of %[[C4_LOAD]], %{{.*}} : (!fir.class>>>, i64) -> !fir.ref> -! CHECK: %[[C4_EMBOX:.*]] = fir.embox %[[C4_COORD]] source_box %[[C4_LOAD]] : (!fir.ref>, !fir.class>>>) -> !fir.class> -! CHECK: fir.dispatch "proc2"(%[[C4_EMBOX]] : !fir.class>) (%[[C4_EMBOX]] : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: %[[C4_LOAD:.*]] = fir.load %[[C4_DECL]]#0 : !fir.ref>>>> +! CHECK: %[[DESIGNATE_C4:.*]] = hlfir.designate %[[C4_LOAD]] (%{{.*}}) : (!fir.class>>>, i64) -> !fir.class> +! CHECK: fir.dispatch "proc2"(%[[DESIGNATE_C4]] : !fir.class>) (%[[DESIGNATE_C4]] : !fir.class>) {pass_arg_pos = 0 : i32} ! CHECK: %[[TYPE_DESC_ADDR:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[P_CAST:.*]] = fir.convert %[[P]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[P_CAST:.*]] = fir.convert %[[P_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC_ADDR]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[P_CAST]], %[[TYPE_NONE]], %{{.*}}, %1{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_ADDR:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C1_CAST:.*]] = fir.convert %[[C1]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[C1_CAST:.*]] = fir.convert %[[C1_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC_ADDR]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[C1_CAST]], %[[TYPE_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_ADDR:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C2_CAST:.*]] = fir.convert %[[C2]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[C2_CAST:.*]] = fir.convert %[[C2_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC_ADDR]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[C2_CAST]], %[[TYPE_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_ADDR:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3]] : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC_ADDR]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[C3_CAST]], %[[TYPE_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_ADDR:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4]] : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC_ADDR]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[C4_CAST]], %[[TYPE_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 @@ -375,27 +380,29 @@ subroutine test_unlimited_polymorphic_with_intrinsic_type_spec() ! CHECK-LABEL: func.func @_QMpolyPtest_unlimited_polymorphic_with_intrinsic_type_spec() { ! CHECK: %[[P:.*]] = fir.alloca !fir.class> {bindc_name = "p", uniq_name = "_QMpolyFtest_unlimited_polymorphic_with_intrinsic_type_specEp"} +! CHECK: %[[P_DECL:.*]]:2 = hlfir.declare %[[P]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_unlimited_polymorphic_with_intrinsic_type_specEp"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) ! CHECK: %[[PTR:.*]] = fir.alloca !fir.class> {bindc_name = "ptr", uniq_name = "_QMpolyFtest_unlimited_polymorphic_with_intrinsic_type_specEptr"} -! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[P]] : (!fir.ref>>) -> !fir.ref> +! CHECK: %[[PTR_DECL:.*]]:2 = hlfir.declare %[[PTR]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_unlimited_polymorphic_with_intrinsic_type_specEptr"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) +! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[P_DECL]]#1 : (!fir.ref>>) -> !fir.ref> ! CHECK: %[[CAT:.*]] = arith.constant 0 : i32 ! CHECK: %[[KIND:.*]] = arith.constant 4 : i32 ! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 ! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableInitIntrinsicForAllocate(%[[BOX_NONE]], %[[CAT]], %[[KIND]], %[[RANK]], %[[CORANK]]) {{.*}} : (!fir.ref>, i32, i32, i32, i32) -> none -! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[P]] : (!fir.ref>>) -> !fir.ref> +! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[P_DECL]]#1 : (!fir.ref>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 -! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[PTR]] : (!fir.ref>>) -> !fir.ref> +! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[PTR_DECL]]#1 : (!fir.ref>>) -> !fir.ref> ! CHECK: %[[CAT:.*]] = arith.constant 1 : i32 ! CHECK: %[[KIND:.*]] = arith.constant 4 : i32 ! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 ! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: %{{.*}} = fir.call @_FortranAPointerNullifyIntrinsic(%[[BOX_NONE]], %[[CAT]], %[[KIND]], %[[RANK]], %[[CORANK]]) {{.*}} : (!fir.ref>, i32, i32, i32, i32) -> none -! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[PTR]] : (!fir.ref>>) -> !fir.ref> +! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[PTR_DECL]]#1 : (!fir.ref>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[NULL_TYPE_DESC:.*]] = fir.zero_bits !fir.ref -! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[PTR]] : (!fir.ref>>) -> !fir.ref> +! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[PTR_DECL]]#1 : (!fir.ref>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerDeallocatePolymorphic(%[[BOX_NONE]], %[[NULL_TYPE_DESC]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 ! Test code generation of deallocate @@ -413,21 +420,24 @@ subroutine test_type_with_polymorphic_pointer_component() end subroutine ! CHECK-LABEL: func.func @_QMpolyPtest_type_with_polymorphic_pointer_component() -! CHECK: %[[TYPE_PTR:.*]] = fir.alloca !fir.ptr>>}>> {uniq_name = "_QMpolyFtest_type_with_polymorphic_pointer_componentEa.addr"} -! CHECK: %[[TYPE_PTR_LOAD:.*]] = fir.load %[[TYPE_PTR]] : !fir.ref>>}>>> -! CHECK: %[[ELEMENT:.*]] = fir.field_index element, !fir.type<_QMpolyTwith_alloc{element:!fir.class>>}> -! CHECK: %[[ELEMENT_DESC:.*]] = fir.coordinate_of %[[TYPE_PTR_LOAD]], %[[ELEMENT]] : (!fir.ptr>>}>>, !fir.field) -> !fir.ref>>> +! CHECK: %[[TYPE_PTR:.*]] = fir.alloca !fir.box>>}>>> {bindc_name = "a", uniq_name = "_QMpolyFtest_type_with_polymorphic_pointer_componentEa"} +! CHECK: %[[TYPE_PTR_DECL:.*]]:2 = hlfir.declare %39 {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_type_with_polymorphic_pointer_componentEa"} : (!fir.ref>>}>>>>) -> (!fir.ref>>}>>>>, !fir.ref>>}>>>>) +! CHECK: %[[TYPE_PTR_CONV:.*]] = fir.convert %[[TYPE_PTR_DECL]]#1 : (!fir.ref>>}>>>>) -> !fir.ref> +! CHECK: fir.call @_FortranAPointerAllocate(%[[TYPE_PTR_CONV]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %[[TYPE_PTR_LOAD:.*]] = fir.load %[[TYPE_PTR_DECL]]#0 : !fir.ref>>}>>>> +! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[TYPE_PTR_LOAD]] : (!fir.box>>}>>>) -> !fir.ptr>>}>> +! CHECK: %[[ELEMENT:.*]] = hlfir.designate %[[BOX_ADDR]]{"element"} {fortran_attrs = #fir.var_attrs} : (!fir.ptr>>}>>) -> !fir.ref>>> ! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.ptr> ! CHECK: %[[ZERO_DESC:.*]] = fir.embox %[[ZERO]] : (!fir.ptr>) -> !fir.class>> -! CHECK: fir.store %[[ZERO_DESC]] to %[[ELEMENT_DESC]] : !fir.ref>>> +! CHECK: fir.store %[[ZERO_DESC]] to %[[ELEMENT]] : !fir.ref>>> ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[ELEMENT_DESC_CAST:.*]] = fir.convert %[[ELEMENT_DESC]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[ELEMENT_DESC_CAST:.*]] = fir.convert %[[ELEMENT]] : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 ! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 -! CHECK: %{{.*}} = fir.call @_FortranAPointerNullifyDerived(%[[ELEMENT_DESC_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[CORANK]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> none -! CHECK: %[[ELEMENT_DESC_CAST:.*]] = fir.convert %[[ELEMENT_DESC]] : (!fir.ref>>>) -> !fir.ref> -! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[ELEMENT_DESC_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.*}} = fir.call @_FortranAPointerNullifyDerived(%[[ELEMENT_DESC_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[CORANK]]) {{.*}} : (!fir.ref>, !fir.ref, i32, i32) -> none +! CHECK: %[[ELEMENT_DESC_CAST:.*]] = fir.convert %[[ELEMENT]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[ELEMENT_DESC_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 subroutine test_allocate_with_mold() type(p2) :: x(10) @@ -441,22 +451,27 @@ subroutine test_allocate_with_mold() ! CHECK-LABEL: func.func @_QMpolyPtest_allocate_with_mold() { ! CHECK: %[[I:.*]] = fir.alloca !fir.array<20xi32> {bindc_name = "i", uniq_name = "_QMpolyFtest_allocate_with_moldEi"} +! CHECK: %[[I_DECL:.*]]:2 = hlfir.declare %[[I]](%{{.*}}) {uniq_name = "_QMpolyFtest_allocate_with_moldEi"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) ! CHECK: %[[P:.*]] = fir.alloca !fir.class>>> {bindc_name = "p", uniq_name = "_QMpolyFtest_allocate_with_moldEp"} +! CHECK: %[[P_DECL:.*]]:2 = hlfir.declare %[[P]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_allocate_with_moldEp"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) ! CHECK: %[[UP:.*]] = fir.alloca !fir.class>> {bindc_name = "up", uniq_name = "_QMpolyFtest_allocate_with_moldEup"} -! CHECK: %[[X:.*]] = fir.alloca !fir.array<10x!fir.type<_QMpolyTp2{a:i32,b:i32,c:i32}>> {bindc_name = "x", uniq_name = "_QMpolyFtest_allocate_with_moldEx"} -! CHECK: %[[EMBOX_X:.*]] = fir.embox %[[X]](%{{.*}}) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>> +! CHECK: %[[UP_DECL:.*]]:2 = hlfir.declare %[[UP:.*]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_allocate_with_moldEup"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: %[[X:.*]] = fir.alloca !fir.array<10x!fir.type<_QMpolyTp2{p1:!fir.type<_QMpolyTp1{a:i32,b:i32}>,c:i32}>> {bindc_name = "x", uniq_name = "_QMpolyFtest_allocate_with_moldEx"} +! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]](%{{.*}}) {uniq_name = "_QMpolyFtest_allocate_with_moldEx"} : (!fir.ref,c:i32}>>>, !fir.shape<1>) -> (!fir.ref,c:i32}>>>, !fir.ref,c:i32}>>>) + +! CHECK: %[[EMBOX_X:.*]] = fir.embox %[[X_DECL]]#1(%{{.*}}) : (!fir.ref,c:i32}>>>, !fir.shape<1>) -> !fir.box,c:i32}>>> ! CHECK: %[[RANK:.*]] = arith.constant 1 : i32 -! CHECK: %[[P_BOX_NONE:.*]] = fir.convert %[[P]] : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %[[X_BOX_NONE:.*]] = fir.convert %[[EMBOX_X]] : (!fir.box>>) -> !fir.box +! CHECK: %[[P_BOX_NONE:.*]] = fir.convert %[[P_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[X_BOX_NONE:.*]] = fir.convert %[[EMBOX_X]] : (!fir.box,c:i32}>>>) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAPointerApplyMold(%[[P_BOX_NONE]], %[[X_BOX_NONE]], %[[RANK]]) {{.*}} : (!fir.ref>, !fir.box, i32) -> none -! CHECK: %[[P_BOX_NONE:.*]] = fir.convert %[[P]] : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[P_BOX_NONE:.*]] = fir.convert %[[P_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[P_BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 -! CHECK: %[[EMBOX_I:.*]] = fir.embox %[[I]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.box> +! CHECK: %[[EMBOX_I:.*]] = fir.embox %[[I_DECL]]#1(%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.box> ! CHECK: %[[RANK:.*]] = arith.constant 1 : i32 -! CHECK: %[[UP_BOX_NONE:.*]] = fir.convert %[[UP]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[UP_BOX_NONE:.*]] = fir.convert %[[UP_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[I_BOX_NONE:.*]] = fir.convert %[[EMBOX_I]] : (!fir.box>) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAPointerApplyMold(%[[UP_BOX_NONE]], %[[I_BOX_NONE]], %[[RANK]]) {{.*}} : (!fir.ref>, !fir.box, i32) -> none -! CHECK: %[[UP_BOX_NONE:.*]] = fir.convert %[[UP]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[UP_BOX_NONE:.*]] = fir.convert %[[UP_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[UP_BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 subroutine test_allocate_with_source() @@ -471,25 +486,29 @@ subroutine test_allocate_with_source() ! CHECK-LABEL: func.func @_QMpolyPtest_allocate_with_source() { ! CHECK: %[[I:.*]] = fir.alloca !fir.array<20xi32> {bindc_name = "i", uniq_name = "_QMpolyFtest_allocate_with_sourceEi"} +! CHECK: %[[I_DECL:.*]]:2 = hlfir.declare %[[I]](%{{.*}}) {uniq_name = "_QMpolyFtest_allocate_with_sourceEi"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) ! CHECK: %[[P:.*]] = fir.alloca !fir.class>>> {bindc_name = "p", uniq_name = "_QMpolyFtest_allocate_with_sourceEp"} +! CHECK: %[[P_DECL:.*]]:2 = hlfir.declare %[[P]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_allocate_with_sourceEp"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) ! CHECK: %[[UP:.*]] = fir.alloca !fir.class>> {bindc_name = "up", uniq_name = "_QMpolyFtest_allocate_with_sourceEup"} -! CHECK: %[[X:.*]] = fir.alloca !fir.array<10x!fir.type<_QMpolyTp2{a:i32,b:i32,c:i32}>> {bindc_name = "x", uniq_name = "_QMpolyFtest_allocate_with_sourceEx"} -! CHECK: %[[EMBOX_X:.*]] = fir.embox %[[X]](%{{.*}}) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>> +! CHECK: %[[UP_DECL:.*]]:2 = hlfir.declare %[[UP]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_allocate_with_sourceEup"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: %[[X:.*]] = fir.alloca !fir.array<10x!fir.type<_QMpolyTp2{p1:!fir.type<_QMpolyTp1{a:i32,b:i32}>,c:i32}>> {bindc_name = "x", uniq_name = "_QMpolyFtest_allocate_with_sourceEx"} +! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]](%{{.*}}) {uniq_name = "_QMpolyFtest_allocate_with_sourceEx"} : (!fir.ref,c:i32}>>>, !fir.shape<1>) -> (!fir.ref,c:i32}>>>, !fir.ref,c:i32}>>>) +! CHECK: %[[EMBOX_X:.*]] = fir.embox %[[X_DECL]]#1(%{{.*}}) : (!fir.ref,c:i32}>>>, !fir.shape<1>) -> !fir.box,c:i32}>>> ! CHECK: %[[RANK:.*]] = arith.constant 1 : i32 -! CHECK: %[[P_BOX_NONE:.*]] = fir.convert %[[P]] : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %[[X_BOX_NONE:.*]] = fir.convert %[[EMBOX_X]] : (!fir.box>>) -> !fir.box +! CHECK: %[[P_BOX_NONE:.*]] = fir.convert %[[P_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[X_BOX_NONE:.*]] = fir.convert %[[EMBOX_X]] : (!fir.box,c:i32}>>>) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAPointerApplyMold(%[[P_BOX_NONE]], %[[X_BOX_NONE]], %[[RANK]]) {{.*}} : (!fir.ref>, !fir.box, i32) -> none ! CHECK: %{{.*}} = fir.call @_FortranAPointerSetBounds -! CHECK: %[[BOX_NONE_P:.*]] = fir.convert %[[P]] : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %[[BOX_NONE_X:.*]] = fir.convert %[[EMBOX_X]] : (!fir.box>>) -> !fir.box +! CHECK: %[[BOX_NONE_P:.*]] = fir.convert %[[P_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[BOX_NONE_X:.*]] = fir.convert %[[EMBOX_X]] : (!fir.box,c:i32}>>>) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocateSource(%[[BOX_NONE_P]], %[[BOX_NONE_X]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, !fir.box, i1, !fir.box, !fir.ref, i32) -> i32 -! CHECK: %[[EMBOX_I:.*]] = fir.embox %[[I]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.box> +! CHECK: %[[EMBOX_I:.*]] = fir.embox %[[I_DECL]]#1(%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.box> ! CHECK: %[[RANK:.*]] = arith.constant 1 : i32 -! CHECK: %[[UP_BOX_NONE:.*]] = fir.convert %[[UP]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[UP_BOX_NONE:.*]] = fir.convert %[[UP_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[I_BOX_NONE:.*]] = fir.convert %[[EMBOX_I]] : (!fir.box>) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAPointerApplyMold(%[[UP_BOX_NONE]], %[[I_BOX_NONE]], %[[RANK]]) {{.*}} : (!fir.ref>, !fir.box, i32) -> none ! CHECK: %{{.*}} = fir.call @_FortranAPointerSetBounds -! CHECK: %[[UP_BOX_NONE:.*]] = fir.convert %[[UP]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[UP_BOX_NONE:.*]] = fir.convert %[[UP_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[I_BOX_NONE:.*]] = fir.convert %[[EMBOX_I]] : (!fir.box>) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocateSource(%[[UP_BOX_NONE]], %[[I_BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, !fir.box, i1, !fir.box, !fir.ref, i32) -> i32 @@ -501,12 +520,14 @@ subroutine test_allocatable_up_from_up_mold(a, b) ! CHECK-LABEL: func.func @_QMpolyPtest_allocatable_up_from_up_mold( ! CHECK-SAME: %[[A:.*]]: !fir.ref>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref>> {fir.bindc_name = "b"}) { -! CHECK: %[[LOAD_B:.*]] = fir.load %[[B]] : !fir.ref>> +! CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_allocatable_up_from_up_moldEa"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) +! CHECK: %[[B_DECL:.*]]:2 = hlfir.declare %[[B]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_allocatable_up_from_up_moldEb"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) +! CHECK: %[[LOAD_B:.*]] = fir.load %[[B_DECL]]#1 : !fir.ref>> ! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 -! CHECK: %[[A_BOX_NONE:.*]] = fir.convert %[[A]] : (!fir.ref>>) -> !fir.ref> +! CHECK: %[[A_BOX_NONE:.*]] = fir.convert %[[A_DECL]]#1 : (!fir.ref>>) -> !fir.ref> ! CHECK: %[[B_BOX_NONE:.*]] = fir.convert %[[LOAD_B]] : (!fir.class>) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableApplyMold(%[[A_BOX_NONE]], %[[B_BOX_NONE]], %[[RANK]]) {{.*}} : (!fir.ref>, !fir.box, i32) -> none -! CHECK: %[[A_BOX_NONE:.*]] = fir.convert %[[A]] : (!fir.ref>>) -> !fir.ref> +! CHECK: %[[A_BOX_NONE:.*]] = fir.convert %[[A_DECL]]#1 : (!fir.ref>>) -> !fir.ref> ! CHECK: %[[B_BOX_NONE:.*]] = fir.convert %[[LOAD_B]] : (!fir.class>) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocateSource(%[[A_BOX_NONE]], %[[B_BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, !fir.box, i1, !fir.box, !fir.ref, i32) -> i32 @@ -517,22 +538,23 @@ subroutine test_allocatable_up_from_mold_rank(a) ! CHECK-LABEL: func.func @_QMpolyPtest_allocatable_up_from_mold_rank( ! CHECK-SAME: %[[A:.*]]: !fir.ref>>> {fir.bindc_name = "a"}) { -! CHECK: %[[VALUE_10:.*]] = fir.alloca i32 {adapt.valuebyref} +! CHECK: %[[VALUE_10:.*]] = fir.alloca i32 +! CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_allocatable_up_from_mold_rankEa"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: %[[C10:.*]] = arith.constant 10 : i32 ! CHECK: fir.store %[[C10]] to %[[VALUE_10]] : !fir.ref ! CHECK: %[[EMBOX_10:.*]] = fir.embox %[[VALUE_10]] : (!fir.ref) -> !fir.box ! CHECK: %[[RANK:.*]] = arith.constant 1 : i32 -! CHECK: %[[A_BOX_NONE:.*]] = fir.convert %[[A]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[A_BOX_NONE:.*]] = fir.convert %[[A_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[BOX_NONE_10:.*]] = fir.convert %[[EMBOX_10]] : (!fir.box) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableApplyMold(%[[A_BOX_NONE]], %[[BOX_NONE_10]], %[[RANK]]) {{.*}} : (!fir.ref>, !fir.box, i32) -> none ! CHECK: %[[C1:.*]] = arith.constant 1 : index ! CHECK: %[[C2:.*]] = arith.constant 20 : i32 ! CHECK: %[[C0:.*]] = arith.constant 0 : i32 -! CHECK: %[[A_BOX_NONE:.*]] = fir.convert %[[A]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[A_BOX_NONE:.*]] = fir.convert %[[A_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[C1_I64:.*]] = fir.convert %[[C1]] : (index) -> i64 ! CHECK: %[[C20_I64:.*]] = fir.convert %[[C20]] : (i32) -> i64 ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableSetBounds(%[[A_BOX_NONE]], %[[C0]], %[[C1_I64]], %[[C20_I64]]) {{.*}} : (!fir.ref>, i32, i64, i64) -> none -! CHECK: %[[A_BOX_NONE:.*]] = fir.convert %[[A]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[A_BOX_NONE:.*]] = fir.convert %[[A_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[BOX_NONE_10:.*]] = fir.convert %[[EMBOX_10]] : (!fir.box) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocateSource(%[[A_BOX_NONE]], %[[BOX_NONE_10]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, !fir.box, i1, !fir.box, !fir.ref, i32) -> i32 @@ -543,13 +565,14 @@ subroutine test_allocatable_up_character() ! CHECK-LABEL: func.func @_QMpolyPtest_allocatable_up_character() { ! CHECK: %[[A:.*]] = fir.alloca !fir.class> {bindc_name = "a", uniq_name = "_QMpolyFtest_allocatable_up_characterEa"} +! CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_allocatable_up_characterEa"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) ! CHECK: %[[LEN:.*]] = arith.constant 10 : i64 -! CHECK: %[[A_NONE:.*]] = fir.convert %[[A]] : (!fir.ref>>) -> !fir.ref> +! CHECK: %[[A_NONE:.*]] = fir.convert %[[A_DECL]]#1 : (!fir.ref>>) -> !fir.ref> ! CHECK: %[[KIND:.*]] = arith.constant 1 : i32 ! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 ! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableInitCharacterForAllocate(%[[A_NONE]], %[[LEN]], %[[KIND]], %[[RANK]], %[[CORANK]]) {{.*}} : (!fir.ref>, i64, i32, i32, i32) -> none -! CHECK: %[[A_NONE:.*]] = fir.convert %[[A:.*]] : (!fir.ref>>) -> !fir.ref> +! CHECK: %[[A_NONE:.*]] = fir.convert %[[A_DECL]]#1 : (!fir.ref>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[A_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 end module diff --git a/flang/test/Lower/dispatch.f90 b/flang/test/Lower/dispatch.f90 index 1658cc0d75add..1aad4a4b8e46f 100644 --- a/flang/test/Lower/dispatch.f90 +++ b/flang/test/Lower/dispatch.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -polymorphic-type -emit-fir -hlfir=false %s -o - | FileCheck %s +! RUN: bbc -polymorphic-type -emit-hlfir %s -o - | FileCheck %s ! Tests the different possible type involving polymorphic entities. @@ -49,6 +49,10 @@ subroutine nopass_defferred(x) type(node_ptr), pointer :: n end type + type :: q1 + class(p1), allocatable :: p + end type + contains ! ------------------------------------------------------------------------------ @@ -147,20 +151,21 @@ subroutine check_dispatch(p) ! CHECK-LABEL: func.func @_QMcall_dispatchPcheck_dispatch( ! CHECK-SAME: %[[P:.*]]: !fir.class> {fir.bindc_name = "p"}) { -! CHECK: fir.dispatch "tbp_nopass"(%[[P]] : !fir.class>){{$}} -! CHECK: fir.dispatch "tbp_pass"(%[[P]] : !fir.class>) (%[[P]] : !fir.class>) {pass_arg_pos = 0 : i32} -! CHECK: fir.dispatch "tbp_pass_arg0"(%[[P]] : !fir.class>) (%[[P]] : !fir.class>) {pass_arg_pos = 0 : i32} -! CHECK: fir.dispatch "tbp_pass_arg1"(%[[P]] : !fir.class>) (%{{.*}}, %[[P]] : !fir.ref, !fir.class>) {pass_arg_pos = 1 : i32} - -! CHECK: fir.dispatch "proc1"(%[[P]] : !fir.class>){{$}} -! CHECK: fir.dispatch "proc2"(%[[P]] : !fir.class>) (%[[P]] : !fir.class>) {pass_arg_pos = 0 : i32} -! CHECK: fir.dispatch "proc3"(%[[P]] : !fir.class>) (%[[P]] : !fir.class>) {pass_arg_pos = 0 : i32} -! CHECK: fir.dispatch "proc4"(%[[P]] : !fir.class>) (%{{.*}}, %[[P]] : !fir.ref, !fir.class>) {pass_arg_pos = 1 : i32} - -! CHECK: %{{.*}} = fir.dispatch "p1_fct1_nopass"(%[[P]] : !fir.class>) -> f32{{$}} -! CHECK: %{{.*}} = fir.dispatch "p1_fct2"(%[[P]] : !fir.class>) (%[[P]] : !fir.class>) -> f32 {pass_arg_pos = 0 : i32} -! CHECK: %{{.*}} = fir.dispatch "p1_fct3_arg0"(%[[P]] : !fir.class>) (%[[P]] : !fir.class>) -> f32 {pass_arg_pos = 0 : i32} -! CHECK: %{{.*}} = fir.dispatch "p1_fct4_arg1"(%[[P]] : !fir.class>) (%{{.*}}, %[[P]] : !fir.ref, !fir.class>) -> f32 {pass_arg_pos = 1 : i32} +! CHECK: %[[P_DECL:.*]]:2 = hlfir.declare %[[P]] {uniq_name = "_QMcall_dispatchFcheck_dispatchEp"} : (!fir.class>) -> (!fir.class>, !fir.class>) +! CHECK: fir.dispatch "tbp_nopass"(%[[P_DECL]]#1 : !fir.class>){{$}} +! CHECK: fir.dispatch "tbp_pass"(%[[P_DECL]]#0 : !fir.class>) (%[[P_DECL]]#0 : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: fir.dispatch "tbp_pass_arg0"(%[[P_DECL]]#0 : !fir.class>) (%[[P_DECL]]#0 : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: fir.dispatch "tbp_pass_arg1"(%[[P_DECL]]#0 : !fir.class>) (%{{.*}}, %[[P_DECL]]#0 : !fir.ref, !fir.class>) {pass_arg_pos = 1 : i32} + +! CHECK: fir.dispatch "proc1"(%[[P_DECL]]#1 : !fir.class>){{$}} +! CHECK: fir.dispatch "proc2"(%[[P_DECL]]#0 : !fir.class>) (%[[P_DECL]]#0 : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: fir.dispatch "proc3"(%[[P_DECL]]#0 : !fir.class>) (%[[P_DECL]]#0 : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: fir.dispatch "proc4"(%[[P_DECL]]#0 : !fir.class>) (%{{.*}}, %[[P_DECL]]#0 : !fir.ref, !fir.class>) {pass_arg_pos = 1 : i32} + +! CHECK: %{{.*}} = fir.dispatch "p1_fct1_nopass"(%[[P_DECL]]#1 : !fir.class>) -> f32{{$}} +! CHECK: %{{.*}} = fir.dispatch "p1_fct2"(%[[P_DECL]]#0 : !fir.class>) (%[[P_DECL]]#0 : !fir.class>) -> f32 {pass_arg_pos = 0 : i32} +! CHECK: %{{.*}} = fir.dispatch "p1_fct3_arg0"(%[[P_DECL]]#0 : !fir.class>) (%[[P_DECL]]#0 : !fir.class>) -> f32 {pass_arg_pos = 0 : i32} +! CHECK: %{{.*}} = fir.dispatch "p1_fct4_arg1"(%[[P_DECL]]#0 : !fir.class>) (%{{.*}}, %[[P_DECL]]#0 : !fir.ref, !fir.class>) -> f32 {pass_arg_pos = 1 : i32} subroutine check_dispatch_deferred(a, x) class(a1) :: a @@ -171,7 +176,9 @@ subroutine check_dispatch_deferred(a, x) ! CHECK-LABEL: func.func @_QMcall_dispatchPcheck_dispatch_deferred( ! CHECK-SAME: %[[ARG0:.*]]: !fir.class> {fir.bindc_name = "a"}, ! CHECK-SAME: %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "x"}) { -! CHECK: fir.dispatch "nopassd"(%[[ARG0]] : !fir.class>) (%[[ARG1]] : !fir.box>) +! CHECK: %[[ARG0_DECL:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QMcall_dispatchFcheck_dispatch_deferredEa"} : (!fir.class>) -> (!fir.class>, !fir.class>) +! CHECK: %[[ARG1_DECL:.*]]:2 = hlfir.declare %[[ARG1]] {uniq_name = "_QMcall_dispatchFcheck_dispatch_deferredEx"} : (!fir.box>) -> (!fir.box>, !fir.box>) +! CHECK: fir.dispatch "nopassd"(%[[ARG0_DECL]]#1 : !fir.class>) (%[[ARG1_DECL]]#0 : !fir.box>) subroutine check_dispatch_scalar_allocatable(p) class(p1), allocatable :: p @@ -180,9 +187,10 @@ subroutine check_dispatch_scalar_allocatable(p) ! 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: %[[ARG0_DECL:.*]]:2 = hlfir.declare %arg0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QMcall_dispatchFcheck_dispatch_scalar_allocatableEp"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0_DECL]]#0 : !fir.ref>>> ! CHECK: %[[REBOX:.*]] = fir.rebox %[[LOAD]] : (!fir.class>>) -> !fir.class> -! CHECK: fir.dispatch "tbp_pass"(%[[LOAD]] : !fir.class>>) (%1 : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: fir.dispatch "tbp_pass"(%[[REBOX]] : !fir.class>) (%[[REBOX]] : !fir.class>) {pass_arg_pos = 0 : i32} subroutine check_dispatch_scalar_pointer(p) class(p1), pointer :: p @@ -191,9 +199,10 @@ subroutine check_dispatch_scalar_pointer(p) ! 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: %[[ARG0_DECL:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMcall_dispatchFcheck_dispatch_scalar_pointerEp"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0_DECL]]#0 : !fir.ref>>> ! CHECK: %[[REBOX:.*]] = fir.rebox %[[LOAD]] : (!fir.class>>) -> !fir.class> -! CHECK: fir.dispatch "tbp_pass"(%[[LOAD]] : !fir.class>>) (%1 : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: fir.dispatch "tbp_pass"(%[[REBOX]] : !fir.class>) (%[[REBOX]] : !fir.class>) {pass_arg_pos = 0 : i32} subroutine check_dispatch_static_array(p, t) class(p1) :: p(10) @@ -211,15 +220,17 @@ subroutine check_dispatch_static_array(p, t) ! CHECK-LABEL: func.func @_QMcall_dispatchPcheck_dispatch_static_array( ! CHECK-SAME: %[[ARG0:.*]]: !fir.class>> {fir.bindc_name = "p"}, ! CHECK-SAME: %[[ARG1:.*]]: !fir.ref>> {fir.bindc_name = "t"}) { +! CHECK: %[[ARG0_DECL:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QMcall_dispatchFcheck_dispatch_static_arrayEp"} : (!fir.class>>) -> (!fir.class>>, !fir.class>>) +! CHECK: %[[ARG1_DECL:.*]]:2 = hlfir.declare %[[ARG1]](%{{.*}}) {uniq_name = "_QMcall_dispatchFcheck_dispatch_static_arrayEt"} : (!fir.ref>>, !fir.shape<1>) -> (!fir.ref>>, !fir.ref>>) ! CHECK: fir.do_loop {{.*}} { -! CHECK: %[[COORD:.*]] = fir.coordinate_of %[[ARG0]], %{{.*}} : (!fir.class>>, i64) -> !fir.ref> -! CHECK: %[[CLASS_BOX:.*]] = fir.embox %[[COORD]] source_box %[[ARG0]] : (!fir.ref>, !fir.class>>) -> !fir.class> -! CHECK: fir.dispatch "tbp_pass"(%[[CLASS_BOX]] : !fir.class>) (%[[CLASS_BOX]] : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[ARG0_DECL]]#0 (%{{.*}}) : (!fir.class>>, i64) -> !fir.class> +! CHECK: fir.dispatch "tbp_pass"(%[[DESIGNATE]] : !fir.class>) (%[[DESIGNATE]] : !fir.class>) {pass_arg_pos = 0 : i32} ! CHECK: fir.do_loop {{.*}} { -! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[ARG1]], %{{.*}} : (!fir.ref>>, i64) -> !fir.ref> -! CHECK: %[[EMBOX:.*]] = fir.embox %[[COORD]] : (!fir.ref>) -> !fir.class> -! CHECK: fir.call @_QMcall_dispatchPtbp_pass(%[[EMBOX]]) {{.*}}: (!fir.class>) -> () +! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[ARG1_DECL]]#0 (%{{.*}}) : (!fir.ref>>, i64) -> !fir.ref> +! CHECK: %[[EMBOX:.*]] = fir.embox %[[DESIGNATE]] : (!fir.ref>) -> !fir.box> +! CHECK: %[[CONV:.*]] = fir.convert %[[EMBOX]] : (!fir.box>) -> !fir.class> +! CHECK: fir.call @_QMcall_dispatchPtbp_pass(%[[CONV]]) {{.*}}: (!fir.class>) -> () subroutine check_dispatch_dynamic_array(p, t) class(p1) :: p(:) @@ -237,15 +248,17 @@ subroutine check_dispatch_dynamic_array(p, t) ! CHECK-LABEL: func.func @_QMcall_dispatchPcheck_dispatch_dynamic_array( ! CHECK-SAME: %[[ARG0:.*]]: !fir.class>> {fir.bindc_name = "p"}, ! CHECK-SAME: %[[ARG1:.*]]: !fir.box>> {fir.bindc_name = "t"}) { +! CHECK: %[[ARG0_DECL:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QMcall_dispatchFcheck_dispatch_dynamic_arrayEp"} : (!fir.class>>) -> (!fir.class>>, !fir.class>>) +! CHECK: %[[ARG1_DECL:.*]]:2 = hlfir.declare %[[ARG1]] {uniq_name = "_QMcall_dispatchFcheck_dispatch_dynamic_arrayEt"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) ! CHECK: %{{.*}} = fir.do_loop {{.*}} { -! CHECK: %[[COORD:.*]] = fir.coordinate_of %[[ARG0]], %{{.*}} : (!fir.class>>, i64) -> !fir.ref> -! CHECK: %[[CLASS_BOX:.*]] = fir.embox %[[COORD]] source_box %[[ARG0]] : (!fir.ref>, !fir.class>>) -> !fir.class> -! CHECK: fir.dispatch "tbp_pass"(%[[CLASS_BOX]] : !fir.class>) (%[[CLASS_BOX]] : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[ARG0_DECL]]#0 (%{{.*}}) : (!fir.class>>, i64) -> !fir.class> +! CHECK: fir.dispatch "tbp_pass"(%[[DESIGNATE]] : !fir.class>) (%[[DESIGNATE]] : !fir.class>) {pass_arg_pos = 0 : i32} ! CHECK: %{{.*}} = fir.do_loop {{.*}} { -! CHECK: %[[COORD:.*]] = fir.coordinate_of %[[ARG1]], %{{.*}} : (!fir.box>>, i64) -> !fir.ref> -! CHECK: %[[EMBOX:.*]] = fir.embox %[[COORD]] : (!fir.ref>) -> !fir.class> -! CHECK: fir.call @_QMcall_dispatchPtbp_pass(%[[EMBOX]]) {{.*}}: (!fir.class>) -> () +! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[ARG1_DECL]]#0 (%{{.*}}) : (!fir.box>>, i64) -> !fir.ref> +! CHECK: %[[EMBOX:.*]] = fir.embox %[[DESIGNATE]] : (!fir.ref>) -> !fir.box> +! CHECK: %[[CONV:.*]] = fir.convert %[[EMBOX]] : (!fir.box>) -> !fir.class> +! CHECK: fir.call @_QMcall_dispatchPtbp_pass(%[[CONV]]) {{.*}} : (!fir.class>) -> () subroutine check_dispatch_allocatable_array(p, t) class(p1), allocatable :: p(:) @@ -263,22 +276,19 @@ subroutine check_dispatch_allocatable_array(p, t) ! CHECK-LABEL: func.func @_QMcall_dispatchPcheck_dispatch_allocatable_array( ! CHECK-SAME: %[[ARG0:.*]]: !fir.ref>>>> {fir.bindc_name = "p"}, ! CHECK-SAME: %[[ARG1:.*]]: !fir.ref>>>> {fir.bindc_name = "t"}) { +! CHECK: %[[ARG0_DECL:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMcall_dispatchFcheck_dispatch_allocatable_arrayEp"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) +! CHECK: %[[ARG1_DECL:.*]]:2 = hlfir.declare %[[ARG1]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMcall_dispatchFcheck_dispatch_allocatable_arrayEt"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) ! CHECK: %{{.*}} = fir.do_loop {{.*}} { -! CHECK: fir.store %arg3 to %0 : !fir.ref -! CHECK: %[[LOAD_ARG0:.*]] = fir.load %[[ARG0]] : !fir.ref>>>> -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[BOX_DIMS_ARG0:.*]]:3 = fir.box_dims %[[LOAD_ARG0]], %[[C0]] : (!fir.class>>>, index) -> (index, index, index) -! CHECK: %[[COORD:.*]] = fir.coordinate_of %[[LOAD_ARG0]], %{{.*}} : (!fir.class>>>, i64) -> !fir.ref> -! CHECK: %[[CLASS_BOX:.*]] = fir.embox %[[COORD]] source_box %[[LOAD_ARG0]] : (!fir.ref>, !fir.class>>>) -> !fir.class> -! CHECK: fir.dispatch "tbp_pass"(%[[CLASS_BOX]] : !fir.class>) (%[[CLASS_BOX]] : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: %[[LOAD_ARG0:.*]] = fir.load %[[ARG0_DECL]]#0 : !fir.ref>>>> +! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[LOAD_ARG0]] (%{{.*}}) : (!fir.class>>>, i64) -> !fir.class> +! CHECK: fir.dispatch "tbp_pass"(%[[DESIGNATE]] : !fir.class>) (%[[DESIGNATE]] : !fir.class>) {pass_arg_pos = 0 : i32} ! CHECK: %{{.*}} = fir.do_loop {{.*}} { -! CHECK: %[[LOAD_ARG1:.*]] = fir.load %[[ARG1]] : !fir.ref>>>> -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[BOX_DIMS_ARG1:.*]]:3 = fir.box_dims %[[LOAD_ARG1]], %[[C0]] : (!fir.box>>>, index) -> (index, index, index) -! CHECK: %[[COORD:.*]] = fir.coordinate_of %[[LOAD_ARG1]], %{{.*}} : (!fir.box>>>, i64) -> !fir.ref> -! CHECK: %[[EMBOX:.*]] = fir.embox %[[COORD]] : (!fir.ref>) -> !fir.class> -! CHECK: fir.call @_QMcall_dispatchPtbp_pass(%[[EMBOX]]) {{.*}}: (!fir.class>) -> () +! CHECK: %[[LOAD_ARG1:.*]] = fir.load %[[ARG1_DECL]]#0 : !fir.ref>>>> +! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[LOAD_ARG1]] (%{{.*}}) : (!fir.box>>>, i64) -> !fir.ref> +! CHECK: %[[EMBOX:.*]] = fir.embox %[[DESIGNATE]] : (!fir.ref>) -> !fir.box> +! CHECK: %[[CONV:.*]] = fir.convert %[[EMBOX]] : (!fir.box>) -> !fir.class> +! CHECK: fir.call @_QMcall_dispatchPtbp_pass(%[[CONV]]) {{.*}}: (!fir.class>) -> () subroutine check_dispatch_pointer_array(p, t) class(p1), pointer :: p(:) @@ -296,22 +306,20 @@ subroutine check_dispatch_pointer_array(p, t) ! CHECK-LABEL: func.func @_QMcall_dispatchPcheck_dispatch_pointer_array( ! CHECK-SAME: %[[ARG0:.*]]: !fir.ref>>>> {fir.bindc_name = "p"}, ! CHECK-SAME: %[[ARG1:.*]]: !fir.ref>>>> {fir.bindc_name = "t"}) { +! CHECK: %[[ARG0_DECL:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMcall_dispatchFcheck_dispatch_pointer_arrayEp"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) +! CHECK: %[[ARG1_DECL:.*]]:2 = hlfir.declare %[[ARG1]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMcall_dispatchFcheck_dispatch_pointer_arrayEt"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) ! CHECK: %{{.*}} = fir.do_loop {{.*}} { -! CHECK: %[[LOAD_ARG0:.*]] = fir.load %[[ARG0]] : !fir.ref>>>> -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[BOX_DIMS_ARG0]]:3 = fir.box_dims %[[LOAD_ARG0]], %[[C0]] : (!fir.class>>>, index) -> (index, index, index) -! CHECK: %[[COORD:.*]] = fir.coordinate_of %[[LOAD_ARG0]], %{{.*}} : (!fir.class>>>, i64) -> !fir.ref> -! CHECK: %[[CLASS_BOX]] = fir.embox %[[COORD]] source_box %[[LOAD_ARG0]] : (!fir.ref>, !fir.class>>>) -> !fir.class> -! CHECK: fir.dispatch "tbp_pass"(%[[CLASS_BOX]] : !fir.class>) (%[[CLASS_BOX]] : !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: %[[LOAD_ARG0:.*]] = fir.load %[[ARG0_DECL]]#0 : !fir.ref>>>> +! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[LOAD_ARG0]] (%{{.*}}) : (!fir.class>>>, i64) -> !fir.class> +! CHECK: fir.dispatch "tbp_pass"(%[[DESIGNATE]] : !fir.class>) (%[[DESIGNATE]] : !fir.class>) {pass_arg_pos = 0 : i32} ! CHECK: %{{.*}} = fir.do_loop {{.*}} { -! CHECK: %[[LOAD_ARG1:.*]] = fir.load %[[ARG1]] : !fir.ref>>>> -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[BOX_DIMS_ARG1:.*]]:3 = fir.box_dims %[[LOAD_ARG1]], %[[C0]] : (!fir.box>>>, index) -> (index, index, index) -! CHECK: %[[COORD:.*]] = fir.coordinate_of %[[LOAD_ARG1]], %{{.*}} : (!fir.box>>>, i64) -> !fir.ref> -! CHECK: %[[EMBOX:.*]] = fir.embox %[[COORD]] : (!fir.ref>) -> !fir.class> -! CHECK: fir.call @_QMcall_dispatchPtbp_pass(%[[EMBOX]]) {{.*}}: (!fir.class>) -> () +! CHECK: %[[LOAD_ARG1:.*]] = fir.load %[[ARG1_DECL]]#0 : !fir.ref>>>> +! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[LOAD_ARG1]] (%{{.*}}) : (!fir.box>>>, i64) -> !fir.ref> +! CHECK: %[[EMBOX:.*]] = fir.embox %[[DESIGNATE]] : (!fir.ref>) -> !fir.box> +! CHECK: %[[CONV:.*]] = fir.convert %[[EMBOX]] : (!fir.box>) -> !fir.class> +! CHECK: fir.call @_QMcall_dispatchPtbp_pass(%[[CONV]]) fastmath : (!fir.class>) -> () subroutine check_dispatch_dynamic_array_copy(p, o) class(p1) :: p(:) @@ -326,12 +334,13 @@ subroutine check_dispatch_dynamic_array_copy(p, o) ! CHECK-LABEL: func.func @_QMcall_dispatchPcheck_dispatch_dynamic_array_copy( ! CHECK-SAME: %[[ARG0:.*]]: !fir.class>> {fir.bindc_name = "p"}, ! CHECK-SAME: %[[ARG1:.*]]: !fir.class>> {fir.bindc_name = "o"}) { +! CHECK: %[[ARG1_DECL:.*]]:2 = hlfir.declare %[[ARG1]] {uniq_name = "_QMcall_dispatchFcheck_dispatch_dynamic_array_copyEo"} : (!fir.class>>) -> (!fir.class>>, !fir.class>>) +! CHECK: %[[ARG0_DECL:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QMcall_dispatchFcheck_dispatch_dynamic_array_copyEp"} : (!fir.class>>) -> (!fir.class>>, !fir.class>>) + ! CHECK: %{{.*}} = fir.do_loop {{.*}} { -! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[ARG0]], %{{.*}} : (!fir.class>>, i64) -> !fir.ref> -! CHECK: %[[CLASS1:.*]] = fir.embox %[[COORD1]] source_box %[[ARG0]] : (!fir.ref>, !fir.class>>) -> !fir.class> -! CHECK: %[[COORD2:.*]] = fir.coordinate_of %[[ARG1]], %{{.*}} : (!fir.class>>, i64) -> !fir.ref> -! CHECK: %[[CLASS2:.*]] = fir.embox %[[COORD2]] source_box %[[ARG1]] : (!fir.ref>, !fir.class>>) -> !fir.class> -! CHECK: fir.dispatch "pass_with_class_arg"(%[[CLASS1]] : !fir.class>) (%[[CLASS1]], %[[CLASS2]] : !fir.class>, !fir.class>) {pass_arg_pos = 0 : i32} +! CHECK: %[[DESIGNATE0:.*]] = hlfir.designate %[[ARG0_DECL]]#0 (%{{.*}}) : (!fir.class>>, i64) -> !fir.class> +! CHECK: %[[DESIGNATE1:.*]] = hlfir.designate %[[ARG1_DECL]]#0 (%{{.*}}) : (!fir.class>>, i64) -> !fir.class> +! CHECK: fir.dispatch "pass_with_class_arg"(%[[DESIGNATE0]] : !fir.class>) (%[[DESIGNATE0]], %[[DESIGNATE1]] : !fir.class>, !fir.class>) {pass_arg_pos = 0 : i32} ! ------------------------------------------------------------------------------ ! Test that direct call is emitted when the type is known @@ -355,4 +364,15 @@ subroutine use_node_test(n) type(use_node) :: n end subroutine + + subroutine base_component() + type(q1) :: q + allocate(p1::q%p) + + call q%p%tbp_nopass() + end subroutine + +! CHECK-LABEL: func.func @_QMcall_dispatchPbase_component() +! CHECK: fir.dispatch "tbp_nopass"(%{{.*}} : !fir.class>>) + end module diff --git a/flang/test/Lower/nullify-polymorphic.f90 b/flang/test/Lower/nullify-polymorphic.f90 index 764aa29485783..005fe93b35435 100644 --- a/flang/test/Lower/nullify-polymorphic.f90 +++ b/flang/test/Lower/nullify-polymorphic.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -polymorphic-type -emit-fir -hlfir=false %s -o - | FileCheck %s +! RUN: bbc -polymorphic-type -emit-hlfir %s -o - | FileCheck %s module poly type p1 @@ -43,9 +43,10 @@ program test ! CHECK-LABEL: func.func @_QMpolyPtest_nullify() ! CHECK: %[[C_DESC:.*]] = fir.alloca !fir.class>> {bindc_name = "c", uniq_name = "_QMpolyFtest_nullifyEc"} +! CHECK: %[[C_DESC_DECL:.*]]:2 = hlfir.declare %28 {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_nullifyEc"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[DECLARED_TYPE_DESC:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C_DESC_CAST:.*]] = fir.convert %[[C_DESC]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[C_DESC_CAST:.*]] = fir.convert %[[C_DESC_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[TYPE_DESC_CAST:.*]] = fir.convert %[[DECLARED_TYPE_DESC]] : (!fir.tdesc>) -> !fir.ref ! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 ! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32