xref: /llvm-project/flang/test/Lower/HLFIR/forall.f90 (revision 3be8e3ad0c424dbeb9e4c8401174335e106a2d5d)
1! Test lowering of Forall to HLFIR.
2! RUN: bbc --hlfir -o - %s | FileCheck %s
3
4module forall_defs
5  integer :: x(10, 10), y(10)
6  interface
7    pure integer(8) function ifoo2(i, j)
8      integer(8), value :: i, j
9    end function
10    pure integer(8) function jfoo()
11    end function
12    pure integer(8) function jbar()
13    end function
14    pure logical function predicate(i)
15      integer(8), intent(in) :: i
16    end function
17  end interface
18end module
19
20subroutine test_simple_forall()
21  use forall_defs
22  forall (integer(8)::i=1:10) x(i, i) = y(i)
23end subroutine
24! CHECK-LABEL:   func.func @_QPtest_simple_forall() {
25! CHECK:  %[[VAL_0:.*]] = arith.constant 10 : i32
26! CHECK:  %[[VAL_1:.*]] = arith.constant 1 : i32
27! CHECK:  %[[VAL_5:.*]]:2 = hlfir.declare {{.*}}Ex
28! CHECK:  %[[VAL_8:.*]]:2 = hlfir.declare {{.*}}Ey
29! CHECK:  hlfir.forall lb {
30! CHECK:    hlfir.yield %[[VAL_1]] : i32
31! CHECK:  } ub {
32! CHECK:    hlfir.yield %[[VAL_0]] : i32
33! CHECK:  }  (%[[VAL_9:.*]]: i64) {
34! CHECK:    hlfir.region_assign {
35! CHECK:      %[[VAL_10:.*]] = hlfir.designate %[[VAL_8]]#0 (%[[VAL_9]])  : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
36! CHECK:      %[[VAL_11:.*]] = fir.load %[[VAL_10]] : !fir.ref<i32>
37! CHECK:      hlfir.yield %[[VAL_11]] : i32
38! CHECK:    } to {
39! CHECK:      %[[VAL_12:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_9]], %[[VAL_9]])  : (!fir.ref<!fir.array<10x10xi32>>, i64, i64) -> !fir.ref<i32>
40! CHECK:      hlfir.yield %[[VAL_12]] : !fir.ref<i32>
41! CHECK:    }
42! CHECK:  }
43
44subroutine test_forall_step(step)
45  use forall_defs
46  integer :: step
47  forall (integer(8)::i=1:10:step) x(i, i) = y(i)
48end subroutine
49! CHECK-LABEL:   func.func @_QPtest_forall_step(
50! CHECK:  %[[VAL_1:.*]] = arith.constant 10 : i32
51! CHECK:  %[[VAL_2:.*]] = arith.constant 1 : i32
52! CHECK:  %[[VAL_4:.*]]:2 = hlfir.declare {{.*}}Estep
53! CHECK:  %[[VAL_7:.*]]:2 = hlfir.declare {{.*}}Ex
54! CHECK:  %[[VAL_10:.*]]:2 = hlfir.declare {{.*}}Ey
55! CHECK:  %[[VAL_11:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<i32>
56! CHECK:  hlfir.forall lb {
57! CHECK:    hlfir.yield %[[VAL_2]] : i32
58! CHECK:  } ub {
59! CHECK:    hlfir.yield %[[VAL_1]] : i32
60! CHECK:  } step {
61! CHECK:    hlfir.yield %[[VAL_11]] : i32
62! CHECK:  }  (%[[VAL_12:.*]]: i64) {
63! CHECK:    hlfir.region_assign {
64! CHECK:      %[[VAL_13:.*]] = hlfir.designate %[[VAL_10]]#0 (%[[VAL_12]])  : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
65! CHECK:      %[[VAL_14:.*]] = fir.load %[[VAL_13]] : !fir.ref<i32>
66! CHECK:      hlfir.yield %[[VAL_14]] : i32
67! CHECK:    } to {
68! CHECK:      %[[VAL_15:.*]] = hlfir.designate %[[VAL_7]]#0 (%[[VAL_12]], %[[VAL_12]])  : (!fir.ref<!fir.array<10x10xi32>>, i64, i64) -> !fir.ref<i32>
69! CHECK:      hlfir.yield %[[VAL_15]] : !fir.ref<i32>
70! CHECK:    }
71! CHECK:  }
72
73subroutine test_forall_mask()
74  use forall_defs
75  forall (integer(8)::i=1:10, predicate(i)) x(i, i) = y(i)
76end subroutine
77! CHECK-LABEL:   func.func @_QPtest_forall_mask() {
78! CHECK:  %[[VAL_0:.*]] = arith.constant 10 : i32
79! CHECK:  %[[VAL_1:.*]] = arith.constant 1 : i32
80! CHECK:  %[[VAL_5:.*]]:2 = hlfir.declare {{.*}}Ex
81! CHECK:  %[[VAL_8:.*]]:2 = hlfir.declare {{.*}}Ey
82! CHECK:  hlfir.forall lb {
83! CHECK:    hlfir.yield %[[VAL_1]] : i32
84! CHECK:  } ub {
85! CHECK:    hlfir.yield %[[VAL_0]] : i32
86! CHECK:  }  (%[[VAL_9:.*]]: i64) {
87! CHECK:    %[[VAL_10:.*]] = hlfir.forall_index "i" %[[VAL_9]] : (i64) -> !fir.ref<i64>
88! CHECK:    hlfir.forall_mask {
89! CHECK:      %[[VAL_11:.*]] = fir.call @_QPpredicate(%[[VAL_10]]) proc_attrs<pure> fastmath<contract> : (!fir.ref<i64>) -> !fir.logical<4>
90! CHECK:      %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.logical<4>) -> i1
91! CHECK:      hlfir.yield %[[VAL_12]] : i1
92! CHECK:    } do {
93! CHECK:      hlfir.region_assign {
94! CHECK:        %[[I_LOAD:.*]] = fir.load %[[VAL_10]] : !fir.ref<i64>
95! CHECK:        %[[VAL_13:.*]] = hlfir.designate %[[VAL_8]]#0 (%[[I_LOAD]])  : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
96! CHECK:        %[[VAL_14:.*]] = fir.load %[[VAL_13]] : !fir.ref<i32>
97! CHECK:        hlfir.yield %[[VAL_14]] : i32
98! CHECK:      } to {
99! CHECK:        %[[I_LOAD:.*]] = fir.load %[[VAL_10]] : !fir.ref<i64>
100! CHECK:        %[[VAL_15:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[I_LOAD]], %[[I_LOAD]])  : (!fir.ref<!fir.array<10x10xi32>>, i64, i64) -> !fir.ref<i32>
101! CHECK:        hlfir.yield %[[VAL_15]] : !fir.ref<i32>
102! CHECK:      }
103! CHECK:    }
104! CHECK:  }
105
106subroutine test_forall_several_indices()
107  use forall_defs
108  ! Test outer forall controls are lowered outside.
109  forall (integer(8)::i=ibar():ifoo(), j=jfoo():jbar()) x(i, j) = y(ifoo2(i, j))
110end subroutine
111! CHECK-LABEL:   func.func @_QPtest_forall_several_indices() {
112! CHECK:  %[[VAL_3:.*]]:2 = hlfir.declare {{.*}}Ex
113! CHECK:  %[[VAL_6:.*]]:2 = hlfir.declare {{.*}}Ey
114! CHECK:  %[[VAL_7:.*]] = fir.call @_QPibar() fastmath<contract> : () -> i32
115! CHECK:  %[[VAL_8:.*]] = fir.call @_QPifoo() fastmath<contract> : () -> i32
116! CHECK:  %[[VAL_9:.*]] = fir.call @_QPjfoo() proc_attrs<pure> fastmath<contract> : () -> i64
117! CHECK:  %[[VAL_10:.*]] = fir.call @_QPjbar() proc_attrs<pure> fastmath<contract> : () -> i64
118! CHECK:  hlfir.forall lb {
119! CHECK:    hlfir.yield %[[VAL_7]] : i32
120! CHECK:  } ub {
121! CHECK:    hlfir.yield %[[VAL_8]] : i32
122! CHECK:  }  (%[[VAL_11:.*]]: i64) {
123! CHECK:    hlfir.forall lb {
124! CHECK:      hlfir.yield %[[VAL_9]] : i64
125! CHECK:    } ub {
126! CHECK:      hlfir.yield %[[VAL_10]] : i64
127! CHECK:    }  (%[[VAL_12:.*]]: i64) {
128! CHECK:      hlfir.region_assign {
129! CHECK:        %[[VAL_13:.*]] = fir.call @_QPifoo2(%[[VAL_11]], %[[VAL_12]]) proc_attrs<pure> fastmath<contract> : (i64, i64) -> i64
130! CHECK:        %[[VAL_14:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_13]])  : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
131! CHECK:        %[[VAL_15:.*]] = fir.load %[[VAL_14]] : !fir.ref<i32>
132! CHECK:        hlfir.yield %[[VAL_15]] : i32
133! CHECK:      } to {
134! CHECK:        %[[VAL_16:.*]] = hlfir.designate %[[VAL_3]]#0 (%[[VAL_11]], %[[VAL_12]])  : (!fir.ref<!fir.array<10x10xi32>>, i64, i64) -> !fir.ref<i32>
135! CHECK:        hlfir.yield %[[VAL_16]] : !fir.ref<i32>
136! CHECK:      }
137! CHECK:    }
138! CHECK:  }
139
140subroutine test_nested_foralls()
141  use forall_defs
142  forall (integer(8)::i=1:10)
143    x(i, i) = y(i)
144    ! ifoo and ibar could depend on x since it is a module
145    ! variable use associated. The calls in the control value
146    ! computation cannot be hoisted from the outer forall
147    ! even when they do not depend on outer forall indices.
148    forall (integer(8)::j=jfoo():jbar())
149      x(i, j) = x(j, i)
150    end forall
151  end forall
152end subroutine
153! CHECK-LABEL:   func.func @_QPtest_nested_foralls() {
154! CHECK:  %[[VAL_0:.*]] = arith.constant 10 : i32
155! CHECK:  %[[VAL_1:.*]] = arith.constant 1 : i32
156! CHECK:  %[[VAL_5:.*]]:2 = hlfir.declare {{.*}}Ex
157! CHECK:  %[[VAL_8:.*]]:2 = hlfir.declare {{.*}}Ey
158! CHECK:  hlfir.forall lb {
159! CHECK:    hlfir.yield %[[VAL_1]] : i32
160! CHECK:  } ub {
161! CHECK:    hlfir.yield %[[VAL_0]] : i32
162! CHECK:  }  (%[[VAL_9:.*]]: i64) {
163! CHECK:    hlfir.region_assign {
164! CHECK:      %[[VAL_10:.*]] = hlfir.designate %[[VAL_8]]#0 (%[[VAL_9]])  : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
165! CHECK:      %[[VAL_11:.*]] = fir.load %[[VAL_10]] : !fir.ref<i32>
166! CHECK:      hlfir.yield %[[VAL_11]] : i32
167! CHECK:    } to {
168! CHECK:      %[[VAL_12:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_9]], %[[VAL_9]])  : (!fir.ref<!fir.array<10x10xi32>>, i64, i64) -> !fir.ref<i32>
169! CHECK:      hlfir.yield %[[VAL_12]] : !fir.ref<i32>
170! CHECK:    }
171! CHECK:    hlfir.forall lb {
172! CHECK:      %[[VAL_13:.*]] = fir.call @_QPjfoo() proc_attrs<pure> fastmath<contract> : () -> i64
173! CHECK:      hlfir.yield %[[VAL_13]] : i64
174! CHECK:    } ub {
175! CHECK:      %[[VAL_14:.*]] = fir.call @_QPjbar() proc_attrs<pure> fastmath<contract> : () -> i64
176! CHECK:      hlfir.yield %[[VAL_14]] : i64
177! CHECK:    }  (%[[VAL_15:.*]]: i64) {
178! CHECK:      hlfir.region_assign {
179! CHECK:        %[[VAL_16:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_15]], %[[VAL_9]])  : (!fir.ref<!fir.array<10x10xi32>>, i64, i64) -> !fir.ref<i32>
180! CHECK:        %[[VAL_17:.*]] = fir.load %[[VAL_16]] : !fir.ref<i32>
181! CHECK:        hlfir.yield %[[VAL_17]] : i32
182! CHECK:      } to {
183! CHECK:        %[[VAL_18:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_9]], %[[VAL_15]])  : (!fir.ref<!fir.array<10x10xi32>>, i64, i64) -> !fir.ref<i32>
184! CHECK:        hlfir.yield %[[VAL_18]] : !fir.ref<i32>
185! CHECK:      }
186! CHECK:    }
187! CHECK:  }
188