This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
next bug
- To: egcs-bugs at cygnus dot com
- Subject: next bug
- From: Ulrich Drepper <drepper at cygnus dot com>
- Date: 26 Apr 1998 21:28:33 -0700
- Reply-To: drepper at cygnus dot com (Ulrich Drepper)
Here's the next bug which can be found by simply compiling glibc. I
got several bugs in the math function test suite and maybe there is
more than one bug. I chose the simplest function first and will see
whether this is the same problem as in the other tests.
The appended source is the nextafter function for double). With the
2.91.24 compiler (from earlier this week) compiled the code to (this is only the beginning):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00000000 <__nextafter>:
0: 83 ec 24 subl $0x24,%esp
3: 55 pushl %ebp
4: 57 pushl %edi
5: 56 pushl %esi
6: dd 44 24 34 fldl 0x34(%esp,1)
a: dd 44 24 3c fldl 0x3c(%esp,1)
e: d9 c9 fxch %st(1)
10: dd 54 24 0c fstl 0xc(%esp,1)
14: d9 c9 fxch %st(1)
16: 8b 6c 24 10 movl 0x10(%esp,1),%ebp
1a: 8b 4c 24 0c movl 0xc(%esp,1),%ecx
1e: dd 54 24 0c fstl 0xc(%esp,1)
22: 8b 44 24 10 movl 0x10(%esp,1),%eax
26: 89 44 24 2c movl %eax,0x2c(%esp,1)
2a: 8b 44 24 0c movl 0xc(%esp,1),%eax
2e: 89 44 24 24 movl %eax,0x24(%esp,1)
32: 89 ea movl %ebp,%edx
34: 81 e2 ff ff ff andl $0x7fffffff,%edx
39: 7f
3a: 8b 44 24 2c movl 0x2c(%esp,1),%eax
3e: 25 ff ff ff 7f andl $0x7fffffff,%eax
43: 89 44 24 28 movl %eax,0x28(%esp,1)
47: 81 fa ff ff ef cmpl $0x7fefffff,%edx
4c: 7f
4d: 7e 0d jle 5c <__nextafter+0x5c>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The current compiler (2.91.25, cvs update ran at about 14:00PDT, Sunday):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00000000 <__nextafter>:
0: 83 ec 24 subl $0x24,%esp
3: 55 pushl %ebp
4: 57 pushl %edi
5: 56 pushl %esi
6: dd 44 24 34 fldl 0x34(%esp,1)
a: dd 44 24 3c fldl 0x3c(%esp,1)
e: d9 c9 fxch %st(1)
10: dd 54 24 0c fstl 0xc(%esp,1)
14: d9 c9 fxch %st(1)
16: 8b 6c 24 10 movl 0x10(%esp,1),%ebp
1a: 8b 4c 24 0c movl 0xc(%esp,1),%ecx
1e: dd 54 24 0c fstl 0xc(%esp,1)
22: 89 e8 movl %ebp,%eax
24: 89 44 24 2c movl %eax,0x2c(%esp,1)
28: 89 c8 movl %ecx,%eax
2a: 89 44 24 24 movl %eax,0x24(%esp,1)
2e: 89 ea movl %ebp,%edx
30: 81 e2 ff ff ff andl $0x7fffffff,%edx
35: 7f
36: 8b 44 24 2c movl 0x2c(%esp,1),%eax
3a: 25 ff ff ff 7f andl $0x7fffffff,%eax
3f: 89 44 24 28 movl %eax,0x28(%esp,1)
43: 81 fa ff ff ef cmpl $0x7fefffff,%edx
48: 7f
49: 7e 0d jle 58 <__nextafter+0x58>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The problem in this piece of code is at address 22 in both cases. In
the old version the instruction
movl 0x10(%esp,1),%eax
gets the MSW from the floating point value it just stored (see the
instruction before). The new egcs is somehow very confused since it
thinks the value is already in a register (%ebp) and therefore does
not load it anymore.
But this is of course very wrong since the value in %ebp is from the
other floating point value. I.e., egcs thinks it has both values in
the integer registers but in fact it only has two copies of the first
floating point value in the registers.
-- Uli
---------------. drepper at gnu.org ,-. 1325 Chesapeake Terrace
Ulrich Drepper \ ,-------------------' \ Sunnyvale, CA 94089 USA
Cygnus Solutions `--' drepper at cygnus.com `------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typedef unsigned int u_int32_t;
typedef int int32_t;
typedef union
{
double value;
struct
{
u_int32_t lsw;
u_int32_t msw;
} parts;
} ieee_double_shape_type;
double
__nextafter(double x, double y)
{
int32_t hx,hy,ix,iy;
u_int32_t lx,ly;
do
{
ieee_double_shape_type ew_u;
ew_u.value = x;
hx = ew_u.parts.msw;
lx = ew_u.parts.lsw;
}
while (0);
do
{
ieee_double_shape_type ew_u;
ew_u.value = y;
hy = ew_u.parts.msw;
ly = ew_u.parts.lsw;
}
while (0);
ix = hx&0x7fffffff;
iy = hy&0x7fffffff;
if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||
((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0))
return x+y;
if(x==y) return y;
if((ix|lx)==0)
{
do
{
ieee_double_shape_type iw_u;
iw_u.parts.msw = hy&0x80000000;
iw_u.parts.lsw = 1;
x = iw_u.value;
}
while (0) ;
y = x*x;
if(y==x) return y; else return x;
}
if(hx>=0)
{
if(hx>hy||((hx==hy)&&(lx>ly)))
{
if(lx==0) hx -= 1;
lx -= 1;
}
else
{
lx += 1;
if(lx==0) hx += 1;
}
}
else
{
if(hy>=0||hx>hy||((hx==hy)&&(lx>ly)))
{
if(lx==0) hx -= 1;
lx -= 1;
}
else
{
lx += 1;
if(lx==0) hx += 1;
}
}
hy = hx&0x7ff00000;
if(hy>=0x7ff00000) return x+x;
if(hy<0x00100000)
{
y = x*x;
if(y!=x)
{
do
{
ieee_double_shape_type iw_u;
iw_u.parts.msw = hx;
iw_u.parts.lsw = lx;
y = iw_u.value;
}
while (0);
return y;
}
}
do
{
ieee_double_shape_type iw_u;
iw_u.parts.msw = hx;
iw_u.parts.lsw = lx;
x = iw_u.value;
}
while (0);
return x;
}