diff options
author | Jakub Jelinek <jakub@redhat.com> | 2011-04-12 12:53:47 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-04-12 12:53:47 +0200 |
commit | 74f091d686a259e096d7fb316d3a2e60623cdd3d (patch) | |
tree | 9968c5e0e6d0256753bb87b2978322b8ad68df3b | |
parent | f20ca7258739d74b12cf381293b10f72125732c5 (diff) | |
download | gcc-74f091d686a259e096d7fb316d3a2e60623cdd3d.zip gcc-74f091d686a259e096d7fb316d3a2e60623cdd3d.tar.gz gcc-74f091d686a259e096d7fb316d3a2e60623cdd3d.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/combine.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/pr48549.C | 63 |
4 files changed, 87 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0010815..6aea7a4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/combine.c b/gcc/combine.c index 32a3d73..23015fd 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 105a162..3eb7c49 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/g++.dg/opt/pr48549.C b/gcc/testsuite/g++.dg/opt/pr48549.C new file mode 100644 index 0000000..30799ee --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr48549.C @@ -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 ()); + } +} |