This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
egcs 1.1.1 machine-independant code generation bug.
- To: egcs-bugs at cygnus dot com
- Subject: egcs 1.1.1 machine-independant code generation bug.
- From: Simon Burge <simonb at telstra dot com dot au>
- Date: Fri, 15 Jan 1999 15:35:20 +1100
- Cc: Simon Burge <simonb at telstra dot com dot au>
Folks,
I seem to have found a bug with egcs 1.1.1. The problem
occured when compiling the freelip package (available from
ftp://ftp.ox.ac.uk/pub/math/freelip/freelip_1.1.tar.gz).
When compiling the package with either -O1 or -O2, it
takes a long time to run (I aborted after 14 hours - ie
overnight), instead of the expected 20 or 30 seconds on a
fast machine.
This occurs on NetBSD-current (as of Janurary 9, 1999) for
both the i386 and pmax (DECstation), as well as for Ultrix
4.5 on a DECstation. For NetBSD, egcs is part of the OS -
I don't know what has been changed during the intergration
of egcs. For Ultrix, it was a clean install using just
"./configure" with no other arguments.
I think the code fragment below shows the bug. I haven't
included a pre-processed version because it only include
<stdio.h>, and the bug exists across operating systems
and the bug still exists with or without the include of
<stdio.h>. Here's a run on a NetBSD/i386 machine:
simonpc:freelip 1058> cc -O0 -o egcsbug egcsbug.c
simonpc:freelip 1059> ./egcsbug
before:
b[0] = 41384962 c[0] = 3
b[1] = 65549965 c[1] = 29419259
b[2] = 125 c[2] = 842016
b[3] = 0 c[3] = 0
after:
b[0] = 49655308 c[0] = 3
b[1] = 63865932 c[1] = 29419259
b[2] = 125 c[2] = 842016
b[3] = 0 c[3] = 0
simonpc:freelip 1060> cc -O1 -o egcsbug egcsbug.c
simonpc:freelip 1061> ./egcsbug
before:
b[0] = 41384962 c[0] = 3
b[1] = 65549965 c[1] = 29419259
b[2] = 125 c[2] = 842016
b[3] = 0 c[3] = 0
after:
b[0] = 49655308 c[0] = 3
b[1] = 63865932 c[1] = 29419259
b[2] = 28577341 c[2] = 842016
b[3] = 0 c[3] = 0
simonpc:freelip 1060> cc -v
Using builtin specs.
gcc version egcs-2.91.60 19981201 (egcs-1.1.1 release)
Notice that the "before" b[2] has a different value (125)
than the "after" b[2] (28577341). Please note that I have
no idea what the code in question is trying to do!
I'm neither a wiz at mips or i386 assembly, so I've provided
no analysis there. Uncommenting the printf(""); at the top
of the for() loop results in a program that gives that same
results with and without -O.
If there's any further info you require, please ask.
Regards,
Simon.
--
#include <stdio.h>
#define LO5(x) (((unsigned long *) &x)[0])
#define HI5(x) (((unsigned long *) &x)[1])
void zsubmul5(long, long *, long *);
int
main()
{
long b[4] = { 41384962, 65549965, 125, 0 };
long c[4] = { 3, 29419259, 842016, 0 };
printf("before:\n");
printf("b[0] = %8ld c[0] = %8ld\n", b[0], c[0]);
printf("b[1] = %8ld c[1] = %8ld\n", b[1], c[1]);
printf("b[2] = %8ld c[2] = %8ld\n", b[2], c[2]);
printf("b[3] = %8ld c[3] = %8ld\n", b[3], c[3]);
zsubmul5(2, &b[0], &c[0]);
printf("after:\n");
printf("b[0] = %8ld c[0] = %8ld\n", b[0], c[0]);
printf("b[1] = %8ld c[1] = %8ld\n", b[1], c[1]);
printf("b[2] = %8ld c[2] = %8ld\n", b[2], c[2]);
printf("b[3] = %8ld c[3] = %8ld\n", b[3], c[3]);
exit(0);
}
void
zsubmul5(long ams, long *ama, long *amb)
{
long carry = (1L<<26);
long i;
double dams = (double) ((1L<<26)-ams);
double xx;
double yy;
unsigned long lo;
unsigned long hi;
i = (*amb++);
xx = ((double) (*amb))*dams + 4503599627370496.0;
for (; i > 1; i--)
{
/* printf(""); */
yy = ((double) (*(amb+1)))*dams + 4503599627370496.0;
lo = LO5(xx) & 0x3FFFFFF;
hi = ((HI5(xx)<<6)|(LO5(xx)>>26)) & 0x3FFFFFF;
lo = lo + (*ama) + carry;
*ama = lo & 0x3FFFFFF;
carry = hi + (lo >> 26);
ama++;
carry += ((1L<<26)-1) - (*(amb++));
xx = yy;
}
lo = LO5(xx) & 0x3FFFFFF;
hi = ((HI5(xx)<<6)|(LO5(xx)>>26)) & 0x3FFFFFF;
lo = lo + (*ama) + carry;
*ama = lo & 0x3FFFFFF;
carry = hi + (lo >> 26);
ama++;
carry += ((1L<<26)-1) - (*amb);
*ama += carry - (1L<<26);
}