Skip to content

Commit e8795dd

Browse files
committed
[flang][OpenMP] Basic mapping of do concurrent ... reduce to OpenMP
Now that we have changes introduced by llvm#145837, mapping reductions from `do concurrent` to OpenMP is almost trivial. This PR adds such mapping. PR stack: - llvm#145837 - llvm#146025 - llvm#146028 - llvm#146033 (this one)
1 parent 8dc7ceb commit e8795dd

File tree

4 files changed

+280
-27
lines changed

4 files changed

+280
-27
lines changed

flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,19 @@ class DoConcurrentConversion
453453
bool isComposite) const {
454454
mlir::omp::WsloopOperands wsloopClauseOps;
455455

456+
auto cloneFIRRegionToOMP = [&rewriter](mlir::Region &firRegion,
457+
mlir::Region &ompRegion) {
458+
if (!firRegion.empty()) {
459+
rewriter.cloneRegionBefore(firRegion, ompRegion, ompRegion.begin());
460+
auto firYield =
461+
mlir::cast<fir::YieldOp>(ompRegion.back().getTerminator());
462+
rewriter.setInsertionPoint(firYield);
463+
rewriter.create<mlir::omp::YieldOp>(firYield.getLoc(),
464+
firYield.getOperands());
465+
rewriter.eraseOp(firYield);
466+
}
467+
};
468+
456469
// For `local` (and `local_init`) opernads, emit corresponding `private`
457470
// clauses and attach these clauses to the workshare loop.
458471
if (!loop.getLocalVars().empty())
@@ -467,50 +480,65 @@ class DoConcurrentConversion
467480
TODO(localizer.getLoc(),
468481
"local_init conversion is not supported yet");
469482

470-
auto oldIP = rewriter.saveInsertionPoint();
483+
mlir::OpBuilder::InsertionGuard guard(rewriter);
471484
rewriter.setInsertionPointAfter(localizer);
485+
472486
auto privatizer = rewriter.create<mlir::omp::PrivateClauseOp>(
473487
localizer.getLoc(), sym.getLeafReference().str() + ".omp",
474488
localizer.getTypeAttr().getValue(),
475489
mlir::omp::DataSharingClauseType::Private);
476490

477-
if (!localizer.getInitRegion().empty()) {
478-
rewriter.cloneRegionBefore(localizer.getInitRegion(),
479-
privatizer.getInitRegion(),
480-
privatizer.getInitRegion().begin());
481-
auto firYield = mlir::cast<fir::YieldOp>(
482-
privatizer.getInitRegion().back().getTerminator());
483-
rewriter.setInsertionPoint(firYield);
484-
rewriter.create<mlir::omp::YieldOp>(firYield.getLoc(),
485-
firYield.getOperands());
486-
rewriter.eraseOp(firYield);
487-
}
488-
489-
if (!localizer.getDeallocRegion().empty()) {
490-
rewriter.cloneRegionBefore(localizer.getDeallocRegion(),
491-
privatizer.getDeallocRegion(),
492-
privatizer.getDeallocRegion().begin());
493-
auto firYield = mlir::cast<fir::YieldOp>(
494-
privatizer.getDeallocRegion().back().getTerminator());
495-
rewriter.setInsertionPoint(firYield);
496-
rewriter.create<mlir::omp::YieldOp>(firYield.getLoc(),
497-
firYield.getOperands());
498-
rewriter.eraseOp(firYield);
499-
}
500-
501-
rewriter.restoreInsertionPoint(oldIP);
491+
cloneFIRRegionToOMP(localizer.getInitRegion(),
492+
privatizer.getInitRegion());
493+
cloneFIRRegionToOMP(localizer.getDeallocRegion(),
494+
privatizer.getDeallocRegion());
502495

503496
wsloopClauseOps.privateVars.push_back(op);
504497
wsloopClauseOps.privateSyms.push_back(
505498
mlir::SymbolRefAttr::get(privatizer));
506499
}
507500

501+
if (!loop.getReduceVars().empty()) {
502+
for (auto [op, byRef, sym, arg] : llvm::zip_equal(
503+
loop.getReduceVars(), loop.getReduceByrefAttr().asArrayRef(),
504+
loop.getReduceSymsAttr().getAsRange<mlir::SymbolRefAttr>(),
505+
loop.getRegionReduceArgs())) {
506+
auto firReducer =
507+
mlir::SymbolTable::lookupNearestSymbolFrom<fir::DeclareReductionOp>(
508+
loop, sym);
509+
510+
mlir::OpBuilder::InsertionGuard guard(rewriter);
511+
rewriter.setInsertionPointAfter(firReducer);
512+
513+
auto ompReducer = rewriter.create<mlir::omp::DeclareReductionOp>(
514+
firReducer.getLoc(), sym.getLeafReference().str() + ".omp",
515+
firReducer.getTypeAttr().getValue());
516+
517+
cloneFIRRegionToOMP(firReducer.getAllocRegion(),
518+
ompReducer.getAllocRegion());
519+
cloneFIRRegionToOMP(firReducer.getInitializerRegion(),
520+
ompReducer.getInitializerRegion());
521+
cloneFIRRegionToOMP(firReducer.getReductionRegion(),
522+
ompReducer.getReductionRegion());
523+
cloneFIRRegionToOMP(firReducer.getAtomicReductionRegion(),
524+
ompReducer.getAtomicReductionRegion());
525+
cloneFIRRegionToOMP(firReducer.getCleanupRegion(),
526+
ompReducer.getCleanupRegion());
527+
528+
wsloopClauseOps.reductionVars.push_back(op);
529+
wsloopClauseOps.reductionByref.push_back(byRef);
530+
wsloopClauseOps.reductionSyms.push_back(
531+
mlir::SymbolRefAttr::get(ompReducer));
532+
}
533+
}
534+
508535
auto wsloopOp =
509536
rewriter.create<mlir::omp::WsloopOp>(loop.getLoc(), wsloopClauseOps);
510537
wsloopOp.setComposite(isComposite);
511538

512539
Fortran::common::openmp::EntryBlockArgs wsloopArgs;
513540
wsloopArgs.priv.vars = wsloopClauseOps.privateVars;
541+
wsloopArgs.reduction.vars = wsloopClauseOps.reductionVars;
514542
Fortran::common::openmp::genEntryBlock(rewriter, wsloopArgs,
515543
wsloopOp.getRegion());
516544

@@ -534,7 +562,8 @@ class DoConcurrentConversion
534562
clauseOps.loopLowerBounds.size())))
535563
rewriter.replaceAllUsesWith(loopNestArg, wsloopArg);
536564

537-
for (unsigned i = 0; i < loop.getLocalVars().size(); ++i)
565+
for (unsigned i = 0;
566+
i < loop.getLocalVars().size() + loop.getReduceVars().size(); ++i)
538567
loopNestOp.getRegion().eraseArgument(clauseOps.loopLowerBounds.size());
539568

540569
return loopNestOp;
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Tests mapping reductions from fir to OpenMP.
2+
3+
// RUN: fir-opt --omp-do-concurrent-conversion="map-to=host" %s | FileCheck %s
4+
5+
fir.declare_reduction @add_reduction_i32 : i32 init {
6+
^bb0(%arg0: i32):
7+
%c0_i32 = arith.constant 0 : i32
8+
fir.yield(%c0_i32 : i32)
9+
} combiner {
10+
^bb0(%arg0: i32, %arg1: i32):
11+
%0 = arith.addi %arg0, %arg1 : i32
12+
fir.yield(%0 : i32)
13+
}
14+
15+
func.func @_QPdo_concurrent_reduce() {
16+
%3 = fir.alloca i32 {bindc_name = "s", uniq_name = "_QFdo_concurrent_reduceEs"}
17+
%4:2 = hlfir.declare %3 {uniq_name = "_QFdo_concurrent_reduceEs"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
18+
%c1 = arith.constant 1 : index
19+
fir.do_concurrent {
20+
%7 = fir.alloca i32 {bindc_name = "i"}
21+
%8:2 = hlfir.declare %7 {uniq_name = "_QFdo_concurrent_reduceEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
22+
fir.do_concurrent.loop (%arg0) = (%c1) to (%c1) step (%c1) reduce(@add_reduction_i32 #fir.reduce_attr<add> %4#0 -> %arg1 : !fir.ref<i32>) {
23+
%9 = fir.convert %arg0 : (index) -> i32
24+
fir.store %9 to %8#0 : !fir.ref<i32>
25+
%10:2 = hlfir.declare %arg1 {uniq_name = "_QFdo_concurrent_reduceEs"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
26+
%11 = fir.load %10#0 : !fir.ref<i32>
27+
%c1_i32_0 = arith.constant 1 : i32
28+
%12 = arith.addi %11, %c1_i32_0 : i32
29+
hlfir.assign %12 to %10#0 : i32, !fir.ref<i32>
30+
}
31+
}
32+
return
33+
}
34+
35+
// CHECK-LABEL: omp.declare_reduction @add_reduction_i32.omp : i32 init {
36+
// CHECK: ^bb0(%[[VAL_0:.*]]: i32):
37+
// CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32
38+
// CHECK: omp.yield(%[[VAL_1]] : i32)
39+
40+
// CHECK-LABEL: } combiner {
41+
// CHECK: ^bb0(%[[VAL_0:.*]]: i32, %[[VAL_1:.*]]: i32):
42+
// CHECK: %[[VAL_2:.*]] = arith.addi %[[VAL_0]], %[[VAL_1]] : i32
43+
// CHECK: omp.yield(%[[VAL_2]] : i32)
44+
// CHECK: }
45+
46+
// CHECK-LABEL: func.func @_QPdo_concurrent_reduce() {
47+
// CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "i"}
48+
// CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFdo_concurrent_reduceEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
49+
// CHECK: %[[VAL_2:.*]] = fir.alloca i32 {bindc_name = "s", uniq_name = "_QFdo_concurrent_reduceEs"}
50+
// CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFdo_concurrent_reduceEs"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
51+
// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index
52+
// CHECK: omp.parallel {
53+
// CHECK: %[[VAL_5:.*]] = fir.alloca i32 {bindc_name = "i"}
54+
// CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] {uniq_name = "_QFdo_concurrent_reduceEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
55+
56+
// CHECK: omp.wsloop reduction(@add_reduction_i32.omp %[[VAL_3]]#0 -> %[[VAL_7:.*]] : !fir.ref<i32>) {
57+
// CHECK: omp.loop_nest (%[[VAL_8:.*]]) : index = (%[[VAL_4]]) to (%[[VAL_4]]) inclusive step (%[[VAL_4]]) {
58+
// CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (index) -> i32
59+
// CHECK: fir.store %[[VAL_9]] to %[[VAL_6]]#0 : !fir.ref<i32>
60+
// CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_7]] {uniq_name = "_QFdo_concurrent_reduceEs"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
61+
// CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_10]]#0 : !fir.ref<i32>
62+
// CHECK: %[[VAL_12:.*]] = arith.constant 1 : i32
63+
// CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_11]], %[[VAL_12]] : i32
64+
// CHECK: hlfir.assign %[[VAL_13]] to %[[VAL_10]]#0 : i32, !fir.ref<i32>
65+
// CHECK: omp.yield
66+
// CHECK: }
67+
// CHECK: }
68+
// CHECK: omp.terminator
69+
// CHECK: }
70+
71+
// CHECK: return
72+
// CHECK: }
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Tests mapping reductions from fir to OpenMP (all regions).
2+
3+
// RUN: fir-opt --omp-do-concurrent-conversion="map-to=host" %s | FileCheck %s
4+
5+
fir.declare_reduction @add_reduction_i32 : i32 init {
6+
^bb0(%arg0: i32):
7+
fir.yield(%arg0 : i32)
8+
} combiner {
9+
^bb0(%arg0: i32, %arg1: i32):
10+
fir.yield(%arg0 : i32)
11+
} atomic {
12+
^bb0(%arg0: !fir.ref<i32>, %arg1: !fir.ref<i32>):
13+
fir.yield(%arg0 : !fir.ref<i32>)
14+
} cleanup {
15+
^bb0(%arg0: i32):
16+
fir.yield
17+
}
18+
19+
func.func @_QPdo_concurrent_reduce() {
20+
%3 = fir.alloca i32 {bindc_name = "s", uniq_name = "_QFdo_concurrent_reduceEs"}
21+
%4:2 = hlfir.declare %3 {uniq_name = "_QFdo_concurrent_reduceEs"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
22+
%c1 = arith.constant 1 : index
23+
fir.do_concurrent {
24+
%7 = fir.alloca i32 {bindc_name = "i"}
25+
%8:2 = hlfir.declare %7 {uniq_name = "_QFdo_concurrent_reduceEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
26+
fir.do_concurrent.loop (%arg0) = (%c1) to (%c1) step (%c1) reduce(@add_reduction_i32 #fir.reduce_attr<add> %4#0 -> %arg1 : !fir.ref<i32>) {
27+
%9 = fir.convert %arg0 : (index) -> i32
28+
fir.store %9 to %8#0 : !fir.ref<i32>
29+
}
30+
}
31+
return
32+
}
33+
34+
// CHECK-LABEL: omp.declare_reduction @add_reduction_i32.omp : i32 init {
35+
// CHECK: ^bb0(%[[VAL_0:.*]]: i32):
36+
// CHECK: omp.yield(%[[VAL_0]] : i32)
37+
38+
// CHECK-LABEL: } combiner {
39+
// CHECK: ^bb0(%[[VAL_0:.*]]: i32, %[[VAL_1:.*]]: i32):
40+
// CHECK: omp.yield(%[[VAL_0]] : i32)
41+
42+
// CHECK-LABEL: } atomic {
43+
// CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>, %[[VAL_1:.*]]: !fir.ref<i32>):
44+
// CHECK: omp.yield(%[[VAL_0]] : !fir.ref<i32>)
45+
46+
// CHECK-LABEL: } cleanup {
47+
// CHECK: ^bb0(%[[VAL_0:.*]]: i32):
48+
// CHECK: omp.yield
49+
// CHECK: }
50+
51+
// CHECK-LABEL: func.func @_QPdo_concurrent_reduce() {
52+
// CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "i"}
53+
// CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFdo_concurrent_reduceEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
54+
// CHECK: %[[VAL_2:.*]] = fir.alloca i32 {bindc_name = "s", uniq_name = "_QFdo_concurrent_reduceEs"}
55+
// CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFdo_concurrent_reduceEs"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
56+
// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index
57+
// CHECK: omp.parallel {
58+
// CHECK: %[[VAL_5:.*]] = fir.alloca i32 {bindc_name = "i"}
59+
// CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] {uniq_name = "_QFdo_concurrent_reduceEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
60+
// CHECK: omp.wsloop reduction(@add_reduction_i32.omp %[[VAL_3]]#0 -> %[[VAL_7:.*]] : !fir.ref<i32>) {
61+
// CHECK: omp.loop_nest (%[[VAL_8:.*]]) : index = (%[[VAL_4]]) to (%[[VAL_4]]) inclusive step (%[[VAL_4]]) {
62+
// CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (index) -> i32
63+
// CHECK: fir.store %[[VAL_9]] to %[[VAL_6]]#0 : !fir.ref<i32>
64+
// CHECK: omp.yield
65+
// CHECK: }
66+
// CHECK: }
67+
// CHECK: omp.terminator
68+
// CHECK: }
69+
// CHECK: return
70+
// CHECK: }
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Tests mapping reductions and local from fir to OpenMP.
2+
3+
// RUN: fir-opt --omp-do-concurrent-conversion="map-to=host" %s | FileCheck %s
4+
5+
fir.declare_reduction @add_reduction_i32 : i32 init {
6+
^bb0(%arg0: i32):
7+
%c0_i32 = arith.constant 0 : i32
8+
fir.yield(%c0_i32 : i32)
9+
} combiner {
10+
^bb0(%arg0: i32, %arg1: i32):
11+
%0 = arith.addi %arg0, %arg1 : i32
12+
fir.yield(%0 : i32)
13+
}
14+
fir.local {type = local} @_QFdo_concurrent_reduceEl_private_i32 : i32
15+
func.func @_QPdo_concurrent_reduce() {
16+
%3 = fir.alloca i32 {bindc_name = "l", uniq_name = "_QFdo_concurrent_reduceEl"}
17+
%4:2 = hlfir.declare %3 {uniq_name = "_QFdo_concurrent_reduceEl"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
18+
%5 = fir.alloca i32 {bindc_name = "s", uniq_name = "_QFdo_concurrent_reduceEs"}
19+
%6:2 = hlfir.declare %5 {uniq_name = "_QFdo_concurrent_reduceEs"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
20+
%c1 = arith.constant 1 : index
21+
fir.do_concurrent {
22+
%9 = fir.alloca i32 {bindc_name = "i"}
23+
%10:2 = hlfir.declare %9 {uniq_name = "_QFdo_concurrent_reduceEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
24+
fir.do_concurrent.loop (%arg0) = (%c1) to (%c1) step (%c1) local(@_QFdo_concurrent_reduceEl_private_i32 %4#0 -> %arg1 : !fir.ref<i32>) reduce(@add_reduction_i32 #fir.reduce_attr<add> %6#0 -> %arg2 : !fir.ref<i32>) {
25+
%11 = fir.convert %arg0 : (index) -> i32
26+
fir.store %11 to %10#0 : !fir.ref<i32>
27+
%12:2 = hlfir.declare %arg1 {uniq_name = "_QFdo_concurrent_reduceEl"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
28+
%13:2 = hlfir.declare %arg2 {uniq_name = "_QFdo_concurrent_reduceEs"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
29+
%c1_i32_0 = arith.constant 1 : i32
30+
hlfir.assign %c1_i32_0 to %12#0 : i32, !fir.ref<i32>
31+
%14 = fir.load %13#0 : !fir.ref<i32>
32+
%15 = fir.load %12#0 : !fir.ref<i32>
33+
%16 = arith.addi %14, %15 : i32
34+
hlfir.assign %16 to %13#0 : i32, !fir.ref<i32>
35+
}
36+
}
37+
return
38+
}
39+
40+
// CHECK-LABEL: omp.declare_reduction @add_reduction_i32.omp : i32 init {
41+
// CHECK: ^bb0(%[[VAL_0:.*]]: i32):
42+
// CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32
43+
// CHECK: omp.yield(%[[VAL_1]] : i32)
44+
45+
// CHECK-LABEL: } combiner {
46+
// CHECK: ^bb0(%[[VAL_0:.*]]: i32, %[[VAL_1:.*]]: i32):
47+
// CHECK: %[[VAL_2:.*]] = arith.addi %[[VAL_0]], %[[VAL_1]] : i32
48+
// CHECK: omp.yield(%[[VAL_2]] : i32)
49+
// CHECK: }
50+
51+
// CHECK: omp.private {type = private} @_QFdo_concurrent_reduceEl_private_i32.omp : i32
52+
53+
// CHECK-LABEL: func.func @_QPdo_concurrent_reduce() {
54+
// CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "i"}
55+
// CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFdo_concurrent_reduceEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
56+
// CHECK: %[[VAL_2:.*]] = fir.alloca i32 {bindc_name = "l", uniq_name = "_QFdo_concurrent_reduceEl"}
57+
// CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFdo_concurrent_reduceEl"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
58+
// CHECK: %[[VAL_4:.*]] = fir.alloca i32 {bindc_name = "s", uniq_name = "_QFdo_concurrent_reduceEs"}
59+
// CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {uniq_name = "_QFdo_concurrent_reduceEs"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
60+
// CHECK: %[[VAL_6:.*]] = arith.constant 1 : index
61+
// CHECK: omp.parallel {
62+
// CHECK: %[[VAL_7:.*]] = fir.alloca i32 {bindc_name = "i"}
63+
// CHECK: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_7]] {uniq_name = "_QFdo_concurrent_reduceEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
64+
// CHECK: omp.wsloop private(@_QFdo_concurrent_reduceEl_private_i32.omp %[[VAL_3]]#0 -> %[[VAL_9:.*]] : !fir.ref<i32>) reduction(@add_reduction_i32.omp %[[VAL_5]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) {
65+
// CHECK: omp.loop_nest (%[[VAL_11:.*]]) : index = (%[[VAL_6]]) to (%[[VAL_6]]) inclusive step (%[[VAL_6]]) {
66+
// CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (index) -> i32
67+
// CHECK: fir.store %[[VAL_12]] to %[[VAL_8]]#0 : !fir.ref<i32>
68+
// CHECK: %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_9]] {uniq_name = "_QFdo_concurrent_reduceEl"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
69+
// CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFdo_concurrent_reduceEs"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
70+
// CHECK: %[[VAL_15:.*]] = arith.constant 1 : i32
71+
// CHECK: hlfir.assign %[[VAL_15]] to %[[VAL_13]]#0 : i32, !fir.ref<i32>
72+
// CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_14]]#0 : !fir.ref<i32>
73+
// CHECK: %[[VAL_17:.*]] = fir.load %[[VAL_13]]#0 : !fir.ref<i32>
74+
// CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_16]], %[[VAL_17]] : i32
75+
// CHECK: hlfir.assign %[[VAL_18]] to %[[VAL_14]]#0 : i32, !fir.ref<i32>
76+
// CHECK: omp.yield
77+
// CHECK: }
78+
// CHECK: }
79+
// CHECK: omp.terminator
80+
// CHECK: }
81+
// CHECK: return
82+
// CHECK: }

0 commit comments

Comments
 (0)