diff options
author | Jakub Jelinek <jakub@redhat.com> | 2010-05-17 19:18:24 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2010-05-17 19:18:24 +0200 |
commit | f1de5107b0c0240cff8df7d678ad78847bdff6b0 (patch) | |
tree | 853ebe1e37eec54e09a73297268d1cf4b6fd5c1c | |
parent | 1eabc6beae22790e518ab4657e28fc4823d1bc3f (diff) | |
download | gcc-f1de5107b0c0240cff8df7d678ad78847bdff6b0.zip gcc-f1de5107b0c0240cff8df7d678ad78847bdff6b0.tar.gz gcc-f1de5107b0c0240cff8df7d678ad78847bdff6b0.tar.bz2 |
re PR middle-end/44102 (ICE with asm goto + __builtin_unreachable () in C++)
PR middle-end/44102
* cfgcleanup.c (try_optimize_cfg): When removing trivially empty
bb with no successors, move footer whenever in IR_RTL_CFGLAYOUT
mode, not just when CLEANUP_CFGLAYOUT, and when in IR_RTL_CFGRTL
add BARRIER after previous bb if needed.
* g++.dg/ext/asmgoto1.C: New test.
From-SVN: r159495
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cfgcleanup.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/asmgoto1.C | 32 |
4 files changed, 75 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a469dee..eeb5110 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2010-05-17 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/44102 + * cfgcleanup.c (try_optimize_cfg): When removing trivially empty + bb with no successors, move footer whenever in IR_RTL_CFGLAYOUT + mode, not just when CLEANUP_CFGLAYOUT, and when in IR_RTL_CFGRTL + add BARRIER after previous bb if needed. + 2010-05-17 Nathan Froyd <froydnj@codesourcery.com> * tree.c (build_function_type_list_1): Remove bogus assert condition. diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index 75f5651..7139e3a 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -1999,24 +1999,40 @@ try_optimize_cfg (int mode) && single_succ_edge (ENTRY_BLOCK_PTR)->dest != b)) { c = b->prev_bb; - if ((mode & CLEANUP_CFGLAYOUT) - && EDGE_COUNT (b->preds) > 0 - && b->il.rtl->footer - && BARRIER_P (b->il.rtl->footer)) + if (EDGE_COUNT (b->preds) > 0) { edge e; edge_iterator ei; - FOR_EACH_EDGE (e, ei, b->preds) - if (e->flags & EDGE_FALLTHRU) - { - if (e->src->il.rtl->footer == NULL) - { - e->src->il.rtl->footer = b->il.rtl->footer; - b->il.rtl->footer = NULL; - } - break; - } + if (current_ir_type () == IR_RTL_CFGLAYOUT) + { + if (b->il.rtl->footer + && BARRIER_P (b->il.rtl->footer)) + FOR_EACH_EDGE (e, ei, b->preds) + if ((e->flags & EDGE_FALLTHRU) + && e->src->il.rtl->footer == NULL) + { + if (b->il.rtl->footer) + { + e->src->il.rtl->footer = b->il.rtl->footer; + b->il.rtl->footer = NULL; + } + else + { + start_sequence (); + e->src->il.rtl->footer = emit_barrier (); + end_sequence (); + } + } + } + else + { + rtx last = get_last_bb_insn (b); + if (last && BARRIER_P (last)) + FOR_EACH_EDGE (e, ei, b->preds) + if ((e->flags & EDGE_FALLTHRU)) + emit_barrier_after (BB_END (e->src)); + } } delete_basic_block (b); if (!(mode & CLEANUP_CFGLAYOUT)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ba78c98..dfe8de7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-05-17 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/44102 + * g++.dg/ext/asmgoto1.C: New test. + 2010-05-17 Martin Jambor <mjambor@suse.cz> PR middle-end/44133 diff --git a/gcc/testsuite/g++.dg/ext/asmgoto1.C b/gcc/testsuite/g++.dg/ext/asmgoto1.C new file mode 100644 index 0000000..dda5167 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asmgoto1.C @@ -0,0 +1,32 @@ +// PR middle-end/44102 +// { dg-do compile } +// { dg-options "-O2" } + +void baz (void); +struct A { A (); ~A (); }; + +static inline int +foo (void) +{ + asm goto ("" : : : : l1, l2); + __builtin_unreachable (); + l1: + return 1; + l2: + return 0; +} + +int +bar (int x) +{ + if (x == 5) + { + A a, b; + baz (); + } + if (foo () || x == 6) + x = 1; + else + x = 2; + return x; +} |