Bug 56184 - [4.8 Regression] Internal compiler error in push_reload during bootstrap stage 2
Summary: [4.8 Regression] Internal compiler error in push_reload during bootstrap stage 2
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.8.0
: P1 normal
Target Milestone: 4.8.0
Assignee: Not yet assigned to anyone
Keywords: ice-on-valid-code
Depends on:
Reported: 2013-02-02 19:28 UTC by Matthew Gretton-Dann
Modified: 2013-02-14 00:16 UTC (History)
6 users (show)

See Also:
Target: arm*-*-*
Known to work:
Known to fail:
Last reconfirmed: 2013-02-10 00:00:00

Reduced test case (2.02 KB, application/octet-stream)
2013-02-02 19:28 UTC, Matthew Gretton-Dann
RTL dump from IRA phase (40.07 KB, text/plain)
2013-02-05 13:11 UTC, mgretton
RTL dump from reload phase (5.05 KB, text/plain)
2013-02-05 13:12 UTC, mgretton

Note You need to log in before you can comment on or make changes to this bug.
Description Matthew Gretton-Dann 2013-02-02 19:28:50 UTC
Created attachment 29337 [details]
Reduced test case

When bootstrapping on an ARM target I get the following error:

/cbuild/slaves/tcpandas/gcc-4.8~svn195568/gcc/default/build/./prev-gcc/xg++ -B/cbuild/slaves/tcpandas/gcc-4.8~svn195568/gcc/default/build/./prev-gcc/ -B/cbuild/slaves/tcpandas/gcc-4.8~svn195568/gcc/default/install/arm-linux-gnueabi/bin/ -nostdinc++ -B/cbuild/slaves/tcpandas/gcc-4.8~svn195568/gcc/default/build/prev-arm-linux-gnueabi/libstdc++-v3/src/.libs -B/cbuild/slaves/tcpandas/gcc-4.8~svn195568/gcc/default/build/prev-arm-linux-gnueabi/libstdc++-v3/libsupc++/.libs -I/cbuild/slaves/tcpandas/gcc-4.8~svn195568/gcc/default/build/prev-arm-linux-gnueabi/libstdc++-v3/include/arm-linux-gnueabi -I/cbuild/slaves/tcpandas/gcc-4.8~svn195568/gcc/default/build/prev-arm-linux-gnueabi/libstdc++-v3/include -I/cbuild/slaves/tcpandas/gcc-4.8~svn195568/gcc/gcc-4.8~svn195568/libstdc++-v3/libsupc++ -L/cbuild/slaves/tcpandas/gcc-4.8~svn195568/gcc/default/build/prev-arm-linux-gnueabi/libstdc++-v3/src/.libs -L/cbuild/slaves/tcpandas/gcc-4.8~svn195568/gcc/default/build/prev-arm-linux-gnueabi/libstdc++-v3/libsupc++/.libs -c   -g -O2 -gtoggle -DIN_GCC   -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Werror -fno-common  -DHAVE_CONFIG_H -I. -I. -I../../../gcc-4.8~svn195568/gcc -I../../../gcc-4.8~svn195568/gcc/. -I../../../gcc-4.8~svn195568/gcc/../include -I../../../gcc-4.8~svn195568/gcc/../libcpp/include  -I../../../gcc-4.8~svn195568/gcc/../libdecnumber -I../../../gcc-4.8~svn195568/gcc/../libdecnumber/dpd -I../libdecnumber -I../../../gcc-4.8~svn195568/gcc/../libbacktrace    ../../../gcc-4.8~svn195568/gcc/lto-streamer-out.c -o lto-streamer-out.o
../../../gcc-4.8~svn195568/gcc/lto-streamer-in.c: In function 'void lto_input_function_body(lto_file_decl_data*, tree, const char*)':
../../../gcc-4.8~svn195568/gcc/lto-streamer-in.c:1003:1: internal compiler error: in push_reload, at reload.c:1014
0x6d1a41 push_reload(rtx_def*, rtx_def*, rtx_def**, rtx_def**, reg_class, machine_mode, machine_mode, int, int, int, reload_type)
0x6daa8d find_reloads(rtx_def*, int, int, int, short*)
0x6e6d8b calculate_needs_all_insns
0x6e560b reload(rtx_def*, int)
0x5f1843 do_reload
0x5f1a33 rest_of_handle_reload
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
make[7]: *** [lto-streamer-in.o] Error 1

GCC has been configured as follows:

--prefix=/cbuild/slaves/tcpandas/gcc-4.8~svn195568/gcc/default/install --enable-languages=c,c++,objc,obj-c++,fortran,lto --enable-linker-build-id --with-mode=thumb --with-arch=armv7-a --with-tune=cortex-a9 --with-fpu=neon --with-float=softfp --build=arm-linux-gnueabi

Attached test case is a reduced version which triggers the same problem with a cross-compiler configured as:

Configured with: /work/sources/gcc-fsf/master/configure --target=arm-none-linux-gnueabi --prefix=/work/builds/gcc-fsf-master/tools --with-sysroot=/work/builds/gcc-fsf-master/sysroot-arm-none-linux-gnueabi --disable-libssp --disable-libgomp --disable-libmudflap --enable-languages=c,c++ --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=softfp --with-thumb

Attached test case invoked by:

.../arm-none-linux-gnueabi-g++  -c    -O2 -mthumb -march=armv7-a -mfpu=neon -mfloat-abi=softfp -mtune=cortex-a9 test.ii

Bisecting suggests the issue was introduced by subversion revision 194558:

    2012-12-17  Andrew Stubbs  <ams@codesourcery.com>
            Ulrich Weigand  <ulrich.weigand@linaro.org>
        * config/arm/arm.md (zero_extend<mode>di2): Add extra alternatives
        for NEON registers.
        Add alternative for one-instruction extend-in-place.
        (extend<mode>di2): Likewise.
        Add constraints for Thumb-mode memory loads.
        Prevent extend splitters doing NEON alternatives.
        * config/arm/iterators.md (qhs_extenddi_cstr, qhs_zextenddi_cstr):
        Adjust constraints to add new alternatives.
        * config/arm/neon.md: Add splitters for zero- and sign-extend.
        * gcc.target/arm/neon-extend-1.c: New file.
        * gcc.target/arm/neon-extend-2.c: New file.
Comment 1 mgretton 2013-02-05 13:08:48 UTC
I can reproduce this is in a compiler targeted for arm-none-eabi (and without needing libraries built) as follows:

Compiler configured with: /work/sources/gcc-fsf/master/configure --target=arm-none-eabi --prefix=/work/builds/gcc-fsf-master/tools --without-headers --with-newlib --disable-shared --disable-threads --disable-libssp --disable-libgomp --disable-libmudflap --disable-libatomic --without-libquadmath --disable-libquadmath --enable-languages=c,c++

./cc1plus -fpreprocessed test.ii -mthumb -march=armv7-a -mfpu=neon -mfloat-abi=softfp -mtune=cortex-a9 -O2 -o /tmp/tmp.s

RTL dumps of 208r.ira and 208r.reload are attached from running the above command.

The assert producing the ICE is:

      int regno = REGNO (out);
      gcc_assert (regno < FIRST_PSEUDO_REGISTER
		  || reg_renumber[regno] >= 0
		  || reg_equiv_constant (regno) == NULL_RTX);

out: (reg:DI 358 [315])
regno: 358
reg_renumber[regno] = -1
reg_equiv_constant (regno) = ? (Can't get GDB to print the value)
Comment 2 mgretton 2013-02-05 13:11:33 UTC
Created attachment 29357 [details]
RTL dump from IRA phase
Comment 3 mgretton 2013-02-05 13:12:18 UTC
Created attachment 29358 [details]
RTL dump from reload phase
Comment 4 Ulrich Weigand 2013-02-05 13:51:24 UTC
This is weird; I cannot reproduce the behaviour even with the exact configure and command lines you specify.  I've been using SVN rev. 195717; which revision do you see the problem with?

In the generated test.ii.208r.ira file I get, I see different register uses even before IRA, compared to your version.

Would you mind sending me (offline) a full set of the dump files so I can see where my compile run starts to diverge from yours?
Comment 5 Ulrich Weigand 2013-02-06 19:27:31 UTC
Depending on configure tests of the installed (cross-)assembler, the ICE may not occur.  In those cases, I'm now able to reliably reproduce the ICE by using -fno-section-anchors (in addition to the flags given above).
Comment 6 Ulrich Weigand 2013-02-06 19:40:30 UTC
The problem occurs with the following insn:

(insn 539 383 384 46
 (set (reg:DI 355 [313]) (const_int 256 [0x100]))
 test.ii:128 643 {*movdi_vfp}
 (expr_list:REG_EQUIV (const_int 256 [0x100])

Register 355 is recognized as always-equal to the constant 256, and insn 539 is the insn that originally sets up the equivalence.  If the register doesn't get a hard reg, what ought to happen is that users of reg 355 get replaced by the constant, and the insn setting the equivalence ought to be deleted.  Because the insn will get deleted anyway, it also ought to be skipped for find_reloads.

To achieve that, reg_equiv_constant(355) should hold the constant, and reg_equiv_init(355) should point to the above insn.  However, what actually happens in this test case is that reg_equiv_init(355) is NULL.  Therefore, the insn is *not* skipped for find_reloads, which then aborts since it tries to push an output reload for an always-constant register, which is not supposed to happen.

Now the register is somewhat special in that it was created by IRA via live range splitting.  The original register was reg 313; and this still has reg_equiv_init(313) pointing to the above insn.  However, reg_equiv_init(355) is NULL.  There is a routine fix_reg_equiv_init in ira.c which appears to be intended to fix the reg_equiv_init settings of new registers created by live range splitting.  However, this doesn't seem to have worked in this case ...

Unfortunately I'm not really familiar with the live range splitting code; maybe Vladimir can help with this?
Comment 7 Vladimir Makarov 2013-02-13 15:15:14 UTC
(In reply to comment #6)
> Unfortunately I'm not really familiar with the live range splitting code; maybe
> Vladimir can help with this?

Yes, Ulrich.  I've started to work on this.
Comment 8 Vladimir Makarov 2013-02-13 17:40:33 UTC
Author: vmakarov
Date: Wed Feb 13 17:40:22 2013
New Revision: 196019

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=196019
2013-02-13  Vladimir Makarov  <vmakarov@redhat.com>

	PR target/56184
	* ira.c (max_regno_before_ira): Move from ...
	(ira): ... here.
	(fix_reg_equiv_init): Use max_regno_before_ira instead of

2013-02-13  Vladimir Makarov  <vmakarov@redhat.com>

	PR target/56184
	* gcc.target/arm/pr56184.C: New test.

Comment 9 Jakub Jelinek 2013-02-14 00:16:19 UTC