xref: /llvm-project/flang/test/Lower/do_loop.f90 (revision a88677edc0792534ba3157bf7d7a1b98e470f2fb)
1! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false -o - %s | FileCheck %s
2! RUN: %flang_fc1 -mllvm --use-desc-for-alloc=false -emit-fir -flang-deprecated-no-hlfir -o - %s | FileCheck %s
3! RUN: %flang_fc1 -mllvm --use-desc-for-alloc=false -emit-fir -flang-deprecated-no-hlfir -fwrapv -o - %s | FileCheck %s --check-prefix=NO-NSW
4
5! Simple tests for structured ordered loops with loop-control.
6! Tests the structure of the loop, storage to index variable and return and
7! storage of the final value of the index variable.
8
9! NO-NSW-NOT: overflow<nsw>
10
11! Test a simple loop with the final value of the index variable read outside the loop
12! CHECK-LABEL: simple_loop
13subroutine simple_loop
14  ! CHECK: %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimple_loopEi"}
15  integer :: i
16
17  ! CHECK: %[[C1:.*]] = arith.constant 1 : i32
18  ! CHECK: %[[C1_CVT:.*]] = fir.convert %c1_i32 : (i32) -> index
19  ! CHECK: %[[C5:.*]] = arith.constant 5 : i32
20  ! CHECK: %[[C5_CVT:.*]] = fir.convert %c5_i32 : (i32) -> index
21  ! CHECK: %[[C1:.*]] = arith.constant 1 : index
22  ! CHECK: %[[LB:.*]] = fir.convert %[[C1_CVT]] : (index) -> i32
23  ! CHECK: %[[LI_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] =
24  ! CHECK-SAME: %[[C1_CVT]] to %[[C5_CVT]] step %[[C1]]
25  ! CHECK-SAME: iter_args(%[[IV:.*]] = %[[LB]]) -> (index, i32) {
26  do i=1,5
27  ! CHECK:   fir.store %[[IV]] to %[[I_REF]] : !fir.ref<i32>
28  ! CHECK:   %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[C1]] overflow<nsw> : index
29  ! CHECK:   %[[STEPCAST:.*]] = fir.convert %[[C1]] : (index) -> i32
30  ! CHECK:   %[[IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref<i32>
31  ! CHECK:   %[[IVINC:.*]] = arith.addi %[[IVLOAD]], %[[STEPCAST]] overflow<nsw> : i32
32  ! CHECK:  fir.result %[[LI_NEXT]], %[[IVINC]] : index, i32
33  ! CHECK: }
34  end do
35  ! CHECK: fir.store %[[LI_RES]]#1 to %[[I_REF]] : !fir.ref<i32>
36  ! CHECK: %[[I:.*]] = fir.load %[[I_REF]] : !fir.ref<i32>
37  ! CHECK: %{{.*}} = fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[I]]) {{.*}}: (!fir.ref<i8>, i32) -> i1
38  print *, i
39end subroutine
40
41! Test a 2-nested loop with a body composed of a reduction. Values are read from a 2d array.
42! CHECK-LABEL: nested_loop
43subroutine nested_loop
44  ! CHECK: %[[ARR_REF:.*]] = fir.alloca !fir.array<5x5xi32> {bindc_name = "arr", uniq_name = "_QFnested_loopEarr"}
45  ! CHECK: %[[ASUM_REF:.*]] = fir.alloca i32 {bindc_name = "asum", uniq_name = "_QFnested_loopEasum"}
46  ! CHECK: %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFnested_loopEi"}
47  ! CHECK: %[[J_REF:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFnested_loopEj"}
48  integer :: asum, arr(5,5)
49  integer :: i, j
50  asum = 0
51  ! CHECK: %[[S_I:.*]] = arith.constant 1 : i32
52  ! CHECK: %[[S_I_CVT:.*]] = fir.convert %[[S_I]] : (i32) -> index
53  ! CHECK: %[[E_I:.*]] = arith.constant 5 : i32
54  ! CHECK: %[[E_I_CVT:.*]] = fir.convert %[[E_I]] : (i32) -> index
55  ! CHECK: %[[ST_I:.*]] = arith.constant 1 : index
56  ! CHECK: %[[I_LB:.*]] = fir.convert %[[S_I_CVT]] : (index) -> i32
57  ! CHECK: %[[I_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] =
58  ! CHECK-SAME: %[[S_I_CVT]] to %[[E_I_CVT]] step %[[ST_I]]
59  ! CHECK-SAME: iter_args(%[[I_IV:.*]] = %[[I_LB]]) -> (index, i32) {
60  do i=1,5
61    ! CHECK: fir.store %[[I_IV]] to %[[I_REF]] : !fir.ref<i32>
62    ! CHECK: %[[S_J:.*]] = arith.constant 1 : i32
63    ! CHECK: %[[S_J_CVT:.*]] = fir.convert %[[S_J]] : (i32) -> index
64    ! CHECK: %[[E_J:.*]] = arith.constant 5 : i32
65    ! CHECK: %[[E_J_CVT:.*]] = fir.convert %[[E_J]] : (i32) -> index
66    ! CHECK: %[[ST_J:.*]] = arith.constant 1 : index
67    ! CHECK: %[[J_LB:.*]] = fir.convert %[[S_J_CVT]] : (index) -> i32
68    ! CHECK: %[[J_RES:.*]]:2 = fir.do_loop %[[LJ:[^ ]*]] =
69    ! CHECK-SAME: %[[S_J_CVT]] to %[[E_J_CVT]] step %[[ST_J]]
70    ! CHECK-SAME: iter_args(%[[J_IV:.*]] = %[[J_LB]]) -> (index, i32) {
71    do j=1,5
72      ! CHECK: fir.store %[[J_IV]] to %[[J_REF]] : !fir.ref<i32>
73      ! CHECK: %[[ASUM:.*]] = fir.load %[[ASUM_REF]] : !fir.ref<i32>
74      ! CHECK: %[[I:.*]] = fir.load %[[I_REF]] : !fir.ref<i32>
75      ! CHECK: %[[I_CVT:.*]] = fir.convert %[[I]] : (i32) -> i64
76      ! CHECK: %[[C1_I:.*]] = arith.constant 1 : i64
77      ! CHECK: %[[I_INDX:.*]] = arith.subi %[[I_CVT]], %[[C1_I]] : i64
78      ! CHECK: %[[J:.*]] = fir.load %[[J_REF]] : !fir.ref<i32>
79      ! CHECK: %[[J_CVT:.*]] = fir.convert %[[J]] : (i32) -> i64
80      ! CHECK: %[[C1_J:.*]] = arith.constant 1 : i64
81      ! CHECK: %[[J_INDX:.*]] = arith.subi %[[J_CVT]], %[[C1_J]] : i64
82      ! CHECK: %[[ARR_IJ_REF:.*]] = fir.coordinate_of %[[ARR_REF]], %[[I_INDX]], %[[J_INDX]] : (!fir.ref<!fir.array<5x5xi32>>, i64, i64) -> !fir.ref<i32>
83      ! CHECK: %[[ARR_VAL:.*]] = fir.load %[[ARR_IJ_REF]] : !fir.ref<i32>
84      ! CHECK: %[[ASUM_NEW:.*]] = arith.addi %[[ASUM]], %[[ARR_VAL]] : i32
85      ! CHECK: fir.store %[[ASUM_NEW]] to %[[ASUM_REF]] : !fir.ref<i32>
86      asum = asum + arr(i,j)
87      ! CHECK: %[[LJ_NEXT:.*]] = arith.addi %[[LJ]], %[[ST_J]] overflow<nsw> : index
88      ! CHECK: %[[J_STEPCAST:.*]] = fir.convert %[[ST_J]] : (index) -> i32
89      ! CHECK: %[[J_IVLOAD:.*]] = fir.load %[[J_REF]] : !fir.ref<i32>
90      ! CHECK: %[[J_IVINC:.*]] = arith.addi %[[J_IVLOAD]], %[[J_STEPCAST]] overflow<nsw> : i32
91      ! CHECK: fir.result %[[LJ_NEXT]], %[[J_IVINC]] : index, i32
92    ! CHECK: }
93    end do
94    ! CHECK: fir.store %[[J_RES]]#1 to %[[J_REF]] : !fir.ref<i32>
95    ! CHECK: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_I]] overflow<nsw> : index
96    ! CHECK: %[[I_STEPCAST:.*]] = fir.convert %[[ST_I]] : (index) -> i32
97    ! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref<i32>
98    ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow<nsw> : i32
99    ! CHECK: fir.result %[[LI_NEXT]], %[[I_IVINC]] : index, i32
100  ! CHECK: }
101  end do
102  ! CHECK: fir.store %[[I_RES]]#1 to %[[I_REF]] : !fir.ref<i32>
103end subroutine
104
105! Test a downcounting loop
106! CHECK-LABEL: down_counting_loop
107subroutine down_counting_loop()
108  integer :: i
109  ! CHECK: %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFdown_counting_loopEi"}
110
111  ! CHECK: %[[C5:.*]] = arith.constant 5 : i32
112  ! CHECK: %[[C5_CVT:.*]] = fir.convert %[[C5]] : (i32) -> index
113  ! CHECK: %[[C1:.*]] = arith.constant 1 : i32
114  ! CHECK: %[[C1_CVT:.*]] = fir.convert %[[C1]] : (i32) -> index
115  ! CHECK: %[[CMINUS1:.*]] = arith.constant -1 : i32
116  ! CHECK: %[[CMINUS1_STEP_CVT:.*]] = fir.convert %[[CMINUS1]] : (i32) -> index
117  ! CHECK: %[[I_LB:.*]] = fir.convert %[[C5_CVT]] : (index) -> i32
118  ! CHECK: %[[I_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] =
119  ! CHECK-SAME: %[[C5_CVT]] to %[[C1_CVT]] step %[[CMINUS1_STEP_CVT]]
120  ! CHECK-SAME: iter_args(%[[I_IV:.*]] = %[[I_LB]]) -> (index, i32) {
121  do i=5,1,-1
122  ! CHECK: fir.store %[[I_IV]] to %[[I_REF]] : !fir.ref<i32>
123  ! CHECK: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[CMINUS1_STEP_CVT]] overflow<nsw> : index
124  ! CHECK: %[[I_STEPCAST:.*]] = fir.convert %[[CMINUS1_STEP_CVT]] : (index) -> i32
125  ! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref<i32>
126  ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow<nsw> : i32
127  ! CHECK: fir.result %[[LI_NEXT]], %[[I_IVINC]] : index, i32
128  ! CHECK: }
129  end do
130  ! CHECK: fir.store %[[I_RES]]#1 to %[[I_REF]] : !fir.ref<i32>
131end subroutine
132
133! Test a general loop with a variable step
134! CHECK-LABEL: loop_with_variable_step
135! CHECK-SAME: (%[[S_REF:.*]]: !fir.ref<i32> {fir.bindc_name = "s"}, %[[E_REF:.*]]: !fir.ref<i32> {fir.bindc_name = "e"}, %[[ST_REF:.*]]: !fir.ref<i32> {fir.bindc_name = "st"}) {
136subroutine loop_with_variable_step(s,e,st)
137  integer :: s, e, st
138  ! CHECK: %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFloop_with_variable_stepEi"}
139  ! CHECK: %[[S:.*]] = fir.load %[[S_REF]] : !fir.ref<i32>
140  ! CHECK: %[[S_CVT:.*]] = fir.convert %[[S]] : (i32) -> index
141  ! CHECK: %[[E:.*]] = fir.load %[[E_REF]] : !fir.ref<i32>
142  ! CHECK: %[[E_CVT:.*]] = fir.convert %[[E]] : (i32) -> index
143  ! CHECK: %[[ST:.*]] = fir.load %[[ST_REF]] : !fir.ref<i32>
144  ! CHECK: %[[ST_CVT:.*]] = fir.convert %[[ST]] : (i32) -> index
145  ! CHECK: %[[I_LB:.*]] = fir.convert %[[S_CVT]] : (index) -> i32
146  ! CHECK: %[[I_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] =
147  ! CHECK-SAME: %[[S_CVT]] to %[[E_CVT]] step %[[ST_CVT]]
148  ! CHECK-SAME: iter_args(%[[I_IV:.*]] = %[[I_LB]]) -> (index, i32) {
149  do i=s,e,st
150  ! CHECK:  fir.store %[[I_IV]] to %[[I_REF]] : !fir.ref<i32>
151  ! CHECK:  %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_CVT]] overflow<nsw> : index
152  ! CHECK: %[[I_STEPCAST:.*]] = fir.convert %[[ST_CVT]] : (index) -> i32
153  ! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref<i32>
154  ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow<nsw> : i32
155  ! CHECK:  fir.result %[[LI_NEXT]], %[[I_IVINC]] : index, i32
156  ! CHECK: }
157  end do
158  ! CHECK: fir.store %[[I_RES]]#1 to %[[I_REF]] : !fir.ref<i32>
159end subroutine
160
161! Test usage of pointer variables as index, start, end and step variables
162! CHECK-LABEL: loop_with_pointer_variables
163! CHECK-SAME: (%[[S_REF:.*]]: !fir.ref<i32> {fir.bindc_name = "s", fir.target}, %[[E_REF:.*]]: !fir.ref<i32> {fir.bindc_name = "e", fir.target}, %[[ST_REF:.*]]: !fir.ref<i32> {fir.bindc_name = "st", fir.target}) {
164subroutine loop_with_pointer_variables(s,e,st)
165! CHECK:  %[[E_PTR_REF:.*]] = fir.alloca !fir.ptr<i32> {uniq_name = "_QFloop_with_pointer_variablesEeptr.addr"}
166! CHECK:  %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", fir.target, uniq_name = "_QFloop_with_pointer_variablesEi"}
167! CHECK:  %[[I_PTR_REF:.*]] = fir.alloca !fir.ptr<i32> {uniq_name = "_QFloop_with_pointer_variablesEiptr.addr"}
168! CHECK:  %[[S_PTR_REF:.*]] = fir.alloca !fir.ptr<i32> {uniq_name = "_QFloop_with_pointer_variablesEsptr.addr"}
169! CHECK:  %[[ST_PTR_REF:.*]] = fir.alloca !fir.ptr<i32> {uniq_name = "_QFloop_with_pointer_variablesEstptr.addr"}
170  integer, target :: i
171  integer, target :: s, e, st
172  integer, pointer :: iptr, sptr, eptr, stptr
173
174! CHECK:  %[[I_PTR:.*]] = fir.convert %[[I_REF]] : (!fir.ref<i32>) -> !fir.ptr<i32>
175! CHECK:  fir.store %[[I_PTR]] to %[[I_PTR_REF]] : !fir.ref<!fir.ptr<i32>>
176! CHECK:  %[[S_PTR:.*]] = fir.convert %[[S_REF]] : (!fir.ref<i32>) -> !fir.ptr<i32>
177! CHECK:  fir.store %[[S_PTR]] to %[[S_PTR_REF]] : !fir.ref<!fir.ptr<i32>>
178! CHECK:  %[[E_PTR:.*]] = fir.convert %[[E_REF]] : (!fir.ref<i32>) -> !fir.ptr<i32>
179! CHECK:  fir.store %[[E_PTR]] to %[[E_PTR_REF]] : !fir.ref<!fir.ptr<i32>>
180! CHECK:  %[[ST_PTR:.*]] = fir.convert %[[ST_REF]] : (!fir.ref<i32>) -> !fir.ptr<i32>
181! CHECK:  fir.store %[[ST_PTR]] to %[[ST_PTR_REF]] : !fir.ref<!fir.ptr<i32>>
182  iptr => i
183  sptr => s
184  eptr => e
185  stptr => st
186
187! CHECK:  %[[I_PTR:.*]] = fir.load %[[I_PTR_REF]] : !fir.ref<!fir.ptr<i32>>
188! CHECK:  %[[S_PTR:.*]] = fir.load %[[S_PTR_REF]] : !fir.ref<!fir.ptr<i32>>
189! CHECK:  %[[S:.*]] = fir.load %[[S_PTR]] : !fir.ptr<i32>
190! CHECK:  %[[S_CVT:.*]] = fir.convert %[[S]] : (i32) -> index
191! CHECK:  %[[E_PTR:.*]] = fir.load %[[E_PTR_REF]] : !fir.ref<!fir.ptr<i32>>
192! CHECK:  %[[E:.*]] = fir.load %[[E_PTR]] : !fir.ptr<i32>
193! CHECK:  %[[E_CVT:.*]] = fir.convert %[[E]] : (i32) -> index
194! CHECK:  %[[ST_PTR:.*]] = fir.load %[[ST_PTR_REF]] : !fir.ref<!fir.ptr<i32>>
195! CHECK:  %[[ST:.*]] = fir.load %[[ST_PTR]] : !fir.ptr<i32>
196! CHECK:  %[[ST_CVT:.*]] = fir.convert %[[ST]] : (i32) -> index
197! CHECK:  %[[I_LB:.*]] = fir.convert %[[S_CVT]] : (index) -> i32
198! CHECK:  %[[I_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] =
199! CHECK-SAME: %[[S_CVT]] to %[[E_CVT]] step %[[ST_CVT]]
200! CHECK-SAME: iter_args(%[[I_IV:.*]] = %[[I_LB]]) -> (index, i32) {
201  do iptr=sptr,eptr,stptr
202! CHECK:    fir.store %[[I_IV]] to %[[I_PTR]] : !fir.ptr<i32>
203! CHECK:    %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_CVT]] overflow<nsw> : index
204! CHECK:    %[[I_STEPCAST:.*]] = fir.convert %[[ST_CVT]] : (index) -> i32
205! CHECK:    %[[I_IVLOAD:.*]] = fir.load %[[I_PTR]] : !fir.ptr<i32>
206! CHECK:    %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow<nsw> : i32
207! CHECK:    fir.result %[[LI_NEXT]], %[[I_IVINC]] : index, i32
208  end do
209! CHECK:  }
210! CHECK:  fir.store %[[I_RES]]#1 to %[[I_PTR]] : !fir.ptr<i32>
211end subroutine
212
213! Test usage of non-default integer kind for loop control and loop index variable
214! CHECK-LABEL: loop_with_non_default_integer
215! CHECK-SAME: (%[[S_REF:.*]]: !fir.ref<i64> {fir.bindc_name = "s"}, %[[E_REF:.*]]: !fir.ref<i64> {fir.bindc_name = "e"}, %[[ST_REF:.*]]: !fir.ref<i64> {fir.bindc_name = "st"}) {
216subroutine loop_with_non_default_integer(s,e,st)
217  ! CHECK: %[[I_REF:.*]] = fir.alloca i64 {bindc_name = "i", uniq_name = "_QFloop_with_non_default_integerEi"}
218  integer(kind=8):: i
219  ! CHECK: %[[S:.*]] = fir.load %[[S_REF]] : !fir.ref<i64>
220  ! CHECK: %[[S_CVT:.*]] = fir.convert %[[S]] : (i64) -> index
221  ! CHECK: %[[E:.*]] = fir.load %[[E_REF]] : !fir.ref<i64>
222  ! CHECK: %[[E_CVT:.*]] = fir.convert %[[E]] : (i64) -> index
223  ! CHECK: %[[ST:.*]] = fir.load %[[ST_REF]] : !fir.ref<i64>
224  ! CHECK: %[[ST_CVT:.*]] = fir.convert %[[ST]] : (i64) -> index
225  integer(kind=8) :: s, e, st
226
227  ! CHECK: %[[I_LB:.*]] = fir.convert %[[S_CVT]] : (index) -> i64
228  ! CHECK: %[[I_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] =
229  ! CHECK-SAME: %[[S_CVT]] to %[[E_CVT]] step %[[ST_CVT]]
230  ! CHECK-SAME: iter_args(%[[I_IV:.*]] = %[[I_LB]]) -> (index, i64) {
231  do i=s,e,st
232    ! CHECK: fir.store %[[I_IV]] to %[[I_REF]] : !fir.ref<i64>
233    ! CHECK: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_CVT]] overflow<nsw> : index
234    ! CHECK: %[[I_STEPCAST:.*]] = fir.convert %[[ST_CVT]] : (index) -> i64
235    ! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref<i64>
236    ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow<nsw> : i64
237    ! CHECK: fir.result %[[LI_NEXT]], %[[I_IVINC]] : index, i64
238  end do
239  ! CHECK: }
240  ! CHECK: fir.store %[[I_RES]]#1 to %[[I_REF]] : !fir.ref<i64>
241end subroutine
242
243! Test real loop control.
244! CHECK-LABEL: loop_with_real_control
245! CHECK-SAME: (%[[S_REF:.*]]: !fir.ref<f32> {fir.bindc_name = "s"}, %[[E_REF:.*]]: !fir.ref<f32> {fir.bindc_name = "e"}, %[[ST_REF:.*]]: !fir.ref<f32> {fir.bindc_name = "st"}) {
246subroutine loop_with_real_control(s,e,st)
247  ! CHECK-DAG: %[[INDEX_REF:.*]] = fir.alloca index
248  ! CHECK-DAG: %[[X_REF:.*]] = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFloop_with_real_controlEx"}
249  ! CHECK-DAG: %[[S:.*]] = fir.load %[[S_REF]] : !fir.ref<f32>
250  ! CHECK-DAG: %[[E:.*]] = fir.load %[[E_REF]] : !fir.ref<f32>
251  ! CHECK-DAG: %[[ST:.*]] = fir.load %[[ST_REF]] : !fir.ref<f32>
252  ! CHECK: fir.store %[[ST]] to %[[ST_VAR:.*]] : !fir.ref<f32>
253  real :: x, s, e, st
254
255  ! CHECK: %[[DIFF:.*]] = arith.subf %[[E]], %[[S]] {{.*}}: f32
256  ! CHECK: %[[RANGE:.*]] = arith.addf %[[DIFF]], %[[ST]] {{.*}}: f32
257  ! CHECK: %[[HIGH:.*]] = arith.divf %[[RANGE]], %[[ST]] {{.*}}: f32
258  ! CHECK: %[[HIGH_INDEX:.*]] = fir.convert %[[HIGH]] : (f32) -> index
259  ! CHECK: fir.store %[[HIGH_INDEX]] to %[[INDEX_REF]] : !fir.ref<index>
260  ! CHECK: fir.store %[[S]] to %[[X_REF]] : !fir.ref<f32>
261
262  ! CHECK: br ^[[HDR:.*]]
263  ! CHECK: ^[[HDR]]:  // 2 preds: ^{{.*}}, ^[[EXIT:.*]]
264  ! CHECK-DAG: %[[INDEX:.*]] = fir.load %[[INDEX_REF]] : !fir.ref<index>
265  ! CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index
266  ! CHECK: %[[COND:.*]] = arith.cmpi sgt, %[[INDEX]], %[[C0]] : index
267  ! CHECK: cond_br %[[COND]], ^[[BODY:.*]], ^[[EXIT:.*]]
268  do x=s,e,st
269    ! CHECK: ^[[BODY]]:  // pred: ^[[HDR]]
270    ! CHECK-DAG: %[[INDEX2:.*]] = fir.load %[[INDEX_REF]] : !fir.ref<index>
271    ! CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index
272    ! CHECK: %[[INC:.*]] = arith.subi %[[INDEX2]], %[[C1]] : index
273    ! CHECK: fir.store %[[INC]] to %[[INDEX_REF]] : !fir.ref<index>
274    ! CHECK: %[[X2:.*]] = fir.load %[[X_REF]] : !fir.ref<f32>
275    ! CHECK: %[[ST_VAL:.*]] = fir.load %[[ST_VAR]] : !fir.ref<f32>
276    ! CHECK: %[[XINC:.*]] = arith.addf %[[X2]], %[[ST_VAL]] {{.*}}: f32
277    ! CHECK: fir.store %[[XINC]] to %[[X_REF]] : !fir.ref<f32>
278    ! CHECK: br ^[[HDR]]
279  end do
280end subroutine
281