From 012dce2b41251f9da2f678a28d266106658c1bcd Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 27 Mar 2014 12:16:23 -0400
Subject: [PATCH 62/89] Concretize gimple_label_label

gcc/
	* gimple.h (gimple_label_label): Require a const_gimple_label
	rather than just a const_gimple.

	* cfgexpand.c (label_rtx_for_bb): Convert local from gimple to
	gimple_label, replacing a check against GIMPLE_LABEL with a
	dyn_cast_gimple_label.
	* predict.c (tree_estimate_probability_bb): Likewise.
	* tree-cfg.c (make_edges): Likewise.
	(cleanup_dead_labels): Likewise (twice).
	(gimple_can_merge_blocks_p): Likewise.
	(gimple_block_label): Likewise.
	* tree-eh.c (unsplit_eh): Likewise.
	(cleanup_empty_eh_unsplit): Likewise.
	* tree-inline.c (mark_local_labels_stmt): Likewise.
	* tree-nested.c (convert_nl_goto_receiver): Likewise.

	* cfgexpand.c (expand_gimple_stmt_1): Add a checked cast to
	gimple_label when invoking gimple_label_label in a region where
	we've checked the code is GIMPLE_LABEL.
	* gimple-pretty-print.c (pp_cfg_jump): Likewise.
	* gimple.c (gimple_set_bb): Likewise.
	* ipa-pure-const.c (check_stmt): Likewise.
	* omp-low.c (diagnose_sb_1): Likewise.
	* tree-cfg.c (gimple_verify_flow_info): Likewise.
	* tree-cfgcleanup.c (tree_forwarder_block_p): Likewise.
	(remove_forwarder_block): Likewise.
	* tree-eh.c (collect_finally_tree): Likewise.

	* ipa-split.c (verify_non_ssa_vars): Replace a check against
	GIMPLE_LABEL with a dyn_cast_gimple_label, introducing a
	gimple_label local.
	* tree-cfg.c (gimple_can_merge_blocks_p): Likewise.
	(gimple_merge_blocks): Likewise.
	(remove_bb): Likewise.
	(stmt_starts_bb_p): Likewise.
	(gimple_verify_flow_info): Likewise.
	(move_block_to_fn): Likewise.
	* tree-cfgcleanup.c (remove_forwarder_block): Likewise.
	(remove_forwarder_block_with_phi): Likewise.
	* tree-ssa-ccp.c (optimize_unreachable): Likewise.
---
 gcc/cfgexpand.c           |  9 +++---
 gcc/gimple-pretty-print.c |  4 ++-
 gcc/gimple.c              |  2 +-
 gcc/gimple.h              |  3 +-
 gcc/ipa-pure-const.c      |  2 +-
 gcc/ipa-split.c           | 16 ++++++-----
 gcc/omp-low.c             |  4 ++-
 gcc/predict.c             |  7 +++--
 gcc/tree-cfg.c            | 72 ++++++++++++++++++++++++-----------------------
 gcc/tree-cfgcleanup.c     | 22 +++++++--------
 gcc/tree-eh.c             | 12 ++++----
 gcc/tree-inline.c         |  4 +--
 gcc/tree-nested.c         |  4 +--
 gcc/tree-ssa-ccp.c        |  4 +--
 14 files changed, 87 insertions(+), 78 deletions(-)

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 71615a8..ed4f037 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -1919,7 +1919,6 @@ label_rtx_for_bb (basic_block bb ATTRIBUTE_UNUSED)
 {
   gimple_stmt_iterator gsi;
   tree lab;
-  gimple lab_stmt;
   void **elt;
 
   if (bb->flags & BB_RTL)
@@ -1933,8 +1932,10 @@ label_rtx_for_bb (basic_block bb ATTRIBUTE_UNUSED)
 
   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     {
-      lab_stmt = gsi_stmt (gsi);
-      if (gimple_code (lab_stmt) != GIMPLE_LABEL)
+      gimple_label lab_stmt;
+
+      lab_stmt = gsi_stmt (gsi)->dyn_cast_gimple_label ();
+      if (!lab_stmt)
 	break;
 
       lab = gimple_label_label (lab_stmt);
@@ -3141,7 +3142,7 @@ expand_gimple_stmt_1 (gimple stmt)
 	expand_computed_goto (op0);
       break;
     case GIMPLE_LABEL:
-      expand_label (gimple_label_label (stmt));
+      expand_label (gimple_label_label (stmt->as_a_gimple_label ()));
       break;
     case GIMPLE_NOP:
     case GIMPLE_PREDICT:
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index f375a61..887093f 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -2354,7 +2354,9 @@ pp_cfg_jump (pretty_printer *buffer, basic_block bb)
   if (stmt && gimple_code (stmt) == GIMPLE_LABEL)
     {
       pp_string (buffer, " (");
-      dump_generic_node (buffer, gimple_label_label (stmt), 0, 0, false);
+      dump_generic_node (buffer,
+			 gimple_label_label (stmt->as_a_gimple_label ()),
+			 0, 0, false);
       pp_right_paren (buffer);
       pp_semicolon (buffer);
     }
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 75a9f5f..5f75b6c 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1492,7 +1492,7 @@ gimple_set_bb (gimple stmt, basic_block bb)
       tree t;
       int uid;
 
-      t = gimple_label_label (stmt);
+      t = gimple_label_label (stmt->as_a_gimple_label ());
       uid = LABEL_DECL_UID (t);
       if (uid == -1)
 	{
diff --git a/gcc/gimple.h b/gcc/gimple.h
index e4aeec6..d54d011 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -3477,9 +3477,8 @@ gimple_cond_set_condition (gimple_cond stmt, enum tree_code code, tree lhs,
 /* Return the LABEL_DECL node used by GIMPLE_LABEL statement GS.  */
 
 static inline tree
-gimple_label_label (const_gimple gs)
+gimple_label_label (const_gimple_label gs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_LABEL);
   return gimple_op (gs, 0);
 }
 
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index 133bc73..66313c8 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -688,7 +688,7 @@ check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
       check_call (local, stmt->as_a_gimple_call (), ipa);
       break;
     case GIMPLE_LABEL:
-      if (DECL_NONLOCAL (gimple_label_label (stmt)))
+      if (DECL_NONLOCAL (gimple_label_label (stmt->as_a_gimple_label ())))
 	/* Target of long jump. */
 	{
           if (dump_file)
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 0797abff..4e00e82 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -247,13 +247,15 @@ verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
 	      ok = false;
 	      goto done;
 	    }
-	  if (gimple_code (stmt) == GIMPLE_LABEL
-	      && test_nonssa_use (stmt, gimple_label_label (stmt),
-				  NULL_TREE, non_ssa_vars))
-	  {
-	    ok = false;
-	    goto done;
-	  }
+	  if (gimple_label label_stmt = stmt->dyn_cast_gimple_label ())
+	    {
+	      if (test_nonssa_use (stmt, gimple_label_label (label_stmt),
+				   NULL_TREE, non_ssa_vars))
+		{
+		  ok = false;
+		  goto done;
+		}
+	    }
 	}
       for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
 	{
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index c978c56..79f725c 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -10398,7 +10398,9 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
       break;
 
     case GIMPLE_LABEL:
-      splay_tree_insert (all_labels, (splay_tree_key) gimple_label_label (stmt),
+      splay_tree_insert (all_labels,
+			 (splay_tree_key) gimple_label_label (
+					    stmt->as_a_gimple_label ()),
 			 (splay_tree_value) context);
       break;
 
diff --git a/gcc/predict.c b/gcc/predict.c
index 7b4bb12..b15de97 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -2347,12 +2347,13 @@ tree_estimate_probability_bb (basic_block bb)
 	  gimple_stmt_iterator gi;
 	  for (gi = gsi_start_bb (e->dest); !gsi_end_p (gi); gsi_next (&gi))
 	    {
-	      gimple stmt = gsi_stmt (gi);
+	      gimple_label label_stmt =
+		gsi_stmt (gi)->dyn_cast_gimple_label ();
 	      tree decl;
 
-	      if (gimple_code (stmt) != GIMPLE_LABEL)
+	      if (!label_stmt)
 		break;
-	      decl = gimple_label_label (stmt);
+	      decl = gimple_label_label (label_stmt);
 	      if (DECL_ARTIFICIAL (decl))
 		continue;
 
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index efc3367..2a54b71 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -863,10 +863,11 @@ make_edges (void)
 	{
 	  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
 	    {
-	      gimple label_stmt = gsi_stmt (gsi);
+	      gimple_label label_stmt =
+		gsi_stmt (gsi)->dyn_cast_gimple_label ();
 	      tree target;
 
-	      if (gimple_code (label_stmt) != GIMPLE_LABEL)
+	      if (!label_stmt)
 		break;
 
 	      target = gimple_label_label (label_stmt);
@@ -1329,12 +1330,12 @@ cleanup_dead_labels (void)
       for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
 	{
 	  tree label;
-	  gimple stmt = gsi_stmt (i);
+	  gimple_label label_stmt = gsi_stmt (i)->dyn_cast_gimple_label ();
 
-	  if (gimple_code (stmt) != GIMPLE_LABEL)
+	  if (!label_stmt)
 	    break;
 
-	  label = gimple_label_label (stmt);
+	  label = gimple_label_label (label_stmt);
 
 	  /* If we have not yet seen a label for the current block,
 	     remember this one and see if there are more labels.  */
@@ -1469,12 +1470,12 @@ cleanup_dead_labels (void)
       for (i = gsi_start_bb (bb); !gsi_end_p (i); )
 	{
 	  tree label;
-	  gimple stmt = gsi_stmt (i);
+	  gimple_label label_stmt = gsi_stmt (i)->dyn_cast_gimple_label ();
 
-	  if (gimple_code (stmt) != GIMPLE_LABEL)
+	  if (!label_stmt)
 	    break;
 
-	  label = gimple_label_label (stmt);
+	  label = gimple_label_label (label_stmt);
 
 	  if (label == label_for_this_bb
 	      || !DECL_ARTIFICIAL (label)
@@ -1616,19 +1617,19 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b)
     return false;
 
   /* Do not allow a block with only a non-local label to be merged.  */
-  if (stmt
-      && gimple_code (stmt) == GIMPLE_LABEL
-      && DECL_NONLOCAL (gimple_label_label (stmt)))
-    return false;
+  if (stmt)
+    if (gimple_label label_stmt = stmt->dyn_cast_gimple_label ())
+      if (DECL_NONLOCAL (gimple_label_label (label_stmt)))
+	return false;
 
   /* Examine the labels at the beginning of B.  */
   for (gsi = gsi_start_bb (b); !gsi_end_p (gsi); gsi_next (&gsi))
     {
       tree lab;
-      stmt = gsi_stmt (gsi);
-      if (gimple_code (stmt) != GIMPLE_LABEL)
+      gimple_label label_stmt = gsi_stmt (gsi)->dyn_cast_gimple_label ();
+      if (!label_stmt)
 	break;
-      lab = gimple_label_label (stmt);
+      lab = gimple_label_label (label_stmt);
 
       /* Do not remove user forced labels or for -O0 any user labels.  */
       if (!DECL_ARTIFICIAL (lab) && (!optimize || FORCED_LABEL (lab)))
@@ -1828,9 +1829,9 @@ gimple_merge_blocks (basic_block a, basic_block b)
   for (gsi = gsi_start_bb (b); !gsi_end_p (gsi);)
     {
       gimple stmt = gsi_stmt (gsi);
-      if (gimple_code (stmt) == GIMPLE_LABEL)
+      if (gimple_label label_stmt = stmt->dyn_cast_gimple_label ())
 	{
-	  tree label = gimple_label_label (stmt);
+	  tree label = gimple_label_label (label_stmt);
 	  int lp_nr;
 
 	  gsi_remove (&gsi, false);
@@ -1979,9 +1980,10 @@ remove_bb (basic_block bb)
       for (i = gsi_last_bb (bb); !gsi_end_p (i);)
 	{
 	  gimple stmt = gsi_stmt (i);
-	  if (gimple_code (stmt) == GIMPLE_LABEL
-	      && (FORCED_LABEL (gimple_label_label (stmt))
-		  || DECL_NONLOCAL (gimple_label_label (stmt))))
+	  gimple_label label_stmt = stmt->dyn_cast_gimple_label ();
+	  if (label_stmt
+	      && (FORCED_LABEL (gimple_label_label (label_stmt))
+		  || DECL_NONLOCAL (gimple_label_label (label_stmt))))
 	    {
 	      basic_block new_bb;
 	      gimple_stmt_iterator new_gsi;
@@ -1989,10 +1991,10 @@ remove_bb (basic_block bb)
 	      /* A non-reachable non-local label may still be referenced.
 		 But it no longer needs to carry the extra semantics of
 		 non-locality.  */
-	      if (DECL_NONLOCAL (gimple_label_label (stmt)))
+	      if (DECL_NONLOCAL (gimple_label_label (label_stmt)))
 		{
-		  DECL_NONLOCAL (gimple_label_label (stmt)) = 0;
-		  FORCED_LABEL (gimple_label_label (stmt)) = 1;
+		  DECL_NONLOCAL (gimple_label_label (label_stmt)) = 0;
+		  FORCED_LABEL (gimple_label_label (label_stmt)) = 1;
 		}
 
 	      new_bb = bb->prev_bb;
@@ -2432,16 +2434,16 @@ stmt_starts_bb_p (gimple stmt, gimple prev_stmt)
   /* Labels start a new basic block only if the preceding statement
      wasn't a label of the same type.  This prevents the creation of
      consecutive blocks that have nothing but a single label.  */
-  if (gimple_code (stmt) == GIMPLE_LABEL)
+  if (gimple_label label_stmt = stmt->dyn_cast_gimple_label ())
     {
       /* Nonlocal and computed GOTO targets always start a new block.  */
-      if (DECL_NONLOCAL (gimple_label_label (stmt))
-	  || FORCED_LABEL (gimple_label_label (stmt)))
+      if (DECL_NONLOCAL (gimple_label_label (label_stmt))
+	  || FORCED_LABEL (gimple_label_label (label_stmt)))
 	return true;
 
       if (prev_stmt && gimple_code (prev_stmt) == GIMPLE_LABEL)
 	{
-	  if (DECL_NONLOCAL (gimple_label_label (prev_stmt)))
+	  if (DECL_NONLOCAL (gimple_label_label (prev_stmt->as_a_gimple_label ())))
 	    return true;
 
 	  cfg_stats.num_merged_labels++;
@@ -5011,7 +5013,7 @@ gimple_verify_flow_info (void)
 	  if (gimple_code (stmt) != GIMPLE_LABEL)
 	    break;
 
-	  label = gimple_label_label (stmt);
+	  label = gimple_label_label (stmt->as_a_gimple_label ());
 	  if (prev_stmt && DECL_NONLOCAL (label))
 	    {
 	      error ("nonlocal label ");
@@ -5064,10 +5066,10 @@ gimple_verify_flow_info (void)
 	  if (stmt_ends_bb_p (stmt))
 	    found_ctrl_stmt = true;
 
-	  if (gimple_code (stmt) == GIMPLE_LABEL)
+	  if (gimple_label label_stmt = stmt->dyn_cast_gimple_label ())
 	    {
 	      error ("label ");
-	      print_generic_expr (stderr, gimple_label_label (stmt), 0);
+	      print_generic_expr (stderr, gimple_label_label (label_stmt), 0);
 	      fprintf (stderr, " in the middle of basic block %d", bb->index);
 	      err = 1;
 	    }
@@ -5326,12 +5328,12 @@ gimple_block_label (basic_block bb)
   gimple_stmt_iterator i, s = gsi_start_bb (bb);
   bool first = true;
   tree label;
-  gimple stmt;
+  gimple_label stmt;
 
   for (i = s; !gsi_end_p (i); first = false, gsi_next (&i))
     {
-      stmt = gsi_stmt (i);
-      if (gimple_code (stmt) != GIMPLE_LABEL)
+      stmt = gsi_stmt (i)->dyn_cast_gimple_label ();
+      if (!stmt)
 	break;
       label = gimple_label_label (stmt);
       if (!DECL_NONLOCAL (label))
@@ -6628,9 +6630,9 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
       wi.info = d;
       walk_gimple_stmt (&si, move_stmt_r, move_stmt_op, &wi);
 
-      if (gimple_code (stmt) == GIMPLE_LABEL)
+      if (gimple_label label_stmt = stmt->dyn_cast_gimple_label ())
 	{
-	  tree label = gimple_label_label (stmt);
+	  tree label = gimple_label_label (label_stmt);
 	  int uid = LABEL_DECL_UID (label);
 
 	  gcc_assert (uid > -1);
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index 3c879f5..914cc71 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -289,7 +289,7 @@ tree_forwarder_block_p (basic_block bb, bool phi_wanted)
       switch (gimple_code (stmt))
 	{
 	case GIMPLE_LABEL:
-	  if (DECL_NONLOCAL (gimple_label_label (stmt)))
+	  if (DECL_NONLOCAL (gimple_label_label (stmt->as_a_gimple_label ())))
 	    return false;
 	  if (optimize == 0 && gimple_location (stmt) != locus)
 	    return false;
@@ -386,11 +386,11 @@ remove_forwarder_block (basic_block bb)
   /* If the destination block consists of a nonlocal label or is a
      EH landing pad, do not merge it.  */
   label = first_stmt (dest);
-  if (label
-      && gimple_code (label) == GIMPLE_LABEL
-      && (DECL_NONLOCAL (gimple_label_label (label))
-	  || EH_LANDING_PAD_NR (gimple_label_label (label)) != 0))
-    return false;
+  if (label)
+    if (gimple_label label_stmt = label->dyn_cast_gimple_label ())
+      if (DECL_NONLOCAL (gimple_label_label (label_stmt))
+	  || EH_LANDING_PAD_NR (gimple_label_label (label_stmt)) != 0)
+	return false;
 
   /* If there is an abnormal edge to basic block BB, but not into
      dest, problems might occur during removal of the phi node at out
@@ -472,7 +472,7 @@ remove_forwarder_block (basic_block bb)
       label = gsi_stmt (gsi);
       if (is_gimple_debug (label))
 	break;
-      decl = gimple_label_label (label);
+      decl = gimple_label_label (label->as_a_gimple_label ());
       if (EH_LANDING_PAD_NR (decl) != 0
 	  || DECL_NONLOCAL (decl)
 	  || FORCED_LABEL (decl)
@@ -815,10 +815,10 @@ remove_forwarder_block_with_phi (basic_block bb)
   /* If the destination block consists of a nonlocal label, do not
      merge it.  */
   label = first_stmt (dest);
-  if (label
-      && gimple_code (label) == GIMPLE_LABEL
-      && DECL_NONLOCAL (gimple_label_label (label)))
-    return false;
+  if (label)
+    if (gimple_label label_stmt = label->dyn_cast_gimple_label ())
+      if (DECL_NONLOCAL (gimple_label_label (label_stmt)))
+	return false;
 
   /* Record BB's single pred in case we need to update the father
      loop's latch information later.  */
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 928d397..412e79a 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -265,7 +265,7 @@ collect_finally_tree (gimple stmt, gimple_try region)
   switch (gimple_code (stmt))
     {
     case GIMPLE_LABEL:
-      temp.t = gimple_label_label (stmt);
+      temp.t = gimple_label_label (stmt->as_a_gimple_label ());
       record_in_finally_tree (temp, region);
       break;
 
@@ -4067,13 +4067,13 @@ unsplit_eh (eh_landing_pad lp)
      for a different region.  */
   for (gsi = gsi_start_bb (e_out->dest); !gsi_end_p (gsi); gsi_next (&gsi))
     {
-      gimple stmt = gsi_stmt (gsi);
+      gimple_label label_stmt = gsi_stmt (gsi)->dyn_cast_gimple_label ();
       tree lab;
       int lp_nr;
 
-      if (gimple_code (stmt) != GIMPLE_LABEL)
+      if (!label_stmt)
 	break;
-      lab = gimple_label_label (stmt);
+      lab = gimple_label_label (label_stmt);
       lp_nr = EH_LANDING_PAD_NR (lab);
       if (lp_nr && get_eh_region_from_lp_number (lp_nr) != lp->region)
 	return false;
@@ -4340,10 +4340,10 @@ cleanup_empty_eh_unsplit (basic_block bb, edge e_out, eh_landing_pad lp)
   lab = NULL;
   for (gsi = gsi_start_bb (e_out->dest); !gsi_end_p (gsi); gsi_next (&gsi))
     {
-      gimple stmt = gsi_stmt (gsi);
+      gimple_label stmt = gsi_stmt (gsi)->dyn_cast_gimple_label ();
       int lp_nr;
 
-      if (gimple_code (stmt) != GIMPLE_LABEL)
+      if (!stmt)
 	break;
       lab = gimple_label_label (stmt);
       lp_nr = EH_LANDING_PAD_NR (lab);
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 37d6a8b..2f675d2 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -4792,9 +4792,9 @@ mark_local_labels_stmt (gimple_stmt_iterator *gsip,
 		        struct walk_stmt_info *wi)
 {
   copy_body_data *id = (copy_body_data *) wi->info;
-  gimple stmt = gsi_stmt (*gsip);
+  gimple_label stmt = gsi_stmt (*gsip)->dyn_cast_gimple_label ();
 
-  if (gimple_code (stmt) == GIMPLE_LABEL)
+  if (stmt)
     {
       tree decl = gimple_label_label (stmt);
 
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index ca3e0ba..ce6f309 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -1938,9 +1938,9 @@ convert_nl_goto_receiver (gimple_stmt_iterator *gsi, bool *handled_ops_p,
   tree label, new_label;
   gimple_stmt_iterator tmp_gsi;
   void **slot;
-  gimple stmt = gsi_stmt (*gsi);
+  gimple_label stmt = gsi_stmt (*gsi)->dyn_cast_gimple_label ();
 
-  if (gimple_code (stmt) != GIMPLE_LABEL)
+  if (!stmt)
     {
       *handled_ops_p = false;
       return NULL_TREE;
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 3f3c27f..3509d31 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -2519,10 +2519,10 @@ optimize_unreachable (gimple_stmt_iterator i)
       if (is_gimple_debug (stmt))
        continue;
 
-      if (gimple_code (stmt) == GIMPLE_LABEL)
+      if (gimple_label label_stmt = stmt->dyn_cast_gimple_label ())
 	{
 	  /* Verify we do not need to preserve the label.  */
-	  if (FORCED_LABEL (gimple_label_label (stmt)))
+	  if (FORCED_LABEL (gimple_label_label (label_stmt)))
 	    return false;
 
 	  continue;
-- 
1.8.5.3

