Subject: egcs-1.1.2-release front-end bug? (was Re: dump)
To: Herb Peyerl <hpeyerl@beer.org>
From: Brian C. Grayson <bgrayson@marvin.ece.utexas.edu>
List: tech-toolchain
Date: 07/29/1999 00:58:42
On Wed, Jun 23, 1999 at 04:18:22PM -0600, Herb Peyerl wrote:
> Juergen Hannken-Illjes <hannken@eis.cs.tu-bs.de> wrote:
> > Due to a codegen bug in egcs-1.2/sparc, /sbin/dump dumps bad sets.
> > This is reported in PR bin/7735.
> >
> > You could try to change the following line from sbin/dump/tape.c,
> > function writerec()
> >
> > *(union u_spcl *)(*(nextblock)++) = *(union u_spcl *)dp;
> >
> > to
> > *(union u_spcl *)(*nextblock) = *(union u_spcl *)dp;
> > nextblock += 1;
> >
> > The problem in short:
> >
> > the post-increment is done BEFORE the assignment.
>
> well I checked out a current 'dump', made the change, and tried
> again... I still see the same symptoms:
This bit me at work today, in a completely unrelated way
(LinuxPPC, for one thing. :(.) egcs-2.91.66 does _not_
generate the proper code for even the following simple example
(i.e., all the casting goo above is not the cause of the bug!):
struct foo *a, *b;
*a++ = *b;
Rather, it generates the code corresponding to:
*++a = *b;
This is not limited to NetBSD/sparc -- I've verified it as
existing in Linux-PPC and Solaris Sparc, which means it probably
affects most of our ports. It only happens when you are
copying structs, not base types, which perfectly matches
Juergen's proposed fix (although I _think_ the cygnus folks have
a better fix for this in their tree). 2.91.60 does _not_
suffer from this bug, if I'm remembering correctly. (I can
verify that again when I get to work in the morning, if anyone
cares.)
This scares the bejabbers out of me. I can't believe that
kernels compiled by 2.91.66 even _work_! For better or worse,
the problem does not occur on i386, since i386 has that
delightful rep instruction prefix, so __builtin_memcpy is
handled differently.
So, two things:
1. Is there a reason Juergen Hannken-Illjes' backout patch has
not been applied, or one of Cygnus' fixes applied? I don't
see any activity on his PR. From looking at Cygnus' web
CVS interface, it may be that expr.c, revision 1.148 is the
fix. Here's the commit message:
* expr.c (emit_block_move): Properly handle case where one of the
block move arguments has a queued increment or decrement.
(clear_storage): Similarly. Fix formatting goof.
It looks like this bug was introduced at revision 1.84.2.7:
* expr.c (emit_block_move): Do not call memcpy as a libcall
instead build up a CALL_EXPR and call it like any other function.
Frankly, I don't see how the egcs folks allowed this release
to go out the door in March(?), and how egcs has gone this
long without releasing a new version, if only to fix this
one bug. This is a showstopper in my view, and I cannot
fathom that gcc, kernels, and the world can even function
with a compiler that can't properly copy structs with
post-**crement. :)
2. The code snippet in dump appears to be only one of two *p++
= *q operations in dump that move structs around, if my grep is
correct. Could one of you that was having problems also change
around line 476 of tape.c, where it does *ntb++ = *otb++? If
we're lucky, {*ntb = *otb; ntb++; otb++;} may solve the
problem for dump, but there are doubtless other locations
throughout userland and the kernel where we do struct copies
with post-decrement or post-increment.
Ack. Thppbbbt.
Brian