Fix PR rtl-optimization/45593

Eric Botcazou ebotcazou@adacore.com
Wed Sep 15 23:59:00 GMT 2010


This is a segfault compiling the kernel at -Os for the SPARC, a regression 
present on the mainline and 4.5 branch.  The crash occurs during delay slot 
scheduling, aka reorg.

We start with an insn that is put into a delay slot by fill_simple_delay_slots 
during the first reorg pass; it is only copied and not deleted.  Then it is 
put into a second delay slot by fill_eager_delay_slots, re-copied and still 
not deleted.  Then fill_eager_delay_slots, upon attempting to put it into a 
third delay slot, notices that the insn is now redundant with the copy of 
itself(!) put into the second delay slot and finally deletes it from its 
original place.  Then relax_delay_slots kicks in and remarks that the cond 
jump owning the second delay slot jumps to the next instruction; therefore it 
re-emits the insn that was in the second delay slot as a stand-alone insn and 
deletes the jump.  In the end, the insn has been copied into a delay slot and 
hoisted in the stream; in particular, its basic block changed.

These transformations are interleaved with queries to mark_target_live_regs 
which needs to know for each insn the basic block it can use to start 
computing liveness info from.  The results are cached in a hash table indexed 
by the INSN_UID of the insns.  Although insns are copied as a whole when they 
are put into delay slots, INSN_UID included, this works because m_t_l_r 
doesn't look within SEQUENCEs to compute the basic block; only the enclosing 
insn is looked at and these insns don't move.

Things go awry when relax_delay_slots re-emits insns that were in delay slots 
as stand-alone insns, because they are re-emitted as-is and thus we end up 
with several top-level insns with the same INSN_UID in the stream, which of 
course mightily confuses the caching done for mark_target_live_regs.  That's 
what happens here and causes the crash during the second reorg pass.

A radical fix could be to hash the insns themselves instead of their INSN_UID 
but that's probably overkill.  So the patch just makes sure the INSN_UID of 
the insns is changed where they are re-emitted in relax_delay_slots.

Bootstrapped/regtesed on sparc-sun-solaris2.8 and sparc64-sun-solaris2.9, 
applied on the mainline and 4.5 branch.


2010-09-15  Eric Botcazou  <ebotcazou@adacore.com>

	PR rtl-optimization/45593
	* reorg.c (relax_delay_slots): Use emit_copy_of_insn_after to re-emit
	insns that were in delay slots as stand-alone insns.


2010-09-15  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.c-torture/compile/20100915-1.c: New test.


-- 
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr45593.diff
Type: text/x-diff
Size: 2886 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20100915/2e1862d0/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 20100915-1.c
Type: text/x-csrc
Size: 1986 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20100915/2e1862d0/attachment-0001.bin>


More information about the Gcc-patches mailing list