From 238065a73bd2bab6c3eb69e6d43cd8115a5b4245 Mon Sep 17 00:00:00 2001 From: Steven Bosscher Date: Mon, 9 Jul 2012 18:53:35 +0000 Subject: [PATCH] re PR middle-end/53887 (ICE in hoist_edge_and_branch_if_true, at tree-switch-conversion.c:79) gcc/ PR tree-optimization/53887 * tree-cfg.c (group_case_labels_stmt): Make non-static. * tree-flow.h (group_case_labels_stmt): Add prototype. * tree-switch-conversion.c (process_switch): Use group_case_labels_stmt to pre-process every switch. testsuite/ PR tree-optimization/53887 * gcc.dg/pr53887.c: New test. From-SVN: r189389 --- gcc/ChangeLog | 8 ++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr53887.c | 24 ++++++++++++++++++++++++ gcc/tree-cfg.c | 3 +-- gcc/tree-flow.h | 1 + gcc/tree-switch-conversion.c | 10 ++++++++-- 6 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr53887.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3e8bfc236c7..d8edad09b3c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2012-07-09 Steven Bosscher + + PR tree-optimization/53887 + * tree-cfg.c (group_case_labels_stmt): Make non-static. + * tree-flow.h (group_case_labels_stmt): Add prototype. + * tree-switch-conversion.c (process_switch): Use group_case_labels_stmt + to pre-process every switch. + 2012-07-09 Jason Merrill PR c++/53882 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 07187ebe3d2..5777c5f9fb4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-07-09 Steven Bosscher + + PR tree-optimization/53887 + * gcc.dg/pr53887.c: New test. + 2012-07-09 Jason Merrill PR c++/53882 diff --git a/gcc/testsuite/gcc.dg/pr53887.c b/gcc/testsuite/gcc.dg/pr53887.c new file mode 100644 index 00000000000..b46126cd2ac --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr53887.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +enum +{ Failed, NoError, NoDiskette } +a; +int b, c; +void +fn1 () +{ + if (c) + a << 1; + switch (b) + { + default: + a << 1; + case 0: + b = 0; + case 1: + case NoDiskette: + ; + } +} + diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index dd4760951a7..bdcf7c3af9d 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -125,7 +125,6 @@ static edge find_taken_edge_computed_goto (basic_block, tree); static edge find_taken_edge_cond_expr (basic_block, tree); static edge find_taken_edge_switch_expr (basic_block, tree); static tree find_case_label_for_value (gimple, tree); -static void group_case_labels_stmt (gimple); void init_empty_tree_cfg_for_function (struct function *fn) @@ -1331,7 +1330,7 @@ cleanup_dead_labels (void) the ones jumping to the same label. Eg. three separate entries 1: 2: 3: become one entry 1..3: */ -static void +void group_case_labels_stmt (gimple stmt) { int old_size = gimple_switch_num_labels (stmt); diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index cf7883985c2..8f7d336037e 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -428,6 +428,7 @@ extern void debug_loop_num (unsigned, int); extern void print_loops (FILE *, int); extern void print_loops_bb (FILE *, basic_block, int, int); extern void cleanup_dead_labels (void); +extern void group_case_labels_stmt (gimple); extern void group_case_labels (void); extern gimple first_stmt (basic_block); extern gimple last_stmt (basic_block); diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index 94fbf1dec69..80457989a47 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -1339,8 +1339,14 @@ process_switch (gimple swtch) { struct switch_conv_info info; - /* Degenerate case with only a default label should never happen. */ - gcc_checking_assert (gimple_switch_num_labels (swtch) > 1); + /* Group case labels so that we get the right results from the heuristics + that decide on the code generation approach for this switch. */ + group_case_labels_stmt (swtch); + + /* If this switch is now a degenerate case with only a default label, + there is nothing left for us to do. */ + if (gimple_switch_num_labels (swtch) < 2) + return "switch is a degenerate case"; collect_switch_conv_info (swtch, &info); -- 2.30.2