aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/cfgexpand.c29
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr21562.c25
4 files changed, 51 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e0a1575..f25e76e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-05-29 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/21562
+ * cfgexpand.c (construct_init_block): Deal properly with the case
+ of entry edge not pointing to very first basic block.
+
2005-05-28 Kazu Hirata <kazu@cs.umass.edu>
* tree-ssa-ccp.c (ccp_fold): Remove code that produces
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index cd9829e..4e4a8e2 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -1157,22 +1157,25 @@ static basic_block
construct_init_block (void)
{
basic_block init_block, first_block;
- edge e = NULL, e2;
- edge_iterator ei;
+ edge e = NULL;
+ int flags;
- FOR_EACH_EDGE (e2, ei, ENTRY_BLOCK_PTR->succs)
- {
- /* Clear EDGE_EXECUTABLE. This flag is never used in the backend.
+ /* Multiple entry points not supported yet. */
+ gcc_assert (EDGE_COUNT (ENTRY_BLOCK_PTR->succs) == 1);
- For all other blocks this edge flag is cleared while expanding
- a basic block in expand_gimple_basic_block, but there we never
- looked at the successors of the entry block.
- This caused PR17513. */
- e2->flags &= ~EDGE_EXECUTABLE;
+ e = EDGE_SUCC (ENTRY_BLOCK_PTR, 0);
- if (e2->dest == ENTRY_BLOCK_PTR->next_bb)
- e = e2;
+ /* When entry edge points to first basic block, we don't need jump,
+ otherwise we have to jump into proper target. */
+ if (e && e->dest != ENTRY_BLOCK_PTR->next_bb)
+ {
+ tree label = tree_block_label (e->dest);
+
+ emit_jump (label_rtx (label));
+ flags = 0;
}
+ else
+ flags = EDGE_FALLTHRU;
init_block = create_basic_block (NEXT_INSN (get_insns ()),
get_last_insn (),
@@ -1183,7 +1186,7 @@ construct_init_block (void)
{
first_block = e->dest;
redirect_edge_succ (e, init_block);
- e = make_edge (init_block, first_block, EDGE_FALLTHRU);
+ e = make_edge (init_block, first_block, flags);
}
else
e = make_edge (init_block, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f1eafd2..f9a5e6a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2005-05-29 Jan Hubicka <jh@suse.cz>
+
+ * gcc.c-torture/compile/pr21562.c: New.
+
2005-05-28 Steven G. Kargl <kargls@comcast.net>
* gfortran.dg/subnormal_1.f90: New test.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr21562.c b/gcc/testsuite/gcc.c-torture/compile/pr21562.c
new file mode 100644
index 0000000..d100b28
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr21562.c
@@ -0,0 +1,25 @@
+/* { dg-options "-O3 -fno-inline" } */
+struct foo { int a, b, c; };
+void abort(void);
+void exit(int);
+
+void
+brother (int a, int b, int c)
+{
+ if (a)
+ abort ();
+}
+
+void
+sister (struct foo f, int b, int c)
+{
+ brother ((f.b == b), b, c);
+}
+
+int
+main ()
+{
+ struct foo f = { 7, 8, 9 };
+ sister (f, 1, 2);
+ exit (0);
+}