1! RUN: bbc -emit-fir -o - %s | FileCheck %s
2! RUN: %flang_fc1 -emit-fir -o - %s | FileCheck %s
3
4! Tests for infinite loop.
5
6subroutine empty_infinite()
7  do
8  end do
9end subroutine
10! CHECK-LABEL: empty_infinite
11! CHECK:  cf.br ^[[BODY:.*]]
12! CHECK: ^[[BODY]]:
13! CHECK:  cf.br ^[[BODY]]
14
15subroutine simple_infinite(i)
16  integer :: i
17  do
18    if (i .gt. 100) exit
19  end do
20end subroutine
21! CHECK-LABEL: simple_infinite
22! CHECK-SAME: %[[I_REF:.*]]: !fir.ref<i32>
23! CHECK:  cf.br ^[[BODY1:.*]]
24! CHECK: ^[[BODY1]]:
25! CHECK:  %[[I:.*]] = fir.load %[[I_REF]] : !fir.ref<i32>
26! CHECK:  %[[C100:.*]] = arith.constant 100 : i32
27! CHECK:  %[[COND:.*]] = arith.cmpi sgt, %[[I]], %[[C100]] : i32
28! CHECK:  cf.cond_br %[[COND]], ^[[EXIT:.*]], ^[[BODY1:.*]]
29! CHECK: ^[[EXIT]]:
30! CHECK:  cf.br ^[[RETURN:.*]]
31! CHECK: ^[[RETURN]]:
32! CHECK:   return
33! CHECK: }
34
35subroutine infinite_with_two_body_blocks(i)
36  integer :: i
37  do
38    i = i + 1
39    if (i .gt. 100) exit
40    i = i * 2
41  end do
42end subroutine
43! CHECK-LABEL: infinite_with_two_body_blocks
44! CHECK-SAME: %[[I_REF:.*]]: !fir.ref<i32>
45! CHECK:  cf.br ^[[BODY1:.*]]
46! CHECK: ^[[BODY1]]:
47! CHECK:  %[[I:.*]] = fir.load %[[I_REF]] : !fir.ref<i32>
48! CHECK:  %[[C1:.*]] = arith.constant 1 : i32
49! CHECK:  %[[I_NEXT:.*]] = arith.addi %[[I]], %[[C1]] : i32
50! CHECK:  fir.store %[[I_NEXT]] to %[[I_REF]] : !fir.ref<i32>
51! CHECK:  %[[I:.*]] = fir.load %[[I_REF]] : !fir.ref<i32>
52! CHECK:  %[[C100:.*]] = arith.constant 100 : i32
53! CHECK:  %[[COND:.*]] = arith.cmpi sgt, %[[I]], %[[C100]] : i32
54! CHECK:  cf.cond_br %[[COND]], ^[[EXIT:.*]], ^[[BODY2:.*]]
55! CHECK: ^[[EXIT]]:
56! CHECK:  cf.br ^[[RETURN:.*]]
57! CHECK: ^[[BODY2]]:
58! CHECK:  %[[C2:.*]] = arith.constant 2 : i32
59! CHECK:  %[[I:.*]] = fir.load %[[I_REF]] : !fir.ref<i32>
60! CHECK:  %[[I_NEXT:.*]] = arith.muli %[[C2]], %[[I]] : i32
61! CHECK:  fir.store %[[I_NEXT]] to %[[I_REF]] : !fir.ref<i32>
62! CHECK:  cf.br ^[[BODY1]]
63! CHECK: ^[[RETURN]]:
64! CHECK:   return
65! CHECK: }
66
67subroutine structured_loop_in_infinite(i)
68  integer :: i
69  integer :: j
70  do
71    if (i .gt. 100) exit
72    do j=1,10
73    end do
74  end do
75end subroutine
76! CHECK-LABEL: structured_loop_in_infinite
77! CHECK-SAME: %[[I_REF:.*]]: !fir.ref<i32>
78! CHECK:  %[[J_REF:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFstructured_loop_in_infiniteEj"}
79! CHECK:  cf.br ^[[BODY1:.*]]
80! CHECK: ^[[BODY1]]:
81! CHECK:  %[[I:.*]] = fir.load %[[I_REF]] : !fir.ref<i32>
82! CHECK:  %[[C100:.*]] = arith.constant 100 : i32
83! CHECK:  %[[COND:.*]] = arith.cmpi sgt, %[[I]], %[[C100]] : i32
84! CHECK:  cf.cond_br %[[COND]], ^[[EXIT:.*]], ^[[BODY2:.*]]
85! CHECK: ^[[EXIT]]:
86! CHECK:  cf.br ^[[RETURN:.*]]
87! CHECK: ^[[BODY2:.*]]:
88! CHECK:  %[[C1:.*]] = arith.constant 1 : i32
89! CHECK:  %[[C1_INDEX:.*]] = fir.convert %[[C1]] : (i32) -> index
90! CHECK:  %[[C10:.*]] = arith.constant 10 : i32
91! CHECK:  %[[C10_INDEX:.*]] = fir.convert %[[C10]] : (i32) -> index
92! CHECK:  %[[C1_1:.*]] = arith.constant 1 : index
93! CHECK:  %[[J_FINAL:.*]] = fir.do_loop %[[J:.*]] = %[[C1_INDEX]] to %[[C10_INDEX]] step %[[C1_1]] -> index {
94! CHECK:    %[[J_I32:.*]] = fir.convert %[[J]] : (index) -> i32
95! CHECK:    fir.store %[[J_I32]] to %[[J_REF]] : !fir.ref<i32>
96! CHECK:    %[[J_NEXT:.*]] = arith.addi %[[J]], %[[C1_1]] : index
97! CHECK:    fir.result %[[J_NEXT]] : index
98! CHECK:  }
99! CHECK:  %[[J_I32:.*]] = fir.convert %[[J_FINAL]] : (index) -> i32
100! CHECK:  fir.store %[[J_I32]] to %[[J_REF]] : !fir.ref<i32>
101! CHECK:  cf.br ^[[BODY1]]
102! CHECK: ^[[RETURN]]:
103! CHECK:   return
104
105subroutine empty_infinite_in_while(i)
106  integer :: i
107  do while (i .gt. 50)
108    do
109    end do
110  end do
111end subroutine
112
113! CHECK-LABEL: empty_infinite_in_while
114! CHECK-SAME: %[[I_REF:.*]]: !fir.ref<i32>
115! CHECK:  cf.br ^bb1
116! CHECK: ^bb1:
117! CHECK:  %[[I:.*]] = fir.load %[[I_REF]] : !fir.ref<i32>
118! CHECK:  %[[C50:.*]] = arith.constant 50 : i32
119! CHECK:  %[[COND:.*]] = arith.cmpi sgt, %[[I]], %[[C50]] : i32
120! CHECK:  cf.cond_br %[[COND]], ^[[INF_HEADER:.*]], ^[[EXIT:.*]]
121! CHECK: ^[[INF_HEADER]]:
122! CHECK:   cf.br ^[[INF_BODY:.*]]
123! CHECK: ^[[INF_BODY]]:
124! CHECK:   cf.br ^[[INF_HEADER]]
125! CHECK: ^[[EXIT]]:
126! CHECK:  return
127