User account creation filtered due to spam.

Bug 48549

Summary: [4.6/4.7 Regression] Combiner ICE with -g
Product: gcc Reporter: Jakub Jelinek <jakub>
Component: rtl-optimizationAssignee: Jakub Jelinek <jakub>
Status: RESOLVED FIXED    
Severity: normal CC: ebotcazou, ojab, steven
Priority: P3 Keywords: ice-on-valid-code
Version: 4.6.1   
Target Milestone: 4.6.1   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2011-04-11 10:28:32

Description Jakub Jelinek 2011-04-11 06:33:28 UTC
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 ());
    }
}

ICEs with -g -O2 on x86_64-linux, starting with 172109/172110.
Comment 1 Eric Botcazou 2011-04-11 10:28:32 UTC
Confirmed.
Comment 3 Jakub Jelinek 2011-04-12 06:28:44 UTC
*** Bug 48567 has been marked as a duplicate of this bug. ***
Comment 4 Jakub Jelinek 2011-04-12 10:53:50 UTC
Author: jakub
Date: Tue Apr 12 10:53:47 2011
New Revision: 172311

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172311
Log:
	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.

Added:
    trunk/gcc/testsuite/g++.dg/opt/pr48549.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/combine.c
    trunk/gcc/testsuite/ChangeLog
Comment 5 Jakub Jelinek 2011-04-12 13:44:35 UTC
Author: jakub
Date: Tue Apr 12 13:44:33 2011
New Revision: 172319

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172319
Log:
	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.

Added:
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/opt/pr48549.C
Modified:
    branches/gcc-4_6-branch/gcc/ChangeLog
    branches/gcc-4_6-branch/gcc/combine.c
    branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
Comment 6 Jakub Jelinek 2011-04-12 13:45:23 UTC
Fixed.
Comment 7 Steven Bosscher 2012-11-30 13:54:10 UTC
A patch to get rid of BARRIERs runs into this one. Here's an alternative fix:

Index: combine.c
===================================================================
--- combine.c   (revision 193989)
+++ combine.c   (working copy)
@@ -1223,11 +1223,10 @@ combine_instructions (rtx f, unsigned int nregs)
          if (NONDEBUG_INSN_P (insn))
            {
              while (last_combined_insn
-                    && INSN_DELETED_P (last_combined_insn))
+                    && INSN_DELETED_P (last_combined_insn)
+                    && last_combined_insn != BB_HEAD (this_basic_block))
                last_combined_insn = PREV_INSN (last_combined_insn);
              if (last_combined_insn == NULL_RTX
-                 || 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;