aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2010-05-17 19:18:24 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2010-05-17 19:18:24 +0200
commitf1de5107b0c0240cff8df7d678ad78847bdff6b0 (patch)
tree853ebe1e37eec54e09a73297268d1cf4b6fd5c1c
parent1eabc6beae22790e518ab4657e28fc4823d1bc3f (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/cfgcleanup.c44
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ext/asmgoto1.C32
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;
+}