xref: /llvm-project/flang/test/Lower/HLFIR/goto-do-body.f90 (revision a88677edc0792534ba3157bf7d7a1b98e470f2fb)
1! RUN: bbc --hlfir -o - %s | FileCheck %s
2
3! Test jumping to the body of a do loop.
4subroutine sub1()
5! CHECK-LABEL:  func @_QPsub1() {
6  implicit none
7  integer :: i
8  external foo
9! CHECK:    %[[C2:.*]] = arith.constant 2 : i32
10! CHECK:    %[[C0:.*]] = arith.constant 0 : i32
11! CHECK:    %[[C1:.*]] = arith.constant 1 : i32
12! CHECK:    %[[TRIP:.*]] = fir.alloca i32
13! CHECK:    %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", {{.*}}}
14! CHECK:    %[[I:.*]]:2 = hlfir.declare %[[I_REF]] {uniq_name = "_QFsub1Ei"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
15
16  do i = 1, 3
17    if (i .eq. 2) goto 70
18! CHECK:    %[[TMP1:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
19! CHECK:    %[[COND:.*]] = arith.cmpi eq, %[[TMP1]], %[[C2]] : i32
20! CHECK:    cf.cond_br %[[COND]], ^[[BODY:.*]], ^{{.*}}
21
22  end do
23
24  call foo
25! CHECK:  fir.call @_QPfoo()
26
27  do i = 1, 2
28! CHECK:    fir.store %[[C2]] to %[[TRIP]] : !fir.ref<i32>
29! CHECK:    fir.store %[[C1]] to %[[I]]#1 : !fir.ref<i32>
30! CHECK:    cf.br ^[[HEADER:.*]]
31! CHECK:  ^[[HEADER]]:
32! CHECK:    %[[TMP2:.*]] = fir.load %[[TRIP]] : !fir.ref<i32>
33! CHECK:    %[[TMP3:.*]] = arith.cmpi sgt, %[[TMP2]], %[[C0]] : i32
34! CHECK:    cf.cond_br %[[TMP3]], ^[[BODY]], ^[[EXIT:.*]]
35
36    70 call foo
37! CHECK:  ^[[BODY]]:
38! CHECK:    fir.call @_QPfoo()
39! CHECK:    %[[TMP4:.*]] = fir.load %[[TRIP]] : !fir.ref<i32>
40! CHECK:    %[[TMP5:.*]] = arith.subi %[[TMP4]], %[[C1]] : i32
41! CHECK:    fir.store %[[TMP5]] to %[[TRIP]] : !fir.ref<i32>
42! CHECK:    %[[TMP6:.*]] = fir.load %[[I]]#1 : !fir.ref<i32>
43! CHECK:    %[[TMP7:.*]] = arith.addi %[[TMP6]], %[[C1]] overflow<nsw> : i32
44! CHECK:    fir.store %[[TMP7]] to %[[I]]#1 : !fir.ref<i32>
45! CHECK:    cf.br ^[[HEADER]]
46  end do
47end subroutine
48! CHECK: ^[[EXIT]]:
49! CHECK:    return
50! CHECK:  }
51
52! Test jumping to the body of a do loop with a step expression.
53subroutine sub2()
54! CHECK-LABEL:  func @_QPsub2() {
55  implicit none
56  integer :: i, j
57  external foo
58! CHECK:    %[[C_7:.*]] = arith.constant -7 : i32
59! CHECK:    %[[C8:.*]] = arith.constant 8 : i32
60! CHECK:    %[[C2:.*]] = arith.constant 2 : i32
61! CHECK:    %[[C0:.*]] = arith.constant 0 : i32
62! CHECK:    %[[C3:.*]] = arith.constant 3 : i32
63! CHECK:    %[[C1:.*]] = arith.constant 1 : i32
64! CHECK:    %[[TRIP:.*]] = fir.alloca i32
65! CHECK:    %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", {{.*}}}
66! CHECK:    %[[I:.*]]:2 = hlfir.declare %[[I_REF]] {uniq_name = "_QFsub2Ei"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
67! CHECK:    %[[J_REF:.*]] = fir.alloca i32 {bindc_name = "j", {{.*}}}
68! CHECK:    %[[J:.*]]:2 = hlfir.declare %[[J_REF]] {uniq_name = "_QFsub2Ej"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
69
70  do i = 1, 3
71    if (i .eq. 2) goto 70
72! CHECK:    %[[TMP1:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
73! CHECK:    %[[COND:.*]] = arith.cmpi eq, %[[TMP1]], %[[C2]] : i32
74! CHECK:    cf.cond_br %[[COND]], ^[[BODY:.*]], ^{{.*}}
75
76  end do
77
78  call foo
79! CHECK:    fir.call @_QPfoo()
80
81  j = 3
82! CHECK:    hlfir.assign %[[C3]] to %[[J]]#0 : i32, !fir.ref<i32>
83
84  do i = 1, 2, 3 * j - 8
85! CHECK:    %[[TMP2:.*]] = fir.load %[[J]]#0 : !fir.ref<i32>
86! CHECK:    %[[TMP3:.*]] = arith.muli %[[TMP2]], %[[C3]] overflow<nsw> : i32
87! CHECK:    %[[STEP:.*]] = arith.subi %[[TMP3]], %[[C8]] overflow<nsw> : i32
88! CHECK:    fir.store %[[STEP]] to %[[STEP_VAR:.*]] : !fir.ref<i32>
89! CHECK:    %[[TMP4:.*]] = arith.addi %[[TMP3]], %[[C_7]] : i32
90! CHECK:    %[[TMP5:.*]] = arith.divsi %[[TMP4]], %[[STEP]] : i32
91! CHECK:    fir.store %[[TMP5]] to %[[TRIP]] : !fir.ref<i32>
92! CHECK:    fir.store %[[C1]] to %[[I]]#1 : !fir.ref<i32>
93! CHECK:    cf.br ^[[HEADER:.*]]
94! CHECK:  ^[[HEADER]]:
95! CHECK:    %[[TMP6:.*]] = fir.load %[[TRIP]] : !fir.ref<i32>
96! CHECK:    %[[TMP7:.*]] = arith.cmpi sgt, %[[TMP6]], %[[C0]] : i32
97! CHECK:    cf.cond_br %[[TMP7]], ^[[BODY]], ^[[EXIT:.*]]
98
99    70 call foo
100! CHECK:  ^[[BODY]]:
101! CHECK:    fir.call @_QPfoo()
102! CHECK:    %[[TMP8:.*]] = fir.load %[[TRIP]] : !fir.ref<i32>
103! CHECK:    %[[TMP9:.*]] = arith.subi %[[TMP8]], %[[C1]] : i32
104! CHECK:    fir.store %[[TMP9]] to %[[TRIP]] : !fir.ref<i32>
105! CHECK:    %[[TMP10:.*]] = fir.load %[[I]]#1 : !fir.ref<i32>
106! CHECK:    %[[STEP_VAL:.*]] = fir.load %[[STEP_VAR]] : !fir.ref<i32>
107! CHECK:    %[[TMP11:.*]] = arith.addi %[[TMP10]], %[[STEP_VAL]] overflow<nsw> : i32
108! CHECK:    fir.store %[[TMP11]] to %[[I]]#1 : !fir.ref<i32>
109! CHECK:    cf.br ^[[HEADER]]
110  end do
111end subroutine
112! CHECK: ^[[EXIT]]:
113! CHECK:    return
114! CHECK:  }
115