Message ID | 9cd0b179-63fb-ba5d-9c31-3d3d0358b300@codesourcery.com |
---|---|
State | New |
Headers | show |
Series | OpenMP/Fortran: Permit impure ELEMENTAL in omp directives | expand |
On Tue, Jun 16, 2020 at 01:27:43PM +0200, Tobias Burnus 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." > > OK for the trunk? Ok. Jakub
Hi! On 2020-06-16T13:27:43+0200, Tobias Burnus <tobias@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
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 <tobias@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. gcc/fortran/ChangeLog: * parse.c (decode_omp_directive): Remove "or ELEMENTAL" from "in PURE" error message. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/pr79154-1.f90: Update dg-*; add an impure elemental example. * gfortran.dg/gomp/pr79154-2.f90: Likewise. gcc/fortran/parse.c | 4 ++-- gcc/testsuite/gfortran.dg/gomp/pr79154-1.f90 | 15 +++++++++----- gcc/testsuite/gfortran.dg/gomp/pr79154-2.f90 | 30 +++++++++++++++++++--------- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index f71a95dd871..9d90e501bf6 100644 --- 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; } diff --git a/gcc/testsuite/gfortran.dg/gomp/pr79154-1.f90 b/gcc/testsuite/gfortran.dg/gomp/pr79154-1.f90 index 69a0009e13c..ea147bfa78e 100644 --- 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 +end function bazei diff --git a/gcc/testsuite/gfortran.dg/gomp/pr79154-2.f90 b/gcc/testsuite/gfortran.dg/gomp/pr79154-2.f90 index 67344f0c028..38d3fe5c384 100644 --- 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 +!$omp end target ! { dg-bogus "may not appear in PURE" } +end function bazei