Commit 64c91930 by Eric Botcazou Committed by Eric Botcazou

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
parent f64acab6
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> 2007-01-21 Jan Hubicka <jh@suse.cz>
* ipa-inline.c (inlining_mode): Comment, move up. * ipa-inline.c (inlining_mode): Comment, move up.
......
...@@ -123,16 +123,22 @@ static int combine_successes; ...@@ -123,16 +123,22 @@ static int combine_successes;
static int total_attempts, total_merges, total_extras, total_successes; static int total_attempts, total_merges, total_extras, total_successes;
/* Sometimes combine tries to replace the right hand side of an insn /* combine_instructions may try to replace the right hand side of the
with the value of a REG_EQUAL note. This is the insn that has been second instruction with the value of an associated REG_EQUAL note
so modified, or null if none. */ 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 /* When I2MOD is nonnull, this is a copy of the old right hand side. */
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. /* Vector mapping INSN_UIDs to cuids.
The cuids are like uids but increase monotonically always. The cuids are like uids but increase monotonically always.
...@@ -932,11 +938,12 @@ combine_instructions (rtx f, unsigned int nregs) ...@@ -932,11 +938,12 @@ combine_instructions (rtx f, unsigned int nregs)
be deleted or recognized by try_combine. */ be deleted or recognized by try_combine. */
rtx orig = SET_SRC (set); rtx orig = SET_SRC (set);
SET_SRC (set) = note; SET_SRC (set) = note;
replaced_rhs_insn = temp; i2mod = temp;
replaced_rhs_value = copy_rtx (note); i2mod_old_rhs = copy_rtx (orig);
next = try_combine (insn, temp, NULL_RTX, i2mod_new_rhs = copy_rtx (note);
next = try_combine (insn, i2mod, NULL_RTX,
&new_direct_jump_p); &new_direct_jump_p);
replaced_rhs_insn = NULL; i2mod = NULL_RTX;
if (next) if (next)
goto retry; goto retry;
SET_SRC (set) = orig; SET_SRC (set) = orig;
...@@ -12140,8 +12147,8 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2, ...@@ -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. */ use of A and put the death note there. */
if (from_insn if (from_insn
&& from_insn == replaced_rhs_insn && from_insn == i2mod
&& !reg_overlap_mentioned_p (XEXP (note, 0), replaced_rhs_value)) && !reg_overlap_mentioned_p (XEXP (note, 0), i2mod_new_rhs))
tem = from_insn; tem = from_insn;
else else
{ {
...@@ -12154,7 +12161,10 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2, ...@@ -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 else if (i2 != 0 && next_nonnote_insn (i2) == i3
&& reg_referenced_p (XEXP (note, 0), PATTERN (i2))) && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
place = 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)) || rtx_equal_p (XEXP (note, 0), elim_i1))
break; break;
tem = i3; tem = i3;
...@@ -12173,14 +12183,12 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2, ...@@ -12173,14 +12183,12 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
continue; continue;
} }
/* If TEM is a (reaching) definition of the use to which the /* If the register is being set at TEM, see if that is all
note was attached, see if that is all TEM is doing. If so, TEM is doing. If so, delete TEM. Otherwise, make this
delete TEM. Otherwise, make this into a REG_UNUSED note into a REG_UNUSED note instead. Don't delete sets to
instead. Don't delete sets to global register vars. */ global register vars. */
if ((!from_insn if ((REGNO (XEXP (note, 0)) >= FIRST_PSEUDO_REGISTER
|| INSN_CUID (tem) < INSN_CUID (from_insn)) || !global_regs[REGNO (XEXP (note, 0))])
&& (REGNO (XEXP (note, 0)) >= FIRST_PSEUDO_REGISTER
|| !global_regs[REGNO (XEXP (note, 0))])
&& reg_set_p (XEXP (note, 0), PATTERN (tem))) && reg_set_p (XEXP (note, 0), PATTERN (tem)))
{ {
rtx set = single_set (tem); rtx set = single_set (tem);
......
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> 2007-01-21 Thomas Koenig <Thomas.Koenig@online.de>
PR libfortran/30525 PR libfortran/30525
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment