IR: de-duplicate two CmpInst routines (NFC) (#116866)
[llvm-project.git] / flang / test / Lower / do_loop_unstructured.f90
blobe1a669e09c9a8954ab9cebd3208b7a815efe2288
1 ! RUN: bbc -emit-fir -hlfir=false -o - %s | FileCheck %s
2 ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -o - %s | FileCheck %s
3 ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -flang-experimental-integer-overflow -o - %s | FileCheck %s --check-prefix=NSW
5 ! Tests for unstructured loops.
7 ! Test a simple unstructured loop. Test for the existence of,
8 ! -> The initialization of the trip-count and loop-variable
9 ! -> The branch to the body or the exit inside the header
10 ! -> The increment of the trip-count and the loop-variable inside the body
11 subroutine simple_unstructured()
12 integer :: i
13 do i=1,100
14 goto 404
15 404 continue
16 end do
17 end subroutine
18 ! CHECK-LABEL: simple_unstructured
19 ! CHECK: %[[TRIP_VAR_REF:.*]] = fir.alloca i32
20 ! CHECK: %[[LOOP_VAR_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimple_unstructuredEi"}
21 ! CHECK: %[[ONE:.*]] = arith.constant 1 : i32
22 ! CHECK: %[[HUNDRED:.*]] = arith.constant 100 : i32
23 ! CHECK: %[[STEP_ONE:.*]] = arith.constant 1 : i32
24 ! CHECK: %[[TMP1:.*]] = arith.subi %[[HUNDRED]], %[[ONE]] : i32
25 ! CHECK: %[[TMP2:.*]] = arith.addi %[[TMP1]], %[[STEP_ONE]] : i32
26 ! CHECK: %[[TRIP_COUNT:.*]] = arith.divsi %[[TMP2]], %[[STEP_ONE]] : i32
27 ! CHECK: fir.store %[[TRIP_COUNT]] to %[[TRIP_VAR_REF]] : !fir.ref<i32>
28 ! CHECK: fir.store %[[ONE]] to %[[LOOP_VAR_REF]] : !fir.ref<i32>
29 ! CHECK: cf.br ^[[HEADER:.*]]
30 ! CHECK: ^[[HEADER]]:
31 ! CHECK: %[[TRIP_VAR:.*]] = fir.load %[[TRIP_VAR_REF]] : !fir.ref<i32>
32 ! CHECK: %[[ZERO:.*]] = arith.constant 0 : i32
33 ! CHECK: %[[COND:.*]] = arith.cmpi sgt, %[[TRIP_VAR]], %[[ZERO]] : i32
34 ! CHECK: cf.cond_br %[[COND]], ^[[BODY:.*]], ^[[EXIT:.*]]
35 ! CHECK: ^[[BODY]]:
36 ! CHECK: %[[TRIP_VAR:.*]] = fir.load %[[TRIP_VAR_REF]] : !fir.ref<i32>
37 ! CHECK: %[[ONE_1:.*]] = arith.constant 1 : i32
38 ! CHECK: %[[TRIP_VAR_NEXT:.*]] = arith.subi %[[TRIP_VAR]], %[[ONE_1]] : i32
39 ! CHECK: fir.store %[[TRIP_VAR_NEXT]] to %[[TRIP_VAR_REF]] : !fir.ref<i32>
40 ! CHECK: %[[LOOP_VAR:.*]] = fir.load %[[LOOP_VAR_REF]] : !fir.ref<i32>
41 ! CHECK: %[[STEP_ONE_2:.*]] = arith.constant 1 : i32
42 ! CHECK: %[[LOOP_VAR_NEXT:.*]] = arith.addi %[[LOOP_VAR]], %[[STEP_ONE_2]] : i32
43 ! CHECK: fir.store %[[LOOP_VAR_NEXT]] to %[[LOOP_VAR_REF]] : !fir.ref<i32>
44 ! CHECK: cf.br ^[[HEADER]]
45 ! CHECK: ^[[EXIT]]:
46 ! CHECK: return
48 ! NSW-LABEL: simple_unstructured
49 ! NSW: %[[TRIP_VAR_REF:.*]] = fir.alloca i32
50 ! NSW: %[[LOOP_VAR_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimple_unstructuredEi"}
51 ! NSW: %[[ONE:.*]] = arith.constant 1 : i32
52 ! NSW: %[[HUNDRED:.*]] = arith.constant 100 : i32
53 ! NSW: %[[STEP_ONE:.*]] = arith.constant 1 : i32
54 ! NSW: %[[TMP1:.*]] = arith.subi %[[HUNDRED]], %[[ONE]] : i32
55 ! NSW: %[[TMP2:.*]] = arith.addi %[[TMP1]], %[[STEP_ONE]] : i32
56 ! NSW: %[[TRIP_COUNT:.*]] = arith.divsi %[[TMP2]], %[[STEP_ONE]] : i32
57 ! NSW: fir.store %[[TRIP_COUNT]] to %[[TRIP_VAR_REF]] : !fir.ref<i32>
58 ! NSW: fir.store %[[ONE]] to %[[LOOP_VAR_REF]] : !fir.ref<i32>
59 ! NSW: cf.br ^[[HEADER:.*]]
60 ! NSW: ^[[HEADER]]:
61 ! NSW: %[[TRIP_VAR:.*]] = fir.load %[[TRIP_VAR_REF]] : !fir.ref<i32>
62 ! NSW: %[[ZERO:.*]] = arith.constant 0 : i32
63 ! NSW: %[[COND:.*]] = arith.cmpi sgt, %[[TRIP_VAR]], %[[ZERO]] : i32
64 ! NSW: cf.cond_br %[[COND]], ^[[BODY:.*]], ^[[EXIT:.*]]
65 ! NSW: ^[[BODY]]:
66 ! NSW: %[[TRIP_VAR:.*]] = fir.load %[[TRIP_VAR_REF]] : !fir.ref<i32>
67 ! NSW: %[[ONE_1:.*]] = arith.constant 1 : i32
68 ! NSW: %[[TRIP_VAR_NEXT:.*]] = arith.subi %[[TRIP_VAR]], %[[ONE_1]] : i32
69 ! NSW: fir.store %[[TRIP_VAR_NEXT]] to %[[TRIP_VAR_REF]] : !fir.ref<i32>
70 ! NSW: %[[LOOP_VAR:.*]] = fir.load %[[LOOP_VAR_REF]] : !fir.ref<i32>
71 ! NSW: %[[STEP_ONE_2:.*]] = arith.constant 1 : i32
72 ! NSW: %[[LOOP_VAR_NEXT:.*]] = arith.addi %[[LOOP_VAR]], %[[STEP_ONE_2]] overflow<nsw> : i32
73 ! NSW: fir.store %[[LOOP_VAR_NEXT]] to %[[LOOP_VAR_REF]] : !fir.ref<i32>
74 ! NSW: cf.br ^[[HEADER]]
75 ! NSW: ^[[EXIT]]:
76 ! NSW: return
78 ! Test an unstructured loop with a step. Mostly similar to the previous one.
79 ! Only difference is a non-unit step.
80 subroutine simple_unstructured_with_step()
81 integer :: i
82 do i=1,100,2
83 goto 404
84 404 continue
85 end do
86 end subroutine
87 ! CHECK-LABEL: simple_unstructured_with_step
88 ! CHECK: %[[TRIP_VAR_REF:.*]] = fir.alloca i32
89 ! CHECK: %[[LOOP_VAR_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimple_unstructured_with_stepEi"}
90 ! CHECK: %[[ONE:.*]] = arith.constant 1 : i32
91 ! CHECK: %[[HUNDRED:.*]] = arith.constant 100 : i32
92 ! CHECK: %[[STEP:.*]] = arith.constant 2 : i32
93 ! CHECK: %[[TMP1:.*]] = arith.subi %[[HUNDRED]], %[[ONE]] : i32
94 ! CHECK: %[[TMP2:.*]] = arith.addi %[[TMP1]], %[[STEP]] : i32
95 ! CHECK: %[[TRIP_COUNT:.*]] = arith.divsi %[[TMP2]], %[[STEP]] : i32
96 ! CHECK: fir.store %[[TRIP_COUNT]] to %[[TRIP_VAR_REF]] : !fir.ref<i32>
97 ! CHECK: fir.store %[[ONE]] to %[[LOOP_VAR_REF]] : !fir.ref<i32>
98 ! CHECK: cf.br ^[[HEADER:.*]]
99 ! CHECK: ^[[HEADER]]:
100 ! CHECK: %[[TRIP_VAR:.*]] = fir.load %[[TRIP_VAR_REF]] : !fir.ref<i32>
101 ! CHECK: %[[ZERO:.*]] = arith.constant 0 : i32
102 ! CHECK: %[[COND:.*]] = arith.cmpi sgt, %[[TRIP_VAR]], %[[ZERO]] : i32
103 ! CHECK: cf.cond_br %[[COND]], ^[[BODY:.*]], ^[[EXIT:.*]]
104 ! CHECK: ^[[BODY]]:
105 ! CHECK: %[[TRIP_VAR:.*]] = fir.load %[[TRIP_VAR_REF]] : !fir.ref<i32>
106 ! CHECK: %[[ONE_1:.*]] = arith.constant 1 : i32
107 ! CHECK: %[[TRIP_VAR_NEXT:.*]] = arith.subi %[[TRIP_VAR]], %[[ONE_1]] : i32
108 ! CHECK: fir.store %[[TRIP_VAR_NEXT]] to %[[TRIP_VAR_REF]] : !fir.ref<i32>
109 ! CHECK: %[[LOOP_VAR:.*]] = fir.load %[[LOOP_VAR_REF]] : !fir.ref<i32>
110 ! CHECK: %[[STEP_2:.*]] = arith.constant 2 : i32
111 ! CHECK: %[[LOOP_VAR_NEXT:.*]] = arith.addi %[[LOOP_VAR]], %[[STEP_2]] : i32
112 ! CHECK: fir.store %[[LOOP_VAR_NEXT]] to %[[LOOP_VAR_REF]] : !fir.ref<i32>
113 ! CHECK: cf.br ^[[HEADER]]
114 ! CHECK: ^[[EXIT]]:
115 ! CHECK: return
117 ! NSW-LABEL: simple_unstructured_with_step
118 ! NSW: %[[TRIP_VAR_REF:.*]] = fir.alloca i32
119 ! NSW: %[[LOOP_VAR_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimple_unstructured_with_stepEi"}
120 ! NSW: %[[ONE:.*]] = arith.constant 1 : i32
121 ! NSW: %[[HUNDRED:.*]] = arith.constant 100 : i32
122 ! NSW: %[[STEP:.*]] = arith.constant 2 : i32
123 ! NSW: %[[TMP1:.*]] = arith.subi %[[HUNDRED]], %[[ONE]] : i32
124 ! NSW: %[[TMP2:.*]] = arith.addi %[[TMP1]], %[[STEP]] : i32
125 ! NSW: %[[TRIP_COUNT:.*]] = arith.divsi %[[TMP2]], %[[STEP]] : i32
126 ! NSW: fir.store %[[TRIP_COUNT]] to %[[TRIP_VAR_REF]] : !fir.ref<i32>
127 ! NSW: fir.store %[[ONE]] to %[[LOOP_VAR_REF]] : !fir.ref<i32>
128 ! NSW: cf.br ^[[HEADER:.*]]
129 ! NSW: ^[[HEADER]]:
130 ! NSW: %[[TRIP_VAR:.*]] = fir.load %[[TRIP_VAR_REF]] : !fir.ref<i32>
131 ! NSW: %[[ZERO:.*]] = arith.constant 0 : i32
132 ! NSW: %[[COND:.*]] = arith.cmpi sgt, %[[TRIP_VAR]], %[[ZERO]] : i32
133 ! NSW: cf.cond_br %[[COND]], ^[[BODY:.*]], ^[[EXIT:.*]]
134 ! NSW: ^[[BODY]]:
135 ! NSW: %[[TRIP_VAR:.*]] = fir.load %[[TRIP_VAR_REF]] : !fir.ref<i32>
136 ! NSW: %[[ONE_1:.*]] = arith.constant 1 : i32
137 ! NSW: %[[TRIP_VAR_NEXT:.*]] = arith.subi %[[TRIP_VAR]], %[[ONE_1]] : i32
138 ! NSW: fir.store %[[TRIP_VAR_NEXT]] to %[[TRIP_VAR_REF]] : !fir.ref<i32>
139 ! NSW: %[[LOOP_VAR:.*]] = fir.load %[[LOOP_VAR_REF]] : !fir.ref<i32>
140 ! NSW: %[[STEP_2:.*]] = arith.constant 2 : i32
141 ! NSW: %[[LOOP_VAR_NEXT:.*]] = arith.addi %[[LOOP_VAR]], %[[STEP_2]] overflow<nsw> : i32
142 ! NSW: fir.store %[[LOOP_VAR_NEXT]] to %[[LOOP_VAR_REF]] : !fir.ref<i32>
143 ! NSW: cf.br ^[[HEADER]]
144 ! NSW: ^[[EXIT]]:
145 ! NSW: return
147 ! Test a three nested unstructured loop. Three nesting is the basic case where
148 ! we have loops that are neither innermost or outermost.
149 subroutine nested_unstructured()
150 integer :: i, j, k
151 do i=1,100
152 do j=1,200
153 do k=1,300
154 goto 404
155 404 continue
156 end do
157 end do
158 end do
159 end subroutine
160 ! CHECK-LABEL: nested_unstructured
161 ! CHECK: %[[TRIP_VAR_K_REF:.*]] = fir.alloca i32
162 ! CHECK: %[[TRIP_VAR_J_REF:.*]] = fir.alloca i32
163 ! CHECK: %[[TRIP_VAR_I_REF:.*]] = fir.alloca i32
164 ! CHECK: %[[LOOP_VAR_I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFnested_unstructuredEi"}
165 ! CHECK: %[[LOOP_VAR_J_REF:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFnested_unstructuredEj"}
166 ! CHECK: %[[LOOP_VAR_K_REF:.*]] = fir.alloca i32 {bindc_name = "k", uniq_name = "_QFnested_unstructuredEk"}
167 ! CHECK: %[[I_START:.*]] = arith.constant 1 : i32
168 ! CHECK: %[[I_END:.*]] = arith.constant 100 : i32
169 ! CHECK: %[[I_STEP:.*]] = arith.constant 1 : i32
170 ! CHECK: %[[TMP1:.*]] = arith.subi %[[I_END]], %[[I_START]] : i32
171 ! CHECK: %[[TMP2:.*]] = arith.addi %[[TMP1]], %[[I_STEP]] : i32
172 ! CHECK: %[[TRIP_COUNT_I:.*]] = arith.divsi %[[TMP2]], %[[I_STEP]] : i32
173 ! CHECK: fir.store %[[TRIP_COUNT_I]] to %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
174 ! CHECK: fir.store %[[I_START]] to %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
175 ! CHECK: cf.br ^[[HEADER_I:.*]]
176 ! CHECK: ^[[HEADER_I]]:
177 ! CHECK: %[[TRIP_VAR_I:.*]] = fir.load %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
178 ! CHECK: %[[ZERO_1:.*]] = arith.constant 0 : i32
179 ! CHECK: %[[COND_I:.*]] = arith.cmpi sgt, %[[TRIP_VAR_I]], %[[ZERO_1]] : i32
180 ! CHECK: cf.cond_br %[[COND_I]], ^[[BODY_I:.*]], ^[[EXIT_I:.*]]
181 ! CHECK: ^[[BODY_I]]:
182 ! CHECK: %[[J_START:.*]] = arith.constant 1 : i32
183 ! CHECK: %[[J_END:.*]] = arith.constant 200 : i32
184 ! CHECK: %[[J_STEP:.*]] = arith.constant 1 : i32
185 ! CHECK: %[[TMP3:.*]] = arith.subi %[[J_END]], %[[J_START]] : i32
186 ! CHECK: %[[TMP4:.*]] = arith.addi %[[TMP3]], %[[J_STEP]] : i32
187 ! CHECK: %[[TRIP_COUNT_J:.*]] = arith.divsi %[[TMP4]], %[[J_STEP]] : i32
188 ! CHECK: fir.store %[[TRIP_COUNT_J]] to %[[TRIP_VAR_J_REF]] : !fir.ref<i32>
189 ! CHECK: fir.store %[[J_START]] to %[[LOOP_VAR_J_REF]] : !fir.ref<i32>
190 ! CHECK: cf.br ^[[HEADER_J:.*]]
191 ! CHECK: ^[[HEADER_J]]:
192 ! CHECK: %[[TRIP_VAR_J:.*]] = fir.load %[[TRIP_VAR_J_REF]] : !fir.ref<i32>
193 ! CHECK: %[[ZERO_2:.*]] = arith.constant 0 : i32
194 ! CHECK: %[[COND_J:.*]] = arith.cmpi sgt, %[[TRIP_VAR_J]], %[[ZERO_2]] : i32
195 ! CHECK: cf.cond_br %[[COND_J]], ^[[BODY_J:.*]], ^[[EXIT_J:.*]]
196 ! CHECK: ^[[BODY_J]]:
197 ! CHECK: %[[K_START:.*]] = arith.constant 1 : i32
198 ! CHECK: %[[K_END:.*]] = arith.constant 300 : i32
199 ! CHECK: %[[K_STEP:.*]] = arith.constant 1 : i32
200 ! CHECK: %[[TMP3:.*]] = arith.subi %[[K_END]], %[[K_START]] : i32
201 ! CHECK: %[[TMP4:.*]] = arith.addi %[[TMP3]], %[[K_STEP]] : i32
202 ! CHECK: %[[TRIP_COUNT_K:.*]] = arith.divsi %[[TMP4]], %[[K_STEP]] : i32
203 ! CHECK: fir.store %[[TRIP_COUNT_K]] to %[[TRIP_VAR_K_REF]] : !fir.ref<i32>
204 ! CHECK: fir.store %[[K_START]] to %[[LOOP_VAR_K_REF]] : !fir.ref<i32>
205 ! CHECK: cf.br ^[[HEADER_K:.*]]
206 ! CHECK: ^[[HEADER_K]]:
207 ! CHECK: %[[TRIP_VAR_K:.*]] = fir.load %[[TRIP_VAR_K_REF]] : !fir.ref<i32>
208 ! CHECK: %[[ZERO_2:.*]] = arith.constant 0 : i32
209 ! CHECK: %[[COND_K:.*]] = arith.cmpi sgt, %[[TRIP_VAR_K]], %[[ZERO_2]] : i32
210 ! CHECK: cf.cond_br %[[COND_K]], ^[[BODY_K:.*]], ^[[EXIT_K:.*]]
211 ! CHECK: ^[[BODY_K]]:
212 ! CHECK: %[[TRIP_VAR_K:.*]] = fir.load %[[TRIP_VAR_K_REF]] : !fir.ref<i32>
213 ! CHECK: %[[ONE_1:.*]] = arith.constant 1 : i32
214 ! CHECK: %[[TRIP_VAR_K_NEXT:.*]] = arith.subi %[[TRIP_VAR_K]], %[[ONE_1]] : i32
215 ! CHECK: fir.store %[[TRIP_VAR_K_NEXT]] to %[[TRIP_VAR_K_REF]] : !fir.ref<i32>
216 ! CHECK: %[[LOOP_VAR_K:.*]] = fir.load %[[LOOP_VAR_K_REF]] : !fir.ref<i32>
217 ! CHECK: %[[K_STEP_2:.*]] = arith.constant 1 : i32
218 ! CHECK: %[[LOOP_VAR_K_NEXT:.*]] = arith.addi %[[LOOP_VAR_K]], %[[K_STEP_2]] : i32
219 ! CHECK: fir.store %[[LOOP_VAR_K_NEXT]] to %[[LOOP_VAR_K_REF]] : !fir.ref<i32>
220 ! CHECK: cf.br ^[[HEADER_K]]
221 ! CHECK: ^[[EXIT_K]]:
222 ! CHECK: %[[TRIP_VAR_J:.*]] = fir.load %[[TRIP_VAR_J_REF]] : !fir.ref<i32>
223 ! CHECK: %[[ONE_1:.*]] = arith.constant 1 : i32
224 ! CHECK: %[[TRIP_VAR_J_NEXT:.*]] = arith.subi %[[TRIP_VAR_J]], %[[ONE_1]] : i32
225 ! CHECK: fir.store %[[TRIP_VAR_J_NEXT]] to %[[TRIP_VAR_J_REF]] : !fir.ref<i32>
226 ! CHECK: %[[LOOP_VAR_J:.*]] = fir.load %[[LOOP_VAR_J_REF]] : !fir.ref<i32>
227 ! CHECK: %[[J_STEP_2:.*]] = arith.constant 1 : i32
228 ! CHECK: %[[LOOP_VAR_J_NEXT:.*]] = arith.addi %[[LOOP_VAR_J]], %[[J_STEP_2]] : i32
229 ! CHECK: fir.store %[[LOOP_VAR_J_NEXT]] to %[[LOOP_VAR_J_REF]] : !fir.ref<i32>
230 ! CHECK: cf.br ^[[HEADER_J]]
231 ! CHECK: ^[[EXIT_J]]:
232 ! CHECK: %[[TRIP_VAR_I:.*]] = fir.load %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
233 ! CHECK: %[[ONE_1:.*]] = arith.constant 1 : i32
234 ! CHECK: %[[TRIP_VAR_I_NEXT:.*]] = arith.subi %[[TRIP_VAR_I]], %[[ONE_1]] : i32
235 ! CHECK: fir.store %[[TRIP_VAR_I_NEXT]] to %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
236 ! CHECK: %[[LOOP_VAR_I:.*]] = fir.load %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
237 ! CHECK: %[[I_STEP_2:.*]] = arith.constant 1 : i32
238 ! CHECK: %[[LOOP_VAR_I_NEXT:.*]] = arith.addi %[[LOOP_VAR_I]], %[[I_STEP_2]] : i32
239 ! CHECK: fir.store %[[LOOP_VAR_I_NEXT]] to %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
240 ! CHECK: cf.br ^[[HEADER_I]]
241 ! CHECK: ^[[EXIT_I]]:
242 ! CHECK: return
244 ! NSW-LABEL: nested_unstructured
245 ! NSW: %[[TRIP_VAR_K_REF:.*]] = fir.alloca i32
246 ! NSW: %[[TRIP_VAR_J_REF:.*]] = fir.alloca i32
247 ! NSW: %[[TRIP_VAR_I_REF:.*]] = fir.alloca i32
248 ! NSW: %[[LOOP_VAR_I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFnested_unstructuredEi"}
249 ! NSW: %[[LOOP_VAR_J_REF:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFnested_unstructuredEj"}
250 ! NSW: %[[LOOP_VAR_K_REF:.*]] = fir.alloca i32 {bindc_name = "k", uniq_name = "_QFnested_unstructuredEk"}
251 ! NSW: %[[I_START:.*]] = arith.constant 1 : i32
252 ! NSW: %[[I_END:.*]] = arith.constant 100 : i32
253 ! NSW: %[[I_STEP:.*]] = arith.constant 1 : i32
254 ! NSW: %[[TMP1:.*]] = arith.subi %[[I_END]], %[[I_START]] : i32
255 ! NSW: %[[TMP2:.*]] = arith.addi %[[TMP1]], %[[I_STEP]] : i32
256 ! NSW: %[[TRIP_COUNT_I:.*]] = arith.divsi %[[TMP2]], %[[I_STEP]] : i32
257 ! NSW: fir.store %[[TRIP_COUNT_I]] to %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
258 ! NSW: fir.store %[[I_START]] to %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
259 ! NSW: cf.br ^[[HEADER_I:.*]]
260 ! NSW: ^[[HEADER_I]]:
261 ! NSW: %[[TRIP_VAR_I:.*]] = fir.load %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
262 ! NSW: %[[ZERO_1:.*]] = arith.constant 0 : i32
263 ! NSW: %[[COND_I:.*]] = arith.cmpi sgt, %[[TRIP_VAR_I]], %[[ZERO_1]] : i32
264 ! NSW: cf.cond_br %[[COND_I]], ^[[BODY_I:.*]], ^[[EXIT_I:.*]]
265 ! NSW: ^[[BODY_I]]:
266 ! NSW: %[[J_START:.*]] = arith.constant 1 : i32
267 ! NSW: %[[J_END:.*]] = arith.constant 200 : i32
268 ! NSW: %[[J_STEP:.*]] = arith.constant 1 : i32
269 ! NSW: %[[TMP3:.*]] = arith.subi %[[J_END]], %[[J_START]] : i32
270 ! NSW: %[[TMP4:.*]] = arith.addi %[[TMP3]], %[[J_STEP]] : i32
271 ! NSW: %[[TRIP_COUNT_J:.*]] = arith.divsi %[[TMP4]], %[[J_STEP]] : i32
272 ! NSW: fir.store %[[TRIP_COUNT_J]] to %[[TRIP_VAR_J_REF]] : !fir.ref<i32>
273 ! NSW: fir.store %[[J_START]] to %[[LOOP_VAR_J_REF]] : !fir.ref<i32>
274 ! NSW: cf.br ^[[HEADER_J:.*]]
275 ! NSW: ^[[HEADER_J]]:
276 ! NSW: %[[TRIP_VAR_J:.*]] = fir.load %[[TRIP_VAR_J_REF]] : !fir.ref<i32>
277 ! NSW: %[[ZERO_2:.*]] = arith.constant 0 : i32
278 ! NSW: %[[COND_J:.*]] = arith.cmpi sgt, %[[TRIP_VAR_J]], %[[ZERO_2]] : i32
279 ! NSW: cf.cond_br %[[COND_J]], ^[[BODY_J:.*]], ^[[EXIT_J:.*]]
280 ! NSW: ^[[BODY_J]]:
281 ! NSW: %[[K_START:.*]] = arith.constant 1 : i32
282 ! NSW: %[[K_END:.*]] = arith.constant 300 : i32
283 ! NSW: %[[K_STEP:.*]] = arith.constant 1 : i32
284 ! NSW: %[[TMP3:.*]] = arith.subi %[[K_END]], %[[K_START]] : i32
285 ! NSW: %[[TMP4:.*]] = arith.addi %[[TMP3]], %[[K_STEP]] : i32
286 ! NSW: %[[TRIP_COUNT_K:.*]] = arith.divsi %[[TMP4]], %[[K_STEP]] : i32
287 ! NSW: fir.store %[[TRIP_COUNT_K]] to %[[TRIP_VAR_K_REF]] : !fir.ref<i32>
288 ! NSW: fir.store %[[K_START]] to %[[LOOP_VAR_K_REF]] : !fir.ref<i32>
289 ! NSW: cf.br ^[[HEADER_K:.*]]
290 ! NSW: ^[[HEADER_K]]:
291 ! NSW: %[[TRIP_VAR_K:.*]] = fir.load %[[TRIP_VAR_K_REF]] : !fir.ref<i32>
292 ! NSW: %[[ZERO_2:.*]] = arith.constant 0 : i32
293 ! NSW: %[[COND_K:.*]] = arith.cmpi sgt, %[[TRIP_VAR_K]], %[[ZERO_2]] : i32
294 ! NSW: cf.cond_br %[[COND_K]], ^[[BODY_K:.*]], ^[[EXIT_K:.*]]
295 ! NSW: ^[[BODY_K]]:
296 ! NSW: %[[TRIP_VAR_K:.*]] = fir.load %[[TRIP_VAR_K_REF]] : !fir.ref<i32>
297 ! NSW: %[[ONE_1:.*]] = arith.constant 1 : i32
298 ! NSW: %[[TRIP_VAR_K_NEXT:.*]] = arith.subi %[[TRIP_VAR_K]], %[[ONE_1]] : i32
299 ! NSW: fir.store %[[TRIP_VAR_K_NEXT]] to %[[TRIP_VAR_K_REF]] : !fir.ref<i32>
300 ! NSW: %[[LOOP_VAR_K:.*]] = fir.load %[[LOOP_VAR_K_REF]] : !fir.ref<i32>
301 ! NSW: %[[K_STEP_2:.*]] = arith.constant 1 : i32
302 ! NSW: %[[LOOP_VAR_K_NEXT:.*]] = arith.addi %[[LOOP_VAR_K]], %[[K_STEP_2]] overflow<nsw> : i32
303 ! NSW: fir.store %[[LOOP_VAR_K_NEXT]] to %[[LOOP_VAR_K_REF]] : !fir.ref<i32>
304 ! NSW: cf.br ^[[HEADER_K]]
305 ! NSW: ^[[EXIT_K]]:
306 ! NSW: %[[TRIP_VAR_J:.*]] = fir.load %[[TRIP_VAR_J_REF]] : !fir.ref<i32>
307 ! NSW: %[[ONE_1:.*]] = arith.constant 1 : i32
308 ! NSW: %[[TRIP_VAR_J_NEXT:.*]] = arith.subi %[[TRIP_VAR_J]], %[[ONE_1]] : i32
309 ! NSW: fir.store %[[TRIP_VAR_J_NEXT]] to %[[TRIP_VAR_J_REF]] : !fir.ref<i32>
310 ! NSW: %[[LOOP_VAR_J:.*]] = fir.load %[[LOOP_VAR_J_REF]] : !fir.ref<i32>
311 ! NSW: %[[J_STEP_2:.*]] = arith.constant 1 : i32
312 ! NSW: %[[LOOP_VAR_J_NEXT:.*]] = arith.addi %[[LOOP_VAR_J]], %[[J_STEP_2]] overflow<nsw> : i32
313 ! NSW: fir.store %[[LOOP_VAR_J_NEXT]] to %[[LOOP_VAR_J_REF]] : !fir.ref<i32>
314 ! NSW: cf.br ^[[HEADER_J]]
315 ! NSW: ^[[EXIT_J]]:
316 ! NSW: %[[TRIP_VAR_I:.*]] = fir.load %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
317 ! NSW: %[[ONE_1:.*]] = arith.constant 1 : i32
318 ! NSW: %[[TRIP_VAR_I_NEXT:.*]] = arith.subi %[[TRIP_VAR_I]], %[[ONE_1]] : i32
319 ! NSW: fir.store %[[TRIP_VAR_I_NEXT]] to %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
320 ! NSW: %[[LOOP_VAR_I:.*]] = fir.load %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
321 ! NSW: %[[I_STEP_2:.*]] = arith.constant 1 : i32
322 ! NSW: %[[LOOP_VAR_I_NEXT:.*]] = arith.addi %[[LOOP_VAR_I]], %[[I_STEP_2]] overflow<nsw> : i32
323 ! NSW: fir.store %[[LOOP_VAR_I_NEXT]] to %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
324 ! NSW: cf.br ^[[HEADER_I]]
325 ! NSW: ^[[EXIT_I]]:
326 ! NSW: return
328 ! Test the existence of a structured loop inside an unstructured loop.
329 ! Only minimal checks are inserted for the structured loop.
330 subroutine nested_structured_in_unstructured()
331 integer :: i, j
332 do i=1,100
333 do j=1,100
334 end do
335 goto 404
336 404 continue
337 end do
338 end subroutine
339 ! CHECK-LABEL: nested_structured_in_unstructured
340 ! CHECK: %[[TRIP_VAR_I_REF:.*]] = fir.alloca i32
341 ! CHECK: %[[LOOP_VAR_I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFnested_structured_in_unstructuredEi"}
342 ! CHECK: %[[LOOP_VAR_J_REF:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFnested_structured_in_unstructuredEj"}
343 ! CHECK: %[[I_START:.*]] = arith.constant 1 : i32
344 ! CHECK: %[[I_END:.*]] = arith.constant 100 : i32
345 ! CHECK: %[[I_STEP:.*]] = arith.constant 1 : i32
346 ! CHECK: %[[TMP1:.*]] = arith.subi %[[I_END]], %[[I_START]] : i32
347 ! CHECK: %[[TMP2:.*]] = arith.addi %[[TMP1]], %[[I_STEP]] : i32
348 ! CHECK: %[[TRIP_COUNT:.*]] = arith.divsi %[[TMP2]], %[[I_STEP]] : i32
349 ! CHECK: fir.store %[[TRIP_COUNT]] to %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
350 ! CHECK: fir.store %[[I_START]] to %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
351 ! CHECK: cf.br ^[[HEADER:.*]]
352 ! CHECK: ^[[HEADER]]:
353 ! CHECK: %[[TRIP_VAR:.*]] = fir.load %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
354 ! CHECK: %[[ZERO:.*]] = arith.constant 0 : i32
355 ! CHECK: %[[COND:.*]] = arith.cmpi sgt, %[[TRIP_VAR]], %[[ZERO]] : i32
356 ! CHECK: cf.cond_br %[[COND]], ^[[BODY:.*]], ^[[EXIT:.*]]
357 ! CHECK: ^[[BODY]]:
358 ! CHECK: %{{.*}} = fir.do_loop %[[J_INDEX:[^ ]*]] =
359 ! CHECK-SAME: %{{.*}} to %{{.*}} step %[[ST:[^ ]*]]
360 ! CHECK-SAME: iter_args(%[[J_IV:.*]] = %{{.*}}) -> (index, i32) {
361 ! CHECK: fir.store %[[J_IV]] to %[[LOOP_VAR_J_REF]] : !fir.ref<i32>
362 ! CHECK: %[[J_INDEX_NEXT:.*]] = arith.addi %[[J_INDEX]], %[[ST]] : index
363 ! CHECK: %[[LOOP_VAR_J:.*]] = fir.load %[[LOOP_VAR_J_REF]] : !fir.ref<i32>
364 ! CHECK: %[[LOOP_VAR_J_NEXT:.*]] = arith.addi %[[LOOP_VAR_J]], %{{[^ ]*}} : i32
365 ! CHECK: }
366 ! CHECK: %[[TRIP_VAR_I:.*]] = fir.load %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
367 ! CHECK: %[[C1_3:.*]] = arith.constant 1 : i32
368 ! CHECK: %[[TRIP_VAR_I_NEXT:.*]] = arith.subi %[[TRIP_VAR_I]], %[[C1_3]] : i32
369 ! CHECK: fir.store %[[TRIP_VAR_I_NEXT]] to %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
370 ! CHECK: %[[LOOP_VAR_I:.*]] = fir.load %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
371 ! CHECK: %[[I_STEP_2:.*]] = arith.constant 1 : i32
372 ! CHECK: %[[LOOP_VAR_I_NEXT:.*]] = arith.addi %[[LOOP_VAR_I]], %[[I_STEP_2]] : i32
373 ! CHECK: fir.store %[[LOOP_VAR_I_NEXT]] to %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
374 ! CHECK: cf.br ^[[HEADER]]
375 ! CHECK: ^[[EXIT]]:
376 ! CHECK: return
378 ! NSW-LABEL: nested_structured_in_unstructured
379 ! NSW: %[[TRIP_VAR_I_REF:.*]] = fir.alloca i32
380 ! NSW: %[[LOOP_VAR_I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFnested_structured_in_unstructuredEi"}
381 ! NSW: %[[LOOP_VAR_J_REF:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFnested_structured_in_unstructuredEj"}
382 ! NSW: %[[I_START:.*]] = arith.constant 1 : i32
383 ! NSW: %[[I_END:.*]] = arith.constant 100 : i32
384 ! NSW: %[[I_STEP:.*]] = arith.constant 1 : i32
385 ! NSW: %[[TMP1:.*]] = arith.subi %[[I_END]], %[[I_START]] : i32
386 ! NSW: %[[TMP2:.*]] = arith.addi %[[TMP1]], %[[I_STEP]] : i32
387 ! NSW: %[[TRIP_COUNT:.*]] = arith.divsi %[[TMP2]], %[[I_STEP]] : i32
388 ! NSW: fir.store %[[TRIP_COUNT]] to %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
389 ! NSW: fir.store %[[I_START]] to %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
390 ! NSW: cf.br ^[[HEADER:.*]]
391 ! NSW: ^[[HEADER]]:
392 ! NSW: %[[TRIP_VAR:.*]] = fir.load %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
393 ! NSW: %[[ZERO:.*]] = arith.constant 0 : i32
394 ! NSW: %[[COND:.*]] = arith.cmpi sgt, %[[TRIP_VAR]], %[[ZERO]] : i32
395 ! NSW: cf.cond_br %[[COND]], ^[[BODY:.*]], ^[[EXIT:.*]]
396 ! NSW: ^[[BODY]]:
397 ! NSW: %{{.*}} = fir.do_loop %[[J_INDEX:[^ ]*]] =
398 ! NSW-SAME: %{{.*}} to %{{.*}} step %[[ST:[^ ]*]]
399 ! NSW-SAME: iter_args(%[[J_IV:.*]] = %{{.*}}) -> (index, i32) {
400 ! NSW: fir.store %[[J_IV]] to %[[LOOP_VAR_J_REF]] : !fir.ref<i32>
401 ! NSW: %[[J_INDEX_NEXT:.*]] = arith.addi %[[J_INDEX]], %[[ST]] overflow<nsw> : index
402 ! NSW: %[[LOOP_VAR_J:.*]] = fir.load %[[LOOP_VAR_J_REF]] : !fir.ref<i32>
403 ! NSW: %[[LOOP_VAR_J_NEXT:.*]] = arith.addi %[[LOOP_VAR_J]], %{{[^ ]*}} overflow<nsw> : i32
404 ! NSW: }
405 ! NSW: %[[TRIP_VAR_I:.*]] = fir.load %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
406 ! NSW: %[[C1_3:.*]] = arith.constant 1 : i32
407 ! NSW: %[[TRIP_VAR_I_NEXT:.*]] = arith.subi %[[TRIP_VAR_I]], %[[C1_3]] : i32
408 ! NSW: fir.store %[[TRIP_VAR_I_NEXT]] to %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
409 ! NSW: %[[LOOP_VAR_I:.*]] = fir.load %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
410 ! NSW: %[[I_STEP_2:.*]] = arith.constant 1 : i32
411 ! NSW: %[[LOOP_VAR_I_NEXT:.*]] = arith.addi %[[LOOP_VAR_I]], %[[I_STEP_2]] overflow<nsw> : i32
412 ! NSW: fir.store %[[LOOP_VAR_I_NEXT]] to %[[LOOP_VAR_I_REF]] : !fir.ref<i32>
413 ! NSW: cf.br ^[[HEADER]]
414 ! NSW: ^[[EXIT]]:
415 ! NSW: return