This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/34302] [4.3 regression] Invalid code reordering
- From: Kenneth Zadeck <zadeck at naturalbridge dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>, gcc-bugzilla at gcc dot gnu dot org, Jakub Jelinek <jakub at redhat dot com>, "Park, Seongbae" <seongbae dot park at gmail dot com>, "Bonzini, Paolo" <bonzini at gnu dot org>
- Date: Mon, 10 Dec 2007 15:46:34 -0500
- Subject: [Bug rtl-optimization/34302] [4.3 regression] Invalid code reordering
This patch fixes where the move insn is inserted on pre increments. it
had been inserted before the auto inc but this is not correct. it needs
to replace the existing add to properly handle the case where the
operands of the add change between the add and the load.
Tested on ppc-32. The patch will only effect architectures with pre
increment.
Ok for commit?
Jakub, note that i changed the name of your testcase from 20071012-1.c
to 20071210-1.c.
I believe that this is the correct.
Kenny
2007-12-10 Kenneth Zadeck <zadeck@naturalbridge.com>
PR rtl-optimization/34302
* auto-inc-dec.c (attempt_change): Change place where move is
inserted.
2007-12-10 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/34302
* gcc.c-torture/execute/20071210-1.c: New test.
Index: auto-inc-dec.c
===================================================================
--- auto-inc-dec.c (revision 130748)
+++ auto-inc-dec.c (working copy)
@@ -550,7 +550,10 @@ attempt_change (rtx new_addr, rtx inc_re
switch (inc_insn.form)
{
case FORM_PRE_ADD:
- mov_insn = insert_move_insn_before (mem_insn.insn,
+ /* Replace the addition with a move. Do it at the location of
+ the addition since the operand of the addition may change
+ before the memory reference. */
+ mov_insn = insert_move_insn_before (inc_insn.insn,
inc_insn.reg_res, inc_insn.reg0);
move_dead_notes (mov_insn, inc_insn.insn, inc_insn.reg0);
@@ -673,7 +676,7 @@ try_merge (void)
}
/* Look to see if the inc register is dead after the memory
- reference. If it is do not do the combination. */
+ reference. If it is, do not do the combination. */
if (find_regno_note (last_insn, REG_DEAD, REGNO (inc_reg)))
{
if (dump_file)
Index: testsuite/gcc.c-torture/execute/20071210-1.c
===================================================================
--- testsuite/gcc.c-torture/execute/20071210-1.c (revision 0)
+++ testsuite/gcc.c-torture/execute/20071210-1.c (revision 0)
@@ -0,0 +1,67 @@
+/* PR rtl-optimization/34302 */
+
+extern void abort (void);
+
+struct S
+{
+ int n1, n2, n3, n4;
+};
+
+__attribute__((noinline)) struct S
+foo (int x, int y, int z)
+{
+ if (x != 10 || y != 9 || z != 8)
+ abort ();
+ struct S s = { 1, 2, 3, 4 };
+ return s;
+}
+
+__attribute__((noinline)) void **
+bar (void **u, int *v)
+{
+ void **w = u;
+ int *s = v, x, y, z;
+ void **p, **q;
+ static void *l[] = { &&lab1, &&lab1, &&lab2, &&lab3, &&lab4 };
+
+ if (!u)
+ return l;
+
+ q = *w++;
+ goto *q;
+lab2:
+ p = q;
+ q = *w++;
+ x = s[2];
+ y = s[1];
+ z = s[0];
+ s -= 1;
+ struct S r = foo (x, y, z);
+ s[3] = r.n1;
+ s[2] = r.n2;
+ s[1] = r.n3;
+ s[0] = r.n4;
+ goto *q;
+lab3:
+ p = q;
+ q = *w++;
+ s += 1;
+ s[0] = 23;
+lab1:
+ goto *q;
+lab4:
+ return 0;
+}
+
+int
+main (void)
+{
+ void **u = bar ((void **) 0, (int *) 0);
+ void *t[] = { u[2], u[4] };
+ int s[] = { 7, 8, 9, 10, 11, 12 };
+ if (bar (t, &s[1]) != (void **) 0
+ || s[0] != 4 || s[1] != 3 || s[2] != 2 || s[3] != 1
+ || s[4] != 11 || s[5] != 12)
+ abort ();
+ return 0;
+}