Skip to content

Commit 94df928

Browse files
committed
Fixed atomic handling for OpenACC.
1 parent 22c381e commit 94df928

File tree

3 files changed

+92
-7
lines changed

3 files changed

+92
-7
lines changed

flang/lib/Lower/OpenACC.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,8 @@ static inline void genAtomicUpdateStatement(
414414
Fortran::lower::AbstractConverter &converter, mlir::Value lhsAddr,
415415
mlir::Type varType, const Fortran::parser::Variable &assignmentStmtVariable,
416416
const Fortran::parser::Expr &assignmentStmtExpr, mlir::Location loc,
417-
mlir::Operation *atomicCaptureOp = nullptr) {
417+
mlir::Operation *atomicCaptureOp = nullptr,
418+
Fortran::lower::StatementContext *atomicCaptureStmtCtx = nullptr) {
418419
// Generate `atomic.update` operation for atomic assignment statements
419420
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
420421
mlir::Location currentLocation = converter.getCurrentLocation();
@@ -494,15 +495,24 @@ static inline void genAtomicUpdateStatement(
494495
},
495496
assignmentStmtExpr.u);
496497
Fortran::lower::StatementContext nonAtomicStmtCtx;
498+
Fortran::lower::StatementContext *stmtCtxPtr = &nonAtomicStmtCtx;
497499
if (!nonAtomicSubExprs.empty()) {
498500
// Generate non atomic part before all the atomic operations.
499501
auto insertionPoint = firOpBuilder.saveInsertionPoint();
500-
if (atomicCaptureOp)
502+
if (atomicCaptureOp) {
503+
assert(atomicCaptureStmtCtx && "must specify statement context");
501504
firOpBuilder.setInsertionPoint(atomicCaptureOp);
505+
// Any clean-ups associated with the expression lowering
506+
// must also be generated outside of the atomic update operation
507+
// and after the atomic capture operation.
508+
// The atomicCaptureStmtCtx will be finalized at the end
509+
// of the atomic capture operation generation.
510+
stmtCtxPtr = atomicCaptureStmtCtx;
511+
}
502512
mlir::Value nonAtomicVal;
503513
for (auto *nonAtomicSubExpr : nonAtomicSubExprs) {
504514
nonAtomicVal = fir::getBase(converter.genExprValue(
505-
currentLocation, *nonAtomicSubExpr, nonAtomicStmtCtx));
515+
currentLocation, *nonAtomicSubExpr, *stmtCtxPtr));
506516
exprValueOverrides.try_emplace(nonAtomicSubExpr, nonAtomicVal);
507517
}
508518
if (atomicCaptureOp)
@@ -650,7 +660,7 @@ void genAtomicCapture(Fortran::lower::AbstractConverter &converter,
650660
genAtomicCaptureStatement(converter, stmt2LHSArg, stmt1LHSArg,
651661
elementType, loc);
652662
genAtomicUpdateStatement(converter, stmt2LHSArg, stmt2VarType, stmt2Var,
653-
stmt2Expr, loc, atomicCaptureOp);
663+
stmt2Expr, loc, atomicCaptureOp, &stmtCtx);
654664
} else {
655665
// Atomic capture construct is of the form [capture-stmt, write-stmt]
656666
firOpBuilder.setInsertionPoint(atomicCaptureOp);
@@ -670,13 +680,15 @@ void genAtomicCapture(Fortran::lower::AbstractConverter &converter,
670680
*Fortran::semantics::GetExpr(stmt2Expr);
671681
mlir::Type elementType = converter.genType(fromExpr);
672682
genAtomicUpdateStatement(converter, stmt1LHSArg, stmt1VarType, stmt1Var,
673-
stmt1Expr, loc, atomicCaptureOp);
683+
stmt1Expr, loc, atomicCaptureOp, &stmtCtx);
674684
genAtomicCaptureStatement(converter, stmt1LHSArg, stmt2LHSArg, elementType,
675685
loc);
676686
}
677687
firOpBuilder.setInsertionPointToEnd(&block);
678688
firOpBuilder.create<mlir::acc::TerminatorOp>(loc);
679-
firOpBuilder.setInsertionPointToStart(&block);
689+
// The clean-ups associated with the statements inside the capture
690+
// construct must be generated after the AtomicCaptureOp.
691+
firOpBuilder.setInsertionPointAfter(atomicCaptureOp);
680692
}
681693

682694
template <typename Op>

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,3 +306,60 @@ end subroutine comp_ref_in_atomic_capture2
306306
! CHECK: }
307307
! CHECK: acc.atomic.read %[[V_DECL]]#0 = %[[C]] : !fir.ref<i32>, !fir.ref<i32>, i32
308308
! CHECK: }
309+
310+
! CHECK-LABEL: func.func @_QPatomic_capture_with_associate() {
311+
subroutine atomic_capture_with_associate
312+
interface
313+
integer function func(x)
314+
integer :: x
315+
end function func
316+
end interface
317+
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFatomic_capture_with_associateEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
318+
! CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFatomic_capture_with_associateEy"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
319+
! CHECK: %[[Z_DECL:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFatomic_capture_with_associateEz"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
320+
integer :: x, y, z
321+
322+
! CHECK: %[[VAL_10:.*]]:3 = hlfir.associate %{{.*}} {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)
323+
! CHECK: %[[VAL_11:.*]] = fir.call @_QPfunc(%[[VAL_10]]#0) fastmath<contract> : (!fir.ref<i32>) -> i32
324+
! CHECK: acc.atomic.capture {
325+
! CHECK: acc.atomic.read %[[X_DECL]]#0 = %[[Y_DECL]]#0 : !fir.ref<i32>, !fir.ref<i32>, i32
326+
! CHECK: acc.atomic.write %[[Y_DECL]]#0 = %[[VAL_11]] : !fir.ref<i32>, i32
327+
! CHECK: }
328+
! CHECK: hlfir.end_associate %[[VAL_10]]#1, %[[VAL_10]]#2 : !fir.ref<i32>, i1
329+
!$acc atomic capture
330+
x = y
331+
y = func(z + 1)
332+
!$acc end atomic
333+
334+
! CHECK: %[[VAL_15:.*]]:3 = hlfir.associate %{{.*}} {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)
335+
! CHECK: %[[VAL_16:.*]] = fir.call @_QPfunc(%[[VAL_15]]#0) fastmath<contract> : (!fir.ref<i32>) -> i32
336+
! CHECK: acc.atomic.capture {
337+
! CHECK: acc.atomic.update %[[Y_DECL]]#0 : !fir.ref<i32> {
338+
! CHECK: ^bb0(%[[VAL_17:.*]]: i32):
339+
! CHECK: %[[VAL_18:.*]] = arith.muli %[[VAL_16]], %[[VAL_17]] : i32
340+
! CHECK: acc.yield %[[VAL_18]] : i32
341+
! CHECK: }
342+
! CHECK: acc.atomic.read %[[X_DECL]]#0 = %[[Y_DECL]]#0 : !fir.ref<i32>, !fir.ref<i32>, i32
343+
! CHECK: }
344+
! CHECK: hlfir.end_associate %[[VAL_15]]#1, %[[VAL_15]]#2 : !fir.ref<i32>, i1
345+
!$acc atomic capture
346+
y = func(z + 1) * y
347+
x = y
348+
!$acc end atomic
349+
350+
! CHECK: %[[VAL_22:.*]]:3 = hlfir.associate %{{.*}} {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)
351+
! CHECK: %[[VAL_23:.*]] = fir.call @_QPfunc(%[[VAL_22]]#0) fastmath<contract> : (!fir.ref<i32>) -> i32
352+
! CHECK: acc.atomic.capture {
353+
! CHECK: acc.atomic.read %[[X_DECL]]#0 = %[[Y_DECL]]#0 : !fir.ref<i32>, !fir.ref<i32>, i32
354+
! CHECK: acc.atomic.update %[[Y_DECL]]#0 : !fir.ref<i32> {
355+
! CHECK: ^bb0(%[[VAL_24:.*]]: i32):
356+
! CHECK: %[[VAL_25:.*]] = arith.addi %[[VAL_23]], %[[VAL_24]] : i32
357+
! CHECK: acc.yield %[[VAL_25]] : i32
358+
! CHECK: }
359+
! CHECK: }
360+
! CHECK: hlfir.end_associate %[[VAL_22]]#1, %[[VAL_22]]#2 : !fir.ref<i32>, i1
361+
!$acc atomic capture
362+
x = y
363+
y = func(z + 1) + y
364+
!$acc end atomic
365+
end subroutine atomic_capture_with_associate

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
! RUN: %flang_fc1 -fopenacc -emit-hlfir %s -o - | FileCheck %s
44

55
program acc_atomic_update_test
6+
interface
7+
integer function func(x)
8+
integer :: x
9+
end function func
10+
end interface
611
integer :: x, y, z
712
integer, pointer :: a, b
813
integer, target :: c, d
@@ -67,7 +72,18 @@ program acc_atomic_update_test
6772
!$acc atomic
6873
i1 = i1 + 1
6974
!$acc end atomic
75+
76+
!CHECK: %[[VAL_44:.*]]:3 = hlfir.associate %{{.*}} {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)
77+
!CHECK: %[[VAL_45:.*]] = fir.call @_QPfunc(%[[VAL_44]]#0) fastmath<contract> : (!fir.ref<i32>) -> i32
78+
!CHECK: acc.atomic.update %[[X_DECL]]#0 : !fir.ref<i32> {
79+
!CHECK: ^bb0(%[[VAL_46:.*]]: i32):
80+
!CHECK: %[[VAL_47:.*]] = arith.addi %[[VAL_46]], %[[VAL_45]] : i32
81+
!CHECK: acc.yield %[[VAL_47]] : i32
82+
!CHECK: }
83+
!CHECK: hlfir.end_associate %[[VAL_44]]#1, %[[VAL_44]]#2 : !fir.ref<i32>, i1
84+
!$acc atomic update
85+
x = x + func(z + 1)
86+
!$acc end atomic
7087
!CHECK: return
7188
!CHECK: }
7289
end program acc_atomic_update_test
73-

0 commit comments

Comments
 (0)