Ups. Good catch. – I think the follow-up patch is obvious.
Unless there are comments, I will commit it as such.
Tobias
On 6/16/20 4:41 PM, Thomas Schwinge wrote:
Hi!
On 2020-06-16T13:27:43+0200, Tobias Burnus <tob...@codesourcery.com> wrote:
when looking into a PURE/ELEMENTAL issue with OpenACC, Thomas and
I came across the analogous OpenMP code – and stumbled over
ELEMENTAL.
In Fortran, ELEMENTAL implies PURE but one can also have an IMPURE
ELEMENTAL procedure.
As PR 79154 quotes, OpenMP 4 had:
"OpenMP directives may not appear in PURE or ELEMENTAL procedures."
While OpenMP 4.5 (and later) have:
"OpenMP directives, except SIMD and declare target directives,
may not appear in pure procedures."
ELEMENTAL is still mentioned – but only for:
"OpenMP runtime library routines may not be called
from PURE or ELEMENTAL procedures."
... but that's mentioned not only diagnoesd here:
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -849,7 +849,7 @@ decode_omp_directive (void)
/* match is for directives that should be recognized only if
-fopenmp, matchs for directives that should be recognized
if either -fopenmp or -fopenmp-simd.
- Handle only the directives allowed in PURE/ELEMENTAL procedures
+ Handle only the directives allowed in PURE procedures
first (those also shall not turn off implicit pure). */
switch (c)
{
@@ -868,7 +868,7 @@ decode_omp_directive (void)
if (flag_openmp && gfc_pure (NULL))
{
gfc_error_now ("OpenMP directives other than SIMD or DECLARE TARGET "
- "at %C may not appear in PURE or ELEMENTAL procedures");
+ "at %C may not appear in PURE procedures");
gfc_error_recovery ();
return ST_NONE;
}
..., but also further down, in the 'finish' label:
finish:
if (!pure_ok)
{
gfc_unset_implicit_pure (NULL);
if (!flag_openmp && gfc_pure (NULL))
{
gfc_error_now ("OpenMP directives other than SIMD or DECLARE TARGET
"
"at %C may not appear in PURE or ELEMENTAL "
"procedures");
reject_statement ();
gfc_error_recovery ();
return ST_NONE;
}
}
return ret;
..., so I suppose this needs to be changed, too -- and maybe is missing
testsuite coverage?
--- a/gcc/testsuite/gfortran.dg/gomp/pr79154-1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/pr79154-1.f90
@@ -2,7 +2,7 @@
! { dg-do compile }
pure real function foo (a, b) ! { dg-warning "GCC does not currently support
mixed size types for 'simd' functions" "" { target aarch64*-*-* } }
-!$omp declare simd(foo) ! { dg-bogus "may not appear in PURE
or ELEMENTAL" }
+!$omp declare simd(foo) ! { dg-bogus "may not appear in
PURE" }
real, intent(in) :: a, b
foo = a + b
end function foo
@@ -10,23 +10,28 @@ pure function bar (a, b)
real, intent(in) :: a(8), b(8)
real :: bar(8)
integer :: i
-!$omp simd ! { dg-bogus "may not appear in PURE or
ELEMENTAL" }
+!$omp simd ! { dg-bogus "may not appear in PURE" }
do i = 1, 8
bar(i) = a(i) + b(i)
end do
end function bar
pure real function baz (a, b)
-!$omp declare target ! { dg-bogus "may not appear in PURE or
ELEMENTAL" }
+!$omp declare target ! { dg-bogus "may not appear in PURE" }
real, intent(in) :: a, b
baz = a + b
end function baz
elemental real function fooe (a, b) ! { dg-warning "GCC does not currently support mixed
size types for 'simd' functions" "" { target aarch64*-*-* } }
-!$omp declare simd(fooe) ! { dg-bogus "may not appear in PURE or
ELEMENTAL" }
+!$omp declare simd(fooe) ! { dg-bogus "may not appear in PURE" }
real, intent(in) :: a, b
fooe = a + b
end function fooe
elemental real function baze (a, b)
-!$omp declare target ! { dg-bogus "may not appear in PURE or
ELEMENTAL" }
+!$omp declare target ! { dg-bogus "may not appear in PURE" }
real, intent(in) :: a, b
baze = a + b
end function baze
+elemental impure real function bazei (a, b)
+!$omp declare target ! { dg-bogus "may not appear in PURE" }
+ real, intent(in) :: a, b
+ baze = a + b
Shouldn't this assign to 'bazei' instead of 'baze'?
+end function bazei
--- a/gcc/testsuite/gfortran.dg/gomp/pr79154-2.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/pr79154-2.f90
@@ -3,14 +3,14 @@
pure real function foo (a, b)
real, intent(in) :: a, b
-!$omp taskwait ! { dg-error "may not appear in PURE
or ELEMENTAL" }
+!$omp taskwait ! { dg-error "may not appear in
PURE" }
foo = a + b
end function foo
pure function bar (a, b)
real, intent(in) :: a(8), b(8)
real :: bar(8)
integer :: i
-!$omp do simd ! { dg-error "may not appear in PURE
or ELEMENTAL" }
+!$omp do simd ! { dg-error "may not appear in
PURE" }
do i = 1, 8
bar(i) = a(i) + b(i)
end do
@@ -19,26 +19,38 @@ pure function baz (a, b)
real, intent(in) :: a(8), b(8)
real :: baz(8)
integer :: i
-!$omp do ! { dg-error "may not appear in PURE or
ELEMENTAL" }
+!$omp do ! { dg-error "may not appear in PURE" }
do i = 1, 8
baz(i) = a(i) + b(i)
end do
-!$omp end do ! { dg-error "may not appear in PURE or
ELEMENTAL" }
+!$omp end do ! { dg-error "may not appear in PURE" }
end function baz
pure real function baz2 (a, b)
real, intent(in) :: a, b
-!$omp target map(from:baz2) ! { dg-error "may not appear in PURE or
ELEMENTAL" }
+!$omp target map(from:baz2) ! { dg-error "may not appear in PURE" }
baz2 = a + b
-!$omp end target ! { dg-error "may not appear in PURE or
ELEMENTAL" }
+!$omp end target ! { dg-error "may not appear in PURE" }
end function baz2
+! ELEMENTAL implies PURE
elemental real function fooe (a, b)
real, intent(in) :: a, b
-!$omp taskyield ! { dg-error "may not appear in PURE
or ELEMENTAL" }
+!$omp taskyield ! { dg-error "may not appear in
PURE" }
fooe = a + b
end function fooe
elemental real function baze (a, b)
real, intent(in) :: a, b
-!$omp target map(from:baz) ! { dg-error "may not appear in PURE or
ELEMENTAL" }
+!$omp target map(from:baz) ! { dg-error "may not appear in PURE" }
baze = a + b
-!$omp end target ! { dg-error "may not appear in PURE or
ELEMENTAL" }
+!$omp end target ! { dg-error "may not appear in PURE" }
end function baze
+elemental impure real function fooei (a, b)
+ real, intent(in) :: a, b
+!$omp taskyield ! { dg-bogus "may not appear in
PURE" }
+ fooe = a + b
+end function fooei
+elemental impure real function bazei (a, b)
+ real, intent(in) :: a, b
+!$omp target map(from:baz) ! { dg-bogus "may not appear in PURE" }
+ baze = a + b
Similar.
+!$omp end target ! { dg-bogus "may not appear in PURE" }
+end function bazei
Grüße
Thomas
-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander
Walter
-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander
Walter
OpenMP/Fortran: Permit impure ELEMENTAL in omp directives
OpenMP since 4.5 permits IMPURE ELEMENTAL in directives and
the code already only checked for PURE. – Followup for
-fopenmp-simd.
gcc/fortran/ChangeLog:
* parse.c (decode_omp_directive): Remove "or ELEMENTAL"
from "in PURE" error message also for -fopenmp-simd.
gcc/testsuite/ChangeLog:
* gfortran.dg/gomp/pr79154-simd.f90: New test.
gcc/fortran/parse.c | 3 +--
gcc/testsuite/gfortran.dg/gomp/pr79154-simd.f90 | 16 ++++++++++++++++
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 9d90e501bf6..46e1e1b2698 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -1078,8 +1078,7 @@ decode_omp_directive (void)
if (!flag_openmp && gfc_pure (NULL))
{
gfc_error_now ("OpenMP directives other than SIMD or DECLARE TARGET "
- "at %C may not appear in PURE or ELEMENTAL "
- "procedures");
+ "at %C may not appear in PURE procedures");
reject_statement ();
gfc_error_recovery ();
return ST_NONE;
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr79154-simd.f90 b/gcc/testsuite/gfortran.dg/gomp/pr79154-simd.f90
new file mode 100644
index 00000000000..d6b72d6f3da
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr79154-simd.f90
@@ -0,0 +1,16 @@
+! { dg-options "-fno-openmp -fopenmp-simd" }
+!
+pure subroutine bar(a)
+ integer, intent(in) :: a(:)
+ !$omp target enter data map(to:a) ! Ignored with -fopenmp-simd otherwise invalid in PURE
+end
+
+pure subroutine foo(a,b)
+ integer, intent(out) :: a(5)
+ integer, intent(in) :: b(5)
+ !$omp target teams distribute simd ! { dg-error "may not appear in PURE procedures" }
+ do i=1, 5
+ a(i) = b(i)
+ end do
+ !$omp end target teams distribute
+end subroutine