435 lines · plain
1! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s2 3module callee4implicit none5contains6! CHECK-LABEL: func @_QMcalleePreturn_cst_array() -> !fir.array<20x30xf32>7function return_cst_array()8 real :: return_cst_array(20, 30)9end function10 11! CHECK-LABEL: func @_QMcalleePreturn_dyn_array(12! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}, %{{.*}}: !fir.ref<i32>{{.*}}) -> !fir.array<?x?xf32>13function return_dyn_array(m, n)14 integer :: m, n15 real :: return_dyn_array(m, n)16end function17 18! CHECK-LABEL: func @_QMcalleePreturn_cst_char_cst_array() -> !fir.array<20x30x!fir.char<1,10>>19function return_cst_char_cst_array()20 character(10) :: return_cst_char_cst_array(20, 30)21end function22 23! CHECK-LABEL: func @_QMcalleePreturn_dyn_char_cst_array(24! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}) -> !fir.array<20x30x!fir.char<1,?>>25function return_dyn_char_cst_array(l)26 integer :: l27 character(l) :: return_dyn_char_cst_array(20, 30)28end function29 30! CHECK-LABEL: func @_QMcalleePreturn_cst_char_dyn_array(31! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}, %{{.*}}: !fir.ref<i32>{{.*}}) -> !fir.array<?x?x!fir.char<1,10>>32function return_cst_char_dyn_array(m, n)33 integer :: m, n34 character(10) :: return_cst_char_dyn_array(m, n)35end function36 37! CHECK-LABEL: func @_QMcalleePreturn_dyn_char_dyn_array(38! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}, %{{.*}}: !fir.ref<i32>{{.*}}, %{{.*}}: !fir.ref<i32>{{.*}}) -> !fir.array<?x?x!fir.char<1,?>>39function return_dyn_char_dyn_array(l, m, n)40 integer :: l, m, n41 character(l) :: return_dyn_char_dyn_array(m, n)42end function43 44! CHECK-LABEL: func @_QMcalleePreturn_alloc() -> !fir.box<!fir.heap<!fir.array<?xf32>>>45function return_alloc()46 real, allocatable :: return_alloc(:)47end function48 49! CHECK-LABEL: func @_QMcalleePreturn_cst_char_alloc() -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>50function return_cst_char_alloc()51 character(10), allocatable :: return_cst_char_alloc(:)52end function53 54! CHECK-LABEL: func @_QMcalleePreturn_dyn_char_alloc(55! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}) -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>56function return_dyn_char_alloc(l)57 integer :: l58 character(l), allocatable :: return_dyn_char_alloc(:)59end function60 61! CHECK-LABEL: func @_QMcalleePreturn_def_char_alloc() -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>62function return_def_char_alloc()63 character(:), allocatable :: return_def_char_alloc(:)64end function65 66! CHECK-LABEL: func @_QMcalleePreturn_pointer() -> !fir.box<!fir.ptr<!fir.array<?xf32>>>67function return_pointer()68 real, pointer :: return_pointer(:)69end function70 71! CHECK-LABEL: func @_QMcalleePreturn_cst_char_pointer() -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>72function return_cst_char_pointer()73 character(10), pointer :: return_cst_char_pointer(:)74end function75 76! CHECK-LABEL: func @_QMcalleePreturn_dyn_char_pointer(77! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}) -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>78function return_dyn_char_pointer(l)79 integer :: l80 character(l), pointer :: return_dyn_char_pointer(:)81end function82 83! CHECK-LABEL: func @_QMcalleePreturn_def_char_pointer() -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>84function return_def_char_pointer()85 character(:), pointer :: return_def_char_pointer(:)86end function87end module88 89module caller90 use callee91contains92 93! CHECK-LABEL: func @_QMcallerPcst_array()94subroutine cst_array()95 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.array<20x30xf32> {{{.*}}bindc_name = ".result"}96 ! CHECK: %[[shape:.*]] = fir.shape %{{.*}}, {{.*}} : (index, index) -> !fir.shape<2>97 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_cst_array() {{.*}}: () -> !fir.array<20x30xf32>98 ! CHECK: fir.save_result %[[res]] to %[[alloc]](%[[shape]]) : !fir.array<20x30xf32>, !fir.ref<!fir.array<20x30xf32>>, !fir.shape<2>99 print *, return_cst_array()100end subroutine101 102! CHECK-LABEL: func @_QMcallerPcst_char_cst_array()103subroutine cst_char_cst_array()104 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.array<20x30x!fir.char<1,10>> {{{.*}}bindc_name = ".result"}105 ! CHECK: %[[shape:.*]] = fir.shape %{{.*}}, {{.*}} : (index, index) -> !fir.shape<2>106 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_cst_char_cst_array() {{.*}}: () -> !fir.array<20x30x!fir.char<1,10>>107 ! CHECK: fir.save_result %[[res]] to %[[alloc]](%[[shape]]) typeparams %{{.*}} : !fir.array<20x30x!fir.char<1,10>>, !fir.ref<!fir.array<20x30x!fir.char<1,10>>>, !fir.shape<2>, index108 print *, return_cst_char_cst_array()109end subroutine110 111! CHECK-LABEL: func @_QMcallerPalloc()112subroutine alloc()113 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {{{.*}}bindc_name = ".result"}114 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_alloc() {{.*}}: () -> !fir.box<!fir.heap<!fir.array<?xf32>>>115 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.heap<!fir.array<?xf32>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>116 print *, return_alloc()117 ! CHECK: _FortranAioOutputDescriptor118 ! CHECK: %[[load:.*]] = fir.load %[[alloc]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>119 ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>120 ! CHECK: %[[cmpi:.*]] = arith.cmpi121 ! CHECK: fir.if %[[cmpi]]122 ! CHECK: fir.freemem %[[addr]] : !fir.heap<!fir.array<?xf32>>123end subroutine124 125! CHECK-LABEL: func @_QMcallerPcst_char_alloc()126subroutine cst_char_alloc()127 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>> {{{.*}}bindc_name = ".result"}128 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_cst_char_alloc() {{.*}}: () -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>129 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>>130 print *, return_cst_char_alloc()131 ! CHECK: _FortranAioOutputDescriptor132 ! CHECK: %[[load:.*]] = fir.load %[[alloc]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>>133 ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>) -> !fir.heap<!fir.array<?x!fir.char<1,10>>>134 ! CHECK: %[[cmpi:.*]] = arith.cmpi135 ! CHECK: fir.if %[[cmpi]]136 ! CHECK: fir.freemem %[[addr]] : !fir.heap<!fir.array<?x!fir.char<1,10>>>137end subroutine138 139! CHECK-LABEL: func @_QMcallerPdef_char_alloc()140subroutine def_char_alloc()141 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>> {{{.*}}bindc_name = ".result"}142 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_def_char_alloc() {{.*}}: () -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>143 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>144 print *, return_def_char_alloc()145 ! CHECK: _FortranAioOutputDescriptor146 ! CHECK: %[[load:.*]] = fir.load %[[alloc]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>147 ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>) -> !fir.heap<!fir.array<?x!fir.char<1,?>>>148 ! CHECK: %[[cmpi:.*]] = arith.cmpi149 ! CHECK: fir.if %[[cmpi]]150 ! CHECK: fir.freemem %[[addr]] : !fir.heap<!fir.array<?x!fir.char<1,?>>>151end subroutine152 153! CHECK-LABEL: func @_QMcallerPpointer_test()154subroutine pointer_test()155 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xf32>>> {{{.*}}bindc_name = ".result"}156 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_pointer() {{.*}}: () -> !fir.box<!fir.ptr<!fir.array<?xf32>>>157 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>158 print *, return_pointer()159 ! CHECK-NOT: fir.freemem160end subroutine161 162! CHECK-LABEL: func @_QMcallerPcst_char_pointer()163subroutine cst_char_pointer()164 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>> {{{.*}}bindc_name = ".result"}165 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_cst_char_pointer() {{.*}}: () -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>166 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>>167 print *, return_cst_char_pointer()168 ! CHECK-NOT: fir.freemem169end subroutine170 171! CHECK-LABEL: func @_QMcallerPdef_char_pointer()172subroutine def_char_pointer()173 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>> {{{.*}}bindc_name = ".result"}174 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_def_char_pointer() {{.*}}: () -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>175 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>176 print *, return_def_char_pointer()177 ! CHECK-NOT: fir.freemem178end subroutine179 180! CHECK-LABEL: func @_QMcallerPdyn_array(181! CHECK-SAME: %[[m:.*]]: !fir.ref<i32>{{.*}}, %[[n:.*]]: !fir.ref<i32>{{.*}}) {182subroutine dyn_array(m, n)183 integer :: m, n184 ! CHECK-DAG: %[[mload:.*]] = fir.load %[[m]] : !fir.ref<i32>185 ! CHECK-DAG: %[[mcast:.*]] = fir.convert %[[mload]] : (i32) -> i64186 ! CHECK-DAG: %[[msub:.*]] = arith.subi %[[mcast]], %c1{{.*}} : i64187 ! CHECK-DAG: %[[madd:.*]] = arith.addi %[[msub]], %c1{{.*}} : i64188 ! CHECK-DAG: %[[mcast2:.*]] = fir.convert %[[madd]] : (i64) -> index189 ! CHECK-DAG: %[[mcmpi:.*]] = arith.cmpi sgt, %[[mcast2]], %{{.*}} : index190 ! CHECK-DAG: %[[mselect:.*]] = arith.select %[[mcmpi]], %[[mcast2]], %{{.*}} : index191 ! CHECK-DAG: %[[nload:.*]] = fir.load %[[n]] : !fir.ref<i32>192 ! CHECK-DAG: %[[ncast:.*]] = fir.convert %[[nload]] : (i32) -> i64193 ! CHECK-DAG: %[[nsub:.*]] = arith.subi %[[ncast]], %c1{{.*}} : i64194 ! CHECK-DAG: %[[nadd:.*]] = arith.addi %[[nsub]], %c1{{.*}} : i64195 ! CHECK-DAG: %[[ncast2:.*]] = fir.convert %[[nadd]] : (i64) -> index196 ! CHECK-DAG: %[[ncmpi:.*]] = arith.cmpi sgt, %[[ncast2]], %{{.*}} : index197 ! CHECK-DAG: %[[nselect:.*]] = arith.select %[[ncmpi]], %[[ncast2]], %{{.*}} : index198 ! CHECK: %[[shape:.*]] = fir.shape %[[mselect]], %[[nselect]] : (index, index) -> !fir.shape<2>199 ! CHECK: %[[tmp:.*]] = fir.alloca !fir.array<?x?xf32>, %[[mselect]], %[[nselect]]200 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_dyn_array(%[[m]], %[[n]]) {{.*}}: (!fir.ref<i32>, !fir.ref<i32>) -> !fir.array<?x?xf32>201 ! CHECK: fir.save_result %[[res]] to %[[tmp]](%[[shape]]) : !fir.array<?x?xf32>, !fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>202 print *, return_dyn_array(m, n)203end subroutine204 205! CHECK-LABEL: func @_QMcallerPdyn_char_cst_array(206! CHECK-SAME: %[[l:.*]]: !fir.ref<i32>{{.*}}) {207subroutine dyn_char_cst_array(l)208 integer :: l209 ! CHECK: %[[lload:.*]] = fir.load %[[l]] : !fir.ref<i32>210 ! CHECK: %[[lcast:.*]] = fir.convert %[[lload]] : (i32) -> i64211 ! CHECK: %[[lcast2:.*]] = fir.convert %[[lcast]] : (i64) -> index212 ! CHECK: %[[cmpi:.*]] = arith.cmpi sgt, %[[lcast2]], %{{.*}} : index213 ! CHECK: %[[select:.*]] = arith.select %[[cmpi]], %[[lcast2]], %{{.*}} : index214 ! CHECK: %[[shape:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>215 ! CHECK: %[[tmp:.*]] = fir.alloca !fir.array<20x30x!fir.char<1,?>>(%[[select]] : index)216 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_dyn_char_cst_array(%[[l]]) {{.*}}: (!fir.ref<i32>) -> !fir.array<20x30x!fir.char<1,?>>217 ! CHECK: fir.save_result %[[res]] to %[[tmp]](%[[shape]]) typeparams %[[select]] : !fir.array<20x30x!fir.char<1,?>>, !fir.ref<!fir.array<20x30x!fir.char<1,?>>>, !fir.shape<2>, index218 print *, return_dyn_char_cst_array(l)219end subroutine220 221! CHECK-LABEL: func @_QMcallerPcst_char_dyn_array(222! CHECK-SAME: %[[m:.*]]: !fir.ref<i32>{{.*}}, %[[n:.*]]: !fir.ref<i32>{{.*}}) {223subroutine cst_char_dyn_array(m, n)224 integer :: m, n225 ! CHECK-DAG: %[[mload:.*]] = fir.load %[[m]] : !fir.ref<i32>226 ! CHECK-DAG: %[[mcast:.*]] = fir.convert %[[mload]] : (i32) -> i64227 ! CHECK-DAG: %[[msub:.*]] = arith.subi %[[mcast]], %c1{{.*}} : i64228 ! CHECK-DAG: %[[madd:.*]] = arith.addi %[[msub]], %c1{{.*}} : i64229 ! CHECK-DAG: %[[mcast2:.*]] = fir.convert %[[madd]] : (i64) -> index230 ! CHECK-DAG: %[[mcmpi:.*]] = arith.cmpi sgt, %[[mcast2]], %{{.*}} : index231 ! CHECK-DAG: %[[mselect:.*]] = arith.select %[[mcmpi]], %[[mcast2]], %{{.*}} : index232 ! CHECK-DAG: %[[nload:.*]] = fir.load %[[n]] : !fir.ref<i32>233 ! CHECK-DAG: %[[ncast:.*]] = fir.convert %[[nload]] : (i32) -> i64234 ! CHECK-DAG: %[[nsub:.*]] = arith.subi %[[ncast]], %c1{{.*}} : i64235 ! CHECK-DAG: %[[nadd:.*]] = arith.addi %[[nsub]], %c1{{.*}} : i64236 ! CHECK-DAG: %[[ncast2:.*]] = fir.convert %[[nadd]] : (i64) -> index237 ! CHECK-DAG: %[[ncmpi:.*]] = arith.cmpi sgt, %[[ncast2]], %{{.*}} : index238 ! CHECK-DAG: %[[nselect:.*]] = arith.select %[[ncmpi]], %[[ncast2]], %{{.*}} : index239 ! CHECK: %[[shape:.*]] = fir.shape %[[mselect]], %[[nselect]] : (index, index) -> !fir.shape<2>240 ! CHECK: %[[tmp:.*]] = fir.alloca !fir.array<?x?x!fir.char<1,10>>, %[[mselect]], %[[nselect]]241 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_cst_char_dyn_array(%[[m]], %[[n]]) {{.*}}: (!fir.ref<i32>, !fir.ref<i32>) -> !fir.array<?x?x!fir.char<1,10>>242 ! CHECK: fir.save_result %[[res]] to %[[tmp]](%[[shape]]) typeparams {{.*}} : !fir.array<?x?x!fir.char<1,10>>, !fir.ref<!fir.array<?x?x!fir.char<1,10>>>, !fir.shape<2>, index243 print *, return_cst_char_dyn_array(m, n)244end subroutine245 246! CHECK-LABEL: func @_QMcallerPdyn_char_dyn_array(247! CHECK-SAME: %[[l:.*]]: !fir.ref<i32>{{.*}}, %[[m:.*]]: !fir.ref<i32>{{.*}}, %[[n:.*]]: !fir.ref<i32>{{.*}}) {248subroutine dyn_char_dyn_array(l, m, n)249 ! CHECK-DAG: %[[mload:.*]] = fir.load %[[m]] : !fir.ref<i32>250 ! CHECK-DAG: %[[mcast:.*]] = fir.convert %[[mload]] : (i32) -> i64251 ! CHECK-DAG: %[[msub:.*]] = arith.subi %[[mcast]], %c1{{.*}} : i64252 ! CHECK-DAG: %[[madd:.*]] = arith.addi %[[msub]], %c1{{.*}} : i64253 ! CHECK-DAG: %[[mcast2:.*]] = fir.convert %[[madd]] : (i64) -> index254 ! CHECK-DAG: %[[mcmpi:.*]] = arith.cmpi sgt, %[[mcast2]], %{{.*}} : index255 ! CHECK-DAG: %[[mselect:.*]] = arith.select %[[mcmpi]], %[[mcast2]], %{{.*}} : index256 257 ! CHECK-DAG: %[[nload:.*]] = fir.load %[[n]] : !fir.ref<i32>258 ! CHECK-DAG: %[[ncast:.*]] = fir.convert %[[nload]] : (i32) -> i64259 ! CHECK-DAG: %[[nsub:.*]] = arith.subi %[[ncast]], %c1{{.*}} : i64260 ! CHECK-DAG: %[[nadd:.*]] = arith.addi %[[nsub]], %c1{{.*}} : i64261 ! CHECK-DAG: %[[ncast2:.*]] = fir.convert %[[nadd]] : (i64) -> index262 ! CHECK-DAG: %[[ncmpi:.*]] = arith.cmpi sgt, %[[ncast2]], %{{.*}} : index263 ! CHECK-DAG: %[[nselect:.*]] = arith.select %[[ncmpi]], %[[ncast2]], %{{.*}} : index264 265 ! CHECK-DAG: %[[lload:.*]] = fir.load %[[l]] : !fir.ref<i32>266 ! CHECK-DAG: %[[lcast:.*]] = fir.convert %[[lload]] : (i32) -> i64267 ! CHECK-DAG: %[[lcast2:.*]] = fir.convert %[[lcast]] : (i64) -> index268 ! CHECK-DAG: %[[lcmpi:.*]] = arith.cmpi sgt, %[[lcast2]], %{{.*}} : index269 ! CHECK-DAG: %[[lselect:.*]] = arith.select %[[lcmpi]], %[[lcast2]], %{{.*}} : index270 ! CHECK: %[[shape:.*]] = fir.shape %[[mselect]], %[[nselect]] : (index, index) -> !fir.shape<2>271 ! CHECK: %[[tmp:.*]] = fir.alloca !fir.array<?x?x!fir.char<1,?>>(%[[lselect]] : index), %[[mselect]], %[[nselect]]272 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_dyn_char_dyn_array(%[[l]], %[[m]], %[[n]]) {{.*}}: (!fir.ref<i32>, !fir.ref<i32>, !fir.ref<i32>) -> !fir.array<?x?x!fir.char<1,?>>273 ! CHECK: fir.save_result %[[res]] to %[[tmp]](%[[shape]]) typeparams {{.*}} : !fir.array<?x?x!fir.char<1,?>>, !fir.ref<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, index274 integer :: l, m, n275 print *, return_dyn_char_dyn_array(l, m, n)276end subroutine277 278! CHECK-LABEL: @_QMcallerPdyn_char_alloc279subroutine dyn_char_alloc(l)280 integer :: l281 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>> {{{.*}}bindc_name = ".result"}282 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_dyn_char_alloc({{.*}}) {{.*}}: (!fir.ref<i32>) -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>283 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>284 print *, return_dyn_char_alloc(l)285 ! CHECK: _FortranAioOutputDescriptor286 ! CHECK: %[[load:.*]] = fir.load %[[alloc]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>287 ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>) -> !fir.heap<!fir.array<?x!fir.char<1,?>>>288 ! CHECK: %[[cmpi:.*]] = arith.cmpi289 ! CHECK: fir.if %[[cmpi]]290 ! CHECK: fir.freemem %[[addr]] : !fir.heap<!fir.array<?x!fir.char<1,?>>>291end subroutine292 293! CHECK-LABEL: @_QMcallerPdyn_char_pointer294subroutine dyn_char_pointer(l)295 integer :: l296 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>> {{{.*}}bindc_name = ".result"}297 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_dyn_char_pointer({{.*}}) {{.*}}: (!fir.ref<i32>) -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>298 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>299 print *, return_dyn_char_pointer(l)300 ! CHECK-NOT: fir.freemem301end subroutine302 303end module304 305 306! Test more complex symbol dependencies in the result specification expression307 308module m_with_equiv309 integer(8) :: l310 integer(8) :: array(3)311 equivalence (array(2), l)312contains313 function result_depends_on_equiv_sym()314 character(l) :: result_depends_on_equiv_sym315 call set_result_with_some_value(result_depends_on_equiv_sym)316 end function317end module318 319! CHECK-LABEL: func @_QPtest_result_depends_on_equiv_sym320subroutine test_result_depends_on_equiv_sym()321 use m_with_equiv, only : result_depends_on_equiv_sym322 ! CHECK: %[[equiv:.*]] = fir.address_of(@_QMm_with_equivEarray) : !fir.ref<!fir.array<24xi8>>323 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[equiv]], %c{{.*}} : (!fir.ref<!fir.array<24xi8>>, index) -> !fir.ref<i8>324 ! CHECK: %[[l:.*]] = fir.convert %[[coor]] : (!fir.ref<i8>) -> !fir.ptr<i64>325 ! CHECK: %[[load:.*]] = fir.load %[[l]] : !fir.ptr<i64>326 ! CHECK: %[[lcast:.*]] = fir.convert %[[load]] : (i64) -> index327 ! CHECK: %[[cmpi:.*]] = arith.cmpi sgt, %[[lcast]], %{{.*}} : index328 ! CHECK: %[[select:.*]] = arith.select %[[cmpi]], %[[lcast]], %{{.*}} : index329 ! CHECK: fir.alloca !fir.char<1,?>(%[[select]] : index)330 print *, result_depends_on_equiv_sym()331end subroutine332 333! CHECK-LABEL: func @_QPtest_depends_on_descriptor(334! CHECK-SAME: %[[x:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {335subroutine test_depends_on_descriptor(x)336 interface337 function depends_on_descriptor(x)338 real :: x(:)339 character(size(x,1, KIND=8)) :: depends_on_descriptor340 end function341 end interface342 real :: x(:)343 ! CHECK: %[[dims:.*]]:3 = fir.box_dims %arg0, %c0 : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)344 ! CHECK: %[[extentCast:.*]] = fir.convert %[[dims]]#1 : (index) -> i64345 ! CHECK: %[[extent:.*]] = fir.convert %[[extentCast]] : (i64) -> index346 ! CHECK: %[[cmpi:.*]] = arith.cmpi sgt, %[[extent]], %{{.*}} : index347 ! CHECK: %[[select:.*]] = arith.select %[[cmpi]], %[[extent]], %{{.*}} : index348 ! CHECK: fir.alloca !fir.char<1,?>(%[[select]] : index)349 print *, depends_on_descriptor(x)350end subroutine351 352! CHECK-LABEL: func @_QPtest_symbol_indirection(353! CHECK-SAME: %[[n:.*]]: !fir.ref<i64>{{.*}}) {354subroutine test_symbol_indirection(n)355 interface356 function symbol_indirection(c, n)357 integer(8) :: n358 character(n) :: c359 character(len(c, KIND=8)) :: symbol_indirection360 end function361 end interface362 integer(8) :: n363 character(n) :: c364 ! CHECK: BeginExternalListOutput365 ! CHECK: %[[nload:.*]] = fir.load %[[n]] : !fir.ref<i64>366 ! CHECK: %[[n_is_positive:.*]] = arith.cmpi sgt, %[[nload]], %c0{{.*}} : i64367 ! CHECK: %[[len:.*]] = arith.select %[[n_is_positive]], %[[nload]], %c0{{.*}} : i64368 ! CHECK: %[[len_cast:.*]] = fir.convert %[[len]] : (i64) -> index369 ! CHECK: %[[cmpi:.*]] = arith.cmpi sgt, %[[len_cast]], %{{.*}} : index370 ! CHECK: %[[select:.*]] = arith.select %[[cmpi]], %[[len_cast]], %{{.*}} : index371 ! CHECK: fir.alloca !fir.char<1,?>(%[[select]] : index)372 print *, symbol_indirection(c, n)373end subroutine374 375! CHECK-LABEL: func @_QPtest_recursion(376! CHECK-SAME: %[[res:.*]]: !fir.ref<!fir.char<1,?>>{{.*}}, %[[resLen:.*]]: index{{.*}}, %[[n:.*]]: !fir.ref<i64>{{.*}}) -> !fir.boxchar<1> {377function test_recursion(n) result(res)378 integer(8) :: n379 character(n) :: res380 ! some_local is here to verify that local symbols that are visible in the381 ! function interface are not instantiated by accident (that only the382 ! symbols needed for the result are instantiated before the call).383 ! CHECK: fir.alloca !fir.array<?xi32>, {{.*}}some_local384 ! CHECK-NOT: fir.alloca !fir.array<?xi32>385 integer :: some_local(n)386 some_local(1) = n + 64387 if (n.eq.1) then388 res = char(some_local(1))389 ! CHECK: else390 else391 ! CHECK-NOT: fir.alloca !fir.array<?xi32>392 393 ! verify that the actual argument for symbol n ("n-1") is used to allocate394 ! the result, and not the local value of symbol n.395 396 ! CHECK: %[[nLoad:.*]] = fir.load %[[n]] : !fir.ref<i64>397 ! CHECK: %[[sub:.*]] = arith.subi %[[nLoad]], %c1{{.*}} : i64398 ! CHECK: fir.store %[[sub]] to %[[nInCall:.*]] : !fir.ref<i64>399 400 ! CHECK-NOT: fir.alloca !fir.array<?xi32>401 402 ! CHECK: %[[nInCallLoad:.*]] = fir.load %[[nInCall]] : !fir.ref<i64>403 ! CHECK: %[[nInCallCast:.*]] = fir.convert %[[nInCallLoad]] : (i64) -> index404 ! CHECK: %[[cmpi:.*]] = arith.cmpi sgt, %[[nInCallCast]], %{{.*}} : index405 ! CHECK: %[[select:.*]] = arith.select %[[cmpi]], %[[nInCallCast]], %{{.*}} : index406 ! CHECK: %[[tmp:.*]] = fir.alloca !fir.char<1,?>(%[[select]] : index)407 408 ! CHECK-NOT: fir.alloca !fir.array<?xi32>409 ! CHECK: fir.call @_QPtest_recursion(%[[tmp]], {{.*}}410 res = char(some_local(1)) // test_recursion(n-1)411 412 ! Verify that symbol n was not remapped to the actual argument passed413 ! to n in the call (that the temporary mapping was cleaned-up).414 415 ! CHECK: %[[nLoad2:.*]] = fir.load %[[n]] : !fir.ref<i64>416 ! CHECK: OutputInteger64(%{{.*}}, %[[nLoad2]])417 print *, n418 end if419end function420 421! Test call to character function for which only the result type is explicit422! CHECK-LABEL:func @_QPtest_not_entirely_explicit_interface(423! CHECK-SAME: %[[n_arg:.*]]: !fir.ref<i64>{{.*}}) {424subroutine test_not_entirely_explicit_interface(n)425 integer(8) :: n426 character(n) :: return_dyn_char_2427 print *, return_dyn_char_2(10)428 ! CHECK: %[[n:.*]] = fir.load %[[n_arg]] : !fir.ref<i64>429 ! CHECK: %[[len:.*]] = fir.convert %[[n]] : (i64) -> index430 ! CHECK: %[[cmpi:.*]] = arith.cmpi sgt, %[[len]], %{{.*}} : index431 ! CHECK: %[[select:.*]] = arith.select %[[cmpi]], %[[len]], %{{.*}} : index432 ! CHECK: %[[result:.*]] = fir.alloca !fir.char<1,?>(%[[select]] : index) {bindc_name = ".result"}433 ! CHECK: fir.call @_QPreturn_dyn_char_2(%[[result]], %[[select]], %{{.*}}) {{.*}}: (!fir.ref<!fir.char<1,?>>, index, !fir.ref<i32>) -> !fir.boxchar<1>434end subroutine435