This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] PR53887
- From: Steven Bosscher <stevenb dot gcc at gmail dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 9 Jul 2012 12:57:38 +0200
- Subject: [patch] PR53887
Hello,
How annoying that it was decided at some point to not always group
switch case labels in tree-cfgcleanup! This PR53887 and PR53881 before
it are both cases where the switch lowering to bit tests ICEs because
the case labels haven't been grouped. For PR53887 there is a case
label that shares an edge with the default label, and for PR53881
there were two cases going to the same basic block (i.e. same edge)
but with different CASE_LABELs.
The most robust fix is to group the case labels before trying the
switch lowering. This also helps for switch conversion to a load from
a static initializer because before this patch the heuristics were
being fooled to perform unprofitable conversions.
Bootstrapped on powerpc64-unknown-linux-gnu, testing in progress. OK
if it passes?
Ciao!
Steven
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.
Index: tree-cfg.c
===================================================================
--- tree-cfg.c (revision 189366)
+++ tree-cfg.c (working copy)
@@ -125,7 +125,6 @@ static edge find_taken_edge_computed_goto (basic_b
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);
Index: tree-flow.h
===================================================================
--- tree-flow.h (revision 189366)
+++ tree-flow.h (working copy)
@@ -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);
Index: tree-switch-conversion.c
===================================================================
--- tree-switch-conversion.c (revision 189366)
+++ tree-switch-conversion.c (working copy)
@@ -1339,9 +1339,15 @@ 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);
/* No error markers should reach here (they should be filtered out
Index: testsuite/gcc.dg/pr53887.c
===================================================================
--- testsuite/gcc.dg/pr53887.c (revision 0)
+++ testsuite/gcc.dg/pr53887.c (revision 0)
@@ -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:
+ ;
+ }
+}
+