From 1bd5f38e6f08e08c922af3efbbb47b9ce305b873 Mon Sep 17 00:00:00 2001 From: bergner Date: Wed, 17 May 2017 14:05:21 +0000 Subject: [PATCH] gcc/ PR middle-end/80775 * tree-cfg.c: Move deletion of unreachable case statements to after the merging of consecutive case labels. gcc/testsuite/ PR middle-end/80775 * gcc.dg/pr80775.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@248155 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr80775.c | 21 +++++++++++++++++++++ gcc/tree-cfg.c | 27 ++++++++++++++++----------- 4 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr80775.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4668e354f4d..004c7bb446f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-05-17 Peter Bergner + + PR middle-end/80775 + * tree-cfg.c: Move deletion of unreachable case statements to after + the merging of consecutive case labels. + 2017-05-17 Thomas Preud'homme * config/arm/arm.c (cmse_nonsecure_call_clear_caller_saved): Refer diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 44f5841c74a..8f62adb2d62 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-05-17 Peter Bergner + + PR middle-end/80775 + * gcc.dg/pr80775.c: New test. + 2017-05-17 Marek Polacek PR sanitizer/80659 diff --git a/gcc/testsuite/gcc.dg/pr80775.c b/gcc/testsuite/gcc.dg/pr80775.c new file mode 100644 index 00000000000..df4d250687b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr80775.c @@ -0,0 +1,21 @@ +/* PR middle-end/80775 ICE: -O3 produces ice in group_case_labels_stmt. */ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +typedef struct { short a; } b; +b c[10]; +int d, e, f, g, h; +int +i (void) +{ + f = 0; + for (; f < e; f++) { + switch (g) { + case 1: + d = 1; + case 2: + c[2 + f].a = 1; + } + h += c[f].a; + } +} diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index e046a13a5fe..ba19661b860 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -1661,7 +1661,7 @@ void group_case_labels_stmt (gswitch *stmt) { int old_size = gimple_switch_num_labels (stmt); - int i, j, new_size = old_size; + int i, j, base_index, new_size = old_size; basic_block default_bb = NULL; default_bb = label_to_block (CASE_LABEL (gimple_switch_default_label (stmt))); @@ -1678,16 +1678,9 @@ group_case_labels_stmt (gswitch *stmt) gcc_assert (base_case); base_bb = label_to_block (CASE_LABEL (base_case)); - /* Discard cases that have the same destination as the default case - or if their destination block is unreachable. */ - if (base_bb == default_bb - || (EDGE_COUNT (base_bb->succs) == 0 - && gimple_seq_unreachable_p (bb_seq (base_bb)))) + /* Discard cases that have the same destination as the default case. */ + if (base_bb == default_bb) { - edge e; - if (base_bb != default_bb - && (e = find_edge (gimple_bb (stmt), base_bb)) != NULL) - remove_edge_and_dominated_blocks (e); gimple_switch_set_label (stmt, i, NULL_TREE); i++; new_size--; @@ -1697,7 +1690,7 @@ group_case_labels_stmt (gswitch *stmt) base_high = CASE_HIGH (base_case) ? CASE_HIGH (base_case) : CASE_LOW (base_case); - i++; + base_index = i++; /* Try to merge case labels. Break out when we reach the end of the label vector or when we cannot merge the next case @@ -1723,6 +1716,18 @@ group_case_labels_stmt (gswitch *stmt) else break; } + + /* Discard cases that have an unreachable destination block. */ + if (EDGE_COUNT (base_bb->succs) == 0 + && gimple_seq_unreachable_p (bb_seq (base_bb))) + { + edge base_edge = find_edge (gimple_bb (stmt), base_bb); + if (base_edge != NULL) + remove_edge_and_dominated_blocks (base_edge); + gimple_switch_set_label (stmt, base_index, NULL_TREE); + new_size--; + i++; + } } /* Compress the case labels in the label vector, and adjust the -- 2.11.4.GIT