target/2309: arm-linux: unrecognizable insn
Bernd Schmidt
bernds@redhat.com
Tue Apr 3 03:39:00 GMT 2001
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. */
More information about the Gcc-bugs
mailing list