[4.1] Fix PR rtl-optimization/29329

Eric Botcazou ebotcazou@libertysurf.fr
Sun Jan 21 22:35:00 GMT 2007


This is yet another ICE related to REG_NOTES handling in the combiner, a 
regression present at -O2 on the 4.1 branch for the ARM architecture.

The combiner is passed

(insn 55 54 102 6 (set (reg/v:SI 107 [ j ])
        (plus:SI (reg/v:SI 107 [ j ])
            (const_int 1 [0x1]))) 4 {*arm_addsi3} (nil)
    (expr_list:REG_EQUAL (const_int 3 [0x3])
        (nil)))

(insn 102 55 115 6 (set (reg:SI 124)
        (ashift:SI (reg/v:SI 107 [ j ])
            (const_int 2 [0x2]))) 98 {*arm_shiftsi3} (insn_list:REG_DEP_TRUE 
55 (nil))
    (expr_list:REG_DEAD (reg/v:SI 107 [ j ])
        (expr_list:REG_EQUAL (const_int 12 [0xc])
            (nil))))

It will first try to directly replace the source of insn 102 by the 
destination of insn 55, but the result fails to validate.  Then it will
try again, after having replaced the source of insn 55 by the contents of the 
REG_EQUAL note, and the result this time validates.

Things go awry when distribute_notes is asked to find a new position for the 
REG_DEAD note because (reg/v:SI 107) is considered the eliminated register so 
the note is ditched without further ado.  Now (reg/v:SI 107) was formally 
live on entry of the basic block and life2 expects it to be still live after 
combine, so it stops the compiler.

This REG_EQUAL + REG_DEAD game has been already "studied" by Richard S. and me 
and we agreed that the best solution is implemented by

2007-01-06  Richard Sandiford  <richard@codesourcery.com>

	Backport from mainline:
	2006-05-23  Richard Sandiford  <richard@codesourcery.com>

	PR rtl-optimization/27736
	* combine.c (replaced_rhs_value): New variable.
	(combine_instructions): Set it.
	(distribute_notes): When distributing a note in replaced_rhs_insn,
	check whether the value was used in replaced_rhs_value.

	2006-05-22  Richard Sandiford  <richard@codesourcery.com>

	PR rtl-optimization/25514
	* combine.c (replaced_rhs_insn): New variable.
	(combine_instructions): Set replaced_rhs_insn when trying to replace
	a SET_SRC with a REG_EQUAL note.
	(distribute_notes): Use replaced_rhs_insn when determining the live
	range of a REG_DEAD register.

that Richard recently backported to the 4.1 branch.  Therefore the fix builds 
on Richard's work to avoid ditching REG_DEAD notes when they pertain to the
source of the insn to which the REG_EQUAL note is attached.  Since this stuff 
is strongly tied to the 2nd insn of the 3-insn window used by the combiner,
I took the liberty to rename the objects to emphasize it.

The patch also reverts

2006-09-12  Eric Botcazou  <ebotcazou@libertysurf.fr>

	PR rtl-optimization/28243
	* combine.c (distribute_notes) <REG_DEAD>: Do not consider SETs past
	the insn to which the note was originally attached.

which was a fix for another variant of the problem and has been superseded by 
Richard's backport (no compilers released by the FSF contain it).

Bootstrapped/regtested on x86_64-suse-linux, applied to mainline, 4.2 branch 
and 4.1 branch.


2007-01-21  Eric Botcazou  <ebotcazou@libertysurf.fr>

	PR rtl-optimization/29329
	* combine.c (replaced_rhs_insn): Rename to i2mod.
	(replaced_rhs_value): Rename to i2mod_new_rhs.
	(i2mod_old_rhs): New global variable.
	(combine_instructions): Adjust for above change.  Save a copy of
	the old RHS into i2mod_old_rhs when the contents of a REG_EQUAL
	note are substituted in the second instruction.
	(distribute_notes) <REG_DEAD>: Adjust for above change.  Do not
	ditch the note if it pertains to the second eliminated register
	and this register is mentioned in i2mod_old_rhs.

	Revert:
	2006-09-12  Eric Botcazou  <ebotcazou@libertysurf.fr>

	* combine.c (distribute_notes) <REG_DEAD>: Do not consider SETs past
	the insn to which the note was originally attached.


2007-01-21  Eric Botcazou  <ebotcazou@libertysurf.fr>

	* gcc.c-torture/compile/20070121.c: New test.


-- 
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr29329.diff
Type: text/x-diff
Size: 3845 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20070121/f14b035e/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr29329.c
Type: text/x-csrc
Size: 356 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20070121/f14b035e/attachment-0001.bin>


More information about the Gcc-patches mailing list