Patchwork Fix combiner ICEs after my recent patch (PR rtl-optimization/48549)

login
register
mail settings
Submitter Jakub Jelinek
Date April 12, 2011, 10:55 a.m.
Message ID <20110412105511.GD17079@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/90765/
State New
Headers show

Comments

Jakub Jelinek - April 12, 2011, 10:55 a.m.
On Tue, Apr 12, 2011 at 10:29:57AM +0200, Eric Botcazou wrote:
> > 2011-04-12  Jakub Jelinek  <jakub@redhat.com>
> >
> > 	PR rtl-optimization/48549
> > 	* combine.c (propagate_for_debug): Also stop after BB_END of
> > 	this_basic_block.  Process LAST and just stop processing after it.
> > 	(combine_instructions): If last_combined_insn has been deleted,
> > 	set last_combined_insn to its PREV_INSN.
> >
> > 	* g++.dg/opt/pr48549.C: New test.
> 
> So OK modulo the last point, thanks.

Thanks, here is what I've committed after bootstrap/regtest on x86_64-linux
and i686-linux.  Will now regtest it on 4.6 branch too, then test the extra
JUMP_P patch + gcc_assert (at_end); just for trunk.

2011-04-12  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/48549
	* combine.c (propagate_for_debug): Also stop after BB_END of
	this_basic_block.  Process LAST and just stop processing after it.
	(combine_instructions): If last_combined_insn has been deleted,
	set last_combined_insn to its PREV_INSN.

	* g++.dg/opt/pr48549.C: New test.



	Jakub

Patch

--- gcc/combine.c.jj	2011-04-11 19:26:52.067577164 +0200
+++ gcc/combine.c	2011-04-12 10:40:12.592795949 +0200
@@ -1198,8 +1198,13 @@  combine_instructions (rtx f, unsigned in
 	  next = 0;
 	  if (NONDEBUG_INSN_P (insn))
 	    {
+	      while (last_combined_insn
+		     && INSN_DELETED_P (last_combined_insn))
+		last_combined_insn = PREV_INSN (last_combined_insn);
 	      if (last_combined_insn == NULL_RTX
-		  || DF_INSN_LUID (last_combined_insn) < DF_INSN_LUID (insn))
+		  || BARRIER_P (last_combined_insn)
+		  || BLOCK_FOR_INSN (last_combined_insn) != this_basic_block
+		  || DF_INSN_LUID (last_combined_insn) <= DF_INSN_LUID (insn))
 		last_combined_insn = insn;
 
 	      /* See if we know about function return values before this
@@ -2446,19 +2451,21 @@  propagate_for_debug_subst (rtx from, con
 }
 
 /* Replace all the occurrences of DEST with SRC in DEBUG_INSNs between INSN
-   and LAST.  */
+   and LAST, not including INSN, but including LAST.  Also stop at the end
+   of THIS_BASIC_BLOCK.  */
 
 static void
 propagate_for_debug (rtx insn, rtx last, rtx dest, rtx src)
 {
-  rtx next, loc;
+  rtx next, loc, end = NEXT_INSN (BB_END (this_basic_block));
 
   struct rtx_subst_pair p;
   p.to = src;
   p.adjusted = false;
 
   next = NEXT_INSN (insn);
-  while (next != last)
+  last = NEXT_INSN (last);
+  while (next != last && next != end)
     {
       insn = next;
       next = NEXT_INSN (insn);
--- gcc/testsuite/g++.dg/opt/pr48549.C.jj	2011-04-12 10:36:23.720513425 +0200
+++ gcc/testsuite/g++.dg/opt/pr48549.C	2011-04-12 10:36:23.720513425 +0200
@@ -0,0 +1,63 @@ 
+// PR rtl-optimization/48549
+// { dg-do compile }
+// { dg-options "-fcompare-debug -O2" }
+
+void
+foo (void *from, void *to)
+{
+  long offset = reinterpret_cast <long>(to) - reinterpret_cast <long>(from);
+  if (offset != static_cast <int>(offset))
+    *(int *) 0xC0DE = 0;
+  reinterpret_cast <int *>(from)[1] = offset;
+}
+struct A
+{
+  A () : a () {}
+  A (void *x) : a (x) {}
+  void *bar () { return a; }
+  void *a;
+};
+struct C;
+struct D;
+struct E : public A
+{
+  C m1 (int);
+  D m2 ();
+  E () {}
+  E (A x) : A (x) {}
+};
+struct C : public E
+{
+  C () {}
+  C (void *x) : E (x) {}
+};
+struct D : public E
+{
+  D (void *x) : E (x) {}
+};
+C
+E::m1 (int x)
+{
+  return (reinterpret_cast <char *>(bar ()) + x);
+}
+D
+E::m2 ()
+{
+  return reinterpret_cast <char *>(bar ());
+}
+struct B
+{
+  E a;
+  unsigned b : 16;
+  unsigned c : 1;
+};
+void
+baz (B *x)
+{
+  for (unsigned i = 0; i < 64; i++)
+    {
+      D d = x[i].a.m2 ();
+      C c = x[i].a.m1 (x[i].c);
+      foo (d.bar (), c.bar ());
+    }
+}