[Bug fortran/51218] [4.7 Regression] Potential optimization bug due to implicit_pure?

anlauf at gmx dot de gcc-bugzilla@gcc.gnu.org
Mon Nov 21 19:48:00 GMT 2011


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51218

--- Comment #16 from Harald Anlauf <anlauf at gmx dot de> 2011-11-21 19:31:13 UTC ---
(In reply to comment #15)
> Because it generates "wrong-code" and I wasn't completely convinced that there
> is no bug lurking in implicit_pure. Thus, for me the status is an "unconfirmed"
> bug which would be - if confirmed - a wrong-code 4.7 regression.

I found a shorter code which shows that functions with
side-effects are erroneously treated as pure, see below.

>  * * *
> 
> (In reply to comment #11)
> > The code does memory management similar to that required by
> > TR15581 for allocatable DT components and allocatable function
> > results, but it also has to work for compilers that do not
> > support TR15581.  It does so by overloading everything needed.
> 
> I think that by now most compilers support TR 15581, thus, you could consider
> to solve the issue by changing the code to TR 15581.

Well, most /= all.

At work I (have to) use a compiler which does not support TR 15581.
The (hard-/software) vendor (non-European, non-US) has been successfully
declining user demands to support F2003.

> At the moment you have code which might work by chance with some compilers but
> fail with others since it is invalid.

Well, I understand that the code does bad thing.
One thing it relies on is that the compiler recognizes
that the bad function are not pure, as they have a
side effect (e.g. accessing module variable call_level).
If a side effect is able to disable critical optimizations,
then I'm optimistic that the code will work on most platforms.

Now as promised, here's the reduced example:


module a
  implicit none
  integer :: neval = 0
! integer, volatile :: neval = 0   ! Won't change anything...
contains
  subroutine inc_eval
    neval = neval + 1
  end subroutine inc_eval
end module a

module b
  use a
  implicit none
contains
  function f(x)
    real :: f
    real, intent(in) :: x
    f = x
  end function f

! impure &       ! This won't help...
  function g(x)
    real :: g
    real, intent(in) :: x
    ! g is not pure, it has a side-effect!
    call inc_eval
!   print *, "In g!"
    g = x
  end function g
end module b

program gfcbug114a
  use a
  use b
  implicit none
  real :: x = 1, y = 1, t, u, v, w
  print *, (neval == 0) ! 0 initially
  t = f(x)*f(y)
  print *, (neval == 0)
  u = f(x)*f(y) + f(x)*f(y)
  print *, (neval == 0)
  v = g(x)*g(y)
  print *, (neval == 2)
  w = g(x)*g(y) + g(x)*g(y)
  print *, (neval == 6)
  print *, neval ! 6???
  print *, t, u, v, w
end program gfcbug114a


Running without optimization, I get:

 T
 T
 T
 T
 T
           6
   1.00000000       2.00000000       1.00000000       2.00000000

With optimization, the result is:

 T
 T
 T
 T
 F
           4
   1.00000000       2.00000000       1.00000000       2.00000000


Thus the number of function evaluations of the non-pure
function g deepends on the optimization.

Enabling the commented out print in g(),
I get the expected result.

Setting g as impure, as well as making neval volatile
does not help.  I do think that this qualifies as a bug.



More information about the Gcc-bugs mailing list