Skip to content

Commit 3f2f95d

Browse files
committed
Generate non atomic expr before atomic.capture and fix tests
1 parent 1bfbe4c commit 3f2f95d

File tree

6 files changed

+37
-30
lines changed

6 files changed

+37
-30
lines changed

flang/lib/Lower/DirectivesCommon.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ static inline void genOmpAccAtomicUpdateStatement(
200200
mlir::Type varType, const Fortran::parser::Variable &assignmentStmtVariable,
201201
const Fortran::parser::Expr &assignmentStmtExpr,
202202
[[maybe_unused]] const AtomicListT *leftHandClauseList,
203-
[[maybe_unused]] const AtomicListT *rightHandClauseList) {
203+
[[maybe_unused]] const AtomicListT *rightHandClauseList,
204+
mlir::Operation *atomicCaptureOp = nullptr) {
204205
// Generate `omp.atomic.update` operation for atomic assignment statements
205206
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
206207
mlir::Location currentLocation = converter.getCurrentLocation();
@@ -240,9 +241,15 @@ static inline void genOmpAccAtomicUpdateStatement(
240241
assignmentStmtExpr.u);
241242
StatementContext nonAtomicStmtCtx;
242243
if (nonAtomicSubExpr) {
244+
// Generate non atomic part before all the atomic operations.
245+
auto insertionPoint = firOpBuilder.saveInsertionPoint();
246+
if (atomicCaptureOp)
247+
firOpBuilder.setInsertionPoint(atomicCaptureOp);
243248
mlir::Value nonAtomicVal = fir::getBase(converter.genExprValue(
244249
currentLocation, *nonAtomicSubExpr, nonAtomicStmtCtx));
245250
exprValueOverrides.try_emplace(nonAtomicSubExpr, nonAtomicVal);
251+
if (atomicCaptureOp)
252+
firOpBuilder.restoreInsertionPoint(insertionPoint);
246253
}
247254

248255
mlir::Operation *atomicUpdateOp = nullptr;
@@ -500,7 +507,7 @@ void genOmpAccAtomicCapture(Fortran::lower::AbstractConverter &converter,
500507
genOmpAccAtomicUpdateStatement<AtomicListT>(
501508
converter, stmt1RHSArg, stmt2VarType, stmt2Var, stmt2Expr,
502509
/*leftHandClauseList=*/nullptr,
503-
/*rightHandClauseList=*/nullptr);
510+
/*rightHandClauseList=*/nullptr, atomicCaptureOp);
504511
} else {
505512
// Atomic capture construct is of the form [capture-stmt, write-stmt]
506513
const Fortran::semantics::SomeExpr &fromExpr =
@@ -529,7 +536,7 @@ void genOmpAccAtomicCapture(Fortran::lower::AbstractConverter &converter,
529536
genOmpAccAtomicUpdateStatement<AtomicListT>(
530537
converter, stmt1LHSArg, stmt1VarType, stmt1Var, stmt1Expr,
531538
/*leftHandClauseList=*/nullptr,
532-
/*rightHandClauseList=*/nullptr);
539+
/*rightHandClauseList=*/nullptr, atomicCaptureOp);
533540
}
534541
firOpBuilder.setInsertionPointToEnd(&block);
535542
if constexpr (std::is_same<AtomicListT,

flang/test/Lower/OpenACC/acc-atomic-capture.f90

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ program acc_atomic_capture_test
77

88
!CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFEx"}
99
!CHECK: %[[Y:.*]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFEy"}
10+
!CHECK: %[[temp:.*]] = fir.load %[[X]] : !fir.ref<i32>
1011
!CHECK: acc.atomic.capture {
1112
!CHECK: acc.atomic.read %[[X]] = %[[Y]] : !fir.ref<i32>
1213
!CHECK: acc.atomic.update %[[Y]] : !fir.ref<i32> {
1314
!CHECK: ^bb0(%[[ARG:.*]]: i32):
14-
!CHECK: %[[temp:.*]] = fir.load %[[X]] : !fir.ref<i32>
1515
!CHECK: %[[result:.*]] = arith.addi %[[temp]], %[[ARG]] : i32
1616
!CHECK: acc.yield %[[result]] : i32
1717
!CHECK: }
@@ -23,10 +23,10 @@ program acc_atomic_capture_test
2323
!$acc end atomic
2424

2525

26+
!CHECK: %[[temp:.*]] = fir.load %[[X]] : !fir.ref<i32>
2627
!CHECK: acc.atomic.capture {
2728
!CHECK: acc.atomic.update %[[Y]] : !fir.ref<i32> {
2829
!CHECK: ^bb0(%[[ARG:.*]]: i32):
29-
!CHECK: %[[temp:.*]] = fir.load %[[X]] : !fir.ref<i32>
3030
!CHECK: %[[result:.*]] = arith.muli %[[temp]], %[[ARG]] : i32
3131
!CHECK: acc.yield %[[result]] : i32
3232
!CHECK: }
@@ -76,12 +76,12 @@ subroutine pointers_in_atomic_capture()
7676
!CHECK: %[[loaded_A_addr:.*]] = fir.box_addr %[[loaded_A]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
7777
!CHECK: %[[loaded_B:.*]] = fir.load %[[B]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
7878
!CHECK: %[[loaded_B_addr:.*]] = fir.box_addr %[[loaded_B]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
79-
!CHECK: acc.atomic.capture {
80-
!CHECK: acc.atomic.update %[[loaded_A_addr]] : !fir.ptr<i32> {
81-
!CHECK: ^bb0(%[[ARG:.*]]: i32):
8279
!CHECK: %[[PRIVATE_LOADED_B:.*]] = fir.load %[[B]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
8380
!CHECK: %[[PRIVATE_LOADED_B_addr:.*]] = fir.box_addr %[[PRIVATE_LOADED_B]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
8481
!CHECK: %[[loaded_value:.*]] = fir.load %[[PRIVATE_LOADED_B_addr]] : !fir.ptr<i32>
82+
!CHECK: acc.atomic.capture {
83+
!CHECK: acc.atomic.update %[[loaded_A_addr]] : !fir.ptr<i32> {
84+
!CHECK: ^bb0(%[[ARG:.*]]: i32):
8585
!CHECK: %[[result:.*]] = arith.addi %[[ARG]], %[[loaded_value]] : i32
8686
!CHECK: acc.yield %[[result]] : i32
8787
!CHECK: }

flang/test/Lower/OpenACC/acc-atomic-update-hlfir.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ subroutine sb
1414
!CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X_REF]] {uniq_name = "_QFsbEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
1515
!CHECK: %[[Y_REF:.*]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFsbEy"}
1616
!CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y_REF]] {uniq_name = "_QFsbEy"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
17+
!CHECK: %[[Y_VAL:.*]] = fir.load %[[Y_DECL]]#0 : !fir.ref<i32>
1718
!CHECK: acc.atomic.update %[[X_DECL]]#1 : !fir.ref<i32> {
1819
!CHECK: ^bb0(%[[ARG_X:.*]]: i32):
19-
!CHECK: %[[Y_VAL:.*]] = fir.load %[[Y_DECL]]#0 : !fir.ref<i32>
2020
!CHECK: %[[X_UPDATE_VAL:.*]] = arith.addi %[[ARG_X]], %[[Y_VAL]] : i32
2121
!CHECK: acc.yield %[[X_UPDATE_VAL]] : i32
2222
!CHECK: }

flang/test/Lower/OpenACC/acc-atomic-update.f90

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,25 @@ program acc_atomic_update_test
3131
!CHECK: %{{.*}} = fir.convert %[[D_ADDR]] : (!fir.ref<i32>) -> !fir.ptr<i32>
3232
!CHECK: fir.store {{.*}} to %[[B_ADDR]] : !fir.ref<!fir.ptr<i32>>
3333
!CHECK: %[[LOADED_A:.*]] = fir.load %[[A_ADDR]] : !fir.ref<!fir.ptr<i32>>
34+
!CHECK: %[[LOADED_B:.*]] = fir.load %[[B_ADDR]] : !fir.ref<!fir.ptr<i32>>
35+
!CHECK: %{{.*}} = fir.load %[[LOADED_B]] : !fir.ptr<i32>
3436
!CHECK: acc.atomic.update %[[LOADED_A]] : !fir.ptr<i32> {
3537
!CHECK: ^bb0(%[[ARG:.*]]: i32):
36-
!CHECK: %[[LOADED_B:.*]] = fir.load %[[B_ADDR]] : !fir.ref<!fir.ptr<i32>>
37-
!CHECK: %{{.*}} = fir.load %[[LOADED_B]] : !fir.ptr<i32>
3838
!CHECK: %[[RESULT:.*]] = arith.addi %[[ARG]], %{{.*}} : i32
3939
!CHECK: acc.yield %[[RESULT]] : i32
4040
!CHECK: }
4141
!$acc atomic update
4242
a = a + b
4343

44+
!CHECK: {{.*}} = arith.constant 1 : i32
4445
!CHECK: acc.atomic.update %[[Y]] : !fir.ref<i32> {
4546
!CHECK: ^bb0(%[[ARG:.*]]: i32):
46-
!CHECK: {{.*}} = arith.constant 1 : i32
4747
!CHECK: %[[RESULT:.*]] = arith.addi %[[ARG]], {{.*}} : i32
4848
!CHECK: acc.yield %[[RESULT]] : i32
4949
!CHECK: }
50+
!CHECK: %[[LOADED_X:.*]] = fir.load %[[X]] : !fir.ref<i32>
5051
!CHECK: acc.atomic.update %[[Z]] : !fir.ref<i32> {
5152
!CHECK: ^bb0(%[[ARG:.*]]: i32):
52-
!CHECK: %[[LOADED_X:.*]] = fir.load %[[X]] : !fir.ref<i32>
5353
!CHECK: %[[RESULT:.*]] = arith.muli %[[LOADED_X]], %[[ARG]] : i32
5454
!CHECK: acc.yield %[[RESULT]] : i32
5555
!CHECK: }
@@ -58,10 +58,10 @@ program acc_atomic_update_test
5858
!$acc atomic update
5959
z = x * z
6060

61+
!CHECK: %[[C1_VAL:.*]] = arith.constant 1 : i32
6162
!CHECK: acc.atomic.update %[[I1]] : !fir.ref<i8> {
6263
!CHECK: ^bb0(%[[VAL:.*]]: i8):
6364
!CHECK: %[[CVT_VAL:.*]] = fir.convert %[[VAL]] : (i8) -> i32
64-
!CHECK: %[[C1_VAL:.*]] = arith.constant 1 : i32
6565
!CHECK: %[[ADD_VAL:.*]] = arith.addi %[[CVT_VAL]], %[[C1_VAL]] : i32
6666
!CHECK: %[[UPDATED_VAL:.*]] = fir.convert %[[ADD_VAL]] : (i32) -> i8
6767
!CHECK: acc.yield %[[UPDATED_VAL]] : i8

flang/test/Lower/OpenMP/FIR/atomic-capture.f90

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ program OmpAtomicCapture
88

99
!CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFEx"}
1010
!CHECK: %[[Y:.*]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFEy"}
11+
!CHECK: %[[temp:.*]] = fir.load %[[X]] : !fir.ref<i32>
1112
!CHECK: omp.atomic.capture memory_order(release) {
1213
!CHECK: omp.atomic.read %[[X]] = %[[Y]] : !fir.ref<i32>
1314
!CHECK: omp.atomic.update %[[Y]] : !fir.ref<i32> {
1415
!CHECK: ^bb0(%[[ARG:.*]]: i32):
15-
!CHECK: %[[temp:.*]] = fir.load %[[X]] : !fir.ref<i32>
1616
!CHECK: %[[result:.*]] = arith.addi %[[temp]], %[[ARG]] : i32
1717
!CHECK: omp.yield(%[[result]] : i32)
1818
!CHECK: }
@@ -24,10 +24,10 @@ program OmpAtomicCapture
2424
!$omp end atomic
2525

2626

27+
!CHECK: %[[temp:.*]] = fir.load %[[X]] : !fir.ref<i32>
2728
!CHECK: omp.atomic.capture hint(uncontended) {
2829
!CHECK: omp.atomic.update %[[Y]] : !fir.ref<i32> {
2930
!CHECK: ^bb0(%[[ARG:.*]]: i32):
30-
!CHECK: %[[temp:.*]] = fir.load %[[X]] : !fir.ref<i32>
3131
!CHECK: %[[result:.*]] = arith.muli %[[temp]], %[[ARG]] : i32
3232
!CHECK: omp.yield(%[[result]] : i32)
3333
!CHECK: }
@@ -94,12 +94,12 @@ subroutine pointers_in_atomic_capture()
9494
!CHECK: %[[loaded_A_addr:.*]] = fir.box_addr %[[loaded_A]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
9595
!CHECK: %[[loaded_B:.*]] = fir.load %[[B]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
9696
!CHECK: %[[loaded_B_addr:.*]] = fir.box_addr %[[loaded_B]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
97-
!CHECK: omp.atomic.capture {
98-
!CHECK: omp.atomic.update %[[loaded_A_addr]] : !fir.ptr<i32> {
99-
!CHECK: ^bb0(%[[ARG:.*]]: i32):
10097
!CHECK: %[[PRIVATE_LOADED_B:.*]] = fir.load %[[B]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
10198
!CHECK: %[[PRIVATE_LOADED_B_addr:.*]] = fir.box_addr %[[PRIVATE_LOADED_B]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
10299
!CHECK: %[[loaded_value:.*]] = fir.load %[[PRIVATE_LOADED_B_addr]] : !fir.ptr<i32>
100+
!CHECK: omp.atomic.capture {
101+
!CHECK: omp.atomic.update %[[loaded_A_addr]] : !fir.ptr<i32> {
102+
!CHECK: ^bb0(%[[ARG:.*]]: i32):
103103
!CHECK: %[[result:.*]] = arith.addi %[[ARG]], %[[loaded_value]] : i32
104104
!CHECK: omp.yield(%[[result]] : i32)
105105
!CHECK: }

flang/test/Lower/OpenMP/FIR/atomic-update.f90

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,25 @@ program OmpAtomicUpdate
3232
!CHECK: %{{.*}} = fir.convert %[[D_ADDR]] : (!fir.ref<i32>) -> !fir.ptr<i32>
3333
!CHECK: fir.store {{.*}} to %[[B_ADDR]] : !fir.ref<!fir.ptr<i32>>
3434
!CHECK: %[[LOADED_A:.*]] = fir.load %[[A_ADDR]] : !fir.ref<!fir.ptr<i32>>
35+
!CHECK: %[[LOADED_B:.*]] = fir.load %[[B_ADDR]] : !fir.ref<!fir.ptr<i32>>
36+
!CHECK: %{{.*}} = fir.load %[[LOADED_B]] : !fir.ptr<i32>
3537
!CHECK: omp.atomic.update %[[LOADED_A]] : !fir.ptr<i32> {
3638
!CHECK: ^bb0(%[[ARG:.*]]: i32):
37-
!CHECK: %[[LOADED_B:.*]] = fir.load %[[B_ADDR]] : !fir.ref<!fir.ptr<i32>>
38-
!CHECK: %{{.*}} = fir.load %[[LOADED_B]] : !fir.ptr<i32>
3939
!CHECK: %[[RESULT:.*]] = arith.addi %[[ARG]], %{{.*}} : i32
4040
!CHECK: omp.yield(%[[RESULT]] : i32)
4141
!CHECK: }
4242
!$omp atomic update
4343
a = a + b
4444

45+
!CHECK: {{.*}} = arith.constant 1 : i32
4546
!CHECK: omp.atomic.update %[[Y]] : !fir.ref<i32> {
4647
!CHECK: ^bb0(%[[ARG:.*]]: i32):
47-
!CHECK: {{.*}} = arith.constant 1 : i32
4848
!CHECK: %[[RESULT:.*]] = arith.addi %[[ARG]], {{.*}} : i32
4949
!CHECK: omp.yield(%[[RESULT]] : i32)
5050
!CHECK: }
51+
!CHECK: %[[LOADED_X:.*]] = fir.load %[[X]] : !fir.ref<i32>
5152
!CHECK: omp.atomic.update %[[Z]] : !fir.ref<i32> {
5253
!CHECK: ^bb0(%[[ARG:.*]]: i32):
53-
!CHECK: %[[LOADED_X:.*]] = fir.load %[[X]] : !fir.ref<i32>
5454
!CHECK: %[[RESULT:.*]] = arith.muli %[[LOADED_X]], %[[ARG]] : i32
5555
!CHECK: omp.yield(%[[RESULT]] : i32)
5656
!CHECK: }
@@ -59,9 +59,9 @@ program OmpAtomicUpdate
5959
!$omp atomic update
6060
z = x * z
6161

62+
!CHECK: %{{.*}} = arith.constant 1 : i32
6263
!CHECK: omp.atomic.update memory_order(relaxed) hint(uncontended) %[[X]] : !fir.ref<i32> {
6364
!CHECK: ^bb0(%[[ARG:.*]]: i32):
64-
!CHECK: %{{.*}} = arith.constant 1 : i32
6565
!CHECK: %[[RESULT:.*]] = arith.subi %[[ARG]], {{.*}} : i32
6666
!CHECK: omp.yield(%[[RESULT]] : i32)
6767
!CHECK: }
@@ -75,9 +75,9 @@ program OmpAtomicUpdate
7575
!CHECK: %[[RESULT:.*]] = arith.select %{{.*}}, %{{.*}}, %[[LOADED_Z]] : i32
7676
!CHECK: omp.yield(%[[RESULT]] : i32)
7777
!CHECK: }
78+
!CHECK: %[[LOADED_X:.*]] = fir.load %[[X]] : !fir.ref<i32>
7879
!CHECK: omp.atomic.update memory_order(relaxed) hint(contended) %[[Z]] : !fir.ref<i32> {
7980
!CHECK: ^bb0(%[[ARG:.*]]: i32):
80-
!CHECK: %[[LOADED_X:.*]] = fir.load %[[X]] : !fir.ref<i32>
8181
!CHECK: %[[RESULT:.*]] = arith.addi %[[ARG]], %[[LOADED_X]] : i32
8282
!CHECK: omp.yield(%[[RESULT]] : i32)
8383
!CHECK: }
@@ -88,15 +88,15 @@ program OmpAtomicUpdate
8888
!$omp atomic relaxed hint(omp_sync_hint_contended)
8989
z = z + x
9090

91+
!CHECK: %{{.*}} = arith.constant 10 : i32
9192
!CHECK: omp.atomic.update memory_order(release) hint(contended) %[[Z]] : !fir.ref<i32> {
9293
!CHECK: ^bb0(%[[ARG:.*]]: i32):
93-
!CHECK: %{{.*}} = arith.constant 10 : i32
9494
!CHECK: %[[RESULT:.*]] = arith.muli {{.*}}, %[[ARG]] : i32
9595
!CHECK: omp.yield(%[[RESULT]] : i32)
9696
!CHECK: }
97+
!CHECK: %[[LOADED_Z:.*]] = fir.load %[[Z]] : !fir.ref<i32>
9798
!CHECK: omp.atomic.update memory_order(release) hint(speculative) %[[X]] : !fir.ref<i32> {
9899
!CHECK: ^bb0(%[[ARG:.*]]: i32):
99-
!CHECK: %[[LOADED_Z:.*]] = fir.load %[[Z]] : !fir.ref<i32>
100100
!CHECK: %[[RESULT:.*]] = arith.divsi %[[ARG]], %[[LOADED_Z]] : i32
101101
!CHECK: omp.yield(%[[RESULT]] : i32)
102102
!CHECK: }
@@ -106,15 +106,15 @@ program OmpAtomicUpdate
106106
!$omp atomic hint(omp_lock_hint_speculative) update release
107107
x = x / z
108108

109+
!CHECK: %{{.*}} = arith.constant 10 : i32
109110
!CHECK: omp.atomic.update memory_order(seq_cst) hint(nonspeculative) %[[Y]] : !fir.ref<i32> {
110111
!CHECK: ^bb0(%[[ARG:.*]]: i32):
111-
!CHECK: %{{.*}} = arith.constant 10 : i32
112112
!CHECK: %[[RESULT:.*]] = arith.addi %{{.*}}, %[[ARG]] : i32
113113
!CHECK: omp.yield(%[[RESULT]] : i32)
114114
!CHECK: }
115+
!CHECK: %[[LOADED_Y:.*]] = fir.load %[[Y]] : !fir.ref<i32>
115116
!CHECK: omp.atomic.update memory_order(seq_cst) %[[Z]] : !fir.ref<i32> {
116117
!CHECK: ^bb0(%[[ARG:.*]]: i32):
117-
!CHECK: %[[LOADED_Y:.*]] = fir.load %[[Y]] : !fir.ref<i32>
118118
!CHECK: %[[RESULT:.*]] = arith.addi %[[LOADED_Y]], %[[ARG]] : i32
119119
!CHECK: omp.yield(%[[RESULT]] : i32)
120120
!CHECK: }
@@ -123,10 +123,10 @@ program OmpAtomicUpdate
123123
!$omp atomic seq_cst update
124124
z = y + z
125125

126+
!CHECK: %[[C1_VAL:.*]] = arith.constant 1 : i32
126127
!CHECK: omp.atomic.update %[[I1]] : !fir.ref<i8> {
127128
!CHECK: ^bb0(%[[VAL:.*]]: i8):
128129
!CHECK: %[[CVT_VAL:.*]] = fir.convert %[[VAL]] : (i8) -> i32
129-
!CHECK: %[[C1_VAL:.*]] = arith.constant 1 : i32
130130
!CHECK: %[[ADD_VAL:.*]] = arith.addi %[[CVT_VAL]], %[[C1_VAL]] : i32
131131
!CHECK: %[[UPDATED_VAL:.*]] = fir.convert %[[ADD_VAL]] : (i32) -> i8
132132
!CHECK: omp.yield(%[[UPDATED_VAL]] : i8)

0 commit comments

Comments
 (0)