This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Unrepresentable subregs and hard_regno_nregs
On Thu, 21 Dec 2006, Andreas Schwab wrote:
> This breaks ia64.
>
> if [ x"-fpic" != x ]; then \
> /tmp/cvs/gcc-20061221/Build/./prev-gcc/xgcc -B/tmp/cvs/gcc-20061221/Build/./prev-gcc/ -B/tmp/cvs/gcc-20061221/Build/root/ia64-suse-linux/bin/ -c -DHAVE_CONFIG_H -g -O2 -I. -I../../libiberty/../include -W -Wall -pedantic -Wwrite-strings -Wstrict-prototypes -Wc++-compat -fpic ../../libiberty/regex.c -o pic/regex.o; \
> else true; fi
> ../../libiberty/regex.c: In function 'byte_regex_compile':
> ../../libiberty/regex.c:4221: internal compiler error: in subreg_get_info, at rtlanal.c:3034
>
> #1 0x40000000006f0720 in subreg_get_info (xregno=<value optimized out>,
> xmode=BImode, offset=0, ymode=BImode, info=0x607ffffffeb69c60)
> at ../../gcc/rtlanal.c:3034
> 3034 gcc_assert (regsize_xmode * nregs_xmode == GET_MODE_SIZE (xmode));
> (gdb) p regsize_xmode
> $1 = 0
> (gdb) p nregs_xmode
> $2 = 2
> (gdb) p xmode
> $3 = BImode
I propose this patch which disables the attempts to reason about register
sizes for such modes as the IA64 BImode taking 2 registers for 1 bit.
2006-12-21 Joseph Myers <joseph@codesourcery.com>
* rtlanal.c (subreg_get_info): Do not make register size
computations for mode sizes not divisible by the number of
registers.
Index: gcc/rtlanal.c
===================================================================
--- gcc/rtlanal.c (revision 120102)
+++ gcc/rtlanal.c (working copy)
@@ -3028,12 +3028,12 @@
/* If registers store different numbers of bits in the different
modes, we cannot generally form this subreg. */
if (!HARD_REGNO_NREGS_HAS_PADDING (xregno, xmode)
- && !HARD_REGNO_NREGS_HAS_PADDING (xregno, ymode))
+ && !HARD_REGNO_NREGS_HAS_PADDING (xregno, ymode)
+ && (GET_MODE_SIZE (xmode) % nregs_xmode) == 0
+ && (GET_MODE_SIZE (ymode) % nregs_ymode) == 0)
{
regsize_xmode = GET_MODE_SIZE (xmode) / nregs_xmode;
- gcc_assert (regsize_xmode * nregs_xmode == GET_MODE_SIZE (xmode));
regsize_ymode = GET_MODE_SIZE (ymode) / nregs_ymode;
- gcc_assert (regsize_ymode * nregs_ymode == GET_MODE_SIZE (ymode));
if (!rknown && regsize_xmode > regsize_ymode && nregs_ymode > 1)
{
info->representable_p = false;
--
Joseph S. Myers
joseph@codesourcery.com