This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
not so trivial powerpc regression fix
- To: gcc-patches at gcc dot gnu dot org, rth at cygnus dot com, kenner at vlsi1 dot ultra dot nyu dot edu
- Subject: not so trivial powerpc regression fix
- From: Jan Hubicka <jh at suse dot cz>
- Date: Fri, 18 May 2001 23:41:43 +0200
Hi
The third powerpc regression is caused by the fact, that combine originally
unconditionally stripped any subreg around MEM, while I am now more selective
and don't strip SUBREGS unless resulting MEM match.
Problem is that combine now produces following operand:
(subreg:QI (mem/s/u:HI (lo_sum:SI (reg/f:SI 84)
(symbol_ref/f:SI ("*.LC0"))) 2) 1)
this operand is silently accepted by general_operand, as it just ignores
subreg, but the memory reference, once subreg is stripped may not match,
as it is not offsetable.
reload later does the offsetting when attempting to remove subreg and
causes gcc to crash in final pass while outputing missformated
memory reference.
The patch seems to be to avoid general_operand from this behaviour.
In the patch I am quite aggressive and simply prohibit nonzero byte for
subreg if inside is memory. Maybe I can be even more aggressive and
prohibit all non-paradoxical subregs instead, or less aggressive and
verify if offsetted memory will match.
I think we should simply avoid existence of unnecesary subregs around
MEMs, especially now when we can strip it easilly, so highest aggresivity
level may be the best. What do you think?
Fri May 18 23:41:00 CEST 2001 Jan Hubicka <jh@suse.cz>
* recog.c (general_operand): Prohibit nonzero subreg bytes on
subregs containing mem.
Index: recog.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/recog.c,v
retrieving revision 1.102
diff -c -3 -p -r1.102 recog.c
*** recog.c 2001/05/17 17:49:34 1.102
--- recog.c 2001/05/18 21:40:08
*************** general_operand (op, mode)
*** 1029,1034 ****
--- 959,969 ----
&& GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))))
return 0;
#endif
+ /* Avoid memories with nonzero SUBREG_BYTE, as offsetting the memory
+ may result in incorrect reference. We should simplify all valid
+ subregs of MEM anyway. */
+ if (SUBREG_BYTE (op) && GET_CODE (SUBREG_REG (op)) == MEM)
+ return 0;
op = SUBREG_REG (op);
code = GET_CODE (op);