[flang-commits] [flang] [flang][OpenMP] Support custom mappers in target update to/from clauses (PR #169673)
Krish Gupta via flang-commits
flang-commits at lists.llvm.org
Thu Nov 27 11:02:56 PST 2025
https://github.com/KrxGu updated https://github.com/llvm/llvm-project/pull/169673
>From b2a07c5763d28c9bb20a948433223c98fedc200e Mon Sep 17 00:00:00 2001
From: Krish Gupta <krishgupta at Krishs-MacBook-Air.local>
Date: Wed, 26 Nov 2025 21:43:27 +0530
Subject: [PATCH 1/3] [flang][OpenMP] Support mappers in target update to/from
Fixes #168701
---
flang/lib/Semantics/resolve-names.cpp | 60 +++++++++++++++++++
.../Lower/OpenMP/target-update-mapper.f90 | 52 ++++++++++++++++
.../Semantics/OpenMP/target-update-mapper.f90 | 54 +++++++++++++++++
3 files changed, 166 insertions(+)
create mode 100644 flang/test/Lower/OpenMP/target-update-mapper.f90
create mode 100644 flang/test/Semantics/OpenMP/target-update-mapper.f90
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 2a487a6d39d51..ca17767dce924 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1631,6 +1631,8 @@ class OmpVisitor : public virtual DeclarationVisitor {
return true;
}
bool Pre(const parser::OmpMapClause &);
+ bool Pre(const parser::OmpClause::To &);
+ bool Pre(const parser::OmpClause::From &);
bool Pre(const parser::OpenMPSectionsConstruct &) {
PushScope(Scope::Kind::OtherConstruct, nullptr);
@@ -1876,6 +1878,64 @@ bool OmpVisitor::Pre(const parser::OmpMapClause &x) {
return true;
}
+bool OmpVisitor::Pre(const parser::OmpClause::To &x) {
+ // Resolve mapper names in "to" clauses (e.g., for target update)
+ auto &mods{OmpGetModifiers(x.v)};
+ if (auto *mapper{OmpGetUniqueModifier<parser::OmpMapper>(mods)}) {
+ if (auto *symbol{FindSymbol(currScope(), mapper->v)}) {
+ auto &ultimate{symbol->GetUltimate()};
+ auto *misc{ultimate.detailsIf<MiscDetails>()};
+ auto *md{ultimate.detailsIf<MapperDetails>()};
+ if (!md && (!misc || misc->kind() != MiscDetails::Kind::ConstructName))
+ context().Say(mapper->v.source,
+ "Name '%s' should be a mapper name"_err_en_US, mapper->v.source);
+ else
+ mapper->v.symbol = symbol;
+ } else {
+ // Allow the special 'default' mapper identifier without prior
+ // declaration so lowering can recognize and handle it. Emit an
+ // error for any other missing mapper identifier.
+ if (mapper->v.source.ToString() == "default") {
+ mapper->v.symbol = &MakeSymbol(
+ mapper->v, MiscDetails{MiscDetails::Kind::ConstructName});
+ } else {
+ context().Say(
+ mapper->v.source, "'%s' not declared"_err_en_US, mapper->v.source);
+ }
+ }
+ }
+ return true;
+}
+
+bool OmpVisitor::Pre(const parser::OmpClause::From &x) {
+ // Resolve mapper names in "from" clauses (e.g., for target update)
+ auto &mods{OmpGetModifiers(x.v)};
+ if (auto *mapper{OmpGetUniqueModifier<parser::OmpMapper>(mods)}) {
+ if (auto *symbol{FindSymbol(currScope(), mapper->v)}) {
+ auto &ultimate{symbol->GetUltimate()};
+ auto *misc{ultimate.detailsIf<MiscDetails>()};
+ auto *md{ultimate.detailsIf<MapperDetails>()};
+ if (!md && (!misc || misc->kind() != MiscDetails::Kind::ConstructName))
+ context().Say(mapper->v.source,
+ "Name '%s' should be a mapper name"_err_en_US, mapper->v.source);
+ else
+ mapper->v.symbol = symbol;
+ } else {
+ // Allow the special 'default' mapper identifier without prior
+ // declaration so lowering can recognize and handle it. Emit an
+ // error for any other missing mapper identifier.
+ if (mapper->v.source.ToString() == "default") {
+ mapper->v.symbol = &MakeSymbol(
+ mapper->v, MiscDetails{MiscDetails::Kind::ConstructName});
+ } else {
+ context().Say(
+ mapper->v.source, "'%s' not declared"_err_en_US, mapper->v.source);
+ }
+ }
+ }
+ return true;
+}
+
void OmpVisitor::ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
const parser::OmpClauseList &clauses) {
// This "manually" walks the tree of the construct, because we need
diff --git a/flang/test/Lower/OpenMP/target-update-mapper.f90 b/flang/test/Lower/OpenMP/target-update-mapper.f90
new file mode 100644
index 0000000000000..d49ad51343679
--- /dev/null
+++ b/flang/test/Lower/OpenMP/target-update-mapper.f90
@@ -0,0 +1,52 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s
+
+! Test mapper usage in target update to/from clauses
+
+program target_update_mapper
+ implicit none
+
+ integer, parameter :: n = 4
+
+ type :: typ
+ integer, allocatable :: a(:)
+ integer, allocatable :: b(:)
+ end type typ
+
+ !$omp declare mapper(custom: typ :: t) map(t%a)
+
+ ! CHECK-LABEL: omp.declare_mapper @_QQFcustom : !fir.type<_QFTtyp{a:!fir.box<!fir.heap<!fir.array<?xi32>>>,b:!fir.box<!fir.heap<!fir.array<?xi32>>>}>
+
+ type(typ) :: t
+
+ allocate(t%a(n), source=1)
+ allocate(t%b(n), source=2)
+
+ !$omp target enter data map(alloc: t)
+
+ ! Test target update to with custom mapper
+ ! CHECK: %[[T_VAR:.*]] = fir.declare %{{.*}} {uniq_name = "_QFtarget_update_mapperEt"} : (!fir.ref<!fir.type<_QFTtyp{a:!fir.box<!fir.heap<!fir.array<?xi32>>>,b:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.type<_QFTtyp{a:!fir.box<!fir.heap<!fir.array<?xi32>>>,b:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
+ ! CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%[[T_VAR]] : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
+ ! CHECK: omp.target_update motion_entries(%[[MAP_INFO]] : {{.*}})
+ t%a = 42
+ !$omp target update to(mapper(custom): t)
+
+ !$omp target
+ t%a(:) = t%a(:) / 2
+ t%b(:) = -1
+ !$omp end target
+
+ ! Test target update from with custom mapper
+ ! CHECK: %[[MAP_INFO2:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(from) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
+ ! CHECK: omp.target_update motion_entries(%[[MAP_INFO2]] : {{.*}})
+ !$omp target update from(mapper(custom): t)
+
+ ! Test target update to with default mapper
+ ! CHECK: %[[MAP_INFO3:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFtyp_omp_default_mapper) -> {{.*}}
+ ! CHECK: omp.target_update motion_entries(%[[MAP_INFO3]] : {{.*}})
+ !$omp target update to(mapper(default): t)
+
+ !$omp target exit data map(delete: t)
+ deallocate(t%a)
+ deallocate(t%b)
+
+end program target_update_mapper
diff --git a/flang/test/Semantics/OpenMP/target-update-mapper.f90 b/flang/test/Semantics/OpenMP/target-update-mapper.f90
new file mode 100644
index 0000000000000..f03496e155568
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/target-update-mapper.f90
@@ -0,0 +1,54 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=52
+
+! Test mapper usage in target update to/from clauses
+
+program target_update_mapper
+ implicit none
+
+ integer, parameter :: n = 4
+
+ type :: typ
+ integer, allocatable :: a(:)
+ integer, allocatable :: b(:)
+ end type typ
+
+ !$omp declare mapper(custom: typ :: t) map(t%a)
+
+ type(typ) :: t
+ integer :: not_a_mapper
+ allocate(t%a(n), source=1)
+ allocate(t%b(n), source=2)
+
+ !$omp target enter data map(alloc: t)
+
+ ! Valid: using custom mapper with target update to
+ t%a = 42
+ !$omp target update to(mapper(custom): t)
+
+ !$omp target
+ t%a(:) = t%a(:) / 2
+ t%b(:) = -1
+ !$omp end target
+
+ ! Valid: using custom mapper with target update from
+ !$omp target update from(mapper(custom): t)
+
+ ! Valid: using default mapper explicitly
+ !$omp target update to(mapper(default): t)
+
+ print*, t%a
+ print*, t%b
+
+ !$omp target exit data map(delete: t)
+ deallocate(t%a)
+ deallocate(t%b)
+
+ ! Test error case: undefined mapper
+ !ERROR: 'undefined_mapper' not declared
+ !$omp target update to(mapper(undefined_mapper): t)
+
+ ! Test error case: wrong kind of symbol
+ !ERROR: Name 'not_a_mapper' should be a mapper name
+ !$omp target update from(mapper(not_a_mapper): t)
+
+end program target_update_mapper
>From f3782239b434b9fd8b1219bfebc8e3a1dfbeaeba Mon Sep 17 00:00:00 2001
From: Krish Gupta <krishgupta at Krishs-MacBook-Air.local>
Date: Wed, 26 Nov 2025 22:37:45 +0530
Subject: [PATCH 2/3] [flang][OpenMP] Implement mapper lowering for target
update
Support mapper modifier in processMotionClauses for to/from clauses
---
flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 29 ++++++++++++++-----
.../Lower/OpenMP/target-update-mapper.f90 | 9 +++---
2 files changed, 25 insertions(+), 13 deletions(-)
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index dd0cb3c42ba26..f9490555644b2 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1548,21 +1548,34 @@ bool ClauseProcessor::processMotionClauses(lower::StatementContext &stmtCtx,
mlir::Location clauseLocation = converter.genLocation(source);
const auto &[expectation, mapper, iterator, objects] = clause.t;
- // TODO Support motion modifiers: mapper, iterator.
- if (mapper) {
- TODO(clauseLocation, "Mapper modifier is not supported yet");
- } else if (iterator) {
- TODO(clauseLocation, "Iterator modifier is not supported yet");
- }
-
mlir::omp::ClauseMapFlags mapTypeBits =
std::is_same_v<llvm::remove_cvref_t<decltype(clause)>, omp::clause::To>
? mlir::omp::ClauseMapFlags::to
: mlir::omp::ClauseMapFlags::from;
if (expectation && *expectation == omp::clause::To::Expectation::Present)
mapTypeBits |= mlir::omp::ClauseMapFlags::present;
+
+ // Support motion modifiers: mapper, iterator.
+ std::string mapperIdName = "__implicit_mapper";
+ if (mapper) {
+ // Only one mapper is allowed by the parser here.
+ assert(mapper->size() == 1 && "more than one mapper");
+ const semantics::Symbol *mapperSym = mapper->front().v.id().symbol;
+ mapperIdName = mapperSym->name().ToString();
+ if (mapperIdName != "default") {
+ // Mangle with the ultimate owner so that use-associated mapper
+ // identifiers resolve to the same symbol as their defining scope.
+ const semantics::Symbol &ultimate = mapperSym->GetUltimate();
+ mapperIdName = converter.mangleName(mapperIdName, ultimate.owner());
+ }
+ }
+ if (iterator) {
+ TODO(clauseLocation, "Iterator modifier is not supported yet");
+ }
+
processMapObjects(stmtCtx, clauseLocation, objects, mapTypeBits,
- parentMemberIndices, result.mapVars, mapSymbols);
+ parentMemberIndices, result.mapVars, mapSymbols,
+ mapperIdName);
};
bool clauseFound = findRepeatableClause<omp::clause::To>(callbackFn);
diff --git a/flang/test/Lower/OpenMP/target-update-mapper.f90 b/flang/test/Lower/OpenMP/target-update-mapper.f90
index d49ad51343679..df23ea79c08f2 100644
--- a/flang/test/Lower/OpenMP/target-update-mapper.f90
+++ b/flang/test/Lower/OpenMP/target-update-mapper.f90
@@ -24,9 +24,8 @@ program target_update_mapper
!$omp target enter data map(alloc: t)
! Test target update to with custom mapper
- ! CHECK: %[[T_VAR:.*]] = fir.declare %{{.*}} {uniq_name = "_QFtarget_update_mapperEt"} : (!fir.ref<!fir.type<_QFTtyp{a:!fir.box<!fir.heap<!fir.array<?xi32>>>,b:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.type<_QFTtyp{a:!fir.box<!fir.heap<!fir.array<?xi32>>>,b:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
- ! CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%[[T_VAR]] : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
- ! CHECK: omp.target_update motion_entries(%[[MAP_INFO]] : {{.*}})
+ ! CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
+ ! CHECK: omp.target_update map_entries(%[[MAP_INFO]] : {{.*}})
t%a = 42
!$omp target update to(mapper(custom): t)
@@ -37,12 +36,12 @@ program target_update_mapper
! Test target update from with custom mapper
! CHECK: %[[MAP_INFO2:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(from) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
- ! CHECK: omp.target_update motion_entries(%[[MAP_INFO2]] : {{.*}})
+ ! CHECK: omp.target_update map_entries(%[[MAP_INFO2]] : {{.*}})
!$omp target update from(mapper(custom): t)
! Test target update to with default mapper
! CHECK: %[[MAP_INFO3:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFtyp_omp_default_mapper) -> {{.*}}
- ! CHECK: omp.target_update motion_entries(%[[MAP_INFO3]] : {{.*}})
+ ! CHECK: omp.target_update map_entries(%[[MAP_INFO3]] : {{.*}})
!$omp target update to(mapper(default): t)
!$omp target exit data map(delete: t)
>From d17b0ca8204a209ba2e55fa92a0cfe62e3982a21 Mon Sep 17 00:00:00 2001
From: Krish Gupta <krishgupta at Krishs-MacBook-Air.local>
Date: Fri, 28 Nov 2025 00:32:22 +0530
Subject: [PATCH 3/3] [flang][OpenMP] Refactor mapper resolution per review
Extract ResolveMapperModifier helper and simplify tests
---
flang/lib/Semantics/resolve-names.cpp | 94 ++++++-------------
flang/test/Lower/OpenMP/declare-mapper.f90 | 34 +++++++
.../Lower/OpenMP/target-update-mapper.f90 | 51 ----------
.../Semantics/OpenMP/target-update-mapper.f90 | 36 ++-----
4 files changed, 67 insertions(+), 148 deletions(-)
delete mode 100644 flang/test/Lower/OpenMP/target-update-mapper.f90
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index ca17767dce924..a870d821e830f 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1779,6 +1779,7 @@ class OmpVisitor : public virtual DeclarationVisitor {
}
private:
+ void ResolveMapperModifier(parser::OmpMapper &mapper);
void ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
const parser::OmpClauseList &clauses);
void ProcessReductionSpecifier(const parser::OmpReductionSpecifier &spec,
@@ -1850,90 +1851,49 @@ void OmpVisitor::Post(const parser::OmpStylizedInstance &x) { //
bool OmpVisitor::Pre(const parser::OmpMapClause &x) {
auto &mods{OmpGetModifiers(x)};
if (auto *mapper{OmpGetUniqueModifier<parser::OmpMapper>(mods)}) {
- if (auto *symbol{FindSymbol(currScope(), mapper->v)}) {
- // TODO: Do we need a specific flag or type here, to distinghuish against
- // other ConstructName things? Leaving this for the full implementation
- // of mapper lowering.
- auto &ultimate{symbol->GetUltimate()};
- auto *misc{ultimate.detailsIf<MiscDetails>()};
- auto *md{ultimate.detailsIf<MapperDetails>()};
- if (!md && (!misc || misc->kind() != MiscDetails::Kind::ConstructName))
- context().Say(mapper->v.source,
- "Name '%s' should be a mapper name"_err_en_US, mapper->v.source);
- else
- mapper->v.symbol = symbol;
- } else {
- // Allow the special 'default' mapper identifier without prior
- // declaration so lowering can recognize and handle it. Emit an
- // error for any other missing mapper identifier.
- if (mapper->v.source.ToString() == "default") {
- mapper->v.symbol = &MakeSymbol(
- mapper->v, MiscDetails{MiscDetails::Kind::ConstructName});
- } else {
- context().Say(
- mapper->v.source, "'%s' not declared"_err_en_US, mapper->v.source);
- }
- }
+ ResolveMapperModifier(const_cast<parser::OmpMapper &>(*mapper));
}
return true;
}
bool OmpVisitor::Pre(const parser::OmpClause::To &x) {
- // Resolve mapper names in "to" clauses (e.g., for target update)
auto &mods{OmpGetModifiers(x.v)};
if (auto *mapper{OmpGetUniqueModifier<parser::OmpMapper>(mods)}) {
- if (auto *symbol{FindSymbol(currScope(), mapper->v)}) {
- auto &ultimate{symbol->GetUltimate()};
- auto *misc{ultimate.detailsIf<MiscDetails>()};
- auto *md{ultimate.detailsIf<MapperDetails>()};
- if (!md && (!misc || misc->kind() != MiscDetails::Kind::ConstructName))
- context().Say(mapper->v.source,
- "Name '%s' should be a mapper name"_err_en_US, mapper->v.source);
- else
- mapper->v.symbol = symbol;
- } else {
- // Allow the special 'default' mapper identifier without prior
- // declaration so lowering can recognize and handle it. Emit an
- // error for any other missing mapper identifier.
- if (mapper->v.source.ToString() == "default") {
- mapper->v.symbol = &MakeSymbol(
- mapper->v, MiscDetails{MiscDetails::Kind::ConstructName});
- } else {
- context().Say(
- mapper->v.source, "'%s' not declared"_err_en_US, mapper->v.source);
- }
- }
+ ResolveMapperModifier(const_cast<parser::OmpMapper &>(*mapper));
}
return true;
}
bool OmpVisitor::Pre(const parser::OmpClause::From &x) {
- // Resolve mapper names in "from" clauses (e.g., for target update)
auto &mods{OmpGetModifiers(x.v)};
if (auto *mapper{OmpGetUniqueModifier<parser::OmpMapper>(mods)}) {
- if (auto *symbol{FindSymbol(currScope(), mapper->v)}) {
- auto &ultimate{symbol->GetUltimate()};
- auto *misc{ultimate.detailsIf<MiscDetails>()};
- auto *md{ultimate.detailsIf<MapperDetails>()};
- if (!md && (!misc || misc->kind() != MiscDetails::Kind::ConstructName))
- context().Say(mapper->v.source,
- "Name '%s' should be a mapper name"_err_en_US, mapper->v.source);
- else
- mapper->v.symbol = symbol;
+ ResolveMapperModifier(const_cast<parser::OmpMapper &>(*mapper));
+ }
+ return true;
+}
+
+void OmpVisitor::ResolveMapperModifier(parser::OmpMapper &mapper) {
+ if (auto *symbol{FindSymbol(currScope(), mapper.v)}) {
+ auto &ultimate{symbol->GetUltimate()};
+ auto *misc{ultimate.detailsIf<MiscDetails>()};
+ auto *md{ultimate.detailsIf<MapperDetails>()};
+ if (!md && (!misc || misc->kind() != MiscDetails::Kind::ConstructName))
+ context().Say(mapper.v.source,
+ "Name '%s' should be a mapper name"_err_en_US, mapper.v.source);
+ else
+ mapper.v.symbol = symbol;
+ } else {
+ // Allow the special 'default' mapper identifier without prior
+ // declaration so lowering can recognize and handle it. Emit an
+ // error for any other missing mapper identifier.
+ if (mapper.v.source.ToString() == "default") {
+ mapper.v.symbol = &MakeSymbol(
+ mapper.v, MiscDetails{MiscDetails::Kind::ConstructName});
} else {
- // Allow the special 'default' mapper identifier without prior
- // declaration so lowering can recognize and handle it. Emit an
- // error for any other missing mapper identifier.
- if (mapper->v.source.ToString() == "default") {
- mapper->v.symbol = &MakeSymbol(
- mapper->v, MiscDetails{MiscDetails::Kind::ConstructName});
- } else {
- context().Say(
- mapper->v.source, "'%s' not declared"_err_en_US, mapper->v.source);
- }
+ context().Say(
+ mapper.v.source, "'%s' not declared"_err_en_US, mapper.v.source);
}
}
- return true;
}
void OmpVisitor::ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
diff --git a/flang/test/Lower/OpenMP/declare-mapper.f90 b/flang/test/Lower/OpenMP/declare-mapper.f90
index 7eda1a4c497be..a2f228811e8f9 100644
--- a/flang/test/Lower/OpenMP/declare-mapper.f90
+++ b/flang/test/Lower/OpenMP/declare-mapper.f90
@@ -11,6 +11,7 @@
! 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
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %t/omp-declare-mapper-9.f90 -o - | FileCheck %t/omp-declare-mapper-9.f90
!--- omp-declare-mapper-1.f90
subroutine declare_mapper_1
@@ -360,3 +361,36 @@ program use_module_default_mapper
a%x = 8
!$omp end target
end program use_module_default_mapper
+
+!--- omp-declare-mapper-9.f90
+! Test mapper usage in target update to/from clauses
+program target_update_mapper
+ type :: typ
+ integer :: a
+ integer :: b
+ end type typ
+
+ !CHECK: omp.declare_mapper @_QQFtarget_update_mapperFtyp_omp_default_mapper : !fir.type<_QFtarget_update_mapperTtyp{a:i32,b:i32}>
+ !CHECK: omp.declare_mapper @_QQFtarget_update_mapperFcustom : !fir.type<_QFtarget_update_mapperTtyp{a:i32,b:i32}>
+
+ !$omp declare mapper(typ :: t) map(t%a, t%b)
+ !$omp declare mapper(custom: typ :: t) map(t%a)
+
+ type(typ) :: t
+
+ ! Test target update to with custom mapper
+ !CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFtarget_update_mapperFcustom) -> {{.*}}
+ !CHECK: omp.target_update map_entries(%[[MAP_INFO]] : {{.*}})
+ !$omp target update to(mapper(custom): t)
+
+ ! Test target update from with custom mapper
+ !CHECK: %[[MAP_INFO2:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(from) capture(ByRef) mapper(@_QQFtarget_update_mapperFcustom) -> {{.*}}
+ !CHECK: omp.target_update map_entries(%[[MAP_INFO2]] : {{.*}})
+ !$omp target update from(mapper(custom): t)
+
+ ! Test target update to with default mapper
+ !CHECK: %[[MAP_INFO3:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFtarget_update_mapperFtyp_omp_default_mapper) -> {{.*}}
+ !CHECK: omp.target_update map_entries(%[[MAP_INFO3]] : {{.*}})
+ !$omp target update to(mapper(default): t)
+
+end program target_update_mapper
diff --git a/flang/test/Lower/OpenMP/target-update-mapper.f90 b/flang/test/Lower/OpenMP/target-update-mapper.f90
deleted file mode 100644
index df23ea79c08f2..0000000000000
--- a/flang/test/Lower/OpenMP/target-update-mapper.f90
+++ /dev/null
@@ -1,51 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s
-
-! Test mapper usage in target update to/from clauses
-
-program target_update_mapper
- implicit none
-
- integer, parameter :: n = 4
-
- type :: typ
- integer, allocatable :: a(:)
- integer, allocatable :: b(:)
- end type typ
-
- !$omp declare mapper(custom: typ :: t) map(t%a)
-
- ! CHECK-LABEL: omp.declare_mapper @_QQFcustom : !fir.type<_QFTtyp{a:!fir.box<!fir.heap<!fir.array<?xi32>>>,b:!fir.box<!fir.heap<!fir.array<?xi32>>>}>
-
- type(typ) :: t
-
- allocate(t%a(n), source=1)
- allocate(t%b(n), source=2)
-
- !$omp target enter data map(alloc: t)
-
- ! Test target update to with custom mapper
- ! CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
- ! CHECK: omp.target_update map_entries(%[[MAP_INFO]] : {{.*}})
- t%a = 42
- !$omp target update to(mapper(custom): t)
-
- !$omp target
- t%a(:) = t%a(:) / 2
- t%b(:) = -1
- !$omp end target
-
- ! Test target update from with custom mapper
- ! CHECK: %[[MAP_INFO2:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(from) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
- ! CHECK: omp.target_update map_entries(%[[MAP_INFO2]] : {{.*}})
- !$omp target update from(mapper(custom): t)
-
- ! Test target update to with default mapper
- ! CHECK: %[[MAP_INFO3:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFtyp_omp_default_mapper) -> {{.*}}
- ! CHECK: omp.target_update map_entries(%[[MAP_INFO3]] : {{.*}})
- !$omp target update to(mapper(default): t)
-
- !$omp target exit data map(delete: t)
- deallocate(t%a)
- deallocate(t%b)
-
-end program target_update_mapper
diff --git a/flang/test/Semantics/OpenMP/target-update-mapper.f90 b/flang/test/Semantics/OpenMP/target-update-mapper.f90
index f03496e155568..f37d288670594 100644
--- a/flang/test/Semantics/OpenMP/target-update-mapper.f90
+++ b/flang/test/Semantics/OpenMP/target-update-mapper.f90
@@ -1,53 +1,29 @@
! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=52
-! Test mapper usage in target update to/from clauses
+! Test mapper name resolution in target update to/from clauses
program target_update_mapper
- implicit none
-
- integer, parameter :: n = 4
-
type :: typ
- integer, allocatable :: a(:)
- integer, allocatable :: b(:)
+ integer :: a
end type typ
!$omp declare mapper(custom: typ :: t) map(t%a)
type(typ) :: t
integer :: not_a_mapper
- allocate(t%a(n), source=1)
- allocate(t%b(n), source=2)
- !$omp target enter data map(alloc: t)
-
- ! Valid: using custom mapper with target update to
- t%a = 42
+ ! Valid: using custom mapper
!$omp target update to(mapper(custom): t)
-
- !$omp target
- t%a(:) = t%a(:) / 2
- t%b(:) = -1
- !$omp end target
-
- ! Valid: using custom mapper with target update from
!$omp target update from(mapper(custom): t)
- ! Valid: using default mapper explicitly
+ ! Valid: using default mapper
!$omp target update to(mapper(default): t)
- print*, t%a
- print*, t%b
-
- !$omp target exit data map(delete: t)
- deallocate(t%a)
- deallocate(t%b)
-
- ! Test error case: undefined mapper
+ ! Error: undefined mapper
!ERROR: 'undefined_mapper' not declared
!$omp target update to(mapper(undefined_mapper): t)
- ! Test error case: wrong kind of symbol
+ ! Error: wrong kind of symbol
!ERROR: Name 'not_a_mapper' should be a mapper name
!$omp target update from(mapper(not_a_mapper): t)
More information about the flang-commits
mailing list