[flang-commits] [flang] 6d1c183 - [Flang] [OpenMP] [Semantics] Add missing semantic check for MAP clause.
Raghu Maddhipatla via flang-commits
flang-commits at lists.llvm.org
Thu Sep 7 13:42:30 PDT 2023
Author: Raghu Maddhipatla
Date: 2023-09-07T15:42:25-05:00
New Revision: 6d1c183c6f8be717e466f6c55f74729d178c8ee2
URL: https://github.com/llvm/llvm-project/commit/6d1c183c6f8be717e466f6c55f74729d178c8ee2
DIFF: https://github.com/llvm/llvm-project/commit/6d1c183c6f8be717e466f6c55f74729d178c8ee2.diff
LOG: [Flang] [OpenMP] [Semantics] Add missing semantic check for MAP clause.
Added support for following semantic check for MAP clause.
- A list item cannot appear in both a map clause and a data-sharing attribute clause on the same target construct.
Reviewed By: NimishMishra
Differential Revision: https://reviews.llvm.org/D158807
Added:
flang/test/Semantics/OpenMP/target01.f90
flang/test/Semantics/OpenMP/target02.f90
Modified:
flang/include/flang/Semantics/symbol.h
flang/lib/Semantics/resolve-directives.cpp
flang/lib/Semantics/symbol.cpp
flang/test/Semantics/OpenMP/firstprivate01.f90
flang/test/Semantics/OpenMP/symbol08.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 1ba489fe21a7227..7280a4eaa5fca57 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -643,8 +643,8 @@ class Symbol {
// OpenMP data-sharing attribute
OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
// OpenMP data-mapping attribute
- OmpMapTo, OmpMapFrom, OmpMapAlloc, OmpMapRelease, OmpMapDelete,
- OmpUseDevicePtr, OmpUseDeviceAddr,
+ OmpMapTo, OmpMapFrom, OmpMapToFrom, OmpMapAlloc, OmpMapRelease,
+ OmpMapDelete, OmpUseDevicePtr, OmpUseDeviceAddr,
// OpenMP data-copying attribute
OmpCopyIn, OmpCopyPrivate,
// OpenMP miscellaneous flags
@@ -674,6 +674,7 @@ class Symbol {
void set_offset(std::size_t offset) { offset_ = offset; }
// Give the symbol a name with a
diff erent source location but same chars.
void ReplaceName(const SourceName &);
+ std::string OmpFlagToClauseName(Flag ompFlag);
// Does symbol have this type of details?
template <typename D> bool has() const {
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 84f00ef82755ef9..38beae33f40e95a 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -529,6 +529,34 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
void Post(const parser::EorLabel &eorLabel) { CheckSourceLabel(eorLabel.v); }
void Post(const parser::OmpMapClause &x) {
+ Symbol::Flag ompFlag = Symbol::Flag::OmpMapToFrom;
+ if (const auto &maptype{std::get<std::optional<parser::OmpMapType>>(x.t)}) {
+ using Type = parser::OmpMapType::Type;
+ const Type &type{std::get<Type>(maptype->t)};
+ switch (type) {
+ case Type::To:
+ ompFlag = Symbol::Flag::OmpMapTo;
+ break;
+ case Type::From:
+ ompFlag = Symbol::Flag::OmpMapFrom;
+ break;
+ case Type::Tofrom:
+ ompFlag = Symbol::Flag::OmpMapToFrom;
+ break;
+ case Type::Alloc:
+ ompFlag = Symbol::Flag::OmpMapAlloc;
+ break;
+ case Type::Release:
+ ompFlag = Symbol::Flag::OmpMapRelease;
+ break;
+ case Type::Delete:
+ ompFlag = Symbol::Flag::OmpMapDelete;
+ break;
+ default:
+ assert(false && "Unsupported map-type");
+ break;
+ }
+ }
const auto &ompObjList{std::get<parser::OmpObjectList>(x.t)};
for (const auto &ompObj : ompObjList.v) {
common::visit(
@@ -536,6 +564,10 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
[&](const parser::Designator &designator) {
if (const auto *name{
semantics::getDesignatorNameIfDataRef(designator)}) {
+ if (name->symbol) {
+ name->symbol->set(ompFlag);
+ AddToContextObjectWithDSA(*name->symbol, ompFlag);
+ }
if (name->symbol &&
semantics::IsAssumedSizeArray(*name->symbol)) {
context_.Say(designator.source,
@@ -1908,6 +1940,27 @@ void OmpAttributeVisitor::ResolveOmpObject(
if (const auto *name{
semantics::getDesignatorNameIfDataRef(designator)}) {
if (auto *symbol{ResolveOmp(*name, ompFlag, currScope())}) {
+ auto checkExclusivelists =
+ [&](const Symbol *symbol1, Symbol::Flag firstOmpFlag,
+ Symbol *symbol2, Symbol::Flag secondOmpFlag) {
+ if ((symbol1->test(firstOmpFlag) &&
+ symbol2->test(secondOmpFlag)) ||
+ (symbol1->test(secondOmpFlag) &&
+ symbol2->test(firstOmpFlag))) {
+ context_.Say(designator.source,
+ "Variable '%s' may not "
+ "appear on both %s and %s "
+ "clauses on a %s construct"_err_en_US,
+ symbol2->name(),
+ const_cast<Symbol *>(symbol1)->OmpFlagToClauseName(
+ firstOmpFlag),
+ symbol2->OmpFlagToClauseName(secondOmpFlag),
+ parser::ToUpperCaseLetters(
+ llvm::omp::getOpenMPDirectiveName(
+ GetContext().directive)
+ .str()));
+ }
+ };
if (dataCopyingAttributeFlags.test(ompFlag)) {
CheckDataCopyingClause(*name, *symbol, ompFlag);
} else {
@@ -1943,28 +1996,37 @@ void OmpAttributeVisitor::ResolveOmpObject(
GetContext().directive)
.str()));
}
- if ((GetContext().directive ==
- llvm::omp::Directive::OMPD_target_data) &&
- (((ompFlag == Symbol::Flag::OmpUseDevicePtr) &&
- symbol->test(Symbol::Flag::OmpUseDeviceAddr)) ||
- ((ompFlag == Symbol::Flag::OmpUseDeviceAddr) &&
- symbol->test(Symbol::Flag::OmpUseDevicePtr)))) {
- context_.Say(designator.source,
- "Variable '%s' may not "
- "appear on both USE_DEVICE_PTR and USE_DEVICE_ADDR "
- "clauses on a TARGET DATA construct"_err_en_US,
- symbol->name());
+ if (GetContext().directive ==
+ llvm::omp::Directive::OMPD_target_data) {
+ checkExclusivelists(symbol, Symbol::Flag::OmpUseDevicePtr,
+ symbol, Symbol::Flag::OmpUseDeviceAddr);
}
- if (llvm::omp::allDistributeSet.test(GetContext().directive) &&
- (((ompFlag == Symbol::Flag::OmpFirstPrivate) &&
- symbol->test(Symbol::Flag::OmpLastPrivate)) ||
- ((ompFlag == Symbol::Flag::OmpLastPrivate) &&
- symbol->test(Symbol::Flag::OmpFirstPrivate)))) {
- context_.Say(designator.source,
- "Variable '%s' may not "
- "appear on both FIRSTPRIVATE and LASTPRIVATE "
- "clauses on a DISTRIBUTE construct"_err_en_US,
- symbol->name());
+ if (llvm::omp::allDistributeSet.test(GetContext().directive)) {
+ checkExclusivelists(symbol, Symbol::Flag::OmpFirstPrivate,
+ symbol, Symbol::Flag::OmpLastPrivate);
+ }
+ if (llvm::omp::allTargetSet.test(GetContext().directive)) {
+ const auto *hostAssocSym{symbol};
+ if (const auto *details{
+ symbol->detailsIf<HostAssocDetails>()}) {
+ hostAssocSym = &details->symbol();
+ }
+ Symbol::Flag dataMappingAttributeFlags[] = {
+ Symbol::Flag::OmpMapTo, Symbol::Flag::OmpMapFrom,
+ Symbol::Flag::OmpMapToFrom, Symbol::Flag::OmpMapAlloc,
+ Symbol::Flag::OmpMapRelease, Symbol::Flag::OmpMapDelete};
+
+ Symbol::Flag dataSharingAttributeFlags[] = {
+ Symbol::Flag::OmpPrivate, Symbol::Flag::OmpFirstPrivate,
+ Symbol::Flag::OmpLastPrivate, Symbol::Flag::OmpShared,
+ Symbol::Flag::OmpLinear};
+
+ for (Symbol::Flag ompFlag1 : dataMappingAttributeFlags) {
+ for (Symbol::Flag ompFlag2 : dataSharingAttributeFlags) {
+ checkExclusivelists(
+ hostAssocSym, ompFlag1, symbol, ompFlag2);
+ }
+ }
}
}
} else {
diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp
index 211b7f80b2a6767..2e14b2e8a19559c 100644
--- a/flang/lib/Semantics/symbol.cpp
+++ b/flang/lib/Semantics/symbol.cpp
@@ -757,6 +757,51 @@ bool GenericKind::Is(GenericKind::OtherKind x) const {
return y && *y == x;
}
+std::string Symbol::OmpFlagToClauseName(Symbol::Flag ompFlag) {
+ std::string clauseName;
+ switch (ompFlag) {
+ case Symbol::Flag::OmpShared:
+ clauseName = "SHARED";
+ break;
+ case Symbol::Flag::OmpPrivate:
+ clauseName = "PRIVATE";
+ break;
+ case Symbol::Flag::OmpLinear:
+ clauseName = "LINEAR";
+ break;
+ case Symbol::Flag::OmpFirstPrivate:
+ clauseName = "FIRSTPRIVATE";
+ break;
+ case Symbol::Flag::OmpLastPrivate:
+ clauseName = "LASTPRIVATE";
+ break;
+ case Symbol::Flag::OmpMapTo:
+ case Symbol::Flag::OmpMapFrom:
+ case Symbol::Flag::OmpMapToFrom:
+ case Symbol::Flag::OmpMapAlloc:
+ case Symbol::Flag::OmpMapRelease:
+ case Symbol::Flag::OmpMapDelete:
+ clauseName = "MAP";
+ break;
+ case Symbol::Flag::OmpUseDevicePtr:
+ clauseName = "USE_DEVICE_PTR";
+ break;
+ case Symbol::Flag::OmpUseDeviceAddr:
+ clauseName = "USE_DEVICE_ADDR";
+ break;
+ case Symbol::Flag::OmpCopyIn:
+ clauseName = "COPYIN";
+ break;
+ case Symbol::Flag::OmpCopyPrivate:
+ clauseName = "COPYPRIVATE";
+ break;
+ default:
+ clauseName = "";
+ break;
+ }
+ return clauseName;
+}
+
bool SymbolOffsetCompare::operator()(
const SymbolRef &x, const SymbolRef &y) const {
const Symbol *xCommon{FindCommonBlockContaining(*x)};
diff --git a/flang/test/Semantics/OpenMP/firstprivate01.f90 b/flang/test/Semantics/OpenMP/firstprivate01.f90
index 166c91165a78de2..0c576a9f07a4251 100644
--- a/flang/test/Semantics/OpenMP/firstprivate01.f90
+++ b/flang/test/Semantics/OpenMP/firstprivate01.f90
@@ -38,27 +38,27 @@ program omp_firstprivate
a(i) = a(i) + b(i) - i
end do
!$omp end teams distribute
- !ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a DISTRIBUTE construct
+ !ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
!$omp teams distribute firstprivate(a,b) lastprivate(b)
do i = 1, 10
a(i) = a(i) + b(i) - i
end do
!$omp end teams distribute
- !ERROR: Variable 'a' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a DISTRIBUTE construct
- !ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a DISTRIBUTE construct
+ !ERROR: Variable 'a' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
+ !ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
!$omp teams distribute firstprivate(a,b) lastprivate(a,b)
do i = 1, 10
a(i) = a(i) + b(i) - i
end do
!$omp end teams distribute
- !ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a DISTRIBUTE construct
+ !ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
!$omp teams distribute lastprivate(a,b) firstprivate(b)
do i = 1, 10
a(i) = a(i) + b(i) - i
end do
!$omp end teams distribute
- !ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a DISTRIBUTE construct
- !ERROR: Variable 'a' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a DISTRIBUTE construct
+ !ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
+ !ERROR: Variable 'a' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
!$omp teams distribute lastprivate(a,b) firstprivate(b,a)
do i = 1, 10
a(i) = a(i) + b(i) - i
diff --git a/flang/test/Semantics/OpenMP/symbol08.f90 b/flang/test/Semantics/OpenMP/symbol08.f90
index 5c5aa4f24dd2e44..b80c94a9f189ae7 100644
--- a/flang/test/Semantics/OpenMP/symbol08.f90
+++ b/flang/test/Semantics/OpenMP/symbol08.f90
@@ -106,8 +106,8 @@ end subroutine test_taskloop
! Rule a); OpenMP 4.5 Examples teams.2.f90
! TODO: reduction; data-mapping attributes
!DEF: /dotprod (Subroutine) Subprogram
-!DEF: /dotprod/b ObjectEntity REAL(4)
-!DEF: /dotprod/c ObjectEntity REAL(4)
+!DEF: /dotprod/b (OmpMapTo) ObjectEntity REAL(4)
+!DEF: /dotprod/c (OmpMapTo) ObjectEntity REAL(4)
!DEF: /dotprod/n ObjectEntity INTEGER(4)
!DEF: /dotprod/block_size ObjectEntity INTEGER(4)
!DEF: /dotprod/num_teams ObjectEntity INTEGER(4)
@@ -119,7 +119,7 @@ subroutine dotprod (b, c, n, block_size, num_teams, block_threads)
!REF: /dotprod/b
!REF: /dotprod/n
!REF: /dotprod/c
- !DEF: /dotprod/sum ObjectEntity REAL(4)
+ !DEF: /dotprod/sum (OmpMapToFrom) ObjectEntity REAL(4)
real b(n), c(n), sum
!REF: /dotprod/block_size
!REF: /dotprod/num_teams
diff --git a/flang/test/Semantics/OpenMP/target01.f90 b/flang/test/Semantics/OpenMP/target01.f90
new file mode 100644
index 000000000000000..8418381740250b0
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/target01.f90
@@ -0,0 +1,10 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+
+integer :: x
+!ERROR: Variable 'x' may not appear on both MAP and PRIVATE clauses on a TARGET construct
+!$omp target map(x) private(x)
+x = x + 1
+!$omp end target
+
+end
diff --git a/flang/test/Semantics/OpenMP/target02.f90 b/flang/test/Semantics/OpenMP/target02.f90
new file mode 100644
index 000000000000000..06ce1c0875cc975
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/target02.f90
@@ -0,0 +1,17 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+
+program p
+integer :: y
+!ERROR: Variable 'y' may not appear on both MAP and FIRSTPRIVATE clauses on a TARGET construct
+!$omp target map(y) firstprivate(y)
+y = y + 1
+!$omp end target
+!ERROR: Variable 'y' may not appear on both MAP and FIRSTPRIVATE clauses on a TARGET SIMD construct
+!$omp target simd map(y) firstprivate(y)
+do i=1,1
+ y = y + 1
+end do
+!$omp end target simd
+
+end program p
More information about the flang-commits
mailing list