This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
bug in latest egcs
- To: egcs-bugs at cygnus dot com
- Subject: bug in latest egcs
- From: Ulrich Drepper <drepper at ipd dot info dot uni-karlsruhe dot de>
- Date: 30 Oct 1997 02:49:27 +0100
- Reply-To: drepper at ipd dot info dot uni-karlsruhe dot de (Ulrich Drepper)
Hi,
One of the last changes introduced a bug in egcs which is only
visible with high optimization. This is the stripped down source:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typedef int int32_t __attribute__ ((__mode__ ( __SI__ ))) ;
typedef unsigned int u_int32_t __attribute__ ((__mode__ ( __SI__ ))) ;
typedef union
{
float value;
u_int32_t word;
} ieee_float_shape_type;
long long int
__llroundf (float x)
{
int32_t j0;
u_int32_t i;
long long int result;
int sign;
do { ieee_float_shape_type gf_u; gf_u.value = ( x ); ( i ) = gf_u.word; } while (0) ;
j0 = ((i >> 23) & 0xff) - 0x7f;
sign = (i & 0x80000000) != 0 ? -1 : 1;
i &= 0x7fffff;
i |= 0x800000;
if (j0 < (int32_t) (8 * sizeof (long long int)))
{
if (j0 < 0)
return j0 < -1 ? 0 : sign;
else if (j0 >= 23)
result = (long int) i << (j0 - 23);
else
{
i += 0x400000 >> j0;
result = i >> (23 - j0);
}
}
else
return (long long int) x;
return sign * result;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The problem is in the assignment to `sign'. On i386 using -O3 -g I get
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
do { ieee_float_shape_type gf_u; gf_u.value = ( x ); ( i ) = gf_u.wor
d; } while (0) ;
c: 83 ec 04 subl $0x4,%esp
f: d9 14 24 fsts (%esp,1)
12: 58 popl %eax
13: 89 c7 movl %eax,%edi
j0 = ((i >> 23) & 0xff) - 0x7f;
15: c1 ef 17 shrl $0x17,%edi
18: 81 e7 ff 00 00 andl $0xff,%edi
1d: 00
sign = (i & 0x80000000) != 0 ? -1 : 1;
1e: be 01 00 00 00 movl $0x1,%esi
23: 8d 5f 81 leal 0xffffff81(%edi),%ebx
26: 85 ff testl %edi,%edi
28: 7d 05 jnl 2f <__llroundf+0x2f>
2a: be ff ff ff ff movl $0xffffffff,%esi
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(We should ignore the lame translation of the assignment to `i'
here, this is another topic).
The opcode at address 13: moves the real value from %eax to %edi.
In the following code the %edi value is modified and in line 23:
the value for the C variable `j0' is written to %ebx.
But in line 26: the `test' opcode examines the modified value and
not the unmodified value in %eax. Therefore this test does not test
whether to MSB of `i' is set but it tests whether the MSB for
(i >> 23) & 0xff
is set.
I guess the the code handling the aliases is wrong and that for
calculating `jo' %eax should have been used, leaving %edi unmodifed.
-- Uli
---------------. drepper at gnu.org ,-. Rubensstrasse 5
Ulrich Drepper \ ,-------------------' \ 76149 Karlsruhe/Germany
Cygnus Solutions `--' drepper at cygnus.com `------------------------