re PR rtl-optimization/48549 (Combiner ICE with -g)

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.

From-SVN: r172311
This commit is contained in:
Jakub Jelinek 2011-04-12 12:53:47 +02:00 committed by Jakub Jelinek
parent f20ca72587
commit 74f091d686
4 changed files with 87 additions and 4 deletions

View File

@ -1,3 +1,11 @@
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.
2011-04-12 Richard Guenther <rguenther@suse.de>
PR tree-optimization/46076

View File

@ -1198,8 +1198,13 @@ combine_instructions (rtx f, unsigned int nregs)
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, const_rtx old_rtx, void *data)
}
/* 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);

View File

@ -1,3 +1,8 @@
2011-04-12 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/48549
* g++.dg/opt/pr48549.C: New test.
2011-04-12 Richard Guenther <rguenther@suse.de>
PR tree-optimization/46076

View File

@ -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 ());
}
}