201 lines · plain
1! Test lowering of derived type assignments2! RUN: bbc -emit-hlfir -I nw %s -o - | FileCheck %s3 4! Assignment of simple "struct" with trivial intrinsic members.5subroutine test16 type t7 integer a8 integer b9 end type t10 type(t) :: t1, t211 t1 = t212end subroutine test113! CHECK-LABEL: func.func @_QPtest1() {14! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QFtest1Tt15! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest1Et1"} : (!fir.ref<!fir.type<_QFtest1Tt16! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.type<_QFtest1Tt17! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest1Et2"} : (!fir.ref<!fir.type<_QFtest1Tt18! CHECK: hlfir.assign %[[VAL_3]]#0 to %[[VAL_1]]#0 : !fir.ref<!fir.type<_QFtest1Tt19! CHECK: return20! CHECK: }21 22! Test a defined assignment on a simple struct.23module m224 type t25 integer a26 integer b27 end type t28 interface assignment (=)29 module procedure t_to_t30 end interface assignment (=)31contains32 subroutine test233 type(t) :: t1, t234 t1 = t235 end subroutine test236! CHECK-LABEL: func.func @_QMm2Ptest2() {37! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QMm2Tt38! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QMm2Ftest2Et1"} : (!fir.ref<!fir.type<_QMm2Tt39! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.type<_QMm2Tt40! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QMm2Ftest2Et2"} : (!fir.ref<!fir.type<_QMm2Tt41! CHECK: hlfir.region_assign {42! CHECK: hlfir.yield %[[VAL_3]]#0 : !fir.ref<!fir.type<_QMm2Tt43! CHECK: } to {44! CHECK: hlfir.yield %[[VAL_1]]#0 : !fir.ref<!fir.type<_QMm2Tt45! CHECK: } user_defined_assign (%[[VAL_4:.*]]: !fir.ref<!fir.type<_QMm2Tt{{.*}}) to (%[[VAL_5:.*]]: !fir.ref<!fir.type<_QMm2Tt46! CHECK: fir.call @_QMm2Pt_to_t(%[[VAL_5]], %[[VAL_4]]) fastmath<contract> : (!fir.ref<!fir.type<_QMm2Tt47! CHECK: }48! CHECK: return49! CHECK: }50 51 ! Swap elements on assignment.52 subroutine t_to_t(a1,b1)53 type(t), intent(out) :: a154 type(t), intent(in) :: b155 a1%a = b1%b56 a1%b = b1%a57 end subroutine t_to_t58! CHECK-LABEL: func.func @_QMm2Pt_to_t(59! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope60! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare {{.*}} dummy_scope %[[VAL_2]] arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<intent_out>, uniq_name = "_QMm2Ft_to_tEa1"} : (!fir.ref<!fir.type<_QMm2Tt61! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[VAL_2]] arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QMm2Ft_to_tEb1"} : (!fir.ref<!fir.type<_QMm2Tt62! CHECK: %[[VAL_5:.*]] = hlfir.designate %[[VAL_4]]#0{"b"} : (!fir.ref<!fir.type<_QMm2Tt63! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_5]] : !fir.ref<i32>64! CHECK: %[[VAL_7:.*]] = hlfir.designate %[[VAL_3]]#0{"a"} : (!fir.ref<!fir.type<_QMm2Tt65! CHECK: hlfir.assign %[[VAL_6]] to %[[VAL_7]] : i32, !fir.ref<i32>66! CHECK: %[[VAL_8:.*]] = hlfir.designate %[[VAL_4]]#0{"a"} : (!fir.ref<!fir.type<_QMm2Tt67! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_8]] : !fir.ref<i32>68! CHECK: %[[VAL_10:.*]] = hlfir.designate %[[VAL_3]]#0{"b"} : (!fir.ref<!fir.type<_QMm2Tt69! CHECK: hlfir.assign %[[VAL_9]] to %[[VAL_10]] : i32, !fir.ref<i32>70! CHECK: return71! CHECK: }72end module m273 74subroutine test375 type t76 character(LEN=20) :: m_c77 integer :: m_i78 end type t79 type(t) :: t1, t280 t1 = t281end subroutine test382! CHECK-LABEL: func.func @_QPtest3() {83! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QFtest3Tt84! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest3Et1"} : (!fir.ref<!fir.type<_QFtest3Tt85! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.type<_QFtest3Tt86! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest3Et2"} : (!fir.ref<!fir.type<_QFtest3Tt87! CHECK: hlfir.assign %[[VAL_3]]#0 to %[[VAL_1]]#0 : !fir.ref<!fir.type<_QFtest3Tt88! CHECK: return89! CHECK: }90 91subroutine test_array_comp(t1, t2)92 type t93 real :: m_x(10)94 integer :: m_i95 end type t96 type(t) :: t1, t297 98 t1 = t299end subroutine100! CHECK-LABEL: func.func @_QPtest_array_comp(101! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope102! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[VAL_2]] arg {{[0-9]+}} {uniq_name = "_QFtest_array_compEt1"} : (!fir.ref<!fir.type<_QFtest_array_compTt103! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[VAL_2]] arg {{[0-9]+}} {uniq_name = "_QFtest_array_compEt2"} : (!fir.ref<!fir.type<_QFtest_array_compTt104! CHECK: hlfir.assign %[[VAL_4]]#0 to %[[VAL_3]]#0 : !fir.ref<!fir.type<_QFtest_array_compTt105! CHECK: return106! CHECK: }107 108subroutine test_ptr_comp(t1, t2)109 type t110 complex, pointer :: ptr(:)111 integer :: m_i112 end type t113 type(t) :: t1, t2114 115 t1 = t2116end subroutine117! CHECK-LABEL: func.func @_QPtest_ptr_comp(118! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope119! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[VAL_2]] arg {{[0-9]+}} {uniq_name = "_QFtest_ptr_compEt1"} : (!fir.ref<!fir.type<_QFtest_ptr_compTt120! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[VAL_2]] arg {{[0-9]+}} {uniq_name = "_QFtest_ptr_compEt2"} : (!fir.ref<!fir.type<_QFtest_ptr_compTt121! CHECK: hlfir.assign %[[VAL_4]]#0 to %[[VAL_3]]#0 : !fir.ref<!fir.type<_QFtest_ptr_compTt122! CHECK: return123! CHECK: }124 125subroutine test_box_assign(t1, t2)126 type t127 integer :: i128 end type t129 ! Note: the implementation of this case is not optimal, the runtime call is overkill, but right now130 ! lowering is conservative with derived type pointers because it does not make a difference between the131 ! polymorphic and non polymorphic ones at the FIR level.132 type(t), pointer :: t1, t2133 t1 = t2134end subroutine135! CHECK-LABEL: func.func @_QPtest_box_assign(136! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope137! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[VAL_2]] arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_box_assignEt1"} : (!fir.ref<!fir.box<!fir.ptr<!fir.type<_QFtest_box_assignTt138! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[VAL_2]] arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_box_assignEt2"} : (!fir.ref<!fir.box<!fir.ptr<!fir.type<_QFtest_box_assignTt139! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QFtest_box_assignTt140! CHECK: %[[VAL_6:.*]] = fir.box_addr %[[VAL_5]] : (!fir.box<!fir.ptr<!fir.type<_QFtest_box_assignTt141! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QFtest_box_assignTt142! CHECK: %[[VAL_8:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box<!fir.ptr<!fir.type<_QFtest_box_assignTt143! CHECK: hlfir.assign %[[VAL_6]] to %[[VAL_8]] : !fir.ptr<!fir.type<_QFtest_box_assignTt144! CHECK: return145! CHECK: }146 147subroutine test_alloc_comp(t1, t2)148! Test that derived type assignment with allocatable components are using the149! runtime to handle the deep copy.150 type t151 real, allocatable :: x(:, :)152 integer :: i153 end type154 type(t) :: t1, t2155 t1 = t2156end subroutine157! CHECK-LABEL: func.func @_QPtest_alloc_comp(158! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope159! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[VAL_2]] arg {{[0-9]+}} {uniq_name = "_QFtest_alloc_compEt1"} : (!fir.ref<!fir.type<_QFtest_alloc_compTt160! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[VAL_2]] arg {{[0-9]+}} {uniq_name = "_QFtest_alloc_compEt2"} : (!fir.ref<!fir.type<_QFtest_alloc_compTt161! CHECK: hlfir.assign %[[VAL_4]]#0 to %[[VAL_3]]#0 : !fir.ref<!fir.type<_QFtest_alloc_compTt162! CHECK: return163! CHECK: }164 165module component_with_user_def_assign166 type t0167 integer :: i168 integer :: j169 contains170 procedure :: user_def171 generic :: assignment(=) => user_def172 end type173 interface174 subroutine user_def(other, self)175 import t0176 class(t0), intent(out) :: other177 class(t0), intent(in) :: self178 end subroutine179 end interface180 181 ! Assignments of type(t) must call the user defined assignment for component a.182 ! Currently this is delegated to the runtime.183 type t184 type(t0) :: a185 integer :: i186 end type187 188contains189 subroutine test(t1, t2)190 type(t) :: t1, t2191 t1 = t2192 end subroutine193! CHECK-LABEL: func.func @_QMcomponent_with_user_def_assignPtest(194! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope195! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[VAL_2]] arg {{[0-9]+}} {uniq_name = "_QMcomponent_with_user_def_assignFtestEt1"} : (!fir.ref<!fir.type<_QMcomponent_with_user_def_assignTt196! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[VAL_2]] arg {{[0-9]+}} {uniq_name = "_QMcomponent_with_user_def_assignFtestEt2"} : (!fir.ref<!fir.type<_QMcomponent_with_user_def_assignTt197! CHECK: hlfir.assign %[[VAL_4]]#0 to %[[VAL_3]]#0 : !fir.ref<!fir.type<_QMcomponent_with_user_def_assignTt198! CHECK: return199! CHECK: }200end module201