1! Test loop variables increment
2! RUN: bbc -emit-fir -o - %s | FileCheck %s
3
4module test_loop_var
5  implicit none
6  integer, pointer:: i_pointer
7  integer, allocatable :: i_allocatable
8  real, pointer :: x_pointer
9  real, allocatable :: x_allocatable
10contains
11! CHECK-LABEL: func @_QMtest_loop_varPtest_pointer
12  subroutine test_pointer()
13    do i_pointer=1,10
14    enddo
15! CHECK:         %[[VAL_0:.*]] = fir.address_of(@_QMtest_loop_varEi_pointer) : !fir.ref<!fir.box<!fir.ptr<i32>>>
16! CHECK:         %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
17! CHECK:         %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
18! CHECK:         fir.do_loop %[[VAL_9:.*]] =
19! CHECK:           %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (index) -> i32
20! CHECK:           fir.store %[[VAL_10]] to %[[VAL_2]] : !fir.ptr<i32>
21! CHECK:         }
22! CHECK:         %[[VAL_12:.*]] = fir.convert %[[VAL_13:.*]] : (index) -> i32
23! CHECK:         fir.store %[[VAL_12]] to %[[VAL_2]] : !fir.ptr<i32>
24  end subroutine
25
26! CHECK-LABEL: func @_QMtest_loop_varPtest_allocatable
27  subroutine test_allocatable()
28    do i_allocatable=1,10
29    enddo
30! CHECK:         %[[VAL_0:.*]] = fir.address_of(@_QMtest_loop_varEi_allocatable) : !fir.ref<!fir.box<!fir.heap<i32>>>
31! CHECK:         %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
32! CHECK:         %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
33! CHECK:         fir.do_loop %[[VAL_9:.*]] =
34! CHECK:           %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (index) -> i32
35! CHECK:           fir.store %[[VAL_10]] to %[[VAL_2]] : !fir.heap<i32>
36! CHECK:         }
37! CHECK:         %[[VAL_12:.*]] = fir.convert %[[VAL_13:.*]] : (index) -> i32
38! CHECK:         fir.store %[[VAL_12]] to %[[VAL_2]] : !fir.heap<i32>
39  end subroutine
40
41! CHECK-LABEL: func @_QMtest_loop_varPtest_real_pointer
42  subroutine test_real_pointer()
43    do x_pointer=1,10
44    enddo
45! CHECK:         %[[VAL_0:.*]] = fir.alloca index
46! CHECK:         %[[VAL_1:.*]] = fir.address_of(@_QMtest_loop_varEx_pointer) : !fir.ref<!fir.box<!fir.ptr<f32>>>
47! CHECK:         %[[VAL_2:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<f32>>>
48! CHECK:         %[[VAL_3:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32>
49! CHECK:         %[[VAL_4:.*]] = arith.constant 1 : i32
50! CHECK:         %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i32) -> f32
51! CHECK:         %[[VAL_8:.*]] = arith.constant 1.000000e+00 : f32
52
53! CHECK:         fir.store %[[VAL_5]] to %[[VAL_3]] : !fir.ptr<f32>
54! CHECK:         br ^bb1
55! CHECK:       ^bb1:
56! CHECK:         cond_br %{{.*}}, ^bb2, ^bb3
57! CHECK:       ^bb2:
58! CHECK:         %[[VAL_19:.*]] = fir.load %[[VAL_3]] : !fir.ptr<f32>
59! CHECK:         %[[VAL_20:.*]] = arith.addf %[[VAL_19]], %[[VAL_8]] : f32
60! CHECK:         fir.store %[[VAL_20]] to %[[VAL_3]] : !fir.ptr<f32>
61! CHECK:         br ^bb1
62! CHECK:       ^bb3:
63! CHECK:         return
64  end subroutine
65
66! CHECK-LABEL: func @_QMtest_loop_varPtest_real_allocatable
67  subroutine test_real_allocatable()
68    do x_allocatable=1,10
69    enddo
70! CHECK:         %[[VAL_0:.*]] = fir.alloca index
71! CHECK:         %[[VAL_1:.*]] = fir.address_of(@_QMtest_loop_varEx_allocatable) : !fir.ref<!fir.box<!fir.heap<f32>>>
72! CHECK:         %[[VAL_2:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<f32>>>
73! CHECK:         %[[VAL_3:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32>
74! CHECK:         %[[VAL_4:.*]] = arith.constant 1 : i32
75! CHECK:         %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i32) -> f32
76! CHECK:         %[[VAL_8:.*]] = arith.constant 1.000000e+00 : f32
77
78! CHECK:         fir.store %[[VAL_5]] to %[[VAL_3]] : !fir.heap<f32>
79! CHECK:         br ^bb1
80! CHECK:       ^bb1:
81! CHECK:         cond_br %{{.*}}, ^bb2, ^bb3
82! CHECK:       ^bb2:
83! CHECK:         %[[VAL_19:.*]] = fir.load %[[VAL_3]] : !fir.heap<f32>
84! CHECK:         %[[VAL_20:.*]] = arith.addf %[[VAL_19]], %[[VAL_8]] : f32
85! CHECK:         fir.store %[[VAL_20]] to %[[VAL_3]] : !fir.heap<f32>
86! CHECK:         br ^bb1
87! CHECK:       ^bb3:
88! CHECK:         return
89  end subroutine
90
91  ! CHECK-LABEL: func @_QMtest_loop_varPtest_pointer_unstructured_loop()
92  subroutine test_pointer_unstructured_loop()
93    do i_pointer=1,10
94      if (i_pointer .gt. 5) exit
95    enddo
96! CHECK:         %[[VAL_1:.*]] = fir.address_of(@_QMtest_loop_varEi_pointer) : !fir.ref<!fir.box<!fir.ptr<i32>>>
97! CHECK:         %[[VAL_2:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
98! CHECK:         %[[VAL_3:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
99! CHECK:         %[[VAL_4:.*]] = arith.constant 1 : i32
100! CHECK:         %[[VAL_6:.*]] = arith.constant 1 : i32
101! CHECK:         fir.store %[[VAL_4]] to %[[VAL_3]] : !fir.ptr<i32>
102! CHECK:         br ^bb1
103! CHECK:       ^bb1:
104! CHECK:         cond_br %{{.*}}, ^bb2, ^bb5
105! CHECK:       ^bb2:
106! CHECK:         cond_br %{{.*}}, ^bb3, ^bb4
107! CHECK:       ^bb3:
108! CHECK:         br ^bb5
109! CHECK:       ^bb4:
110! CHECK:         %[[VAL_21:.*]] = fir.load %[[VAL_3]] : !fir.ptr<i32>
111! CHECK:         %[[VAL_22:.*]] = arith.addi %[[VAL_21]], %[[VAL_6]] : i32
112! CHECK:         fir.store %[[VAL_22]] to %[[VAL_3]] : !fir.ptr<i32>
113! CHECK:         br ^bb1
114! CHECK:       ^bb5:
115! CHECK:         return
116! CHECK:       }
117  end subroutine
118
119end module
120
121  use test_loop_var
122  implicit none
123  integer, target :: i_target = -1
124  real, target :: x_target = -1.
125  i_pointer => i_target
126  allocate(i_allocatable)
127  i_allocatable = -1
128  x_pointer => x_target
129  allocate(x_allocatable)
130  x_allocatable = -1.
131
132  call test_pointer()
133  call test_allocatable()
134  call test_real_pointer()
135  call test_real_allocatable()
136  ! Expect 11 everywhere
137  print *, i_target
138  print *, i_allocatable
139  print *, x_target
140  print *, x_allocatable
141
142  call test_pointer_unstructured_loop()
143  call test_allocatable_unstructured_loop()
144  ! Expect 6 everywhere
145  print *, i_target
146end
147