[flang-commits] [flang] [flang][openacc] Fixed atomic capture with array/comp refs on the RHS. (PR #71013)
via flang-commits
flang-commits at lists.llvm.org
Wed Nov 1 20:30:53 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Slava Zakharin (vzakhari)
<details>
<summary>Changes</summary>
checkForSingleVariableOnRHS() failed for assignments like `v = x(i)`,
so the lowering produced incorrect code for atomic capture regions.
I believe any designator on the RHS should indicate that this is
a capture statement.
---
Full diff: https://github.com/llvm/llvm-project/pull/71013.diff
2 Files Affected:
- (modified) flang/lib/Lower/DirectivesCommon.h (+1-5)
- (modified) flang/test/Lower/OpenACC/acc-atomic-capture.f90 (+91-1)
``````````diff
diff --git a/flang/lib/Lower/DirectivesCommon.h b/flang/lib/Lower/DirectivesCommon.h
index b2e9ed374d2103c..86787961382441f 100644
--- a/flang/lib/Lower/DirectivesCommon.h
+++ b/flang/lib/Lower/DirectivesCommon.h
@@ -55,11 +55,7 @@ static inline bool checkForSingleVariableOnRHS(
const Fortran::common::Indirection<Fortran::parser::Designator> *designator =
std::get_if<Fortran::common::Indirection<Fortran::parser::Designator>>(
&expr.u);
- const Fortran::parser::Name *name =
- designator
- ? Fortran::semantics::getDesignatorNameIfDataRef(designator->value())
- : nullptr;
- return name != nullptr;
+ return designator != nullptr;
}
/// Checks if the symbol on the LHS of the assignment statement is present in
diff --git a/flang/test/Lower/OpenACC/acc-atomic-capture.f90 b/flang/test/Lower/OpenACC/acc-atomic-capture.f90
index 59c16cf61acf718..0dc09d71e6b1e1a 100644
--- a/flang/test/Lower/OpenACC/acc-atomic-capture.f90
+++ b/flang/test/Lower/OpenACC/acc-atomic-capture.f90
@@ -1,4 +1,4 @@
-! RUN: %flang_fc1 -emit-fir -fopenacc %s -o - | FileCheck %s
+! RUN: %flang_fc1 -I nowhere -emit-fir -fopenacc %s -o - | FileCheck %s
! This test checks the lowering of atomic capture
@@ -122,3 +122,93 @@ subroutine capture_with_convert_f32_to_i32()
! CHECK: acc.atomic.read %[[V]] = %[[K]] : !fir.ref<i32>, i32
! CHECK: acc.atomic.write %[[K]] = %[[CONV]] : !fir.ref<i32>, i32
! CHECK: }
+
+subroutine array_ref_in_atomic_capture1
+ integer :: x(10), v
+ !$acc atomic capture
+ v = x(7)
+ x(7) = x(7) + 1
+ !$acc end atomic
+end subroutine array_ref_in_atomic_capture1
+! CHECK-LABEL: func.func @_QParray_ref_in_atomic_capture1() {
+! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFarray_ref_in_atomic_capture1Ev"}
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "x", uniq_name = "_QFarray_ref_in_atomic_capture1Ex"}
+! CHECK: %[[VAL_5:.*]] = fir.coordinate_of %[[VAL_1]], %{{.*}} : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
+! CHECK: acc.atomic.capture {
+! CHECK: acc.atomic.read %[[VAL_0]] = %[[VAL_5]] : !fir.ref<i32>, i32
+! CHECK: acc.atomic.update %[[VAL_5]] : !fir.ref<i32> {
+! CHECK: ^bb0(%[[VAL_7:.*]]: i32):
+! CHECK: %[[VAL_8:.*]] = arith.addi %[[VAL_7]], %{{.*}} : i32
+! CHECK: acc.yield %[[VAL_8]] : i32
+! CHECK: }
+! CHECK: }
+
+subroutine array_ref_in_atomic_capture2
+ integer :: x(10), v
+ !$acc atomic capture
+ x(7) = x(7) + 1
+ v = x(7)
+ !$acc end atomic
+end subroutine array_ref_in_atomic_capture2
+! CHECK-LABEL: func.func @_QParray_ref_in_atomic_capture2() {
+! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFarray_ref_in_atomic_capture2Ev"}
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "x", uniq_name = "_QFarray_ref_in_atomic_capture2Ex"}
+! CHECK: %[[VAL_5:.*]] = fir.coordinate_of %[[VAL_1]], %{{.*}} : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
+! CHECK: acc.atomic.capture {
+! CHECK: acc.atomic.update %[[VAL_5]] : !fir.ref<i32> {
+! CHECK: ^bb0(%[[VAL_7:.*]]: i32):
+! CHECK: %[[VAL_8:.*]] = arith.addi %[[VAL_7]], %{{.*}} : i32
+! CHECK: acc.yield %[[VAL_8]] : i32
+! CHECK: }
+! CHECK: acc.atomic.read %[[VAL_0]] = %[[VAL_5]] : !fir.ref<i32>, i32
+! CHECK: }
+
+subroutine comp_ref_in_atomic_capture1
+ type t1
+ integer :: c
+ end type t1
+ integer :: v
+ type(t1) :: x
+ !$acc atomic capture
+ v = x%c
+ x%c = x%c + 1
+ !$acc end atomic
+end subroutine comp_ref_in_atomic_capture1
+! CHECK-LABEL: func.func @_QPcomp_ref_in_atomic_capture1() {
+! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFcomp_ref_in_atomic_capture1Ev"}
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}> {bindc_name = "x", uniq_name = "_QFcomp_ref_in_atomic_capture1Ex"}
+! CHECK: %[[VAL_2:.*]] = fir.field_index c, !fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}>
+! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}>>, !fir.field) -> !fir.ref<i32>
+! CHECK: acc.atomic.capture {
+! CHECK: acc.atomic.read %[[VAL_0]] = %[[VAL_3]] : !fir.ref<i32>, i32
+! CHECK: acc.atomic.update %[[VAL_3]] : !fir.ref<i32> {
+! CHECK: ^bb0(%[[VAL_5:.*]]: i32):
+! CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_5]], %{{.*}} : i32
+! CHECK: acc.yield %[[VAL_6]] : i32
+! CHECK: }
+! CHECK: }
+
+subroutine comp_ref_in_atomic_capture2
+ type t1
+ integer :: c
+ end type t1
+ integer :: v
+ type(t1) :: x
+ !$acc atomic capture
+ x%c = x%c + 1
+ v = x%c
+ !$acc end atomic
+end subroutine comp_ref_in_atomic_capture2
+! CHECK-LABEL: func.func @_QPcomp_ref_in_atomic_capture2() {
+! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFcomp_ref_in_atomic_capture2Ev"}
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QFcomp_ref_in_atomic_capture2Tt1{c:i32}> {bindc_name = "x", uniq_name = "_QFcomp_ref_in_atomic_capture2Ex"}
+! CHECK: %[[VAL_2:.*]] = fir.field_index c, !fir.type<_QFcomp_ref_in_atomic_capture2Tt1{c:i32}>
+! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture2Tt1{c:i32}>>, !fir.field) -> !fir.ref<i32>
+! CHECK: acc.atomic.capture {
+! CHECK: acc.atomic.update %[[VAL_3]] : !fir.ref<i32> {
+! CHECK: ^bb0(%[[VAL_5:.*]]: i32):
+! CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_5]], %{{.*}} : i32
+! CHECK: acc.yield %[[VAL_6]] : i32
+! CHECK: }
+! CHECK: acc.atomic.read %[[VAL_0]] = %[[VAL_3]] : !fir.ref<i32>, i32
+! CHECK: }
``````````
</details>
https://github.com/llvm/llvm-project/pull/71013
More information about the flang-commits
mailing list