https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121570
--- Comment #14 from kargls at comcast dot net ---
(In reply to Andi Kleen from comment #13)
> Reducing the use of the function makes sense (I suspect it's not needed in
> many cases), but another option would be to allow moving it out of loops if
> it covers the whole loop body. The later would fix this test case too. This
> would need some special case code in the loop im optimizer though.
It would be better to understand if it is needed at all
than adding code to do the analysis of whether it can be
moved out of a loop.
Consider,
program bah
integer i
real :: y = 1.
do i = 1, 10
call foo(y)
end do
end program bah
subroutine foo(x)
use ieee_arithmetic
integer i
real x
real, external :: bar
x = ieee_next_after(x, 10.) + bar(x)
end subroutine foo
This has the intermediate code (with comments added)
__attribute__((fn spec (". w ")))
void foo (real(kind=4) & restrict x)
{
c_char fpstate.0[33];
try
{
/* Required on entry into foo() */
_gfortran_ieee_procedure_entry ((void *) &fpstate.0);
{
c_char fpstate.1[33];
/* Intended for entry into ieee_next_after, but applies to entire
expression. There is no loop, and it is clear the this should
not be needed here. */
_gfortran_ieee_procedure_entry ((void *) &fpstate.1);
*x = __builtin_nextafterf (*x, 1.0e+1) + bar ((real(kind=4) *) x);
/* Intended for exit from ieee_next_after, but applies to entire
expression. There is no loop, and it is clear the this should
not be need here as the 'finally' section takes care of updating
. */
_gfortran_ieee_procedure_exit ((void *) &fpstate.1);
}
}
finally
{
/* Required on exit from foo() */
_gfortran_ieee_procedure_exit ((void *) &fpstate.0);
}
}
__attribute__((fn spec (". ")))
void bah ()
{
integer(kind=4) i;
static real(kind=4) y = 1.0e+0;
/* Here's your loop. */
i = 1;
while (1)
{
{
logical(kind=4) D.4673;
D.4673 = i > 10;
if (D.4673) goto L.2;
foo (&y);
L.1:;
i = i + 1;
}
}
L.2:;
}