xref: /llvm-project/flang/test/Lower/procedure-declarations.f90 (revision f35f863a88f83332bef9605ef4cfe4f05c066efb)
1*f35f863aSjeanPerier! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s
25754bae4SValentin Clement
35754bae4SValentin Clement! Test procedure declarations. Change appearance order of definition and usages
45754bae4SValentin Clement! (passing a procedure and calling it), with and without definitions.
55754bae4SValentin Clement! Check that the definition type prevail if available and that casts are inserted to
65754bae4SValentin Clement! accommodate for the signature mismatch in the different location due to implicit
75754bae4SValentin Clement! typing rules and Fortran loose interface compatibility rule history.
85754bae4SValentin Clement
95754bae4SValentin Clement
105754bae4SValentin Clement! Note: all the cases where their is a definition are exactly the same,
115754bae4SValentin Clement! since definition should be processed first regardless.
125754bae4SValentin Clement
135754bae4SValentin Clement! pass, call, define
14fe252f8eSValentin Clement! CHECK-LABEL: func @_QPpass_foo() {
15fe252f8eSValentin Clementsubroutine pass_foo()
16fe252f8eSValentin Clement  external :: foo
17fe252f8eSValentin Clement  ! CHECK: %[[f:.*]] = fir.address_of(@_QPfoo)
18fe252f8eSValentin Clement  ! CHECK: fir.emboxproc %[[f]] : ((!fir.ref<!fir.array<2x5xi32>>) -> ()) -> !fir.boxproc<() -> ()>
19fe252f8eSValentin Clement  call bar(foo)
20fe252f8eSValentin Clementend subroutine
215754bae4SValentin Clement! CHECK-LABEL: func @_QPcall_foo(
225754bae4SValentin Clement! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<10xi32>>{{.*}}) {
235754bae4SValentin Clementsubroutine call_foo(i)
245754bae4SValentin Clement  integer :: i(10)
255754bae4SValentin Clement  ! %[[argconvert:*]] = fir.convert %arg0 :
264cc9437aSTom Eccles  ! fir.call @_QPfoo(%[[argconvert]]) {{.*}}: (!fir.ref<!fir.array<2x5xi32>>) -> ()
275754bae4SValentin Clement  call foo(i)
285754bae4SValentin Clementend subroutine
295754bae4SValentin Clement! CHECK-LABEL: func @_QPfoo(
305754bae4SValentin Clement! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<2x5xi32>>{{.*}}) {
315754bae4SValentin Clementsubroutine foo(i)
325754bae4SValentin Clement  integer :: i(2, 5)
335754bae4SValentin Clement  call do_something(i)
345754bae4SValentin Clementend subroutine
355754bae4SValentin Clement
365754bae4SValentin Clement! call, pass, define
375754bae4SValentin Clement! CHECK-LABEL: func @_QPcall_foo2(
385754bae4SValentin Clement! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<10xi32>>{{.*}}) {
395754bae4SValentin Clementsubroutine call_foo2(i)
405754bae4SValentin Clement  integer :: i(10)
415754bae4SValentin Clement  ! %[[argconvert:*]] = fir.convert %arg0 :
424cc9437aSTom Eccles  ! fir.call @_QPfoo2(%[[argconvert]]) {{.*}}: (!fir.ref<!fir.array<2x5xi32>>) -> ()
435754bae4SValentin Clement  call foo2(i)
445754bae4SValentin Clementend subroutine
45fe252f8eSValentin Clement! CHECK-LABEL: func @_QPpass_foo2() {
46fe252f8eSValentin Clementsubroutine pass_foo2()
47fe252f8eSValentin Clement  external :: foo2
48fe252f8eSValentin Clement  ! CHECK: %[[f:.*]] = fir.address_of(@_QPfoo2)
49fe252f8eSValentin Clement  ! CHECK: fir.emboxproc %[[f]] : ((!fir.ref<!fir.array<2x5xi32>>) -> ()) -> !fir.boxproc<() -> ()>
50fe252f8eSValentin Clement  call bar(foo2)
51fe252f8eSValentin Clementend subroutine
525754bae4SValentin Clement! CHECK-LABEL: func @_QPfoo2(
535754bae4SValentin Clement! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<2x5xi32>>{{.*}}) {
545754bae4SValentin Clementsubroutine foo2(i)
555754bae4SValentin Clement  integer :: i(2, 5)
565754bae4SValentin Clement  call do_something(i)
575754bae4SValentin Clementend subroutine
585754bae4SValentin Clement
595754bae4SValentin Clement! call, define, pass
605754bae4SValentin Clement! CHECK-LABEL: func @_QPcall_foo3(
615754bae4SValentin Clement! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<10xi32>>{{.*}}) {
625754bae4SValentin Clementsubroutine call_foo3(i)
635754bae4SValentin Clement  integer :: i(10)
645754bae4SValentin Clement  ! %[[argconvert:*]] = fir.convert %arg0 :
654cc9437aSTom Eccles  ! fir.call @_QPfoo3(%[[argconvert]]) {{.*}}: (!fir.ref<!fir.array<2x5xi32>>) -> ()
665754bae4SValentin Clement  call foo3(i)
675754bae4SValentin Clementend subroutine
685754bae4SValentin Clement! CHECK-LABEL: func @_QPfoo3(
695754bae4SValentin Clement! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<2x5xi32>>{{.*}}) {
705754bae4SValentin Clementsubroutine foo3(i)
715754bae4SValentin Clement  integer :: i(2, 5)
725754bae4SValentin Clement  call do_something(i)
735754bae4SValentin Clementend subroutine
74fe252f8eSValentin Clement! CHECK-LABEL: func @_QPpass_foo3() {
75fe252f8eSValentin Clementsubroutine pass_foo3()
76fe252f8eSValentin Clement  external :: foo3
77fe252f8eSValentin Clement  ! CHECK: %[[f:.*]] = fir.address_of(@_QPfoo3)
78fe252f8eSValentin Clement  ! CHECK: fir.emboxproc %[[f]] : ((!fir.ref<!fir.array<2x5xi32>>) -> ()) -> !fir.boxproc<() -> ()>
79fe252f8eSValentin Clement  call bar(foo3)
80fe252f8eSValentin Clementend subroutine
815754bae4SValentin Clement
825754bae4SValentin Clement! define, call, pass
835754bae4SValentin Clement! CHECK-LABEL: func @_QPfoo4(
845754bae4SValentin Clement! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<2x5xi32>>{{.*}}) {
855754bae4SValentin Clementsubroutine foo4(i)
865754bae4SValentin Clement  integer :: i(2, 5)
875754bae4SValentin Clement  call do_something(i)
885754bae4SValentin Clementend subroutine
895754bae4SValentin Clement! CHECK-LABEL: func @_QPcall_foo4(
905754bae4SValentin Clement! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<10xi32>>{{.*}}) {
915754bae4SValentin Clementsubroutine call_foo4(i)
925754bae4SValentin Clement  integer :: i(10)
935754bae4SValentin Clement  ! %[[argconvert:*]] = fir.convert %arg0 :
944cc9437aSTom Eccles  ! fir.call @_QPfoo4(%[[argconvert]]) {{.*}}: (!fir.ref<!fir.array<2x5xi32>>) -> ()
955754bae4SValentin Clement  call foo4(i)
965754bae4SValentin Clementend subroutine
97fe252f8eSValentin Clement! CHECK-LABEL: func @_QPpass_foo4() {
98fe252f8eSValentin Clementsubroutine pass_foo4()
99fe252f8eSValentin Clement  external :: foo4
100fe252f8eSValentin Clement  ! CHECK: %[[f:.*]] = fir.address_of(@_QPfoo4)
101fe252f8eSValentin Clement  ! CHECK: fir.emboxproc %[[f]] : ((!fir.ref<!fir.array<2x5xi32>>) -> ()) -> !fir.boxproc<() -> ()>
102fe252f8eSValentin Clement  call bar(foo4)
103fe252f8eSValentin Clementend subroutine
1045754bae4SValentin Clement
1055754bae4SValentin Clement! define, pass, call
1065754bae4SValentin Clement! CHECK-LABEL: func @_QPfoo5(
1075754bae4SValentin Clement! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<2x5xi32>>{{.*}}) {
1085754bae4SValentin Clementsubroutine foo5(i)
1095754bae4SValentin Clement  integer :: i(2, 5)
1105754bae4SValentin Clement  call do_something(i)
1115754bae4SValentin Clementend subroutine
112fe252f8eSValentin Clement! CHECK-LABEL: func @_QPpass_foo5() {
113fe252f8eSValentin Clementsubroutine pass_foo5()
114fe252f8eSValentin Clement  external :: foo5
115fe252f8eSValentin Clement  ! CHECK: %[[f:.*]] = fir.address_of(@_QPfoo5)
116fe252f8eSValentin Clement  ! CHECK: fir.emboxproc %[[f]] : ((!fir.ref<!fir.array<2x5xi32>>) -> ()) -> !fir.boxproc<() -> ()>
117fe252f8eSValentin Clement  call bar(foo5)
118fe252f8eSValentin Clementend subroutine
1195754bae4SValentin Clement! CHECK-LABEL: func @_QPcall_foo5(
1205754bae4SValentin Clement! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<10xi32>>{{.*}}) {
1215754bae4SValentin Clementsubroutine call_foo5(i)
1225754bae4SValentin Clement  integer :: i(10)
1235754bae4SValentin Clement  ! %[[argconvert:*]] = fir.convert %arg0 :
1244cc9437aSTom Eccles  ! fir.call @_QPfoo5(%[[argconvert]]) {{.*}}: (!fir.ref<!fir.array<2x5xi32>>) -> ()
1255754bae4SValentin Clement  call foo5(i)
1265754bae4SValentin Clementend subroutine
1275754bae4SValentin Clement
1285754bae4SValentin Clement
1295754bae4SValentin Clement! Test when there is no definition (declaration at the end of the mlir module)
1305754bae4SValentin Clement! First use gives the function type
1315754bae4SValentin Clement
1325754bae4SValentin Clement! call, pass
1335754bae4SValentin Clement! CHECK-LABEL: func @_QPcall_foo6(
1345754bae4SValentin Clement! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<10xi32>>{{.*}}) {
1355754bae4SValentin Clementsubroutine call_foo6(i)
1365754bae4SValentin Clement  integer :: i(10)
1375754bae4SValentin Clement  ! CHECK-NOT: convert
1385754bae4SValentin Clement  call foo6(i)
1395754bae4SValentin Clementend subroutine
140fe252f8eSValentin Clement! CHECK-LABEL: func @_QPpass_foo6() {
141fe252f8eSValentin Clementsubroutine pass_foo6()
142fe252f8eSValentin Clement  external :: foo6
143fe252f8eSValentin Clement  ! CHECK: %[[f:.*]] = fir.address_of(@_QPfoo6) : (!fir.ref<!fir.array<10xi32>>) -> ()
144fe252f8eSValentin Clement  ! CHECK: fir.emboxproc %[[f]] : ((!fir.ref<!fir.array<10xi32>>) -> ()) -> !fir.boxproc<() -> ()>
145fe252f8eSValentin Clement  call bar(foo6)
146fe252f8eSValentin Clementend subroutine
147fe252f8eSValentin Clement
148fe252f8eSValentin Clement! pass, call
149fe252f8eSValentin Clement! CHECK-LABEL: func @_QPpass_foo7() {
150fe252f8eSValentin Clementsubroutine pass_foo7()
151fe252f8eSValentin Clement  external :: foo7
152fe252f8eSValentin Clement  ! CHECK-NOT: convert
153fe252f8eSValentin Clement  call bar(foo7)
154fe252f8eSValentin Clementend subroutine
155fe252f8eSValentin Clement! CHECK-LABEL: func @_QPcall_foo7(
156fe252f8eSValentin Clement! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<10xi32>>{{.*}}) -> f32 {
157fe252f8eSValentin Clementfunction call_foo7(i)
158fe252f8eSValentin Clement  integer :: i(10)
159fe252f8eSValentin Clement  ! CHECK: %[[f:.*]] = fir.address_of(@_QPfoo7) : () -> ()
160fe252f8eSValentin Clement  ! CHECK: %[[funccast:.*]] = fir.convert %[[f]] : (() -> ()) -> ((!fir.ref<!fir.array<10xi32>>) -> f32)
1614cc9437aSTom Eccles  ! CHECK: fir.call %[[funccast]](%arg0) {{.*}}: (!fir.ref<!fir.array<10xi32>>) -> f32
162fe252f8eSValentin Clement  call_foo7 =  foo7(i)
163fe252f8eSValentin Clementend function
1645754bae4SValentin Clement
1655754bae4SValentin Clement
1665754bae4SValentin Clement! call, call with different type
1675754bae4SValentin Clement! CHECK-LABEL: func @_QPcall_foo8(
1685754bae4SValentin Clement! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<10xi32>>{{.*}}) {
1695754bae4SValentin Clementsubroutine call_foo8(i)
1705754bae4SValentin Clement  integer :: i(10)
1715754bae4SValentin Clement  ! CHECK-NOT: convert
1725754bae4SValentin Clement  call foo8(i)
1735754bae4SValentin Clementend subroutine
1745754bae4SValentin Clement! CHECK-LABEL: func @_QPcall_foo8_2(
1755754bae4SValentin Clement! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<2x5xi32>>{{.*}}) {
1765754bae4SValentin Clementsubroutine call_foo8_2(i)
1775754bae4SValentin Clement  integer :: i(2, 5)
1785754bae4SValentin Clement  ! %[[argconvert:*]] = fir.convert %arg0 :
1795754bae4SValentin Clement  call foo8(i)
1805754bae4SValentin Clementend subroutine
1815754bae4SValentin Clement
1825754bae4SValentin Clement! Test that target attribute is lowered in declaration of functions that are
1835754bae4SValentin Clement! not defined in this file.
1845754bae4SValentin Clement! CHECK-LABEL:func @_QPtest_target_in_iface
1855754bae4SValentin Clementsubroutine test_target_in_iface()
1865754bae4SValentin Clement  interface
1875754bae4SValentin Clement  subroutine test_target(i, x)
1885754bae4SValentin Clement    integer, target :: i
1895754bae4SValentin Clement    real, target :: x(:)
1905754bae4SValentin Clement  end subroutine
1915754bae4SValentin Clement  end interface
1925754bae4SValentin Clement  integer :: i
1935754bae4SValentin Clement  real :: x(10)
1945754bae4SValentin Clement  ! CHECK: fir.call @_QPtest_target
1955754bae4SValentin Clement  call test_target(i, x)
1965754bae4SValentin Clementend subroutine
1975754bae4SValentin Clement
1985754bae4SValentin Clement! CHECK: func private @_QPfoo6(!fir.ref<!fir.array<10xi32>>)
199fe252f8eSValentin Clement! CHECK: func private @_QPfoo7()
2005754bae4SValentin Clement
2015754bae4SValentin Clement! Test declaration from test_target_in_iface
2025754bae4SValentin Clement! CHECK-LABEL: func private @_QPtest_target(!fir.ref<i32> {fir.target}, !fir.box<!fir.array<?xf32>> {fir.target})
203