[gnu.gcc.bug] bug in combine.c

piet@ruuinf (Piet van Oostrum) (02/16/89)

------------------------------------------------------------------------
combine.c tries to optimize (SUBREG:m (MEM:n ...) k) RTL's and does not
take into account the BIG-endianness of the computer.
(This is on gcc version 1.32).

This generates wrong addresses when m<n (e.g. m=QI and n=SI).

This strikes the tahoe/hcx when a shift instruction is used with a
parameter as the shift count and the count is not loaded in a register.

e.g.

test(i,j)
unsigned i, j[];
{
	j[0] |= (1<<i);
}

A patch for updating addresses in combine.c follows.
------------------------------------------------------------------------
*** combine.c.~1~	Tue Jan 17 13:49:03 1989
--- combine.c	Wed Feb 15 16:33:38 1989
***************
*** 879,884
        if (SUBREG_REG (x) == to
  	  && GET_CODE (to) == MEM)
  	{
  	  if (!undobuf.storage)
  	    undobuf.storage = (char *) oballoc (0);
  	  /* Note if the plus_constant doesn't make a valid address

--- 879,885 -----
        if (SUBREG_REG (x) == to
  	  && GET_CODE (to) == MEM)
  	{
+ 	  register int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
  	  if (!undobuf.storage)
  	    undobuf.storage = (char *) oballoc (0);
  	  /* Note if the plus_constant doesn't make a valid address
***************
*** 883,888
  	    undobuf.storage = (char *) oballoc (0);
  	  /* Note if the plus_constant doesn't make a valid address
  	     then this combination won't be accepted.  */
  	  return gen_rtx (MEM, GET_MODE (x),
  			  plus_constant (XEXP (to, 0),
  					 SUBREG_WORD (x) * UNITS_PER_WORD));

--- 884,893 -----
  	    undobuf.storage = (char *) oballoc (0);
  	  /* Note if the plus_constant doesn't make a valid address
  	     then this combination won't be accepted.  */
+ #ifdef BYTES_BIG_ENDIAN
+ 	  offset -= (min (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))
+ 		     - min (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (to))));
+ #endif
  	  return gen_rtx (MEM, GET_MODE (x),
  			  plus_constant (XEXP (to, 0), offset));
  	}
***************
*** 884,891
  	  /* Note if the plus_constant doesn't make a valid address
  	     then this combination won't be accepted.  */
  	  return gen_rtx (MEM, GET_MODE (x),
! 			  plus_constant (XEXP (to, 0),
! 					 SUBREG_WORD (x) * UNITS_PER_WORD));
  	}
        break;
  

--- 889,895 -----
  		     - min (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (to))));
  #endif
  	  return gen_rtx (MEM, GET_MODE (x),
! 			  plus_constant (XEXP (to, 0), offset));
  	}
        break;
  
------------------------------------------------------------------------
Another thing which I wouldn't call a bug (maybe it was on purpose) is that
combine.c does not try to combine a binary operation with its two operands.
(it only tries to distribute the operation)
There is code in it for a special case but that is disabled.
Here is a patch to enable the code. Alternatively it could be integrated in
the distribution loop.
------------------------------------------------------------------------
***************
*** 325,330
  		  || GET_CODE (SET_DEST (PATTERN (insn))) == SIGN_EXTRACT
  		  || GET_CODE (SET_SRC (PATTERN (insn))) == ZERO_EXTRACT
  		  || GET_CODE (SET_SRC (PATTERN (insn))) == SIGN_EXTRACT))
  	    {
  	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
  		if (GET_CODE (XEXP (links, 0)) != NOTE)

--- 325,331 -----
  		  || GET_CODE (SET_DEST (PATTERN (insn))) == SIGN_EXTRACT
  		  || GET_CODE (SET_SRC (PATTERN (insn))) == ZERO_EXTRACT
  		  || GET_CODE (SET_SRC (PATTERN (insn))) == SIGN_EXTRACT))
+ #endif
  	    {
  	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
  		if (GET_CODE (XEXP (links, 0)) != NOTE)
***************
*** 333,339
  		    if (try_combine (insn, XEXP (links, 0), XEXP (nextlinks, 0)))
  		      goto retry;
  	    }
- #endif
  	  record_dead_and_set_regs (insn);
  	  prev = insn;
  	}

--- 334,339 -----
  		    if (try_combine (insn, XEXP (links, 0), XEXP (nextlinks, 0)))
  		      goto retry;
  	    }
  	  record_dead_and_set_regs (insn);
  	  prev = insn;
  	}
-- 
Piet van Oostrum, Dept of Computer Science, University of Utrecht
Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands
Telephone: +31-30-531806. piet@cs.ruu.nl (mcvax!hp4nl!ruuinf!piet)