From f513a1bc128b41de3db1c813655c330d48373400 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 13 May 2014 15:48:19 -0400
Subject: [PATCH 06/29] Introduce gcond and use it in various places

gcc/
	* coretypes.h (gcond): Add forward declaration.

	* gimple.h (struct gcond): New subclass of gimple_with_ops, adding
	the invariant that stmt->code == GIMPLE_COND.
	(is_a_helper <gcond *>::test): New.
	(gimple_build_cond): Return a gcond, rather than just
	a gimple.
	(gimple_build_cond_from_tree): Likewise.

	* gdbhooks.py (build_pretty_printer): Add "gcond *" and
	"const gcond *", using the gimple printer.

	* cfgexpand.c (expand_gimple_cond): Require a gcond rather
	than just a gimple.
	* gimple.h (gimple_cond_set_condition_from_tree): Likewise.
	(gimple_cond_true_p): Likewise.
	(gimple_cond_false_p): Likewise.
	(gimple_cond_set_condition): Likewise.
	* gimple.c (gimple_cond_set_condition_from_tree): Likewise.
	* gimple-fold.c (fold_gimple_cond): Likewise.
	* gimple-pretty-print.c (dump_gimple_cond): Likewise.
	* tree-ssa-dom.c (canonicalize_comparison): Likewise.
	* tree-ssa-forwprop.c (forward_propagate_into_gimple_cond): Likewise.
	* tree-ssa-ifcombine.c (recognize_single_bit_test): Likewise.
	(recognize_bits_test): Likewise.
	* tree-ssa-threadedge.c (simplify_control_stmt_condition): Likewise.
	(thread_around_empty_blocks): Likewise.
	(thread_through_normal_block): Likewise.
	(thread_across_edge): Likewise.
	* tree-ssa-threadedge.h (thread_across_edge): Likewise.
	* tree-vrp.c (range_fits_type_p): Likewise.

	* cfgexpand.c (expand_gimple_basic_block): Add checked cast to
	gcond in regions where a stmt is known to have code GIMPLE_COND.
	* gimple-fold.c (fold_stmt_1): Likewise.
	* gimple-pretty-print.c (pp_gimple_stmt_1): Likewise.
	* tree-ssa-dom.c (optimize_stmt): Likewise.
	* tree-ssa-forwprop.c (ssa_forward_propagate_and_combine): Likewise.
	* tree-ssa-loop-unswitch.c (tree_unswitch_single_loop): Likewise.
	* tree-vrp.c (simplify_stmt_using_ranges): Likewise.

	* cfgloopmanip.c (create_empty_loop_on_edge): Update local to be a
	gcond.
	* tree-vrp.c (identify_jump_threads): Likewise.

	* gimple.c (gimple_build_cond): Return a gcond, rather than
	just a gimple.
	(gimple_build_cond_from_tree): Likewise.

	* tree-ssa-dom.c (class dom_opt_dom_walker): Strengthen type of
	field "m_dummy_cond" from a plain gimple to a gcond.

	* tree-ssa-ifcombine.c (ifcombine_ifandif): Introduce locals
	inner_stmt and outer_stmt so that inner_cond and outer_cond can be
	of type gcond once we know that we have code == GIMPLE_COND.
	* tree-ssa-loop-unswitch.c (tree_may_unswitch_on): Introduce local
	"last" so that stmt can be of type gcond.

	* doc/gimple.texi: Update for above changes.
---
 gcc/cfgexpand.c              |  4 ++--
 gcc/cfgloopmanip.c           |  2 +-
 gcc/coretypes.h              |  1 +
 gcc/doc/gimple.texi          |  6 ++++--
 gcc/gdbhooks.py              |  1 +
 gcc/gimple-fold.c            |  4 ++--
 gcc/gimple-pretty-print.c    |  4 ++--
 gcc/gimple.c                 | 10 +++++-----
 gcc/gimple.h                 | 30 ++++++++++++++++++++++++------
 gcc/tree-ssa-dom.c           |  6 +++---
 gcc/tree-ssa-forwprop.c      |  5 +++--
 gcc/tree-ssa-ifcombine.c     | 21 ++++++++++++---------
 gcc/tree-ssa-loop-unswitch.c | 19 ++++++++++++-------
 gcc/tree-ssa-threadedge.c    |  8 ++++----
 gcc/tree-ssa-threadedge.h    |  2 +-
 gcc/tree-vrp.c               |  8 ++++----
 16 files changed, 81 insertions(+), 50 deletions(-)

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index ef8824a..38beeac 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2053,7 +2053,7 @@ maybe_cleanup_end_of_block (edge e, rtx last)
    block and created a new one.  */
 
 static basic_block
-expand_gimple_cond (basic_block bb, gimple *stmt)
+expand_gimple_cond (basic_block bb, gcond *stmt)
 {
   basic_block new_bb, dest;
   edge new_edge;
@@ -5060,7 +5060,7 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls)
 	 fixup the CFG accordingly.  */
       if (gimple_code (stmt) == GIMPLE_COND)
 	{
-	  new_bb = expand_gimple_cond (bb, stmt);
+	  new_bb = expand_gimple_cond (bb, as_a <gcond *> (stmt));
 	  if (new_bb)
 	    return new_bb;
 	}
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 660704b..089df3a 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -776,7 +776,7 @@ create_empty_loop_on_edge (edge entry_edge,
   struct loop *loop;
   gimple_stmt_iterator gsi;
   gimple_seq stmts;
-  gimple *cond_expr;
+  gcond *cond_expr;
   tree exit_test;
   edge exit_e;
   int prob;
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 6af341f..a9b1b5a 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -70,6 +70,7 @@ struct gimple_stmt_iterator;
 
 /* Forward declarations of gimple subclasses.
    Keep this in the same order as the corresponding codes in gimple.def.  */
+class gcond;
 class gswitch;
 class gbind;
 
diff --git a/gcc/doc/gimple.texi b/gcc/doc/gimple.texi
index 088a498..8f09f9a 100644
--- a/gcc/doc/gimple.texi
+++ b/gcc/doc/gimple.texi
@@ -312,11 +312,13 @@ kinds, along with their relationships to @code{GSS_} values (layouts) and
      |   |
      |   + gimple_with_ops
      |   |   |    layout: GSS_WITH_OPS
-     |   |   |    Used for 4 codes: GIMPLE_COND
-     |   |   |                      GIMPLE_DEBUG
+     |   |   |    Used for 3 codes: GIMPLE_DEBUG
      |   |   |                      GIMPLE_GOTO
      |   |   |                      GIMPLE_LABEL
      |   |   |
+     |   |   + gcond
+     |   |   |        code: GIMPLE_COND
+     |   |   |
      |   |   + gswitch
      |   |            code: GIMPLE_SWITCH
      |   |
diff --git a/gcc/gdbhooks.py b/gcc/gdbhooks.py
index 799aced..bdf49c1 100644
--- a/gcc/gdbhooks.py
+++ b/gcc/gdbhooks.py
@@ -456,6 +456,7 @@ def build_pretty_printer():
                              'cgraph_node', CGraphNodePrinter)
     pp.add_printer_for_types(['gimple *',
                               # Keep this in the same order as gimple.def:
+                              'gcond *', 'const gcond *',
                               'gswitch *', 'const gswitch *',
                               'gbind *', 'const gbind *'],
                              'gimple',
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index b64e779..bdb1866 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -602,7 +602,7 @@ fold_gimple_assign (gimple_stmt_iterator *si)
    assumed that the operands have been previously folded.  */
 
 static bool
-fold_gimple_cond (gimple *stmt)
+fold_gimple_cond (gcond *stmt)
 {
   tree result = fold_binary_loc (gimple_location (stmt),
 			     gimple_cond_code (stmt),
@@ -1294,7 +1294,7 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace)
       }
 
     case GIMPLE_COND:
-      changed |= fold_gimple_cond (stmt);
+      changed |= fold_gimple_cond (as_a <gcond *> (stmt));
       break;
 
     case GIMPLE_CALL:
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 3a9e4f8..41551e5 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -808,7 +808,7 @@ dump_gimple_switch (pretty_printer *buffer, gswitch *gs, int spc, int flags)
    pp_gimple_stmt_1.  */
 
 static void
-dump_gimple_cond (pretty_printer *buffer, gimple *gs, int spc, int flags)
+dump_gimple_cond (pretty_printer *buffer, gcond *gs, int spc, int flags)
 {
   if (flags & TDF_RAW)
     dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T, %T, %T, %T>", gs,
@@ -2100,7 +2100,7 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple *gs, int spc, int flags)
       break;
 
     case GIMPLE_COND:
-      dump_gimple_cond (buffer, gs, spc, flags);
+      dump_gimple_cond (buffer, as_a <gcond *> (gs), spc, flags);
       break;
 
     case GIMPLE_LABEL:
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 1d14d2b..924a7ef 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -438,14 +438,14 @@ gimple_build_assign_with_ops (enum tree_code subcode, tree lhs, tree op1,
    T_LABEL is the label to jump to if the condition is true.
    F_LABEL is the label to jump to otherwise.  */
 
-gimple *
+gcond *
 gimple_build_cond (enum tree_code pred_code, tree lhs, tree rhs,
 		   tree t_label, tree f_label)
 {
-  gimple *p;
+  gcond *p;
 
   gcc_assert (TREE_CODE_CLASS (pred_code) == tcc_comparison);
-  p = gimple_build_with_ops (GIMPLE_COND, pred_code, 4);
+  p = as_a <gcond *> (gimple_build_with_ops (GIMPLE_COND, pred_code, 4));
   gimple_cond_set_lhs (p, lhs);
   gimple_cond_set_rhs (p, rhs);
   gimple_cond_set_true_label (p, t_label);
@@ -456,7 +456,7 @@ gimple_build_cond (enum tree_code pred_code, tree lhs, tree rhs,
 /* Build a GIMPLE_COND statement from the conditional expression tree
    COND.  T_LABEL and F_LABEL are as in gimple_build_cond.  */
 
-gimple *
+gcond *
 gimple_build_cond_from_tree (tree cond, tree t_label, tree f_label)
 {
   enum tree_code code;
@@ -470,7 +470,7 @@ gimple_build_cond_from_tree (tree cond, tree t_label, tree f_label)
    boolean expression tree COND.  */
 
 void
-gimple_cond_set_condition_from_tree (gimple *stmt, tree cond)
+gimple_cond_set_condition_from_tree (gcond *stmt, tree cond)
 {
   enum tree_code code;
   tree lhs, rhs;
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 81ca11c..ef35ac4 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -765,6 +765,16 @@ enum gimple_statement_structure_enum {
 #undef DEFGSSTRUCT
 
 /* A statement with the invariant that
+      stmt->code == GIMPLE_COND
+   i.e. a conditional jump statement.  */
+
+struct GTY((tag("GSS_WITH_OPS")))
+  gcond : public gimple_with_ops
+{
+  /* no additional fields; this uses the layout for GSS_WITH_OPS. */
+};
+
+/* A statement with the invariant that
       stmt->code == GIMPLE_SWITCH
    i.e. a switch statement.  */
 
@@ -817,6 +827,14 @@ is_a_helper <gresx *>::test (gimple *gs)
 template <>
 template <>
 inline bool
+is_a_helper <gcond *>::test (gimple *gs)
+{
+  return gs->code == GIMPLE_COND;
+}
+
+template <>
+template <>
+inline bool
 is_a_helper <geh_dispatch *>::test (gimple *gs)
 {
   return gs->code == GIMPLE_EH_DISPATCH;
@@ -1201,9 +1219,9 @@ gimple *gimple_build_assign_with_ops (enum tree_code, tree,
 				     tree, tree, tree CXX_MEM_STAT_INFO);
 gimple *gimple_build_assign_with_ops (enum tree_code, tree,
 				     tree, tree CXX_MEM_STAT_INFO);
-gimple *gimple_build_cond (enum tree_code, tree, tree, tree, tree);
-gimple *gimple_build_cond_from_tree (tree, tree, tree);
-void gimple_cond_set_condition_from_tree (gimple *, tree);
+gcond *gimple_build_cond (enum tree_code, tree, tree, tree, tree);
+gcond *gimple_build_cond_from_tree (tree, tree, tree);
+void gimple_cond_set_condition_from_tree (gcond *, tree);
 gimple *gimple_build_label (tree label);
 gimple *gimple_build_goto (tree dest);
 gimple *gimple_build_nop (void);
@@ -3006,7 +3024,7 @@ gimple_cond_make_true (gimple *gs)
   'if (0 == 0)', 'if (1 != 0)' or 'if (0 != 1)' */
 
 static inline bool
-gimple_cond_true_p (const gimple *gs)
+gimple_cond_true_p (const gcond *gs)
 {
   tree lhs = gimple_cond_lhs (gs);
   tree rhs = gimple_cond_rhs (gs);
@@ -3031,7 +3049,7 @@ gimple_cond_true_p (const gimple *gs)
    'if (0 != 0)', 'if (1 == 0)' or 'if (0 == 1)' */
 
 static inline bool
-gimple_cond_false_p (const gimple *gs)
+gimple_cond_false_p (const gcond *gs)
 {
   tree lhs = gimple_cond_lhs (gs);
   tree rhs = gimple_cond_rhs (gs);
@@ -3055,7 +3073,7 @@ gimple_cond_false_p (const gimple *gs)
 /* Set the code, LHS and RHS of GIMPLE_COND STMT from CODE, LHS and RHS.  */
 
 static inline void
-gimple_cond_set_condition (gimple *stmt, enum tree_code code, tree lhs, tree rhs)
+gimple_cond_set_condition (gcond *stmt, enum tree_code code, tree lhs, tree rhs)
 {
   gimple_cond_set_code (stmt, code);
   gimple_cond_set_lhs (stmt, lhs);
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 8abee2f..49fc8c8 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -823,7 +823,7 @@ public:
 private:
   void thread_across_edge (edge);
 
-  gimple *m_dummy_cond;
+  gcond *m_dummy_cond;
 };
 
 /* Jump threading, redundancy elimination and const/copy propagation.
@@ -995,7 +995,7 @@ make_pass_dominator (gcc::context *ctxt)
    condition to a canonical form.  */
 
 static void
-canonicalize_comparison (gimple *condstmt)
+canonicalize_comparison (gcond *condstmt)
 {
   tree op0;
   tree op1;
@@ -2330,7 +2330,7 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si)
     }
 
   if (gimple_code (stmt) == GIMPLE_COND)
-    canonicalize_comparison (stmt);
+    canonicalize_comparison (as_a <gcond *> (stmt));
 
   update_stmt_if_modified (stmt);
   opt_stats.num_stmts++;
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 0b68e07..b2c171e 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -501,7 +501,7 @@ forward_propagate_into_comparison (gimple_stmt_iterator *gsi)
    This must be kept in sync with forward_propagate_into_cond.  */
 
 static int
-forward_propagate_into_gimple_cond (gimple *stmt)
+forward_propagate_into_gimple_cond (gcond *stmt)
 {
   tree tmp;
   enum tree_code code = gimple_cond_code (stmt);
@@ -3817,7 +3817,8 @@ pass_forwprop::execute (function *fun)
 	    case GIMPLE_COND:
 	      {
 		int did_something;
-		did_something = forward_propagate_into_gimple_cond (stmt);
+		did_something =
+		  forward_propagate_into_gimple_cond (as_a <gcond *> (stmt));
 		if (did_something == 2)
 		  cfg_changed = true;
 		changed = did_something != 0;
diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c
index b3d2f7e..d424ce2 100644
--- a/gcc/tree-ssa-ifcombine.c
+++ b/gcc/tree-ssa-ifcombine.c
@@ -198,7 +198,7 @@ get_name_for_bit_test (tree candidate)
    Returns true if the pattern matched, false otherwise.  */
 
 static bool
-recognize_single_bit_test (gimple *cond, tree *name, tree *bit, bool inv)
+recognize_single_bit_test (gcond *cond, tree *name, tree *bit, bool inv)
 {
   gimple *stmt;
 
@@ -306,7 +306,7 @@ recognize_single_bit_test (gimple *cond, tree *name, tree *bit, bool inv)
    Returns true if the pattern matched, false otherwise.  */
 
 static bool
-recognize_bits_test (gimple *cond, tree *name, tree *bits, bool inv)
+recognize_bits_test (gcond *cond, tree *name, tree *bits, bool inv)
 {
   gimple *stmt;
 
@@ -337,18 +337,21 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
 		   basic_block outer_cond_bb, bool outer_inv, bool result_inv)
 {
   gimple_stmt_iterator gsi;
-  gimple *inner_cond, *outer_cond;
+  gimple *inner_stmt, *outer_stmt;
+  gcond *inner_cond, *outer_cond;
   tree name1, name2, bit1, bit2, bits1, bits2;
 
-  inner_cond = last_stmt (inner_cond_bb);
-  if (!inner_cond
-      || gimple_code (inner_cond) != GIMPLE_COND)
+  inner_stmt = last_stmt (inner_cond_bb);
+  if (!inner_stmt
+      || gimple_code (inner_stmt) != GIMPLE_COND)
     return false;
+  inner_cond = as_a <gcond *> (inner_stmt);
 
-  outer_cond = last_stmt (outer_cond_bb);
-  if (!outer_cond
-      || gimple_code (outer_cond) != GIMPLE_COND)
+  outer_stmt = last_stmt (outer_cond_bb);
+  if (!outer_stmt
+      || gimple_code (outer_stmt) != GIMPLE_COND)
     return false;
+  outer_cond = as_a <gcond *> (outer_stmt);
 
   /* See if we test a single bit of the same name in both tests.  In
      that case remove the outer test, merging both else edges,
diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c
index 7fed691..fe095ef 100644
--- a/gcc/tree-ssa-loop-unswitch.c
+++ b/gcc/tree-ssa-loop-unswitch.c
@@ -138,15 +138,17 @@ tree_ssa_unswitch_loops (void)
 static tree
 tree_may_unswitch_on (basic_block bb, struct loop *loop)
 {
-  gimple *stmt, *def;
+  gimple *last, *def;
+  gcond *stmt;
   tree cond, use;
   basic_block def_bb;
   ssa_op_iter iter;
 
   /* BB must end in a simple conditional jump.  */
-  stmt = last_stmt (bb);
-  if (!stmt || gimple_code (stmt) != GIMPLE_COND)
+  last = last_stmt (bb);
+  if (!last || gimple_code (last) != GIMPLE_COND)
     return NULL_TREE;
+  stmt = as_a <gcond *> (last);
 
   /* To keep the things simple, we do not directly remove the conditions,
      but just replace tests with 0 != 0 resp. 1 != 0.  Prevent the infinite
@@ -248,13 +250,15 @@ tree_unswitch_single_loop (struct loop *loop, int num)
       if (integer_nonzerop (cond))
 	{
 	  /* Remove false path.  */
-	  gimple_cond_set_condition_from_tree (stmt, boolean_true_node);
+	  gimple_cond_set_condition_from_tree (as_a <gcond *> (stmt),
+					       boolean_true_node);
 	  changed = true;
 	}
       else if (integer_zerop (cond))
 	{
 	  /* Remove true path.  */
-	  gimple_cond_set_condition_from_tree (stmt, boolean_false_node);
+	  gimple_cond_set_condition_from_tree (as_a <gcond *> (stmt),
+					       boolean_false_node);
 	  changed = true;
 	}
       /* Do not unswitch too much.  */
@@ -316,9 +320,10 @@ tree_unswitch_single_loop (struct loop *loop, int num)
 	      if (stmt
 		  && gimple_code (stmt) == GIMPLE_COND)
 		{
-		  if (gimple_cond_true_p (stmt))
+		  gcond *cond_stmt = as_a <gcond *> (stmt);
+		  if (gimple_cond_true_p (cond_stmt))
 		    flags = EDGE_FALSE_VALUE;
-		  else if (gimple_cond_false_p (stmt))
+		  else if (gimple_cond_false_p (cond_stmt))
 		    flags = EDGE_TRUE_VALUE;
 		}
 	    }
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 0bcc7ac..f7a4b07 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -563,7 +563,7 @@ dummy_simplify (gimple *stmt1 ATTRIBUTE_UNUSED, gimple *stmt2 ATTRIBUTE_UNUSED)
 static tree
 simplify_control_stmt_condition (edge e,
 				 gimple *stmt,
-				 gimple *dummy_cond,
+				 gcond *dummy_cond,
 				 tree (*simplify) (gimple *, gimple *),
 				 bool handle_dominating_asserts)
 {
@@ -827,7 +827,7 @@ propagate_threaded_block_debug_into (basic_block dest, basic_block src)
    try and simplify the condition at the end of TAKEN_EDGE->dest.  */
 static bool
 thread_around_empty_blocks (edge taken_edge,
-			    gimple *dummy_cond,
+			    gcond *dummy_cond,
 			    bool handle_dominating_asserts,
 			    tree (*simplify) (gimple *, gimple *),
 			    bitmap visited,
@@ -975,7 +975,7 @@ thread_around_empty_blocks (edge taken_edge,
 
 static int
 thread_through_normal_block (edge e,
-			     gimple *dummy_cond,
+			     gcond *dummy_cond,
 			     bool handle_dominating_asserts,
 			     vec<tree> *stack,
 			     tree (*simplify) (gimple *, gimple *),
@@ -1104,7 +1104,7 @@ thread_through_normal_block (edge e,
    SIMPLIFY is a pass-specific function used to simplify statements.  */
 
 void
-thread_across_edge (gimple *dummy_cond,
+thread_across_edge (gcond *dummy_cond,
 		    edge e,
 		    bool handle_dominating_asserts,
 		    vec<tree> *stack,
diff --git a/gcc/tree-ssa-threadedge.h b/gcc/tree-ssa-threadedge.h
index d4ae281..41afb0b 100644
--- a/gcc/tree-ssa-threadedge.h
+++ b/gcc/tree-ssa-threadedge.h
@@ -30,7 +30,7 @@ extern void threadedge_initialize_values (void);
 extern void threadedge_finalize_values (void);
 extern bool potentially_threadable_block (basic_block);
 extern void propagate_threaded_block_debug_into (basic_block, basic_block);
-extern void thread_across_edge (gimple *, edge, bool,
+extern void thread_across_edge (gcond *, edge, bool,
 				vec<tree> *, tree (*) (gimple *, gimple *));
 
 #endif /* GCC_TREE_SSA_THREADEDGE_H */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 0978d3d..cb78747 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -8809,7 +8809,7 @@ range_fits_type_p (value_range_t *vr, unsigned dest_precision, signop dest_sgn)
    the original conditional.  */
 
 static bool
-simplify_cond_using_ranges (gimple *stmt)
+simplify_cond_using_ranges (gcond *stmt)
 {
   tree op0 = gimple_cond_lhs (stmt);
   tree op1 = gimple_cond_rhs (stmt);
@@ -9347,8 +9347,8 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
 	  break;
 	}
     }
-  else if (gimple_code (stmt) == GIMPLE_COND)
-    return simplify_cond_using_ranges (stmt);
+  else if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
+    return simplify_cond_using_ranges (cond_stmt);
   else if (gswitch *switch_stmt = dyn_cast <gswitch *> (stmt))
     return simplify_switch_using_ranges (switch_stmt);
   else if (is_gimple_call (stmt)
@@ -9492,7 +9492,7 @@ static void
 identify_jump_threads (void)
 {
   basic_block bb;
-  gimple *dummy;
+  gcond *dummy;
   int i;
   edge e;
 
-- 
1.8.5.3

