From 469b75f7ffaf41f590c14f88b74ed63d808e332d Mon Sep 17 00:00:00 2001 From: hp Date: Thu, 3 Apr 2008 02:09:20 +0000 Subject: [PATCH] PR middle-end/35800 * expr.h (try_casesi): Adjust prototype. * expr.c (try_casesi): Take fallback label as extra parameter. Use that for gen_casesi if default_label is NULL. * stmt.c (expand_case): Pass fallback label to try_casesi, make sure to fill gaps with a fallback label if default_label is not present. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@133857 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 ++++++++++ gcc/expr.c | 6 ++++-- gcc/expr.h | 2 +- gcc/stmt.c | 17 +++++++++++------ 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8460c75..aa78346 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2008-04-03 Richard Guenther + + PR middle-end/35800 + * expr.h (try_casesi): Adjust prototype. + * expr.c (try_casesi): Take fallback label as extra parameter. + Use that for gen_casesi if default_label is NULL. + * stmt.c (expand_case): Pass fallback label to try_casesi, + make sure to fill gaps with a fallback label if default_label + is not present. + 2008-04-03 Dominique d'Humieres PR target/35801 diff --git a/gcc/expr.c b/gcc/expr.c index a2bd86c..b0690f51 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -9830,7 +9830,8 @@ case_values_threshold (void) 0 otherwise (i.e. if there is no casesi instruction). */ int try_casesi (tree index_type, tree index_expr, tree minval, tree range, - rtx table_label ATTRIBUTE_UNUSED, rtx default_label) + rtx table_label ATTRIBUTE_UNUSED, rtx default_label, + rtx fallback_label ATTRIBUTE_UNUSED) { enum machine_mode index_mode = SImode; int index_bits = GET_MODE_BITSIZE (index_mode); @@ -9894,7 +9895,8 @@ try_casesi (tree index_type, tree index_expr, tree minval, tree range, op2 = copy_to_mode_reg (op_mode, op2); emit_jump_insn (gen_casesi (index, op1, op2, - table_label, default_label)); + table_label, !default_label + ? fallback_label : default_label)); return 1; } diff --git a/gcc/expr.h b/gcc/expr.h index a1352a1..beb44bd 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -555,7 +555,7 @@ extern void do_compare_rtx_and_jump (rtx, rtx, enum rtx_code, int, enum machine_mode, rtx, rtx, rtx); /* Two different ways of generating switch statements. */ -extern int try_casesi (tree, tree, tree, tree, rtx, rtx); +extern int try_casesi (tree, tree, tree, tree, rtx, rtx, rtx); extern int try_tablejump (tree, tree, tree, tree, rtx, rtx); /* Smallest number of adjacent cases before we use a jump table. diff --git a/gcc/stmt.c b/gcc/stmt.c index 6f8d494..aeea509 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -2521,9 +2521,10 @@ expand_case (tree exp) } else { + rtx fallback_label = label_rtx (case_list->code_label); table_label = gen_label_rtx (); if (! try_casesi (index_type, index_expr, minval, range, - table_label, default_label)) + table_label, default_label, fallback_label)) { bool ok; @@ -2566,11 +2567,15 @@ expand_case (tree exp) = gen_rtx_LABEL_REF (Pmode, label_rtx (n->code_label)); } - /* Fill in the gaps with the default. */ - if (default_label) - for (i = 0; i < ncases; i++) - if (labelvec[i] == 0) - labelvec[i] = gen_rtx_LABEL_REF (Pmode, default_label); + /* Fill in the gaps with the default. We may have gaps at + the beginning if we tried to avoid the minval subtraction, + so substitute some label even if the default label was + deemed unreachable. */ + if (!default_label) + default_label = fallback_label; + for (i = 0; i < ncases; i++) + if (labelvec[i] == 0) + labelvec[i] = gen_rtx_LABEL_REF (Pmode, default_label); /* Output the table. */ emit_label (table_label); -- 2.7.4