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. */