This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: target/2309: arm-linux: unrecognizable insn
- To: <philb at gnu dot org>
- Subject: Re: target/2309: arm-linux: unrecognizable insn
- From: Bernd Schmidt <bernds at redhat dot com>
- Date: Tue, 3 Apr 2001 11:39:44 +0100 (BST)
- Cc: <gcc-gnats at gcc dot gnu dot org>, <gcc-patches at gcc dot gnu dot org>,<gcc-bugs at gcc dot gnu dot org>
On 17 Mar 2001 philb@gnu.org wrote:
> The attached testcase (actually part of GNU binutils) produces this error:
>
> gcc -DHAVE_CONFIG_H -I. -I../../bfd -I. -D_GNU_SOURCE -I. -I../../bfd -I../../bfd/../include -I../../bfd/../intl -I../intl -W -Wall -O2 -c pepigen.c -o pepigen.o
> pepigen.c: In function `pe_print_pdata':
> pepigen.c:1687: internal error--unrecognizable insn:
> (insn 564 558 566 (set (reg:SI 176)
> (mem/s:SI (plus:SI (reg/v:SI 36)
> (subreg:SI (reg:DI 132) 0)) 0)) -1 (nil)
> (nil))
An analysis of this problem can be found at
http://gcc.gnu.org/ml/gcc-patches/1999-06/msg00419.html
I originally planned to fix it by modifying GO_IF_LEGITIMATE_ADDRESS et al.
in arm.h, but then I decided to avoid the problem in the loop optimizer.
If it affects mips and arm, it'll probably affect more targets as well.
I'll install the following patch on the 2.95 branch. We may want to consider
it for the mainline and for 3.0 as well if there are targets in the current
sources that don't allow SUBREGs in memory references.
Bernd
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ChangeLog,v
retrieving revision 1.3667.4.348
diff -u -p -r1.3667.4.348 ChangeLog
--- ChangeLog 2001/04/03 10:34:15 1.3667.4.348
+++ ChangeLog 2001/04/03 10:37:01
@@ -5,6 +5,10 @@
Remove ia32 linux PIC kludge and move it...
* config/i386/linux.h (CRT_END_INIT_DUMMY): ...here.
+ * loop.c (combine_movables): Restrict combinations of constants with
+ different modes so that we don't introduce SUBREGs into memory
+ addresses.
+
2001-03-30 Bernd Schmidt <bernds@redhat.com>
* jump.c (delete_barrier_successors): Fix error in last change.
Index: loop.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/loop.c,v
retrieving revision 1.156.4.20
diff -u -p -r1.156.4.20 loop.c
--- loop.c 2001/01/25 14:03:18 1.156.4.20
+++ loop.c 2001/04/03 10:37:04
@@ -1481,10 +1481,16 @@ combine_movables (movables, nregs)
width as M1. The check for integer is redundant, but
safe, since the only case of differing destination
modes with equal sources is when both sources are
- VOIDmode, i.e., CONST_INT. */
+ VOIDmode, i.e., CONST_INT.
+
+ For 2.95, don't do this if the mode of M1 is Pmode.
+ This prevents us from substituting SUBREGs for REGs
+ in memory accesses; not all targets are prepared to
+ handle this properly. */
(GET_MODE (m->set_dest) == GET_MODE (m1->set_dest)
|| (GET_MODE_CLASS (GET_MODE (m->set_dest)) == MODE_INT
&& GET_MODE_CLASS (GET_MODE (m1->set_dest)) == MODE_INT
+ && GET_MODE (m1->set_dest) != Pmode
&& (GET_MODE_BITSIZE (GET_MODE (m->set_dest))
>= GET_MODE_BITSIZE (GET_MODE (m1->set_dest)))))
/* See if the source of M1 says it matches M. */