This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

egcs 1.1.1 machine-independant code generation bug.


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);
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]