@@ -2816,7 +2816,8 @@ static void genAtomicUpdateStatement(
28162816 const parser::Expr &assignmentStmtExpr,
28172817 const parser::OmpAtomicClauseList *leftHandClauseList,
28182818 const parser::OmpAtomicClauseList *rightHandClauseList, mlir::Location loc,
2819- mlir::Operation *atomicCaptureOp = nullptr ) {
2819+ mlir::Operation *atomicCaptureOp = nullptr ,
2820+ lower::StatementContext *atomicCaptureStmtCtx = nullptr ) {
28202821 // Generate `atomic.update` operation for atomic assignment statements
28212822 fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder ();
28222823 mlir::Location currentLocation = converter.getCurrentLocation ();
@@ -2890,15 +2891,24 @@ static void genAtomicUpdateStatement(
28902891 },
28912892 assignmentStmtExpr.u );
28922893 lower::StatementContext nonAtomicStmtCtx;
2894+ lower::StatementContext *stmtCtxPtr = &nonAtomicStmtCtx;
28932895 if (!nonAtomicSubExprs.empty ()) {
28942896 // Generate non atomic part before all the atomic operations.
28952897 auto insertionPoint = firOpBuilder.saveInsertionPoint ();
2896- if (atomicCaptureOp)
2898+ if (atomicCaptureOp) {
2899+ assert (atomicCaptureStmtCtx && " must specify statement context" );
28972900 firOpBuilder.setInsertionPoint (atomicCaptureOp);
2901+ // Any clean-ups associated with the expression lowering
2902+ // must also be generated outside of the atomic update operation
2903+ // and after the atomic capture operation.
2904+ // The atomicCaptureStmtCtx will be finalized at the end
2905+ // of the atomic capture operation generation.
2906+ stmtCtxPtr = atomicCaptureStmtCtx;
2907+ }
28982908 mlir::Value nonAtomicVal;
28992909 for (auto *nonAtomicSubExpr : nonAtomicSubExprs) {
29002910 nonAtomicVal = fir::getBase (converter.genExprValue (
2901- currentLocation, *nonAtomicSubExpr, nonAtomicStmtCtx ));
2911+ currentLocation, *nonAtomicSubExpr, *stmtCtxPtr ));
29022912 exprValueOverrides.try_emplace (nonAtomicSubExpr, nonAtomicVal);
29032913 }
29042914 if (atomicCaptureOp)
@@ -3238,7 +3248,7 @@ static void genAtomicCapture(lower::AbstractConverter &converter,
32383248 genAtomicUpdateStatement (
32393249 converter, stmt2LHSArg, stmt2VarType, stmt2Var, stmt2Expr,
32403250 /* leftHandClauseList=*/ nullptr ,
3241- /* rightHandClauseList=*/ nullptr , loc, atomicCaptureOp);
3251+ /* rightHandClauseList=*/ nullptr , loc, atomicCaptureOp, &stmtCtx );
32423252 } else {
32433253 // Atomic capture construct is of the form [capture-stmt, write-stmt]
32443254 firOpBuilder.setInsertionPoint (atomicCaptureOp);
@@ -3284,7 +3294,7 @@ static void genAtomicCapture(lower::AbstractConverter &converter,
32843294 genAtomicUpdateStatement (
32853295 converter, stmt1LHSArg, stmt1VarType, stmt1Var, stmt1Expr,
32863296 /* leftHandClauseList=*/ nullptr ,
3287- /* rightHandClauseList=*/ nullptr , loc, atomicCaptureOp);
3297+ /* rightHandClauseList=*/ nullptr , loc, atomicCaptureOp, &stmtCtx );
32883298
32893299 if (stmt1VarType != stmt2VarType) {
32903300 mlir::Value alloca;
0 commit comments