summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-21 22:32:39 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-21 22:32:39 +0000
commitcf86e5cee072b19c09ee8e8c11726e71d23bed26 (patch)
treea02be706edc515e25b0af6853ce327ff8283cda9
parentdb019aef86f8fd438b1e6c8d11411f4df6a0bf4d (diff)
downloadgcc-cf86e5cee072b19c09ee8e8c11726e71d23bed26.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121037 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/combine.c52
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20070121.c18
4 files changed, 71 insertions, 22 deletions
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 <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.
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 <ebotcazou@libertysurf.fr>
+
+ * gcc.c-torture/compile/20070121.c: New test.
+
2007-01-21 Thomas Koenig <Thomas.Koenig@online.de>
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 <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;
+}