Skip to content

Commit a63f915

Browse files
authored
[flang][openacc][openmp] Support implicit casting on the atomic interface (#114390)
ACCMP atomics do not support type conversion. Specifically, I have encountered semantically incorrect code for atomic reads. Example: ``` program main implicit none real(8) :: n integer :: x x = 1.0 !$acc atomic capture n = x x = n !$acc end atomic end program main ``` We have this error when compiling it with flang-new: `error: loc("rep.f90":6:9): expected three operations in atomic.capture region (one terminator, and two atomic ops)` Yet, in the following generated FIR code, we observe three issues. 1. `fir.convert` intrudes into the capture region. 2. An incorrect temporary (`%2`) is being updated instead of `n`. 3. If we allow `n` in place of `%2`, the operand types of `atomic.read` do not match. Introducing a `!fir.ref<i32> -> !fir.ref<f64>` conversion on `x` is inaccurate because we need to convert the value of `x`. ``` %2 = "fir.alloca"() <{in_type = i32, operandSegmentSizes = array<i32: 0, 0>}> : () -> !fir.ref<i32> %3 = "fir.alloca"() <{bindc_name = "n", in_type = f64, operandSegmentSizes = array<i32: 0, 0>, uniq_name = "_QFEn"}> : () -> !fir.ref<f64> %4:2 = "hlfir.declare"(%3) <{operandSegmentSizes = array<i32: 1, 0, 0, 0>, uniq_name = "_QFEn"}> : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>) %5 = "fir.alloca"() <{bindc_name = "x", in_type = i32, operandSegmentSizes = array<i32: 0, 0>, uniq_name = "_QFEx"}> : () -> !fir.ref<i32> %6:2 = "hlfir.declare"(%5) <{operandSegmentSizes = array<i32: 1, 0, 0, 0>, uniq_name = "_QFEx"}> : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) %7 = "arith.constant"() <{value = 1 : i32}> : () -> i32 "hlfir.assign"(%7, %6#0) : (i32, !fir.ref<i32>) -> () %8 = "fir.load"(%4#0) : (!fir.ref<f64>) -> f64 %9 = "fir.convert"(%8) : (f64) -> i32 "fir.store"(%9, %2) : (i32, !fir.ref<i32>) -> () %10 = "fir.load"(%6#0) : (!fir.ref<i32>) -> i32 %11 = "fir.convert"(%10) : (i32) -> f64 "acc.atomic.capture"() ({ "acc.atomic.read"(%2, %6#1) <{element_type = f64}> : (!fir.ref<i32>, !fir.ref<i32>) -> () %12 = "fir.convert"(%11) : (f64) -> i32 "acc.atomic.write"(%2, %12) : (!fir.ref<i32>, i32) -> () "acc.terminator"() : () -> () }) : () -> () ``` This PR updates `flang/lib/Lower/DirectivesCommon.h` to solve the issues by taking the following approaches (from top to bottom): 1. Move `fir.convert` for `atomic.write` out of the capture region. 2. Remove the `!fir.ref<i32> -> !fir.ref<f64>` conversion found in `genOmpAccAtomicRead`. 3. Eliminate unnecessary `genExprAddr` calls on the RHS, which create an invalid temporary for `x = 1.0`. 4. When generating a capture operation, refer to the original LHS instead of the type-casted RHS. Here, we have to allow for the cases where the operand types of `atomic.read` differ from one another. Thus, this PR also removes the `AllTypesMatch` trait from both `acc.atomic.read` and `omp.atomic.read`. The example code is converted as follows: ``` %0 = fir.alloca f64 {bindc_name = "n", uniq_name = "_QFEn"} %1:2 = hlfir.declare %0 {uniq_name = "_QFEn"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>) %2 = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFEx"} %3:2 = hlfir.declare %2 {uniq_name = "_QFEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) %c1_i32 = arith.constant 1 : i32 hlfir.assign %c1_i32 to %3#0 : i32, !fir.ref<i32> %4 = fir.load %1#0 : !fir.ref<f64> %5 = fir.convert %4 : (f64) -> i32 acc.atomic.capture { acc.atomic.read %1#1 = %3#1 : !fir.ref<f64>, !fir.ref<i32>, i32 acc.atomic.write %3#1 = %5 : !fir.ref<i32>, i32 } ``` Fixes #112911.
1 parent 92574b5 commit a63f915

File tree

17 files changed

+290
-211
lines changed

17 files changed

+290
-211
lines changed

flang/lib/Lower/DirectivesCommon.h

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,11 @@ static inline void genOmpAccAtomicWriteStatement(
179179
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
180180

181181
mlir::Type varType = fir::unwrapRefType(lhsAddr.getType());
182+
// Create a conversion outside the capture block.
183+
auto insertionPoint = firOpBuilder.saveInsertionPoint();
184+
firOpBuilder.setInsertionPointAfter(rhsExpr.getDefiningOp());
182185
rhsExpr = firOpBuilder.createConvert(loc, varType, rhsExpr);
186+
firOpBuilder.restoreInsertionPoint(insertionPoint);
183187

184188
processOmpAtomicTODO<AtomicListT>(varType, loc);
185189

@@ -410,10 +414,6 @@ void genOmpAccAtomicRead(Fortran::lower::AbstractConverter &converter,
410414
fir::getBase(converter.genExprAddr(fromExpr, stmtCtx));
411415
mlir::Value toAddress = fir::getBase(converter.genExprAddr(
412416
*Fortran::semantics::GetExpr(assignmentStmtVariable), stmtCtx));
413-
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
414-
if (fromAddress.getType() != toAddress.getType())
415-
fromAddress =
416-
builder.create<fir::ConvertOp>(loc, toAddress.getType(), fromAddress);
417417
genOmpAccAtomicCaptureStatement(converter, fromAddress, toAddress,
418418
leftHandClauseList, rightHandClauseList,
419419
elementType, loc);
@@ -497,23 +497,12 @@ void genOmpAccAtomicCapture(Fortran::lower::AbstractConverter &converter,
497497
// a `atomic.read`, `atomic.write`, or `atomic.update` operation
498498
// inside `atomic.capture`
499499
Fortran::lower::StatementContext stmtCtx;
500-
mlir::Value stmt1LHSArg, stmt1RHSArg, stmt2LHSArg, stmt2RHSArg;
501-
mlir::Type elementType;
502500
// LHS evaluations are common to all combinations of `atomic.capture`
503-
stmt1LHSArg = fir::getBase(converter.genExprAddr(assign1.lhs, stmtCtx));
504-
stmt2LHSArg = fir::getBase(converter.genExprAddr(assign2.lhs, stmtCtx));
501+
mlir::Value stmt1LHSArg =
502+
fir::getBase(converter.genExprAddr(assign1.lhs, stmtCtx));
503+
mlir::Value stmt2LHSArg =
504+
fir::getBase(converter.genExprAddr(assign2.lhs, stmtCtx));
505505

506-
// Operation specific RHS evaluations
507-
if (Fortran::semantics::checkForSingleVariableOnRHS(stmt1)) {
508-
// Atomic capture construct is of the form [capture-stmt, update-stmt] or
509-
// of the form [capture-stmt, write-stmt]
510-
stmt1RHSArg = fir::getBase(converter.genExprAddr(assign1.rhs, stmtCtx));
511-
stmt2RHSArg = fir::getBase(converter.genExprValue(assign2.rhs, stmtCtx));
512-
} else {
513-
// Atomic capture construct is of the form [update-stmt, capture-stmt]
514-
stmt1RHSArg = fir::getBase(converter.genExprValue(assign1.rhs, stmtCtx));
515-
stmt2RHSArg = fir::getBase(converter.genExprAddr(assign2.lhs, stmtCtx));
516-
}
517506
// Type information used in generation of `atomic.update` operation
518507
mlir::Type stmt1VarType =
519508
fir::getBase(converter.genExprValue(assign1.lhs, stmtCtx)).getType();
@@ -545,44 +534,46 @@ void genOmpAccAtomicCapture(Fortran::lower::AbstractConverter &converter,
545534
// Atomic capture construct is of the form [capture-stmt, update-stmt]
546535
const Fortran::semantics::SomeExpr &fromExpr =
547536
*Fortran::semantics::GetExpr(stmt1Expr);
548-
elementType = converter.genType(fromExpr);
537+
mlir::Type elementType = converter.genType(fromExpr);
549538
genOmpAccAtomicCaptureStatement<AtomicListT>(
550-
converter, stmt1RHSArg, stmt1LHSArg,
539+
converter, stmt2LHSArg, stmt1LHSArg,
551540
/*leftHandClauseList=*/nullptr,
552541
/*rightHandClauseList=*/nullptr, elementType, loc);
553542
genOmpAccAtomicUpdateStatement<AtomicListT>(
554-
converter, stmt1RHSArg, stmt2VarType, stmt2Var, stmt2Expr,
543+
converter, stmt2LHSArg, stmt2VarType, stmt2Var, stmt2Expr,
555544
/*leftHandClauseList=*/nullptr,
556545
/*rightHandClauseList=*/nullptr, loc, atomicCaptureOp);
557546
} else {
558547
// Atomic capture construct is of the form [capture-stmt, write-stmt]
548+
firOpBuilder.setInsertionPoint(atomicCaptureOp);
549+
mlir::Value stmt2RHSArg =
550+
fir::getBase(converter.genExprValue(assign2.rhs, stmtCtx));
551+
firOpBuilder.setInsertionPointToStart(&block);
559552
const Fortran::semantics::SomeExpr &fromExpr =
560553
*Fortran::semantics::GetExpr(stmt1Expr);
561-
elementType = converter.genType(fromExpr);
554+
mlir::Type elementType = converter.genType(fromExpr);
562555
genOmpAccAtomicCaptureStatement<AtomicListT>(
563-
converter, stmt1RHSArg, stmt1LHSArg,
556+
converter, stmt2LHSArg, stmt1LHSArg,
564557
/*leftHandClauseList=*/nullptr,
565558
/*rightHandClauseList=*/nullptr, elementType, loc);
566559
genOmpAccAtomicWriteStatement<AtomicListT>(
567-
converter, stmt1RHSArg, stmt2RHSArg,
560+
converter, stmt2LHSArg, stmt2RHSArg,
568561
/*leftHandClauseList=*/nullptr,
569562
/*rightHandClauseList=*/nullptr, loc);
570563
}
571564
} else {
572565
// Atomic capture construct is of the form [update-stmt, capture-stmt]
573-
firOpBuilder.setInsertionPointToEnd(&block);
574566
const Fortran::semantics::SomeExpr &fromExpr =
575567
*Fortran::semantics::GetExpr(stmt2Expr);
576-
elementType = converter.genType(fromExpr);
577-
genOmpAccAtomicCaptureStatement<AtomicListT>(
578-
converter, stmt1LHSArg, stmt2LHSArg,
579-
/*leftHandClauseList=*/nullptr,
580-
/*rightHandClauseList=*/nullptr, elementType, loc);
581-
firOpBuilder.setInsertionPointToStart(&block);
568+
mlir::Type elementType = converter.genType(fromExpr);
582569
genOmpAccAtomicUpdateStatement<AtomicListT>(
583570
converter, stmt1LHSArg, stmt1VarType, stmt1Var, stmt1Expr,
584571
/*leftHandClauseList=*/nullptr,
585572
/*rightHandClauseList=*/nullptr, loc, atomicCaptureOp);
573+
genOmpAccAtomicCaptureStatement<AtomicListT>(
574+
converter, stmt1LHSArg, stmt2LHSArg,
575+
/*leftHandClauseList=*/nullptr,
576+
/*rightHandClauseList=*/nullptr, elementType, loc);
586577
}
587578
firOpBuilder.setInsertionPointToEnd(&block);
588579
if constexpr (std::is_same<AtomicListT,

flang/test/Fir/convert-to-llvm-openmp-and-fir.fir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -781,11 +781,11 @@ func.func @_QPsimple_reduction(%arg0: !fir.ref<!fir.array<100x!fir.logical<4>>>
781781
// -----
782782

783783
// CHECK: llvm.func @_QPs
784-
// CHECK: omp.atomic.read %{{.*}} = %{{.*}} : !llvm.ptr, !llvm.struct<(f32, f32)>
784+
// CHECK: omp.atomic.read %{{.*}} = %{{.*}} : !llvm.ptr, !llvm.ptr, !llvm.struct<(f32, f32)>
785785

786786
func.func @_QPs(%arg0: !fir.ref<complex<f32>> {fir.bindc_name = "x"}) {
787787
%0 = fir.alloca complex<f32> {bindc_name = "v", uniq_name = "_QFsEv"}
788-
omp.atomic.read %0 = %arg0 : !fir.ref<complex<f32>>, complex<f32>
788+
omp.atomic.read %0 = %arg0 : !fir.ref<complex<f32>>, !fir.ref<complex<f32>>, complex<f32>
789789
return
790790
}
791791

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

Lines changed: 98 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ program acc_atomic_capture_test
1111
!CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %2 {uniq_name = "_QFEy"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
1212
!CHECK: %[[temp:.*]] = fir.load %[[X_DECL]]#0 : !fir.ref<i32>
1313
!CHECK: acc.atomic.capture {
14-
!CHECK: acc.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 : !fir.ref<i32>
14+
!CHECK: acc.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 : !fir.ref<i32>, !fir.ref<i32>, i32
1515
!CHECK: acc.atomic.update %[[Y_DECL]]#1 : !fir.ref<i32> {
1616
!CHECK: ^bb0(%[[ARG:.*]]: i32):
1717
!CHECK: %[[result:.*]] = arith.addi %[[temp]], %[[ARG]] : i32
@@ -32,7 +32,7 @@ program acc_atomic_capture_test
3232
!CHECK: %[[result:.*]] = arith.muli %[[temp]], %[[ARG]] : i32
3333
!CHECK: acc.yield %[[result]] : i32
3434
!CHECK: }
35-
!CHECK: acc.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 : !fir.ref<i32>
35+
!CHECK: acc.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 : !fir.ref<i32>, !fir.ref<i32>, i32
3636
!CHECK: }
3737

3838
!$acc atomic capture
@@ -47,7 +47,7 @@ program acc_atomic_capture_test
4747
!CHECK: %[[result_noreassoc:.*]] = hlfir.no_reassoc %[[result]] : i32
4848
!CHECK: %[[result:.*]] = arith.addi %[[constant_20]], %[[result_noreassoc]] : i32
4949
!CHECK: acc.atomic.capture {
50-
!CHECK: acc.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 : !fir.ref<i32>
50+
!CHECK: acc.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 : !fir.ref<i32>, !fir.ref<i32>, i32
5151
!CHECK: acc.atomic.write %[[Y_DECL]]#1 = %[[result]] : !fir.ref<i32>, i32
5252
!CHECK: }
5353

@@ -82,7 +82,7 @@ subroutine pointers_in_atomic_capture()
8282
!CHECK: %[[result:.*]] = arith.addi %[[ARG]], %[[loaded_value]] : i32
8383
!CHECK: acc.yield %[[result]] : i32
8484
!CHECK: }
85-
!CHECK: acc.atomic.read %[[loaded_B_addr]] = %[[loaded_A_addr]] : !fir.ptr<i32>, i32
85+
!CHECK: acc.atomic.read %[[loaded_B_addr]] = %[[loaded_A_addr]] : !fir.ptr<i32>, !fir.ptr<i32>, i32
8686
!CHECK: }
8787
integer, pointer :: a, b
8888
integer, target :: c, d
@@ -118,10 +118,99 @@ subroutine capture_with_convert_f32_to_i32()
118118
! CHECK: %[[MUL:.*]] = arith.mulf %{{.*}}, %[[CST]] fastmath<contract> : f32
119119
! CHECK: %[[CONV:.*]] = fir.convert %[[MUL]] : (f32) -> i32
120120
! CHECK: acc.atomic.capture {
121-
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[K_DECL]]#1 : !fir.ref<i32>, i32
121+
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[K_DECL]]#1 : !fir.ref<i32>, !fir.ref<i32>, i32
122122
! CHECK: acc.atomic.write %[[K_DECL]]#1 = %[[CONV]] : !fir.ref<i32>, i32
123123
! CHECK: }
124124

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]]#1 = %[[X_DECL]]#1 : !fir.ref<i32>, !fir.ref<f64>, f64
149+
! CHECK: acc.atomic.write %[[X_DECL]]#1 = %[[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]]#1 : !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]]#1 = %[[X_DECL]]#1 : !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]]#1 = %[[X_DECL]]#1 : !fir.ref<i32>, !fir.ref<f32>, f32
206+
! CHECK: acc.atomic.update %[[X_DECL]]#1 : !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+
125214
subroutine array_ref_in_atomic_capture1
126215
integer :: x(10), v
127216
!$acc atomic capture
@@ -136,7 +225,7 @@ end subroutine array_ref_in_atomic_capture1
136225
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]](%{{.*}}) {uniq_name = "_QFarray_ref_in_atomic_capture1Ex"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
137226
! CHECK: %[[X_REF:.*]] = hlfir.designate %[[X_DECL]]#0 (%{{.*}}) : (!fir.ref<!fir.array<10xi32>>, index) -> !fir.ref<i32>
138227
! CHECK: acc.atomic.capture {
139-
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_REF]] : !fir.ref<i32>, i32
228+
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_REF]] : !fir.ref<i32>, !fir.ref<i32>, i32
140229
! CHECK: acc.atomic.update %[[X_REF]] : !fir.ref<i32> {
141230
! CHECK: ^bb0(%[[VAL_7:.*]]: i32):
142231
! CHECK: %[[VAL_8:.*]] = arith.addi %[[VAL_7]], %{{.*}} : i32
@@ -163,7 +252,7 @@ end subroutine array_ref_in_atomic_capture2
163252
! CHECK: %[[VAL_8:.*]] = arith.addi %[[VAL_7]], %{{.*}} : i32
164253
! CHECK: acc.yield %[[VAL_8]] : i32
165254
! CHECK: }
166-
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_REF]] : !fir.ref<i32>, i32
255+
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_REF]] : !fir.ref<i32>, !fir.ref<i32>, i32
167256
! CHECK: }
168257

169258
subroutine comp_ref_in_atomic_capture1
@@ -184,7 +273,7 @@ end subroutine comp_ref_in_atomic_capture1
184273
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcomp_ref_in_atomic_capture1Ex"} : (!fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}>>) -> (!fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}>>, !fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}>>)
185274
! CHECK: %[[C:.*]] = hlfir.designate %[[X_DECL]]#0{"c"} : (!fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}>>) -> !fir.ref<i32>
186275
! CHECK: acc.atomic.capture {
187-
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[C]] : !fir.ref<i32>, i32
276+
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[C]] : !fir.ref<i32>, !fir.ref<i32>, i32
188277
! CHECK: acc.atomic.update %[[C]] : !fir.ref<i32> {
189278
! CHECK: ^bb0(%[[VAL_5:.*]]: i32):
190279
! CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_5]], %{{.*}} : i32
@@ -215,5 +304,5 @@ end subroutine comp_ref_in_atomic_capture2
215304
! CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_5]], %{{.*}} : i32
216305
! CHECK: acc.yield %[[VAL_6]] : i32
217306
! CHECK: }
218-
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[C]] : !fir.ref<i32>, i32
307+
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[C]] : !fir.ref<i32>, !fir.ref<i32>, i32
219308
! CHECK: }

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

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ end program acc_atomic_test
1313
! CHECK: %[[G_DECL:.*]]:2 = hlfir.declare %[[VAR_G]] {uniq_name = "_QFEg"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
1414
! CHECK: %[[VAR_H:.*]] = fir.alloca f32 {bindc_name = "h", uniq_name = "_QFEh"}
1515
! CHECK: %[[H_DECL:.*]]:2 = hlfir.declare %[[VAR_H]] {uniq_name = "_QFEh"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
16-
! CHECK: acc.atomic.read %[[G_DECL]]#1 = %[[H_DECL]]#1 : !fir.ref<f32>, f32
16+
! CHECK: acc.atomic.read %[[G_DECL]]#1 = %[[H_DECL]]#1 : !fir.ref<f32>, !fir.ref<f32>, f32
1717
! CHECK: return
1818
! CHECK: }
1919

@@ -39,21 +39,20 @@ subroutine atomic_read_pointer()
3939
! CHECK: %[[BOX_ADDR_X:.*]] = fir.box_addr %[[LOAD_X]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
4040
! CHECK: %[[LOAD_Y:.*]] = fir.load %[[Y_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
4141
! CHECK: %[[BOX_ADDR_Y:.*]] = fir.box_addr %[[LOAD_Y]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
42-
! CHECK: acc.atomic.read %[[BOX_ADDR_Y]] = %[[BOX_ADDR_X]] : !fir.ptr<i32>, i32
42+
! CHECK: acc.atomic.read %[[BOX_ADDR_Y]] = %[[BOX_ADDR_X]] : !fir.ptr<i32>, !fir.ptr<i32>, i32
4343
! CHECK: }
4444

45-
subroutine atomic_read_with_convert()
45+
subroutine atomic_read_with_cast()
4646
integer(4) :: x
4747
integer(8) :: y
4848

4949
!$acc atomic read
5050
y = x
5151
end
5252

53-
! CHECK-LABEL: func.func @_QPatomic_read_with_convert() {
54-
! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFatomic_read_with_convertEx"}
55-
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFatomic_read_with_convertEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
56-
! CHECK: %[[Y:.*]] = fir.alloca i64 {bindc_name = "y", uniq_name = "_QFatomic_read_with_convertEy"}
57-
! CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]] {uniq_name = "_QFatomic_read_with_convertEy"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
58-
! CHECK: %[[CONV:.*]] = fir.convert %[[X_DECL]]#1 : (!fir.ref<i32>) -> !fir.ref<i64>
59-
! CHECK: acc.atomic.read %[[Y_DECL]]#1 = %[[CONV]] : !fir.ref<i64>, i32
53+
! CHECK-LABEL: func.func @_QPatomic_read_with_cast() {
54+
! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFatomic_read_with_castEx"}
55+
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFatomic_read_with_castEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
56+
! CHECK: %[[Y:.*]] = fir.alloca i64 {bindc_name = "y", uniq_name = "_QFatomic_read_with_castEy"}
57+
! 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]]#1 = %[[X_DECL]]#1 : !fir.ref<i64>, !fir.ref<i32>, i32

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ subroutine atomic_read_array1(r, n, x)
4545
! CHECK: %[[DECL_X:.*]]:2 = hlfir.declare %[[ARG2]] dummy_scope %{{[0-9]+}} {uniq_name = "_QFatomic_read_array1Ex"} : (!fir.ref<f32>, !fir.dscope) -> (!fir.ref<f32>, !fir.ref<f32>)
4646
! CHECK: %[[DECL_R:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) dummy_scope %{{[0-9]+}} {uniq_name = "_QFatomic_read_array1Er"} : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.ref<!fir.array<?xf32>>)
4747
! CHECK: %[[DES:.*]] = hlfir.designate %[[DECL_R]]#0 (%{{.*}}) : (!fir.box<!fir.array<?xf32>>, i64) -> !fir.ref<f32>
48-
! CHECK: acc.atomic.read %[[DECL_X]]#1 = %[[DES]] : !fir.ref<f32>, f32
48+
! CHECK: acc.atomic.read %[[DECL_X]]#1 = %[[DES]] : !fir.ref<f32>, !fir.ref<f32>, f32
4949

5050
subroutine atomic_write_array1(r, n, x)
5151
implicit none
@@ -88,5 +88,5 @@ subroutine atomic_capture_array1(r, n, x, y)
8888
! CHECK: %[[ADD:.*]] = arith.addf %[[ARG]], %[[LOAD]] fastmath<contract> : f32
8989
! CHECK: acc.yield %[[ADD]] : f32
9090
! CHECK: }
91-
! CHECK: acc.atomic.read %[[DECL_Y]]#1 = %[[R_I]] : !fir.ref<f32>, f32
91+
! CHECK: acc.atomic.read %[[DECL_Y]]#1 = %[[R_I]] : !fir.ref<f32>, !fir.ref<f32>, f32
9292
! CHECK: }

0 commit comments

Comments
 (0)