@@ -414,7 +414,8 @@ static inline void genAtomicUpdateStatement(
414
414
Fortran::lower::AbstractConverter &converter, mlir::Value lhsAddr,
415
415
mlir::Type varType, const Fortran::parser::Variable &assignmentStmtVariable,
416
416
const Fortran::parser::Expr &assignmentStmtExpr, mlir::Location loc,
417
- mlir::Operation *atomicCaptureOp = nullptr ) {
417
+ mlir::Operation *atomicCaptureOp = nullptr ,
418
+ Fortran::lower::StatementContext *atomicCaptureStmtCtx = nullptr ) {
418
419
// Generate `atomic.update` operation for atomic assignment statements
419
420
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder ();
420
421
mlir::Location currentLocation = converter.getCurrentLocation ();
@@ -494,15 +495,24 @@ static inline void genAtomicUpdateStatement(
494
495
},
495
496
assignmentStmtExpr.u );
496
497
Fortran::lower::StatementContext nonAtomicStmtCtx;
498
+ Fortran::lower::StatementContext *stmtCtxPtr = &nonAtomicStmtCtx;
497
499
if (!nonAtomicSubExprs.empty ()) {
498
500
// Generate non atomic part before all the atomic operations.
499
501
auto insertionPoint = firOpBuilder.saveInsertionPoint ();
500
- if (atomicCaptureOp)
502
+ if (atomicCaptureOp) {
503
+ assert (atomicCaptureStmtCtx && " must specify statement context" );
501
504
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
+ }
502
512
mlir::Value nonAtomicVal;
503
513
for (auto *nonAtomicSubExpr : nonAtomicSubExprs) {
504
514
nonAtomicVal = fir::getBase (converter.genExprValue (
505
- currentLocation, *nonAtomicSubExpr, nonAtomicStmtCtx ));
515
+ currentLocation, *nonAtomicSubExpr, *stmtCtxPtr ));
506
516
exprValueOverrides.try_emplace (nonAtomicSubExpr, nonAtomicVal);
507
517
}
508
518
if (atomicCaptureOp)
@@ -650,7 +660,7 @@ void genAtomicCapture(Fortran::lower::AbstractConverter &converter,
650
660
genAtomicCaptureStatement (converter, stmt2LHSArg, stmt1LHSArg,
651
661
elementType, loc);
652
662
genAtomicUpdateStatement (converter, stmt2LHSArg, stmt2VarType, stmt2Var,
653
- stmt2Expr, loc, atomicCaptureOp);
663
+ stmt2Expr, loc, atomicCaptureOp, &stmtCtx );
654
664
} else {
655
665
// Atomic capture construct is of the form [capture-stmt, write-stmt]
656
666
firOpBuilder.setInsertionPoint (atomicCaptureOp);
@@ -670,13 +680,15 @@ void genAtomicCapture(Fortran::lower::AbstractConverter &converter,
670
680
*Fortran::semantics::GetExpr (stmt2Expr);
671
681
mlir::Type elementType = converter.genType (fromExpr);
672
682
genAtomicUpdateStatement (converter, stmt1LHSArg, stmt1VarType, stmt1Var,
673
- stmt1Expr, loc, atomicCaptureOp);
683
+ stmt1Expr, loc, atomicCaptureOp, &stmtCtx );
674
684
genAtomicCaptureStatement (converter, stmt1LHSArg, stmt2LHSArg, elementType,
675
685
loc);
676
686
}
677
687
firOpBuilder.setInsertionPointToEnd (&block);
678
688
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);
680
692
}
681
693
682
694
template <typename Op>
0 commit comments