[flang-commits] [flang] [Flang][OpenMP] Skip component symbols when creating extended values (PR #79657)

Krzysztof Parzyszek via flang-commits flang-commits at lists.llvm.org
Fri Jan 26 14:19:07 PST 2024


https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/79657

The `map` clause in OpenMP allows structure components to be specified (unlike other clauses). Structure components do get their own symbols, but these are not meant to be instantiated.

When a component reference is passed as an argument to the omp.target op, it gets a corresponding parameter in the target op's entry block. The original symbols are then bound to the same kind of an extended value as before, but the value is now based on the parameters.

To handle structure components more gracefully, put their symbols on the list of mapped objects, but skip them when creating extended values.

Fixes https://github.com/llvm/llvm-project/issues/79478.

>From 9ebc0ea0daa637a7714d3b2f63ed9cd74d739847 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 25 Jan 2024 12:33:18 -0600
Subject: [PATCH] [Flang][OpenMP] Skip component symbols when creating extended
 values

The `map` clause in OpenMP allows structure components to be specified
(unlike other clauses). Structure components do get their own symbols,
but these are not meant to be instantiated.

When a component reference is passed as an argument to the omp.target
op, it gets a corresponding parameter in the target op's entry block.
The original symbols are then bound to the same kind of an extended
value as before, but the value is now based on the parameters.

To handle structure components more gracefully, put their symbols on
the list of mapped objects, but skip them when creating extended values.

Fixes https://github.com/llvm/llvm-project/issues/79478.
---
 flang/lib/Lower/OpenMP.cpp                    |  6 ++++
 .../Lower/OpenMP/FIR/map-component-ref.f90    | 33 +++++++++++++++++++
 flang/test/Lower/OpenMP/map-component-ref.f90 | 31 +++++++++++++++++
 3 files changed, 70 insertions(+)
 create mode 100644 flang/test/Lower/OpenMP/FIR/map-component-ref.f90
 create mode 100644 flang/test/Lower/OpenMP/map-component-ref.f90

diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp
index d2215f4d1bf1ce..e11d189e969e6d 100644
--- a/flang/lib/Lower/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP.cpp
@@ -58,6 +58,9 @@ getOmpObjectSymbol(const Fortran::parser::OmpObject &ompObject) {
                     Fortran::parser::Unwrap<Fortran::parser::ArrayElement>(
                         designator)) {
               sym = GetFirstName(arrayEle->base).symbol;
+            } else if (auto *structComp = Fortran::parser::Unwrap<
+                           Fortran::parser::StructureComponent>(designator)) {
+              sym = structComp->component.symbol;
             } else if (const Fortran::parser::Name *name =
                            Fortran::semantics::getDesignatorNameIfDataRef(
                                designator)) {
@@ -2743,6 +2746,9 @@ static void genBodyOfTargetOp(
     const mlir::BlockArgument &arg = region.getArgument(argIndex);
     // Avoid capture of a reference to a structured binding.
     const Fortran::semantics::Symbol *sym = argSymbol;
+    // Structure component symbols don't have bindings.
+    if (sym->owner().IsDerivedType())
+      continue;
     fir::ExtendedValue extVal = converter.getSymbolExtendedValue(*sym);
     extVal.match(
         [&](const fir::BoxValue &v) {
diff --git a/flang/test/Lower/OpenMP/FIR/map-component-ref.f90 b/flang/test/Lower/OpenMP/FIR/map-component-ref.f90
new file mode 100644
index 00000000000000..af8c6fa3c5e877
--- /dev/null
+++ b/flang/test/Lower/OpenMP/FIR/map-component-ref.f90
@@ -0,0 +1,33 @@
+! RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s
+! RUN: bbc -fopenmp -emit-fir %s -o - | FileCheck %s
+
+! CHECK: %[[V0:[0-9]+]] = fir.alloca !fir.type<_QFfooTt0{a0:i32,a1:i32}> {bindc_name = "a", uniq_name = "_QFfooEa"}
+! CHECK: %[[V1:[0-9]+]] = fir.declare %[[V0]] {uniq_name = "_QFfooEa"} : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) -> !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>
+! CHECK: %[[V2:[0-9]+]] = fir.field_index a1, !fir.type<_QFfooTt0{a0:i32,a1:i32}>
+! CHECK: %[[V3:[0-9]+]] = fir.coordinate_of %[[V1]], %[[V2]] : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.field) -> !fir.ref<i32>
+! CHECK: %[[V4:[0-9]+]] = omp.map_info var_ptr(%[[V3]] : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "a%a1"}
+! CHECK: %[[V5:[0-9]+]] = omp.map_info var_ptr(%[[V1]] : !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.type<_QFfooTt0{a0:i32,a1:i32}>) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>> {name = "a"}
+! CHECK: omp.target map_entries(%[[V4]] -> %arg0, %[[V5]] -> %arg1 : !fir.ref<i32>, !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) {
+! CHECK: ^bb0(%arg0: !fir.ref<i32>, %arg1: !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>):
+! CHECK:   %c0_i32 = arith.constant 0 : i32
+! CHECK:   %[[V6:[0-9]+]] = fir.declare %arg1 {uniq_name = "_QFfooEa"} : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) -> !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>
+! CHECK:   %[[V7:[0-9]+]] = fir.field_index a1, !fir.type<_QFfooTt0{a0:i32,a1:i32}>
+! CHECK:   %[[V8:[0-9]+]] = fir.coordinate_of %[[V6]], %[[V7]] : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.field) -> !fir.ref<i32>
+! CHECK:   fir.store %c0_i32 to %[[V8]] : !fir.ref<i32>
+! CHECK:   omp.terminator
+! CHECK: }
+
+subroutine foo()
+  implicit none
+
+  type t0
+    integer :: a0, a1
+  end type
+
+  type(t0) :: a
+
+  !$omp target map(a%a1)
+  a%a1 = 0
+  !$omp end target
+end
+
diff --git a/flang/test/Lower/OpenMP/map-component-ref.f90 b/flang/test/Lower/OpenMP/map-component-ref.f90
new file mode 100644
index 00000000000000..1ed37e73158025
--- /dev/null
+++ b/flang/test/Lower/OpenMP/map-component-ref.f90
@@ -0,0 +1,31 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck %s
+
+! CHECK: %[[V0:[0-9]+]] = fir.alloca !fir.type<_QFfooTt0{a0:i32,a1:i32}> {bindc_name = "a", uniq_name = "_QFfooEa"}
+! CHECK: %[[V1:[0-9]+]]:2 = hlfir.declare %[[V0]] {uniq_name = "_QFfooEa"} : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) -> (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>)
+! CHECK: %[[V2:[0-9]+]] = hlfir.designate %[[V1]]#0{"a1"}   : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) -> !fir.ref<i32>
+! CHECK: %[[V3:[0-9]+]] = omp.map_info var_ptr(%[[V2]] : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "a%a1"}
+! CHECK: %[[V4:[0-9]+]] = omp.map_info var_ptr(%[[V1]]#1 : !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.type<_QFfooTt0{a0:i32,a1:i32}>) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>> {name = "a"}
+! CHECK: omp.target map_entries(%[[V3]] -> %arg0, %[[V4]] -> %arg1 : !fir.ref<i32>, !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) {
+! CHECK: ^bb0(%arg0: !fir.ref<i32>, %arg1: !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>):
+! CHECK:   %[[V5:[0-9]+]]:2 = hlfir.declare %arg1 {uniq_name = "_QFfooEa"} : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) -> (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>)
+! CHECK:   %c0_i32 = arith.constant 0 : i32
+! CHECK:   %[[V6:[0-9]+]] = hlfir.designate %[[V5]]#0{"a1"}   : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) -> !fir.ref<i32>
+! CHECK:   hlfir.assign %c0_i32 to %[[V6]] : i32, !fir.ref<i32>
+! CHECK:   omp.terminator
+! CHECK: }
+
+subroutine foo()
+  implicit none
+
+  type t0
+    integer :: a0, a1
+  end type
+
+  type(t0) :: a
+
+  !$omp target map(a%a1)
+  a%a1 = 0
+  !$omp end target
+end
+



More information about the flang-commits mailing list