[flang-commits] [llvm] [flang] [flang][OpenMP] Add semantic check for declare target (PR #71861)
via flang-commits
flang-commits at lists.llvm.org
Thu Nov 9 12:24:32 PST 2023
https://github.com/shraiysh created https://github.com/llvm/llvm-project/pull/71861
This patch adds the following check from OpenMP 5.2.
```
If the directive has a clause, it must contain at least one enter clause
or at least one link clause.
```
Also added a warning for the deprication of `TO` clause on `DECLARE TARGET` construct.
```
The clause-name to may be used as a synonym for the clause-name enter.
This use has been deprecated.
```
>From bb2cf5f9695436a4fadb0e52cc274818c755c57b Mon Sep 17 00:00:00 2001
From: Shraiysh Vaishay <shraiysh.vaishay at amd.com>
Date: Thu, 9 Nov 2023 14:19:05 -0600
Subject: [PATCH] [flang][OpenMP] Add semantic check for declare target
This patch adds the following check from OpenMP 5.2.
```
If the directive has a clause, it must contain at least one enter clause
or at least one link clause.
```
Also added a warning for the deprication of `TO` clause on `DECLARE
TARGET` construct.
```
The clause-name to may be used as a synonym for the clause-name enter.
This use has been deprecated.
```
---
flang/lib/Parser/openmp-parsers.cpp | 2 +
flang/lib/Semantics/check-omp-structure.cpp | 38 ++++++++++++++++---
flang/lib/Semantics/check-omp-structure.h | 2 +
.../OpenMP/declare_target-device_type.f90 | 13 ++++---
.../OpenMP/declarative-directive.f90 | 5 ++-
.../Semantics/OpenMP/declare-target01.f90 | 27 +++++++------
.../Semantics/OpenMP/declare-target02.f90 | 30 +++++++--------
.../Semantics/OpenMP/declare-target06.f90 | 2 +-
flang/test/Semantics/OpenMP/requires04.f90 | 3 +-
flang/test/Semantics/OpenMP/requires05.f90 | 2 +-
llvm/include/llvm/Frontend/OpenMP/OMP.td | 6 ++-
11 files changed, 85 insertions(+), 45 deletions(-)
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 0271f699a687ff0..bba1be27158ce7e 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -259,6 +259,8 @@ TYPE_PARSER(
parenthesized("STATIC" >> maybe("," >> scalarIntExpr)))) ||
"DYNAMIC_ALLOCATORS" >>
construct<OmpClause>(construct<OmpClause::DynamicAllocators>()) ||
+ "ENTER" >> construct<OmpClause>(construct<OmpClause::Enter>(
+ parenthesized(Parser<OmpObjectList>{}))) ||
"FINAL" >> construct<OmpClause>(construct<OmpClause::Final>(
parenthesized(scalarLogicalExpr))) ||
"FULL" >> construct<OmpClause>(construct<OmpClause::Full>()) ||
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index d7a0681d1c3d476..2cb938ab11d9f22 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1164,13 +1164,31 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Allocate &x) {
}
}
+void OmpStructureChecker::Enter(const parser::OmpDeclareTargetWithClause &x) {
+ SetClauseSets(llvm::omp::Directive::OMPD_declare_target);
+}
+
+void OmpStructureChecker::Leave(const parser::OmpDeclareTargetWithClause &x) {
+ if (x.v.v.size() > 0) {
+ const parser::OmpClause *enterClause =
+ FindClause(llvm::omp::Clause::OMPC_enter);
+ const parser::OmpClause *toClause = FindClause(llvm::omp::Clause::OMPC_to);
+ const parser::OmpClause *linkClause =
+ FindClause(llvm::omp::Clause::OMPC_link);
+ if (!enterClause && !toClause && !linkClause) {
+ context_.Say(x.source,
+ "If the DECLARE TARGET directive has a clause, it must contain at lease one ENTER clause or LINK clause"_err_en_US);
+ }
+ if (toClause) {
+ context_.Say(toClause->source,
+ "The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead."_warn_en_US);
+ }
+ }
+}
+
void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) {
const auto &dir{std::get<parser::Verbatim>(x.t)};
PushContext(dir.source, llvm::omp::Directive::OMPD_declare_target);
- const auto &spec{std::get<parser::OmpDeclareTargetSpecifier>(x.t)};
- if (std::holds_alternative<parser::OmpDeclareTargetWithClause>(spec.u)) {
- SetClauseSets(llvm::omp::Directive::OMPD_declare_target);
- }
}
void OmpStructureChecker::Enter(const parser::OmpDeclareTargetWithList &x) {
@@ -1244,7 +1262,8 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) {
CheckThreadprivateOrDeclareTargetVar(*objectList);
} else if (const auto *clauseList{
parser::Unwrap<parser::OmpClauseList>(spec.u)}) {
- bool toClauseFound{false}, deviceTypeClauseFound{false};
+ bool toClauseFound{false}, deviceTypeClauseFound{false},
+ enterClauseFound{false};
for (const auto &clause : clauseList->v) {
common::visit(
common::visitors{
@@ -1259,6 +1278,12 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) {
CheckIsVarPartOfAnotherVar(dir.source, linkClause.v);
CheckThreadprivateOrDeclareTargetVar(linkClause.v);
},
+ [&](const parser::OmpClause::Enter &enterClause) {
+ enterClauseFound = true;
+ CheckSymbolNames(dir.source, enterClause.v);
+ CheckIsVarPartOfAnotherVar(dir.source, enterClause.v);
+ CheckThreadprivateOrDeclareTargetVar(enterClause.v);
+ },
[&](const parser::OmpClause::DeviceType &deviceTypeClause) {
deviceTypeClauseFound = true;
if (deviceTypeClause.v.v !=
@@ -1272,7 +1297,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) {
},
clause.u);
- if (toClauseFound && !deviceTypeClauseFound) {
+ if ((toClauseFound || enterClauseFound) && !deviceTypeClauseFound) {
deviceConstructFound_ = true;
}
}
@@ -2227,6 +2252,7 @@ CHECK_SIMPLE_CLAUSE(CancellationConstructType, OMPC_cancellation_construct_type)
CHECK_SIMPLE_CLAUSE(Doacross, OMPC_doacross)
CHECK_SIMPLE_CLAUSE(OmpxAttribute, OMPC_ompx_attribute)
CHECK_SIMPLE_CLAUSE(OmpxBare, OMPC_ompx_bare)
+CHECK_SIMPLE_CLAUSE(Enter, OMPC_enter)
CHECK_REQ_SCALAR_INT_CLAUSE(Grainsize, OMPC_grainsize)
CHECK_REQ_SCALAR_INT_CLAUSE(NumTasks, OMPC_num_tasks)
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index d35602cca75d549..90e5c9f19127750 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -80,6 +80,8 @@ class OmpStructureChecker
void Enter(const parser::OpenMPDeclareTargetConstruct &);
void Leave(const parser::OpenMPDeclareTargetConstruct &);
void Enter(const parser::OmpDeclareTargetWithList &);
+ void Enter(const parser::OmpDeclareTargetWithClause &);
+ void Leave(const parser::OmpDeclareTargetWithClause &);
void Enter(const parser::OpenMPExecutableAllocate &);
void Leave(const parser::OpenMPExecutableAllocate &);
void Enter(const parser::OpenMPAllocatorsConstruct &);
diff --git a/flang/test/Parser/OpenMP/declare_target-device_type.f90 b/flang/test/Parser/OpenMP/declare_target-device_type.f90
index 2f6b68ab30f6e91..19e5accc4fc034f 100644
--- a/flang/test/Parser/OpenMP/declare_target-device_type.f90
+++ b/flang/test/Parser/OpenMP/declare_target-device_type.f90
@@ -2,12 +2,13 @@
! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s
subroutine openmp_declare_target
- !CHECK: !$omp declare target device_type(host)
- !$omp declare target device_type(host)
- !CHECK: !$omp declare target device_type(nohost)
- !$omp declare target device_type(nohost)
- !CHECK: !$omp declare target device_type(any)
- !$omp declare target device_type(any)
+ integer, save :: x
+ !CHECK: !$omp declare target device_type(host) enter(x)
+ !$omp declare target device_type(host) enter(x)
+ !CHECK: !$omp declare target device_type(nohost) enter(x)
+ !$omp declare target device_type(nohost) enter(x)
+ !CHECK: !$omp declare target device_type(any) enter(x)
+ !$omp declare target device_type(any) enter(x)
integer :: a(1024), i
!CHECK: do
do i = 1, 1024
diff --git a/flang/test/Semantics/OpenMP/declarative-directive.f90 b/flang/test/Semantics/OpenMP/declarative-directive.f90
index e48a682288583f7..326b4d446608dba 100644
--- a/flang/test/Semantics/OpenMP/declarative-directive.f90
+++ b/flang/test/Semantics/OpenMP/declarative-directive.f90
@@ -64,9 +64,10 @@ subroutine foo
!ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
!ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
!ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
- !$omp declare target to(Q, S) link(R)
+ !$omp declare target enter(Q, S) link(R)
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
!ERROR: MAP clause is not allowed on the DECLARE TARGET directive
- !$omp declare target map(from:Q)
+ !$omp declare target enter(Q) map(from:Q)
integer, parameter :: N=10000, M=1024
integer :: i
real :: Q(N, N), R(N,M), S(M,M)
diff --git a/flang/test/Semantics/OpenMP/declare-target01.f90 b/flang/test/Semantics/OpenMP/declare-target01.f90
index 862b4c5866f3fb6..6dec7896aec0b45 100644
--- a/flang/test/Semantics/OpenMP/declare-target01.f90
+++ b/flang/test/Semantics/OpenMP/declare-target01.f90
@@ -49,40 +49,43 @@ module declare_target01
!ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
!$omp declare target (y%KIND)
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
!$omp declare target to (my_var)
- !$omp declare target to (my_var) device_type(host)
+ !$omp declare target enter (my_var)
+
+ !$omp declare target enter (my_var) device_type(host)
!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
- !$omp declare target to (my_var%t_i)
+ !$omp declare target enter (my_var%t_i)
!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
- !$omp declare target to (my_var%t_arr)
+ !$omp declare target enter (my_var%t_arr)
!ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
- !$omp declare target to (my_var%kind_param)
+ !$omp declare target enter (my_var%kind_param)
!ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
- !$omp declare target to (my_var%len_param)
+ !$omp declare target enter (my_var%len_param)
- !$omp declare target to (arr)
+ !$omp declare target enter (arr)
- !$omp declare target to (arr) device_type(nohost)
+ !$omp declare target enter (arr) device_type(nohost)
!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
- !$omp declare target to (arr(1))
+ !$omp declare target enter (arr(1))
!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
- !$omp declare target to (arr(1:2))
+ !$omp declare target enter (arr(1:2))
!ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
- !$omp declare target to (x%KIND)
+ !$omp declare target enter (x%KIND)
!ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
- !$omp declare target to (w%LEN)
+ !$omp declare target enter (w%LEN)
!ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
- !$omp declare target to (y%KIND)
+ !$omp declare target enter (y%KIND)
!$omp declare target link (my_var2)
diff --git a/flang/test/Semantics/OpenMP/declare-target02.f90 b/flang/test/Semantics/OpenMP/declare-target02.f90
index 57a2776ff934054..77c8bb62fb7b23a 100644
--- a/flang/test/Semantics/OpenMP/declare-target02.f90
+++ b/flang/test/Semantics/OpenMP/declare-target02.f90
@@ -16,12 +16,12 @@ program declare_target02
!ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
!$omp declare target (a1)
- !$omp declare target to (arr1_to)
+ !$omp declare target enter (arr1_to)
- !$omp declare target to (blk1_to)
+ !$omp declare target enter (blk1_to)
!ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
- !$omp declare target to (a1_to)
+ !$omp declare target enter (a1_to)
!$omp declare target link (arr1_link)
@@ -35,7 +35,7 @@ program declare_target02
!$omp declare target (eq_a)
!ERROR: A variable in a DECLARE TARGET directive cannot appear in an EQUIVALENCE statement
- !$omp declare target to (eq_a)
+ !$omp declare target enter (eq_a)
!ERROR: A variable in a DECLARE TARGET directive cannot appear in an EQUIVALENCE statement
!$omp declare target link (eq_b)
@@ -44,7 +44,7 @@ program declare_target02
!$omp declare target (eq_c)
!ERROR: A variable in a DECLARE TARGET directive cannot appear in an EQUIVALENCE statement
- !$omp declare target to (eq_c)
+ !$omp declare target enter (eq_c)
!ERROR: A variable in a DECLARE TARGET directive cannot appear in an EQUIVALENCE statement
!$omp declare target link (eq_d)
@@ -70,15 +70,15 @@ subroutine func()
!$omp declare target (a3)
!ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
- !$omp declare target to (arr2_to)
+ !$omp declare target enter (arr2_to)
- !$omp declare target to (arr3_to)
+ !$omp declare target enter (arr3_to)
!ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
- !$omp declare target to (a2_to)
+ !$omp declare target enter (a2_to)
!ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
- !$omp declare target to (a3_to)
+ !$omp declare target enter (a3_to)
!ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
!$omp declare target link (arr2_link)
@@ -104,12 +104,12 @@ module mod4
!ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
!$omp declare target (a4)
- !$omp declare target to (arr4_to)
+ !$omp declare target enter (arr4_to)
- !$omp declare target to (blk4_to)
+ !$omp declare target enter (blk4_to)
!ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
- !$omp declare target to (a4_to)
+ !$omp declare target enter (a4_to)
!$omp declare target link (arr4_link)
@@ -133,13 +133,13 @@ subroutine func5()
!$omp declare target (a5)
!ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
- !$omp declare target to (arr5_to)
+ !$omp declare target enter (arr5_to)
!ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
- !$omp declare target to (blk5_to)
+ !$omp declare target enter (blk5_to)
!ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
- !$omp declare target to (a5_to)
+ !$omp declare target enter (a5_to)
!ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
!$omp declare target link (arr5_link)
diff --git a/flang/test/Semantics/OpenMP/declare-target06.f90 b/flang/test/Semantics/OpenMP/declare-target06.f90
index a2d8263a60294ba..ea29c4b05810ab3 100644
--- a/flang/test/Semantics/OpenMP/declare-target06.f90
+++ b/flang/test/Semantics/OpenMP/declare-target06.f90
@@ -16,7 +16,7 @@ module test_0
!ERROR: The given DECLARE TARGET directive clause has an invalid argument
!ERROR: No explicit type declared for 'no_implicit_materialization_3'
-!$omp declare target to(no_implicit_materialization_3)
+!$omp declare target enter(no_implicit_materialization_3)
INTEGER :: data_int = 10
!$omp declare target(data_int)
diff --git a/flang/test/Semantics/OpenMP/requires04.f90 b/flang/test/Semantics/OpenMP/requires04.f90
index ae1c2c08aa1c7ec..b8d4002cbe7d9e7 100644
--- a/flang/test/Semantics/OpenMP/requires04.f90
+++ b/flang/test/Semantics/OpenMP/requires04.f90
@@ -5,7 +5,8 @@
! device constructs, such as declare target with device_type=nohost|any.
subroutine f
- !$omp declare target device_type(nohost)
+ integer, save :: x
+ !$omp declare target enter(x) device_type(nohost)
end subroutine f
subroutine g
diff --git a/flang/test/Semantics/OpenMP/requires05.f90 b/flang/test/Semantics/OpenMP/requires05.f90
index 9281f8bab4a1694..149d646d2e3af97 100644
--- a/flang/test/Semantics/OpenMP/requires05.f90
+++ b/flang/test/Semantics/OpenMP/requires05.f90
@@ -5,7 +5,7 @@
! device constructs, such as declare target with 'to' clause and no device_type.
subroutine f
- !$omp declare target to(f)
+ !$omp declare target enter(f)
end subroutine f
subroutine g
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index f8b3b0c7524979b..8bfacd85864c062 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -289,6 +289,9 @@ def OMPC_To : Clause<"to"> {
let clangClass = "OMPToClause";
let flangClass = "OmpObjectList";
}
+def OMPC_Enter : Clause<"enter"> {
+ let flangClass = "OmpObjectList";
+}
def OMPC_From : Clause<"from"> {
let clangClass = "OMPFromClause";
let flangClass = "OmpObjectList";
@@ -1124,7 +1127,8 @@ def OMP_DeclareTarget : Directive<"declare target"> {
let allowedClauses = [
VersionedClause<OMPC_To>,
VersionedClause<OMPC_Link>,
- VersionedClause<OMPC_Indirect>
+ VersionedClause<OMPC_Indirect>,
+ VersionedClause<OMPC_Enter, 52>
];
let allowedOnceClauses = [
VersionedClause<OMPC_DeviceType, 50>
More information about the flang-commits
mailing list