PR middle-end/35800
authorhp <hp@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 3 Apr 2008 02:09:20 +0000 (02:09 +0000)
committerhp <hp@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 3 Apr 2008 02:09:20 +0000 (02:09 +0000)
* 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
gcc/expr.c
gcc/expr.h
gcc/stmt.c

index 8460c75..aa78346 100644 (file)
@@ -1,3 +1,13 @@
+2008-04-03  Richard Guenther  <rguenther@suse.de>
+
+       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 <dominiq@lps.ens.fr>
 
        PR target/35801
index a2bd86c..b0690f5 100644 (file)
@@ -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;
 }
 
index a1352a1..beb44bd 100644 (file)
@@ -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.
index 6f8d494..aeea509 100644 (file)
@@ -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);