From: Eric Botcazou Date: Sun, 21 Jan 2007 22:32:39 +0000 (+0100) Subject: re PR rtl-optimization/29329 (internal consistency failure) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=64c919306327433c4c07e55cb4b106800d3ad0b7;p=gcc.git 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) : 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 * combine.c (distribute_notes) : Do not consider SETs past the insn to which the note was originally attached. From-SVN: r121037 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a201681e4dc..da8bbf58caf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2007-01-21 Eric Botcazou + + 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) : 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 + + * combine.c (distribute_notes) : Do not consider SETs past + the insn to which the note was originally attached. + 2007-01-21 Jan Hubicka * ipa-inline.c (inlining_mode): Comment, move up. diff --git a/gcc/combine.c b/gcc/combine.c index 32117bee219..aa1e2ce2034 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e92e40bcf4f..ff69cda1751 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-01-21 Eric Botcazou + + * gcc.c-torture/compile/20070121.c: New test. + 2007-01-21 Thomas Koenig PR libfortran/30525 diff --git a/gcc/testsuite/gcc.c-torture/compile/20070121.c b/gcc/testsuite/gcc.c-torture/compile/20070121.c new file mode 100644 index 00000000000..88af8bf6286 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20070121.c @@ -0,0 +1,18 @@ +/* PR rtl-optimization/29329 */ +/* Origin: Debian GCC Maintainers */ +/* Testcase by: Andrew Pinski */ + +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; +}