Debugging f-torture/execute/20000503-1.f failure

Geoff Keating geoffk@cygnus.com
Sat Jul 1 00:22:00 GMT 2000


"Billinghurst, David (CRTS)" <David.Billinghurst@riotinto.com.au> writes:

> This is a partial analysis of f-torture/execute/20000503-1.f
> 
> This failure occurs on all platforms, and at all optimisation levels.
> It does not fail for:
>    gcc-2.95
>    snapshots up to and including 19991006
>  
> I think:
>   this shows that the error occurs during RTL generation,
>   something weird is being attempted
> 
> The bug has been isolated to the subroutine below.
> 
>       INTEGER FUNCTION SLASQX( N )
>       INTEGER  N, I0, I, K
>       I0 = 1
>       DO I = 4*I0, 2*( I0+N-1 ), 4
>          K = I
>       END DO
>       SLASQX = K
>       RETURN
>       END
> 
> When called with N=20, the return value is 36, rather than 2*N = 40.
> 
> Below is annotated RTL dump after RTL generation (g77 -O0 -c -dr).
> This is my first attempt at deciphering RTL.
> I think the error occurs in calculating the loop counter,
> between instructions 24 and 35.  I don't understand what is
> going on there, but it looks complicated and wrong

It does look wrong, but I don't think the complicated bits are the problem.

Most of the complicated code is trying to compute

(1 + N)/2

rounded _towards_ zero, on machines where the RTL 'div' operation
rounds towards -infinity.  So what it does is compute

(1 + N + (1 + N < 0))/2

and the '1 + N < 0' bit is the tricky bit with the shifts; an ashiftrt
by 31 gets you -1 if the value is negative and 0 if positive, then a
logical shift right by 31 gets you 1 if the value is negative and
still 0 if positive.

I don't know whether it really means 1 or I0.  I suspect the fortran
frontend has decided they are the same and so is using the same
register to store them.  That is ok too.

What it's really trying to compute is the number of times the loop
executes.  I think this number of times is 
(N + 1)/2
but my grasp of Fortran is not quite good enough to be sure it's
correct.

What it actually does calculate seems to be
(N + 1)/2 - 1
(it calculates it just like that, subtracting one later) and I don't
know where the - 1 came from.  If you could track that down, that
would be very helpful.

-- 
- Geoffrey Keating <geoffk@cygnus.com>


More information about the Gcc-bugs mailing list