Re: [davidm@azstarnet.com: Re: gcc-2.7.1 bug]

Richard Henderson (richard@atheist.tamu.edu)
Tue, 26 Mar 1996 00:48:25 -0600 (CST)


On Mon, 25 Mar 1996 David Mosberger-Tang <davidm@AZStarNet.com> wrote:
> Here is a detailed description (and a small test program that
> reproduces the problem) of the gcc bug I mentioned earlier today.
> Richard Kenner determined that the latest gcc still has this problem.
> It's apparently due to a bug in `combine' (not the instruction
> scheduler as I guessed). Since Richard won't be able to fix it
> immediately, I thought I'd forward this to the mailing lists so people
> know what exactly goes wrong. Of course, if somebody could find a
> fix, I'm sure Richard wouldn't mind receiving a patch either... :-)

It is indeed in the combiner. The problem in this example is where
insns 52, 25, and 24 are combined into two insns. Unfortunately,
the new insn 25 overwrites $20, used in insn 48.

My fix is to notice when we are going to successfully combine
into two insns, and check to see if the destination of the
earlier insn is used between the two insns. If so, we cannot
do the combination.

For completeness, the test function is reproduced along with
the patch.

r~

==============================
long
XGetRGBColormaps (dpy, w, stdcmap, count, property)
void *dpy;
long w;
long **stdcmap;
int *count;
long property;
{
long *data = 0;
int actual_format;
unsigned long nitems;
unsigned long actual_type, leftover;

if (XGetWindowProperty (dpy, w, property, 0L, 1000000L, 0,
27, &actual_type, &actual_format,
&nitems, &leftover, (unsigned char **)&data)
!= 0)
return 0;
return 1;
}
==============================
Tue Mar 26 00:39:05 1996 Richard Henderson <rth@tamu.edu>

* combine.c (try_combine): When three insns have been
merged into two, fail if the destination of the new
i2 pattern is live between i2 and i3.


Index: combine.c
===================================================================
RCS file: /home/richard/Repository/cygnus/gcc/combine.c,v
retrieving revision 1.1.1.1
diff -c -p -r1.1.1.1 combine.c
*** combine.c 1996/03/26 02:30:31 1.1.1.1
--- combine.c 1996/03/26 06:37:10
*************** try_combine (i3, i2, i1)
*** 2077,2082 ****
--- 2077,2091 ----
undobuf.other_insn, NULL_RTX, NULL_RTX, NULL_RTX);
}

+ /* If we are modifying i2, make sure its SET won't overwrite
+ something that's still live through i3. */
+ if (newi2pat && GET_CODE(newi2pat) == SET
+ && reg_used_between_p (SET_DEST (newi2pat), i2, i3))
+ {
+ undo_all ();
+ return 0;
+ }
+
/* We now know that we can do this combination. Merge the insns and
update the status of registers and LOG_LINKS. */