Skip to content

Commit 79fb3b1

Browse files
committed
[flang][llvm][OpenMP][OpenACC] Add implicit casts to omp.atomic and acc.atomic
1 parent ddfd81b commit 79fb3b1

File tree

8 files changed

+214
-164
lines changed

8 files changed

+214
-164
lines changed

flang/include/flang/Lower/DirectivesCommon.h

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -386,9 +386,53 @@ void genOmpAccAtomicRead(Fortran::lower::AbstractConverter &converter,
386386
fir::getBase(converter.genExprAddr(fromExpr, stmtCtx));
387387
mlir::Value toAddress = fir::getBase(converter.genExprAddr(
388388
*Fortran::semantics::GetExpr(assignmentStmtVariable), stmtCtx));
389-
genOmpAccAtomicCaptureStatement(converter, fromAddress, toAddress,
390-
leftHandClauseList, rightHandClauseList,
391-
elementType, loc);
389+
if (fromAddress.getType() != toAddress.getType()) {
390+
// Emit an implicit cast
391+
mlir::Type toType = fir::unwrapRefType(toAddress.getType());
392+
mlir::Type fromType = fir::unwrapRefType(fromAddress.getType());
393+
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
394+
auto oldIP = builder.saveInsertionPoint();
395+
builder.setInsertionPointToStart(builder.getAllocaBlock());
396+
mlir::Value alloca = builder.create<fir::AllocaOp>(loc, fromType);
397+
builder.restoreInsertionPoint(oldIP);
398+
genOmpAccAtomicCaptureStatement(converter, fromAddress, alloca,
399+
leftHandClauseList, rightHandClauseList,
400+
elementType, loc);
401+
auto load = builder.create<fir::LoadOp>(loc, alloca);
402+
if (fir::isa_complex(fromType) && !fir::isa_complex(toType)) {
403+
// Emit an additional `ExtractValueOp` if `fromAddress` is of complex
404+
// type, but `toAddress` is not.
405+
auto extract = builder.create<fir::ExtractValueOp>(
406+
loc, mlir::cast<mlir::ComplexType>(fromType).getElementType(), load,
407+
builder.getArrayAttr(
408+
builder.getIntegerAttr(builder.getIndexType(), 0)));
409+
auto cvt = builder.create<fir::ConvertOp>(loc, toType, extract);
410+
builder.create<fir::StoreOp>(loc, cvt, toAddress);
411+
} else if (!fir::isa_complex(fromType) && fir::isa_complex(toType)) {
412+
// Emit an additional `InsertValueOp` if `toAddress` is of complex
413+
// type, but `fromAddress` is not.
414+
mlir::Value undef = builder.create<fir::UndefOp>(loc, toType);
415+
mlir::Type complexEleTy =
416+
mlir::cast<mlir::ComplexType>(toType).getElementType();
417+
mlir::Value cvt = builder.create<fir::ConvertOp>(loc, complexEleTy, load);
418+
mlir::Value zero = builder.createRealZeroConstant(loc, complexEleTy);
419+
mlir::Value idx0 = builder.create<fir::InsertValueOp>(
420+
loc, toType, undef, cvt,
421+
builder.getArrayAttr(
422+
builder.getIntegerAttr(builder.getIndexType(), 0)));
423+
mlir::Value idx1 = builder.create<fir::InsertValueOp>(
424+
loc, toType, idx0, zero,
425+
builder.getArrayAttr(
426+
builder.getIntegerAttr(builder.getIndexType(), 1)));
427+
builder.create<fir::StoreOp>(loc, idx1, toAddress);
428+
} else {
429+
auto cvt = builder.create<fir::ConvertOp>(loc, toType, load);
430+
builder.create<fir::StoreOp>(loc, cvt, toAddress);
431+
}
432+
} else
433+
genOmpAccAtomicCaptureStatement(converter, fromAddress, toAddress,
434+
leftHandClauseList, rightHandClauseList,
435+
elementType, loc);
392436
}
393437

394438
/// Processes an atomic construct with update clause.
@@ -481,6 +525,10 @@ void genOmpAccAtomicCapture(Fortran::lower::AbstractConverter &converter,
481525
mlir::Type stmt2VarType =
482526
fir::getBase(converter.genExprValue(assign2.lhs, stmtCtx)).getType();
483527

528+
// Check if implicit type is needed
529+
if (stmt1VarType != stmt2VarType)
530+
TODO(loc, "atomic capture requiring implicit type casts");
531+
484532
mlir::Operation *atomicCaptureOp = nullptr;
485533
if constexpr (std::is_same<AtomicListT,
486534
Fortran::parser::OmpAtomicClauseList>()) {
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
!RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenacc -o - %s 2>&1 | FileCheck %s
2+
3+
!CHECK: not yet implemented: atomic capture requiring implicit type casts
4+
subroutine capture_with_convert_f32_to_i32()
5+
implicit none
6+
integer :: k, v, i
7+
8+
k = 1
9+
v = 0
10+
11+
!$acc atomic capture
12+
v = k
13+
k = (i + 1) * 3.14
14+
!$acc end atomic
15+
end subroutine
16+
17+
subroutine capture_with_convert_i32_to_f64()
18+
real(8) :: x
19+
integer :: v
20+
x = 1.0
21+
v = 0
22+
!$acc atomic capture
23+
v = x
24+
x = v
25+
!$acc end atomic
26+
end subroutine capture_with_convert_i32_to_f64
27+
28+
subroutine capture_with_convert_f64_to_i32()
29+
integer :: x
30+
real(8) :: v
31+
x = 1
32+
v = 0
33+
!$acc atomic capture
34+
x = v * v
35+
v = x
36+
!$acc end atomic
37+
end subroutine capture_with_convert_f64_to_i32
38+
39+
subroutine capture_with_convert_i32_to_f32()
40+
real(4) :: x
41+
integer :: v
42+
x = 1.0
43+
v = 0
44+
!$acc atomic capture
45+
v = x
46+
x = x + v
47+
!$acc end atomic
48+
end subroutine capture_with_convert_i32_to_f32

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

Lines changed: 0 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -96,121 +96,6 @@ subroutine pointers_in_atomic_capture()
9696
end subroutine
9797

9898

99-
subroutine capture_with_convert_f32_to_i32()
100-
implicit none
101-
integer :: k, v, i
102-
103-
k = 1
104-
v = 0
105-
106-
!$acc atomic capture
107-
v = k
108-
k = (i + 1) * 3.14
109-
!$acc end atomic
110-
end subroutine
111-
112-
! CHECK-LABEL: func.func @_QPcapture_with_convert_f32_to_i32()
113-
! CHECK: %[[K:.*]] = fir.alloca i32 {bindc_name = "k", uniq_name = "_QFcapture_with_convert_f32_to_i32Ek"}
114-
! CHECK: %[[K_DECL:.*]]:2 = hlfir.declare %[[K]] {uniq_name = "_QFcapture_with_convert_f32_to_i32Ek"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
115-
! CHECK: %[[V:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFcapture_with_convert_f32_to_i32Ev"}
116-
! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcapture_with_convert_f32_to_i32Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
117-
! CHECK: %[[CST:.*]] = arith.constant 3.140000e+00 : f32
118-
! CHECK: %[[MUL:.*]] = arith.mulf %{{.*}}, %[[CST]] fastmath<contract> : f32
119-
! CHECK: %[[CONV:.*]] = fir.convert %[[MUL]] : (f32) -> i32
120-
! CHECK: acc.atomic.capture {
121-
! CHECK: acc.atomic.read %[[V_DECL]]#0 = %[[K_DECL]]#0 : !fir.ref<i32>, !fir.ref<i32>, i32
122-
! CHECK: acc.atomic.write %[[K_DECL]]#0 = %[[CONV]] : !fir.ref<i32>, i32
123-
! CHECK: }
124-
125-
subroutine capture_with_convert_i32_to_f64()
126-
real(8) :: x
127-
integer :: v
128-
x = 1.0
129-
v = 0
130-
!$acc atomic capture
131-
v = x
132-
x = v
133-
!$acc end atomic
134-
end subroutine capture_with_convert_i32_to_f64
135-
136-
! CHECK-LABEL: func.func @_QPcapture_with_convert_i32_to_f64()
137-
! CHECK: %[[V:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFcapture_with_convert_i32_to_f64Ev"}
138-
! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcapture_with_convert_i32_to_f64Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
139-
! CHECK: %[[X:.*]] = fir.alloca f64 {bindc_name = "x", uniq_name = "_QFcapture_with_convert_i32_to_f64Ex"}
140-
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcapture_with_convert_i32_to_f64Ex"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
141-
! CHECK: %[[CST:.*]] = arith.constant 1.000000e+00 : f64
142-
! CHECK: hlfir.assign %[[CST]] to %[[X_DECL]]#0 : f64, !fir.ref<f64>
143-
! CHECK: %c0_i32 = arith.constant 0 : i32
144-
! CHECK: hlfir.assign %c0_i32 to %[[V_DECL]]#0 : i32, !fir.ref<i32>
145-
! CHECK: %[[LOAD:.*]] = fir.load %[[V_DECL]]#0 : !fir.ref<i32>
146-
! CHECK: %[[CONV:.*]] = fir.convert %[[LOAD]] : (i32) -> f64
147-
! CHECK: acc.atomic.capture {
148-
! CHECK: acc.atomic.read %[[V_DECL]]#0 = %[[X_DECL]]#0 : !fir.ref<i32>, !fir.ref<f64>, f64
149-
! CHECK: acc.atomic.write %[[X_DECL]]#0 = %[[CONV]] : !fir.ref<f64>, f64
150-
! CHECK: }
151-
152-
subroutine capture_with_convert_f64_to_i32()
153-
integer :: x
154-
real(8) :: v
155-
x = 1
156-
v = 0
157-
!$acc atomic capture
158-
x = v * v
159-
v = x
160-
!$acc end atomic
161-
end subroutine capture_with_convert_f64_to_i32
162-
163-
! CHECK-LABEL: func.func @_QPcapture_with_convert_f64_to_i32()
164-
! CHECK: %[[V:.*]] = fir.alloca f64 {bindc_name = "v", uniq_name = "_QFcapture_with_convert_f64_to_i32Ev"}
165-
! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcapture_with_convert_f64_to_i32Ev"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
166-
! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFcapture_with_convert_f64_to_i32Ex"}
167-
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcapture_with_convert_f64_to_i32Ex"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
168-
! CHECK: %c1_i32 = arith.constant 1 : i32
169-
! CHECK: hlfir.assign %c1_i32 to %[[X_DECL]]#0 : i32, !fir.ref<i32>
170-
! CHECK: %[[CST:.*]] = arith.constant 0.000000e+00 : f64
171-
! CHECK: hlfir.assign %[[CST]] to %[[V_DECL]]#0 : f64, !fir.ref<f64>
172-
! CHECK: %[[LOAD:.*]] = fir.load %[[V_DECL]]#0 : !fir.ref<f64>
173-
! CHECK: acc.atomic.capture {
174-
! CHECK: acc.atomic.update %[[X_DECL]]#0 : !fir.ref<i32> {
175-
! CHECK: ^bb0(%arg0: i32):
176-
! CHECK: %[[MUL:.*]] = arith.mulf %[[LOAD]], %[[LOAD]] fastmath<contract> : f64
177-
! CHECK: %[[CONV:.*]] = fir.convert %[[MUL]] : (f64) -> i32
178-
! CHECK: acc.yield %[[CONV]] : i32
179-
! CHECK: }
180-
! CHECK: acc.atomic.read %[[V_DECL]]#0 = %[[X_DECL]]#0 : !fir.ref<f64>, !fir.ref<i32>, i32
181-
! CHECK: }
182-
183-
subroutine capture_with_convert_i32_to_f32()
184-
real(4) :: x
185-
integer :: v
186-
x = 1.0
187-
v = 0
188-
!$acc atomic capture
189-
v = x
190-
x = x + v
191-
!$acc end atomic
192-
end subroutine capture_with_convert_i32_to_f32
193-
194-
! CHECK-LABEL: func.func @_QPcapture_with_convert_i32_to_f32()
195-
! CHECK: %[[V:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFcapture_with_convert_i32_to_f32Ev"}
196-
! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcapture_with_convert_i32_to_f32Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
197-
! CHECK: %[[X:.*]] = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFcapture_with_convert_i32_to_f32Ex"}
198-
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcapture_with_convert_i32_to_f32Ex"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
199-
! CHECK: %[[CST:.*]] = arith.constant 1.000000e+00 : f32
200-
! CHECK: hlfir.assign %[[CST]] to %[[X_DECL]]#0 : f32, !fir.ref<f32>
201-
! CHECK: %c0_i32 = arith.constant 0 : i32
202-
! CHECK: hlfir.assign %c0_i32 to %[[V_DECL]]#0 : i32, !fir.ref<i32>
203-
! CHECK: %[[LOAD:.*]] = fir.load %[[V_DECL]]#0 : !fir.ref<i32>
204-
! CHECK: acc.atomic.capture {
205-
! CHECK: acc.atomic.read %[[V_DECL]]#0 = %[[X_DECL]]#0 : !fir.ref<i32>, !fir.ref<f32>, f32
206-
! CHECK: acc.atomic.update %[[X_DECL]]#0 : !fir.ref<f32> {
207-
! CHECK: ^bb0(%arg0: f32):
208-
! CHECK: %[[CONV:.*]] = fir.convert %[[LOAD]] : (i32) -> f32
209-
! CHECK: %[[ADD:.*]] = arith.addf %arg0, %[[CONV]] fastmath<contract> : f32
210-
! CHECK: acc.yield %[[ADD]] : f32
211-
! CHECK: }
212-
! CHECK: }
213-
21499
subroutine array_ref_in_atomic_capture1
215100
integer :: x(10), v
216101
!$acc atomic capture

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,11 @@ subroutine atomic_read_with_cast()
5151
end
5252

5353
! CHECK-LABEL: func.func @_QPatomic_read_with_cast() {
54+
! CHECK: %[[ALLOCA:.*]] = fir.alloca i32
5455
! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFatomic_read_with_castEx"}
5556
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFatomic_read_with_castEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
5657
! CHECK: %[[Y:.*]] = fir.alloca i64 {bindc_name = "y", uniq_name = "_QFatomic_read_with_castEy"}
5758
! CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]] {uniq_name = "_QFatomic_read_with_castEy"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
58-
! CHECK: acc.atomic.read %[[Y_DECL]]#0 = %[[X_DECL]]#0 : !fir.ref<i64>, !fir.ref<i32>, i32
59+
! CHECK: %[[LOAD:.*]] = fir.load %[[ALLOCA]] : !fir.ref<i32>
60+
! CHECK: %[[CVT:.*]] = fir.convert %[[LOAD]] : (i32) -> i64
61+
! CHECK: fir.store %[[CVT]] to %[[Y_DECL]]#0 : !fir.ref<i64>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
!RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
2+
3+
!CHECK: not yet implemented: atomic capture requiring implicit type casts
4+
subroutine capture_with_convert_f32_to_i32()
5+
implicit none
6+
integer :: k, v, i
7+
8+
k = 1
9+
v = 0
10+
11+
!$omp atomic capture
12+
v = k
13+
k = (i + 1) * 3.14
14+
!$omp end atomic
15+
end subroutine
16+
17+
subroutine capture_with_convert_i32_to_f64()
18+
real(8) :: x
19+
integer :: v
20+
x = 1.0
21+
v = 0
22+
!$omp atomic capture
23+
v = x
24+
x = v
25+
!$omp end atomic
26+
end subroutine capture_with_convert_i32_to_f64
27+
28+
subroutine capture_with_convert_f64_to_i32()
29+
integer :: x
30+
real(8) :: v
31+
x = 1
32+
v = 0
33+
!$omp atomic capture
34+
x = v
35+
v = x
36+
!$omp end atomic
37+
end subroutine capture_with_convert_f64_to_i32
38+
39+
subroutine capture_with_convert_i32_to_f32()
40+
real(4) :: x
41+
integer :: v
42+
x = 1.0
43+
v = 0
44+
!$omp atomic capture
45+
v = x
46+
x = x + v
47+
!$omp end atomic
48+
end subroutine capture_with_convert_i32_to_f32
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
! REQUIRES : openmp_runtime
2+
3+
! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
4+
5+
! CHECK: func.func @_QPatomic_implicit_cast_read() {
6+
subroutine atomic_implicit_cast_read
7+
! CHECK: %[[ALLOCA3:.*]] = fir.alloca complex<f32>
8+
! CHECK: %[[ALLOCA2:.*]] = fir.alloca complex<f32>
9+
! CHECK: %[[ALLOCA1:.*]] = fir.alloca i32
10+
! CHECK: %[[ALLOCA0:.*]] = fir.alloca f32
11+
12+
! CHECK: %[[M:.*]] = fir.alloca complex<f64> {bindc_name = "m", uniq_name = "_QFatomic_implicit_cast_readEm"}
13+
! CHECK: %[[M_DECL:.*]]:2 = hlfir.declare %[[M]] {uniq_name = "_QFatomic_implicit_cast_readEm"} : (!fir.ref<complex<f64>>) -> (!fir.ref<complex<f64>>, !fir.ref<complex<f64>>)
14+
! CHECK: %[[W:.*]] = fir.alloca complex<f32> {bindc_name = "w", uniq_name = "_QFatomic_implicit_cast_readEw"}
15+
! CHECK: %[[W_DECL:.*]]:2 = hlfir.declare %[[W]] {uniq_name = "_QFatomic_implicit_cast_readEw"} : (!fir.ref<complex<f32>>) -> (!fir.ref<complex<f32>>, !fir.ref<complex<f32>>)
16+
! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFatomic_implicit_cast_readEx"}
17+
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFatomic_implicit_cast_readEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
18+
! CHECK: %[[Y:.*]] = fir.alloca f32 {bindc_name = "y", uniq_name = "_QFatomic_implicit_cast_readEy"}
19+
! CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]] {uniq_name = "_QFatomic_implicit_cast_readEy"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
20+
! CHECK: %[[Z:.*]] = fir.alloca f64 {bindc_name = "z", uniq_name = "_QFatomic_implicit_cast_readEz"}
21+
! CHECK: %[[Z_DECL:.*]]:2 = hlfir.declare %[[Z]] {uniq_name = "_QFatomic_implicit_cast_readEz"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
22+
integer :: x
23+
real :: y
24+
double precision :: z
25+
complex :: w
26+
complex(8) :: m
27+
28+
! CHECK: omp.atomic.read %[[ALLOCA0:.*]] = %[[Y_DECL]]#0 : !fir.ref<f32>, !fir.ref<f32>, f32
29+
! CHECK: %[[LOAD:.*]] = fir.load %[[ALLOCA0]] : !fir.ref<f32>
30+
! CHECK: %[[CVT:.*]] = fir.convert %[[LOAD]] : (f32) -> i32
31+
! CHECK: fir.store %[[CVT]] to %[[X_DECL]]#0 : !fir.ref<i32>
32+
!$omp atomic read
33+
x = y
34+
35+
! CHECK: omp.atomic.read %[[ALLOCA1:.*]] = %[[X_DECL]]#0 : !fir.ref<i32>, !fir.ref<i32>, i32
36+
! CHECK: %[[LOAD:.*]] = fir.load %[[ALLOCA1]] : !fir.ref<i32>
37+
! CHECK: %[[CVT:.*]] = fir.convert %[[LOAD]] : (i32) -> f64
38+
! CHECK: fir.store %[[CVT]] to %[[Z_DECL]]#0 : !fir.ref<f64>
39+
!$omp atomic read
40+
z = x
41+
42+
! CHECK: omp.atomic.read %[[ALLOCA2:.*]] = %[[W_DECL]]#0 : !fir.ref<complex<f32>>, !fir.ref<complex<f32>>, complex<f32>
43+
! CHECK: %[[LOAD:.*]] = fir.load %[[ALLOCA2]] : !fir.ref<complex<f32>>
44+
! CHECK: %[[EXTRACT:.*]] = fir.extract_value %[[LOAD]], [0 : index] : (complex<f32>) -> f32
45+
! CHECK: %[[CVT:.*]] = fir.convert %[[EXTRACT]] : (f32) -> i32
46+
! CHECK: fir.store %[[CVT]] to %[[X_DECL]]#0 : !fir.ref<i32>
47+
!$omp atomic read
48+
x = w
49+
50+
! CHECK: omp.atomic.read %[[ALLOCA3:.*]] = %[[W_DECL]]#0 : !fir.ref<complex<f32>>, !fir.ref<complex<f32>>, complex<f32>
51+
! CHECK: %[[LOAD:.*]] = fir.load %[[ALLOCA3]] : !fir.ref<complex<f32>>
52+
! CHECK: %[[CVT:.*]] = fir.convert %[[LOAD]] : (complex<f32>) -> complex<f64>
53+
! CHECK: fir.store %[[CVT]] to %[[M_DECL]]#0 : !fir.ref<complex<f64>>
54+
!$omp atomic read
55+
m = w
56+
end subroutine

0 commit comments

Comments
 (0)