[LLVM] Fix Maintainers.md formatting (NFC)
[llvm-project.git] / flang / test / HLFIR / opt-bufferization.fir
blob87afb3cc924533990fb87be936f9da80ca60474e
1 // RUN: fir-opt --opt-bufferization %s | FileCheck %s
3 // simplified example
4 func.func @simple(%arg: !fir.ref<!fir.array<42xi32>>) {
5   %c42 = arith.constant 42 : index
6   %c1_i32 = arith.constant 1 : i32
7   %shape = fir.shape %c42 : (index) -> !fir.shape<1>
8   %array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
9   %elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
10   ^bb0(%i: index):
11     %ref = hlfir.designate %array#0 (%i) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
12     %val = fir.load %ref : !fir.ref<i32>
13     %sub = arith.subi %val, %c1_i32 : i32
14     hlfir.yield_element %sub : i32
15   }
16   hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
17   hlfir.destroy %elemental : !hlfir.expr<42xi32>
18   return
20 // CHECK-LABEL:   func.func @simple(
21 // CHECK-SAME:                      %[[VAL_0:.*]]: !fir.ref<!fir.array<42xi32>>) {
22 // CHECK:           %[[VAL_1:.*]] = arith.constant 1 : index
23 // CHECK:           %[[VAL_2:.*]] = arith.constant 42 : index
24 // CHECK:           %[[VAL_3:.*]] = arith.constant 1 : i32
25 // CHECK:           %[[VAL_4:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
26 // CHECK:           %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_4]]) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
27 // CHECK:           fir.do_loop %[[VAL_6:.*]] = %[[VAL_1]] to %[[VAL_2]] step %[[VAL_1]] unordered {
28 // CHECK:             %[[VAL_7:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_6]])  : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
29 // CHECK:             %[[VAL_8:.*]] = fir.load %[[VAL_7]] : !fir.ref<i32>
30 // CHECK:             %[[VAL_9:.*]] = arith.subi %[[VAL_8]], %[[VAL_3]] : i32
31 // CHECK:             %[[VAL_10:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_6]])  : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
32 // CHECK:             hlfir.assign %[[VAL_9]] to %[[VAL_10]] : i32, !fir.ref<i32>
33 // CHECK:           }
34 // CHECK:           return
35 // CHECK:         }
37 // check we support reads that don't alias the transformed array
38 func.func @read_no_alias(%arg: !fir.ref<!fir.array<42xi32>>, %arg1: !fir.ref<!fir.array<42xi32>>) {
39   %c42 = arith.constant 42 : index
40   %shape = fir.shape %c42 : (index) -> !fir.shape<1>
41   %array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
42   %other:2 = hlfir.declare %arg1(%shape) {uniq_name = "other"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
43   %elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
44   ^bb0(%i: index):
45     %ref = hlfir.designate %array#0 (%i) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
46     %other_ref = hlfir.designate %other#0 (%i) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
47     %val = fir.load %ref : !fir.ref<i32>
48     %other_val = fir.load %other_ref : !fir.ref<i32>
49     %sub = arith.subi %val, %other_val : i32
50     hlfir.yield_element %sub : i32
51   }
52   hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
53   hlfir.destroy %elemental : !hlfir.expr<42xi32>
54   return
56 // CHECK-LABEL:   func.func @read_no_alias(
57 // CHECK-SAME:                             %[[VAL_0:.*]]: !fir.ref<!fir.array<42xi32>>,
58 // CHECK-SAME:                             %[[VAL_1:.*]]: !fir.ref<!fir.array<42xi32>>) {
59 // CHECK:           %[[VAL_2:.*]] = arith.constant 1 : index
60 // CHECK:           %[[VAL_3:.*]] = arith.constant 42 : index
61 // CHECK:           %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1>
62 // CHECK:           %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_4]]) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
63 // CHECK:           %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_4]]) {uniq_name = "other"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
64 // CHECK:           fir.do_loop %[[VAL_7:.*]] = %[[VAL_2]] to %[[VAL_3]] step %[[VAL_2]] unordered {
65 // CHECK:             %[[VAL_8:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_7]])  : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
66 // CHECK:             %[[VAL_9:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_7]])  : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
67 // CHECK:             %[[VAL_10:.*]] = fir.load %[[VAL_8]] : !fir.ref<i32>
68 // CHECK:             %[[VAL_11:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32>
69 // CHECK:             %[[VAL_12:.*]] = arith.subi %[[VAL_10]], %[[VAL_11]] : i32
70 // CHECK:             %[[VAL_13:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_7]])  : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
71 // CHECK:             hlfir.assign %[[VAL_12]] to %[[VAL_13]] : i32, !fir.ref<i32>
72 // CHECK:           }
73 // CHECK:           return
74 // CHECK:         }
77 // check we don't transform when there is another use of the elemental expr
78 func.func @two_uses(%arg: !fir.ref<!fir.array<42xi32>>) -> i32 {
79   %c42 = arith.constant 42 : index
80   %c1_i32 = arith.constant 1 : i32
81   %shape = fir.shape %c42 : (index) -> !fir.shape<1>
82   %array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
83   %elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
84   ^bb0(%i: index):
85     %ref = hlfir.designate %array#0 (%i) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
86     %val = fir.load %ref : !fir.ref<i32>
87     %sub = arith.subi %val, %c1_i32 : i32
88     hlfir.yield_element %sub : i32
89   }
90   hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
91   %bad = hlfir.apply %elemental, %c42 : (!hlfir.expr<42xi32>, index) -> i32
92   hlfir.destroy %elemental : !hlfir.expr<42xi32>
93   return %bad : i32
95 // CHECK-LABEL:   func.func @two_uses(
96 // CHECK-SAME:                        %[[VAL_0:.*]]: !fir.ref<!fir.array<42xi32>>) -> i32 {
97 // CHECK:           %[[VAL_1:.*]] = arith.constant 42 : index
98 // CHECK:           %[[VAL_2:.*]] = arith.constant 1 : i32
99 // CHECK:           %[[VAL_3:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
100 // CHECK:           %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_3]]) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
101 // CHECK:           %[[VAL_5:.*]] = hlfir.elemental %[[VAL_3]] unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
102 // CHECK:           ^bb0(%[[VAL_6:.*]]: index):
103 // CHECK:             %[[VAL_7:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_6]])  : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
104 // CHECK:             %[[VAL_8:.*]] = fir.load %[[VAL_7]] : !fir.ref<i32>
105 // CHECK:             %[[VAL_9:.*]] = arith.subi %[[VAL_8]], %[[VAL_2]] : i32
106 // CHECK:             hlfir.yield_element %[[VAL_9]] : i32
107 // CHECK:           }
108 // CHECK:           hlfir.assign %[[VAL_10:.*]] to %[[VAL_4]]#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
109 // CHECK:           %[[VAL_11:.*]] = hlfir.apply %[[VAL_10]], %[[VAL_1]] : (!hlfir.expr<42xi32>, index) -> i32
110 // CHECK:           hlfir.destroy %[[VAL_10]] : !hlfir.expr<42xi32>
111 // CHECK:           return %[[VAL_11]] : i32
112 // CHECK:         }
114 // two dimensional array
115 func.func @two_dimensional(%arg: !fir.ref<!fir.array<42x42xi32>>) {
116   %c42 = arith.constant 42 : index
117   %c1_i32 = arith.constant 1 : i32
118   %shape = fir.shape %c42, %c42 : (index, index) -> !fir.shape<2>
119   %array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42x42xi32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<42x42xi32>>, !fir.ref<!fir.array<42x42xi32>>)
120   %elemental = hlfir.elemental %shape unordered : (!fir.shape<2>) -> !hlfir.expr<42x42xi32> {
121   ^bb0(%i: index, %j: index):
122     %ref = hlfir.designate %array#0 (%i, %j) : (!fir.ref<!fir.array<42x42xi32>>, index, index) -> !fir.ref<i32>
123     %val = fir.load %ref : !fir.ref<i32>
124     %sub = arith.subi %val, %c1_i32 : i32
125     hlfir.yield_element %sub : i32
126   }
127   hlfir.assign %elemental to %array#0 : !hlfir.expr<42x42xi32>, !fir.ref<!fir.array<42x42xi32>>
128   hlfir.destroy %elemental : !hlfir.expr<42x42xi32>
129   return
131 // CHECK-LABEL:   func.func @two_dimensional(
132 // CHECK-SAME:                               %[[VAL_0:.*]]: !fir.ref<!fir.array<42x42xi32>>) {
133 // CHECK:           %[[VAL_1:.*]] = arith.constant 1 : index
134 // CHECK:           %[[VAL_2:.*]] = arith.constant 42 : index
135 // CHECK:           %[[VAL_3:.*]] = arith.constant 1 : i32
136 // CHECK:           %[[VAL_4:.*]] = fir.shape %[[VAL_2]], %[[VAL_2]] : (index, index) -> !fir.shape<2>
137 // CHECK:           %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_4]]) {uniq_name = "array"} : (!fir.ref<!fir.array<42x42xi32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<42x42xi32>>, !fir.ref<!fir.array<42x42xi32>>)
138 // CHECK:           fir.do_loop %[[VAL_6:.*]] = %[[VAL_1]] to %[[VAL_2]] step %[[VAL_1]] unordered {
139 // CHECK:             fir.do_loop %[[VAL_7:.*]] = %[[VAL_1]] to %[[VAL_2]] step %[[VAL_1]] unordered {
140 // CHECK:               %[[VAL_8:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_7]], %[[VAL_6]])  : (!fir.ref<!fir.array<42x42xi32>>, index, index) -> !fir.ref<i32>
141 // CHECK:               %[[VAL_9:.*]] = fir.load %[[VAL_8]] : !fir.ref<i32>
142 // CHECK:               %[[VAL_10:.*]] = arith.subi %[[VAL_9]], %[[VAL_3]] : i32
143 // CHECK:               %[[VAL_11:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_7]], %[[VAL_6]])  : (!fir.ref<!fir.array<42x42xi32>>, index, index) -> !fir.ref<i32>
144 // CHECK:               hlfir.assign %[[VAL_10]] to %[[VAL_11]] : i32, !fir.ref<i32>
145 // CHECK:             }
146 // CHECK:           }
147 // CHECK:           return
148 // CHECK:         }
150 // don't transform when elements are accessessed out of order (e.g. transposed)
151 func.func @transposed(%arg: !fir.ref<!fir.array<42x42xi32>>) {
152   %c42 = arith.constant 42 : index
153   %c1_i32 = arith.constant 1 : i32
154   %shape = fir.shape %c42, %c42 : (index, index) -> !fir.shape<2>
155   %array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42x42xi32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<42x42xi32>>, !fir.ref<!fir.array<42x42xi32>>)
156   %elemental = hlfir.elemental %shape unordered : (!fir.shape<2>) -> !hlfir.expr<42x42xi32> {
157   ^bb0(%i: index, %j: index):
158     %ref = hlfir.designate %array#0 (%j, %i) : (!fir.ref<!fir.array<42x42xi32>>, index, index) -> !fir.ref<i32>
159     %val = fir.load %ref : !fir.ref<i32>
160     %sub = arith.subi %val, %c1_i32 : i32
161     hlfir.yield_element %sub : i32
162   }
163   hlfir.assign %elemental to %array#0 : !hlfir.expr<42x42xi32>, !fir.ref<!fir.array<42x42xi32>>
164   hlfir.destroy %elemental : !hlfir.expr<42x42xi32>
165   return
167 // CHECK-LABEL:   func.func @transposed(
168 // CHECK-SAME:                          %[[VAL_0:.*]]: !fir.ref<!fir.array<42x42xi32>>) {
169 // CHECK:           %[[VAL_1:.*]] = arith.constant 42 : index
170 // CHECK:           %[[VAL_2:.*]] = arith.constant 1 : i32
171 // CHECK:           %[[VAL_3:.*]] = fir.shape %[[VAL_1]], %[[VAL_1]] : (index, index) -> !fir.shape<2>
172 // CHECK:           %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_3]]) {uniq_name = "array"} : (!fir.ref<!fir.array<42x42xi32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<42x42xi32>>, !fir.ref<!fir.array<42x42xi32>>)
173 // CHECK:           %[[VAL_5:.*]] = hlfir.elemental %[[VAL_3]] unordered : (!fir.shape<2>) -> !hlfir.expr<42x42xi32> {
174 // CHECK:           ^bb0(%[[VAL_6:.*]]: index, %[[VAL_7:.*]]: index):
175 // CHECK:             %[[VAL_8:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_7]], %[[VAL_6]])  : (!fir.ref<!fir.array<42x42xi32>>, index, index) -> !fir.ref<i32>
176 // CHECK:             %[[VAL_9:.*]] = fir.load %[[VAL_8]] : !fir.ref<i32>
177 // CHECK:             %[[VAL_10:.*]] = arith.subi %[[VAL_9]], %[[VAL_2]] : i32
178 // CHECK:             hlfir.yield_element %[[VAL_10]] : i32
179 // CHECK:           }
180 // CHECK:           hlfir.assign %[[VAL_11:.*]] to %[[VAL_4]]#0 : !hlfir.expr<42x42xi32>, !fir.ref<!fir.array<42x42xi32>>
181 // CHECK:           hlfir.destroy %[[VAL_11]] : !hlfir.expr<42x42xi32>
182 // CHECK:           return
183 // CHECK:         }
185 // don't transform when there's an operation with unknown effects
186 func.func @unknown(%arg: !fir.ref<!fir.array<42xi32>>) {
187   %c42 = arith.constant 42 : index
188   %c1_i32 = arith.constant 1 : i32
189   %shape = fir.shape %c42 : (index) -> !fir.shape<1>
190   %array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
191   %elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
192   ^bb0(%i: index):
193     %ref = hlfir.designate %array#0 (%i) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
194     %val = fir.load %ref : !fir.ref<i32>
195     %sub = arith.subi %val, %c1_i32 : i32
196     %res = fir.call @impure(%sub) : (i32) -> i32
197     hlfir.yield_element %res : i32
198   }
199   hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
200   hlfir.destroy %elemental : !hlfir.expr<42xi32>
201   return
203 // CHECK-LABEL:   func.func @unknown(
204 // CHECK-SAME:                       %[[VAL_0:.*]]: !fir.ref<!fir.array<42xi32>>) {
205 // CHECK:           %[[VAL_1:.*]] = arith.constant 42 : index
206 // CHECK:           %[[VAL_2:.*]] = arith.constant 1 : i32
207 // CHECK:           %[[VAL_3:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
208 // CHECK:           %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_3]]) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
209 // CHECK:           %[[VAL_5:.*]] = hlfir.elemental %[[VAL_3]] unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
210 // CHECK:           ^bb0(%[[VAL_6:.*]]: index):
211 // CHECK:             %[[VAL_7:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_6]])  : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
212 // CHECK:             %[[VAL_8:.*]] = fir.load %[[VAL_7]] : !fir.ref<i32>
213 // CHECK:             %[[VAL_9:.*]] = arith.subi %[[VAL_8]], %[[VAL_2]] : i32
214 // CHECK:             %[[VAL_10:.*]] = fir.call @impure(%[[VAL_9]]) : (i32) -> i32
215 // CHECK:             hlfir.yield_element %[[VAL_10]] : i32
216 // CHECK:           }
217 // CHECK:           hlfir.assign %[[VAL_11:.*]] to %[[VAL_4]]#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
218 // CHECK:           hlfir.destroy %[[VAL_11]] : !hlfir.expr<42xi32>
219 // CHECK:           return
220 // CHECK:         }
222 // don't transform when there's an operation with write effects
223 func.func @write(%arg: !fir.ref<!fir.array<42xi32>>, %arg1: !fir.ref<!fir.array<42xi32>>) {
224   %alloc = fir.alloca i32
225   %c42 = arith.constant 42 : index
226   %c1_i32 = arith.constant 1 : i32
227   %shape = fir.shape %c42 : (index) -> !fir.shape<1>
228   %array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
229   %array2:2 = hlfir.declare %arg1(%shape) {uniq_name = "array2"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
230   %elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
231   ^bb0(%i: index):
232     hlfir.assign %array2#0 to %array#0 : !fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>
233     %ref = hlfir.designate %array#0 (%i) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
234     %val = fir.load %ref : !fir.ref<i32>
235     %sub = arith.subi %val, %c1_i32 : i32
236     fir.store %sub to %alloc : !fir.ref<i32>
237     hlfir.yield_element %sub : i32
238   }
239   hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
240   hlfir.destroy %elemental : !hlfir.expr<42xi32>
241   return
243 // CHECK-LABEL:   func.func @write(
244 // CHECK-SAME:                     %[[VAL_0:.*]]: !fir.ref<!fir.array<42xi32>>,
245 // CHECK-SAME:                     %[[ARG_1:.*]]: !fir.ref<!fir.array<42xi32>>) {
246 // CHECK:           %[[VAL_1:.*]] = arith.constant 1 : i32
247 // CHECK:           %[[VAL_2:.*]] = arith.constant 42 : index
248 // CHECK:           %[[VAL_3:.*]] = fir.alloca i32
249 // CHECK:           %[[VAL_4:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
250 // CHECK:           %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_4]]) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
251 // CHECK:           %[[VAL_5B:.*]]:2 = hlfir.declare %[[ARG_1]](%[[VAL_4]]) {uniq_name = "array2"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
252 // CHECK:           %[[VAL_6:.*]] = hlfir.elemental %[[VAL_4]] unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
253 // CHECK:           ^bb0(%[[VAL_7:.*]]: index):
254 // CHECK:             hlfir.assign
255 // CHECK:             %[[VAL_8:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_7]])  : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
256 // CHECK:             %[[VAL_9:.*]] = fir.load %[[VAL_8]] : !fir.ref<i32>
257 // CHECK:             %[[VAL_10:.*]] = arith.subi %[[VAL_9]], %[[VAL_1]] : i32
258 // CHECK:             fir.store %[[VAL_10]] to %[[VAL_3]] : !fir.ref<i32>
259 // CHECK:             hlfir.yield_element %[[VAL_10]] : i32
260 // CHECK:           }
261 // CHECK:           hlfir.assign %[[VAL_11:.*]] to %[[VAL_5]]#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
262 // CHECK:           hlfir.destroy %[[VAL_11]] : !hlfir.expr<42xi32>
263 // CHECK:           return
264 // CHECK:         }
266 // don't transform when there is an aliasing read
267 func.func @readAlias(%arg: !fir.ref<!fir.array<42xi32>>) {
268   %c42 = arith.constant 42 : index
269   %shape = fir.shape %c42 : (index) -> !fir.shape<1>
270   %array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
271   %arrayDup:2 = hlfir.declare %arg(%shape) {uniq_name = "arrayDup"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
272   %elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
273   ^bb0(%i: index):
274     %ref = hlfir.designate %array#0 (%i) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
275     %refDup = hlfir.designate %arrayDup#0 (%i) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
276     %val = fir.load %ref : !fir.ref<i32>
277     %valDup = fir.load %refDup : !fir.ref<i32>
278     %sub = arith.subi %val, %valDup : i32
279     hlfir.yield_element %sub : i32
280   }
281   hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
282   hlfir.destroy %elemental : !hlfir.expr<42xi32>
283   return
285 // CHECK-LABEL:   func.func @readAlias(
286 // CHECK-SAME:                         %[[VAL_0:.*]]: !fir.ref<!fir.array<42xi32>>) {
287 // CHECK:           %[[VAL_1:.*]] = arith.constant 42 : index
288 // CHECK:           %[[VAL_2:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
289 // CHECK:           %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_2]]) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
290 // CHECK:           %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_2]]) {uniq_name = "arrayDup"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
291 // CHECK:           %[[VAL_5:.*]] = hlfir.elemental %[[VAL_2]] unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
292 // CHECK:           ^bb0(%[[VAL_6:.*]]: index):
293 // CHECK:             %[[VAL_7:.*]] = hlfir.designate %[[VAL_3]]#0 (%[[VAL_6]])  : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
294 // CHECK:             %[[VAL_8:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_6]])  : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
295 // CHECK:             %[[VAL_9:.*]] = fir.load %[[VAL_7]] : !fir.ref<i32>
296 // CHECK:             %[[VAL_10:.*]] = fir.load %[[VAL_8]] : !fir.ref<i32>
297 // CHECK:             %[[VAL_11:.*]] = arith.subi %[[VAL_9]], %[[VAL_10]] : i32
298 // CHECK:             hlfir.yield_element %[[VAL_11]] : i32
299 // CHECK:           }
300 // CHECK:           hlfir.assign %[[VAL_12:.*]] to %[[VAL_3]]#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
301 // CHECK:           hlfir.destroy %[[VAL_12]] : !hlfir.expr<42xi32>
302 // CHECK:           return
303 // CHECK:         }
305 // don't transform when moving the elemental to the assignment could change the results of a read
306 func.func @write_conflict(%arg: !fir.ref<!fir.array<42xi32>>) -> index {
307   %alloc = fir.alloca index
308   %c42 = arith.constant 42 : index
309   %c1_i32 = arith.constant 1 : i32
310   %shape = fir.shape %c42 : (index) -> !fir.shape<1>
311   %array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
312   %elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
313   ^bb0(%i: index):
314     %ref = hlfir.designate %array#0 (%i) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
315     %val = fir.load %ref : !fir.ref<i32>
316     %sub = arith.subi %val, %c1_i32 : i32
317     // write in elemental:
318     hlfir.assign %i to %alloc : index, !fir.ref<index>
319     hlfir.yield_element %sub : i32
320   }
321   // conflicting read:
322   %conflict = fir.load %alloc : !fir.ref<index>
323   hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
324   hlfir.destroy %elemental : !hlfir.expr<42xi32>
325   return %conflict : index
327 // CHECK-LABEL:   func.func @write_conflict(
328 // CHECK-SAME:                              %[[VAL_0:.*]]: !fir.ref<!fir.array<42xi32>>) -> index {
329 // CHECK:           %[[VAL_1:.*]] = arith.constant 1 : i32
330 // CHECK:           %[[VAL_2:.*]] = arith.constant 42 : index
331 // CHECK:           %[[VAL_3:.*]] = fir.alloca index
332 // CHECK:           %[[VAL_4:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
333 // CHECK:           %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_4]]) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
334 // CHECK:           %[[VAL_6:.*]] = hlfir.elemental %[[VAL_4]] unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
335 // CHECK:           ^bb0(%[[VAL_7:.*]]: index):
336 // CHECK:             %[[VAL_8:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_7]])  : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
337 // CHECK:             %[[VAL_9:.*]] = fir.load %[[VAL_8]] : !fir.ref<i32>
338 // CHECK:             %[[VAL_10:.*]] = arith.subi %[[VAL_9]], %[[VAL_1]] : i32
339 // CHECK:             hlfir.assign %[[VAL_7]] to %[[VAL_3]] : index, !fir.ref<index>
340 // CHECK:             hlfir.yield_element %[[VAL_10]] : i32
341 // CHECK:           }
342 // CHECK:           %[[VAL_11:.*]] = fir.load %[[VAL_3]] : !fir.ref<index>
343 // CHECK:           hlfir.assign %[[VAL_6]] to %[[VAL_5]]#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
344 // CHECK:           hlfir.destroy %[[VAL_6]] : !hlfir.expr<42xi32>
345 // CHECK:           return %[[VAL_11]] : index
346 // CHECK:         }
348 // don't transform when moving the elemental to the assignment could change the results of a read #2
349 func.func @read_conflict(%arg: !fir.ref<!fir.array<42xi32>>) {
350   %alloc = fir.alloca i32
351   %c0_i32 = arith.constant 0 : i32
352   %c1_i32 = arith.constant 1 : i32
353   hlfir.assign %c1_i32 to %alloc : i32, !fir.ref<i32>
354   %c42 = arith.constant 42 : index
355   %shape = fir.shape %c42 : (index) -> !fir.shape<1>
356   %array:2 = hlfir.declare %arg(%shape) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
357   %elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
358   ^bb0(%i: index):
359     %ref = hlfir.designate %array#0 (%i) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
360     %val = fir.load %ref : !fir.ref<i32>
361     // conflicting read:
362     %read = fir.load %alloc : !fir.ref<i32>
363     %sub = arith.subi %val, %read : i32
364     hlfir.yield_element %sub : i32
365   }
366   // conflicting write:
367   hlfir.assign %c0_i32 to %alloc : i32, !fir.ref<i32>
368   hlfir.assign %elemental to %array#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
369   hlfir.destroy %elemental : !hlfir.expr<42xi32>
370   return
372 // CHECK-LABEL:   func.func @read_conflict(
373 // CHECK-SAME:                             %[[VAL_0:.*]]: !fir.ref<!fir.array<42xi32>>) {
374 // CHECK:           %[[VAL_1:.*]] = arith.constant 42 : index
375 // CHECK:           %[[VAL_2:.*]] = arith.constant 1 : i32
376 // CHECK:           %[[VAL_3:.*]] = arith.constant 0 : i32
377 // CHECK:           %[[VAL_4:.*]] = fir.alloca i32
378 // CHECK:           hlfir.assign %[[VAL_2]] to %[[VAL_4]] : i32, !fir.ref<i32>
379 // CHECK:           %[[VAL_5:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
380 // CHECK:           %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_5]]) {uniq_name = "array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
381 // CHECK:           %[[VAL_7:.*]] = hlfir.elemental %[[VAL_5]] unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
382 // CHECK:           ^bb0(%[[VAL_8:.*]]: index):
383 // CHECK:             %[[VAL_9:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_8]])  : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
384 // CHECK:             %[[VAL_10:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32>
385 // CHECK:             %[[VAL_11:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32>
386 // CHECK:             %[[VAL_12:.*]] = arith.subi %[[VAL_10]], %[[VAL_11]] : i32
387 // CHECK:             hlfir.yield_element %[[VAL_12]] : i32
388 // CHECK:           }
389 // CHECK:           hlfir.assign %[[VAL_3]] to %[[VAL_4]] : i32, !fir.ref<i32>
390 // CHECK:           hlfir.assign %[[VAL_7]] to %[[VAL_6]]#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
391 // CHECK:           hlfir.destroy %[[VAL_7]] : !hlfir.expr<42xi32>
392 // CHECK:           return
393 // CHECK:         }
395 fir.global @_QMmEblock : !fir.array<9x9x9xi32> {
396   %0 = fir.undefined !fir.array<9x9x9xi32>
397   fir.has_value %0 : !fir.array<9x9x9xi32>
399 fir.global @_QMmECr constant : i32 {
400   %c9_i32 = arith.constant 9 : i32
401   fir.has_value %c9_i32 : i32
404 // does it work for the intended case?
405 func.func @_QMmPrepro(%arg0: !fir.ref<i32> {fir.bindc_name = "imin"}, %arg1: !fir.ref<i32> {fir.bindc_name = "imax"}, %arg2: !fir.ref<i32> {fir.bindc_name = "row"}) {
406   %c10_i32 = arith.constant 10 : i32
407   %c8 = arith.constant 8 : index
408   %c2 = arith.constant 2 : index
409   %c1 = arith.constant 1 : index
410   %c9 = arith.constant 9 : index
411   %0 = fir.address_of(@_QMmEblock) : !fir.ref<!fir.array<9x9x9xi32>>
412   %1 = fir.shape %c9, %c9, %c9 : (index, index, index) -> !fir.shape<3>
413   %2:2 = hlfir.declare %0(%1) {uniq_name = "_QMmEblock"} : (!fir.ref<!fir.array<9x9x9xi32>>, !fir.shape<3>) -> (!fir.ref<!fir.array<9x9x9xi32>>, !fir.ref<!fir.array<9x9x9xi32>>)
414   %3 = fir.address_of(@_QMmECr) : !fir.ref<i32>
415   %4:2 = hlfir.declare %3 {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QMmECr"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
416   %5 = fir.alloca i32 {bindc_name = "i1", uniq_name = "_QMmFreproEi1"}
417   %6:2 = hlfir.declare %5 {uniq_name = "_QMmFreproEi1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
418   %7:2 = hlfir.declare %arg1 {uniq_name = "_QMmFreproEimax"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
419   %8:2 = hlfir.declare %arg0 {uniq_name = "_QMmFreproEimin"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
420   %9:2 = hlfir.declare %arg2 {uniq_name = "_QMmFreproErow"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
421   %10 = fir.load %8#0 : !fir.ref<i32>
422   %11 = fir.convert %10 : (i32) -> index
423   %12 = fir.load %7#0 : !fir.ref<i32>
424   %13 = fir.convert %12 : (i32) -> index
425   %14 = fir.convert %11 : (index) -> i32
426   %15:2 = fir.do_loop %arg3 = %11 to %13 step %c1 iter_args(%arg4 = %14) -> (index, i32) {
427     fir.store %arg4 to %6#1 : !fir.ref<i32>
428     %16 = fir.load %9#0 : !fir.ref<i32>
429     %17 = fir.convert %16 : (i32) -> i64
430     %18 = fir.load %6#0 : !fir.ref<i32>
431     %19 = fir.convert %18 : (i32) -> i64
432     %20 = fir.shape %c8 : (index) -> !fir.shape<1>
433     %21 = hlfir.designate %2#0 (%17, %c2:%c9:%c1, %19)  shape %20 : (!fir.ref<!fir.array<9x9x9xi32>>, i64, index, index, index, i64, !fir.shape<1>) -> !fir.box<!fir.array<8xi32>>
434     %22 = hlfir.elemental %20 unordered : (!fir.shape<1>) -> !hlfir.expr<8xi32> {
435     ^bb0(%arg5: index):
436       %27 = hlfir.designate %21 (%arg5)  : (!fir.box<!fir.array<8xi32>>, index) -> !fir.ref<i32>
437       %28 = fir.load %27 : !fir.ref<i32>
438       %29 = arith.subi %28, %c10_i32 : i32
439       hlfir.yield_element %29 : i32
440     }
441     hlfir.assign %22 to %21 : !hlfir.expr<8xi32>, !fir.box<!fir.array<8xi32>>
442     hlfir.destroy %22 : !hlfir.expr<8xi32>
443     %23 = arith.addi %arg3, %c1 : index
444     %24 = fir.convert %c1 : (index) -> i32
445     %25 = fir.load %6#1 : !fir.ref<i32>
446     %26 = arith.addi %25, %24 : i32
447     fir.result %23, %26 : index, i32
448   }
449   fir.store %15#1 to %6#1 : !fir.ref<i32>
450   return
452 // CHECK-LABEL:   func.func @_QMmPrepro(
453 // CHECK-SAME:                          %[[VAL_0:.*]]: !fir.ref<i32> {fir.bindc_name = "imin"},
454 // CHECK-SAME:                          %[[VAL_1:.*]]: !fir.ref<i32> {fir.bindc_name = "imax"},
455 // CHECK-SAME:                          %[[VAL_2:.*]]: !fir.ref<i32> {fir.bindc_name = "row"}) {
456 // CHECK:           %[[VAL_3:.*]] = arith.constant 10 : i32
457 // CHECK:           %[[VAL_4:.*]] = arith.constant 8 : index
458 // CHECK:           %[[VAL_5:.*]] = arith.constant 2 : index
459 // CHECK:           %[[VAL_6:.*]] = arith.constant 1 : index
460 // CHECK:           %[[VAL_7:.*]] = arith.constant 9 : index
461 // CHECK:           %[[VAL_8:.*]] = fir.address_of(@_QMmEblock) : !fir.ref<!fir.array<9x9x9xi32>>
462 // CHECK:           %[[VAL_9:.*]] = fir.shape %[[VAL_7]], %[[VAL_7]], %[[VAL_7]] : (index, index, index) -> !fir.shape<3>
463 // CHECK:           %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_8]](%[[VAL_9]]) {uniq_name = "_QMmEblock"} : (!fir.ref<!fir.array<9x9x9xi32>>, !fir.shape<3>) -> (!fir.ref<!fir.array<9x9x9xi32>>, !fir.ref<!fir.array<9x9x9xi32>>)
464 // CHECK:           %[[VAL_11:.*]] = fir.address_of(@_QMmECr) : !fir.ref<i32>
465 // CHECK:           %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_11]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QMmECr"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
466 // CHECK:           %[[VAL_13:.*]] = fir.alloca i32 {bindc_name = "i1", uniq_name = "_QMmFreproEi1"}
467 // CHECK:           %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_13]] {uniq_name = "_QMmFreproEi1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
468 // CHECK:           %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QMmFreproEimax"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
469 // CHECK:           %[[VAL_16:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QMmFreproEimin"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
470 // CHECK:           %[[VAL_17:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QMmFreproErow"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
471 // CHECK:           %[[VAL_18:.*]] = fir.load %[[VAL_16]]#0 : !fir.ref<i32>
472 // CHECK:           %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (i32) -> index
473 // CHECK:           %[[VAL_20:.*]] = fir.load %[[VAL_15]]#0 : !fir.ref<i32>
474 // CHECK:           %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i32) -> index
475 // CHECK:           %[[VAL_22:.*]] = fir.convert %[[VAL_19]] : (index) -> i32
476 // CHECK:           %[[VAL_23:.*]]:2 = fir.do_loop %[[VAL_24:.*]] = %[[VAL_19]] to %[[VAL_21]] step %[[VAL_6]] iter_args(%[[VAL_25:.*]] = %[[VAL_22]]) -> (index, i32) {
477 // CHECK:             fir.store %[[VAL_25]] to %[[VAL_14]]#1 : !fir.ref<i32>
478 // CHECK:             %[[VAL_26:.*]] = fir.load %[[VAL_17]]#0 : !fir.ref<i32>
479 // CHECK:             %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (i32) -> i64
480 // CHECK:             %[[VAL_28:.*]] = fir.load %[[VAL_14]]#0 : !fir.ref<i32>
481 // CHECK:             %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (i32) -> i64
482 // CHECK:             %[[VAL_30:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>
483 // CHECK:             %[[VAL_31:.*]] = hlfir.designate %[[VAL_10]]#0 (%[[VAL_27]], %[[VAL_5]]:%[[VAL_7]]:%[[VAL_6]], %[[VAL_29]])  shape %[[VAL_30]] : (!fir.ref<!fir.array<9x9x9xi32>>, i64, index, index, index, i64, !fir.shape<1>) -> !fir.box<!fir.array<8xi32>>
484 // CHECK:             fir.do_loop %[[VAL_32:.*]] = %[[VAL_6]] to %[[VAL_4]] step %[[VAL_6]] unordered {
485 // CHECK:               %[[VAL_33:.*]] = hlfir.designate %[[VAL_31]] (%[[VAL_32]])  : (!fir.box<!fir.array<8xi32>>, index) -> !fir.ref<i32>
486 // CHECK:               %[[VAL_34:.*]] = fir.load %[[VAL_33]] : !fir.ref<i32>
487 // CHECK:               %[[VAL_35:.*]] = arith.subi %[[VAL_34]], %[[VAL_3]] : i32
488 // CHECK:               %[[VAL_36:.*]] = hlfir.designate %[[VAL_31]] (%[[VAL_32]])  : (!fir.box<!fir.array<8xi32>>, index) -> !fir.ref<i32>
489 // CHECK:               hlfir.assign %[[VAL_35]] to %[[VAL_36]] : i32, !fir.ref<i32>
490 // CHECK:             }
491 // CHECK:             %[[VAL_37:.*]] = arith.addi %[[VAL_24]], %[[VAL_6]] : index
492 // CHECK:             %[[VAL_38:.*]] = fir.convert %[[VAL_6]] : (index) -> i32
493 // CHECK:             %[[VAL_39:.*]] = fir.load %[[VAL_14]]#1 : !fir.ref<i32>
494 // CHECK:             %[[VAL_40:.*]] = arith.addi %[[VAL_39]], %[[VAL_38]] : i32
495 // CHECK:             fir.result %[[VAL_37]], %[[VAL_40]] : index, i32
496 // CHECK:           }
497 // CHECK:           fir.store %[[VAL_41:.*]]#1 to %[[VAL_14]]#1 : !fir.ref<i32>
498 // CHECK:           return
499 // CHECK:         }
501 // support for z = x + y
502 func.func @other_reads(%z_arg: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "z"}, %x_arg: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"}, %y_arg: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "y"}) {
503   %c0 = arith.constant 0 : index
504   %box_dims:3 = fir.box_dims %z_arg, %c0 : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
505   // ignore lower bound etc
506   %shape = fir.shape %box_dims#1 : (index) -> !fir.shape<1>
508   %z:2 = hlfir.declare %z_arg(%shape) {uniq_name = "z"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
509   %x:2 = hlfir.declare %x_arg(%shape) {uniq_name = "x"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
510   %y:2 = hlfir.declare %y_arg(%shape) {uniq_name = "y"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
512   %elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
513   ^bb0(%i: index):
514     %x_ref = hlfir.designate %x#0 (%i) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
515     %x_val = fir.load %x_ref : !fir.ref<f32>
516     %y_ref = hlfir.designate %y#0 (%i) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
517     %y_val = fir.load %y_ref : !fir.ref<f32>
518     %add = arith.addf %x_val, %y_val : f32
519     hlfir.yield_element %add : f32
520   }
521   hlfir.assign %elemental to %z#0 : !hlfir.expr<?xf32>, !fir.box<!fir.array<?xf32>>
522   hlfir.destroy %elemental : !hlfir.expr<?xf32>
523   return
525 // CHECK-LABEL:   func.func @other_reads(
526 // CHECK-SAME:                      %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "z"},
527 // CHECK-SAME:                      %[[VAL_1:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"},
528 // CHECK-SAME:                      %[[VAL_2:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "y"}) {
529 // CHECK:           %[[VAL_3:.*]] = arith.constant 1 : index
530 // CHECK:           %[[VAL_4:.*]] = arith.constant 0 : index
531 // CHECK:           %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
532 // CHECK:           %[[VAL_6:.*]] = fir.shape %[[VAL_5]]#1 : (index) -> !fir.shape<1>
533 // CHECK:           %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_6]]) {uniq_name = "z"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
534 // CHECK:           %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_6]]) {uniq_name = "x"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
535 // CHECK:           %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_2]](%[[VAL_6]]) {uniq_name = "y"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
536 // CHECK:           fir.do_loop %[[VAL_10:.*]] = %[[VAL_3]] to %[[VAL_5]]#1 step %[[VAL_3]] unordered {
537 // CHECK:             %[[VAL_11:.*]] = hlfir.designate %[[VAL_8]]#0 (%[[VAL_10]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
538 // CHECK:             %[[VAL_12:.*]] = fir.load %[[VAL_11]] : !fir.ref<f32>
539 // CHECK:             %[[VAL_13:.*]] = hlfir.designate %[[VAL_9]]#0 (%[[VAL_10]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
540 // CHECK:             %[[VAL_14:.*]] = fir.load %[[VAL_13]] : !fir.ref<f32>
541 // CHECK:             %[[VAL_15:.*]] = arith.addf %[[VAL_12]], %[[VAL_14]] : f32
542 // CHECK:             %[[VAL_16:.*]] = hlfir.designate %[[VAL_7]]#0 (%[[VAL_10]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
543 // CHECK:             hlfir.assign %[[VAL_15]] to %[[VAL_16]] : f32, !fir.ref<f32>
544 // CHECK:           }
545 // CHECK:           return
546 // CHECK:         }
548 // support for z = x + y, when z is declared after the elemental
549 func.func @other_reads_late_decl(%z_arg: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "z"}, %x_arg: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"}, %y_arg: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "y"}) {
550   %c0 = arith.constant 0 : index
551   %box_dims:3 = fir.box_dims %z_arg, %c0 : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
552   // ignore lower bound etc
553   %shape = fir.shape %box_dims#1 : (index) -> !fir.shape<1>
555   %x:2 = hlfir.declare %x_arg(%shape) {uniq_name = "x"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
556   %y:2 = hlfir.declare %y_arg(%shape) {uniq_name = "y"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
558   %elemental = hlfir.elemental %shape unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
559   ^bb0(%i: index):
560     %x_ref = hlfir.designate %x#0 (%i) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
561     %x_val = fir.load %x_ref : !fir.ref<f32>
562     %y_ref = hlfir.designate %y#0 (%i) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
563     %y_val = fir.load %y_ref : !fir.ref<f32>
564     %add = arith.addf %x_val, %y_val : f32
565     hlfir.yield_element %add : f32
566   }
567   %z:2 = hlfir.declare %z_arg(%shape) {uniq_name = "z"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
568   hlfir.assign %elemental to %z#0 : !hlfir.expr<?xf32>, !fir.box<!fir.array<?xf32>>
569   hlfir.destroy %elemental : !hlfir.expr<?xf32>
570   return
572 // CHECK-LABEL:   func.func @other_reads_late_decl(
573 // CHECK-SAME:                      %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "z"},
574 // CHECK-SAME:                      %[[VAL_1:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"},
575 // CHECK-SAME:                      %[[VAL_2:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "y"}) {
576 // CHECK:           %[[VAL_3:.*]] = arith.constant 1 : index
577 // CHECK:           %[[VAL_4:.*]] = arith.constant 0 : index
578 // CHECK:           %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
579 // CHECK:           %[[VAL_6:.*]] = fir.shape %[[VAL_5]]#1 : (index) -> !fir.shape<1>
580 // CHECK-DAG:           %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_6]]) {uniq_name = "z"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
581 // CHECK-DAG:           %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_6]]) {uniq_name = "x"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
582 // CHECK-DAG:           %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_2]](%[[VAL_6]]) {uniq_name = "y"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
583 // CHECK:           fir.do_loop %[[VAL_10:.*]] = %[[VAL_3]] to %[[VAL_5]]#1 step %[[VAL_3]] unordered {
584 // CHECK:             %[[VAL_11:.*]] = hlfir.designate %[[VAL_8]]#0 (%[[VAL_10]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
585 // CHECK:             %[[VAL_12:.*]] = fir.load %[[VAL_11]] : !fir.ref<f32>
586 // CHECK:             %[[VAL_13:.*]] = hlfir.designate %[[VAL_9]]#0 (%[[VAL_10]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
587 // CHECK:             %[[VAL_14:.*]] = fir.load %[[VAL_13]] : !fir.ref<f32>
588 // CHECK:             %[[VAL_15:.*]] = arith.addf %[[VAL_12]], %[[VAL_14]] : f32
589 // CHECK:             %[[VAL_16:.*]] = hlfir.designate %[[VAL_7]]#0 (%[[VAL_10]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
590 // CHECK:             hlfir.assign %[[VAL_15]] to %[[VAL_16]] : f32, !fir.ref<f32>
591 // CHECK:           }
592 // CHECK:           return
593 // CHECK:         }
595 // support for z = x + y, when z is declared after the elemental and the shape values are different
596 func.func @other_reads_odd_shape(%z_arg: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "z"}, %x_arg: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"}, %y_arg: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "y"}) {
597   %c0 = arith.constant 0 : index
598   %x_box_dims:3 = fir.box_dims %x_arg, %c0 : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
599   // ignore lower bound etc
600   %xy_shape = fir.shape %x_box_dims#1 : (index) -> !fir.shape<1>
602   %x:2 = hlfir.declare %x_arg(%xy_shape) {uniq_name = "x"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
603   %y:2 = hlfir.declare %y_arg(%xy_shape) {uniq_name = "y"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
605   %elemental = hlfir.elemental %xy_shape unordered : (!fir.shape<1>) -> !hlfir.expr<?xf32> {
606   ^bb0(%i: index):
607     %x_ref = hlfir.designate %x#0 (%i) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
608     %x_val = fir.load %x_ref : !fir.ref<f32>
609     %y_ref = hlfir.designate %y#0 (%i) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
610     %y_val = fir.load %y_ref : !fir.ref<f32>
611     %add = arith.addf %x_val, %y_val : f32
612     hlfir.yield_element %add : f32
613   }
615   %z_box_dims:3 = fir.box_dims %z_arg, %c0 : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
616   // ignore lower bound etc
617   %z_shape = fir.shape %z_box_dims#1 : (index) -> !fir.shape<1>
618   %z:2 = hlfir.declare %z_arg(%z_shape) {uniq_name = "z"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
619   // assume the length of z is 10 longer than the length of x
620   %c10 = arith.constant 10 : index
621   %c1 = arith.constant 1 : index
622   %slice_extent = arith.addi %c10, %x_box_dims#1 : index
623   %slice_shape = fir.shape %slice_extent : (index) -> !fir.shape<1>
624   %z_slice = hlfir.designate %z#0 (%c10:%slice_extent:%c1) shape %slice_shape : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
626   hlfir.assign %elemental to %z_slice : !hlfir.expr<?xf32>, !fir.box<!fir.array<?xf32>>
627   hlfir.destroy %elemental : !hlfir.expr<?xf32>
628   return
630 // CHECK-LABEL: func.func @other_reads_odd_shape(
631 // CHECK-SAME:                                   %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "z"},
632 // CHECK-SAME:                                   %[[VAL_1:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"},
633 // CHECK-SAME:                                   %[[VAL_2:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "y"}) {
634 // CHECK:         %[[VAL_3:.*]] = arith.constant 1 : index
635 // CHECK:         %[[VAL_4:.*]] = arith.constant 10 : index
636 // CHECK:         %[[VAL_5:.*]] = arith.constant 0 : index
637 // CHECK:         %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_5]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
638 // CHECK:         %[[VAL_7:.*]] = fir.shape %[[VAL_6]]#1 : (index) -> !fir.shape<1>
639 // CHECK:         %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_7]]) {uniq_name = "x"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
640 // CHECK:         %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_2]](%[[VAL_7]]) {uniq_name = "y"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
641 // CHECK:         %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
642 // CHECK:         %[[VAL_11:.*]] = fir.shape %[[VAL_10]]#1 : (index) -> !fir.shape<1>
643 // CHECK:         %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_11]]) {uniq_name = "z"} : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
644 // CHECK:         %[[VAL_13:.*]] = arith.addi %[[VAL_6]]#1, %[[VAL_4]] : index
645 // CHECK:         %[[VAL_14:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1>
646 // CHECK:         %[[VAL_15:.*]] = hlfir.designate %[[VAL_12]]#0 (%[[VAL_4]]:%[[VAL_13]]:%[[VAL_3]])  shape %[[VAL_14]] : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
647 // CHECK:         fir.do_loop %[[VAL_16:.*]] = %[[VAL_3]] to %[[VAL_6]]#1 step %[[VAL_3]] unordered {
648 // CHECK:           %[[VAL_17:.*]] = hlfir.designate %[[VAL_8]]#0 (%[[VAL_16]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
649 // CHECK:           %[[VAL_18:.*]] = fir.load %[[VAL_17]] : !fir.ref<f32>
650 // CHECK:           %[[VAL_19:.*]] = hlfir.designate %[[VAL_9]]#0 (%[[VAL_16]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
651 // CHECK:           %[[VAL_20:.*]] = fir.load %[[VAL_19]] : !fir.ref<f32>
652 // CHECK:           %[[VAL_21:.*]] = arith.addf %[[VAL_18]], %[[VAL_20]] : f32
653 // CHECK:           %[[VAL_22:.*]] = hlfir.designate %[[VAL_15]] (%[[VAL_16]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
654 // CHECK:           hlfir.assign %[[VAL_21]] to %[[VAL_22]] : f32, !fir.ref<f32>
655 // CHECK:         }
656 // CHECK:         return
657 // CHECK:       }
659 // full test from intended code samplemodule attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.target_triple = "aarch64-unknown-linux-gnu"} {
660 func.func @_QPddx(%arg0: !fir.box<!fir.array<?x?xf64>> {fir.bindc_name = "array"}) -> !fir.array<?x?xf64> {
661   %c-1 = arith.constant -1 : index
662   %c-2 = arith.constant -2 : index
663   %c1_i32 = arith.constant 1 : i32
664   %c2 = arith.constant 2 : index
665   %c2_i32 = arith.constant 2 : i32
666   %c3 = arith.constant 3 : index
667   %c1 = arith.constant 1 : index
668   %c0 = arith.constant 0 : index
669   %0:2 = hlfir.declare %arg0 {uniq_name = "_QFddxEarray"} : (!fir.box<!fir.array<?x?xf64>>) -> (!fir.box<!fir.array<?x?xf64>>, !fir.box<!fir.array<?x?xf64>>)
670   %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFddxEi"}
671   %2:2 = hlfir.declare %1 {uniq_name = "_QFddxEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
672   %3 = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFddxEj"}
673   %4:2 = hlfir.declare %3 {uniq_name = "_QFddxEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
674   %5:3 = fir.box_dims %0#0, %c0 : (!fir.box<!fir.array<?x?xf64>>, index) -> (index, index, index)
675   %6 = fir.convert %5#1 : (index) -> i64
676   %7 = fir.convert %6 : (i64) -> index
677   %8 = arith.cmpi sgt, %7, %c0 : index
678   %9 = arith.select %8, %7, %c0 : index
679   %10:3 = fir.box_dims %0#0, %c1 : (!fir.box<!fir.array<?x?xf64>>, index) -> (index, index, index)
680   %11 = fir.convert %10#1 : (index) -> i64
681   %12 = fir.convert %11 : (i64) -> index
682   %13 = arith.cmpi sgt, %12, %c0 : index
683   %14 = arith.select %13, %12, %c0 : index
684   %15 = fir.alloca !fir.array<?x?xf64>, %9, %14 {bindc_name = "ddx", uniq_name = "_QFddxEddx"}
685   %16 = fir.shape %9, %14 : (index, index) -> !fir.shape<2>
686   %17:2 = hlfir.declare %15(%16) {uniq_name = "_QFddxEddx"} : (!fir.ref<!fir.array<?x?xf64>>, !fir.shape<2>) -> (!fir.box<!fir.array<?x?xf64>>, !fir.ref<!fir.array<?x?xf64>>)
687   %18 = fir.convert %5#1 : (index) -> i32
688   hlfir.assign %18 to %2#0 : i32, !fir.ref<i32>
689   %19 = fir.convert %10#1 : (index) -> i32
690   hlfir.assign %19 to %4#0 : i32, !fir.ref<i32>
691   %20 = fir.load %2#0 : !fir.ref<i32>
692   %21 = fir.convert %20 : (i32) -> index
693   %22 = arith.addi %21, %c-2 : index
694   %23 = arith.cmpi sgt, %22, %c0 : index
695   %24 = arith.select %23, %22, %c0 : index
696   %25 = fir.load %4#0 : !fir.ref<i32>
697   %26 = fir.convert %25 : (i32) -> index
698   %27 = arith.cmpi sgt, %26, %c0 : index
699   %28 = arith.select %27, %26, %c0 : index
700   %29 = fir.shape %24, %28 : (index, index) -> !fir.shape<2>
701   %30 = hlfir.designate %0#0 (%c3:%21:%c1, %c1:%26:%c1)  shape %29 : (!fir.box<!fir.array<?x?xf64>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf64>>
702   %31 = arith.subi %20, %c2_i32 : i32
703   %32 = fir.convert %31 : (i32) -> index
704   %33 = arith.cmpi sgt, %32, %c0 : index
705   %34 = arith.select %33, %32, %c0 : index
706   %35 = fir.shape %34, %28 : (index, index) -> !fir.shape<2>
707   %36 = hlfir.designate %0#0 (%c1:%32:%c1, %c1:%26:%c1)  shape %35 : (!fir.box<!fir.array<?x?xf64>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf64>>
708   %37 = hlfir.elemental %29 unordered : (!fir.shape<2>) -> !hlfir.expr<?x?xf64> {
709   ^bb0(%arg1: index, %arg2: index):
710     %46 = hlfir.designate %30 (%arg1, %arg2)  : (!fir.box<!fir.array<?x?xf64>>, index, index) -> !fir.ref<f64>
711     %47 = hlfir.designate %36 (%arg1, %arg2)  : (!fir.box<!fir.array<?x?xf64>>, index, index) -> !fir.ref<f64>
712     %48 = fir.load %46 : !fir.ref<f64>
713     %49 = fir.load %47 : !fir.ref<f64>
714     %50 = arith.subf %48, %49 fastmath<contract> : f64
715     hlfir.yield_element %50 : f64
716   }
717   %38 = arith.subi %20, %c1_i32 : i32
718   %39 = fir.convert %38 : (i32) -> index
719   %40 = arith.addi %39, %c-1 : index
720   %41 = arith.cmpi sgt, %40, %c0 : index
721   %42 = arith.select %41, %40, %c0 : index
722   %43 = fir.shape %42, %28 : (index, index) -> !fir.shape<2>
723   %44 = hlfir.designate %17#0 (%c2:%39:%c1, %c1:%26:%c1)  shape %43 : (!fir.box<!fir.array<?x?xf64>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf64>>
724   hlfir.assign %37 to %44 : !hlfir.expr<?x?xf64>, !fir.box<!fir.array<?x?xf64>>
725   hlfir.destroy %37 : !hlfir.expr<?x?xf64>
726   %45 = fir.load %17#1 : !fir.ref<!fir.array<?x?xf64>>
727   return %45 : !fir.array<?x?xf64>
729 // CHECK-LABEL:   func.func @_QPddx(
730 // CHECK-SAME:                      %[[VAL_0:.*]]: !fir.box<!fir.array<?x?xf64>> {fir.bindc_name = "array"}) -> !fir.array<?x?xf64> {
731 // CHECK:           %[[VAL_1:.*]] = arith.constant -1 : index
732 // CHECK:           %[[VAL_2:.*]] = arith.constant -2 : index
733 // CHECK:           %[[VAL_3:.*]] = arith.constant 1 : i32
734 // CHECK:           %[[VAL_4:.*]] = arith.constant 2 : index
735 // CHECK:           %[[VAL_5:.*]] = arith.constant 2 : i32
736 // CHECK:           %[[VAL_6:.*]] = arith.constant 3 : index
737 // CHECK:           %[[VAL_7:.*]] = arith.constant 1 : index
738 // CHECK:           %[[VAL_8:.*]] = arith.constant 0 : index
739 // CHECK:           %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFddxEarray"} : (!fir.box<!fir.array<?x?xf64>>) -> (!fir.box<!fir.array<?x?xf64>>, !fir.box<!fir.array<?x?xf64>>)
740 // CHECK:           %[[VAL_10:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFddxEi"}
741 // CHECK:           %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFddxEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
742 // CHECK:           %[[VAL_12:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFddxEj"}
743 // CHECK:           %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QFddxEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
744 // CHECK:           %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_9]]#0, %[[VAL_8]] : (!fir.box<!fir.array<?x?xf64>>, index) -> (index, index, index)
745 // CHECK:           %[[VAL_15:.*]] = fir.convert %[[VAL_14]]#1 : (index) -> i64
746 // CHECK:           %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i64) -> index
747 // CHECK:           %[[VAL_17:.*]] = arith.cmpi sgt, %[[VAL_16]], %[[VAL_8]] : index
748 // CHECK:           %[[VAL_18:.*]] = arith.select %[[VAL_17]], %[[VAL_16]], %[[VAL_8]] : index
749 // CHECK:           %[[VAL_19:.*]]:3 = fir.box_dims %[[VAL_9]]#0, %[[VAL_7]] : (!fir.box<!fir.array<?x?xf64>>, index) -> (index, index, index)
750 // CHECK:           %[[VAL_20:.*]] = fir.convert %[[VAL_19]]#1 : (index) -> i64
751 // CHECK:           %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i64) -> index
752 // CHECK:           %[[VAL_22:.*]] = arith.cmpi sgt, %[[VAL_21]], %[[VAL_8]] : index
753 // CHECK:           %[[VAL_23:.*]] = arith.select %[[VAL_22]], %[[VAL_21]], %[[VAL_8]] : index
754 // CHECK:           %[[VAL_24:.*]] = fir.alloca !fir.array<?x?xf64>, %[[VAL_18]], %[[VAL_23]] {bindc_name = "ddx", uniq_name = "_QFddxEddx"}
755 // CHECK:           %[[VAL_25:.*]] = fir.shape %[[VAL_18]], %[[VAL_23]] : (index, index) -> !fir.shape<2>
756 // CHECK:           %[[VAL_26:.*]]:2 = hlfir.declare %[[VAL_24]](%[[VAL_25]]) {uniq_name = "_QFddxEddx"} : (!fir.ref<!fir.array<?x?xf64>>, !fir.shape<2>) -> (!fir.box<!fir.array<?x?xf64>>, !fir.ref<!fir.array<?x?xf64>>)
757 // CHECK:           %[[VAL_27:.*]] = fir.convert %[[VAL_14]]#1 : (index) -> i32
758 // CHECK:           hlfir.assign %[[VAL_27]] to %[[VAL_11]]#0 : i32, !fir.ref<i32>
759 // CHECK:           %[[VAL_28:.*]] = fir.convert %[[VAL_19]]#1 : (index) -> i32
760 // CHECK:           hlfir.assign %[[VAL_28]] to %[[VAL_13]]#0 : i32, !fir.ref<i32>
761 // CHECK:           %[[VAL_29:.*]] = fir.load %[[VAL_11]]#0 : !fir.ref<i32>
762 // CHECK:           %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i32) -> index
763 // CHECK:           %[[VAL_31:.*]] = arith.addi %[[VAL_30]], %[[VAL_2]] : index
764 // CHECK:           %[[VAL_32:.*]] = arith.cmpi sgt, %[[VAL_31]], %[[VAL_8]] : index
765 // CHECK:           %[[VAL_33:.*]] = arith.select %[[VAL_32]], %[[VAL_31]], %[[VAL_8]] : index
766 // CHECK:           %[[VAL_34:.*]] = fir.load %[[VAL_13]]#0 : !fir.ref<i32>
767 // CHECK:           %[[VAL_35:.*]] = fir.convert %[[VAL_34]] : (i32) -> index
768 // CHECK:           %[[VAL_36:.*]] = arith.cmpi sgt, %[[VAL_35]], %[[VAL_8]] : index
769 // CHECK:           %[[VAL_37:.*]] = arith.select %[[VAL_36]], %[[VAL_35]], %[[VAL_8]] : index
770 // CHECK:           %[[VAL_38:.*]] = fir.shape %[[VAL_33]], %[[VAL_37]] : (index, index) -> !fir.shape<2>
771 // CHECK:           %[[VAL_39:.*]] = hlfir.designate %[[VAL_9]]#0 (%[[VAL_6]]:%[[VAL_30]]:%[[VAL_7]], %[[VAL_7]]:%[[VAL_35]]:%[[VAL_7]])  shape %[[VAL_38]] : (!fir.box<!fir.array<?x?xf64>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf64>>
772 // CHECK:           %[[VAL_40:.*]] = arith.subi %[[VAL_29]], %[[VAL_5]] : i32
773 // CHECK:           %[[VAL_41:.*]] = fir.convert %[[VAL_40]] : (i32) -> index
774 // CHECK:           %[[VAL_42:.*]] = arith.cmpi sgt, %[[VAL_41]], %[[VAL_8]] : index
775 // CHECK:           %[[VAL_43:.*]] = arith.select %[[VAL_42]], %[[VAL_41]], %[[VAL_8]] : index
776 // CHECK:           %[[VAL_44:.*]] = fir.shape %[[VAL_43]], %[[VAL_37]] : (index, index) -> !fir.shape<2>
777 // CHECK:           %[[VAL_45:.*]] = hlfir.designate %[[VAL_9]]#0 (%[[VAL_7]]:%[[VAL_41]]:%[[VAL_7]], %[[VAL_7]]:%[[VAL_35]]:%[[VAL_7]])  shape %[[VAL_44]] : (!fir.box<!fir.array<?x?xf64>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf64>>
778 // CHECK:           %[[VAL_46:.*]] = arith.subi %[[VAL_29]], %[[VAL_3]] : i32
779 // CHECK:           %[[VAL_47:.*]] = fir.convert %[[VAL_46]] : (i32) -> index
780 // CHECK:           %[[VAL_48:.*]] = arith.addi %[[VAL_47]], %[[VAL_1]] : index
781 // CHECK:           %[[VAL_49:.*]] = arith.cmpi sgt, %[[VAL_48]], %[[VAL_8]] : index
782 // CHECK:           %[[VAL_50:.*]] = arith.select %[[VAL_49]], %[[VAL_48]], %[[VAL_8]] : index
783 // CHECK:           %[[VAL_51:.*]] = fir.shape %[[VAL_50]], %[[VAL_37]] : (index, index) -> !fir.shape<2>
784 // CHECK:           %[[VAL_52:.*]] = hlfir.designate %[[VAL_26]]#0 (%[[VAL_4]]:%[[VAL_47]]:%[[VAL_7]], %[[VAL_7]]:%[[VAL_35]]:%[[VAL_7]])  shape %[[VAL_51]] : (!fir.box<!fir.array<?x?xf64>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf64>>
785 // CHECK:           fir.do_loop %[[VAL_53:.*]] = %[[VAL_7]] to %[[VAL_37]] step %[[VAL_7]] unordered {
786 // CHECK:             fir.do_loop %[[VAL_54:.*]] = %[[VAL_7]] to %[[VAL_33]] step %[[VAL_7]] unordered {
787 // CHECK:               %[[VAL_55:.*]] = hlfir.designate %[[VAL_39]] (%[[VAL_54]], %[[VAL_53]])  : (!fir.box<!fir.array<?x?xf64>>, index, index) -> !fir.ref<f64>
788 // CHECK:               %[[VAL_56:.*]] = hlfir.designate %[[VAL_45]] (%[[VAL_54]], %[[VAL_53]])  : (!fir.box<!fir.array<?x?xf64>>, index, index) -> !fir.ref<f64>
789 // CHECK:               %[[VAL_57:.*]] = fir.load %[[VAL_55]] : !fir.ref<f64>
790 // CHECK:               %[[VAL_58:.*]] = fir.load %[[VAL_56]] : !fir.ref<f64>
791 // CHECK:               %[[VAL_59:.*]] = arith.subf %[[VAL_57]], %[[VAL_58]] fastmath<contract> : f64
792 // CHECK:               %[[VAL_60:.*]] = hlfir.designate %[[VAL_52]] (%[[VAL_54]], %[[VAL_53]])  : (!fir.box<!fir.array<?x?xf64>>, index, index) -> !fir.ref<f64>
793 // CHECK:               hlfir.assign %[[VAL_59]] to %[[VAL_60]] : f64, !fir.ref<f64>
794 // CHECK:             }
795 // CHECK:           }
796 // CHECK:           %[[VAL_61:.*]] = fir.load %[[VAL_26]]#1 : !fir.ref<!fir.array<?x?xf64>>
797 // CHECK:           return %[[VAL_61]] : !fir.array<?x?xf64>
798 // CHECK:         }
800 // `hlfir.expr` bufferization (when the expresion is not the result of
801 // `hlfir.elemental`)
802 func.func @_QPfoo() {
803   %c1 = arith.constant 1 : index
804   %0 = fir.alloca !fir.array<1xi32> {bindc_name = "iavs", uniq_name = "_QFfooEiavs"}
805   %1 = fir.shape %c1 : (index) -> !fir.shape<1>
806   %2:2 = hlfir.declare %0(%1) {uniq_name = "_QFfooEiavs"} : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<1xi32>>, !fir.ref<!fir.array<1xi32>>)
807   %3 = fir.alloca i32 {bindc_name = "iv", uniq_name = "_QFfooEiv"}
808   %4:2 = hlfir.declare %3 {uniq_name = "_QFfooEiv"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
809   %c10_i32 = arith.constant 10 : i32
810   %6 = fir.convert %c10_i32 : (i32) -> index
811   %7 = fir.convert %c1 : (index) -> i32
812   %8:2 = fir.do_loop %arg0 = %c1 to %6 step %c1 iter_args(%arg1 = %7) -> (index, i32) {
813     fir.store %arg1 to %4#1 : !fir.ref<i32>
814     %9 = fir.allocmem !fir.array<1xi32> {bindc_name = ".tmp.arrayctor", uniq_name = ""}
815     %10 = fir.shape %c1 : (index) -> !fir.shape<1>
816     %11:2 = hlfir.declare %9(%10) {uniq_name = ".tmp.arrayctor"} : (!fir.heap<!fir.array<1xi32>>, !fir.shape<1>) -> (!fir.heap<!fir.array<1xi32>>, !fir.heap<!fir.array<1xi32>>)
817     %12 = fir.load %4#0 : !fir.ref<i32>
818     %13 = hlfir.designate %11#0 (%c1)  : (!fir.heap<!fir.array<1xi32>>, index) -> !fir.ref<i32>
819     hlfir.assign %12 to %13 : i32, !fir.ref<i32>
820     %true = arith.constant true
821     %14 = hlfir.as_expr %11#0 move %true : (!fir.heap<!fir.array<1xi32>>, i1) -> !hlfir.expr<1xi32>
822     hlfir.assign %14 to %2#0 : !hlfir.expr<1xi32>, !fir.ref<!fir.array<1xi32>>
823     hlfir.destroy %14 : !hlfir.expr<1xi32>
824     %15 = arith.addi %arg0, %c1 : index
825     %16 = fir.convert %c1 : (index) -> i32
826     %17 = fir.load %4#1 : !fir.ref<i32>
827     %18 = arith.addi %17, %16 : i32
828     fir.result %15, %18 : index, i32
829   }
830   fir.store %8#1 to %4#1 : !fir.ref<i32>
831   return
834 // CHECK-LABEL:   func.func @_QPfoo
835 // CHECK:           %[[C1:.*]] = arith.constant 1 : index
836 // CHECK:           fir.do_loop {{.*}} {
837 // CHECK-NOT:         hlfir.assign %{{.*}} to %{{.*}}#0 : !hlfir.expr<1xi32>, !fir.ref<!fir.array<1xi32>>
838 // CHECK:             fir.do_loop %{{.*}} = %[[C1]] to %[[C1]] step %[[C1]] unordered {
839 // CHECK:             }
840 // CHECK:           }