diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 29 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr21562.c | 25 |
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); +} |