[flang-commits] [flang] [flang][openacc] Fixed atomic capture with array/comp refs on the RHS. (PR #71013)

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Wed Nov 1 20:30:23 PDT 2023


https://github.com/vzakhari created https://github.com/llvm/llvm-project/pull/71013

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.


>From 9f8309cba91cda904fab55c53577ff0985080645 Mon Sep 17 00:00:00 2001
From: Slava Zakharin <szakharin at nvidia.com>
Date: Wed, 1 Nov 2023 19:04:07 -0700
Subject: [PATCH] [flang][openacc] Fixed atomic capture with array/comp refs on
 the RHS.

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.
---
 flang/lib/Lower/DirectivesCommon.h            |  6 +-
 .../test/Lower/OpenACC/acc-atomic-capture.f90 | 92 ++++++++++++++++++-
 2 files changed, 92 insertions(+), 6 deletions(-)

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:           }



More information about the flang-commits mailing list