[flang-commits] [flang] ee3b6b0 - [Flang][OpenMP] Fix broken offload test caused by MapInfoFinalization code movement (#226384)

via flang-commits flang-commits at lists.llvm.org
Fri Sep 25 13:55:09 PDT 2026


Author: agozillon
Date: 2026-09-25T22:55:02+02:00
New Revision: ee3b6b045bc37b156c3860481090d68367e961dc

URL: https://github.com/llvm/llvm-project/commit/ee3b6b045bc37b156c3860481090d68367e961dc
DIFF: https://github.com/llvm/llvm-project/commit/ee3b6b045bc37b156c3860481090d68367e961dc.diff

LOG: [Flang][OpenMP] Fix broken offload test caused by MapInfoFinalization code movement (#226384)

This change addresses the breakage in
target-map-nested-dtype-allocatable-member.f90 I inadvertently broke it
by removing the excess bit of implicit mapping code in the
MapInfoFinalizaiton pass without correctly addressing it.

This PR tries to do so by allowing mappers to be generated for member
maps such as var1%b, var2%b, which were previously being blocked.

Currently (and conveniently for this patch) we do avoid duplicate maps
in the scenario where we specify something along the lines of:

map(tofrom: var1, var1%b, var2, var2%b)

But that is through the fact that we completely negate var1/var2's
mapper attachment in this scenario, which I do not believe is the
correct behavior. But it's the existing behavior and facilitates this
patch, but it is something I'll see if I can address in a follow up PR
in the near future, the logic might need a bit of debating. For now this
simply seeks to amend the existing test without rocking the boat more
than required (that's the hope at least).

Added: 
    flang/test/Lower/OpenMP/target-map-nested-dtype-allocatable-member.f90

Modified: 
    flang/lib/Lower/OpenMP/ClauseProcessor.cpp
    flang/lib/Lower/OpenMP/Utils.cpp
    flang/lib/Lower/OpenMP/Utils.h
    flang/test/Lower/OpenMP/declare-mapper.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index b871f630d3dae..e41223b5b16c0 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1918,7 +1918,7 @@ void ClauseProcessor::processMapObjects(
 
     mlir::FlatSymbolRefAttr mapperId =
         resolveMapperId(converter, clauseLocation, object, mapperIdNameRef,
-                        mapTypeBits, directive, parentObj.has_value());
+                        mapTypeBits, directive);
 
     // Explicit map captures are captured ByRef by default,
     // optimisation passes may alter this to ByCopy or other capture

diff  --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp
index b52c03ff63fed..e05a3eab6fad6 100644
--- a/flang/lib/Lower/OpenMP/Utils.cpp
+++ b/flang/lib/Lower/OpenMP/Utils.cpp
@@ -1224,12 +1224,10 @@ addImplicitMapper(Fortran::lower::AbstractConverter &converter,
       });
 }
 
-mlir::FlatSymbolRefAttr
-resolveMapperId(Fortran::lower::AbstractConverter &converter,
-                mlir::Location loc, const omp::Object &object,
-                llvm::StringRef mapperIdNameRef,
-                mlir::omp::ClauseMapFlags mapTypeBits,
-                llvm::omp::Directive directive, bool hasParentObj) {
+mlir::FlatSymbolRefAttr resolveMapperId(
+    Fortran::lower::AbstractConverter &converter, mlir::Location loc,
+    const omp::Object &object, llvm::StringRef mapperIdNameRef,
+    mlir::omp::ClauseMapFlags mapTypeBits, llvm::omp::Directive directive) {
   const semantics::DerivedTypeSpec *objectTypeSpec =
       getSymbolDerivedType(*object.sym());
   if (!objectTypeSpec)
@@ -1259,10 +1257,10 @@ resolveMapperId(Fortran::lower::AbstractConverter &converter,
     // specification.
     auto *userDefinedDefault =
         converter.getModuleOp().lookupSymbol(mapperIdName);
-    if (!userDefinedDefault && !hasParentObj &&
-        (directive != llvm::omp::Directive::OMPD_target_enter_data &&
-         directive != llvm::omp::Directive::OMPD_target_exit_data &&
-         directive != llvm::omp::Directive::OMPD_target_update)) {
+    if (!userDefinedDefault &&
+        directive != llvm::omp::Directive::OMPD_target_enter_data &&
+        directive != llvm::omp::Directive::OMPD_target_exit_data &&
+        directive != llvm::omp::Directive::OMPD_target_update) {
       bool isAllocOrPointer =
           semantics::IsAllocatableOrObjectPointer(object.sym());
       bool isPointer = semantics::IsPointer(*object.sym());

diff  --git a/flang/lib/Lower/OpenMP/Utils.h b/flang/lib/Lower/OpenMP/Utils.h
index 7fde1825b006a..4560c9df349b2 100644
--- a/flang/lib/Lower/OpenMP/Utils.h
+++ b/flang/lib/Lower/OpenMP/Utils.h
@@ -236,9 +236,8 @@ mlir::Value genIteratorCoordinate(Fortran::lower::AbstractConverter &converter,
 /// Resolve the declare mapper symbol to attach to a mapped object.
 ///
 /// The default mapper path first looks for a user-defined mapper. If none
-/// exists, it may synthesize a compiler-generated mapper, except for mapped
-/// members whose parent object is also mapped and for target enter data,
-/// target exit data, and target update directives.
+/// exists, it may synthesize a compiler-generated mapper, except for target
+/// enter data, target exit data, and target update directives.
 ///
 /// \param converter The converter used to query and generate mapper symbols.
 /// \param loc The location to use when generating an implicit mapper.
@@ -248,15 +247,12 @@ mlir::Value genIteratorCoordinate(Fortran::lower::AbstractConverter &converter,
 /// \param mapTypeBits The map flags used when deciding whether an implicit
 ///        mapper should be generated.
 /// \param directive The enclosing OpenMP directive.
-/// \param hasParentObj True if a mapped parent object already owns this object.
 /// \return A symbol reference to the resolved mapper, or a null attribute when
 ///         no mapper applies.
-mlir::FlatSymbolRefAttr
-resolveMapperId(Fortran::lower::AbstractConverter &converter,
-                mlir::Location loc, const omp::Object &object,
-                llvm::StringRef mapperIdName,
-                mlir::omp::ClauseMapFlags mapTypeBits,
-                llvm::omp::Directive directive, bool hasParentObj);
+mlir::FlatSymbolRefAttr resolveMapperId(
+    Fortran::lower::AbstractConverter &converter, mlir::Location loc,
+    const omp::Object &object, llvm::StringRef mapperIdName,
+    mlir::omp::ClauseMapFlags mapTypeBits, llvm::omp::Directive directive);
 
 std::optional<llvm::SmallVector<mlir::Value>> getIteratorElementIndices(
     Fortran::lower::AbstractConverter &converter, const omp::Object &object,

diff  --git a/flang/test/Lower/OpenMP/declare-mapper.f90 b/flang/test/Lower/OpenMP/declare-mapper.f90
index 51b155ea31f48..4327d8bd1498f 100644
--- a/flang/test/Lower/OpenMP/declare-mapper.f90
+++ b/flang/test/Lower/OpenMP/declare-mapper.f90
@@ -88,7 +88,7 @@ subroutine declare_mapper_2
    !CHECK:        %[[VAL_8:.*]] = omp.map.bounds lower_bound(%[[VAL_6]] : index) upper_bound(%[[VAL_7]] : index) extent(%[[VAL_2]] : index) stride(%[[VAL_5]] : index) start_idx(%[[VAL_5]] : index)
    !CHECK:        %[[VAL_9:.*]] = omp.map.info var_ptr(%[[VAL_4]] : !fir.ref<!fir.array<250xf32>>, !fir.array<250xf32>) map_clauses(tofrom) capture(ByRef) bounds(%[[VAL_8]]) name("v%[[VAL_10:.*]]") -> !fir.ref<!fir.array<250xf32>>
    !CHECK:        %[[VAL_11:.*]] = hlfir.designate %[[VAL_1]]#0{"temp"}   : (!fir.ref<[[MY_TYPE]]>) -> !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
-   !CHECK:        %[[VAL_12:.*]] = omp.map.info var_ptr(%[[VAL_11]] : !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>) map_clauses(storage) capture(ByRef) name("v%[[VAL_13:.*]]") -> !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
+   !CHECK:        %[[VAL_12:.*]] = omp.map.info var_ptr(%[[VAL_11]] : !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>) map_clauses(storage) capture(ByRef) mapper(@_QQFdeclare_mapper_2my_type_omp_default_mapper) name("v%[[VAL_13:.*]]") -> !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
    !CHECK:        %[[VAL_14:.*]] = omp.map.info var_ptr(%[[VAL_1]]#1 : !fir.ref<[[MY_TYPE]]>, [[MY_TYPE]]) map_clauses(storage) capture(ByRef) members(%[[VAL_9]], %[[VAL_12]] : [3], [1] : !fir.ref<!fir.array<250xf32>>, !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) name("v") partial_map(true) -> !fir.ref<[[MY_TYPE]]>
    !CHECK:        omp.declare_mapper.info map_entries(%[[VAL_14]], %[[VAL_9]], %[[VAL_12]] : !fir.ref<[[MY_TYPE]]>, !fir.ref<!fir.array<250xf32>>, !fir.ref<!fir.type<_QFdeclare_mapper_2Tmy_type{num_vals:i32,values:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>)
    !CHECK:      }

diff  --git a/flang/test/Lower/OpenMP/target-map-nested-dtype-allocatable-member.f90 b/flang/test/Lower/OpenMP/target-map-nested-dtype-allocatable-member.f90
new file mode 100644
index 0000000000000..9d39de0c4ee51
--- /dev/null
+++ b/flang/test/Lower/OpenMP/target-map-nested-dtype-allocatable-member.f90
@@ -0,0 +1,31 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+! Check that explicit maps of derived-type components can still get an
+! implicit default mapper when the component type requires deep-copy mapping.
+! The synthetic parent maps for var1/var2 are only structural containers for
+! the explicit var1%b/var2%b list items and must not suppress mapper emission
+! for those list items.
+
+subroutine target_map_nested_dtype_allocatable_member
+  type :: inner_type
+    integer, allocatable :: a
+  end type inner_type
+
+  type :: outer_type
+    type(inner_type) :: b
+  end type outer_type
+
+  type(outer_type) :: var1, var2
+
+  !$omp target map(tofrom: var1%b, var2%b)
+    var1%b%a = var2%b%a
+  !$omp end target
+end subroutine
+
+! CHECK: omp.declare_mapper @{{.*}}inner_type_omp_default_mapper
+
+! CHECK-LABEL: func.func @_QPtarget_map_nested_dtype_allocatable_member
+! CHECK: %[[VAR1_B:.*]] = omp.map.info {{.*}}map_clauses(tofrom){{.*}}mapper(@{{.*}}inner_type_omp_default_mapper){{.*}}name("var1%b")
+! CHECK: %[[VAR2_B:.*]] = omp.map.info {{.*}}map_clauses(tofrom){{.*}}mapper(@{{.*}}inner_type_omp_default_mapper){{.*}}name("var2%b")
+! CHECK: omp.map.info {{.*}}map_clauses(storage){{.*}}members(%[[VAR1_B]] : [0] :{{.*}}){{.*}}name("var1"){{.*}}partial_map(true)
+! CHECK: omp.map.info {{.*}}map_clauses(storage){{.*}}members(%[[VAR2_B]] : [0] :{{.*}}){{.*}}name("var2"){{.*}}partial_map(true)


        


More information about the flang-commits mailing list