This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
GCC 3.0 patch for subreg's in recog.c
- To: gcc-patches at gcc dot gnu dot org
- Subject: GCC 3.0 patch for subreg's in recog.c
- From: Andrew Macleod <amacleod at cygnus dot com>
- Date: Tue, 25 Sep 2001 07:13:42 -0700
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