re PR rtl-optimization/29329 (internal consistency failure)

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.

From-SVN: r121037
This commit is contained in:
Eric Botcazou 2007-01-21 23:32:39 +01:00 committed by Eric Botcazou
parent f64acab6ab
commit 64c9193063
4 changed files with 71 additions and 22 deletions

View File

@ -1,3 +1,22 @@
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 Jan Hubicka <jh@suse.cz>
* ipa-inline.c (inlining_mode): Comment, move up.

View File

@ -123,16 +123,22 @@ static int combine_successes;
static int total_attempts, total_merges, total_extras, total_successes;
/* Sometimes combine tries to replace the right hand side of an insn
with the value of a REG_EQUAL note. This is the insn that has been
so modified, or null if none. */
/* combine_instructions may try to replace the right hand side of the
second instruction with the value of an associated REG_EQUAL note
before throwing it at try_combine. That is problematic when there
is a REG_DEAD note for a register used in the old right hand side
and can cause distribute_notes to do wrong things. This is the
second instruction if it has been so modified, null otherwise. */
static rtx replaced_rhs_insn;
static rtx i2mod;
/* When REPLACED_RHS_INSN is nonnull, this is a copy of the new right
hand side. */
/* When I2MOD is nonnull, this is a copy of the old right hand side. */
static rtx replaced_rhs_value;
static rtx i2mod_old_rhs;
/* When I2MOD is nonnull, this is a copy of the new right hand side. */
static rtx i2mod_new_rhs;
/* Vector mapping INSN_UIDs to cuids.
The cuids are like uids but increase monotonically always.
@ -932,11 +938,12 @@ combine_instructions (rtx f, unsigned int nregs)
be deleted or recognized by try_combine. */
rtx orig = SET_SRC (set);
SET_SRC (set) = note;
replaced_rhs_insn = temp;
replaced_rhs_value = copy_rtx (note);
next = try_combine (insn, temp, NULL_RTX,
i2mod = temp;
i2mod_old_rhs = copy_rtx (orig);
i2mod_new_rhs = copy_rtx (note);
next = try_combine (insn, i2mod, NULL_RTX,
&new_direct_jump_p);
replaced_rhs_insn = NULL;
i2mod = NULL_RTX;
if (next)
goto retry;
SET_SRC (set) = orig;
@ -12140,8 +12147,8 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
use of A and put the death note there. */
if (from_insn
&& from_insn == replaced_rhs_insn
&& !reg_overlap_mentioned_p (XEXP (note, 0), replaced_rhs_value))
&& from_insn == i2mod
&& !reg_overlap_mentioned_p (XEXP (note, 0), i2mod_new_rhs))
tem = from_insn;
else
{
@ -12154,7 +12161,10 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
else if (i2 != 0 && next_nonnote_insn (i2) == i3
&& reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
place = i2;
else if (rtx_equal_p (XEXP (note, 0), elim_i2)
else if ((rtx_equal_p (XEXP (note, 0), elim_i2)
&& !(i2mod
&& reg_overlap_mentioned_p (XEXP (note, 0),
i2mod_old_rhs)))
|| rtx_equal_p (XEXP (note, 0), elim_i1))
break;
tem = i3;
@ -12173,14 +12183,12 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
continue;
}
/* If TEM is a (reaching) definition of the use to which the
note was attached, see if that is all TEM is doing. If so,
delete TEM. Otherwise, make this into a REG_UNUSED note
instead. Don't delete sets to global register vars. */
if ((!from_insn
|| INSN_CUID (tem) < INSN_CUID (from_insn))
&& (REGNO (XEXP (note, 0)) >= FIRST_PSEUDO_REGISTER
|| !global_regs[REGNO (XEXP (note, 0))])
/* If the register is being set at TEM, see if that is all
TEM is doing. If so, delete TEM. Otherwise, make this
into a REG_UNUSED note instead. Don't delete sets to
global register vars. */
if ((REGNO (XEXP (note, 0)) >= FIRST_PSEUDO_REGISTER
|| !global_regs[REGNO (XEXP (note, 0))])
&& reg_set_p (XEXP (note, 0), PATTERN (tem)))
{
rtx set = single_set (tem);

View File

@ -1,3 +1,7 @@
2007-01-21 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.c-torture/compile/20070121.c: New test.
2007-01-21 Thomas Koenig <Thomas.Koenig@online.de>
PR libfortran/30525

View File

@ -0,0 +1,18 @@
/* PR rtl-optimization/29329 */
/* Origin: Debian GCC Maintainers <debian-gcc@lists.debian.org> */
/* Testcase by: Andrew Pinski <pinskia@gmail.com> */
struct node234_Tag
{
int t1;
int kids[4];
void *elems[3];
};
void *add234_internal(struct node234_Tag *n, int ei)
{
int j;
for (j = ei; j < 2 && n->elems[j+1];)
j++;
n->kids[j+1] = 0;
}