[Bug fortran/85599] invalid optimization: function not always evaluated in logical expression
sgk at troutmask dot apl.washington.edu
gcc-bugzilla@gcc.gnu.org
Wed May 2 14:56:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85599
--- Comment #9 from Steve Kargl <sgk at troutmask dot apl.washington.edu> ---
On Wed, May 02, 2018 at 08:53:27AM +0000, janus at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85599
>
> --- Comment #4 from janus at gcc dot gnu.org ---
> (In reply to kargl from comment #1)
> > The behavior may not be buggy, and it's best not to depend
> > on side-effects. From F2018,
> >
> > 10.1.5.4.2 Evaluation of logical intrinsic operations
> >
> > Once the interpretation of a logical intrinsic operation is
> > established, the processor may evaluate any other expression
> > that is logically equivalent, provided that the integrity of
> > parentheses in any expression is not violated.
> >
> > Two expressions of type logical are logically equivalent
> > if their values are equal for all possible values of their
> > primaries.
> >
>
> Thanks for the standard quote, Steve. It certainly goes in
> the right direction, but I feel like it's not quite to the point.
>
> Some other (possibly) relevant passages I found in the 2008 standard:
>
> *****
> 7.1.7 Evaluation of operands
> 1 It is not necessary for a processor to evaluate all of the operands of an
> expression, or to evaluate entirely each operand, if the value of the
> expression can be determined otherwise.
> *****
The above is actually the clause I went looking for, but I was
short on time yesterday. I think that this is the one along with
the description of evaluation of a logical expression that
applies.
> That also sounds like optimizing away the function call might be valid, but
> then there is also this one:
>
> *****
> 7.1.4 Evaluation of operations
> 2 The evaluation of a function reference shall neither affect nor be affected
> by the evaluation of any other entity within the statement.
> *****
You could be right in that this clause applies. I, however,
tend to think that this is meant to prevent a side effect
such as
program foo
integer i, j
integer, external :: ping, pong
common /ah/i
i = 1
j = ping() + pong() ! ping() changes value of i
print *, pong(), j ! which effects the output of pong()
i = 1
j = pong() + ping()
print *, pong(), j
end program foo
function ping() result(n)
integer k
common /ah/ k
k = k + 1
n = 42
end function ping
function pong() result(n)
common /ah/ m
if (m > 0) then
n = m
else
n = 0
end if
end function pong
Yes, it is admittedly a contrived example. It is also possible
for a compiler to replace
j = 0 * ping() + pong()
with simply
j = pong()
where ping() is never evaluated. I'll note that gfortran currently
will evaluate ping(), but if ping() takes ages to compute it might
be nice to have -ffrontend-optimize remove its evaluation.
> What worries me most is that other compilers choose different implementations.
> Can this kind of code really be processor-dependent?
Yes, that is troublesome.
More information about the Gcc-bugs
mailing list