Hi
now committed the following as r15-3856-gfcff9c3dad4f35 with two
testcase additions (and improved changelog wording).
Tobias Burnus wrote:
OpenMP mandates that when certain clauses are used with 'omp requires'
that in all compilation units this requires clause appears.
Those clauses influence the offloading behavior (+ potentially
codegen); hence, the must requires must match for those claues when
device code is involved. That's the case for device functions (in
particular 'declare target') and all OpenMP directives that take a
'device' clause.
Before OpenMP was rather vague, but in .e.g. TR13, it is fortunally
more explicit. Thus, this patch adds it for 'declare target' and it
adds it ("device" clause!) for 'interop' (but only for Fortran as
C/C++ still does not support 'interop' directive plarsing.)
(Side note: the "device global requirement" got only added to the
'device_safesync' clause after TR13; but we don't support that clause
yet; it does appear in the commit log only.)
Thanks,
Tobias
commit fcff9c3dad4f356cbf56feaed7442893203a3003
Author: Tobias Burnus <tbur...@baylibre.com>
Date: Wed Sep 25 13:57:02 2024 +0200
OpenMP: Update OMP_REQUIRES_TARGET_USED for declare_target + interop
Older versions of the OpenMP specification were not clear about what counted
as device usage. Newer (like TR13) are rather clear. Hence, this commit adds
GCC's target-used flag also when a 'declare target' or an 'interop' are
encountered. (The latter only to Fortran as C/C++ parsing support is still
missing.) TR13 also lists 'dispatch' as target-used construct (as it has the
device clause) and 'device_safesync' as clause with global requirement
property, but both are not yet supported in GCC.
gcc/c/ChangeLog:
* c-parser.cc (c_parser_omp_declare_target): Set target-used bit
in omp_requires_mask.
gcc/cp/ChangeLog:
* parser.cc (cp_parser_omp_declare_target): Set target-used bit
in omp_requires_mask.
gcc/fortran/ChangeLog:
* parse.cc (decode_omp_directive): Set target-used bit of
omp_requires_mask when encountering the declare_target or interop
directive.
gcc/testsuite/ChangeLog:
* gfortran.dg/gomp/interop-1.f90: Add dg-error for missing
omp requires requirement and declare_variant usage.
* gfortran.dg/gomp/requires-8.f90: Likewise.
---
gcc/c/c-parser.cc | 3 +++
gcc/cp/parser.cc | 3 +++
gcc/fortran/parse.cc | 8 ++++++--
gcc/testsuite/gfortran.dg/gomp/interop-1.f90 | 2 +-
gcc/testsuite/gfortran.dg/gomp/requires-8.f90 | 4 ++--
5 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 6a46577f511..a681438cbbe 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -25492,6 +25492,9 @@ c_parser_omp_declare_target (c_parser *parser)
int device_type = 0;
bool indirect = false;
bool only_device_type_or_indirect = true;
+ if (flag_openmp)
+ omp_requires_mask
+ = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
if (c_parser_next_token_is (parser, CPP_NAME)
|| (c_parser_next_token_is (parser, CPP_COMMA)
&& c_parser_peek_2nd_token (parser)->type == CPP_NAME))
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 83ae38a33ab..6d3be94bf44 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -49571,6 +49571,9 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
int device_type = 0;
bool indirect = false;
bool only_device_type_or_indirect = true;
+ if (flag_openmp)
+ omp_requires_mask
+ = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
|| (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
&& cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME)))
diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc
index e749bbdc6b5..9e06dbf0911 100644
--- a/gcc/fortran/parse.cc
+++ b/gcc/fortran/parse.cc
@@ -1345,8 +1345,12 @@ decode_omp_directive (void)
switch (ret)
{
- /* Set omp_target_seen; exclude ST_OMP_DECLARE_TARGET.
- FIXME: Get clarification, cf. OpenMP Spec Issue #3240. */
+ /* For the constraints on clauses with the global requirement property,
+ we set omp_target_seen. This included all clauses that take the
+ DEVICE clause, (BEGIN) DECLARE_TARGET and procedures run the device
+ (which effectively is implied by the former). */
+ case ST_OMP_DECLARE_TARGET:
+ case ST_OMP_INTEROP:
case ST_OMP_TARGET:
case ST_OMP_TARGET_DATA:
case ST_OMP_TARGET_ENTER_DATA:
diff --git a/gcc/testsuite/gfortran.dg/gomp/interop-1.f90 b/gcc/testsuite/gfortran.dg/gomp/interop-1.f90
index 8c99fc97f88..b7d2164812c 100644
--- a/gcc/testsuite/gfortran.dg/gomp/interop-1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/interop-1.f90
@@ -17,7 +17,7 @@ module m
integer (omp_interop_fr_kind), parameter :: omp_ifr_hsa = 7
end module m
-subroutine sub1
+subroutine sub1 ! { dg-error "Program unit at .1. has OpenMP device constructs/routines but does not set !.OMP REQUIRES REVERSE_OFFLOAD but other program units do" }
!$omp interop
integer :: y ! { dg-error "Unexpected data declaration statement" }
end subroutine sub1
diff --git a/gcc/testsuite/gfortran.dg/gomp/requires-8.f90 b/gcc/testsuite/gfortran.dg/gomp/requires-8.f90
index 583c5a56b32..3b0a7d81768 100644
--- a/gcc/testsuite/gfortran.dg/gomp/requires-8.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/requires-8.f90
@@ -17,9 +17,9 @@ contains
end subroutine foo
end module m
-subroutine bar
+subroutine bar ! { dg-error "has OpenMP device constructs/routines but does not set !.OMP REQUIRES REVERSE_OFFLOAD but other program units do" }
!use m
- !$omp requires unified_shared_memory ! Possibly OK - needs OpenMP Lang Spec clarification (-> #3240)
+ !$omp requires unified_shared_memory
!$omp declare target
end subroutine bar