xref: /llvm-project/flang/test/Lower/explicit-interface-results-2.f90 (revision cd7e65398fbbd9642573013800dc3ae1e7307f82)
100cc7304SValentin Clement! Test lowering of internal procedures returning arrays or characters.
200cc7304SValentin Clement! This test allocation on the caller side of the results that may depend on
300cc7304SValentin Clement! host associated symbols.
4f35f863aSjeanPerier! RUN: bbc -hlfir=false %s -o - | FileCheck %s
500cc7304SValentin Clement
600cc7304SValentin Clementmodule some_module
700cc7304SValentin Clement integer :: n_module
800cc7304SValentin Clementend module
900cc7304SValentin Clement
1000cc7304SValentin Clement! Test host calling array internal procedure.
1100cc7304SValentin Clement! Result depends on host variable.
1200cc7304SValentin Clement! CHECK-LABEL: func @_QPhost1
1300cc7304SValentin Clementsubroutine host1()
1400cc7304SValentin Clement  implicit none
1500cc7304SValentin Clement  integer :: n
1600cc7304SValentin Clement! CHECK:  %[[VAL_1:.*]] = fir.alloca i32
1700cc7304SValentin Clement  call takes_array(return_array())
1800cc7304SValentin Clement! CHECK:  %[[VAL_4:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
1900cc7304SValentin Clement! CHECK:  %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i32) -> index
204235bd60SValentin Clement! CHECK:  %[[CMPI:.*]] = arith.cmpi sgt, %[[VAL_5]], %{{.*}} : index
214235bd60SValentin Clement! CHECK:  %[[SELECT:.*]] = arith.select %[[CMPI]], %[[VAL_5]], %{{.*}} : index
224235bd60SValentin Clement! CHECK:  %[[VAL_6:.*]] = fir.alloca !fir.array<?xf32>, %[[SELECT]] {bindc_name = ".result"}
2300cc7304SValentin Clementcontains
2400cc7304SValentin Clement  function return_array()
2500cc7304SValentin Clement    real :: return_array(n)
2600cc7304SValentin Clement  end function
2700cc7304SValentin Clementend subroutine
2800cc7304SValentin Clement
2900cc7304SValentin Clement! Test host calling array internal procedure.
3000cc7304SValentin Clement! Result depends on module variable with the use statement inside the host.
3100cc7304SValentin Clement! CHECK-LABEL: func @_QPhost2
3200cc7304SValentin Clementsubroutine host2()
3300cc7304SValentin Clement  use :: some_module
3400cc7304SValentin Clement  call takes_array(return_array())
3500cc7304SValentin Clement! CHECK:  %[[VAL_0:.*]] = fir.address_of(@_QMsome_moduleEn_module) : !fir.ref<i32>
3600cc7304SValentin Clement! CHECK:  %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<i32>
3700cc7304SValentin Clement! CHECK:  %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (i32) -> index
384235bd60SValentin Clement! CHECK:  %[[CMPI:.*]] = arith.cmpi sgt, %[[VAL_2]], %{{.*}} : index
394235bd60SValentin Clement! CHECK:  %[[SELECT:.*]] = arith.select %[[CMPI]], %[[VAL_2]], %{{.*}} : index
404235bd60SValentin Clement! CHECK:  %[[VAL_3:.*]] = fir.alloca !fir.array<?xf32>, %[[SELECT]] {bindc_name = ".result"}
4100cc7304SValentin Clementcontains
4200cc7304SValentin Clement  function return_array()
4300cc7304SValentin Clement    real :: return_array(n_module)
4400cc7304SValentin Clement  end function
4500cc7304SValentin Clementend subroutine
4600cc7304SValentin Clement
4700cc7304SValentin Clement! Test host calling array internal procedure.
4800cc7304SValentin Clement! Result depends on module variable with the use statement inside the internal procedure.
4900cc7304SValentin Clement! CHECK-LABEL: func @_QPhost3
5000cc7304SValentin Clementsubroutine host3()
5100cc7304SValentin Clement  call takes_array(return_array())
5200cc7304SValentin Clement! CHECK:  %[[VAL_0:.*]] = fir.address_of(@_QMsome_moduleEn_module) : !fir.ref<i32>
5300cc7304SValentin Clement! CHECK:  %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<i32>
5400cc7304SValentin Clement! CHECK:  %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (i32) -> index
554235bd60SValentin Clement! CHECK:  %[[CMPI:.*]] = arith.cmpi sgt, %[[VAL_2]], %{{.*}} : index
564235bd60SValentin Clement! CHECK:  %[[SELECT:.*]] = arith.select %[[CMPI]], %[[VAL_2]], %{{.*}} : index
574235bd60SValentin Clement! CHECK:  %[[VAL_3:.*]] = fir.alloca !fir.array<?xf32>, %[[SELECT]] {bindc_name = ".result"}
5800cc7304SValentin Clementcontains
5900cc7304SValentin Clement  function return_array()
6000cc7304SValentin Clement    use :: some_module
6100cc7304SValentin Clement    real :: return_array(n_module)
6200cc7304SValentin Clement  end function
6300cc7304SValentin Clementend subroutine
6400cc7304SValentin Clement
6500cc7304SValentin Clement! Test internal procedure A calling array internal procedure B.
6600cc7304SValentin Clement! Result depends on host variable not directly used in A.
6700cc7304SValentin Clementsubroutine host4()
6800cc7304SValentin Clement  implicit none
6900cc7304SValentin Clement  integer :: n
7000cc7304SValentin Clement  call internal_proc_a()
7100cc7304SValentin Clementcontains
7206f775a8SjeanPerier! CHECK-LABEL: func private @_QFhost4Pinternal_proc_a
73*971237daSjeanPerier! CHECK-SAME:  %[[VAL_0:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
7400cc7304SValentin Clement  subroutine internal_proc_a()
7500cc7304SValentin Clement    call takes_array(return_array())
7600cc7304SValentin Clement! CHECK:  %[[VAL_1:.*]] = arith.constant 0 : i32
7700cc7304SValentin Clement! CHECK:  %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_1]] : (!fir.ref<tuple<!fir.ref<i32>>>, i32) -> !fir.llvm_ptr<!fir.ref<i32>>
7800cc7304SValentin Clement! CHECK:  %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.llvm_ptr<!fir.ref<i32>>
7900cc7304SValentin Clement! CHECK:  %[[VAL_4:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32>
8000cc7304SValentin Clement! CHECK:  %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i32) -> index
814235bd60SValentin Clement! CHECK:  %[[CMPI:.*]] = arith.cmpi sgt, %[[VAL_5]], %{{.*}} : index
824235bd60SValentin Clement! CHECK:  %[[SELECT:.*]] = arith.select %[[CMPI]], %[[VAL_5]], %{{.*}} : index
834235bd60SValentin Clement! CHECK:  %[[VAL_6:.*]] = fir.alloca !fir.array<?xf32>, %[[SELECT]] {bindc_name = ".result"}
8400cc7304SValentin Clement  end subroutine
8500cc7304SValentin Clement  function return_array()
8600cc7304SValentin Clement    real :: return_array(n)
8700cc7304SValentin Clement  end function
8800cc7304SValentin Clementend subroutine
8900cc7304SValentin Clement
9000cc7304SValentin Clement! Test internal procedure A calling array internal procedure B.
9100cc7304SValentin Clement! Result depends on module variable with use statement in the host.
9200cc7304SValentin Clementsubroutine host5()
9300cc7304SValentin Clement  use :: some_module
9400cc7304SValentin Clement  implicit none
9500cc7304SValentin Clement  call internal_proc_a()
9600cc7304SValentin Clementcontains
97*971237daSjeanPerier! CHECK-LABEL: func private @_QFhost5Pinternal_proc_a() attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
9800cc7304SValentin Clement  subroutine internal_proc_a()
9900cc7304SValentin Clement    call takes_array(return_array())
10000cc7304SValentin Clement! CHECK:  %[[VAL_0:.*]] = fir.address_of(@_QMsome_moduleEn_module) : !fir.ref<i32>
10100cc7304SValentin Clement! CHECK:  %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<i32>
10200cc7304SValentin Clement! CHECK:  %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (i32) -> index
1034235bd60SValentin Clement! CHECK:  %[[CMPI:.*]] = arith.cmpi sgt, %[[VAL_2]], %{{.*}} : index
1044235bd60SValentin Clement! CHECK:  %[[SELECT:.*]] = arith.select %[[CMPI]], %[[VAL_2]], %{{.*}} : index
1054235bd60SValentin Clement! CHECK:  %[[VAL_3:.*]] = fir.alloca !fir.array<?xf32>, %[[SELECT]] {bindc_name = ".result"}
10600cc7304SValentin Clement  end subroutine
10700cc7304SValentin Clement  function return_array()
10800cc7304SValentin Clement    real :: return_array(n_module)
10900cc7304SValentin Clement  end function
11000cc7304SValentin Clementend subroutine
11100cc7304SValentin Clement
11200cc7304SValentin Clement! Test internal procedure A calling array internal procedure B.
11300cc7304SValentin Clement! Result depends on module variable with use statement in B.
11400cc7304SValentin Clementsubroutine host6()
11500cc7304SValentin Clement  implicit none
11600cc7304SValentin Clement  call internal_proc_a()
11700cc7304SValentin Clementcontains
11806f775a8SjeanPerier! CHECK-LABEL: func private @_QFhost6Pinternal_proc_a
11900cc7304SValentin Clement  subroutine internal_proc_a()
12000cc7304SValentin Clement    call takes_array(return_array())
12100cc7304SValentin Clement! CHECK:  %[[VAL_0:.*]] = fir.address_of(@_QMsome_moduleEn_module) : !fir.ref<i32>
12200cc7304SValentin Clement! CHECK:  %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<i32>
12300cc7304SValentin Clement! CHECK:  %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (i32) -> index
1244235bd60SValentin Clement! CHECK:  %[[CMPI:.*]] = arith.cmpi sgt, %[[VAL_2]], %{{.*}} : index
1254235bd60SValentin Clement! CHECK:  %[[SELECT:.*]] = arith.select %[[CMPI]], %[[VAL_2]], %{{.*}} : index
1264235bd60SValentin Clement! CHECK:  %[[VAL_3:.*]] = fir.alloca !fir.array<?xf32>, %[[SELECT]] {bindc_name = ".result"}
12700cc7304SValentin Clement  end subroutine
12800cc7304SValentin Clement  function return_array()
12900cc7304SValentin Clement    use :: some_module
13000cc7304SValentin Clement    real :: return_array(n_module)
13100cc7304SValentin Clement  end function
13200cc7304SValentin Clementend subroutine
13300cc7304SValentin Clement
13400cc7304SValentin Clement! Test host calling array internal procedure.
13500cc7304SValentin Clement! Result depends on a common block variable declared in the host.
13600cc7304SValentin Clement! CHECK-LABEL: func @_QPhost7
13700cc7304SValentin Clementsubroutine host7()
13800cc7304SValentin Clement  implicit none
13900cc7304SValentin Clement  integer :: n_common
14000cc7304SValentin Clement  common /mycom/ n_common
14100cc7304SValentin Clement  call takes_array(return_array())
14200cc7304SValentin Clement! CHECK:  %[[VAL_0:.*]] = arith.constant 0 : index
1436ffea74fSjeanPerier! CHECK:  %[[VAL_2:.*]] = fir.address_of(@mycom_) : !fir.ref<!fir.array<4xi8>>
14400cc7304SValentin Clement! CHECK:  %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.array<4xi8>>) -> !fir.ref<!fir.array<?xi8>>
14500cc7304SValentin Clement! CHECK:  %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_3]], %[[VAL_0]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
14600cc7304SValentin Clement! CHECK:  %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.ref<i8>) -> !fir.ref<i32>
14700cc7304SValentin Clement! CHECK:  %[[VAL_8:.*]] = fir.load %[[VAL_5]] : !fir.ref<i32>
14800cc7304SValentin Clement! CHECK:  %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (i32) -> index
1494235bd60SValentin Clement! CHECK:  %[[CMPI:.*]] = arith.cmpi sgt, %[[VAL_9]], %{{.*}} : index
1504235bd60SValentin Clement! CHECK:  %[[SELECT:.*]] = arith.select %[[CMPI]], %[[VAL_9]], %{{.*}} : index
1514235bd60SValentin Clement! CHECK:  %[[VAL_10:.*]] = fir.alloca !fir.array<?xf32>, %[[SELECT]] {bindc_name = ".result"}
15200cc7304SValentin Clementcontains
15300cc7304SValentin Clement  function return_array()
15400cc7304SValentin Clement    real :: return_array(n_common)
15500cc7304SValentin Clement  end function
15600cc7304SValentin Clementend subroutine
15700cc7304SValentin Clement
15800cc7304SValentin Clement! Test host calling array internal procedure.
15900cc7304SValentin Clement! Result depends on a common block variable declared in the internal procedure.
16000cc7304SValentin Clement! CHECK-LABEL: func @_QPhost8
16100cc7304SValentin Clementsubroutine host8()
16200cc7304SValentin Clement  implicit none
16300cc7304SValentin Clement  call takes_array(return_array())
16400cc7304SValentin Clement! CHECK:  %[[VAL_0:.*]] = arith.constant 0 : index
1656ffea74fSjeanPerier! CHECK:  %[[VAL_1:.*]] = fir.address_of(@mycom_) : !fir.ref<!fir.array<4xi8>>
16600cc7304SValentin Clement! CHECK:  %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<4xi8>>) -> !fir.ref<!fir.array<?xi8>>
16700cc7304SValentin Clement! CHECK:  %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_0]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
16800cc7304SValentin Clement! CHECK:  %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<i8>) -> !fir.ref<i32>
16900cc7304SValentin Clement! CHECK:  %[[VAL_5:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32>
17000cc7304SValentin Clement! CHECK:  %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> index
1714235bd60SValentin Clement! CHECK:  %[[CMPI:.*]] = arith.cmpi sgt, %[[VAL_6]], %{{.*}} : index
1724235bd60SValentin Clement! CHECK:  %[[SELECT:.*]] = arith.select %[[CMPI]], %[[VAL_6]], %{{.*}} : index
1734235bd60SValentin Clement! CHECK:  %[[VAL_7:.*]] = fir.alloca !fir.array<?xf32>, %[[SELECT]] {bindc_name = ".result"}
17400cc7304SValentin Clementcontains
17500cc7304SValentin Clement  function return_array()
17600cc7304SValentin Clement    integer :: n_common
17700cc7304SValentin Clement    common /mycom/ n_common
17800cc7304SValentin Clement    real :: return_array(n_common)
17900cc7304SValentin Clement  end function
18000cc7304SValentin Clementend subroutine
18100cc7304SValentin Clement
18200cc7304SValentin Clement! Test internal procedure A calling array internal procedure B.
18300cc7304SValentin Clement! Result depends on a common block variable declared in the host.
18400cc7304SValentin Clementsubroutine host9()
18500cc7304SValentin Clement  implicit none
18600cc7304SValentin Clement  integer :: n_common
18700cc7304SValentin Clement  common /mycom/ n_common
18800cc7304SValentin Clement  call internal_proc_a()
18900cc7304SValentin Clementcontains
19006f775a8SjeanPerier! CHECK-LABEL: func private @_QFhost9Pinternal_proc_a
19100cc7304SValentin Clement  subroutine internal_proc_a()
19293129ca8SJean Perier! CHECK:  %[[VAL_0:.*]] = arith.constant 0 : index
1936ffea74fSjeanPerier! CHECK:  %[[VAL_1:.*]] = fir.address_of(@mycom_) : !fir.ref<!fir.array<4xi8>>
19493129ca8SJean Perier! CHECK:  %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<4xi8>>) -> !fir.ref<!fir.array<?xi8>>
19593129ca8SJean Perier! CHECK:  %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_0]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
19693129ca8SJean Perier! CHECK:  %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<i8>) -> !fir.ref<i32>
19793129ca8SJean Perier! CHECK:  %[[VAL_5:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32>
19893129ca8SJean Perier! CHECK:  %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> index
19993129ca8SJean Perier! CHECK:  %[[VAL_7:.*]] = arith.cmpi sgt, %[[VAL_6]], %[[VAL_0]] : index
20093129ca8SJean Perier! CHECK:  %[[VAL_8:.*]] = arith.select %[[VAL_7]], %[[VAL_6]], %[[VAL_0]] : index
20193129ca8SJean Perier! CHECK:  %[[VAL_10:.*]] = fir.alloca !fir.array<?xf32>, %[[VAL_8]] {bindc_name = ".result"}
20200cc7304SValentin Clement    call takes_array(return_array())
20300cc7304SValentin Clement  end subroutine
20400cc7304SValentin Clement  function return_array()
20500cc7304SValentin Clement    use :: some_module
20600cc7304SValentin Clement    real :: return_array(n_common)
20700cc7304SValentin Clement  end function
20800cc7304SValentin Clementend subroutine
20900cc7304SValentin Clement
21000cc7304SValentin Clement! Test internal procedure A calling array internal procedure B.
21100cc7304SValentin Clement! Result depends on a common block variable declared in B.
21200cc7304SValentin Clementsubroutine host10()
21300cc7304SValentin Clement  implicit none
21400cc7304SValentin Clement  call internal_proc_a()
21500cc7304SValentin Clementcontains
21606f775a8SjeanPerier! CHECK-LABEL: func private @_QFhost10Pinternal_proc_a
21700cc7304SValentin Clement  subroutine internal_proc_a()
21800cc7304SValentin Clement    call takes_array(return_array())
21900cc7304SValentin Clement! CHECK:  %[[VAL_0:.*]] = arith.constant 0 : index
2206ffea74fSjeanPerier! CHECK:  %[[VAL_1:.*]] = fir.address_of(@mycom_) : !fir.ref<!fir.array<4xi8>>
22100cc7304SValentin Clement! CHECK:  %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<4xi8>>) -> !fir.ref<!fir.array<?xi8>>
22200cc7304SValentin Clement! CHECK:  %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_0]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
22300cc7304SValentin Clement! CHECK:  %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<i8>) -> !fir.ref<i32>
22400cc7304SValentin Clement! CHECK:  %[[VAL_5:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32>
22500cc7304SValentin Clement! CHECK:  %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> index
2264235bd60SValentin Clement! CHECK:  %[[CMPI:.*]] = arith.cmpi sgt, %[[VAL_6]], %{{.*}} : index
2274235bd60SValentin Clement! CHECK:  %[[SELECT:.*]] = arith.select %[[CMPI]], %[[VAL_6]], %{{.*}} : index
2284235bd60SValentin Clement! CHECK:  %[[VAL_7:.*]] = fir.alloca !fir.array<?xf32>, %[[SELECT]] {bindc_name = ".result"}
22900cc7304SValentin Clement  end subroutine
23000cc7304SValentin Clement  function return_array()
23100cc7304SValentin Clement    integer :: n_common
23200cc7304SValentin Clement    common /mycom/ n_common
23300cc7304SValentin Clement    real :: return_array(n_common)
23400cc7304SValentin Clement  end function
23500cc7304SValentin Clementend subroutine
23600cc7304SValentin Clement
23700cc7304SValentin Clement
23800cc7304SValentin Clement! Test call to a function returning an array where the interface is use
23900cc7304SValentin Clement! associated from a module.
24000cc7304SValentin Clementmodule define_interface
24100cc7304SValentin Clementcontains
24200cc7304SValentin Clementfunction foo()
24300cc7304SValentin Clement  real :: foo(100)
24400cc7304SValentin Clement  foo = 42
24500cc7304SValentin Clementend function
24600cc7304SValentin Clementend module
24700cc7304SValentin Clement! CHECK-LABEL: func @_QPtest_call_to_used_interface(
24800cc7304SValentin Clement! CHECK-SAME:  %[[VAL_0:.*]]: !fir.boxproc<() -> ()>) {
24900cc7304SValentin Clementsubroutine test_call_to_used_interface(dummy_proc)
25000cc7304SValentin Clement  use define_interface
25100cc7304SValentin Clement  procedure(foo) :: dummy_proc
25200cc7304SValentin Clement  call takes_array(dummy_proc())
25300cc7304SValentin Clement! CHECK:  %[[VAL_1:.*]] = arith.constant 100 : index
25400cc7304SValentin Clement! CHECK:  %[[VAL_2:.*]] = fir.alloca !fir.array<100xf32> {bindc_name = ".result"}
25500cc7304SValentin Clement! CHECK:  %[[VAL_4:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
25600cc7304SValentin Clement! CHECK:  %[[VAL_5:.*]] = fir.box_addr %[[VAL_0]] : (!fir.boxproc<() -> ()>) -> (() -> !fir.array<100xf32>)
2574cc9437aSTom Eccles! CHECK:  %[[VAL_6:.*]] = fir.call %[[VAL_5]]() {{.*}}: () -> !fir.array<100xf32>
25800cc7304SValentin Clement! CHECK:  fir.save_result %[[VAL_6]] to %[[VAL_2]](%[[VAL_4]]) : !fir.array<100xf32>, !fir.ref<!fir.array<100xf32>>, !fir.shape<1>
25900cc7304SValentin Clement! CHECK:  %[[VAL_7:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.array<100xf32>>) -> !fir.ref<!fir.array<?xf32>>
2604cc9437aSTom Eccles! CHECK:  fir.call @_QPtakes_array(%[[VAL_7]]) {{.*}}: (!fir.ref<!fir.array<?xf32>>) -> ()
26100cc7304SValentin Clementend subroutine
262