This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

GCC 3.0 patch for subreg's in recog.c



I tracked down a problem I was having in gcc 3.0 tree to some 
funny looking notes produced by gcse. There was a subreg
expression in which a constant was being subsitituted, and
instead of either leaving the expression or evaluating
it, we were getting an insn that looked like :

(insn 4591 4590 4592 (set (reg:DI 1249)
        (sign_extend:DI (subreg/s:HI (reg/v:SI 349) 0))) 17 {extendhidi2} (nil)
    (expr_list:REG_EQUAL (clobber:DI (const_int 0 [0x0]))

Where we knew the value of  SI 349 to be a constant.

I traced it to this hunk of code for a zero/sign-extend

	  if (GET_CODE (XEXP (x, 0)) == SUBREG)
            {
              if (GET_MODE_SIZE (GET_MODE (XEXP (x, 0))) <= UNITS_PER_WORD)
                to = operand_subword (to, SUBREG_WORD (XEXP (x, 0)),
                                      0, GET_MODE (from));
	      else if (GET_MODE_CLASS (GET_MODE (from)) == MODE_INT
                       && (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
                           <= HOST_BITS_PER_WIDE_INT))
                {
		<...blah...>

(I had forgotten until now that subreg_byte was never applied to the
gcc3.0 branch.)

We call operand_subword if the size of the subreg is less than or equal
to UNITS_PER_WORD.  When you look at operand_subword (), one of the first things
it does is:

  /* If OP is narrower than a word, fail. */
  if (mode != BLKmode
      && (GET_MODE_SIZE (mode) < UNITS_PER_WORD))
    return 0;

So the code in validate_replace_rtx_1 appears to call operand_subword 
on the wrong conditions. The else clause does appear to handle items
less than UNITS_PER_WORD in size at whatever SUBREG_WORD offset is, if
it gets a chance to execute :-) 

I have tried the following patch, and it solves the problem, working the
way one might expect it to.  It passes all the tests and bootstraps on
ia64.  Is this OK to check into the 3.0 branch? 

The problem doesnt exist on the mainline branch because this code 
has all been replaced with various simplification routines.

Andrew

	* recog.c (validate_replace_rtx_1): Call operand_subreg only when
	the subreg type requires it.



Index: recog.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/recog.c,v
retrieving revision 1.87.4.3
diff -c -p -r1.87.4.3 recog.c
*** recog.c	2001/07/12 01:38:09	1.87.4.3
--- recog.c	2001/09/24 21:04:48
*************** validate_replace_rtx_1 (loc, from, to, o
*** 498,504 ****
  	     constant that we are interested in.  */
  	  if (GET_CODE (XEXP (x, 0)) == SUBREG)
  	    {
! 	      if (GET_MODE_SIZE (GET_MODE (XEXP (x, 0))) <= UNITS_PER_WORD)
  		to = operand_subword (to, SUBREG_WORD (XEXP (x, 0)),
  				      0, GET_MODE (from));
  	      else if (GET_MODE_CLASS (GET_MODE (from)) == MODE_INT
--- 498,504 ----
  	     constant that we are interested in.  */
  	  if (GET_CODE (XEXP (x, 0)) == SUBREG)
  	    {
! 	      if (GET_MODE_SIZE (GET_MODE (XEXP (x, 0))) >= UNITS_PER_WORD)
  		to = operand_subword (to, SUBREG_WORD (XEXP (x, 0)),
  				      0, GET_MODE (from));
  	      else if (GET_MODE_CLASS (GET_MODE (from)) == MODE_INT


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]