1 // RUN: mlir-translate -mlir-to-llvmir -split-input-file %s | FileCheck %s
3 // Only check the overall shape of the code and the presence of relevant
4 // runtime calls. Actual IR checking is done at the OpenMPIRBuilder level.
6 omp.declare_reduction @add_f32 : f32
9 %0 = llvm.mlir.constant(0.0 : f32) : f32
13 ^bb1(%arg0: f32, %arg1: f32):
14 %1 = llvm.fadd %arg0, %arg1 : f32
18 ^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):
19 %2 = llvm.load %arg3 : !llvm.ptr -> f32
20 llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32
24 // CHECK-LABEL: @simple_reduction
25 llvm.func @simple_reduction(%lb : i64, %ub : i64, %step : i64) {
26 %c1 = llvm.mlir.constant(1 : i32) : i32
27 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
29 omp.wsloop reduction(@add_f32 %0 -> %prv : !llvm.ptr) {
30 omp.loop_nest (%iv) : i64 = (%lb) to (%ub) step (%step) {
31 %1 = llvm.mlir.constant(2.0 : f32) : f32
32 %2 = llvm.load %prv : !llvm.ptr -> f32
33 %3 = llvm.fadd %1, %2 : f32
34 llvm.store %3, %prv : f32, !llvm.ptr
43 // Call to the outlined function.
44 // CHECK: call void {{.*}} @__kmpc_fork_call
45 // CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]
48 // CHECK: define internal void @[[OUTLINED]]
50 // Private reduction variable and its initialization.
51 // CHECK: %[[PRIVATE:.+]] = alloca float
52 // CHECK: store float 0.000000e+00, ptr %[[PRIVATE]]
54 // Call to the reduction function.
55 // CHECK: call i32 @__kmpc_reduce
56 // CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]
59 // CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]
60 // CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL]]
62 // Non-atomic reduction:
64 // CHECK: call void @__kmpc_end_reduce
65 // CHECK: br label %[[FINALIZE:.+]]
67 // CHECK: [[FINALIZE]]:
68 // CHECK: call void @__kmpc_barrier
70 // Update of the private variable using the reduction region
71 // (the body block currently comes after all the other blocks).
72 // CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]
73 // CHECK: %[[UPDATED:.+]] = fadd float 2.000000e+00, %[[PARTIAL]]
74 // CHECK: store float %[[UPDATED]], ptr %[[PRIVATE]]
76 // Reduction function.
77 // CHECK: define internal void @[[REDFUNC]]
82 omp.declare_reduction @add_f32 : f32
85 %0 = llvm.mlir.constant(0.0 : f32) : f32
89 ^bb1(%arg0: f32, %arg1: f32):
90 %1 = llvm.fadd %arg0, %arg1 : f32
94 ^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):
95 %2 = llvm.load %arg3 : !llvm.ptr -> f32
96 llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32
100 // When the same reduction declaration is used several times, its regions
101 // are translated several times, which shouldn't lead to value/block
102 // remapping assertions.
103 // CHECK-LABEL: @reuse_declaration
104 llvm.func @reuse_declaration(%lb : i64, %ub : i64, %step : i64) {
105 %c1 = llvm.mlir.constant(1 : i32) : i32
106 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
107 %2 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
109 omp.wsloop reduction(@add_f32 %0 -> %prv0, @add_f32 %2 -> %prv1 : !llvm.ptr, !llvm.ptr) {
110 omp.loop_nest (%iv) : i64 = (%lb) to (%ub) step (%step) {
111 %1 = llvm.mlir.constant(2.0 : f32) : f32
112 %3 = llvm.load %prv0 : !llvm.ptr -> f32
113 %4 = llvm.fadd %3, %1 : f32
114 llvm.store %4, %prv0 : f32, !llvm.ptr
115 %5 = llvm.load %prv1 : !llvm.ptr -> f32
116 %6 = llvm.fadd %5, %1 : f32
117 llvm.store %6, %prv1 : f32, !llvm.ptr
126 // Call to the outlined function.
127 // CHECK: call void {{.*}} @__kmpc_fork_call
128 // CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]
130 // Outlined function.
131 // CHECK: define internal void @[[OUTLINED]]
133 // Private reduction variable and its initialization.
134 // CHECK: %[[PRIVATE1:.+]] = alloca float
135 // CHECK: %[[PRIVATE2:.+]] = alloca float
136 // CHECK: store float 0.000000e+00, ptr %[[PRIVATE1]]
137 // CHECK: store float 0.000000e+00, ptr %[[PRIVATE2]]
139 // Call to the reduction function.
140 // CHECK: call i32 @__kmpc_reduce
141 // CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]
144 // CHECK: %[[PARTIAL1:.+]] = load float, ptr %[[PRIVATE1]]
145 // CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL1]]
146 // CHECK: %[[PARTIAL2:.+]] = load float, ptr %[[PRIVATE2]]
147 // CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL2]]
149 // Non-atomic reduction:
152 // CHECK: call void @__kmpc_end_reduce
153 // CHECK: br label %[[FINALIZE:.+]]
155 // CHECK: [[FINALIZE]]:
156 // CHECK: call void @__kmpc_barrier
158 // Update of the private variable using the reduction region
159 // (the body block currently comes after all the other blocks).
160 // CHECK: %[[PARTIAL1:.+]] = load float, ptr %[[PRIVATE1]]
161 // CHECK: %[[UPDATED1:.+]] = fadd float %[[PARTIAL1]], 2.000000e+00
162 // CHECK: store float %[[UPDATED1]], ptr %[[PRIVATE1]]
163 // CHECK: %[[PARTIAL2:.+]] = load float, ptr %[[PRIVATE2]]
164 // CHECK: %[[UPDATED2:.+]] = fadd float %[[PARTIAL2]], 2.000000e+00
165 // CHECK: store float %[[UPDATED2]], ptr %[[PRIVATE2]]
167 // Reduction function.
168 // CHECK: define internal void @[[REDFUNC]]
175 omp.declare_reduction @add_f32 : f32
178 %0 = llvm.mlir.constant(0.0 : f32) : f32
182 ^bb1(%arg0: f32, %arg1: f32):
183 %1 = llvm.fadd %arg0, %arg1 : f32
187 ^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):
188 %2 = llvm.load %arg3 : !llvm.ptr -> f32
189 llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32
193 // It's okay not to reference the reduction variable in the body.
194 // CHECK-LABEL: @missing_omp_reduction
195 llvm.func @missing_omp_reduction(%lb : i64, %ub : i64, %step : i64) {
196 %c1 = llvm.mlir.constant(1 : i32) : i32
197 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
198 %2 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
200 omp.wsloop reduction(@add_f32 %0 -> %prv0, @add_f32 %2 -> %prv1 : !llvm.ptr, !llvm.ptr) {
201 omp.loop_nest (%iv) : i64 = (%lb) to (%ub) step (%step) {
202 %1 = llvm.mlir.constant(2.0 : f32) : f32
203 %3 = llvm.load %prv0 : !llvm.ptr -> f32
204 %4 = llvm.fadd %3, %1 : f32
205 llvm.store %4, %prv0 : f32, !llvm.ptr
214 // Call to the outlined function.
215 // CHECK: call void {{.*}} @__kmpc_fork_call
216 // CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]
218 // Outlined function.
219 // CHECK: define internal void @[[OUTLINED]]
221 // Private reduction variable and its initialization.
222 // CHECK: %[[PRIVATE1:.+]] = alloca float
223 // CHECK: %[[PRIVATE2:.+]] = alloca float
224 // CHECK: store float 0.000000e+00, ptr %[[PRIVATE1]]
225 // CHECK: store float 0.000000e+00, ptr %[[PRIVATE2]]
227 // Call to the reduction function.
228 // CHECK: call i32 @__kmpc_reduce
229 // CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]
232 // CHECK: %[[PARTIAL1:.+]] = load float, ptr %[[PRIVATE1]]
233 // CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL1]]
234 // CHECK: %[[PARTIAL2:.+]] = load float, ptr %[[PRIVATE2]]
235 // CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL2]]
237 // Non-atomic reduction:
240 // CHECK: call void @__kmpc_end_reduce
241 // CHECK: br label %[[FINALIZE:.+]]
243 // CHECK: [[FINALIZE]]:
244 // CHECK: call void @__kmpc_barrier
246 // Update of the private variable using the reduction region
247 // (the body block currently comes after all the other blocks).
248 // CHECK: %[[PARTIAL1:.+]] = load float, ptr %[[PRIVATE1]]
249 // CHECK: %[[UPDATED1:.+]] = fadd float %[[PARTIAL1]], 2.000000e+00
250 // CHECK: store float %[[UPDATED1]], ptr %[[PRIVATE1]]
251 // CHECK-NOT: %{{.*}} = load float, ptr %[[PRIVATE2]]
252 // CHECK-NOT: %{{.*}} = fadd float %[[PARTIAL2]], 2.000000e+00
254 // Reduction function.
255 // CHECK: define internal void @[[REDFUNC]]
261 omp.declare_reduction @add_f32 : f32
264 %0 = llvm.mlir.constant(0.0 : f32) : f32
268 ^bb1(%arg0: f32, %arg1: f32):
269 %1 = llvm.fadd %arg0, %arg1 : f32
273 ^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):
274 %2 = llvm.load %arg3 : !llvm.ptr -> f32
275 llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32
279 // It's okay to refer to the same reduction variable more than once in the
281 // CHECK-LABEL: @double_reference
282 llvm.func @double_reference(%lb : i64, %ub : i64, %step : i64) {
283 %c1 = llvm.mlir.constant(1 : i32) : i32
284 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
286 omp.wsloop reduction(@add_f32 %0 -> %prv : !llvm.ptr) {
287 omp.loop_nest (%iv) : i64 = (%lb) to (%ub) step (%step) {
288 %1 = llvm.mlir.constant(2.0 : f32) : f32
289 %2 = llvm.load %prv : !llvm.ptr -> f32
290 %3 = llvm.fadd %2, %1 : f32
291 llvm.store %3, %prv : f32, !llvm.ptr
292 %4 = llvm.load %prv : !llvm.ptr -> f32
293 %5 = llvm.fadd %4, %1 : f32
294 llvm.store %5, %prv : f32, !llvm.ptr
303 // Call to the outlined function.
304 // CHECK: call void {{.*}} @__kmpc_fork_call
305 // CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]
307 // Outlined function.
308 // CHECK: define internal void @[[OUTLINED]]
310 // Private reduction variable and its initialization.
311 // CHECK: %[[PRIVATE:.+]] = alloca float
312 // CHECK: store float 0.000000e+00, ptr %[[PRIVATE]]
314 // Call to the reduction function.
315 // CHECK: call i32 @__kmpc_reduce
316 // CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]
319 // CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]
320 // CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL]]
322 // Non-atomic reduction:
324 // CHECK: call void @__kmpc_end_reduce
325 // CHECK: br label %[[FINALIZE:.+]]
327 // CHECK: [[FINALIZE]]:
328 // CHECK: call void @__kmpc_barrier
330 // Update of the private variable using the reduction region
331 // (the body block currently comes after all the other blocks).
332 // CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]
333 // CHECK: %[[UPDATED:.+]] = fadd float %[[PARTIAL]], 2.000000e+00
334 // CHECK: store float %[[UPDATED]], ptr %[[PRIVATE]]
335 // CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]
336 // CHECK: %[[UPDATED:.+]] = fadd float %[[PARTIAL]], 2.000000e+00
337 // CHECK: store float %[[UPDATED]], ptr %[[PRIVATE]]
339 // Reduction function.
340 // CHECK: define internal void @[[REDFUNC]]
345 omp.declare_reduction @add_f32 : f32
348 %0 = llvm.mlir.constant(0.0 : f32) : f32
352 ^bb1(%arg0: f32, %arg1: f32):
353 %1 = llvm.fadd %arg0, %arg1 : f32
357 ^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):
358 %2 = llvm.load %arg3 : !llvm.ptr -> f32
359 llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32
363 omp.declare_reduction @mul_f32 : f32
366 %0 = llvm.mlir.constant(1.0 : f32) : f32
370 ^bb1(%arg0: f32, %arg1: f32):
371 %1 = llvm.fmul %arg0, %arg1 : f32
375 // CHECK-LABEL: @no_atomic
376 llvm.func @no_atomic(%lb : i64, %ub : i64, %step : i64) {
377 %c1 = llvm.mlir.constant(1 : i32) : i32
378 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
379 %2 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
381 omp.wsloop reduction(@add_f32 %0 -> %prv0, @mul_f32 %2 -> %prv1 : !llvm.ptr, !llvm.ptr) {
382 omp.loop_nest (%iv) : i64 = (%lb) to (%ub) step (%step) {
383 %1 = llvm.mlir.constant(2.0 : f32) : f32
384 %3 = llvm.load %prv0 : !llvm.ptr -> f32
385 %4 = llvm.fadd %3, %1 : f32
386 llvm.store %4, %prv0 : f32, !llvm.ptr
387 %5 = llvm.load %prv1 : !llvm.ptr -> f32
388 %6 = llvm.fmul %5, %1 : f32
389 llvm.store %6, %prv1 : f32, !llvm.ptr
398 // Call to the outlined function.
399 // CHECK: call void {{.*}} @__kmpc_fork_call
400 // CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]
402 // Outlined function.
403 // CHECK: define internal void @[[OUTLINED]]
405 // Private reduction variable and its initialization.
406 // CHECK: %[[PRIVATE1:.+]] = alloca float
407 // CHECK: %[[PRIVATE2:.+]] = alloca float
408 // CHECK: store float 0.000000e+00, ptr %[[PRIVATE1]]
409 // CHECK: store float 1.000000e+00, ptr %[[PRIVATE2]]
411 // Call to the reduction function.
412 // CHECK: call i32 @__kmpc_reduce
413 // CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]
415 // Atomic reduction not provided.
416 // CHECK: unreachable
418 // Non-atomic reduction:
421 // CHECK: call void @__kmpc_end_reduce
422 // CHECK: br label %[[FINALIZE:.+]]
424 // CHECK: [[FINALIZE]]:
425 // CHECK: call void @__kmpc_barrier
427 // Update of the private variable using the reduction region
428 // (the body block currently comes after all the other blocks).
429 // CHECK: %[[PARTIAL1:.+]] = load float, ptr %[[PRIVATE1]]
430 // CHECK: %[[UPDATED1:.+]] = fadd float %[[PARTIAL1]], 2.000000e+00
431 // CHECK: store float %[[UPDATED1]], ptr %[[PRIVATE1]]
432 // CHECK: %[[PARTIAL2:.+]] = load float, ptr %[[PRIVATE2]]
433 // CHECK: %[[UPDATED2:.+]] = fmul float %[[PARTIAL2]], 2.000000e+00
434 // CHECK: store float %[[UPDATED2]], ptr %[[PRIVATE2]]
436 // Reduction function.
437 // CHECK: define internal void @[[REDFUNC]]
443 omp.declare_reduction @add_f32 : f32
446 %0 = llvm.mlir.constant(0.0 : f32) : f32
450 ^bb1(%arg0: f32, %arg1: f32):
451 %1 = llvm.fadd %arg0, %arg1 : f32
455 ^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):
456 %2 = llvm.load %arg3 : !llvm.ptr -> f32
457 llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32
461 // CHECK-LABEL: @simple_reduction_parallel
462 llvm.func @simple_reduction_parallel() {
463 %c1 = llvm.mlir.constant(1 : i32) : i32
464 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
465 omp.parallel reduction(@add_f32 %0 -> %prv : !llvm.ptr) {
466 %1 = llvm.mlir.constant(2.0 : f32) : f32
467 %2 = llvm.load %prv : !llvm.ptr -> f32
468 %3 = llvm.fadd %2, %1 : f32
469 llvm.store %3, %prv : f32, !llvm.ptr
475 // Call to the outlined function.
476 // CHECK: call void {{.*}} @__kmpc_fork_call
477 // CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]
479 // Outlined function.
480 // CHECK: define internal void @[[OUTLINED]]
482 // Private reduction variable and its initialization.
483 // CHECK: %[[PRIVATE:.+]] = alloca float
484 // CHECK: store float 0.000000e+00, ptr %[[PRIVATE]]
486 // Update of the private variable
487 // CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]
488 // CHECK: %[[UPDATED:.+]] = fadd float %[[PARTIAL]], 2.000000e+00
489 // CHECK: store float %[[UPDATED]], ptr %[[PRIVATE]]
491 // Call to the reduction function.
492 // CHECK: call i32 @__kmpc_reduce
493 // CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]
496 // CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]
497 // CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL]]
499 // Non-atomic reduction:
501 // CHECK: call void @__kmpc_end_reduce
502 // CHECK: br label %[[FINALIZE:.+]]
504 // CHECK: [[FINALIZE]]:
506 // Reduction function.
507 // CHECK: define internal void @[[REDFUNC]]
512 omp.declare_reduction @add_i32 : i32
515 %0 = llvm.mlir.constant(0 : i32) : i32
519 ^bb1(%arg0: i32, %arg1: i32):
520 %1 = llvm.add %arg0, %arg1 : i32
524 ^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):
525 %2 = llvm.load %arg3 : !llvm.ptr -> i32
526 llvm.atomicrmw add %arg2, %2 monotonic : !llvm.ptr, i32
530 // CHECK-LABEL: @parallel_nested_workshare_reduction
531 llvm.func @parallel_nested_workshare_reduction(%ub : i64) {
532 %c1 = llvm.mlir.constant(1 : i32) : i32
533 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
535 %lb = llvm.mlir.constant(1 : i64) : i64
536 %step = llvm.mlir.constant(1 : i64) : i64
539 omp.wsloop reduction(@add_i32 %0 -> %prv : !llvm.ptr) {
540 omp.loop_nest (%iv) : i64 = (%lb) to (%ub) step (%step) {
541 %ival = llvm.trunc %iv : i64 to i32
542 %lprv = llvm.load %prv : !llvm.ptr -> i32
543 %add = llvm.add %lprv, %ival : i32
544 llvm.store %add, %prv : i32, !llvm.ptr
554 // Call to the outlined function.
555 // CHECK: call void {{.*}} @__kmpc_fork_call
556 // CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]
558 // Outlined function.
559 // CHECK: define internal void @[[OUTLINED]]
561 // Private reduction variable and its initialization.
562 // CHECK: %[[PRIVATE:[0-9]+]] = alloca i32
563 // CHECK: store i32 0, ptr %[[PRIVATE]]
566 // CHECK: call void @__kmpc_barrier
568 // Call to the reduction function.
569 // CHECK: call i32 @__kmpc_reduce
570 // CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]
573 // CHECK: %[[PARTIAL:.+]] = load i32, ptr %[[PRIVATE]]
574 // CHECK: atomicrmw add ptr %{{.*}}, i32 %[[PARTIAL]]
576 // Non-atomic reduction:
578 // CHECK: call void @__kmpc_end_reduce
580 // Update of the private variable using the reduction region
581 // (the body block currently comes after all the other blocks).
582 // CHECK: %[[PARTIAL:.+]] = load i32, ptr %[[PRIVATE]]
583 // CHECK: %[[UPDATED:.+]] = add i32 %[[PARTIAL]], {{.*}}
584 // CHECK: store i32 %[[UPDATED]], ptr %[[PRIVATE]]
586 // Reduction function.
587 // CHECK: define internal void @[[REDFUNC]]
592 omp.declare_reduction @add_f32 : f32
595 %0 = llvm.mlir.constant(0.0 : f32) : f32
599 ^bb1(%arg0: f32, %arg1: f32):
600 %1 = llvm.fadd %arg0, %arg1 : f32
604 ^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):
605 %2 = llvm.load %arg3 : !llvm.ptr -> f32
606 llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32
610 // CHECK-LABEL: @wsloop_simd_reduction
611 llvm.func @wsloop_simd_reduction(%lb : i64, %ub : i64, %step : i64) {
612 %c1 = llvm.mlir.constant(1 : i32) : i32
613 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
615 omp.wsloop reduction(@add_f32 %0 -> %prv1 : !llvm.ptr) {
616 omp.simd reduction(@add_f32 %prv1 -> %prv2 : !llvm.ptr) {
617 omp.loop_nest (%iv) : i64 = (%lb) to (%ub) step (%step) {
618 %1 = llvm.mlir.constant(2.0 : f32) : f32
619 %2 = llvm.load %prv2 : !llvm.ptr -> f32
620 %3 = llvm.fadd %1, %2 : f32
621 llvm.store %3, %prv2 : f32, !llvm.ptr
631 // Same checks as for wsloop reduction, because currently omp.simd is ignored in
632 // a composite 'do/for simd' construct.
633 // Call to the outlined function.
634 // CHECK: call void {{.*}} @__kmpc_fork_call
635 // CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]
637 // Outlined function.
638 // CHECK: define internal void @[[OUTLINED]]
640 // Private reduction variable and its initialization.
641 // CHECK: %[[PRIVATE:.+]] = alloca float
642 // CHECK: store float 0.000000e+00, ptr %[[PRIVATE]]
644 // Call to the reduction function.
645 // CHECK: call i32 @__kmpc_reduce
646 // CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]
649 // CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]
650 // CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL]]
652 // Non-atomic reduction:
654 // CHECK: call void @__kmpc_end_reduce
655 // CHECK: br label %[[FINALIZE:.+]]
657 // CHECK: [[FINALIZE]]:
658 // CHECK: call void @__kmpc_barrier
660 // Update of the private variable using the reduction region
661 // (the body block currently comes after all the other blocks).
662 // CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]
663 // CHECK: %[[UPDATED:.+]] = fadd float 2.000000e+00, %[[PARTIAL]]
664 // CHECK: store float %[[UPDATED]], ptr %[[PRIVATE]]
666 // Reduction function.
667 // CHECK: define internal void @[[REDFUNC]]