@@ -2891,32 +2891,34 @@ static void genAtomicRead(lower::AbstractConverter &converter,
28912891 *semantics::GetExpr (assignmentStmtVariable), stmtCtx));
28922892
28932893 if (fromAddress.getType () != toAddress.getType ()) {
2894- // Emit an implicit cast.
2895- // Different yet compatible types on omp.atomic.read constitute valid
2896- // Fortran. The OMPIRBuilder will emit atomic instructions (on primitive
2897- // types) and
2898- // __atomic_load libcall (on complex type) without explicitly converting
2899- // between such compatible types, leading to execute issues. The
2900- // OMPIRBuilder relies on the frontend to resolve such inconsistencies
2901- // between omp.atomic.read operand types. Inconsistency between operand
2902- // types in omp.atomic.write are resolved through implicit casting by use of
2903- // typed assignment (i.e. `evaluate::Assignment`). However, use of typed
2904- // assignment in omp.atomic.read (of form `v = x`) leads to an unsafe,
2894+ // Emit an implicit cast. Different yet compatible types on
2895+ // omp.atomic.read constitute valid Fortran. The OMPIRBuilder will
2896+ // emit atomic instructions (on primitive types) and `__atomic_load`
2897+ // libcall (on complex type) without explicitly converting
2898+ // between such compatible types. The OMPIRBuilder relies on the
2899+ // frontend to resolve such inconsistencies between `omp.atomic.read `
2900+ // operand types. Similar inconsistencies between operand types in
2901+ // `omp.atomic.write` are resolved through implicit casting by use of typed
2902+ // assignment (i.e. `evaluate::Assignment`). However, use of typed
2903+ // assignment in `omp.atomic.read` (of form `v = x`) leads to an unsafe,
29052904 // non-atomic load of `x` into a temporary `alloca`, followed by an atomic
2906- // read of form `v = alloca`. Hence, perform a custom implicit cast.
2905+ // read of form `v = alloca`. Hence, it is needed to perform a custom
2906+ // implicit cast.
29072907
2908- // For an atomic read of form `v = x` that would (without implicit casting)
2908+ // An atomic read of form `v = x` would (without implicit casting)
29092909 // lower to `omp.atomic.read %v = %x : !fir.ref<type1>, !fir.ref<typ2>,
2910- // type2`, this implicit casting will generate the following FIR: %alloca =
2911- // fir.alloca type2
2912- // omp.atomic.read %alloca = %x : !fir.ref<type2>, !fir.ref<type2>,
2913- // type2 %load = fir.load %alloca : !fir.ref<type2> %cvt = fir.convert %load
2914- // : (type2) -> type1 fir.store %cvt to %v : !fir.ref<type1>
2910+ // type2`. This implicit casting will rather generate the following FIR:
2911+ //
2912+ // %alloca = fir.alloca type2
2913+ // omp.atomic.read %alloca = %x : !fir.ref<type2>, !fir.ref<type2>, type2
2914+ // %load = fir.load %alloca : !fir.ref<type2>
2915+ // %cvt = fir.convert %load: (type2) -> type1
2916+ // fir.store %cvt to %v : !fir.ref<type1>
29152917
29162918 // These sequence of operations is thread-safe since each thread allocates
29172919 // the `alloca` in its stack, and performs `%alloca = %x` atomically. Once
2918- // safely read, each thread performs the implicit cast on the local alloca,
2919- // and writes the final result to `%v`.
2920+ // safely read, each thread performs the implicit cast on the local
2921+ // `alloca`, and writes the final result to `%v`.
29202922 mlir::Type toType = fir::unwrapRefType (toAddress.getType ());
29212923 mlir::Type fromType = fir::unwrapRefType (fromAddress.getType ());
29222924 fir::FirOpBuilder &builder = converter.getFirOpBuilder ();
@@ -2932,7 +2934,6 @@ static void genAtomicRead(lower::AbstractConverter &converter,
29322934 if (fir::isa_complex (fromType) && !fir::isa_complex (toType)) {
29332935 // Emit an additional `ExtractValueOp` if `fromAddress` is of complex
29342936 // type, but `toAddress` is not.
2935-
29362937 auto extract = builder.create <fir::ExtractValueOp>(
29372938 loc, mlir::cast<mlir::ComplexType>(fromType).getElementType (), load,
29382939 builder.getArrayAttr (
0 commit comments