[OpenMP][Flang] Change the OmpDefaultMapperName suffix (#168399)

This PR fixes a Fortran syntax violation in the OpenMP default mapper
naming convention. The suffix .omp.default.mapper contains dots which
are invalid in Fortran identifiers, causing failures when mappers are
written to and read from module files. The fix changes the suffix to
_omp_default_mapper which uses underscores instead of dots, complying
with Fortran syntax rules.

Key changes:

- Changed OmpDefaultMapperName constant from .omp.default.mapper to
_omp_default_mapper
- Added GetUltimate() calls in mapper symbol resolution to properly
handle symbols across module boundaries
- Added new test case verifying default mappers work correctly when
defined in a module and used in consuming programs

This fixes #168336.
This commit is contained in:
Akash Banerjee
2025-11-17 17:18:12 +00:00
committed by GitHub
parent fb2b1387fb
commit 8c674f04aa
10 changed files with 51 additions and 15 deletions

View File

@@ -1278,7 +1278,8 @@ void ClauseProcessor::processMapObjects(
std::string mapperIdName =
typeSpec->name().ToString() + llvm::omp::OmpDefaultMapperName;
if (auto *sym = converter.getCurrentScope().FindSymbol(mapperIdName)) {
mapperIdName = converter.mangleName(mapperIdName, sym->owner());
mapperIdName =
converter.mangleName(mapperIdName, sym->GetUltimate().owner());
} else {
mapperIdName = converter.mangleName(mapperIdName, *typeSpec->GetScope());
}

View File

@@ -2612,8 +2612,8 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
typeSpec->name().ToString() + llvm::omp::OmpDefaultMapperName;
if (auto *mapperSym =
converter.getCurrentScope().FindSymbol(mapperIdName))
mapperIdName =
converter.mangleName(mapperIdName, mapperSym->owner());
mapperIdName = converter.mangleName(
mapperIdName, mapperSym->GetUltimate().owner());
else
mapperIdName =
converter.mangleName(mapperIdName, *typeSpec->GetScope());

View File

@@ -9,6 +9,8 @@
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-6.f90 -o - | FileCheck %t/omp-declare-mapper-6.f90
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -module-dir %t %t/omp-declare-mapper-7.mod.f90 -o - >/dev/null
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -J %t %t/omp-declare-mapper-7.use.f90 -o - | FileCheck %t/omp-declare-mapper-7.use.f90
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -module-dir %t %t/omp-declare-mapper-8.mod.f90 -o - >/dev/null
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -J %t %t/omp-declare-mapper-8.use.f90 -o - | FileCheck %t/omp-declare-mapper-8.use.f90
!--- omp-declare-mapper-1.f90
subroutine declare_mapper_1
@@ -26,7 +28,7 @@ subroutine declare_mapper_1
end type
type(my_type2) :: t
real :: x, y(nvals)
!CHECK:omp.declare_mapper @[[MY_TYPE_MAPPER:_QQFdeclare_mapper_1my_type\.omp\.default\.mapper]] : [[MY_TYPE:!fir\.type<_QFdeclare_mapper_1Tmy_type\{num_vals:i32,values:!fir\.box<!fir\.heap<!fir\.array<\?xi32>>>\}>]] {
!CHECK:omp.declare_mapper @[[MY_TYPE_MAPPER:_QQFdeclare_mapper_1my_type_omp_default_mapper]] : [[MY_TYPE:!fir\.type<_QFdeclare_mapper_1Tmy_type\{num_vals:i32,values:!fir\.box<!fir\.heap<!fir\.array<\?xi32>>>\}>]] {
!CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<[[MY_TYPE]]>):
!CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFdeclare_mapper_1Evar"} : (!fir.ref<[[MY_TYPE]]>) -> (!fir.ref<[[MY_TYPE]]>, !fir.ref<[[MY_TYPE]]>)
!CHECK: %[[VAL_2:.*]] = hlfir.designate %[[VAL_1]]#0{"values"} {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<[[MY_TYPE]]>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
@@ -153,7 +155,7 @@ subroutine declare_mapper_4
integer :: num
end type
!CHECK: omp.declare_mapper @[[MY_TYPE_MAPPER:_QQFdeclare_mapper_4my_type.omp.default.mapper]] : [[MY_TYPE:!fir\.type<_QFdeclare_mapper_4Tmy_type\{num:i32\}>]]
!CHECK: omp.declare_mapper @[[MY_TYPE_MAPPER:_QQFdeclare_mapper_4my_type_omp_default_mapper]] : [[MY_TYPE:!fir\.type<_QFdeclare_mapper_4Tmy_type\{num:i32\}>]]
!$omp declare mapper (my_type :: var) map (var%num)
type(my_type) :: a
@@ -185,9 +187,9 @@ program declare_mapper_5
end type
!CHECK: omp.declare_mapper @[[INNER_MAPPER_NAMED:_QQFFuse_innermy_mapper]] : [[MY_TYPE:!fir\.type<_QFTmytype\{x:i32,y:i32\}>]]
!CHECK: omp.declare_mapper @[[INNER_MAPPER_DEFAULT:_QQFFuse_innermytype.omp.default.mapper]] : [[MY_TYPE]]
!CHECK: omp.declare_mapper @[[INNER_MAPPER_DEFAULT:_QQFFuse_innermytype_omp_default_mapper]] : [[MY_TYPE]]
!CHECK: omp.declare_mapper @[[OUTER_MAPPER_NAMED:_QQFmy_mapper]] : [[MY_TYPE]]
!CHECK: omp.declare_mapper @[[OUTER_MAPPER_DEFAULT:_QQFmytype.omp.default.mapper]] : [[MY_TYPE]]
!CHECK: omp.declare_mapper @[[OUTER_MAPPER_DEFAULT:_QQFmytype_omp_default_mapper]] : [[MY_TYPE]]
!$omp declare mapper(mytype :: var) map(tofrom: var%x)
!$omp declare mapper(my_mapper : mytype :: var) map(tofrom: var%y)
@@ -325,3 +327,36 @@ program use_module_mapper
a%x = 42
!$omp end target
end program use_module_mapper
!--- omp-declare-mapper-8.mod.f90
! Module with a default DECLARE MAPPER to be compiled separately.
module default_mapper_mod
implicit none
type :: dtype
integer :: x
end type dtype
!$omp declare mapper(dtype :: v) map(tofrom: v%x)
end module default_mapper_mod
!--- omp-declare-mapper-8.use.f90
! Consumer program that USEs the module and relies on the default mapper.
! CHECK: omp.declare_mapper @{{.*dtype_omp_default_mapper}} : !fir.type<_QMdefault_mapper_modTdtype{x:i32}>
! CHECK: %{{.*}} = omp.map.info {{.*}} map_clauses(tofrom) {{.*}} mapper(@{{.*dtype_omp_default_mapper}}) {{.*}} {name = "a"}
! CHECK: %{{.*}} = omp.map.info {{.*}} map_clauses(tofrom) {{.*}} mapper(@{{.*dtype_omp_default_mapper}}) {{.*}} {name = "a"}
! CHECK: %{{.*}} = omp.map.info {{.*}} map_clauses(implicit, tofrom) {{.*}} mapper(@{{.*dtype_omp_default_mapper}}) {{.*}} {name = "a"}
program use_module_default_mapper
use default_mapper_mod
implicit none
type(dtype) :: a
!$omp target map(a)
a%x = 7
!$omp end target
!$omp target map(mapper(default) : a)
a%x = 8
!$omp end target
!$omp target
a%x = 8
!$omp end target
end program use_module_default_mapper

View File

@@ -1,6 +1,6 @@
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
!CHECK: omp.declare_mapper @[[MAPPER1:_QQFmaptype_derived_implicit_allocatablescalar_and_array.omp.default.mapper]] : !fir.type<_QFmaptype_derived_implicit_allocatableTscalar_and_array{real:f32,array:!fir.array<10xi32>,int:i32}> {
!CHECK: omp.declare_mapper @[[MAPPER1:_QQFmaptype_derived_implicit_allocatablescalar_and_array_omp_default_mapper]] : !fir.type<_QFmaptype_derived_implicit_allocatableTscalar_and_array{real:f32,array:!fir.array<10xi32>,int:i32}> {
!CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.type<_QFmaptype_derived_implicitTscalar_and_array{real:f32,array:!fir.array<10xi32>,int:i32}> {bindc_name = "scalar_arr", uniq_name = "_QFmaptype_derived_implicitEscalar_arr"}
!CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "_QFmaptype_derived_implicitEscalar_arr"} : (!fir.ref<!fir.type<_QFmaptype_derived_implicitTscalar_and_array{real:f32,array:!fir.array<10xi32>,int:i32}>>) -> (!fir.ref<!fir.type<_QFmaptype_derived_implicitTscalar_and_array{real:f32,array:!fir.array<10xi32>,int:i32}>>, !fir.ref<!fir.type<_QFmaptype_derived_implicitTscalar_and_array{real:f32,array:!fir.array<10xi32>,int:i32}>>)

View File

@@ -8,7 +8,7 @@ program p
!$omp declare mapper(xx : t1 :: nn) map(to: nn, nn%x)
!$omp declare mapper(t1 :: nn) map(from: nn)
!CHECK-LABEL: omp.declare_mapper @_QQFt1.omp.default.mapper : !fir.type<_QFTt1{x:!fir.array<256xi32>}>
!CHECK-LABEL: omp.declare_mapper @_QQFt1_omp_default_mapper : !fir.type<_QFTt1{x:!fir.array<256xi32>}>
!CHECK-LABEL: omp.declare_mapper @_QQFxx : !fir.type<_QFTt1{x:!fir.array<256xi32>}>
type(t1) :: a, b
@@ -20,7 +20,7 @@ program p
end do
!$omp end target
!CHECK: %[[MAP_B:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(tofrom) capture(ByRef) mapper(@_QQFt1.omp.default.mapper) -> {{.*}} {name = "b"}
!CHECK: %[[MAP_B:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(tofrom) capture(ByRef) mapper(@_QQFt1_omp_default_mapper) -> {{.*}} {name = "b"}
!CHECK: omp.target map_entries(%[[MAP_B]] -> %{{.*}}, %{{.*}} -> %{{.*}} : {{.*}}, {{.*}}) {
!$omp target map(mapper(default) : b)
do i = 1, n

View File

@@ -529,7 +529,7 @@ subroutine omp_target_device_ptr
use iso_c_binding, only : c_ptr, c_loc
type(c_ptr) :: a
integer, target :: b
!CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(tofrom) capture(ByRef) mapper(@[[CPTR_DEFAULT:_QQM__fortran_builtinsc_ptr\.omp\.default\.mapper]]) -> {{.*}} {name = "a"}
!CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(tofrom) capture(ByRef) mapper(@[[CPTR_DEFAULT:_QQM__fortran_builtinsc_ptr_omp_default_mapper]]) -> {{.*}} {name = "a"}
!CHECK: omp.target_data map_entries(%[[MAP]]{{.*}}) use_device_ptr({{.*}} -> %[[VAL_1:.*]] : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>)
!$omp target data map(tofrom: a) use_device_ptr(a)
!CHECK: {{.*}} = fir.coordinate_of %[[VAL_1:.*]], __address : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> !fir.ref<i64>

View File

@@ -29,7 +29,7 @@ program main
!PARSE-TREE: OpenMPDeclareMapperConstruct
!PARSE-TREE: OmpMapperSpecifier
!PARSE-TREE: string = 'ty.omp.default.mapper'
!PARSE-TREE: string = 'ty_omp_default_mapper'
!PARSE-TREE: TypeSpec -> DerivedTypeSpec
!PARSE-TREE: Name = 'ty'
!PARSE-TREE: Name = 'mapped'

View File

@@ -57,7 +57,7 @@ end
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareMapperConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare mapper
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpMapperSpecifier
!PARSE-TREE: | | string = 't.omp.default.mapper'
!PARSE-TREE: | | string = 't_omp_default_mapper'
!PARSE-TREE: | | TypeSpec -> DerivedTypeSpec
!PARSE-TREE: | | | Name = 't'
!PARSE-TREE: | | Name = 'v'

View File

@@ -13,7 +13,7 @@ program main
!! Note, symbols come out in their respective scope, but not in declaration order.
!CHECK: mymapper: MapperDetails
!CHECK: ty: DerivedType components: x
!CHECK: ty.omp.default.mapper: MapperDetails
!CHECK: ty_omp_default_mapper: MapperDetails
!CHECK: DerivedType scope: ty
!CHECK: OtherConstruct scope:
!CHECK: mapped (OmpMapToFrom) {{.*}} ObjectEntity type: TYPE(ty)

View File

@@ -201,7 +201,7 @@ enum class OMPDynGroupprivateFallbackType : uint64_t {
};
// Default OpenMP mapper name suffix.
inline constexpr const char *OmpDefaultMapperName = ".omp.default.mapper";
inline constexpr const char *OmpDefaultMapperName = "_omp_default_mapper";
/// Values for bit flags used to specify the mapping type for
/// offloading.