Patchwork Fix up an IRA ICE (PR middle-end/53411, rtl-optimization/53495)

login
register
mail settings
Submitter Jakub Jelinek
Date Aug. 13, 2012, 6:44 p.m.
Message ID <20120813184442.GQ1999@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/177025/
State New
Headers show

Comments

Jakub Jelinek - Aug. 13, 2012, 6:44 p.m.
Hi!

move_unallocated_pseudos apparently relies on no insns being deleted
in between find_moveable_pseudos and itself, which can happen when
delete_trivially_dead_insns removes dead insns and insns that feed them.

This can be fixed either by moving the delete_trivially_dead_insns
call earlier in ira function (is there anything in between those lines that
could create trivially dead insns?), as done in this patch, or e.g. as done
in the first patch in the PR can be fixed by making move_unallocated_pseudos
more tollerant to insns being removed.

I've bootstrapped/regtested this on x86_64-linux and i686-linux, ok for
trunk (or is the patch in the PR preferred, or something else)?

2012-08-13  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/53411
	PR rtl-optimization/53495
	* ira.c (ira): Move delete_trivially_dead_insns call before
	find_moveable_pseudos call.

	* gcc.c-torture/compile/pr53411.c: New test.
	* gcc.c-torture/compile/pr53495.c: New test.


	Jakub
Vladimir Makarov - Aug. 14, 2012, 12:07 a.m.
On 08/13/2012 02:44 PM, Jakub Jelinek wrote:
> Hi!
>
> move_unallocated_pseudos apparently relies on no insns being deleted
> in between find_moveable_pseudos and itself, which can happen when
> delete_trivially_dead_insns removes dead insns and insns that feed them.
>
> This can be fixed either by moving the delete_trivially_dead_insns
> call earlier in ira function (is there anything in between those lines that
> could create trivially dead insns?),
I can not imagine what can create trivially dead insns between those 
lines.  So this solution is ok.
>   as done in this patch, or e.g. as done
> in the first patch in the PR can be fixed by making move_unallocated_pseudos
> more tollerant to insns being removed.
>
> I've bootstrapped/regtested this on x86_64-linux and i686-linux, ok for
> trunk (or is the patch in the PR preferred, or something else)?
Ok.  Thanks for fixing this bug, Jakub.
> 2012-08-13  Jakub Jelinek  <jakub@redhat.com>
>
> 	PR middle-end/53411
> 	PR rtl-optimization/53495
> 	* ira.c (ira): Move delete_trivially_dead_insns call before
> 	find_moveable_pseudos call.
>
> 	* gcc.c-torture/compile/pr53411.c: New test.
> 	* gcc.c-torture/compile/pr53495.c: New test.
>
>

Patch

--- gcc/ira.c.jj	2012-08-10 12:57:39.000000000 +0200
+++ gcc/ira.c	2012-08-13 13:23:08.137339807 +0200
@@ -4206,6 +4206,9 @@  ira (FILE *f)
 
   allocated_reg_info_size = max_reg_num ();
 
+  if (delete_trivially_dead_insns (get_insns (), max_reg_num ()))
+    df_analyze ();
+
   /* It is not worth to do such improvement when we use a simple
      allocation because of -O0 usage or because the function is too
      big.  */
@@ -4288,9 +4291,6 @@  ira (FILE *f)
     check_allocation ();
 #endif
 
-  if (delete_trivially_dead_insns (get_insns (), max_reg_num ()))
-    df_analyze ();
-
   if (max_regno != max_regno_before_ira)
     {
       regstat_free_n_sets_and_refs ();
--- gcc/testsuite/gcc.c-torture/compile/pr53411.c.jj	2012-08-13 12:53:23.153131907 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr53411.c	2012-08-13 12:53:01.000000000 +0200
@@ -0,0 +1,33 @@ 
+/* PR middle-end/53411 */
+
+int a, b, c, d, e, f, g, h;
+void fn1 (void);
+int fn2 (void);
+
+int
+fn3 (x)
+     int x;
+{
+  return a ? 0 : x;
+}
+
+void
+fn4 (char x)
+{
+  int i, j, k;
+  for (; e; e++)
+    if (fn2 ())
+      {
+	f = 1;
+	k = 0;
+	for (; k <= 1; k++)
+	  {
+	    j = ~x;
+	    i = f * j;
+	    h = (fn3 (i | 0 <= c ^ 9L) != b | d) & 8;
+	    g = x | 1;
+	    fn1 ();
+	  }
+      }
+  c = x;
+}
--- gcc/testsuite/gcc.c-torture/compile/pr53495.c.jj	2012-08-13 12:28:27.311493428 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr53495.c	2012-08-13 12:27:57.000000000 +0200
@@ -0,0 +1,41 @@ 
+/* PR rtl-optimization/53495 */
+
+int a, b, c, d, e, g;
+static char
+fn1 (char p1, int p2)
+{
+  return p1 || p2 < 0 || p2 >= 1 || 1 >> p2 ? p1 : 0;
+}
+
+static long long fn2 (int *, int);
+static int fn3 ();
+void
+fn4 ()
+{
+  fn3 ();
+  fn2 (&a, d);
+}
+
+long long
+fn2 (int *p1, int p2)
+{
+  int f = -1L;
+  for (; c <= 1; c++)
+    {
+      *p1 = 0;
+      *p1 = fn1 (c, p2 ^ f);
+    }
+  a = 0;
+  e = p2;
+  return 0;
+}
+
+int
+fn3 ()
+{
+  b = 3;
+  for (; b; b--)
+    c++;
+  g = 0 >= c;
+  return 0;
+}