Break circular dependency between FIR dialect and utilities
[llvm-project.git] / flang / test / Lower / allocatable-callee.f90
blob5627cd44f62e12e476ce78c9c15f51eb6e8e5f3a
1 ! RUN: bbc -emit-fir %s -o - | FileCheck %s
3 ! Test allocatable dummy argument on callee side
5 ! CHECK-LABEL: func @_QPtest_scalar(
6 ! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.box<!fir.heap<f32>>>{{.*}})
7 subroutine test_scalar(x)
8 real, allocatable :: x
10 print *, x
11 ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref<!fir.box<!fir.heap<f32>>>
12 ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32>
13 ! CHECK: %[[val:.*]] = fir.load %[[addr]] : !fir.heap<f32>
14 end subroutine
16 ! CHECK-LABEL: func @_QPtest_array(
17 ! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>>{{.*}})
18 subroutine test_array(x)
19 integer, allocatable :: x(:,:)
21 print *, x(1,2)
22 ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>>
23 ! CHECK-DAG: fir.box_addr %[[box]] : (!fir.box<!fir.heap<!fir.array<?x?xi32>>>) -> !fir.heap<!fir.array<?x?xi32>>
24 ! CHECK-DAG: fir.box_dims %[[box]], %c0{{.*}} : (!fir.box<!fir.heap<!fir.array<?x?xi32>>>, index) -> (index, index, index)
25 ! CHECK-DAG: fir.box_dims %[[box]], %c1{{.*}} : (!fir.box<!fir.heap<!fir.array<?x?xi32>>>, index) -> (index, index, index)
26 end subroutine
28 ! CHECK-LABEL: func @_QPtest_char_scalar_deferred(
29 ! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>{{.*}})
30 subroutine test_char_scalar_deferred(c)
31 character(:), allocatable :: c
32 external foo1
33 call foo1(c)
34 ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
35 ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> !fir.heap<!fir.char<1,?>>
36 ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> index
37 ! CHECK-DAG: %[[addr_cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,?>>
38 ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr_cast]], %[[len]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
39 ! CHECK: fir.call @_QPfoo1(%[[boxchar]]) {{.*}}: (!fir.boxchar<1>) -> ()
40 end subroutine
42 ! CHECK-LABEL: func @_QPtest_char_scalar_explicit_cst(
43 ! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.char<1,10>>>>{{.*}})
44 subroutine test_char_scalar_explicit_cst(c)
45 character(10), allocatable :: c
46 external foo1
47 call foo1(c)
48 ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,10>>>>
49 ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.heap<!fir.char<1,10>>>) -> !fir.heap<!fir.char<1,10>>
50 ! CHECK-DAG: %[[addr_cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.char<1,10>>) -> !fir.ref<!fir.char<1,?>>
51 ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr_cast]], %c10{{.*}} : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
52 ! CHECK: fir.call @_QPfoo1(%[[boxchar]]) {{.*}}: (!fir.boxchar<1>) -> ()
53 end subroutine
55 ! CHECK-LABEL: func @_QPtest_char_scalar_explicit_dynamic(
56 ! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>{{.*}}, %[[arg1:.*]]: !fir.ref<i32>{{.*}})
57 subroutine test_char_scalar_explicit_dynamic(c, n)
58 integer :: n
59 character(n), allocatable :: c
60 external foo1
61 ! Check that the length expr was evaluated before the execution parts.
62 ! CHECK: %[[raw_len:.*]] = fir.load %arg1 : !fir.ref<i32>
63 ! CHECK: %[[c0_i32:.*]] = arith.constant 0 : i32
64 ! CHECK: %[[cmp:.*]] = arith.cmpi sgt, %[[raw_len]], %[[c0_i32]] : i32
65 ! CHECK: %[[len:.*]] = arith.select %[[cmp]], %[[raw_len]], %[[c0_i32]] : i32
66 n = n + 1
67 ! CHECK: fir.store {{.*}} to %arg1 : !fir.ref<i32>
68 call foo1(c)
69 ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
70 ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> !fir.heap<!fir.char<1,?>>
71 ! CHECK-DAG: %[[addr_cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,?>>
72 ! CHECK-DAG: %[[len_cast:.*]] = fir.convert %[[len]] : (i32) -> index
73 ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr_cast]], %[[len_cast]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
74 ! CHECK: fir.call @_QPfoo1(%[[boxchar]]) {{.*}}: (!fir.boxchar<1>) -> ()
75 end subroutine
77 ! CHECK-LABEL: func @_QPtest_char_array_deferred(
78 ! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>{{.*}})
79 subroutine test_char_array_deferred(c)
80 character(:), allocatable :: c(:)
81 external foo1
82 call foo1(c(10))
83 ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>
84 ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>) -> !fir.heap<!fir.array<?x!fir.char<1,?>>>
85 ! CHECK-DAG: fir.box_dims %[[box]], %c0{{.*}} : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>, index) -> (index, index, index)
86 ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>) -> index
87 ! [...] address computation
88 ! CHECK: %[[boxchar:.*]] = fir.emboxchar %{{.*}}, %[[len]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
89 ! CHECK: fir.call @_QPfoo1(%[[boxchar]]) {{.*}}: (!fir.boxchar<1>) -> ()
90 end subroutine
92 ! CHECK-LABEL: func @_QPtest_char_array_explicit_cst(
93 ! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>>{{.*}})
94 subroutine test_char_array_explicit_cst(c)
95 character(10), allocatable :: c(:)
96 external foo1
97 call foo1(c(3))
98 ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>>
99 ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>) -> !fir.heap<!fir.array<?x!fir.char<1,10>>>
100 ! [...] address computation
101 ! CHECK: %[[boxchar:.*]] = fir.emboxchar %{{.*}}, %c10{{.*}} : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
102 ! CHECK: fir.call @_QPfoo1(%[[boxchar]]) {{.*}}: (!fir.boxchar<1>) -> ()
103 end subroutine
105 ! CHECK-LABEL: func @_QPtest_char_array_explicit_dynamic(
106 ! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>{{.*}}, %[[arg1:.*]]: !fir.ref<i32>{{.*}})
107 subroutine test_char_array_explicit_dynamic(c, n)
108 integer :: n
109 character(n), allocatable :: c(:)
110 external foo1
111 ! Check that the length expr was evaluated before the execution parts.
112 ! CHECK: %[[raw_len:.*]] = fir.load %arg1 : !fir.ref<i32>
113 ! CHECK: %[[c0_i32:.*]] = arith.constant 0 : i32
114 ! CHECK: %[[cmp:.*]] = arith.cmpi sgt, %[[raw_len]], %[[c0_i32]] : i32
115 ! CHECK: %[[len:.*]] = arith.select %[[cmp]], %[[raw_len]], %[[c0_i32]] : i32
116 n = n + 1
117 ! CHECK: fir.store {{.*}} to %arg1 : !fir.ref<i32>
118 call foo1(c(1))
119 ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>
120 ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>) -> !fir.heap<!fir.array<?x!fir.char<1,?>>>
121 ! [...] address computation
122 ! CHECK: fir.coordinate_of
123 ! CHECK-DAG: %[[len_cast:.*]] = fir.convert %[[len]] : (i32) -> index
124 ! CHECK: %[[boxchar:.*]] = fir.emboxchar %{{.*}}, %[[len_cast]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
125 ! CHECK: fir.call @_QPfoo1(%[[boxchar]]) {{.*}}: (!fir.boxchar<1>) -> ()
126 end subroutine
128 ! Check that when reading allocatable length from descriptor, the width is taking
129 ! into account when the kind is not 1.
131 ! CHECK-LABEL: func @_QPtest_char_scalar_deferred_k2(
132 ! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.char<2,?>>>>{{.*}})
133 subroutine test_char_scalar_deferred_k2(c)
134 character(kind=2, len=:), allocatable :: c
135 external foo2
136 call foo2(c)
137 ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref<!fir.box<!fir.heap<!fir.char<2,?>>>>
138 ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.heap<!fir.char<2,?>>>) -> !fir.heap<!fir.char<2,?>>
139 ! CHECK-DAG: %[[size:.*]] = fir.box_elesize %[[box]] : (!fir.box<!fir.heap<!fir.char<2,?>>>) -> index
140 ! CHECK-DAG: %[[len:.*]] = arith.divsi %[[size]], %c2{{.*}} : index
141 ! CHECK-DAG: %[[addr_cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.char<2,?>>) -> !fir.ref<!fir.char<2,?>>
142 ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr_cast]], %[[len]] : (!fir.ref<!fir.char<2,?>>, index) -> !fir.boxchar<2>
143 ! CHECK: fir.call @_QPfoo2(%[[boxchar]]) {{.*}}: (!fir.boxchar<2>) -> ()
144 end subroutine
146 ! Check that assumed length character allocatables are reading the length from
147 ! the descriptor.
149 ! CHECK-LABEL: _QPtest_char_assumed(
150 ! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>{{.*}}
151 subroutine test_char_assumed(a)
152 integer :: n
153 character(len=*), allocatable :: a
154 ! CHECK: %[[argLoad:.*]] = fir.load %[[arg0]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
155 ! CHECK: %[[argLen:.*]] = fir.box_elesize %[[argLoad]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> index
157 n = len(a)
158 ! CHECK: %[[argLenCast:.*]] = fir.convert %[[argLen]] : (index) -> i32
159 ! CHECK: fir.store %[[argLenCast]] to %{{.*}} : !fir.ref<i32>
160 end subroutine
162 ! CHECK-LABEL: _QPtest_char_assumed_optional(
163 ! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>{{.*}}
164 subroutine test_char_assumed_optional(a)
165 integer :: n
166 character(len=*), allocatable, optional :: a
167 ! CHECK: %[[argPresent:.*]] = fir.is_present %[[arg0]] : (!fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>) -> i1
168 ! CHECK: %[[argLen:.*]] = fir.if %[[argPresent]] -> (index) {
169 ! CHECK: %[[argLoad:.*]] = fir.load %[[arg0]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
170 ! CHECK: %[[argEleSz:.*]] = fir.box_elesize %[[argLoad]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> index
171 ! CHECK: fir.result %[[argEleSz]] : index
172 ! CHECK: } else {
173 ! CHECK: %[[undef:.*]] = fir.undefined index
174 ! CHECK: fir.result %[[undef]] : index
176 if (present(a)) then
177 n = len(a)
178 ! CHECK: %[[argLenCast:.*]] = fir.convert %[[argLen]] : (index) -> i32
179 ! CHECK: fir.store %[[argLenCast]] to %{{.*}} : !fir.ref<i32>
180 endif
181 end subroutine