[flang-commits] [flang] [Flang][FIR] Handle SequenceTypes in isRecordWithAllocatableMember (PR #224048)

via flang-commits flang-commits at lists.llvm.org
Thu Sep 17 09:48:57 PDT 2026


https://github.com/agozillon updated https://github.com/llvm/llvm-project/pull/224048

>From bff7de9d0ce8b2ff9089a3c5c9cee5a6ff5fd1fc Mon Sep 17 00:00:00 2001
From: agozillon <Andrew.Gozillon at amd.com>
Date: Wed, 16 Sep 2026 10:20:47 -0500
Subject: [PATCH] [Flang][FIR] Handle SequenceTypes in
 isRecordWithAllocatableMember

Currently isRecordWithAllocatableMember does not handle sequence types,
either at the top level on the input type or in subsequent nestings, it
will effectively skip them. This is quite different to how isRecordWithDescriptorMember
handles these cases, as it does in fact unwrap sequence types to correctly
dictate if there are descriptor members inside of a record type.

This PR simply aims to align the behaviour with isRecordWithDescriptorMember, as
there are several locations where isRecordWithAllocatableMember is being used and
the expectation is that it will indicate if there's an allocatable member inside of
the record type irrespective of sequence types being part of the equation.
---
 flang/lib/Optimizer/Dialect/FIRType.cpp       |  2 +
 ...firstprivate-nested-allocatable-mapper.f90 | 42 +++++++++++++++++++
 2 files changed, 44 insertions(+)
 create mode 100644 flang/test/Lower/OpenMP/DelayedPrivatization/target-firstprivate-nested-allocatable-mapper.f90

diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp
index 5f0dd68aa9396..c43e4a41071d8 100644
--- a/flang/lib/Optimizer/Dialect/FIRType.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -424,8 +424,10 @@ bool isUnlimitedPolymorphicType(mlir::Type ty) {
 }
 
 bool isRecordWithAllocatableMember(mlir::Type ty) {
+  ty = unwrapSequenceType(ty);
   if (auto recTy = mlir::dyn_cast<fir::RecordType>(ty))
     for (auto [field, memTy] : recTy.getTypeList()) {
+      memTy = unwrapSequenceType(memTy);
       if (fir::isAllocatableType(memTy))
         return true;
       // A record type cannot recursively include itself as a direct member.
diff --git a/flang/test/Lower/OpenMP/DelayedPrivatization/target-firstprivate-nested-allocatable-mapper.f90 b/flang/test/Lower/OpenMP/DelayedPrivatization/target-firstprivate-nested-allocatable-mapper.f90
new file mode 100644
index 0000000000000..c8342ba0a8c5f
--- /dev/null
+++ b/flang/test/Lower/OpenMP/DelayedPrivatization/target-firstprivate-nested-allocatable-mapper.f90
@@ -0,0 +1,42 @@
+! Test that firstprivate target privatization of an array of derived types
+! generates implicit declare mappers when the array element type contains an
+! array of another derived type that also contains an allocatable member.
+!
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+! RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+
+subroutine target_firstprivate_nested_allocatable_mapper
+  implicit none
+
+  type :: inner_type
+    integer, allocatable :: values(:)
+  end type inner_type
+
+  type :: outer_type
+    type(inner_type) :: children(4)
+  end type outer_type
+
+  type(outer_type) :: objs(4)
+
+  !$omp target firstprivate(objs)
+    if (allocated(objs(1)%children(1)%values)) then
+      objs(1)%children(1)%values(1) = 42
+    end if
+  !$omp end target
+end subroutine target_firstprivate_nested_allocatable_mapper
+
+! CHECK:       omp.declare_mapper @[[INNER_MAPPER:.*inner_type_omp_default_mapper]] : !fir.type<{{.*}}Tinner_type{{.*}}>
+! CHECK:       %[[INNER_VALUES_MAP:.*]] = omp.map.info {{.*}}map_clauses(implicit, tofrom, ref_ptee)
+! CHECK:       %[[INNER_VALUES_ATTACH:.*]] = omp.map.info {{.*}}map_clauses(attach, ref_ptee)
+! CHECK:       %[[INNER_PARENT_MAP:.*]] = omp.map.info {{.*}}map_clauses(implicit, tofrom){{.*}}members(%[[INNER_VALUES_MAP]] : [0] :
+
+! CHECK:       omp.declare_mapper @[[OUTER_MAPPER:.*outer_type_omp_default_mapper]] : !fir.type<{{.*}}Touter_type{{.*}}>
+! CHECK:       %[[OUTER_CHILDREN_MAP:.*]] = omp.map.info {{.*}}map_clauses(implicit, tofrom){{.*}}mapper(@[[INNER_MAPPER]])
+! CHECK:       %[[OUTER_PARENT_MAP:.*]] = omp.map.info {{.*}}map_clauses(implicit, tofrom){{.*}}members(%[[OUTER_CHILDREN_MAP]] : [0] :
+
+! CHECK:       omp.private {type = firstprivate} @{{.*}}objs_firstprivate{{.*}}outer_type : !fir.box<!fir.array<4x!fir.type<
+
+! CHECK-LABEL: func.func @_QPtarget_firstprivate_nested_allocatable_mapper()
+! CHECK:       %[[OBJS_DATA_MAP:.*]] = omp.map.info {{.*}}map_clauses(tofrom){{.*}}mapper(@[[OUTER_MAPPER]])
+! CHECK:       %[[OBJS_DESC_MAP:.*]] = omp.map.info {{.*}}map_clauses(always, to){{.*}}members(%[[OBJS_DATA_MAP]] : [0] :
+! CHECK:       omp.target {{.*}}map_entries(%[[OBJS_DESC_MAP]] -> {{.*}}, {{.*}}, %[[OBJS_DATA_MAP]] ->{{.*}}private(@{{.*}}objs_firstprivate{{.*}}outer_type {{.*}}[map_idx=0]



More information about the flang-commits mailing list