Using r144996 configured for crisv32-axis-linux-gnu (but the error is there for crisv32-axis-elf, which is somewhat more repeatable and simulator-friendly), I get these errors: Running /tmp/x144980/gcc/gcc/testsuite/gcc.c-torture/execute/execute.exp ... ... FAIL: gcc.c-torture/execute/stdarg-3.c compilation, -O3 -fomit-frame-pointer -funroll-loops (internal compiler error) FAIL: gcc.c-torture/execute/stdarg-3.c compilation, -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (internal compiler error) The error message in gcc.log for the both is: x/gcc.c-torture/execute/stdarg-3.c: In function 'main': x/gcc.c-torture/execute/stdarg-3.c:166: internal compiler error: in reload_as_needed, at reload1.c:4380 "call debug_rtx (insn)" at the gcc_assert at the line in question yields (insn 427 1353 1140 17 /tmp/x144980/gcc/gcc/testsuite/gcc.c-torture/execute/stdarg-3.c:144 (set (mem/s/c:SI (reg:SI 6 r6) [10 S4 A8]) (reg:SI 8 r8)) 38 {*movsi_internal} (expr_list:REG_INC (reg:SI 8 r8) (expr_list:REG_INC (reg:SI 6 r6) (nil)))) and in_hard_regno is 8 and in_regno is 207. Note the "spurious" left-over REG_INC note. It seems revision 142328 (the fix for PR37514, in which the code and the triggering gcc_assert was added) exposed or cause this bug. A crisv32-axis-elf cc1 from tags/gcc_4_3_3_release does not give any such error, neither does trunk r142327. Trunk r142328 does give the error. FWIW, crisv32-*-* has the interesting trait that it's AUTO_INC_DEC, has a moderate amount of registers available (in contrast to e.g. ia64) and can't offset addresses (only (mem reg) and (mem (post_inc reg)) are valid).
Created attachment 17515 [details] preprocessed stdarg-3.c to avoid stdarg.h dependency.
Same bug is present as a g++.dg/torture/pr31863.C -O2 (and higher) regression.
Thanks for reporting this. The compiler is broken on gcc_assert in the following code + else if ((code == PRE_INC || code == PRE_DEC + || code == POST_INC || code == POST_DEC)) + { + int in_hard_regno; + int in_regno = REGNO (XEXP (in_reg, 0)); + + if (reg_last_reload_reg[in_regno] != NULL_RTX) + { + in_hard_regno = REGNO (reg_last_reload_reg[in_regno]); + gcc_assert (TEST_HARD_REG_BIT (reg_reloaded_valid, + in_hard_regno)); + for (x = old_prev ? NEXT_INSN (old_prev) : insn; + x != old_next; + x = NEXT_INSN (x)) + if (x == reg_reloaded_insn[in_hard_regno]) + break; + /* If for some reasons, we didn't set up + reg_last_reload_reg in this insn, + invalidate inheritance from previous + insns for the incremented/decremented + register. Such registers will be not in + reg_has_output_reload. */ + if (x == old_next) + forget_old_reloads_1 (XEXP (in_reg, 0), + NULL_RTX, NULL); + } + } Here in_regno is 191 and in_hard_regno is 8. This code is executed after emit_insn_reloads which invalidates hard register 8 when processing reload #5 of the current insn. I've overlooked this possibility in my patch for PR37514 http://gcc.gnu.org/ml/gcc-patches/2008-11/msg01424.html reg_reloaded_valid should be checked for reg_reloaded_insn validity but not as gcc_assert. I'll send a new patch solving the problem soon. (insn 411 1161 1160 17 /tmp/x144980/gcc/gcc/testsuite/gcc.c-torture/execute/stdarg-3.c:144 (set (mem/s/c:SI (post_inc:SI (reg/f:SI 192)) [10 S4 A8]) (mem/s/c:SI (post_inc:SI (reg/f:SI 191)) [10 a3+4 S4 A16])) 38 {*movsi_internal} (expr_list:REG_INC (reg/f:SI 191) (expr_list:REG_INC (reg/f:SI 192) (nil)))) Reloads for insn # 411 Reload 0: reload_in (SI) = (plus:SI (reg/f:SI 14 sp) (const_int 104 [0x68])) GENERAL_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 0), can't combine reload_in_reg: (plus:SI (reg/f:SI 14 sp) (const_int 104 [0x68])) reload_reg_rtx: (reg:SI 9 r9) Reload 1: reload_in (SI) = (post_inc:SI (mem/c:SI (plus:SI (reg/f:SI 14 sp) (const_int 104 [0x68])) [11 %sfp+-280 S4 A8])) reload_out (SI) = (post_inc:SI (mem/c:SI (plus:SI (reg/f:SI 14 sp) (const_int 104 [0x68])) [11 %sfp+-280 S4 A8])) GENERAL_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 0), inc by 4, can't combine reload_in_reg: (post_inc:SI (reg/f:SI 192)) reload_reg_rtx: (reg:SI 6 r6) Reload 2: reload_in (SI) = (plus:SI (reg/f:SI 14 sp) (const_int 100 [0x64])) GENERAL_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 1), can't combine reload_in_reg: (plus:SI (reg/f:SI 14 sp) (const_int 100 [0x64])) reload_reg_rtx: (reg:SI 9 r9) Reload 3: reload_in (SI) = (post_inc:SI (mem/c:SI (plus:SI (reg/f:SI 14 sp) (const_int 100 [0x64])) [11 %sfp+-284 S4 A8])) reload_out (SI) = (post_inc:SI (mem/c:SI (plus:SI (reg/f:SI 14 sp) (const_int 100 [0x64])) [11 %sfp+-284 S4 A8])) GENERAL_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 1), inc by 4, can't combine reload_in_reg: (post_inc:SI (reg/f:SI 191)) reload_reg_rtx: (reg:SI 8 r8) Reload 4: reload_out (SI) = (mem/s/c:SI (post_inc:SI (reg/f:SI 192)) [10 S4 A8]) NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional reload_out_reg: (mem/s/c:SI (post_inc:SI (reg/f:SI 192)) [10 S4 A8]) Reload 5: reload_in (SI) = (mem/s/c:SI (post_inc:SI (reg/f:SI 191)) [10 a3+4 S4 A16]) GENERAL_REGS, RELOAD_FOR_INPUT (opnum = 1) reload_in_reg: (mem/s/c:SI (post_inc:SI (reg/f:SI 191)) [10 a3+4 S4 A16]) reload_reg_rtx: (reg:SI 8 r8)
Patch at <http://gcc.gnu.org/ml/gcc-patches/2009-03/msg01229.html>. Thanks! I'll test crisv32-axis-linux-gnu and report.
Subject: Bug 39522 Author: vmakarov Date: Thu Mar 26 19:21:18 2009 New Revision: 145093 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=145093 Log: 2009-03-26 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/39522 * reload1.c (reload_as_needed): Invalidate reg_last_reload_reg too when reg_reloaded_valid is set. Modified: trunk/gcc/ChangeLog trunk/gcc/reload1.c
Closing. The patch, now committed, does the job with no regressions for crisv32-axis-linux-gnu.