Command line: gcc -O2 -ftracer -fcompare-debug -c testcase.c Tested revisions: r156367 - crash r155609 - crash r154830 - crash r153685 - crash Output: $ /mnt/svn/gcc-trunk/binary-156367-lto/bin/gcc -O2 -ftracer -fcompare-debug -c testcase.c gcc: testcase.c: -fcompare-debug failure (length)
Created attachment 19768 [details] reduced testcase Command line: gcc -O2 -ftracer -fcompare-debug -c pr42918.c
Confirmed.
The problem here is missing INSN location on insn generated by insert_restore with -g (without -g it has one). Before IRA we have: (note 26 25 27 5 [bb 5] NOTE_INSN_BASIC_BLOCK) (call_insn 27 26 28 5 pr42918.c:14 (call (mem:QI (symbol_ref:DI ("fv") [flags 0x41] <function_decl 0x7feab75d6b00 fv>) [0 S1 A8]) (const_int 0 [0x0])) 638 {*call_0} (nil) (nil)) (note 28 27 30 5 ("lab") NOTE_INSN_DELETED_LABEL 3) (debug_insn 30 28 34 5 (var_location:SI i (reg/v:SI 59 [ i ])) -1 (nil)) at the end of a basic block (obviously with -g0 the debug_insn is missing). Now save_call_clobbered_regs restores all still saved regs at the end of a basic block, when the bb doesn't end with a jump, it restores after the last insn mentioned in reload_insn_chain for that bb, when it is a jump, then before it. As DEBUG_INSNs are included in reload_insn_chain, that is for -g after the DEBUG_INSN (and as insert_restore inserts after that insn, the insn has no location as DEBUG_INSN has no location either). For -g0 that is after the call insn, which has location and thus the restore insn gets the location of the call. Although emit_insn_after ignores DEBUG_INSNs, it doesn't ignore notes and there is this deleted label note in between. Changing save_call_clobbered_regs to restore all regs after the last non-debug insn in a bb wouldn't work well, as the restore insn invalidates the hard regs that could still hold something in the debug insn. I guess we could remember the INSN_LOCATOR of the last non-debug insn in the reload chain and use emit_insn_after_setloc in insert_restore (going to test it now), but wonder whether the fact that the deleted label is now after the hard reg restore insn in the -g0 case and before it in the -g case couldn't introduce other -fcompare-debug differences on other testcases.
Created attachment 19882 [details] gcc45-pr42918.patch Patch I've bootstrapped/regtested on x86_64-linux and i686-linux.
Subject: Bug 42918 Author: jakub Date: Wed Feb 17 08:54:59 2010 New Revision: 156823 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=156823 Log: PR debug/42918 * caller-save.c (save_call_clobbered_regs): If BB ends with a DEBUG_INSN, move any notes in between last real insn and the last DEBUG_INSN after the last DEBUG_INSN. * gcc.dg/pr42918.c: New test. Added: trunk/gcc/testsuite/gcc.dg/pr42918.c Modified: trunk/gcc/ChangeLog trunk/gcc/caller-save.c trunk/gcc/testsuite/ChangeLog
Fixed.