Obscure bugfix in combine.c

Richard Kenner kenner@vlsi1.ultra.nyu.edu
Tue Jan 16 15:01:00 GMT 2001


If we have an insn that sets a part of a multi-word register to a constant
and that register was previously set to a (usually zero) constant, we can
replace the two insns with a set of a new constant.  This is a rare
kind of substitution where we update I2.

There is tracking code in try_combine to do something special in this case
if I2 has multiple sets.  However, instead of checking single_set, it
looks for a PARALLEL, which is wrong since I2 might have had a CLOBBER,
like on x86.

The problem with executing this code is that register notes get copied
to the new insn, including a REG_EQUIV or REG_EQUIV for the wrong constant.
This caused problems in reload on an Ada example in GCC 2.8.1.  On the
current compiler, the wrong REG_NOTE is still there, but it so happens
that it doesn't cause any problems.  But the bug is still there.  This is
the obvious fix, to make the code agree with the comments.  I know of no
test case that fails for the current compiler, but enough work could
produce one, I suspect.

Tue Jan 16 17:20:43 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* combine.c (try_combine): If i3_subst_into_i2, properly check for
	I3 having more than one SET.

*** combine.c	2001/01/14 10:39:49	1.176
--- combine.c	2001/01/16 14:13:53
*************** try_combine (i3, i2, i1, new_direct_jump
*** 2525,2529 ****
         properly handled.  */
  
!     if (i3_subst_into_i2 && GET_CODE (PATTERN (i2)) == PARALLEL)
        {
  	for (i = 0; i < XVECLEN (PATTERN (i2), 0); i++)
--- 2525,2529 ----
         properly handled.  */
  
!     if (i3_subst_into_i2 && single_set (i2) == 0)
        {
  	for (i = 0; i < XVECLEN (PATTERN (i2), 0); i++)


More information about the Gcc-patches mailing list