! RUN: bbc -emit-fir %s -o - | FileCheck %s module callee implicit none contains ! CHECK-LABEL: func @_QMcalleePreturn_cst_array() -> !fir.array<20x30xf32> function return_cst_array() real :: return_cst_array(20, 30) end function ! CHECK-LABEL: func @_QMcalleePreturn_dyn_array( ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}, %{{.*}}: !fir.ref{{.*}}) -> !fir.array function return_dyn_array(m, n) integer :: m, n real :: return_dyn_array(m, n) end function ! CHECK-LABEL: func @_QMcalleePreturn_cst_char_cst_array() -> !fir.array<20x30x!fir.char<1,10>> function return_cst_char_cst_array() character(10) :: return_cst_char_cst_array(20, 30) end function ! CHECK-LABEL: func @_QMcalleePreturn_dyn_char_cst_array( ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}) -> !fir.array<20x30x!fir.char<1,?>> function return_dyn_char_cst_array(l) integer :: l character(l) :: return_dyn_char_cst_array(20, 30) end function ! CHECK-LABEL: func @_QMcalleePreturn_cst_char_dyn_array( ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}, %{{.*}}: !fir.ref{{.*}}) -> !fir.array> function return_cst_char_dyn_array(m, n) integer :: m, n character(10) :: return_cst_char_dyn_array(m, n) end function ! CHECK-LABEL: func @_QMcalleePreturn_dyn_char_dyn_array( ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}, %{{.*}}: !fir.ref{{.*}}, %{{.*}}: !fir.ref{{.*}}) -> !fir.array> function return_dyn_char_dyn_array(l, m, n) integer :: l, m, n character(l) :: return_dyn_char_dyn_array(m, n) end function ! CHECK-LABEL: func @_QMcalleePreturn_alloc() -> !fir.box>> function return_alloc() real, allocatable :: return_alloc(:) end function ! CHECK-LABEL: func @_QMcalleePreturn_cst_char_alloc() -> !fir.box>>> function return_cst_char_alloc() character(10), allocatable :: return_cst_char_alloc(:) end function ! CHECK-LABEL: func @_QMcalleePreturn_dyn_char_alloc( ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}) -> !fir.box>>> function return_dyn_char_alloc(l) integer :: l character(l), allocatable :: return_dyn_char_alloc(:) end function ! CHECK-LABEL: func @_QMcalleePreturn_def_char_alloc() -> !fir.box>>> function return_def_char_alloc() character(:), allocatable :: return_def_char_alloc(:) end function ! CHECK-LABEL: func @_QMcalleePreturn_pointer() -> !fir.box>> function return_pointer() real, pointer :: return_pointer(:) end function ! CHECK-LABEL: func @_QMcalleePreturn_cst_char_pointer() -> !fir.box>>> function return_cst_char_pointer() character(10), pointer :: return_cst_char_pointer(:) end function ! CHECK-LABEL: func @_QMcalleePreturn_dyn_char_pointer( ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}) -> !fir.box>>> function return_dyn_char_pointer(l) integer :: l character(l), pointer :: return_dyn_char_pointer(:) end function ! CHECK-LABEL: func @_QMcalleePreturn_def_char_pointer() -> !fir.box>>> function return_def_char_pointer() character(:), pointer :: return_def_char_pointer(:) end function end module module caller use callee contains ! CHECK-LABEL: func @_QMcallerPcst_array() subroutine cst_array() ! CHECK: %[[alloc:.*]] = fir.alloca !fir.array<20x30xf32> {{{.*}}bindc_name = ".result"} ! CHECK: %[[shape:.*]] = fir.shape %{{.*}}, {{.*}} : (index, index) -> !fir.shape<2> ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_cst_array() : () -> !fir.array<20x30xf32> ! CHECK: fir.save_result %[[res]] to %[[alloc]](%[[shape]]) : !fir.array<20x30xf32>, !fir.ref>, !fir.shape<2> print *, return_cst_array() end subroutine ! CHECK-LABEL: func @_QMcallerPcst_char_cst_array() subroutine cst_char_cst_array() ! CHECK: %[[alloc:.*]] = fir.alloca !fir.array<20x30x!fir.char<1,10>> {{{.*}}bindc_name = ".result"} ! CHECK: %[[shape:.*]] = fir.shape %{{.*}}, {{.*}} : (index, index) -> !fir.shape<2> ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_cst_char_cst_array() : () -> !fir.array<20x30x!fir.char<1,10>> ! CHECK: fir.save_result %[[res]] to %[[alloc]](%[[shape]]) typeparams %{{.*}} : !fir.array<20x30x!fir.char<1,10>>, !fir.ref>>, !fir.shape<2>, index print *, return_cst_char_cst_array() end subroutine ! CHECK-LABEL: func @_QMcallerPalloc() subroutine alloc() ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box>> {{{.*}}bindc_name = ".result"} ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_alloc() : () -> !fir.box>> ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box>>, !fir.ref>>> print *, return_alloc() ! CHECK: _FortranAioOutputDescriptor ! CHECK: %[[load:.*]] = fir.load %[[alloc]] : !fir.ref>>> ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box>>) -> !fir.heap> ! CHECK: %[[cmpi:.*]] = arith.cmpi ! CHECK: fir.if %[[cmpi]] ! CHECK: fir.freemem %[[addr]] end subroutine ! CHECK-LABEL: func @_QMcallerPcst_char_alloc() subroutine cst_char_alloc() ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box>>> {{{.*}}bindc_name = ".result"} ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_cst_char_alloc() : () -> !fir.box>>> ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box>>>, !fir.ref>>>> print *, return_cst_char_alloc() ! CHECK: _FortranAioOutputDescriptor ! CHECK: %[[load:.*]] = fir.load %[[alloc]] : !fir.ref>>>> ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box>>>) -> !fir.heap>> ! CHECK: %[[cmpi:.*]] = arith.cmpi ! CHECK: fir.if %[[cmpi]] ! CHECK: fir.freemem %[[addr]] end subroutine ! CHECK-LABEL: func @_QMcallerPdef_char_alloc() subroutine def_char_alloc() ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box>>> {{{.*}}bindc_name = ".result"} ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_def_char_alloc() : () -> !fir.box>>> ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box>>>, !fir.ref>>>> print *, return_def_char_alloc() ! CHECK: _FortranAioOutputDescriptor ! CHECK: %[[load:.*]] = fir.load %[[alloc]] : !fir.ref>>>> ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box>>>) -> !fir.heap>> ! CHECK: %[[cmpi:.*]] = arith.cmpi ! CHECK: fir.if %[[cmpi]] ! CHECK: fir.freemem %[[addr]] end subroutine ! CHECK-LABEL: func @_QMcallerPpointer_test() subroutine pointer_test() ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box>> {{{.*}}bindc_name = ".result"} ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_pointer() : () -> !fir.box>> ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box>>, !fir.ref>>> print *, return_pointer() ! CHECK-NOT: fir.freemem end subroutine ! CHECK-LABEL: func @_QMcallerPcst_char_pointer() subroutine cst_char_pointer() ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box>>> {{{.*}}bindc_name = ".result"} ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_cst_char_pointer() : () -> !fir.box>>> ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box>>>, !fir.ref>>>> print *, return_cst_char_pointer() ! CHECK-NOT: fir.freemem end subroutine ! CHECK-LABEL: func @_QMcallerPdef_char_pointer() subroutine def_char_pointer() ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box>>> {{{.*}}bindc_name = ".result"} ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_def_char_pointer() : () -> !fir.box>>> ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box>>>, !fir.ref>>>> print *, return_def_char_pointer() ! CHECK-NOT: fir.freemem end subroutine ! CHECK-LABEL: func @_QMcallerPdyn_array( ! CHECK-SAME: %[[m:.*]]: !fir.ref{{.*}}, %[[n:.*]]: !fir.ref{{.*}}) { subroutine dyn_array(m, n) integer :: m, n ! CHECK-DAG: %[[mload:.*]] = fir.load %[[m]] : !fir.ref ! CHECK-DAG: %[[mcast:.*]] = fir.convert %[[mload]] : (i32) -> i64 ! CHECK-DAG: %[[msub:.*]] = arith.subi %[[mcast]], %c1{{.*}} : i64 ! CHECK-DAG: %[[madd:.*]] = arith.addi %[[msub]], %c1{{.*}} : i64 ! CHECK-DAG: %[[mcast2:.*]] = fir.convert %[[madd]] : (i64) -> index ! CHECK-DAG: %[[nload:.*]] = fir.load %[[n]] : !fir.ref ! CHECK-DAG: %[[ncast:.*]] = fir.convert %[[nload]] : (i32) -> i64 ! CHECK-DAG: %[[nsub:.*]] = arith.subi %[[ncast]], %c1{{.*}} : i64 ! CHECK-DAG: %[[nadd:.*]] = arith.addi %[[nsub]], %c1{{.*}} : i64 ! CHECK-DAG: %[[ncast2:.*]] = fir.convert %[[nadd]] : (i64) -> index ! CHECK: %[[tmp:.*]] = fir.alloca !fir.array, %[[mcast2]], %[[ncast2]] ! CHECK: %[[shape:.*]] = fir.shape %[[mcast2]], %[[ncast2]] : (index, index) -> !fir.shape<2> ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_dyn_array(%[[m]], %[[n]]) : (!fir.ref, !fir.ref) -> !fir.array ! CHECK: fir.save_result %[[res]] to %[[tmp]](%[[shape]]) : !fir.array, !fir.ref>, !fir.shape<2> print *, return_dyn_array(m, n) end subroutine ! CHECK-LABEL: func @_QMcallerPdyn_char_cst_array( ! CHECK-SAME: %[[l:.*]]: !fir.ref{{.*}}) { subroutine dyn_char_cst_array(l) integer :: l ! CHECK: %[[lload:.*]] = fir.load %[[l]] : !fir.ref ! CHECK: %[[lcast:.*]] = fir.convert %[[lload]] : (i32) -> i64 ! CHECK: %[[lcast2:.*]] = fir.convert %[[lcast]] : (i64) -> index ! CHECK: %[[tmp:.*]] = fir.alloca !fir.array<20x30x!fir.char<1,?>>(%[[lcast2]] : index) ! CHECK: %[[shape:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_dyn_char_cst_array(%[[l]]) : (!fir.ref) -> !fir.array<20x30x!fir.char<1,?>> ! CHECK: fir.save_result %[[res]] to %[[tmp]](%[[shape]]) typeparams %[[lcast2]] : !fir.array<20x30x!fir.char<1,?>>, !fir.ref>>, !fir.shape<2>, index print *, return_dyn_char_cst_array(l) end subroutine ! CHECK-LABEL: func @_QMcallerPcst_char_dyn_array( ! CHECK-SAME: %[[m:.*]]: !fir.ref{{.*}}, %[[n:.*]]: !fir.ref{{.*}}) { subroutine cst_char_dyn_array(m, n) integer :: m, n ! CHECK-DAG: %[[mload:.*]] = fir.load %[[m]] : !fir.ref ! CHECK-DAG: %[[mcast:.*]] = fir.convert %[[mload]] : (i32) -> i64 ! CHECK-DAG: %[[msub:.*]] = arith.subi %[[mcast]], %c1{{.*}} : i64 ! CHECK-DAG: %[[madd:.*]] = arith.addi %[[msub]], %c1{{.*}} : i64 ! CHECK-DAG: %[[mcast2:.*]] = fir.convert %[[madd]] : (i64) -> index ! CHECK-DAG: %[[nload:.*]] = fir.load %[[n]] : !fir.ref ! CHECK-DAG: %[[ncast:.*]] = fir.convert %[[nload]] : (i32) -> i64 ! CHECK-DAG: %[[nsub:.*]] = arith.subi %[[ncast]], %c1{{.*}} : i64 ! CHECK-DAG: %[[nadd:.*]] = arith.addi %[[nsub]], %c1{{.*}} : i64 ! CHECK-DAG: %[[ncast2:.*]] = fir.convert %[[nadd]] : (i64) -> index ! CHECK: %[[tmp:.*]] = fir.alloca !fir.array>, %[[mcast2]], %[[ncast2]] ! CHECK: %[[shape:.*]] = fir.shape %[[mcast2]], %[[ncast2]] : (index, index) -> !fir.shape<2> ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_cst_char_dyn_array(%[[m]], %[[n]]) : (!fir.ref, !fir.ref) -> !fir.array> ! CHECK: fir.save_result %[[res]] to %[[tmp]](%[[shape]]) typeparams {{.*}} : !fir.array>, !fir.ref>>, !fir.shape<2>, index print *, return_cst_char_dyn_array(m, n) end subroutine ! CHECK-LABEL: func @_QMcallerPdyn_char_dyn_array( ! CHECK-SAME: %[[l:.*]]: !fir.ref{{.*}}, %[[m:.*]]: !fir.ref{{.*}}, %[[n:.*]]: !fir.ref{{.*}}) { subroutine dyn_char_dyn_array(l, m, n) ! CHECK-DAG: %[[mload:.*]] = fir.load %[[m]] : !fir.ref ! CHECK-DAG: %[[mcast:.*]] = fir.convert %[[mload]] : (i32) -> i64 ! CHECK-DAG: %[[msub:.*]] = arith.subi %[[mcast]], %c1{{.*}} : i64 ! CHECK-DAG: %[[madd:.*]] = arith.addi %[[msub]], %c1{{.*}} : i64 ! CHECK-DAG: %[[mcast2:.*]] = fir.convert %[[madd]] : (i64) -> index ! CHECK-DAG: %[[nload:.*]] = fir.load %[[n]] : !fir.ref ! CHECK-DAG: %[[ncast:.*]] = fir.convert %[[nload]] : (i32) -> i64 ! CHECK-DAG: %[[nsub:.*]] = arith.subi %[[ncast]], %c1{{.*}} : i64 ! CHECK-DAG: %[[nadd:.*]] = arith.addi %[[nsub]], %c1{{.*}} : i64 ! CHECK-DAG: %[[ncast2:.*]] = fir.convert %[[nadd]] : (i64) -> index ! CHECK-DAG: %[[lload:.*]] = fir.load %[[l]] : !fir.ref ! CHECK-DAG: %[[lcast:.*]] = fir.convert %[[lload]] : (i32) -> i64 ! CHECK-DAG: %[[lcast2:.*]] = fir.convert %[[lcast]] : (i64) -> index ! CHECK: %[[tmp:.*]] = fir.alloca !fir.array>(%[[lcast2]] : index), %[[mcast2]], %[[ncast2]] ! CHECK: %[[shape:.*]] = fir.shape %[[mcast2]], %[[ncast2]] : (index, index) -> !fir.shape<2> ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_dyn_char_dyn_array(%[[l]], %[[m]], %[[n]]) : (!fir.ref, !fir.ref, !fir.ref) -> !fir.array> ! CHECK: fir.save_result %[[res]] to %[[tmp]](%[[shape]]) typeparams {{.*}} : !fir.array>, !fir.ref>>, !fir.shape<2>, index integer :: l, m, n print *, return_dyn_char_dyn_array(l, m, n) end subroutine ! CHECK-LABEL: @_QMcallerPdyn_char_alloc subroutine dyn_char_alloc(l) integer :: l ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box>>> {{{.*}}bindc_name = ".result"} ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_dyn_char_alloc({{.*}}) : (!fir.ref) -> !fir.box>>> ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box>>>, !fir.ref>>>> print *, return_dyn_char_alloc(l) ! CHECK: _FortranAioOutputDescriptor ! CHECK: %[[load:.*]] = fir.load %[[alloc]] : !fir.ref>>>> ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box>>>) -> !fir.heap>> ! CHECK: %[[cmpi:.*]] = arith.cmpi ! CHECK: fir.if %[[cmpi]] ! CHECK: fir.freemem %[[addr]] end subroutine ! CHECK-LABEL: @_QMcallerPdyn_char_pointer subroutine dyn_char_pointer(l) integer :: l ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box>>> {{{.*}}bindc_name = ".result"} ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_dyn_char_pointer({{.*}}) : (!fir.ref) -> !fir.box>>> ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box>>>, !fir.ref>>>> print *, return_dyn_char_pointer(l) ! CHECK-NOT: fir.freemem end subroutine end module ! Test more complex symbol dependencies in the result specification expression module m_with_equiv integer(8) :: l integer(8) :: array(3) equivalence (array(2), l) contains function result_depends_on_equiv_sym() character(l) :: result_depends_on_equiv_sym call set_result_with_some_value(result_depends_on_equiv_sym) end function end module ! CHECK-LABEL: func @_QPtest_result_depends_on_equiv_sym subroutine test_result_depends_on_equiv_sym() use m_with_equiv, only : result_depends_on_equiv_sym ! CHECK: %[[equiv:.*]] = fir.address_of(@_QMm_with_equivEarray) : !fir.ref> ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[equiv]], %c{{.*}} : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[l:.*]] = fir.convert %[[coor]] : (!fir.ref) -> !fir.ptr ! CHECK: %[[load:.*]] = fir.load %[[l]] : !fir.ptr ! CHECK: %[[lcast:.*]] = fir.convert %[[load]] : (i64) -> index ! CHECK: fir.alloca !fir.char<1,?>(%[[lcast]] : index) print *, result_depends_on_equiv_sym() end subroutine ! CHECK-LABEL: func @_QPtest_depends_on_descriptor( ! CHECK-SAME: %[[x:.*]]: !fir.box>{{.*}}) { subroutine test_depends_on_descriptor(x) interface function depends_on_descriptor(x) real :: x(:) character(size(x,1, KIND=8)) :: depends_on_descriptor end function end interface real :: x(:) ! CHECK: %[[dims:.*]]:3 = fir.box_dims %arg0, %c0 : (!fir.box>, index) -> (index, index, index) ! CHECK: %[[extentCast:.*]] = fir.convert %[[dims]]#1 : (index) -> i64 ! CHECK: %[[extent:.*]] = fir.convert %[[extentCast]] : (i64) -> index ! CHECK: fir.alloca !fir.char<1,?>(%[[extent]] : index) print *, depends_on_descriptor(x) end subroutine ! CHECK-LABEL: func @_QPtest_symbol_indirection( ! CHECK-SAME: %[[n:.*]]: !fir.ref{{.*}}) { subroutine test_symbol_indirection(n) interface function symbol_indirection(c, n) integer(8) :: n character(n) :: c character(len(c, KIND=8)) :: symbol_indirection end function end interface integer(8) :: n character(n) :: c ! CHECK: BeginExternalListOutput ! CHECK: %[[nload:.*]] = fir.load %[[n]] : !fir.ref ! CHECK: %[[n_is_positive:.*]] = arith.cmpi sgt, %[[nload]], %c0{{.*}} : i64 ! CHECK: %[[len:.*]] = arith.select %[[n_is_positive]], %[[nload]], %c0{{.*}} : i64 ! CHECK: %[[len_cast:.*]] = fir.convert %[[len]] : (i64) -> index ! CHECK: fir.alloca !fir.char<1,?>(%[[len_cast]] : index) print *, symbol_indirection(c, n) end subroutine ! CHECK-LABEL: func @_QPtest_recursion( ! CHECK-SAME: %[[res:.*]]: !fir.ref>{{.*}}, %[[resLen:.*]]: index{{.*}}, %[[n:.*]]: !fir.ref{{.*}}) -> !fir.boxchar<1> { function test_recursion(n) result(res) integer(8) :: n character(n) :: res ! some_local is here to verify that local symbols that are visible in the ! function interface are not instantiated by accident (that only the ! symbols needed for the result are instantiated before the call). ! CHECK: fir.alloca !fir.array, {{.*}}some_local ! CHECK-NOT: fir.alloca !fir.array integer :: some_local(n) some_local(0) = n + 64 if (n.eq.1) then res = char(some_local(0)) ! CHECK: else else ! CHECK-NOT: fir.alloca !fir.array ! verify that the actual argument for symbol n ("n-1") is used to allocate ! the result, and not the local value of symbol n. ! CHECK: %[[nLoad:.*]] = fir.load %[[n]] : !fir.ref ! CHECK: %[[sub:.*]] = arith.subi %[[nLoad]], %c1{{.*}} : i64 ! CHECK: fir.store %[[sub]] to %[[nInCall:.*]] : !fir.ref ! CHECK-NOT: fir.alloca !fir.array ! CHECK: %[[nInCallLoad:.*]] = fir.load %[[nInCall]] : !fir.ref ! CHECK: %[[nInCallCast:.*]] = fir.convert %[[nInCallLoad]] : (i64) -> index ! CHECK: %[[tmp:.*]] = fir.alloca !fir.char<1,?>(%[[nInCallCast]] : index) ! CHECK-NOT: fir.alloca !fir.array ! CHECK: fir.call @_QPtest_recursion(%[[tmp]], {{.*}} res = char(some_local(0)) // test_recursion(n-1) ! Verify that symbol n was not remapped to the actual argument passed ! to n in the call (that the temporary mapping was cleaned-up). ! CHECK: %[[nLoad2:.*]] = fir.load %[[n]] : !fir.ref ! CHECK: OutputInteger64(%{{.*}}, %[[nLoad2]]) print *, n end if end function ! Test call to character function for which only the result type is explicit ! CHECK-LABEL:func @_QPtest_not_entirely_explicit_interface( ! CHECK-SAME: %[[n_arg:.*]]: !fir.ref{{.*}}) { subroutine test_not_entirely_explicit_interface(n) integer(8) :: n character(n) :: return_dyn_char_2 print *, return_dyn_char_2(10) ! CHECK: %[[n:.*]] = fir.load %[[n_arg]] : !fir.ref ! CHECK: %[[len:.*]] = fir.convert %[[n]] : (i64) -> index ! CHECK: %[[result:.*]] = fir.alloca !fir.char<1,?>(%[[len]] : index) {bindc_name = ".result"} ! CHECK: fir.call @_QPreturn_dyn_char_2(%[[result]], %[[len]], %{{.*}}) : (!fir.ref>, index, !fir.ref) -> !fir.boxchar<1> end subroutine