1 ! RUN: %flang_fc1 -I nowhere -emit-hlfir -fopenacc %s -o - | FileCheck %s
3 ! This test checks the lowering of atomic capture
5 program acc_atomic_capture_test
8 !CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFEx"}
9 !CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %0 {uniq_name = "_QFEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
10 !CHECK: %[[Y:.*]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFEy"}
11 !CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %2 {uniq_name = "_QFEy"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
12 !CHECK: %[[temp:.*]] = fir.load %[[X_DECL]]#0 : !fir.ref<i32>
13 !CHECK: acc.atomic.capture {
14 !CHECK: acc.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 : !fir.ref<i32>, !fir.ref<i32>, i32
15 !CHECK: acc.atomic.update %[[Y_DECL]]#1 : !fir.ref<i32> {
16 !CHECK: ^bb0(%[[ARG:.*]]: i32):
17 !CHECK: %[[result:.*]] = arith.addi %[[temp]], %[[ARG]] : i32
18 !CHECK: acc.yield %[[result]] : i32
28 !CHECK: %[[temp:.*]] = fir.load %[[X_DECL]]#0 : !fir.ref<i32>
29 !CHECK: acc.atomic.capture {
30 !CHECK: acc.atomic.update %[[Y_DECL]]#1 : !fir.ref<i32> {
31 !CHECK: ^bb0(%[[ARG:.*]]: i32):
32 !CHECK: %[[result:.*]] = arith.muli %[[temp]], %[[ARG]] : i32
33 !CHECK: acc.yield %[[result]] : i32
35 !CHECK: acc.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 : !fir.ref<i32>, !fir.ref<i32>, i32
43 !CHECK: %[[constant_20:.*]] = arith.constant 20 : i32
44 !CHECK: %[[constant_8:.*]] = arith.constant 8 : i32
45 !CHECK: %[[temp:.*]] = fir.load %[[X_DECL]]#0 : !fir.ref<i32>
46 !CHECK: %[[result:.*]] = arith.subi %[[constant_8]], %[[temp]] : i32
47 !CHECK: %[[result_noreassoc:.*]] = hlfir.no_reassoc %[[result]] : i32
48 !CHECK: %[[result:.*]] = arith.addi %[[constant_20]], %[[result_noreassoc]] : i32
49 !CHECK: acc.atomic.capture {
50 !CHECK: acc.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 : !fir.ref<i32>, !fir.ref<i32>, i32
51 !CHECK: acc.atomic.write %[[Y_DECL]]#1 = %[[result]] : !fir.ref<i32>, i32
62 subroutine pointers_in_atomic_capture()
63 !CHECK: %[[A:.*]] = fir.alloca !fir.box<!fir.ptr<i32>> {bindc_name = "a", uniq_name = "_QFpointers_in_atomic_captureEa"}
64 !CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFpointers_in_atomic_captureEa"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
65 !CHECK: %[[B:.*]] = fir.alloca !fir.box<!fir.ptr<i32>> {bindc_name = "b", uniq_name = "_QFpointers_in_atomic_captureEb"}
66 !CHECK: %[[B_DECL:.*]]:2 = hlfir.declare %[[B]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFpointers_in_atomic_captureEb"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
67 !CHECK: %[[C:.*]] = fir.alloca i32 {bindc_name = "c", fir.target, uniq_name = "_QFpointers_in_atomic_captureEc"}
68 !CHECK: %[[C_DECL:.*]]:2 = hlfir.declare %[[C]] {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFpointers_in_atomic_captureEc"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
69 !CHECK: %[[D:.*]] = fir.alloca i32 {bindc_name = "d", fir.target, uniq_name = "_QFpointers_in_atomic_captureEd"}
70 !CHECK: %[[D_DECL:.*]]:2 = hlfir.declare %[[D]] {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFpointers_in_atomic_captureEd"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
72 !CHECK: %[[loaded_A:.*]] = fir.load %[[A_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
73 !CHECK: %[[loaded_A_addr:.*]] = fir.box_addr %[[loaded_A]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
74 !CHECK: %[[loaded_B:.*]] = fir.load %[[B_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
75 !CHECK: %[[loaded_B_addr:.*]] = fir.box_addr %[[loaded_B]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
76 !CHECK: %[[PRIVATE_LOADED_B:.*]] = fir.load %[[B_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
77 !CHECK: %[[PRIVATE_LOADED_B_addr:.*]] = fir.box_addr %[[PRIVATE_LOADED_B]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
78 !CHECK: %[[loaded_value:.*]] = fir.load %[[PRIVATE_LOADED_B_addr]] : !fir.ptr<i32>
79 !CHECK: acc.atomic.capture {
80 !CHECK: acc.atomic.update %[[loaded_A_addr]] : !fir.ptr<i32> {
81 !CHECK: ^bb0(%[[ARG:.*]]: i32):
82 !CHECK: %[[result:.*]] = arith.addi %[[ARG]], %[[loaded_value]] : i32
83 !CHECK: acc.yield %[[result]] : i32
85 !CHECK: acc.atomic.read %[[loaded_B_addr]] = %[[loaded_A_addr]] : !fir.ptr<i32>, !fir.ptr<i32>, i32
87 integer, pointer :: a
, b
88 integer, target
:: c
, d
99 subroutine capture_with_convert_f32_to_i32()
112 ! CHECK-LABEL: func.func @_QPcapture_with_convert_f32_to_i32()
113 ! CHECK: %[[K:.*]] = fir.alloca i32 {bindc_name = "k", uniq_name = "_QFcapture_with_convert_f32_to_i32Ek"}
114 ! CHECK: %[[K_DECL:.*]]:2 = hlfir.declare %[[K]] {uniq_name = "_QFcapture_with_convert_f32_to_i32Ek"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
115 ! CHECK: %[[V:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFcapture_with_convert_f32_to_i32Ev"}
116 ! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcapture_with_convert_f32_to_i32Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
117 ! CHECK: %[[CST:.*]] = arith.constant 3.140000e+00 : f32
118 ! CHECK: %[[MUL:.*]] = arith.mulf %{{.*}}, %[[CST]] fastmath<contract> : f32
119 ! CHECK: %[[CONV:.*]] = fir.convert %[[MUL]] : (f32) -> i32
120 ! CHECK: acc.atomic.capture {
121 ! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[K_DECL]]#1 : !fir.ref<i32>, !fir.ref<i32>, i32
122 ! CHECK: acc.atomic.write %[[K_DECL]]#1 = %[[CONV]] : !fir.ref<i32>, i32
125 subroutine capture_with_convert_i32_to_f64()
134 end subroutine capture_with_convert_i32_to_f64
136 ! CHECK-LABEL: func.func @_QPcapture_with_convert_i32_to_f64()
137 ! CHECK: %[[V:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFcapture_with_convert_i32_to_f64Ev"}
138 ! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcapture_with_convert_i32_to_f64Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
139 ! CHECK: %[[X:.*]] = fir.alloca f64 {bindc_name = "x", uniq_name = "_QFcapture_with_convert_i32_to_f64Ex"}
140 ! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcapture_with_convert_i32_to_f64Ex"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
141 ! CHECK: %[[CST:.*]] = arith.constant 1.000000e+00 : f64
142 ! CHECK: hlfir.assign %[[CST]] to %[[X_DECL]]#0 : f64, !fir.ref<f64>
143 ! CHECK: %c0_i32 = arith.constant 0 : i32
144 ! CHECK: hlfir.assign %c0_i32 to %[[V_DECL]]#0 : i32, !fir.ref<i32>
145 ! CHECK: %[[LOAD:.*]] = fir.load %[[V_DECL]]#0 : !fir.ref<i32>
146 ! CHECK: %[[CONV:.*]] = fir.convert %[[LOAD]] : (i32) -> f64
147 ! CHECK: acc.atomic.capture {
148 ! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_DECL]]#1 : !fir.ref<i32>, !fir.ref<f64>, f64
149 ! CHECK: acc.atomic.write %[[X_DECL]]#1 = %[[CONV]] : !fir.ref<f64>, f64
152 subroutine capture_with_convert_f64_to_i32()
161 end subroutine capture_with_convert_f64_to_i32
163 ! CHECK-LABEL: func.func @_QPcapture_with_convert_f64_to_i32()
164 ! CHECK: %[[V:.*]] = fir.alloca f64 {bindc_name = "v", uniq_name = "_QFcapture_with_convert_f64_to_i32Ev"}
165 ! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcapture_with_convert_f64_to_i32Ev"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
166 ! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFcapture_with_convert_f64_to_i32Ex"}
167 ! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcapture_with_convert_f64_to_i32Ex"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
168 ! CHECK: %c1_i32 = arith.constant 1 : i32
169 ! CHECK: hlfir.assign %c1_i32 to %[[X_DECL]]#0 : i32, !fir.ref<i32>
170 ! CHECK: %[[CST:.*]] = arith.constant 0.000000e+00 : f64
171 ! CHECK: hlfir.assign %[[CST]] to %[[V_DECL]]#0 : f64, !fir.ref<f64>
172 ! CHECK: %[[LOAD:.*]] = fir.load %[[V_DECL]]#0 : !fir.ref<f64>
173 ! CHECK: acc.atomic.capture {
174 ! CHECK: acc.atomic.update %[[X_DECL]]#1 : !fir.ref<i32> {
175 ! CHECK: ^bb0(%arg0: i32):
176 ! CHECK: %[[MUL:.*]] = arith.mulf %[[LOAD]], %[[LOAD]] fastmath<contract> : f64
177 ! CHECK: %[[CONV:.*]] = fir.convert %[[MUL]] : (f64) -> i32
178 ! CHECK: acc.yield %[[CONV]] : i32
180 ! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_DECL]]#1 : !fir.ref<f64>, !fir.ref<i32>, i32
183 subroutine capture_with_convert_i32_to_f32()
192 end subroutine capture_with_convert_i32_to_f32
194 ! CHECK-LABEL: func.func @_QPcapture_with_convert_i32_to_f32()
195 ! CHECK: %[[V:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFcapture_with_convert_i32_to_f32Ev"}
196 ! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcapture_with_convert_i32_to_f32Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
197 ! CHECK: %[[X:.*]] = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFcapture_with_convert_i32_to_f32Ex"}
198 ! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcapture_with_convert_i32_to_f32Ex"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
199 ! CHECK: %[[CST:.*]] = arith.constant 1.000000e+00 : f32
200 ! CHECK: hlfir.assign %[[CST]] to %[[X_DECL]]#0 : f32, !fir.ref<f32>
201 ! CHECK: %c0_i32 = arith.constant 0 : i32
202 ! CHECK: hlfir.assign %c0_i32 to %[[V_DECL]]#0 : i32, !fir.ref<i32>
203 ! CHECK: %[[LOAD:.*]] = fir.load %[[V_DECL]]#0 : !fir.ref<i32>
204 ! CHECK: acc.atomic.capture {
205 ! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_DECL]]#1 : !fir.ref<i32>, !fir.ref<f32>, f32
206 ! CHECK: acc.atomic.update %[[X_DECL]]#1 : !fir.ref<f32> {
207 ! CHECK: ^bb0(%arg0: f32):
208 ! CHECK: %[[CONV:.*]] = fir.convert %[[LOAD]] : (i32) -> f32
209 ! CHECK: %[[ADD:.*]] = arith.addf %arg0, %[[CONV]] fastmath<contract> : f32
210 ! CHECK: acc.yield %[[ADD]] : f32
214 subroutine array_ref_in_atomic_capture1
220 end subroutine array_ref_in_atomic_capture1
221 ! CHECK-LABEL: func.func @_QParray_ref_in_atomic_capture1() {
222 ! CHECK: %[[V:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFarray_ref_in_atomic_capture1Ev"}
223 ! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFarray_ref_in_atomic_capture1Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
224 ! CHECK: %[[X:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "x", uniq_name = "_QFarray_ref_in_atomic_capture1Ex"}
225 ! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]](%{{.*}}) {uniq_name = "_QFarray_ref_in_atomic_capture1Ex"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
226 ! CHECK: %[[X_REF:.*]] = hlfir.designate %[[X_DECL]]#0 (%{{.*}}) : (!fir.ref<!fir.array<10xi32>>, index) -> !fir.ref<i32>
227 ! CHECK: acc.atomic.capture {
228 ! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_REF]] : !fir.ref<i32>, !fir.ref<i32>, i32
229 ! CHECK: acc.atomic.update %[[X_REF]] : !fir.ref<i32> {
230 ! CHECK: ^bb0(%[[VAL_7:.*]]: i32):
231 ! CHECK: %[[VAL_8:.*]] = arith.addi %[[VAL_7]], %{{.*}} : i32
232 ! CHECK: acc.yield %[[VAL_8]] : i32
236 subroutine array_ref_in_atomic_capture2
242 end subroutine array_ref_in_atomic_capture2
243 ! CHECK-LABEL: func.func @_QParray_ref_in_atomic_capture2() {
244 ! CHECK: %[[V:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFarray_ref_in_atomic_capture2Ev"}
245 ! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFarray_ref_in_atomic_capture2Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
246 ! CHECK: %[[X:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "x", uniq_name = "_QFarray_ref_in_atomic_capture2Ex"}
247 ! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]](%{{.*}}) {uniq_name = "_QFarray_ref_in_atomic_capture2Ex"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
248 ! CHECK: %[[X_REF:.*]] = hlfir.designate %[[X_DECL]]#0 (%{{.*}}) : (!fir.ref<!fir.array<10xi32>>, index) -> !fir.ref<i32>
249 ! CHECK: acc.atomic.capture {
250 ! CHECK: acc.atomic.update %[[X_REF]] : !fir.ref<i32> {
251 ! CHECK: ^bb0(%[[VAL_7:.*]]: i32):
252 ! CHECK: %[[VAL_8:.*]] = arith.addi %[[VAL_7]], %{{.*}} : i32
253 ! CHECK: acc.yield %[[VAL_8]] : i32
255 ! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_REF]] : !fir.ref<i32>, !fir.ref<i32>, i32
258 subroutine comp_ref_in_atomic_capture1
268 end subroutine comp_ref_in_atomic_capture1
269 ! CHECK-LABEL: func.func @_QPcomp_ref_in_atomic_capture1() {
270 ! CHECK: %[[V:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFcomp_ref_in_atomic_capture1Ev"}
271 ! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcomp_ref_in_atomic_capture1Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
272 ! CHECK: %[[X:.*]] = fir.alloca !fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}> {bindc_name = "x", uniq_name = "_QFcomp_ref_in_atomic_capture1Ex"}
273 ! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcomp_ref_in_atomic_capture1Ex"} : (!fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}>>) -> (!fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}>>, !fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}>>)
274 ! CHECK: %[[C:.*]] = hlfir.designate %[[X_DECL]]#0{"c"} : (!fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}>>) -> !fir.ref<i32>
275 ! CHECK: acc.atomic.capture {
276 ! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[C]] : !fir.ref<i32>, !fir.ref<i32>, i32
277 ! CHECK: acc.atomic.update %[[C]] : !fir.ref<i32> {
278 ! CHECK: ^bb0(%[[VAL_5:.*]]: i32):
279 ! CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_5]], %{{.*}} : i32
280 ! CHECK: acc.yield %[[VAL_6]] : i32
284 subroutine comp_ref_in_atomic_capture2
294 end subroutine comp_ref_in_atomic_capture2
295 ! CHECK-LABEL: func.func @_QPcomp_ref_in_atomic_capture2() {
296 ! CHECK: %[[V:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFcomp_ref_in_atomic_capture2Ev"}
297 ! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcomp_ref_in_atomic_capture2Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
298 ! CHECK: %[[X:.*]] = fir.alloca !fir.type<_QFcomp_ref_in_atomic_capture2Tt1{c:i32}> {bindc_name = "x", uniq_name = "_QFcomp_ref_in_atomic_capture2Ex"}
299 ! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcomp_ref_in_atomic_capture2Ex"} : (!fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture2Tt1{c:i32}>>) -> (!fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture2Tt1{c:i32}>>, !fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture2Tt1{c:i32}>>)
300 ! CHECK: %[[C:.*]] = hlfir.designate %[[X_DECL]]#0{"c"} : (!fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture2Tt1{c:i32}>>) -> !fir.ref<i32>
301 ! CHECK: acc.atomic.capture {
302 ! CHECK: acc.atomic.update %[[C]] : !fir.ref<i32> {
303 ! CHECK: ^bb0(%[[VAL_5:.*]]: i32):
304 ! CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_5]], %{{.*}} : i32
305 ! CHECK: acc.yield %[[VAL_6]] : i32
307 ! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[C]] : !fir.ref<i32>, !fir.ref<i32>, i32