xref: /llvm-project/flang/test/Lower/assignment.f90 (revision c4204c0b29a6721267b1bcbaeedd7b1118e42396)
1! RUN: %flang_fc1 %s -o "-" -emit-fir -cpp -flang-deprecated-no-hlfir | FileCheck %s --check-prefixes=CHECK%if target=x86_64{{.*}} %{,CHECK-X86-64%}
2
3subroutine sub1(a)
4  integer :: a
5  a = 1
6end
7
8! CHECK-LABEL: func @_QPsub1(
9! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<i32>
10! CHECK:         %[[C1:.*]] = arith.constant 1 : i32
11! CHECK:         fir.store %[[C1]] to %[[ARG0]] : !fir.ref<i32>
12
13subroutine sub2(a, b)
14  integer(4) :: a
15  integer(8) :: b
16  a = b
17end
18
19! CHECK-LABEL: func @_QPsub2(
20! CHECK:         %[[A:.*]]: !fir.ref<i32> {fir.bindc_name = "a"}
21! CHECK:         %[[B:.*]]: !fir.ref<i64> {fir.bindc_name = "b"}
22! CHECK:         %[[B_VAL:.*]] = fir.load %arg1 : !fir.ref<i64>
23! CHECK:         %[[B_CONV:.*]] = fir.convert %[[B_VAL]] : (i64) -> i32
24! CHECK:         fir.store %[[B_CONV]] to %[[A]] : !fir.ref<i32>
25
26integer function negi(a)
27  integer :: a
28  negi = -a
29end
30
31! CHECK-LABEL: func @_QPnegi(
32! CHECK-SAME:    %[[A:.*]]: !fir.ref<i32> {fir.bindc_name = "a"}) -> i32 {
33! CHECK:         %[[FCTRES:.*]] = fir.alloca i32 {bindc_name = "negi", uniq_name = "_QFnegiEnegi"}
34! CHECK:         %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
35! CHECK:         %[[C0:.*]] = arith.constant 0 : i32
36! CHECK:         %[[NEG:.*]] = arith.subi %[[C0]], %[[A_VAL]] : i32
37! CHECK:         fir.store %[[NEG]] to %[[FCTRES]] : !fir.ref<i32>
38! CHECK:         %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<i32>
39! CHECK:         return %[[RET]] : i32
40
41real function negr(a)
42  real :: a
43  negr = -a
44end
45
46! CHECK-LABEL: func @_QPnegr(
47! CHECK-SAME:    %[[A:.*]]: !fir.ref<f32> {fir.bindc_name = "a"}) -> f32 {
48! CHECK:         %[[FCTRES:.*]] = fir.alloca f32 {bindc_name = "negr", uniq_name = "_QFnegrEnegr"}
49! CHECK:         %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<f32>
50! CHECK:         %[[NEG:.*]] = arith.negf %[[A_VAL]] {{.*}}: f32
51! CHECK:         fir.store %[[NEG]] to %[[FCTRES]] : !fir.ref<f32>
52! CHECK:         %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<f32>
53! CHECK:         return %[[RET]] : f32
54
55complex function negc(a)
56  complex :: a
57  negc = -a
58end
59
60! CHECK-LABEL: func @_QPnegc(
61! CHECK-SAME:    %[[A:.*]]: !fir.ref<complex<f32>> {fir.bindc_name = "a"}) -> complex<f32> {
62! CHECK:         %[[FCTRES:.*]] = fir.alloca complex<f32> {bindc_name = "negc", uniq_name = "_QFnegcEnegc"}
63! CHECK:         %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<complex<f32>>
64! CHECK:         %[[NEG:.*]] = fir.negc %[[A_VAL]] : complex<f32>
65! CHECK:         fir.store %[[NEG]] to %[[FCTRES]] : !fir.ref<complex<f32>>
66
67integer function addi(a, b)
68  integer :: a, b
69  addi = a + b
70end
71
72! CHECK-LABEL: func @_QPaddi(
73! CHECK-SAME:    %[[A:.*]]: !fir.ref<i32> {fir.bindc_name = "a"},
74! CHECK-SAME:    %[[B:.*]]: !fir.ref<i32> {fir.bindc_name = "b"}
75! CHECK:         %[[FCTRES:.*]] = fir.alloca i32
76! CHECK:         %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
77! CHECK:         %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
78! CHECK:         %[[ADD:.*]] = arith.addi %[[A_VAL]], %[[B_VAL]] : i32
79! CHECK:         fir.store %[[ADD]] to %[[FCTRES]] : !fir.ref<i32>
80! CHECK:         %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<i32>
81! CHECK:         return %[[RET]] : i32
82
83integer function subi(a, b)
84  integer :: a, b
85  subi = a - b
86end
87
88! CHECK-LABEL: func @_QPsubi(
89! CHECK-SAME:    %[[A:.*]]: !fir.ref<i32> {fir.bindc_name = "a"},
90! CHECK-SAME:    %[[B:.*]]: !fir.ref<i32> {fir.bindc_name = "b"}
91! CHECK:         %[[FCTRES:.*]] = fir.alloca i32
92! CHECK:         %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
93! CHECK:         %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
94! CHECK:         %[[SUB:.*]] = arith.subi %[[A_VAL]], %[[B_VAL]] : i32
95! CHECK:         fir.store %[[SUB]] to %[[FCTRES]] : !fir.ref<i32>
96! CHECK:         %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<i32>
97! CHECK:         return %[[RET]] : i32
98
99integer function muli(a, b)
100  integer :: a, b
101  muli = a * b
102end
103
104! CHECK-LABEL: func @_QPmuli(
105! CHECK-SAME:    %[[A:.*]]: !fir.ref<i32> {fir.bindc_name = "a"},
106! CHECK-SAME:    %[[B:.*]]: !fir.ref<i32> {fir.bindc_name = "b"}
107! CHECK:         %[[FCTRES:.*]] = fir.alloca i32
108! CHECK:         %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
109! CHECK:         %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
110! CHECK:         %[[MUL:.*]] = arith.muli %[[A_VAL]], %[[B_VAL]] : i32
111! CHECK:         fir.store %[[MUL]] to %[[FCTRES]] : !fir.ref<i32>
112! CHECK:         %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<i32>
113! CHECK:         return %[[RET]] : i32
114
115integer function divi(a, b)
116  integer :: a, b
117  divi = a / b
118end
119
120! CHECK-LABEL: func @_QPdivi(
121! CHECK-SAME:    %[[A:.*]]: !fir.ref<i32> {fir.bindc_name = "a"},
122! CHECK-SAME:    %[[B:.*]]: !fir.ref<i32> {fir.bindc_name = "b"}
123! CHECK:         %[[FCTRES:.*]] = fir.alloca i32
124! CHECK:         %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
125! CHECK:         %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
126! CHECK:         %[[DIV:.*]] = arith.divsi %[[A_VAL]], %[[B_VAL]] : i32
127! CHECK:         fir.store %[[DIV]] to %[[FCTRES]] : !fir.ref<i32>
128! CHECK:         %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<i32>
129! CHECK:         return %[[RET]] : i32
130
131real function addf(a, b)
132  real :: a, b
133  addf = a + b
134end
135
136! CHECK-LABEL: func @_QPaddf(
137! CHECK-SAME:    %[[A:.*]]: !fir.ref<f32> {fir.bindc_name = "a"},
138! CHECK-SAME:    %[[B:.*]]: !fir.ref<f32> {fir.bindc_name = "b"}
139! CHECK:         %[[FCTRES:.*]] = fir.alloca f32
140! CHECK:         %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<f32>
141! CHECK:         %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<f32>
142! CHECK:         %[[ADD:.*]] = arith.addf %[[A_VAL]], %[[B_VAL]] {{.*}}: f32
143! CHECK:         fir.store %[[ADD]] to %[[FCTRES]] : !fir.ref<f32>
144! CHECK:         %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<f32>
145! CHECK:         return %[[RET]] : f32
146
147real function subf(a, b)
148  real :: a, b
149  subf = a - b
150end
151
152! CHECK-LABEL: func @_QPsubf(
153! CHECK-SAME:    %[[A:.*]]: !fir.ref<f32> {fir.bindc_name = "a"},
154! CHECK-SAME:    %[[B:.*]]: !fir.ref<f32> {fir.bindc_name = "b"}
155! CHECK:         %[[FCTRES:.*]] = fir.alloca f32
156! CHECK:         %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<f32>
157! CHECK:         %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<f32>
158! CHECK:         %[[SUB:.*]] = arith.subf %[[A_VAL]], %[[B_VAL]] {{.*}}: f32
159! CHECK:         fir.store %[[SUB]] to %[[FCTRES]] : !fir.ref<f32>
160! CHECK:         %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<f32>
161! CHECK:         return %[[RET]] : f32
162
163real function mulf(a, b)
164  real :: a, b
165  mulf = a * b
166end
167
168! CHECK-LABEL: func @_QPmulf(
169! CHECK-SAME:    %[[A:.*]]: !fir.ref<f32> {fir.bindc_name = "a"},
170! CHECK-SAME:    %[[B:.*]]: !fir.ref<f32> {fir.bindc_name = "b"}
171! CHECK:         %[[FCTRES:.*]] = fir.alloca f32
172! CHECK:         %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<f32>
173! CHECK:         %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<f32>
174! CHECK:         %[[MUL:.*]] = arith.mulf %[[A_VAL]], %[[B_VAL]] {{.*}}: f32
175! CHECK:         fir.store %[[MUL]] to %[[FCTRES]] : !fir.ref<f32>
176! CHECK:         %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<f32>
177! CHECK:         return %[[RET]] : f32
178
179real function divf(a, b)
180  real :: a, b
181  divf = a / b
182end
183
184! CHECK-LABEL: func @_QPdivf(
185! CHECK-SAME:    %[[A:.*]]: !fir.ref<f32> {fir.bindc_name = "a"},
186! CHECK-SAME:    %[[B:.*]]: !fir.ref<f32> {fir.bindc_name = "b"}
187! CHECK:         %[[FCTRES:.*]] = fir.alloca f32
188! CHECK:         %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<f32>
189! CHECK:         %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<f32>
190! CHECK:         %[[DIV:.*]] = arith.divf %[[A_VAL]], %[[B_VAL]] {{.*}}: f32
191! CHECK:         fir.store %[[DIV]] to %[[FCTRES]] : !fir.ref<f32>
192! CHECK:         %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<f32>
193! CHECK:         return %[[RET]] : f32
194
195complex function addc(a, b)
196  complex :: a, b
197  addc = a + b
198end
199
200! CHECK-LABEL: func @_QPaddc(
201! CHECK-SAME:    %[[A:.*]]: !fir.ref<complex<f32>> {fir.bindc_name = "a"},
202! CHECK-SAME:    %[[B:.*]]: !fir.ref<complex<f32>> {fir.bindc_name = "b"}
203! CHECK:         %[[FCTRES:.*]] = fir.alloca complex<f32>
204! CHECK:         %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<complex<f32>>
205! CHECK:         %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<complex<f32>>
206! CHECK:         %[[ADD:.*]] = fir.addc %[[A_VAL]], %[[B_VAL]] {fastmath = #arith.fastmath<contract>} : complex<f32>
207! CHECK:         fir.store %[[ADD]] to %[[FCTRES]] : !fir.ref<complex<f32>>
208! CHECK:         %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<complex<f32>>
209! CHECK:         return %[[RET]] : complex<f32>
210
211complex function subc(a, b)
212  complex :: a, b
213  subc = a - b
214end
215
216! CHECK-LABEL: func @_QPsubc(
217! CHECK-SAME:    %[[A:.*]]: !fir.ref<complex<f32>> {fir.bindc_name = "a"},
218! CHECK-SAME:    %[[B:.*]]: !fir.ref<complex<f32>> {fir.bindc_name = "b"}
219! CHECK:         %[[FCTRES:.*]] = fir.alloca complex<f32>
220! CHECK:         %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<complex<f32>>
221! CHECK:         %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<complex<f32>>
222! CHECK:         %[[SUB:.*]] = fir.subc %[[A_VAL]], %[[B_VAL]] {fastmath = #arith.fastmath<contract>} : complex<f32>
223! CHECK:         fir.store %[[SUB]] to %[[FCTRES]] : !fir.ref<complex<f32>>
224! CHECK:         %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<complex<f32>>
225! CHECK:         return %[[RET]] : complex<f32>
226
227complex function mulc(a, b)
228  complex :: a, b
229  mulc = a * b
230end
231
232! CHECK-LABEL: func @_QPmulc(
233! CHECK-SAME:    %[[A:.*]]: !fir.ref<complex<f32>> {fir.bindc_name = "a"},
234! CHECK-SAME:    %[[B:.*]]: !fir.ref<complex<f32>> {fir.bindc_name = "b"}
235! CHECK:         %[[FCTRES:.*]] = fir.alloca complex<f32>
236! CHECK:         %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<complex<f32>>
237! CHECK:         %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<complex<f32>>
238! CHECK:         %[[MUL:.*]] = fir.mulc %[[A_VAL]], %[[B_VAL]] {fastmath = #arith.fastmath<contract>} : complex<f32>
239! CHECK:         fir.store %[[MUL]] to %[[FCTRES]] : !fir.ref<complex<f32>>
240! CHECK:         %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<complex<f32>>
241! CHECK:         return %[[RET]] : complex<f32>
242
243complex function divc(a, b)
244  complex :: a, b
245  divc = a / b
246end
247
248! CHECK-LABEL: func @_QPdivc(
249! CHECK-SAME:    %[[A:.*]]: !fir.ref<complex<f32>> {fir.bindc_name = "a"},
250! CHECK-SAME:    %[[B:.*]]: !fir.ref<complex<f32>> {fir.bindc_name = "b"}
251! CHECK:         %[[FCTRES:.*]] = fir.alloca complex<f32>
252! CHECK:         %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<complex<f32>>
253! CHECK:         %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<complex<f32>>
254! CHECK:         %[[A_REAL:.*]] = fir.extract_value %[[A_VAL]], [0 : index] : (complex<f32>) -> f32
255! CHECK:         %[[A_IMAG:.*]] = fir.extract_value %[[A_VAL]], [1 : index] : (complex<f32>) -> f32
256! CHECK:         %[[B_REAL:.*]] = fir.extract_value %[[B_VAL]], [0 : index] : (complex<f32>) -> f32
257! CHECK:         %[[B_IMAG:.*]] = fir.extract_value %[[B_VAL]], [1 : index] : (complex<f32>) -> f32
258! CHECK:         %[[DIV:.*]] = fir.call @__divsc3(%[[A_REAL]], %[[A_IMAG]], %[[B_REAL]], %[[B_IMAG]]) fastmath<contract> : (f32, f32, f32, f32) -> complex<f32>
259! CHECK:         fir.store %[[DIV]] to %[[FCTRES]] : !fir.ref<complex<f32>>
260! CHECK:         %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<complex<f32>>
261! CHECK:         return %[[RET]] : complex<f32>
262
263subroutine real_constant()
264  real(2) :: a
265  real(4) :: b
266  real(8) :: c
267#if __x86_64__
268  real(10) :: d
269#endif
270  real(16) :: e
271  a = 2.0_2
272  b = 4.0_4
273  c = 8.0_8
274#if __x86_64__
275  d = 10.0_10
276#endif
277  e = 16.0_16
278end
279
280! CHECK: %[[A:.*]] = fir.alloca f16
281! CHECK: %[[B:.*]] = fir.alloca f32
282! CHECK: %[[C:.*]] = fir.alloca f64
283! CHECK-X86-64: %[[D:.*]] = fir.alloca f80
284! CHECK: %[[E:.*]] = fir.alloca f128
285! CHECK: %[[C2:.*]] = arith.constant 2.000000e+00 : f16
286! CHECK: fir.store %[[C2]] to %[[A]] : !fir.ref<f16>
287! CHECK: %[[C4:.*]] = arith.constant 4.000000e+00 : f32
288! CHECK: fir.store %[[C4]] to %[[B]] : !fir.ref<f32>
289! CHECK: %[[C8:.*]] = arith.constant 8.000000e+00 : f64
290! CHECK: fir.store %[[C8]] to %[[C]] : !fir.ref<f64>
291! CHECK-X86-64: %[[C10:.*]] = arith.constant 1.000000e+01 : f80
292! CHECK-X86-64: fir.store %[[C10]] to %[[D]] : !fir.ref<f80>
293! CHECK: %[[C16:.*]] = arith.constant 1.600000e+01 : f128
294! CHECK: fir.store %[[C16]] to %[[E]] : !fir.ref<f128>
295
296subroutine complex_constant()
297  complex(4) :: a
298  a = (0, 1)
299end
300
301! CHECK-LABEL: func @_QPcomplex_constant()
302! CHECK:         %[[A:.*]] = fir.alloca complex<f32> {bindc_name = "a", uniq_name = "_QFcomplex_constantEa"}
303! CHECK:         %[[C0:.*]] = arith.constant 0.000000e+00 : f32
304! CHECK:         %[[C1:.*]] = arith.constant 1.000000e+00 : f32
305! CHECK:         %[[UNDEF:.*]] = fir.undefined complex<f32>
306! CHECK:         %[[INS0:.*]] = fir.insert_value %[[UNDEF]], %[[C0]], [0 : index] : (complex<f32>, f32) -> complex<f32>
307! CHECK:         %[[INS1:.*]] = fir.insert_value %[[INS0]], %[[C1]], [1 : index] : (complex<f32>, f32) -> complex<f32>
308! CHECK:         fir.store %[[INS1]] to %[[A]] : !fir.ref<complex<f32>>
309
310subroutine sub1_arr(a)
311  integer :: a(10)
312  a(2) = 10
313end
314
315! CHECK-LABEL: func @_QPsub1_arr(
316! CHECK-SAME:    %[[A:.*]]: !fir.ref<!fir.array<10xi32>> {fir.bindc_name = "a"})
317! CHECK-DAG:     %[[C10:.*]] = arith.constant 10 : i32
318! CHECK-DAG:     %[[C2:.*]] = arith.constant 2 : i64
319! CHECK-DAG:     %[[C1:.*]] = arith.constant 1 : i64
320! CHECK:         %[[ZERO_BASED_INDEX:.*]] = arith.subi %[[C2]], %[[C1]] : i64
321! CHECK:         %[[COORD:.*]] = fir.coordinate_of %[[A]], %[[ZERO_BASED_INDEX]] : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
322! CHECK:         fir.store %[[C10]] to %[[COORD]] : !fir.ref<i32>
323! CHECK:         return
324
325subroutine sub2_arr(a)
326  integer :: a(10)
327  a = 10
328end
329
330! CHECK-LABEL: func @_QPsub2_arr(
331! CHECK-SAME:    %[[A:.*]]: !fir.ref<!fir.array<10xi32>> {fir.bindc_name = "a"})
332! CHECK-DAG:     %[[C10_0:.*]] = arith.constant 10 : index
333! CHECK:         %[[SHAPE:.*]] = fir.shape %[[C10_0]] : (index) -> !fir.shape<1>
334! CHECK:         %[[LOAD:.*]] = fir.array_load %[[A]](%[[SHAPE]]) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.array<10xi32>
335! CHECK-DAG:     %[[C10_1:.*]] = arith.constant 10 : i32
336! CHECK-DAG:     %[[C1:.*]] = arith.constant 1 : index
337! CHECK-DAG:     %[[C0:.*]] = arith.constant 0 : index
338! CHECK-DAG:     %[[UB:.*]] = arith.subi %[[C10_0]], %c1 : index
339! CHECK:         %[[DO_RES:.*]] = fir.do_loop %[[ARG1:.*]] = %[[C0]] to %[[UB]] step %[[C1]] unordered iter_args(%[[ARG2:.*]] = %[[LOAD]]) -> (!fir.array<10xi32>) {
340! CHECK:           %[[RES:.*]] = fir.array_update %[[ARG2]], %[[C10_1]], %[[ARG1]] : (!fir.array<10xi32>, i32, index) -> !fir.array<10xi32>
341! CHECK:           fir.result %[[RES]] : !fir.array<10xi32>
342! CHECK:         }
343! CHECK:         fir.array_merge_store %[[LOAD]], %[[DO_RES]] to %[[A]] : !fir.array<10xi32>, !fir.array<10xi32>, !fir.ref<!fir.array<10xi32>>
344! CHECK:         return
345