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

Reply via email to