xref: /llvm-project/flang/test/Lower/host-associated-functions.f90 (revision 5aaf384b1614fcef5504d0b16d3e5063f72943c1)
1f35f863aSjeanPerier! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s
224e8cf45SValentin Clement
324e8cf45SValentin Clement! Test calling functions whose result interface is evaluated on the call site
424e8cf45SValentin Clement! and where the calls are located in an internal procedure while the
524e8cf45SValentin Clement! interface is defined in the host procedure.
624e8cf45SValentin Clement
724e8cf45SValentin Clement! CHECK-LABEL: func @_QPcapture_char_func_dummy(
824e8cf45SValentin Clement! CHECK-SAME:  %[[VAL_0:.*]]: tuple<!fir.boxproc<() -> ()>, i64> {fir.char_proc},
924e8cf45SValentin Clement! CHECK-SAME:  %[[VAL_1:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
1024e8cf45SValentin Clementsubroutine capture_char_func_dummy(char_func_dummy, n)
1124e8cf45SValentin Clement  character(n),external :: char_func_dummy
1224e8cf45SValentin Clement  ! CHECK:  %[[VAL_2:.*]] = fir.alloca tuple<tuple<!fir.boxproc<() -> ()>, i64>, !fir.ref<i32>>
1324e8cf45SValentin Clement  ! CHECK:  %[[VAL_3:.*]] = arith.constant 0 : i32
1424e8cf45SValentin Clement  ! CHECK:  %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_3]] : (!fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>, !fir.ref<i32>>>, i32) -> !fir.ref<tuple<!fir.boxproc<() -> ()>, i64>>
1524e8cf45SValentin Clement  ! CHECK:  fir.store %[[VAL_0]] to %[[VAL_4]] : !fir.ref<tuple<!fir.boxproc<() -> ()>, i64>>
1624e8cf45SValentin Clement  ! CHECK:  %[[VAL_5:.*]] = arith.constant 1 : i32
1724e8cf45SValentin Clement  ! CHECK:  %[[VAL_6:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_5]] : (!fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>, !fir.ref<i32>>>, i32) -> !fir.llvm_ptr<!fir.ref<i32>>
1824e8cf45SValentin Clement  ! CHECK:  fir.store %[[VAL_1]] to %[[VAL_6]] : !fir.llvm_ptr<!fir.ref<i32>>
194cc9437aSTom Eccles  ! CHECK:  fir.call @_QFcapture_char_func_dummyPinternal(%[[VAL_2]]) {{.*}}: (!fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>, !fir.ref<i32>>>) -> ()
2024e8cf45SValentin Clement  call internal()
2124e8cf45SValentin Clementcontains
2206f775a8SjeanPerier  ! CHECK-LABEL: func private @_QFcapture_char_func_dummyPinternal(
23971237daSjeanPerier  ! CHECK-SAME:  %[[VAL_0:.*]]: !fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>, !fir.ref<i32>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
2424e8cf45SValentin Clement  subroutine internal()
2524e8cf45SValentin Clement  ! CHECK:  %[[VAL_1:.*]] = arith.constant 0 : i32
2624e8cf45SValentin Clement  ! CHECK:  %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_1]] : (!fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>, !fir.ref<i32>>>, i32) -> !fir.ref<tuple<!fir.boxproc<() -> ()>, i64>>
2724e8cf45SValentin Clement  ! CHECK:  %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.ref<tuple<!fir.boxproc<() -> ()>, i64>>
2824e8cf45SValentin Clement  ! CHECK:  %[[VAL_4:.*]] = arith.constant 1 : i32
2924e8cf45SValentin Clement  ! CHECK:  %[[VAL_5:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_4]] : (!fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>, !fir.ref<i32>>>, i32) -> !fir.llvm_ptr<!fir.ref<i32>>
3024e8cf45SValentin Clement  ! CHECK:  %[[VAL_6:.*]] = fir.load %[[VAL_5]] : !fir.llvm_ptr<!fir.ref<i32>>
3124e8cf45SValentin Clement  ! CHECK:  %[[VAL_12:.*]] = fir.extract_value %[[VAL_3]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>) -> !fir.boxproc<() -> ()>
3224e8cf45SValentin Clement  ! CHECK:  %[[VAL_13:.*]] = fir.box_addr %[[VAL_12]] : (!fir.boxproc<() -> ()>) -> (() -> ())
3324e8cf45SValentin Clement  ! CHECK:  %[[VAL_14:.*]] = fir.load %[[VAL_6]] : !fir.ref<i32>
3424e8cf45SValentin Clement  ! CHECK:  %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i32) -> i64
3524e8cf45SValentin Clement  ! CHECK:  %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i64) -> index
364235bd60SValentin Clement  ! CHECK:  %[[C0:.*]] = arith.constant 0 : index
374235bd60SValentin Clement  ! CHECK:  %[[CMPI:.*]] = arith.cmpi sgt, %[[VAL_16]], %[[C0]] : index
384235bd60SValentin Clement  ! CHECK:  %[[SELECT:.*]] = arith.select %[[CMPI]], %[[VAL_16]], %[[C0]] : index
39*5aaf384bSTom Eccles  ! CHECK:  %[[VAL_17:.*]] = llvm.intr.stacksave : !llvm.ptr
404235bd60SValentin Clement  ! CHECK:  %[[VAL_18:.*]] = fir.alloca !fir.char<1,?>(%[[SELECT]] : index) {bindc_name = ".result"}
4124e8cf45SValentin Clement  ! CHECK:  %[[VAL_19:.*]] = fir.convert %[[VAL_13]] : (() -> ()) -> ((!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>)
424cc9437aSTom Eccles  ! CHECK:  %[[VAL_20:.*]] = fir.call %[[VAL_19]](%[[VAL_18]], %[[SELECT]]) {{.*}}: (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
4324e8cf45SValentin Clement   print *, char_func_dummy()
4424e8cf45SValentin Clement  end subroutine
4524e8cf45SValentin Clementend subroutine
4624e8cf45SValentin Clement
4724e8cf45SValentin Clement! CHECK-LABEL: func @_QPcapture_char_func_assumed_dummy(
4824e8cf45SValentin Clement! CHECK-SAME:  %[[VAL_0:.*]]: tuple<!fir.boxproc<() -> ()>, i64> {fir.char_proc}) {
4924e8cf45SValentin Clementsubroutine capture_char_func_assumed_dummy(char_func_dummy)
5024e8cf45SValentin Clement  character(*),external :: char_func_dummy
5124e8cf45SValentin Clement! CHECK:  %[[VAL_1:.*]] = fir.alloca tuple<tuple<!fir.boxproc<() -> ()>, i64>>
5224e8cf45SValentin Clement! CHECK:  %[[VAL_2:.*]] = arith.constant 0 : i32
5324e8cf45SValentin Clement! CHECK:  %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>>>, i32) -> !fir.ref<tuple<!fir.boxproc<() -> ()>, i64>>
5424e8cf45SValentin Clement! CHECK:  fir.store %[[VAL_0]] to %[[VAL_3]] : !fir.ref<tuple<!fir.boxproc<() -> ()>, i64>>
554cc9437aSTom Eccles! CHECK:  fir.call @_QFcapture_char_func_assumed_dummyPinternal(%[[VAL_1]]) {{.*}}: (!fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>>>) -> ()
5624e8cf45SValentin Clement  call internal()
5724e8cf45SValentin Clementcontains
5806f775a8SjeanPerier! CHECK-LABEL: func private @_QFcapture_char_func_assumed_dummyPinternal(
59971237daSjeanPerier! CHECK-SAME:  %[[VAL_0:.*]]: !fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
6024e8cf45SValentin Clement  subroutine internal()
6124e8cf45SValentin Clement! CHECK:  %[[VAL_1:.*]] = arith.constant 0 : i32
6224e8cf45SValentin Clement! CHECK:  %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_1]] : (!fir.ref<tuple<tuple<!fir.boxproc<() -> ()>, i64>>>, i32) -> !fir.ref<tuple<!fir.boxproc<() -> ()>, i64>>
6324e8cf45SValentin Clement! CHECK:  %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.ref<tuple<!fir.boxproc<() -> ()>, i64>>
6424e8cf45SValentin Clement! CHECK:  %[[VAL_9:.*]] = fir.extract_value %[[VAL_3]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>) -> !fir.boxproc<() -> ()>
6524e8cf45SValentin Clement! CHECK:  %[[VAL_10:.*]] = fir.box_addr %[[VAL_9]] : (!fir.boxproc<() -> ()>) -> (() -> ())
6624e8cf45SValentin Clement! CHECK:  %[[VAL_11:.*]] = fir.extract_value %[[VAL_3]], [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>) -> i64
67*5aaf384bSTom Eccles! CHECK:  %[[VAL_12:.*]] = llvm.intr.stacksave : !llvm.ptr
6824e8cf45SValentin Clement! CHECK:  %[[VAL_13:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_11]] : i64) {bindc_name = ".result"}
6924e8cf45SValentin Clement! CHECK:  %[[VAL_14:.*]] = fir.convert %[[VAL_10]] : (() -> ()) -> ((!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>)
7024e8cf45SValentin Clement! CHECK:  %[[VAL_15:.*]] = fir.convert %[[VAL_11]] : (i64) -> index
714cc9437aSTom Eccles! CHECK:  %[[VAL_16:.*]] = fir.call %[[VAL_14]](%[[VAL_13]], %[[VAL_15]]) {{.*}}: (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
7224e8cf45SValentin Clement   print *, char_func_dummy()
7324e8cf45SValentin Clement  end subroutine
7424e8cf45SValentin Clementend subroutine
7524e8cf45SValentin Clement
7624e8cf45SValentin Clement! CHECK-LABEL: func @_QPcapture_char_func(
7724e8cf45SValentin Clement! CHECK-SAME:  %[[VAL_0:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
7824e8cf45SValentin Clementsubroutine capture_char_func(n)
7924e8cf45SValentin Clement  character(n), external :: char_func
8024e8cf45SValentin Clement! CHECK:  %[[VAL_1:.*]] = fir.alloca tuple<!fir.ref<i32>>
8124e8cf45SValentin Clement! CHECK:  %[[VAL_2:.*]] = arith.constant 0 : i32
8224e8cf45SValentin Clement! CHECK:  %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<tuple<!fir.ref<i32>>>, i32) -> !fir.llvm_ptr<!fir.ref<i32>>
8324e8cf45SValentin Clement! CHECK:  fir.store %[[VAL_0]] to %[[VAL_3]] : !fir.llvm_ptr<!fir.ref<i32>>
844cc9437aSTom Eccles! CHECK:  fir.call @_QFcapture_char_funcPinternal(%[[VAL_1]]) {{.*}}: (!fir.ref<tuple<!fir.ref<i32>>>) -> ()
8524e8cf45SValentin Clement  call internal()
8624e8cf45SValentin Clementcontains
8706f775a8SjeanPerier! CHECK-LABEL: func private @_QFcapture_char_funcPinternal(
8824e8cf45SValentin Clement! CHECK-SAME:  %[[VAL_0:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc})
8924e8cf45SValentin Clement  subroutine internal()
9024e8cf45SValentin Clement   print *, char_func()
9124e8cf45SValentin Clement  end subroutine
9224e8cf45SValentin Clementend subroutine
9324e8cf45SValentin Clement
9424e8cf45SValentin Clement! CHECK-LABEL: func @_QPcapture_array_func(
9524e8cf45SValentin Clement! CHECK-SAME:  %[[VAL_0:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
9624e8cf45SValentin Clementsubroutine capture_array_func(n)
9724e8cf45SValentin Clement  integer :: n
9824e8cf45SValentin Clement  interface
9924e8cf45SValentin Clement  function array_func()
10024e8cf45SValentin Clement    import :: n
10124e8cf45SValentin Clement    integer :: array_func(n)
10224e8cf45SValentin Clement  end function
10324e8cf45SValentin Clement  end interface
10424e8cf45SValentin Clement! CHECK:  %[[VAL_1:.*]] = fir.alloca tuple<!fir.ref<i32>>
10524e8cf45SValentin Clement! CHECK:  %[[VAL_2:.*]] = arith.constant 0 : i32
10624e8cf45SValentin Clement! CHECK:  %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<tuple<!fir.ref<i32>>>, i32) -> !fir.llvm_ptr<!fir.ref<i32>>
10724e8cf45SValentin Clement! CHECK:  fir.store %[[VAL_0]] to %[[VAL_3]] : !fir.llvm_ptr<!fir.ref<i32>>
1084cc9437aSTom Eccles! CHECK:  fir.call @_QFcapture_array_funcPinternal(%[[VAL_1]]) {{.*}}: (!fir.ref<tuple<!fir.ref<i32>>>) -> ()
10924e8cf45SValentin Clement  call internal()
11024e8cf45SValentin Clementcontains
11124e8cf45SValentin Clement  subroutine internal()
11206f775a8SjeanPerier! CHECK-LABEL: func private @_QFcapture_array_funcPinternal(
113971237daSjeanPerier! CHECK-SAME:  %[[VAL_0:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
11424e8cf45SValentin Clement! CHECK:  %[[VAL_1:.*]] = arith.constant 0 : i32
11524e8cf45SValentin Clement! CHECK:  %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_1]] : (!fir.ref<tuple<!fir.ref<i32>>>, i32) -> !fir.llvm_ptr<!fir.ref<i32>>
11624e8cf45SValentin Clement! CHECK:  %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.llvm_ptr<!fir.ref<i32>>
11724e8cf45SValentin Clement! CHECK:  %[[VAL_9:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32>
11824e8cf45SValentin Clement! CHECK:  %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> i64
11924e8cf45SValentin Clement! CHECK:  %[[VAL_11:.*]] = arith.constant 1 : i64
12024e8cf45SValentin Clement! CHECK:  %[[VAL_12:.*]] = arith.subi %[[VAL_10]], %[[VAL_11]] : i64
12124e8cf45SValentin Clement! CHECK:  %[[VAL_13:.*]] = arith.constant 1 : i64
12224e8cf45SValentin Clement! CHECK:  %[[VAL_14:.*]] = arith.addi %[[VAL_12]], %[[VAL_13]] : i64
12324e8cf45SValentin Clement! CHECK:  %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i64) -> index
1244235bd60SValentin Clement! CHECK:  %[[C0:.*]] = arith.constant 0 : index
1254235bd60SValentin Clement! CHECK:  %[[CMPI:.*]] = arith.cmpi sgt, %[[VAL_15]], %[[C0]] : index
1264235bd60SValentin Clement! CHECK:  %[[SELECT:.*]] = arith.select %[[CMPI]], %[[VAL_15]], %[[C0]] : index
127*5aaf384bSTom Eccles! CHECK:  %[[VAL_16:.*]] = llvm.intr.stacksave : !llvm.ptr
1284235bd60SValentin Clement! CHECK:  %[[VAL_17:.*]] = fir.alloca !fir.array<?xi32>, %[[SELECT]] {bindc_name = ".result"}
12924e8cf45SValentin Clement   print *, array_func()
13024e8cf45SValentin Clement  end subroutine
13124e8cf45SValentin Clementend subroutine
13224e8cf45SValentin Clement
13324e8cf45SValentin Clementmodule define_char_func
13424e8cf45SValentin Clement  contains
13524e8cf45SValentin Clement  function return_char(n)
13624e8cf45SValentin Clement    integer :: n
13724e8cf45SValentin Clement    character(n) :: return_char
13824e8cf45SValentin Clement    return_char = "a"
13924e8cf45SValentin Clement  end function
14024e8cf45SValentin Clementend module
14124e8cf45SValentin Clement
14224e8cf45SValentin Clement! CHECK-LABEL: func @_QPuse_module() {
14324e8cf45SValentin Clementsubroutine use_module()
14424e8cf45SValentin Clement  ! verify there is no capture triggers by the interface.
14524e8cf45SValentin Clement  use define_char_func
1464cc9437aSTom Eccles! CHECK:  fir.call @_QFuse_modulePinternal() {{.*}}: () -> ()
14724e8cf45SValentin Clement  call internal()
14824e8cf45SValentin Clement  contains
14906f775a8SjeanPerier! CHECK-LABEL: func private @_QFuse_modulePinternal() {{.*}} {
15024e8cf45SValentin Clement  subroutine internal()
15124e8cf45SValentin Clement    print *, return_char(42)
15224e8cf45SValentin Clement  end subroutine
15324e8cf45SValentin Clementend subroutine
154