xref: /llvm-project/flang/test/Lower/array-user-def-assignments.f90 (revision 3be8e3ad0c424dbeb9e4c8401174335e106a2d5d)
1! Test lower of elemental user defined assignments
2! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s
3
4module defined_assignments
5  type t
6    integer :: i
7  end type
8  interface assignment(=)
9    elemental subroutine assign_t(a,b)
10      import t
11      type(t),intent(out) :: a
12      type(t),intent(in) :: b
13    end
14  end interface
15  interface assignment(=)
16    elemental subroutine assign_logical_to_real(a,b)
17      real, intent(out) :: a
18      logical, intent(in) :: b
19    end
20  end interface
21  interface assignment(=)
22    elemental subroutine assign_real_to_logical(a,b)
23      logical, intent(out) :: a
24      real, intent(in) :: b
25    end
26  end interface
27end module
28
29! CHECK-LABEL: func @_QPtest_derived(
30! CHECK-SAME:        %arg0: !fir.ref<!fir.array<100x!fir.type<_QMdefined_assignmentsTt{i:i32}>>> {fir.bindc_name = "x"}) {
31! CHECK:     %[[C_100:[-0-9a-z_]+]] = arith.constant 100 : index
32! CHECK:     %[[V_0:[0-9]+]] = fir.shape %[[C_100]] : (index) -> !fir.shape<1>
33! CHECK:     %[[V_1:[0-9]+]] = fir.array_load %arg0(%[[V_0]]) : (!fir.ref<!fir.array<100x!fir.type<_QMdefined_assignmentsTt{i:i32}>>>, !fir.shape<1>) -> !fir.array<100x!fir.type<_QMdefined_assignmentsTt{i:i32}>>
34! CHECK:     %[[C_100_i64:[-0-9a-z_]+]] = arith.constant 100 : i64
35! CHECK:     %[[V_2:[0-9]+]] = fir.convert %[[C_100_i64]] : (i64) -> index
36! CHECK:     %[[C_m1_i64:[-0-9a-z_]+]] = arith.constant -1 : i64
37! CHECK:     %[[V_3:[0-9]+]] = fir.convert %[[C_m1_i64]] : (i64) -> index
38! CHECK:     %[[C_1_i64:[-0-9a-z_]+]] = arith.constant 1 : i64
39! CHECK:     %[[V_4:[0-9]+]] = fir.convert %[[C_1_i64]] : (i64) -> index
40! CHECK:     %[[V_5:[0-9]+]] = fir.shape %[[C_100]] : (index) -> !fir.shape<1>
41! CHECK:     %[[V_6:[0-9]+]] = fir.slice %[[V_2]], %[[V_4]], %[[V_3:[0-9]+]] : (index, index, index) -> !fir.slice<1>
42! CHECK:     %[[V_7:[0-9]+]] = fir.array_load %arg0(%[[V_5]]) [%[[V_6]]] : (!fir.ref<!fir.array<100x!fir.type<_QMdefined_assignmentsTt{i:i32}>>>, !fir.shape<1>, !fir.slice<1>) -> !fir.array<100x!fir.type<_QMdefined_assignmentsTt{i:i32}>>
43! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
44! CHECK:     %[[C_0:[-0-9a-z_]+]] = arith.constant 0 : index
45! CHECK:     %[[V_8:[0-9]+]] = arith.subi %[[C_100]], %[[C_1]] : index
46! CHECK:     %[[V_9:[0-9]+]] = fir.do_loop %arg1 = %[[C_0]] to %[[V_8]] step %[[C_1]] unordered iter_args(%arg2 = %[[V_1]]) -> (!fir.array<100x!fir.type<_QMdefined_assignmentsTt{i:i32}>>) {
47! CHECK:       %[[V_10:[0-9]+]] = fir.array_access %[[V_7]], %arg1 : (!fir.array<100x!fir.type<_QMdefined_assignmentsTt{i:i32}>>, index) -> !fir.ref<!fir.type<_QMdefined_assignmentsTt{i:i32}>>
48! CHECK:       %[[V_11:[0-9]+]] = fir.no_reassoc %[[V_10:[0-9]+]] : !fir.ref<!fir.type<_QMdefined_assignmentsTt{i:i32}>>
49! CHECK:       %[[V_12:[0-9]+]]:2 = fir.array_modify %arg2, %arg1 : (!fir.array<100x!fir.type<_QMdefined_assignmentsTt{i:i32}>>, index) -> (!fir.ref<!fir.type<_QMdefined_assignmentsTt{i:i32}>>, !fir.array<100x!fir.type<_QMdefined_assignmentsTt{i:i32}>>)
50! CHECK:       fir.call @_QPassign_t(%[[V_12]]#0, %[[V_11]]) fastmath<contract> : (!fir.ref<!fir.type<_QMdefined_assignmentsTt{i:i32}>>, !fir.ref<!fir.type<_QMdefined_assignmentsTt{i:i32}>>) -> ()
51! CHECK:       fir.result %[[V_12]]#1 : !fir.array<100x!fir.type<_QMdefined_assignmentsTt{i:i32}>>
52! CHECK:     }
53! CHECK:     fir.array_merge_store %[[V_1]], %[[V_9]] to %arg0 : !fir.array<100x!fir.type<_QMdefined_assignmentsTt{i:i32}>>, !fir.array<100x!fir.type<_QMdefined_assignmentsTt{i:i32}>>, !fir.ref<!fir.array<100x!fir.type<_QMdefined_assignmentsTt{i:i32}>>>
54! CHECK:     return
55! CHECK:   }
56
57! CHECK-LABEL: func @_QPtest_intrinsic(
58! CHECK-SAME:                          %arg0: !fir.ref<!fir.array<100xf32>> {fir.bindc_name = "x"}) {
59! CHECK:     %[[V_0:[0-9]+]] = fir.alloca !fir.logical<4>
60! CHECK:     %[[C_100:[-0-9a-z_]+]] = arith.constant 100 : index
61! CHECK:     %[[V_1:[0-9]+]] = fir.shape %[[C_100]] : (index) -> !fir.shape<1>
62! CHECK:     %[[V_2:[0-9]+]] = fir.array_load %arg0(%[[V_1]]) : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> !fir.array<100xf32>
63! CHECK:     %[[C_100_i64:[-0-9a-z_]+]] = arith.constant 100 : i64
64! CHECK:     %[[V_3:[0-9]+]] = fir.convert %[[C_100_i64]] : (i64) -> index
65! CHECK:     %[[C_m1_i64:[-0-9a-z_]+]] = arith.constant -1 : i64
66! CHECK:     %[[V_4:[0-9]+]] = fir.convert %[[C_m1_i64]] : (i64) -> index
67! CHECK:     %[[C_1_i64:[-0-9a-z_]+]] = arith.constant 1 : i64
68! CHECK:     %[[V_5:[0-9]+]] = fir.convert %[[C_1_i64]] : (i64) -> index
69! CHECK:     %[[V_6:[0-9]+]] = fir.shape %[[C_100]] : (index) -> !fir.shape<1>
70! CHECK:     %[[V_7:[0-9]+]] = fir.slice %[[V_3]], %[[V_5]], %[[V_4:[0-9]+]] : (index, index, index) -> !fir.slice<1>
71! CHECK:     %[[V_8:[0-9]+]] = fir.array_load %arg0(%[[V_6]]) [%[[V_7]]] : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.array<100xf32>
72! CHECK:     %[[C_st:[-0-9a-z_]+]] = arith.constant 0.000000e+00 : f32
73! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
74! CHECK:     %[[C_0:[-0-9a-z_]+]] = arith.constant 0 : index
75! CHECK:     %[[V_9:[0-9]+]] = arith.subi %[[C_100]], %[[C_1]] : index
76! CHECK:     %[[V_10:[0-9]+]] = fir.do_loop %arg1 = %[[C_0]] to %[[V_9]] step %[[C_1]] unordered iter_args(%arg2 = %[[V_2]]) -> (!fir.array<100xf32>) {
77! CHECK:       %[[V_11:[0-9]+]] = fir.array_fetch %[[V_8]], %arg1 : (!fir.array<100xf32>, index) -> f32
78! CHECK:       %[[V_12:[0-9]+]] = arith.cmpf olt, %[[V_11]], %[[C_st]] {{.*}} : f32
79! CHECK:       %[[V_13:[0-9]+]]:2 = fir.array_modify %arg2, %arg1 : (!fir.array<100xf32>, index) -> (!fir.ref<f32>, !fir.array<100xf32>)
80! CHECK:       %[[V_14:[0-9]+]] = fir.convert %[[V_12:[0-9]+]] : (i1) -> !fir.logical<4>
81! CHECK:       fir.store %[[V_14]] to %[[V_0:[0-9]+]] : !fir.ref<!fir.logical<4>>
82! CHECK:       fir.call @_QPassign_logical_to_real(%[[V_13]]#0, %[[V_0]]) fastmath<contract> : (!fir.ref<f32>, !fir.ref<!fir.logical<4>>) -> ()
83! CHECK:       fir.result %[[V_13]]#1 : !fir.array<100xf32>
84! CHECK:     }
85! CHECK:     fir.array_merge_store %[[V_2]], %[[V_10]] to %arg0 : !fir.array<100xf32>, !fir.array<100xf32>, !fir.ref<!fir.array<100xf32>>
86! CHECK:     return
87! CHECK:   }
88
89! CHECK-LABEL: func @_QPtest_intrinsic_2(
90! CHECK-SAME:                            %arg0: !fir.ref<!fir.array<100x!fir.logical<4>>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.array<100xf32>> {fir.bindc_name = "y"}) {
91! CHECK:     %[[V_0:[0-9]+]] = fir.alloca f32
92! CHECK:     %[[C_100:[-0-9a-z_]+]] = arith.constant 100 : index
93! CHECK:     %[[C_100_0:[-0-9a-z_]+]] = arith.constant 100 : index
94! CHECK:     %[[V_1:[0-9]+]] = fir.shape %[[C_100]] : (index) -> !fir.shape<1>
95! CHECK:     %[[V_2:[0-9]+]] = fir.array_load %arg0(%[[V_1]]) : (!fir.ref<!fir.array<100x!fir.logical<4>>>, !fir.shape<1>) -> !fir.array<100x!fir.logical<4>>
96! CHECK:     %[[V_3:[0-9]+]] = fir.shape %[[C_100_0]] : (index) -> !fir.shape<1>
97! CHECK:     %[[V_4:[0-9]+]] = fir.array_load %arg1(%[[V_3]]) : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> !fir.array<100xf32>
98! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
99! CHECK:     %[[C_0:[-0-9a-z_]+]] = arith.constant 0 : index
100! CHECK:     %[[V_5:[0-9]+]] = arith.subi %[[C_100]], %[[C_1]] : index
101! CHECK:     %[[V_6:[0-9]+]] = fir.do_loop %arg2 = %[[C_0]] to %[[V_5]] step %[[C_1]] unordered iter_args(%arg3 = %[[V_2]]) -> (!fir.array<100x!fir.logical<4>>) {
102! CHECK:       %[[V_7:[0-9]+]] = fir.array_fetch %[[V_4]], %arg2 : (!fir.array<100xf32>, index) -> f32
103! CHECK:       %[[V_8:[0-9]+]] = fir.no_reassoc %[[V_7:[0-9]+]] : f32
104! CHECK:       %[[V_9:[0-9]+]]:2 = fir.array_modify %arg3, %arg2 : (!fir.array<100x!fir.logical<4>>, index) -> (!fir.ref<!fir.logical<4>>, !fir.array<100x!fir.logical<4>>)
105! CHECK:       fir.store %[[V_8]] to %[[V_0:[0-9]+]] : !fir.ref<f32>
106! CHECK:       fir.call @_QPassign_real_to_logical(%[[V_9]]#0, %[[V_0]]) fastmath<contract> : (!fir.ref<!fir.logical<4>>, !fir.ref<f32>) -> ()
107! CHECK:       fir.result %[[V_9]]#1 : !fir.array<100x!fir.logical<4>>
108! CHECK:     }
109! CHECK:     fir.array_merge_store %[[V_2]], %[[V_6]] to %arg0 : !fir.array<100x!fir.logical<4>>, !fir.array<100x!fir.logical<4>>, !fir.ref<!fir.array<100x!fir.logical<4>>>
110! CHECK:     return
111! CHECK:   }
112
113! CHECK-LABEL: func @_QPfrom_char(
114! CHECK-SAME:                     %arg0: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "i"}, %arg1: !fir.box<!fir.array<?x!fir.char<1,?>>> {fir.bindc_name = "c"}) {
115! CHECK:     %[[C_0:[-0-9a-z_]+]] = arith.constant 0 : index
116! CHECK:     %[[V_0:[0-9]+]]:3 = fir.box_dims %arg0, %[[C_0]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
117! CHECK:     %[[V_1:[0-9]+]] = fir.array_load %arg0 : (!fir.box<!fir.array<?xi32>>) -> !fir.array<?xi32>
118! CHECK:     %[[V_2:[0-9]+]] = fir.array_load %arg1 : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> !fir.array<?x!fir.char<1,?>>
119! CHECK:     %[[V_3:[0-9]+]] = fir.box_elesize %arg1 : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> index
120! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
121! CHECK:     %[[V_4:[0-9]+]] = arith.divsi %[[V_3]], %[[C_1]] : index
122! CHECK:     %[[C_1_0:[-0-9a-z_]+]] = arith.constant 1 : index
123! CHECK:     %[[C_0_1:[-0-9a-z_]+]] = arith.constant 0 : index
124! CHECK:     %[[V_5:[0-9]+]] = arith.subi %[[V_0]]#1, %[[C_1_0]] : index
125! CHECK:     %[[V_6:[0-9]+]] = fir.do_loop %arg2 = %[[C_0_1]] to %[[V_5]] step %[[C_1_0]] unordered iter_args(%arg3 = %[[V_1]]) -> (!fir.array<?xi32>) {
126! CHECK:       %[[V_7:[0-9]+]] = fir.array_access %[[V_2]], %arg2 typeparams %[[V_4:[0-9]+]] : (!fir.array<?x!fir.char<1,?>>, index, index) -> !fir.ref<!fir.char<1,?>>
127! CHECK:       %[[V_8:[0-9]+]] = fir.box_elesize %arg1 : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> index
128! CHECK:       %[[V_9:[0-9]+]] = fir.no_reassoc %[[V_7:[0-9]+]] : !fir.ref<!fir.char<1,?>>
129! CHECK:       %[[V_10:[0-9]+]]:2 = fir.array_modify %arg3, %arg2 : (!fir.array<?xi32>, index) -> (!fir.ref<i32>, !fir.array<?xi32>)
130! CHECK:       %[[V_11:[0-9]+]] = fir.emboxchar %[[V_9]], %[[V_8:[0-9]+]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
131! CHECK:       fir.call @_QPsfrom_char(%[[V_10]]#0, %[[V_11]]) fastmath<contract> : (!fir.ref<i32>, !fir.boxchar<1>) -> ()
132! CHECK:       fir.result %[[V_10]]#1 : !fir.array<?xi32>
133! CHECK:     }
134! CHECK:     fir.array_merge_store %[[V_1]], %[[V_6]] to %arg0 : !fir.array<?xi32>, !fir.array<?xi32>, !fir.box<!fir.array<?xi32>>
135! CHECK:     return
136! CHECK:   }
137
138! CHECK-LABEL: func @_QPto_char(
139! CHECK-SAME:                   %arg0: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "i"}, %arg1: !fir.box<!fir.array<?x!fir.char<1,?>>> {fir.bindc_name = "c"}) {
140! CHECK:     %[[V_0:[0-9]+]] = fir.alloca i32
141! CHECK:     %[[C_0:[-0-9a-z_]+]] = arith.constant 0 : index
142! CHECK:     %[[V_1:[0-9]+]]:3 = fir.box_dims %arg1, %[[C_0]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>, index) -> (index, index, index)
143! CHECK:     %[[V_2:[0-9]+]] = fir.array_load %arg1 : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> !fir.array<?x!fir.char<1,?>>
144! CHECK:     %[[V_3:[0-9]+]] = fir.array_load %arg0 : (!fir.box<!fir.array<?xi32>>) -> !fir.array<?xi32>
145! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
146! CHECK:     %[[C_0_0:[-0-9a-z_]+]] = arith.constant 0 : index
147! CHECK:     %[[V_4:[0-9]+]] = arith.subi %[[V_1]]#1, %[[C_1]] : index
148! CHECK:     %[[V_5:[0-9]+]] = fir.do_loop %arg2 = %[[C_0_0]] to %[[V_4]] step %[[C_1]] unordered iter_args(%arg3 = %[[V_2]]) -> (!fir.array<?x!fir.char<1,?>>) {
149! CHECK:       %[[V_6:[0-9]+]] = fir.array_fetch %[[V_3]], %arg2 : (!fir.array<?xi32>, index) -> i32
150! CHECK:       %[[V_7:[0-9]+]] = fir.no_reassoc %[[V_6:[0-9]+]] : i32
151! CHECK:       %[[V_8:[0-9]+]]:2 = fir.array_modify %arg3, %arg2 : (!fir.array<?x!fir.char<1,?>>, index) -> (!fir.ref<!fir.char<1,?>>, !fir.array<?x!fir.char<1,?>>)
152! CHECK:       %[[V_9:[0-9]+]] = fir.box_elesize %arg1 : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> index
153! CHECK:       %[[V_10:[0-9]+]] = fir.emboxchar %[[V_8]]#0, %[[V_9:[0-9]+]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
154! CHECK:       fir.store %[[V_7]] to %[[V_0:[0-9]+]] : !fir.ref<i32>
155! CHECK:       fir.call @_QPsto_char(%[[V_10]], %[[V_0]]) fastmath<contract> : (!fir.boxchar<1>, !fir.ref<i32>) -> ()
156! CHECK:       fir.result %[[V_8]]#1 : !fir.array<?x!fir.char<1,?>>
157! CHECK:     }
158! CHECK:     fir.array_merge_store %[[V_2]], %[[V_5]] to %arg1 : !fir.array<?x!fir.char<1,?>>, !fir.array<?x!fir.char<1,?>>, !fir.box<!fir.array<?x!fir.char<1,?>>>
159! CHECK:     return
160! CHECK:   }
161
162subroutine test_derived(x)
163  use defined_assignments
164  type(t) :: x(100)
165  x = x(100:1:-1)
166end subroutine
167
168subroutine test_intrinsic(x)
169  use defined_assignments
170  real :: x(100)
171  x = x(100:1:-1) .lt. 0.
172end subroutine
173
174subroutine test_intrinsic_2(x, y)
175  use defined_assignments
176  logical :: x(100)
177  real :: y(100)
178  x = y
179end subroutine
180
181subroutine from_char(i, c)
182  interface assignment(=)
183    elemental subroutine sfrom_char(a,b)
184      integer, intent(out) :: a
185      character(*),intent(in) :: b
186    end subroutine
187  end interface
188  integer :: i(:)
189  character(*) :: c(:)
190  i = c
191end subroutine
192
193subroutine to_char(i, c)
194  interface assignment(=)
195    elemental subroutine sto_char(a,b)
196      character(*), intent(out) :: a
197      integer,intent(in) :: b
198    end subroutine
199  end interface
200  integer :: i(:)
201  character(*) :: c(:)
202  c = i
203end subroutine
204
205! -----------------------------------------------------------------------------
206!     Test user defined assignments inside FORALL and WHERE
207! -----------------------------------------------------------------------------
208
209! CHECK-LABEL: func @_QPtest_in_forall_1(
210! CHECK-SAME:                            %arg0: !fir.ref<!fir.array<10x!fir.logical<4>>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.array<10xf32>> {fir.bindc_name = "y"}) {
211! CHECK:     %[[V_0:[0-9]+]] = fir.alloca f32
212! CHECK:     %[[V_1:[0-9]+]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
213! CHECK:     %[[C_10:[-0-9a-z_]+]] = arith.constant 10 : index
214! CHECK:     %[[C_10_0:[-0-9a-z_]+]] = arith.constant 10 : index
215! CHECK:     %[[C_1_i32:[-0-9a-z_]+]] = arith.constant 1 : i32
216! CHECK:     %[[V_2:[0-9]+]] = fir.convert %[[C_1_i32]] : (i32) -> index
217! CHECK:     %[[C_10_i32:[-0-9a-z_]+]] = arith.constant 10 : i32
218! CHECK:     %[[V_3:[0-9]+]] = fir.convert %[[C_10_i32]] : (i32) -> index
219! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
220! CHECK:     %[[V_4:[0-9]+]] = fir.shape %[[C_10]] : (index) -> !fir.shape<1>
221! CHECK:     %[[V_5:[0-9]+]] = fir.array_load %arg0(%[[V_4]]) : (!fir.ref<!fir.array<10x!fir.logical<4>>>, !fir.shape<1>) -> !fir.array<10x!fir.logical<4>>
222! CHECK:     %[[V_6:[0-9]+]] = fir.shape %[[C_10_0]] : (index) -> !fir.shape<1>
223! CHECK:     %[[V_7:[0-9]+]] = fir.array_load %arg1(%[[V_6]]) : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.array<10xf32>
224! CHECK:     %[[V_8:[0-9]+]] = fir.do_loop %arg2 = %[[V_2]] to %[[V_3]] step %[[C_1]] unordered iter_args(%arg3 = %[[V_5]]) -> (!fir.array<10x!fir.logical<4>>) {
225! CHECK:       %[[V_9:[0-9]+]] = fir.convert %arg2 : (index) -> i32
226! CHECK:       fir.store %[[V_9]] to %[[V_1:[0-9]+]] : !fir.ref<i32>
227! CHECK:       %[[C_1_1:[-0-9a-z_]+]] = arith.constant 1 : index
228! CHECK:       %[[V_10:[0-9]+]] = fir.load %[[V_1:[0-9]+]] : !fir.ref<i32>
229! CHECK:       %[[V_11:[0-9]+]] = fir.convert %[[V_10:[0-9]+]] : (i32) -> i64
230! CHECK:       %[[V_12:[0-9]+]] = fir.convert %[[V_11:[0-9]+]] : (i64) -> index
231! CHECK:       %[[V_13:[0-9]+]] = arith.subi %[[V_12]], %[[C_1_1]] : index
232! CHECK:       %[[V_14:[0-9]+]] = fir.array_fetch %[[V_7]], %[[V_13:[0-9]+]] : (!fir.array<10xf32>, index) -> f32
233! CHECK:       %[[V_15:[0-9]+]] = fir.no_reassoc %[[V_14:[0-9]+]] : f32
234! CHECK:       %[[C_1_2:[-0-9a-z_]+]] = arith.constant 1 : index
235! CHECK:       %[[V_16:[0-9]+]] = fir.load %[[V_1:[0-9]+]] : !fir.ref<i32>
236! CHECK:       %[[V_17:[0-9]+]] = fir.convert %[[V_16:[0-9]+]] : (i32) -> i64
237! CHECK:       %[[V_18:[0-9]+]] = fir.convert %[[V_17:[0-9]+]] : (i64) -> index
238! CHECK:       %[[V_19:[0-9]+]] = arith.subi %[[V_18]], %[[C_1_2]] : index
239! CHECK:       %[[V_20:[0-9]+]]:2 = fir.array_modify %arg3, %[[V_19:[0-9]+]] : (!fir.array<10x!fir.logical<4>>, index) -> (!fir.ref<!fir.logical<4>>, !fir.array<10x!fir.logical<4>>)
240! CHECK:       fir.store %[[V_15]] to %[[V_0:[0-9]+]] : !fir.ref<f32>
241! CHECK:       fir.call @_QPassign_real_to_logical(%[[V_20]]#0, %[[V_0]]) fastmath<contract> : (!fir.ref<!fir.logical<4>>, !fir.ref<f32>) -> ()
242! CHECK:       fir.result %[[V_20]]#1 : !fir.array<10x!fir.logical<4>>
243! CHECK:     }
244! CHECK:     fir.array_merge_store %[[V_5]], %[[V_8]] to %arg0 : !fir.array<10x!fir.logical<4>>, !fir.array<10x!fir.logical<4>>, !fir.ref<!fir.array<10x!fir.logical<4>>>
245! CHECK:     return
246! CHECK:   }
247
248! CHECK-LABEL: func @_QPtest_in_forall_2(
249! CHECK-SAME:                            %arg0: !fir.ref<!fir.array<10x!fir.logical<4>>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.array<10xf32>> {fir.bindc_name = "y"}) {
250! CHECK:     %[[V_0:[0-9]+]] = fir.alloca !fir.logical<4>
251! CHECK:     %[[V_1:[0-9]+]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
252! CHECK:     %[[C_10:[-0-9a-z_]+]] = arith.constant 10 : index
253! CHECK:     %[[C_1_i32:[-0-9a-z_]+]] = arith.constant 1 : i32
254! CHECK:     %[[V_2:[0-9]+]] = fir.convert %[[C_1_i32]] : (i32) -> index
255! CHECK:     %[[C_10_i32:[-0-9a-z_]+]] = arith.constant 10 : i32
256! CHECK:     %[[V_3:[0-9]+]] = fir.convert %[[C_10_i32]] : (i32) -> index
257! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
258! CHECK:     %[[V_4:[0-9]+]] = fir.shape %[[C_10]] : (index) -> !fir.shape<1>
259! CHECK:     %[[V_5:[0-9]+]] = fir.array_load %arg1(%[[V_4]]) : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.array<10xf32>
260! CHECK:     %[[V_6:[0-9]+]] = fir.do_loop %arg2 = %[[V_2]] to %[[V_3]] step %[[C_1]] unordered iter_args(%arg3 = %[[V_5]]) -> (!fir.array<10xf32>) {
261! CHECK:       %[[V_7:[0-9]+]] = fir.convert %arg2 : (index) -> i32
262! CHECK:       fir.store %[[V_7]] to %[[V_1:[0-9]+]] : !fir.ref<i32>
263! CHECK:       %[[C_1_0:[-0-9a-z_]+]] = arith.constant 1 : index
264! CHECK:       %[[V_8:[0-9]+]] = fir.load %[[V_1:[0-9]+]] : !fir.ref<i32>
265! CHECK:       %[[V_9:[0-9]+]] = fir.convert %[[V_8:[0-9]+]] : (i32) -> i64
266! CHECK:       %[[V_10:[0-9]+]] = fir.convert %[[V_9:[0-9]+]] : (i64) -> index
267! CHECK:       %[[V_11:[0-9]+]] = arith.subi %[[V_10]], %[[C_1_0]] : index
268! CHECK:       %[[V_12:[0-9]+]] = fir.array_fetch %[[V_5]], %[[V_11:[0-9]+]] : (!fir.array<10xf32>, index) -> f32
269! CHECK:       %[[C_st:[-0-9a-z_]+]] = arith.constant 0.000000e+00 : f32
270! CHECK:       %[[V_13:[0-9]+]] = arith.cmpf olt, %[[V_12]], %[[C_st]] {{.*}} : f32
271! CHECK:       %[[C_1_1:[-0-9a-z_]+]] = arith.constant 1 : index
272! CHECK:       %[[V_14:[0-9]+]] = fir.load %[[V_1:[0-9]+]] : !fir.ref<i32>
273! CHECK:       %[[V_15:[0-9]+]] = fir.convert %[[V_14:[0-9]+]] : (i32) -> i64
274! CHECK:       %[[V_16:[0-9]+]] = fir.convert %[[V_15:[0-9]+]] : (i64) -> index
275! CHECK:       %[[V_17:[0-9]+]] = arith.subi %[[V_16]], %[[C_1_1]] : index
276! CHECK:       %[[V_18:[0-9]+]]:2 = fir.array_modify %arg3, %[[V_17:[0-9]+]] : (!fir.array<10xf32>, index) -> (!fir.ref<f32>, !fir.array<10xf32>)
277! CHECK:       %[[V_19:[0-9]+]] = fir.convert %[[V_13:[0-9]+]] : (i1) -> !fir.logical<4>
278! CHECK:       fir.store %[[V_19]] to %[[V_0:[0-9]+]] : !fir.ref<!fir.logical<4>>
279! CHECK:       fir.call @_QPassign_logical_to_real(%[[V_18]]#0, %[[V_0]]) fastmath<contract> : (!fir.ref<f32>, !fir.ref<!fir.logical<4>>) -> ()
280! CHECK:       fir.result %[[V_18]]#1 : !fir.array<10xf32>
281! CHECK:     }
282! CHECK:     fir.array_merge_store %[[V_5]], %[[V_6]] to %arg1 : !fir.array<10xf32>, !fir.array<10xf32>, !fir.ref<!fir.array<10xf32>>
283! CHECK:     return
284! CHECK:   }
285
286! CHECK-LABEL: func @_QPtest_intrinsic_where_1(
287! CHECK-SAME:             %arg0: !fir.ref<!fir.array<10x!fir.logical<4>>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.array<10xf32>> {fir.bindc_name = "y"}, %arg2: !fir.ref<!fir.array<10x!fir.logical<4>>> {fir.bindc_name = "l"}) {
288! CHECK:     %[[V_0:[0-9]+]] = fir.alloca f32
289! CHECK:     %[[C_10:[-0-9a-z_]+]] = arith.constant 10 : index
290! CHECK:     %[[C_10_0:[-0-9a-z_]+]] = arith.constant 10 : index
291! CHECK:     %[[C_10_1:[-0-9a-z_]+]] = arith.constant 10 : index
292! CHECK:     %[[C_10_2:[-0-9a-z_]+]] = arith.constant 10 : index
293! CHECK:     %[[V_1:[0-9]+]] = fir.shape %[[C_10]] : (index) -> !fir.shape<1>
294! CHECK:     %[[V_2:[0-9]+]] = fir.array_load %arg2(%[[V_1]]) : (!fir.ref<!fir.array<10x!fir.logical<4>>>, !fir.shape<1>) -> !fir.array<10x!fir.logical<4>>
295! CHECK:     %[[V_3:[0-9]+]] = fir.allocmem !fir.array<10x!fir.logical<4>>
296! CHECK:     %[[V_4:[0-9]+]] = fir.shape %[[C_10_2]] : (index) -> !fir.shape<1>
297! CHECK:     %[[V_5:[0-9]+]] = fir.array_load %[[V_3]](%[[V_4]]) : (!fir.heap<!fir.array<10x!fir.logical<4>>>, !fir.shape<1>) -> !fir.array<10x!fir.logical<4>>
298! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
299! CHECK:     %[[C_0:[-0-9a-z_]+]] = arith.constant 0 : index
300! CHECK:     %[[V_6:[0-9]+]] = arith.subi %[[C_10_2]], %[[C_1]] : index
301! CHECK:     %[[V_7:[0-9]+]] = fir.do_loop %arg3 = %[[C_0]] to %[[V_6]] step %[[C_1]] unordered iter_args(%arg4 = %[[V_5]]) -> (!fir.array<10x!fir.logical<4>>) {
302! CHECK:       %[[V_15:[0-9]+]] = fir.array_fetch %[[V_2]], %arg3 : (!fir.array<10x!fir.logical<4>>, index) -> !fir.logical<4>
303! CHECK:       %[[V_16:[0-9]+]] = fir.array_update %arg4, %[[V_15]], %arg3 : (!fir.array<10x!fir.logical<4>>, !fir.logical<4>, index) -> !fir.array<10x!fir.logical<4>>
304! CHECK:       fir.result %[[V_16:[0-9]+]] : !fir.array<10x!fir.logical<4>>
305! CHECK:     }
306! CHECK:     fir.array_merge_store %[[V_5]], %[[V_7]] to %[[V_3:[0-9]+]] : !fir.array<10x!fir.logical<4>>, !fir.array<10x!fir.logical<4>>, !fir.heap<!fir.array<10x!fir.logical<4>>>
307! CHECK:     %[[V_8:[0-9]+]] = fir.shape %[[C_10_2]] : (index) -> !fir.shape<1>
308! CHECK:     %[[V_9:[0-9]+]] = fir.shape %[[C_10_0]] : (index) -> !fir.shape<1>
309! CHECK:     %[[V_10:[0-9]+]] = fir.array_load %arg0(%[[V_9]]) : (!fir.ref<!fir.array<10x!fir.logical<4>>>, !fir.shape<1>) -> !fir.array<10x!fir.logical<4>>
310! CHECK:     %[[V_11:[0-9]+]] = fir.shape %[[C_10_1]] : (index) -> !fir.shape<1>
311! CHECK:     %[[V_12:[0-9]+]] = fir.array_load %arg1(%[[V_11]]) : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.array<10xf32>
312! CHECK:     %[[C_1_3:[-0-9a-z_]+]] = arith.constant 1 : index
313! CHECK:     %[[C_0_4:[-0-9a-z_]+]] = arith.constant 0 : index
314! CHECK:     %[[V_13:[0-9]+]] = arith.subi %[[C_10_0]], %[[C_1_3]] : index
315! CHECK:     %[[V_14:[0-9]+]] = fir.do_loop %arg3 = %[[C_0_4]] to %[[V_13]] step %[[C_1_3]] unordered iter_args(%arg4 = %[[V_10]]) -> (!fir.array<10x!fir.logical<4>>) {
316! CHECK:       %[[C_1_5:[-0-9a-z_]+]] = arith.constant 1 : index
317! CHECK:       %[[V_15:[0-9]+]] = arith.addi %arg3, %[[C_1_5]] : index
318! CHECK:       %[[V_16:[0-9]+]] = fir.array_coor %[[V_3]](%[[V_8]]) %[[V_15:[0-9]+]] : (!fir.heap<!fir.array<10x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
319! CHECK:       %[[V_17:[0-9]+]] = fir.load %[[V_16:[0-9]+]] : !fir.ref<!fir.logical<4>>
320! CHECK:       %[[V_18:[0-9]+]] = fir.convert %[[V_17:[0-9]+]] : (!fir.logical<4>) -> i1
321! CHECK:       %[[V_19:[0-9]+]] = fir.if %[[V_18]] -> (!fir.array<10x!fir.logical<4>>) {
322! CHECK:         %[[V_20:[0-9]+]] = fir.array_fetch %[[V_12]], %arg3 : (!fir.array<10xf32>, index) -> f32
323! CHECK:         %[[V_21:[0-9]+]] = fir.no_reassoc %[[V_20:[0-9]+]] : f32
324! CHECK:         %[[V_22:[0-9]+]]:2 = fir.array_modify %arg4, %arg3 : (!fir.array<10x!fir.logical<4>>, index) -> (!fir.ref<!fir.logical<4>>, !fir.array<10x!fir.logical<4>>)
325! CHECK:         fir.store %[[V_21]] to %[[V_0:[0-9]+]] : !fir.ref<f32>
326! CHECK:         fir.call @_QPassign_real_to_logical(%[[V_22]]#0, %[[V_0]]) fastmath<contract> : (!fir.ref<!fir.logical<4>>, !fir.ref<f32>) -> ()
327! CHECK:         fir.result %[[V_22]]#1 : !fir.array<10x!fir.logical<4>>
328! CHECK:       } else {
329! CHECK:         fir.result %arg4 : !fir.array<10x!fir.logical<4>>
330! CHECK:       }
331! CHECK:       fir.result %[[V_19:[0-9]+]] : !fir.array<10x!fir.logical<4>>
332! CHECK:     }
333! CHECK:     fir.array_merge_store %[[V_10]], %[[V_14]] to %arg0 : !fir.array<10x!fir.logical<4>>, !fir.array<10x!fir.logical<4>>, !fir.ref<!fir.array<10x!fir.logical<4>>>
334! CHECK:     fir.freemem %[[V_3:[0-9]+]] : !fir.heap<!fir.array<10x!fir.logical<4>>>
335! CHECK:     return
336! CHECK:   }
337
338! CHECK-LABEL: func @_QPtest_intrinsic_where_2(
339! CHECK-SAME:           %arg0: !fir.ref<!fir.array<10x!fir.logical<4>>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.array<10xf32>> {fir.bindc_name = "y"}, %arg2: !fir.ref<!fir.array<10x!fir.logical<4>>> {fir.bindc_name = "l"}) {
340! CHECK:     %[[V_0:[0-9]+]] = fir.alloca !fir.logical<4>
341! CHECK:     %[[C_10:[-0-9a-z_]+]] = arith.constant 10 : index
342! CHECK:     %[[C_10_0:[-0-9a-z_]+]] = arith.constant 10 : index
343! CHECK:     %[[C_10_1:[-0-9a-z_]+]] = arith.constant 10 : index
344! CHECK:     %[[V_1:[0-9]+]] = fir.shape %[[C_10]] : (index) -> !fir.shape<1>
345! CHECK:     %[[V_2:[0-9]+]] = fir.array_load %arg2(%[[V_1]]) : (!fir.ref<!fir.array<10x!fir.logical<4>>>, !fir.shape<1>) -> !fir.array<10x!fir.logical<4>>
346! CHECK:     %[[V_3:[0-9]+]] = fir.allocmem !fir.array<10x!fir.logical<4>>
347! CHECK:     %[[V_4:[0-9]+]] = fir.shape %[[C_10_1]] : (index) -> !fir.shape<1>
348! CHECK:     %[[V_5:[0-9]+]] = fir.array_load %[[V_3]](%[[V_4]]) : (!fir.heap<!fir.array<10x!fir.logical<4>>>, !fir.shape<1>) -> !fir.array<10x!fir.logical<4>>
349! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
350! CHECK:     %[[C_0:[-0-9a-z_]+]] = arith.constant 0 : index
351! CHECK:     %[[V_6:[0-9]+]] = arith.subi %[[C_10_1]], %[[C_1]] : index
352! CHECK:     %[[V_7:[0-9]+]] = fir.do_loop %arg3 = %[[C_0]] to %[[V_6]] step %[[C_1]] unordered iter_args(%arg4 = %[[V_5]]) -> (!fir.array<10x!fir.logical<4>>) {
353! CHECK:       %[[V_15:[0-9]+]] = fir.array_fetch %[[V_2]], %arg3 : (!fir.array<10x!fir.logical<4>>, index) -> !fir.logical<4>
354! CHECK:       %[[V_16:[0-9]+]] = fir.array_update %arg4, %[[V_15]], %arg3 : (!fir.array<10x!fir.logical<4>>, !fir.logical<4>, index) -> !fir.array<10x!fir.logical<4>>
355! CHECK:       fir.result %[[V_16:[0-9]+]] : !fir.array<10x!fir.logical<4>>
356! CHECK:     }
357! CHECK:     fir.array_merge_store %[[V_5]], %[[V_7]] to %[[V_3:[0-9]+]] : !fir.array<10x!fir.logical<4>>, !fir.array<10x!fir.logical<4>>, !fir.heap<!fir.array<10x!fir.logical<4>>>
358! CHECK:     %[[V_8:[0-9]+]] = fir.shape %[[C_10_1]] : (index) -> !fir.shape<1>
359! CHECK:     %[[V_9:[0-9]+]] = fir.shape %[[C_10_0]] : (index) -> !fir.shape<1>
360! CHECK:     %[[V_10:[0-9]+]] = fir.array_load %arg1(%[[V_9]]) : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.array<10xf32>
361! CHECK:     %[[V_11:[0-9]+]] = fir.shape %[[C_10_0]] : (index) -> !fir.shape<1>
362! CHECK:     %[[V_12:[0-9]+]] = fir.array_load %arg1(%[[V_11]]) : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.array<10xf32>
363! CHECK:     %[[C_st:[-0-9a-z_]+]] = arith.constant 0.000000e+00 : f32
364! CHECK:     %[[C_1_2:[-0-9a-z_]+]] = arith.constant 1 : index
365! CHECK:     %[[C_0_3:[-0-9a-z_]+]] = arith.constant 0 : index
366! CHECK:     %[[V_13:[0-9]+]] = arith.subi %[[C_10_0]], %[[C_1_2]] : index
367! CHECK:     %[[V_14:[0-9]+]] = fir.do_loop %arg3 = %[[C_0_3]] to %[[V_13]] step %[[C_1_2]] unordered iter_args(%arg4 = %[[V_10]]) -> (!fir.array<10xf32>) {
368! CHECK:       %[[C_1_4:[-0-9a-z_]+]] = arith.constant 1 : index
369! CHECK:       %[[V_15:[0-9]+]] = arith.addi %arg3, %[[C_1_4]] : index
370! CHECK:       %[[V_16:[0-9]+]] = fir.array_coor %[[V_3]](%[[V_8]]) %[[V_15:[0-9]+]] : (!fir.heap<!fir.array<10x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
371! CHECK:       %[[V_17:[0-9]+]] = fir.load %[[V_16:[0-9]+]] : !fir.ref<!fir.logical<4>>
372! CHECK:       %[[V_18:[0-9]+]] = fir.convert %[[V_17:[0-9]+]] : (!fir.logical<4>) -> i1
373! CHECK:       %[[V_19:[0-9]+]] = fir.if %[[V_18]] -> (!fir.array<10xf32>) {
374! CHECK:         %[[V_20:[0-9]+]] = fir.array_fetch %[[V_12]], %arg3 : (!fir.array<10xf32>, index) -> f32
375! CHECK:         %[[V_21:[0-9]+]] = arith.cmpf olt, %[[V_20]], %[[C_st]] {{.*}} : f32
376! CHECK:         %[[V_22:[0-9]+]]:2 = fir.array_modify %arg4, %arg3 : (!fir.array<10xf32>, index) -> (!fir.ref<f32>, !fir.array<10xf32>)
377! CHECK:         %[[V_23:[0-9]+]] = fir.convert %[[V_21:[0-9]+]] : (i1) -> !fir.logical<4>
378! CHECK:         fir.store %[[V_23]] to %[[V_0:[0-9]+]] : !fir.ref<!fir.logical<4>>
379! CHECK:         fir.call @_QPassign_logical_to_real(%[[V_22]]#0, %[[V_0]]) fastmath<contract> : (!fir.ref<f32>, !fir.ref<!fir.logical<4>>) -> ()
380! CHECK:         fir.result %[[V_22]]#1 : !fir.array<10xf32>
381! CHECK:       } else {
382! CHECK:         fir.result %arg4 : !fir.array<10xf32>
383! CHECK:       }
384! CHECK:       fir.result %[[V_19:[0-9]+]] : !fir.array<10xf32>
385! CHECK:     }
386! CHECK:     fir.array_merge_store %[[V_10]], %[[V_14]] to %arg1 : !fir.array<10xf32>, !fir.array<10xf32>, !fir.ref<!fir.array<10xf32>>
387! CHECK:     fir.freemem %[[V_3:[0-9]+]] : !fir.heap<!fir.array<10x!fir.logical<4>>>
388! CHECK:     return
389! CHECK:   }
390
391! CHECK-LABEL: func @_QPtest_scalar_func_but_not_elemental(
392! CHECK-SAME:        %arg0: !fir.ref<!fir.array<100x!fir.logical<4>>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.array<100xi32>> {fir.bindc_name = "y"}) {
393! CHECK:     %[[V_0:[0-9]+]] = fir.alloca i32
394! CHECK:     %[[V_1:[0-9]+]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
395! CHECK:     %[[C_100:[-0-9a-z_]+]] = arith.constant 100 : index
396! CHECK:     %[[C_100_0:[-0-9a-z_]+]] = arith.constant 100 : index
397! CHECK:     %[[C_1_i32:[-0-9a-z_]+]] = arith.constant 1 : i32
398! CHECK:     %[[V_2:[0-9]+]] = fir.convert %[[C_1_i32]] : (i32) -> index
399! CHECK:     %[[C_10_i32:[-0-9a-z_]+]] = arith.constant 10 : i32
400! CHECK:     %[[V_3:[0-9]+]] = fir.convert %[[C_10_i32]] : (i32) -> index
401! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
402! CHECK:     %[[V_4:[0-9]+]] = fir.shape %[[C_100]] : (index) -> !fir.shape<1>
403! CHECK:     %[[V_5:[0-9]+]] = fir.array_load %arg0(%[[V_4]]) : (!fir.ref<!fir.array<100x!fir.logical<4>>>, !fir.shape<1>) -> !fir.array<100x!fir.logical<4>>
404! CHECK:     %[[V_6:[0-9]+]] = fir.shape %[[C_100_0]] : (index) -> !fir.shape<1>
405! CHECK:     %[[V_7:[0-9]+]] = fir.array_load %arg1(%[[V_6]]) : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> !fir.array<100xi32>
406! CHECK:     %[[V_8:[0-9]+]] = fir.do_loop %arg2 = %[[V_2]] to %[[V_3]] step %[[C_1]] unordered iter_args(%arg3 = %[[V_5]]) -> (!fir.array<100x!fir.logical<4>>) {
407! CHECK:       %[[V_9:[0-9]+]] = fir.convert %arg2 : (index) -> i32
408! CHECK:       fir.store %[[V_9]] to %[[V_1:[0-9]+]] : !fir.ref<i32>
409! CHECK:       %[[C_1_1:[-0-9a-z_]+]] = arith.constant 1 : index
410! CHECK:       %[[V_10:[0-9]+]] = fir.load %[[V_1:[0-9]+]] : !fir.ref<i32>
411! CHECK:       %[[V_11:[0-9]+]] = fir.convert %[[V_10:[0-9]+]] : (i32) -> i64
412! CHECK:       %[[V_12:[0-9]+]] = fir.convert %[[V_11:[0-9]+]] : (i64) -> index
413! CHECK:       %[[V_13:[0-9]+]] = arith.subi %[[V_12]], %[[C_1_1]] : index
414! CHECK:       %[[V_14:[0-9]+]] = fir.array_fetch %[[V_7]], %[[V_13:[0-9]+]] : (!fir.array<100xi32>, index) -> i32
415! CHECK:       %[[V_15:[0-9]+]] = fir.no_reassoc %[[V_14:[0-9]+]] : i32
416! CHECK:       %[[C_1_2:[-0-9a-z_]+]] = arith.constant 1 : index
417! CHECK:       %[[V_16:[0-9]+]] = fir.load %[[V_1:[0-9]+]] : !fir.ref<i32>
418! CHECK:       %[[V_17:[0-9]+]] = fir.convert %[[V_16:[0-9]+]] : (i32) -> i64
419! CHECK:       %[[V_18:[0-9]+]] = fir.convert %[[V_17:[0-9]+]] : (i64) -> index
420! CHECK:       %[[V_19:[0-9]+]] = arith.subi %[[V_18]], %[[C_1_2]] : index
421! CHECK:       %[[V_20:[0-9]+]]:2 = fir.array_modify %arg3, %[[V_19:[0-9]+]] : (!fir.array<100x!fir.logical<4>>, index) -> (!fir.ref<!fir.logical<4>>, !fir.array<100x!fir.logical<4>>)
422! CHECK:       fir.store %[[V_15]] to %[[V_0:[0-9]+]] : !fir.ref<i32>
423! CHECK:       fir.call @_QPassign_integer_to_logical(%[[V_20]]#0, %[[V_0]]) fastmath<contract> : (!fir.ref<!fir.logical<4>>, !fir.ref<i32>) -> ()
424! CHECK:       fir.result %[[V_20]]#1 : !fir.array<100x!fir.logical<4>>
425! CHECK:     }
426! CHECK:     fir.array_merge_store %[[V_5]], %[[V_8]] to %arg0 : !fir.array<100x!fir.logical<4>>, !fir.array<100x!fir.logical<4>>, !fir.ref<!fir.array<100x!fir.logical<4>>>
427! CHECK:     return
428! CHECK:   }
429
430! CHECK-LABEL: func @_QPtest_in_forall_with_cleanup(
431! CHECK-SAME:       %arg0: !fir.ref<!fir.array<10x!fir.logical<4>>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.array<10xf32>> {fir.bindc_name = "y"}) {
432! CHECK:     %[[V_0:[0-9]+]] = fir.alloca !fir.box<!fir.heap<f32>> {bindc_name = ".result"}
433! CHECK:     %[[V_1:[0-9]+]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
434! CHECK:     %[[C_10:[-0-9a-z_]+]] = arith.constant 10 : index
435! CHECK:     %[[C_1_i32:[-0-9a-z_]+]] = arith.constant 1 : i32
436! CHECK:     %[[V_2:[0-9]+]] = fir.convert %[[C_1_i32]] : (i32) -> index
437! CHECK:     %[[C_10_i32:[-0-9a-z_]+]] = arith.constant 10 : i32
438! CHECK:     %[[V_3:[0-9]+]] = fir.convert %[[C_10_i32]] : (i32) -> index
439! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
440! CHECK:     %[[V_4:[0-9]+]] = fir.shape %[[C_10]] : (index) -> !fir.shape<1>
441! CHECK:     %[[V_5:[0-9]+]] = fir.array_load %arg0(%[[V_4]]) : (!fir.ref<!fir.array<10x!fir.logical<4>>>, !fir.shape<1>) -> !fir.array<10x!fir.logical<4>>
442! CHECK:     %[[V_6:[0-9]+]] = fir.do_loop %arg2 = %[[V_2]] to %[[V_3]] step %[[C_1]] unordered iter_args(%arg3 = %[[V_5]]) -> (!fir.array<10x!fir.logical<4>>) {
443! CHECK:       %[[V_7:[0-9]+]] = fir.convert %arg2 : (index) -> i32
444! CHECK:       fir.store %[[V_7]] to %[[V_1:[0-9]+]] : !fir.ref<i32>
445! CHECK:       %[[V_8:[0-9]+]] = fir.call @_QPreturns_alloc(%[[V_1]]) proc_attrs<pure> fastmath<contract> : (!fir.ref<i32>) -> !fir.box<!fir.heap<f32>>
446! CHECK:       fir.save_result %[[V_8]] to %[[V_0:[0-9]+]] : !fir.box<!fir.heap<f32>>, !fir.ref<!fir.box<!fir.heap<f32>>>
447! CHECK:       %[[V_9:[0-9]+]] = fir.load %[[V_0:[0-9]+]] : !fir.ref<!fir.box<!fir.heap<f32>>>
448! CHECK:       %[[V_10:[0-9]+]] = fir.box_addr %[[V_9:[0-9]+]] : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32>
449! CHECK:       %[[C_1_0:[-0-9a-z_]+]] = arith.constant 1 : index
450! CHECK:       %[[V_11:[0-9]+]] = fir.load %[[V_1:[0-9]+]] : !fir.ref<i32>
451! CHECK:       %[[V_12:[0-9]+]] = fir.convert %[[V_11:[0-9]+]] : (i32) -> i64
452! CHECK:       %[[V_13:[0-9]+]] = fir.convert %[[V_12:[0-9]+]] : (i64) -> index
453! CHECK:       %[[V_14:[0-9]+]] = arith.subi %[[V_13]], %[[C_1_0]] : index
454! CHECK:       %[[V_15:[0-9]+]]:2 = fir.array_modify %arg3, %[[V_14:[0-9]+]] : (!fir.array<10x!fir.logical<4>>, index) -> (!fir.ref<!fir.logical<4>>, !fir.array<10x!fir.logical<4>>)
455! CHECK:       %[[V_16:[0-9]+]] = fir.convert %[[V_10:[0-9]+]] : (!fir.heap<f32>) -> !fir.ref<f32>
456! CHECK:       fir.call @_QPassign_real_to_logical(%[[V_15]]#0, %[[V_16]]) fastmath<contract> : (!fir.ref<!fir.logical<4>>, !fir.ref<f32>) -> ()
457! CHECK:       %[[V_17:[0-9]+]] = fir.load %[[V_0:[0-9]+]] : !fir.ref<!fir.box<!fir.heap<f32>>>
458! CHECK:       %[[V_18:[0-9]+]] = fir.box_addr %[[V_17:[0-9]+]] : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32>
459! CHECK:       %[[V_19:[0-9]+]] = fir.convert %[[V_18:[0-9]+]] : (!fir.heap<f32>) -> i64
460! CHECK:       %[[C_0_i64:[-0-9a-z_]+]] = arith.constant 0 : i64
461! CHECK:       %[[V_20:[0-9]+]] = arith.cmpi ne, %[[V_19]], %[[C_0_i64]] : i64
462! CHECK:       fir.if %[[V_20]] {
463! CHECK:         fir.freemem %[[V_18:[0-9]+]] : !fir.heap<f32>
464! CHECK:       }
465! CHECK:       fir.result %[[V_15]]#1 : !fir.array<10x!fir.logical<4>>
466! CHECK:     }
467! CHECK:     fir.array_merge_store %[[V_5]], %[[V_6]] to %arg0 : !fir.array<10x!fir.logical<4>>, !fir.array<10x!fir.logical<4>>, !fir.ref<!fir.array<10x!fir.logical<4>>>
468! CHECK:     return
469! CHECK:   }
470
471subroutine test_in_forall_1(x, y)
472  use defined_assignments
473  logical :: x(10)
474  real :: y(10)
475  forall (i=1:10) x(i) = y(i)
476end subroutine
477
478subroutine test_in_forall_2(x, y)
479  use defined_assignments
480  logical :: x(10)
481  real :: y(10)
482  forall (i=1:10) y(i) = y(i).lt.0.
483end subroutine
484
485subroutine test_intrinsic_where_1(x, y, l)
486  use defined_assignments
487  logical :: x(10), l(10)
488  real :: y(10)
489  where(l) x = y
490end subroutine
491
492subroutine test_intrinsic_where_2(x, y, l)
493  use defined_assignments
494  logical :: x(10), l(10)
495  real :: y(10)
496  where(l) y = y.lt.0.
497end subroutine
498
499subroutine test_scalar_func_but_not_elemental(x, y)
500  interface assignment(=)
501    ! scalar, but not elemental
502    elemental subroutine assign_integer_to_logical(a,b)
503      logical, intent(out) :: a
504      integer, intent(in) :: b
505    end
506  end interface
507  logical :: x(100)
508  integer :: y(100)
509  ! Scalar assignment in forall should be treated just like elemental
510  ! functions.
511  forall(i=1:10) x(i) = y(i)
512end subroutine
513
514subroutine test_in_forall_with_cleanup(x, y)
515  use defined_assignments
516  interface
517    pure function returns_alloc(i)
518      integer, intent(in) :: i
519      real, allocatable :: returns_alloc
520    end function
521  end interface
522  logical :: x(10)
523  real :: y(10)
524  forall (i=1:10) x(i) = returns_alloc(i)
525end subroutine
526
527! CHECK-LABEL: func @_QPtest_forall_array(
528! CHECK-SAME:        %arg0: !fir.box<!fir.array<?x?x!fir.logical<4>>> {fir.bindc_name = "x"}, %arg1: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "y"}) {
529! CHECK:     %[[V_0:[0-9]+]] = fir.alloca f32
530! CHECK:     %[[V_1:[0-9]+]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
531! CHECK:     %[[C_1_i32:[-0-9a-z_]+]] = arith.constant 1 : i32
532! CHECK:     %[[V_2:[0-9]+]] = fir.convert %[[C_1_i32]] : (i32) -> index
533! CHECK:     %[[C_10_i32:[-0-9a-z_]+]] = arith.constant 10 : i32
534! CHECK:     %[[V_3:[0-9]+]] = fir.convert %[[C_10_i32]] : (i32) -> index
535! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
536! CHECK:     %[[V_4:[0-9]+]] = fir.array_load %arg0 : (!fir.box<!fir.array<?x?x!fir.logical<4>>>) -> !fir.array<?x?x!fir.logical<4>>
537! CHECK:     %[[V_5:[0-9]+]] = fir.array_load %arg1 : (!fir.box<!fir.array<?x?xf32>>) -> !fir.array<?x?xf32>
538! CHECK:     %[[V_6:[0-9]+]] = fir.do_loop %arg2 = %[[V_2]] to %[[V_3]] step %[[C_1]] unordered iter_args(%arg3 = %[[V_4]]) -> (!fir.array<?x?x!fir.logical<4>>) {
539! CHECK:       %[[V_7:[0-9]+]] = fir.convert %arg2 : (index) -> i32
540! CHECK:       fir.store %[[V_7]] to %[[V_1:[0-9]+]] : !fir.ref<i32>
541! CHECK:       %[[C_1_0:[-0-9a-z_]+]] = arith.constant 1 : index
542! CHECK:       %[[V_8:[0-9]+]]:3 = fir.box_dims %arg0, %[[C_1_0]] : (!fir.box<!fir.array<?x?x!fir.logical<4>>>, index) -> (index, index, index)
543! CHECK:       %[[C_1_1:[-0-9a-z_]+]] = arith.constant 1 : index
544! CHECK:       %[[V_9:[0-9]+]] = fir.load %[[V_1:[0-9]+]] : !fir.ref<i32>
545! CHECK:       %[[V_10:[0-9]+]] = fir.convert %[[V_9:[0-9]+]] : (i32) -> i64
546! CHECK:       %[[V_11:[0-9]+]] = fir.convert %[[V_10:[0-9]+]] : (i64) -> index
547! CHECK:       %[[V_12:[0-9]+]] = arith.subi %[[V_11]], %[[C_1_1]] : index
548! CHECK:       %[[C_1_i64:[-0-9a-z_]+]] = arith.constant 1 : i64
549! CHECK:       %[[V_13:[0-9]+]] = fir.convert %[[C_1_i64]] : (i64) -> index
550! CHECK:       %[[V_14:[0-9]+]] = arith.addi %[[C_1_1]], %[[V_8]]#1 : index
551! CHECK:       %[[V_15:[0-9]+]] = arith.subi %[[V_14]], %[[C_1_1]] : index
552! CHECK:       %[[C_0:[-0-9a-z_]+]] = arith.constant 0 : index
553! CHECK:       %[[V_16:[0-9]+]] = arith.subi %[[V_15]], %[[C_1_1]] : index
554! CHECK:       %[[V_17:[0-9]+]] = arith.addi %[[V_16]], %[[V_13:[0-9]+]] : index
555! CHECK:       %[[V_18:[0-9]+]] = arith.divsi %[[V_17]], %[[V_13:[0-9]+]] : index
556! CHECK:       %[[V_19:[0-9]+]] = arith.cmpi sgt, %[[V_18]], %[[C_0]] : index
557! CHECK:       %[[V_20:[0-9]+]] = arith.select %[[V_19]], %[[V_18]], %[[C_0]] : index
558! CHECK:       %[[C_1_2:[-0-9a-z_]+]] = arith.constant 1 : index
559! CHECK:       %[[V_21:[0-9]+]] = fir.load %[[V_1:[0-9]+]] : !fir.ref<i32>
560! CHECK:       %[[V_22:[0-9]+]] = fir.convert %[[V_21:[0-9]+]] : (i32) -> i64
561! CHECK:       %[[V_23:[0-9]+]] = fir.convert %[[V_22:[0-9]+]] : (i64) -> index
562! CHECK:       %[[V_24:[0-9]+]] = arith.subi %[[V_23]], %[[C_1_2]] : index
563! CHECK:       %[[C_1_i64_3:[-0-9a-z_]+]] = arith.constant 1 : i64
564! CHECK:       %[[V_25:[0-9]+]] = fir.convert %[[C_1_i64_3]] : (i64) -> index
565! CHECK:       %[[C_1_4:[-0-9a-z_]+]] = arith.constant 1 : index
566! CHECK:       %[[C_0_5:[-0-9a-z_]+]] = arith.constant 0 : index
567! CHECK:       %[[V_26:[0-9]+]] = arith.subi %[[V_20]], %[[C_1_4]] : index
568! CHECK:       %[[V_27:[0-9]+]] = fir.do_loop %arg4 = %[[C_0_5]] to %[[V_26]] step %[[C_1_4]] unordered iter_args(%arg5 = %arg3) -> (!fir.array<?x?x!fir.logical<4>>) {
569! CHECK:         %[[V_28:[0-9]+]] = arith.subi %[[C_1_2]], %[[C_1_2]] : index
570! CHECK:         %[[V_29:[0-9]+]] = arith.muli %arg4, %[[V_25:[0-9]+]] : index
571! CHECK:         %[[V_30:[0-9]+]] = arith.addi %[[V_28]], %[[V_29:[0-9]+]] : index
572! CHECK:         %[[V_31:[0-9]+]] = fir.array_fetch %[[V_5]], %[[V_24]], %[[V_30:[0-9]+]] : (!fir.array<?x?xf32>, index, index) -> f32
573! CHECK:         %[[V_32:[0-9]+]] = fir.no_reassoc %[[V_31:[0-9]+]] : f32
574! CHECK:         %[[V_33:[0-9]+]] = arith.subi %[[C_1_1]], %[[C_1_1]] : index
575! CHECK:         %[[V_34:[0-9]+]] = arith.muli %arg4, %[[V_13:[0-9]+]] : index
576! CHECK:         %[[V_35:[0-9]+]] = arith.addi %[[V_33]], %[[V_34:[0-9]+]] : index
577! CHECK:         %[[V_36:[0-9]+]]:2 = fir.array_modify %arg5, %[[V_12]], %[[V_35:[0-9]+]] : (!fir.array<?x?x!fir.logical<4>>, index, index) -> (!fir.ref<!fir.logical<4>>, !fir.array<?x?x!fir.logical<4>>)
578! CHECK:         fir.store %[[V_32]] to %[[V_0:[0-9]+]] : !fir.ref<f32>
579! CHECK:         fir.call @_QPassign_real_to_logical(%[[V_36]]#0, %[[V_0]]) fastmath<contract> : (!fir.ref<!fir.logical<4>>, !fir.ref<f32>) -> ()
580! CHECK:         fir.result %[[V_36]]#1 : !fir.array<?x?x!fir.logical<4>>
581! CHECK:       }
582! CHECK:       fir.result %[[V_27:[0-9]+]] : !fir.array<?x?x!fir.logical<4>>
583! CHECK:     }
584! CHECK:     fir.array_merge_store %[[V_4]], %[[V_6]] to %arg0 : !fir.array<?x?x!fir.logical<4>>, !fir.array<?x?x!fir.logical<4>>, !fir.box<!fir.array<?x?x!fir.logical<4>>>
585! CHECK:     return
586! CHECK:   }
587
588subroutine test_forall_array(x, y)
589  use defined_assignments
590  logical :: x(:, :)
591  real :: y(:, :)
592  forall (i=1:10) x(i, :) = y(i, :)
593end subroutine
594
595! CHECK-LABEL: func @_QPfrom_char_forall(
596! CHECK-SAME:       %arg0: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "i"}, %arg1: !fir.box<!fir.array<?x!fir.char<1,?>>> {fir.bindc_name = "c"}) {
597! CHECK:     %[[V_0:[0-9]+]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "j"}
598! CHECK:     %[[C_1_i32:[-0-9a-z_]+]] = arith.constant 1 : i32
599! CHECK:     %[[V_1:[0-9]+]] = fir.convert %[[C_1_i32]] : (i32) -> index
600! CHECK:     %[[C_10_i32:[-0-9a-z_]+]] = arith.constant 10 : i32
601! CHECK:     %[[V_2:[0-9]+]] = fir.convert %[[C_10_i32]] : (i32) -> index
602! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
603! CHECK:     %[[V_3:[0-9]+]] = fir.array_load %arg0 : (!fir.box<!fir.array<?xi32>>) -> !fir.array<?xi32>
604! CHECK:     %[[V_4:[0-9]+]] = fir.array_load %arg1 : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> !fir.array<?x!fir.char<1,?>>
605! CHECK:     %[[V_5:[0-9]+]] = fir.do_loop %arg2 = %[[V_1]] to %[[V_2]] step %[[C_1]] unordered iter_args(%arg3 = %[[V_3]]) -> (!fir.array<?xi32>) {
606! CHECK:       %[[V_6:[0-9]+]] = fir.convert %arg2 : (index) -> i32
607! CHECK:       fir.store %[[V_6]] to %[[V_0:[0-9]+]] : !fir.ref<i32>
608! CHECK:       %[[C_1_0:[-0-9a-z_]+]] = arith.constant 1 : index
609! CHECK:       %[[V_7:[0-9]+]] = fir.load %[[V_0:[0-9]+]] : !fir.ref<i32>
610! CHECK:       %[[V_8:[0-9]+]] = fir.convert %[[V_7:[0-9]+]] : (i32) -> i64
611! CHECK:       %[[V_9:[0-9]+]] = fir.convert %[[V_8:[0-9]+]] : (i64) -> index
612! CHECK:       %[[V_10:[0-9]+]] = arith.subi %[[V_9]], %[[C_1_0]] : index
613! CHECK:       %[[V_11:[0-9]+]] = fir.box_elesize %arg1 : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> index
614! CHECK:       %[[C_1_1:[-0-9a-z_]+]] = arith.constant 1 : index
615! CHECK:       %[[V_12:[0-9]+]] = arith.divsi %[[V_11]], %[[C_1_1]] : index
616! CHECK:       %[[V_13:[0-9]+]] = fir.array_access %[[V_4]], %[[V_10]] typeparams %[[V_12:[0-9]+]] : (!fir.array<?x!fir.char<1,?>>, index, index) -> !fir.ref<!fir.char<1,?>>
617! CHECK:       %[[V_14:[0-9]+]] = fir.box_elesize %arg1 : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> index
618! CHECK:       %[[V_15:[0-9]+]] = fir.no_reassoc %[[V_13:[0-9]+]] : !fir.ref<!fir.char<1,?>>
619! CHECK:       %[[C_1_2:[-0-9a-z_]+]] = arith.constant 1 : index
620! CHECK:       %[[V_16:[0-9]+]] = fir.load %[[V_0:[0-9]+]] : !fir.ref<i32>
621! CHECK:       %[[V_17:[0-9]+]] = fir.convert %[[V_16:[0-9]+]] : (i32) -> i64
622! CHECK:       %[[V_18:[0-9]+]] = fir.convert %[[V_17:[0-9]+]] : (i64) -> index
623! CHECK:       %[[V_19:[0-9]+]] = arith.subi %[[V_18]], %[[C_1_2]] : index
624! CHECK:       %[[V_20:[0-9]+]]:2 = fir.array_modify %arg3, %[[V_19:[0-9]+]] : (!fir.array<?xi32>, index) -> (!fir.ref<i32>, !fir.array<?xi32>)
625! CHECK:       %[[V_21:[0-9]+]] = fir.emboxchar %[[V_15]], %[[V_14:[0-9]+]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
626! CHECK:       fir.call @_QPsfrom_char(%[[V_20]]#0, %[[V_21]]) fastmath<contract> : (!fir.ref<i32>, !fir.boxchar<1>) -> ()
627! CHECK:       fir.result %[[V_20]]#1 : !fir.array<?xi32>
628! CHECK:     }
629! CHECK:     fir.array_merge_store %[[V_3]], %[[V_5]] to %arg0 : !fir.array<?xi32>, !fir.array<?xi32>, !fir.box<!fir.array<?xi32>>
630! CHECK:     return
631! CHECK:   }
632
633! CHECK-LABEL: func @_QPto_char_forall(
634! CHECK-SAME:        %arg0: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "i"}, %arg1: !fir.box<!fir.array<?x!fir.char<1,?>>> {fir.bindc_name = "c"}) {
635! CHECK:     %[[V_0:[0-9]+]] = fir.alloca i32
636! CHECK:     %[[V_1:[0-9]+]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "j"}
637! CHECK:     %[[C_1_i32:[-0-9a-z_]+]] = arith.constant 1 : i32
638! CHECK:     %[[V_2:[0-9]+]] = fir.convert %[[C_1_i32]] : (i32) -> index
639! CHECK:     %[[C_10_i32:[-0-9a-z_]+]] = arith.constant 10 : i32
640! CHECK:     %[[V_3:[0-9]+]] = fir.convert %[[C_10_i32]] : (i32) -> index
641! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
642! CHECK:     %[[V_4:[0-9]+]] = fir.array_load %arg1 : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> !fir.array<?x!fir.char<1,?>>
643! CHECK:     %[[V_5:[0-9]+]] = fir.array_load %arg0 : (!fir.box<!fir.array<?xi32>>) -> !fir.array<?xi32>
644! CHECK:     %[[V_6:[0-9]+]] = fir.do_loop %arg2 = %[[V_2]] to %[[V_3]] step %[[C_1]] unordered iter_args(%arg3 = %[[V_4]]) -> (!fir.array<?x!fir.char<1,?>>) {
645! CHECK:       %[[V_7:[0-9]+]] = fir.convert %arg2 : (index) -> i32
646! CHECK:       fir.store %[[V_7]] to %[[V_1:[0-9]+]] : !fir.ref<i32>
647! CHECK:       %[[C_1_0:[-0-9a-z_]+]] = arith.constant 1 : index
648! CHECK:       %[[V_8:[0-9]+]] = fir.load %[[V_1:[0-9]+]] : !fir.ref<i32>
649! CHECK:       %[[V_9:[0-9]+]] = fir.convert %[[V_8:[0-9]+]] : (i32) -> i64
650! CHECK:       %[[V_10:[0-9]+]] = fir.convert %[[V_9:[0-9]+]] : (i64) -> index
651! CHECK:       %[[V_11:[0-9]+]] = arith.subi %[[V_10]], %[[C_1_0]] : index
652! CHECK:       %[[V_12:[0-9]+]] = fir.array_fetch %[[V_5]], %[[V_11:[0-9]+]] : (!fir.array<?xi32>, index) -> i32
653! CHECK:       %[[V_13:[0-9]+]] = fir.no_reassoc %[[V_12:[0-9]+]] : i32
654! CHECK:       %[[C_1_1:[-0-9a-z_]+]] = arith.constant 1 : index
655! CHECK:       %[[V_14:[0-9]+]] = fir.load %[[V_1:[0-9]+]] : !fir.ref<i32>
656! CHECK:       %[[V_15:[0-9]+]] = fir.convert %[[V_14:[0-9]+]] : (i32) -> i64
657! CHECK:       %[[V_16:[0-9]+]] = fir.convert %[[V_15:[0-9]+]] : (i64) -> index
658! CHECK:       %[[V_17:[0-9]+]] = arith.subi %[[V_16]], %[[C_1_1]] : index
659! CHECK:       %[[V_18:[0-9]+]]:2 = fir.array_modify %arg3, %[[V_17:[0-9]+]] : (!fir.array<?x!fir.char<1,?>>, index) -> (!fir.ref<!fir.char<1,?>>, !fir.array<?x!fir.char<1,?>>)
660! CHECK:       %[[V_19:[0-9]+]] = fir.box_elesize %arg1 : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> index
661! CHECK:       %[[V_20:[0-9]+]] = fir.emboxchar %[[V_18]]#0, %[[V_19:[0-9]+]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
662! CHECK:       fir.store %[[V_13]] to %[[V_0:[0-9]+]] : !fir.ref<i32>
663! CHECK:       fir.call @_QPsto_char(%[[V_20]], %[[V_0]]) fastmath<contract> : (!fir.boxchar<1>, !fir.ref<i32>) -> ()
664! CHECK:       fir.result %[[V_18]]#1 : !fir.array<?x!fir.char<1,?>>
665! CHECK:     }
666! CHECK:     fir.array_merge_store %[[V_4]], %[[V_6]] to %arg1 : !fir.array<?x!fir.char<1,?>>, !fir.array<?x!fir.char<1,?>>, !fir.box<!fir.array<?x!fir.char<1,?>>>
667! CHECK:     return
668! CHECK:   }
669
670subroutine from_char_forall(i, c)
671  interface assignment(=)
672    elemental subroutine sfrom_char(a,b)
673      integer, intent(out) :: a
674      character(*),intent(in) :: b
675    end subroutine
676  end interface
677  integer :: i(:)
678  character(*) :: c(:)
679  forall (j=1:10) i(j) = c(j)
680end subroutine
681
682subroutine to_char_forall(i, c)
683  interface assignment(=)
684    elemental subroutine sto_char(a,b)
685      character(*), intent(out) :: a
686      integer,intent(in) :: b
687    end subroutine
688  end interface
689  integer :: i(:)
690  character(*) :: c(:)
691  forall (j=1:10) c(j) = i(j)
692end subroutine
693
694! CHECK-LABEL: func @_QPfrom_char_forall_array(
695! CHECK-SAME:        %arg0: !fir.box<!fir.array<?x?xi32>> {fir.bindc_name = "i"}, %arg1: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "c"}) {
696! CHECK:     %[[V_0:[0-9]+]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "j"}
697! CHECK:     %[[C_1_i32:[-0-9a-z_]+]] = arith.constant 1 : i32
698! CHECK:     %[[V_1:[0-9]+]] = fir.convert %[[C_1_i32]] : (i32) -> index
699! CHECK:     %[[C_10_i32:[-0-9a-z_]+]] = arith.constant 10 : i32
700! CHECK:     %[[V_2:[0-9]+]] = fir.convert %[[C_10_i32]] : (i32) -> index
701! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
702! CHECK:     %[[V_3:[0-9]+]] = fir.array_load %arg0 : (!fir.box<!fir.array<?x?xi32>>) -> !fir.array<?x?xi32>
703! CHECK:     %[[V_4:[0-9]+]] = fir.array_load %arg1 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.array<?x?x!fir.char<1,?>>
704! CHECK:     %[[V_5:[0-9]+]] = fir.do_loop %arg2 = %[[V_1]] to %[[V_2]] step %[[C_1]] unordered iter_args(%arg3 = %[[V_3]]) -> (!fir.array<?x?xi32>) {
705! CHECK:       %[[V_6:[0-9]+]] = fir.convert %arg2 : (index) -> i32
706! CHECK:       fir.store %[[V_6]] to %[[V_0:[0-9]+]] : !fir.ref<i32>
707! CHECK:       %[[C_1_0:[-0-9a-z_]+]] = arith.constant 1 : index
708! CHECK:       %[[V_7:[0-9]+]]:3 = fir.box_dims %arg0, %[[C_1_0]] : (!fir.box<!fir.array<?x?xi32>>, index) -> (index, index, index)
709! CHECK:       %[[C_1_1:[-0-9a-z_]+]] = arith.constant 1 : index
710! CHECK:       %[[V_8:[0-9]+]] = fir.load %[[V_0:[0-9]+]] : !fir.ref<i32>
711! CHECK:       %[[V_9:[0-9]+]] = fir.convert %[[V_8:[0-9]+]] : (i32) -> i64
712! CHECK:       %[[V_10:[0-9]+]] = fir.convert %[[V_9:[0-9]+]] : (i64) -> index
713! CHECK:       %[[V_11:[0-9]+]] = arith.subi %[[V_10]], %[[C_1_1]] : index
714! CHECK:       %[[C_1_i64:[-0-9a-z_]+]] = arith.constant 1 : i64
715! CHECK:       %[[V_12:[0-9]+]] = fir.convert %[[C_1_i64]] : (i64) -> index
716! CHECK:       %[[V_13:[0-9]+]] = arith.addi %[[C_1_1]], %[[V_7]]#1 : index
717! CHECK:       %[[V_14:[0-9]+]] = arith.subi %[[V_13]], %[[C_1_1]] : index
718! CHECK:       %[[C_0:[-0-9a-z_]+]] = arith.constant 0 : index
719! CHECK:       %[[V_15:[0-9]+]] = arith.subi %[[V_14]], %[[C_1_1]] : index
720! CHECK:       %[[V_16:[0-9]+]] = arith.addi %[[V_15]], %[[V_12:[0-9]+]] : index
721! CHECK:       %[[V_17:[0-9]+]] = arith.divsi %[[V_16]], %[[V_12:[0-9]+]] : index
722! CHECK:       %[[V_18:[0-9]+]] = arith.cmpi sgt, %[[V_17]], %[[C_0]] : index
723! CHECK:       %[[V_19:[0-9]+]] = arith.select %[[V_18]], %[[V_17]], %[[C_0]] : index
724! CHECK:       %[[C_1_2:[-0-9a-z_]+]] = arith.constant 1 : index
725! CHECK:       %[[V_20:[0-9]+]] = fir.load %[[V_0:[0-9]+]] : !fir.ref<i32>
726! CHECK:       %[[V_21:[0-9]+]] = fir.convert %[[V_20:[0-9]+]] : (i32) -> i64
727! CHECK:       %[[V_22:[0-9]+]] = fir.convert %[[V_21:[0-9]+]] : (i64) -> index
728! CHECK:       %[[V_23:[0-9]+]] = arith.subi %[[V_22]], %[[C_1_2]] : index
729! CHECK:       %[[C_1_i64_3:[-0-9a-z_]+]] = arith.constant 1 : i64
730! CHECK:       %[[V_24:[0-9]+]] = fir.convert %[[C_1_i64_3]] : (i64) -> index
731! CHECK:       %[[C_1_4:[-0-9a-z_]+]] = arith.constant 1 : index
732! CHECK:       %[[C_0_5:[-0-9a-z_]+]] = arith.constant 0 : index
733! CHECK:       %[[V_25:[0-9]+]] = arith.subi %[[V_19]], %[[C_1_4]] : index
734! CHECK:       %[[V_26:[0-9]+]] = fir.do_loop %arg4 = %[[C_0_5]] to %[[V_25]] step %[[C_1_4]] unordered iter_args(%arg5 = %arg3) -> (!fir.array<?x?xi32>) {
735! CHECK:         %[[V_27:[0-9]+]] = arith.subi %[[C_1_2]], %[[C_1_2]] : index
736! CHECK:         %[[V_28:[0-9]+]] = arith.muli %arg4, %[[V_24:[0-9]+]] : index
737! CHECK:         %[[V_29:[0-9]+]] = arith.addi %[[V_27]], %[[V_28:[0-9]+]] : index
738! CHECK:         %[[V_30:[0-9]+]] = fir.box_elesize %arg1 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> index
739! CHECK:         %[[C_1_6:[-0-9a-z_]+]] = arith.constant 1 : index
740! CHECK:         %[[V_31:[0-9]+]] = arith.divsi %[[V_30]], %[[C_1_6]] : index
741! CHECK:         %[[V_32:[0-9]+]] = fir.array_access %[[V_4]], %[[V_23]], %[[V_29]] typeparams %[[V_31:[0-9]+]] : (!fir.array<?x?x!fir.char<1,?>>, index, index, index) -> !fir.ref<!fir.char<1,?>>
742! CHECK:         %[[V_33:[0-9]+]] = fir.box_elesize %arg1 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> index
743! CHECK:         %[[V_34:[0-9]+]] = fir.no_reassoc %[[V_32:[0-9]+]] : !fir.ref<!fir.char<1,?>>
744! CHECK:         %[[V_35:[0-9]+]] = arith.subi %[[C_1_1]], %[[C_1_1]] : index
745! CHECK:         %[[V_36:[0-9]+]] = arith.muli %arg4, %[[V_12:[0-9]+]] : index
746! CHECK:         %[[V_37:[0-9]+]] = arith.addi %[[V_35]], %[[V_36:[0-9]+]] : index
747! CHECK:         %[[V_38:[0-9]+]]:2 = fir.array_modify %arg5, %[[V_11]], %[[V_37:[0-9]+]] : (!fir.array<?x?xi32>, index, index) -> (!fir.ref<i32>, !fir.array<?x?xi32>)
748! CHECK:         %[[V_39:[0-9]+]] = fir.emboxchar %[[V_34]], %[[V_33:[0-9]+]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
749! CHECK:         fir.call @_QPsfrom_char(%[[V_38]]#0, %[[V_39]]) fastmath<contract> : (!fir.ref<i32>, !fir.boxchar<1>) -> ()
750! CHECK:         fir.result %[[V_38]]#1 : !fir.array<?x?xi32>
751! CHECK:       }
752! CHECK:       fir.result %[[V_26:[0-9]+]] : !fir.array<?x?xi32>
753! CHECK:     }
754! CHECK:     fir.array_merge_store %[[V_3]], %[[V_5]] to %arg0 : !fir.array<?x?xi32>, !fir.array<?x?xi32>, !fir.box<!fir.array<?x?xi32>>
755! CHECK:     return
756! CHECK:   }
757
758! CHECK-LABEL: func @_QPto_char_forall_array(
759! CHECK-SAME:      %arg0: !fir.box<!fir.array<?x?xi32>> {fir.bindc_name = "i"}, %arg1: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "c"}) {
760! CHECK:     %[[V_0:[0-9]+]] = fir.alloca i32
761! CHECK:     %[[V_1:[0-9]+]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "j"}
762! CHECK:     %[[C_1_i32:[-0-9a-z_]+]] = arith.constant 1 : i32
763! CHECK:     %[[V_2:[0-9]+]] = fir.convert %[[C_1_i32]] : (i32) -> index
764! CHECK:     %[[C_10_i32:[-0-9a-z_]+]] = arith.constant 10 : i32
765! CHECK:     %[[V_3:[0-9]+]] = fir.convert %[[C_10_i32]] : (i32) -> index
766! CHECK:     %[[C_1:[-0-9a-z_]+]] = arith.constant 1 : index
767! CHECK:     %[[V_4:[0-9]+]] = fir.array_load %arg1 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.array<?x?x!fir.char<1,?>>
768! CHECK:     %[[V_5:[0-9]+]] = fir.array_load %arg0 : (!fir.box<!fir.array<?x?xi32>>) -> !fir.array<?x?xi32>
769! CHECK:     %[[V_6:[0-9]+]] = fir.do_loop %arg2 = %[[V_2]] to %[[V_3]] step %[[C_1]] unordered iter_args(%arg3 = %[[V_4]]) -> (!fir.array<?x?x!fir.char<1,?>>) {
770! CHECK:       %[[V_7:[0-9]+]] = fir.convert %arg2 : (index) -> i32
771! CHECK:       fir.store %[[V_7]] to %[[V_1:[0-9]+]] : !fir.ref<i32>
772! CHECK:       %[[C_1_0:[-0-9a-z_]+]] = arith.constant 1 : index
773! CHECK:       %[[V_8:[0-9]+]]:3 = fir.box_dims %arg1, %[[C_1_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
774! CHECK:       %[[C_1_1:[-0-9a-z_]+]] = arith.constant 1 : index
775! CHECK:       %[[V_9:[0-9]+]] = fir.load %[[V_1:[0-9]+]] : !fir.ref<i32>
776! CHECK:       %[[V_10:[0-9]+]] = fir.convert %[[V_9:[0-9]+]] : (i32) -> i64
777! CHECK:       %[[V_11:[0-9]+]] = fir.convert %[[V_10:[0-9]+]] : (i64) -> index
778! CHECK:       %[[V_12:[0-9]+]] = arith.subi %[[V_11]], %[[C_1_1]] : index
779! CHECK:       %[[C_1_i64:[-0-9a-z_]+]] = arith.constant 1 : i64
780! CHECK:       %[[V_13:[0-9]+]] = fir.convert %[[C_1_i64]] : (i64) -> index
781! CHECK:       %[[V_14:[0-9]+]] = arith.addi %[[C_1_1]], %[[V_8]]#1 : index
782! CHECK:       %[[V_15:[0-9]+]] = arith.subi %[[V_14]], %[[C_1_1]] : index
783! CHECK:       %[[C_0:[-0-9a-z_]+]] = arith.constant 0 : index
784! CHECK:       %[[V_16:[0-9]+]] = arith.subi %[[V_15]], %[[C_1_1]] : index
785! CHECK:       %[[V_17:[0-9]+]] = arith.addi %[[V_16]], %[[V_13:[0-9]+]] : index
786! CHECK:       %[[V_18:[0-9]+]] = arith.divsi %[[V_17]], %[[V_13:[0-9]+]] : index
787! CHECK:       %[[V_19:[0-9]+]] = arith.cmpi sgt, %[[V_18]], %[[C_0]] : index
788! CHECK:       %[[V_20:[0-9]+]] = arith.select %[[V_19]], %[[V_18]], %[[C_0]] : index
789! CHECK:       %[[C_1_2:[-0-9a-z_]+]] = arith.constant 1 : index
790! CHECK:       %[[V_21:[0-9]+]] = fir.load %[[V_1:[0-9]+]] : !fir.ref<i32>
791! CHECK:       %[[V_22:[0-9]+]] = fir.convert %[[V_21:[0-9]+]] : (i32) -> i64
792! CHECK:       %[[V_23:[0-9]+]] = fir.convert %[[V_22:[0-9]+]] : (i64) -> index
793! CHECK:       %[[V_24:[0-9]+]] = arith.subi %[[V_23]], %[[C_1_2]] : index
794! CHECK:       %[[C_1_i64_3:[-0-9a-z_]+]] = arith.constant 1 : i64
795! CHECK:       %[[V_25:[0-9]+]] = fir.convert %[[C_1_i64_3]] : (i64) -> index
796! CHECK:       %[[C_1_4:[-0-9a-z_]+]] = arith.constant 1 : index
797! CHECK:       %[[C_0_5:[-0-9a-z_]+]] = arith.constant 0 : index
798! CHECK:       %[[V_26:[0-9]+]] = arith.subi %[[V_20]], %[[C_1_4]] : index
799! CHECK:       %[[V_27:[0-9]+]] = fir.do_loop %arg4 = %[[C_0_5]] to %[[V_26]] step %[[C_1_4]] unordered iter_args(%arg5 = %arg3) -> (!fir.array<?x?x!fir.char<1,?>>) {
800! CHECK:         %[[V_28:[0-9]+]] = arith.subi %[[C_1_2]], %[[C_1_2]] : index
801! CHECK:         %[[V_29:[0-9]+]] = arith.muli %arg4, %[[V_25:[0-9]+]] : index
802! CHECK:         %[[V_30:[0-9]+]] = arith.addi %[[V_28]], %[[V_29:[0-9]+]] : index
803! CHECK:         %[[V_31:[0-9]+]] = fir.array_fetch %[[V_5]], %[[V_24]], %[[V_30:[0-9]+]] : (!fir.array<?x?xi32>, index, index) -> i32
804! CHECK:         %[[V_32:[0-9]+]] = fir.no_reassoc %[[V_31:[0-9]+]] : i32
805! CHECK:         %[[V_33:[0-9]+]] = arith.subi %[[C_1_1]], %[[C_1_1]] : index
806! CHECK:         %[[V_34:[0-9]+]] = arith.muli %arg4, %[[V_13:[0-9]+]] : index
807! CHECK:         %[[V_35:[0-9]+]] = arith.addi %[[V_33]], %[[V_34:[0-9]+]] : index
808! CHECK:         %[[V_36:[0-9]+]]:2 = fir.array_modify %arg5, %[[V_12]], %[[V_35:[0-9]+]] : (!fir.array<?x?x!fir.char<1,?>>, index, index) -> (!fir.ref<!fir.char<1,?>>, !fir.array<?x?x!fir.char<1,?>>)
809! CHECK:         %[[V_37:[0-9]+]] = fir.box_elesize %arg1 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> index
810! CHECK:         %[[V_38:[0-9]+]] = fir.emboxchar %[[V_36]]#0, %[[V_37:[0-9]+]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
811! CHECK:         fir.store %[[V_32]] to %[[V_0:[0-9]+]] : !fir.ref<i32>
812! CHECK:         fir.call @_QPsto_char(%[[V_38]], %[[V_0]]) fastmath<contract> : (!fir.boxchar<1>, !fir.ref<i32>) -> ()
813! CHECK:         fir.result %[[V_36]]#1 : !fir.array<?x?x!fir.char<1,?>>
814! CHECK:       }
815! CHECK:       fir.result %[[V_27:[0-9]+]] : !fir.array<?x?x!fir.char<1,?>>
816! CHECK:     }
817! CHECK:     fir.array_merge_store %[[V_4]], %[[V_6]] to %arg1 : !fir.array<?x?x!fir.char<1,?>>, !fir.array<?x?x!fir.char<1,?>>, !fir.box<!fir.array<?x?x!fir.char<1,?>>>
818! CHECK:     return
819! CHECK:   }
820
821subroutine from_char_forall_array(i, c)
822  interface assignment(=)
823    elemental subroutine sfrom_char(a,b)
824      integer, intent(out) :: a
825      character(*),intent(in) :: b
826    end subroutine
827  end interface
828  integer :: i(:, :)
829  character(*) :: c(:, :)
830  forall (j=1:10) i(j, :) = c(j, :)
831end subroutine
832
833subroutine to_char_forall_array(i, c)
834  interface assignment(=)
835    elemental subroutine sto_char(a,b)
836      character(*), intent(out) :: a
837      integer,intent(in) :: b
838    end subroutine
839  end interface
840  integer :: i(:, :)
841  character(*) :: c(:, :)
842  forall (j=1:10) c(j, :) = i(j, :)
843end subroutine
844
845! TODO: test array user defined assignment inside FORALL.
846subroutine test_todo(x, y)
847  interface assignment(=)
848    ! User assignment is not elemental, it takes array arguments.
849    pure subroutine assign_array(a,b)
850      logical, intent(out) :: a(:)
851      integer, intent(in) :: b(:)
852    end
853  end interface
854  logical :: x(10, 10)
855  integer :: y(10, 10)
856!  forall(i=1:10) x(i, :) = y(i, :)
857end subroutine
858