[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