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