From 55187c8a16273a21be18e982bc2389e534e48975 Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguenther@suse.de>
Date: Thu, 3 Apr 2008 02:09:20 +0000
Subject: [PATCH] re PR middle-end/35800 (Revision 133835 failed to compile
 binutils)

	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.

From-SVN: r133857
---
 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 8460c75ae219..aa78346a55eb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/expr.c b/gcc/expr.c
index a2bd86c4d091..b0690f51c534 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 a1352a1ee50d..beb44bd80b7d 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 6f8d4948d550..aeea50970f61 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);
-- 
GitLab