diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index a60a771..5902705 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,5 +1,27 @@
 2014-10-31  David Malcolm  <dmalcolm@redhat.com>
 
+	* tree-ssa-forwprop.c (get_prop_source_stmt): Strengthen return
+	type and local "def_stmt" from gimple to gassign *, using a
+	dyn_cast in place of an is_gimple_assign.
+	(can_propagate_from): Strengthen param from gimple to gassign *.
+	(forward_propagate_into_comparison_1): Likewise for locals named
+	"def_stmt".
+	(forward_propagate_into_cond): Likewise.
+	(simplify_bitwise_binary_1): Introduce local "assign", using it in
+	place of "def" for typesafety.
+	(associate_plusminus): Strengthen local "stmt" from gimple to
+	gassign *.  Likewise for locals "def_stmt", using dyn_casts in
+	place of is_gimple_assign calls.  Likewise for local "def_stmt2".
+	(associate_pointerplus): Likewise.
+	(simplify_bitfield_ref): Strengthen local "def_stmt" from gimple
+	to gassign *.
+	(simplify_permutation): Likewise, also for local "def_stmt2".
+	(simplify_vector_constructor): Likewise.
+	(pass_forwprop::execute): Strengthen local "stmt" from gimple to
+	gassign *, using a dyn_cast in place of an is_gimple_assign.
+
+2014-10-31  David Malcolm  <dmalcolm@redhat.com>
+
 	* gimple.h (is_a_helper <const gassign *>::test): New.
 	(gimple_assign_copy_p): Update return type from bool to
 	gassign *, returning GS if the predicate holds.
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 3a03b9f..7a51516 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -241,14 +241,12 @@ get_prop_dest_stmt (tree name, tree *final_name_p)
    it is set to whether the chain to NAME is a single use chain
    or not.  SINGLE_USE_P is not written to if SINGLE_USE_ONLY is set.  */
 
-static gimple
+static gassign *
 get_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p)
 {
   bool single_use = true;
 
   do {
-    gimple def_stmt = SSA_NAME_DEF_STMT (name);
-
     if (!has_single_use (name))
       {
 	single_use = false;
@@ -257,7 +255,8 @@ get_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p)
       }
 
     /* If name is defined by a PHI node or is the default def, bail out.  */
-    if (!is_gimple_assign (def_stmt))
+    gassign *def_stmt = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (name));
+    if (!def_stmt)
       return NULL;
 
     /* If def_stmt is a simple copy, continue looking.  */
@@ -277,7 +276,7 @@ get_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p)
    propagation source.  Returns true if so, otherwise false.  */
 
 static bool
-can_propagate_from (gimple def_stmt)
+can_propagate_from (gassign *def_stmt)
 {
   gcc_assert (is_gimple_assign (def_stmt));
 
@@ -438,7 +437,7 @@ forward_propagate_into_comparison_1 (gimple stmt,
      simplify comparisons against constants.  */
   if (TREE_CODE (op0) == SSA_NAME)
     {
-      gimple def_stmt = get_prop_source_stmt (op0, false, &single_use0_p);
+      gassign *def_stmt = get_prop_source_stmt (op0, false, &single_use0_p);
       if (def_stmt && can_propagate_from (def_stmt))
 	{
 	  rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
@@ -452,7 +451,7 @@ forward_propagate_into_comparison_1 (gimple stmt,
   /* If that wasn't successful, try the second operand.  */
   if (TREE_CODE (op1) == SSA_NAME)
     {
-      gimple def_stmt = get_prop_source_stmt (op1, false, &single_use1_p);
+      gassign *def_stmt = get_prop_source_stmt (op1, false, &single_use1_p);
       if (def_stmt && can_propagate_from (def_stmt))
 	{
 	  rhs1 = rhs_to_tree (TREE_TYPE (op0), def_stmt);
@@ -596,7 +595,7 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
     {
       enum tree_code def_code;
       tree name = cond;
-      gimple def_stmt = get_prop_source_stmt (name, true, NULL);
+      gassign *def_stmt = get_prop_source_stmt (name, true, NULL);
       if (!def_stmt || !can_propagate_from (def_stmt))
 	return 0;
 
@@ -1843,7 +1842,6 @@ simplify_bitwise_binary_1 (enum tree_code code, tree type,
 static inline void
 defcodefor_name (tree name, enum tree_code *code, tree *arg1, tree *arg2)
 {
-  gimple def;
   enum tree_code code1;
   tree arg11;
   tree arg21;
@@ -1857,15 +1855,16 @@ defcodefor_name (tree name, enum tree_code *code, tree *arg1, tree *arg2)
 
   if (code1 == SSA_NAME)
     {
-      def = SSA_NAME_DEF_STMT (name);
-      
-      if (def && is_gimple_assign (def)
-	  && can_propagate_from (def))
+      gimple def = SSA_NAME_DEF_STMT (name);
+      gassign *assign = def ? dyn_cast <gassign *> (def) : NULL;
+
+      if (assign
+	  && can_propagate_from (assign))
 	{
-	  code1 = gimple_assign_rhs_code (def);
-	  arg11 = gimple_assign_rhs1 (def);
-          arg21 = gimple_assign_rhs2 (def);
-          arg31 = gimple_assign_rhs2 (def);
+	  code1 = gimple_assign_rhs_code (assign);
+	  arg11 = gimple_assign_rhs1 (assign);
+          arg21 = gimple_assign_rhs2 (assign);
+          arg31 = gimple_assign_rhs2 (assign);
 	}
     }
   else if (grhs_class == GIMPLE_TERNARY_RHS
@@ -2482,7 +2481,7 @@ simplify_rotate (gimple_stmt_iterator *gsi)
 static bool
 associate_plusminus (gimple_stmt_iterator *gsi)
 {
-  gimple stmt = gsi_stmt (*gsi);
+  gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
   tree rhs1 = gimple_assign_rhs1 (stmt);
   tree rhs2 = gimple_assign_rhs2 (stmt);
   enum tree_code code = gimple_assign_rhs_code (stmt);
@@ -2500,8 +2499,8 @@ associate_plusminus (gimple_stmt_iterator *gsi)
       /* A +- (-B) -> A -+ B.  */
       if (TREE_CODE (rhs2) == SSA_NAME)
 	{
-	  gimple def_stmt = SSA_NAME_DEF_STMT (rhs2);
-	  if (is_gimple_assign (def_stmt)
+	  gassign *def_stmt = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs2));
+	  if (def_stmt
 	      && gimple_assign_rhs_code (def_stmt) == NEGATE_EXPR
 	      && can_propagate_from (def_stmt))
 	    {
@@ -2518,8 +2517,8 @@ associate_plusminus (gimple_stmt_iterator *gsi)
       if (TREE_CODE (rhs1) == SSA_NAME
 	  && code == PLUS_EXPR)
 	{
-	  gimple def_stmt = SSA_NAME_DEF_STMT (rhs1);
-	  if (is_gimple_assign (def_stmt)
+	  gassign *def_stmt = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs1));
+	  if (def_stmt
 	      && gimple_assign_rhs_code (def_stmt) == NEGATE_EXPR
 	      && can_propagate_from (def_stmt))
 	    {
@@ -2563,8 +2562,8 @@ associate_plusminus (gimple_stmt_iterator *gsi)
 
   if (TREE_CODE (rhs1) == SSA_NAME)
     {
-      gimple def_stmt = SSA_NAME_DEF_STMT (rhs1);
-      if (is_gimple_assign (def_stmt) && can_propagate_from (def_stmt))
+      gassign *def_stmt = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs1));
+      if (def_stmt && can_propagate_from (def_stmt))
 	{
 	  enum tree_code def_code = gimple_assign_rhs_code (def_stmt);
 	  if (def_code == PLUS_EXPR
@@ -2666,16 +2665,19 @@ associate_plusminus (gimple_stmt_iterator *gsi)
 		   && TREE_CODE (rhs2) == SSA_NAME)
 	    {
 	      /* (T)(P + A) - (T)P -> (T)A.  */
-	      gimple def_stmt2 = SSA_NAME_DEF_STMT (rhs2);
-	      if (is_gimple_assign (def_stmt2)
+	      gassign *def_stmt2 =
+		dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs2));
+	      if (def_stmt2
 		  && can_propagate_from (def_stmt2)
 		  && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt2))
 		  && TREE_CODE (gimple_assign_rhs1 (def_stmt2)) == SSA_NAME)
 		{
 		  /* Now we have (T)X - (T)P.  */
 		  tree p = gimple_assign_rhs1 (def_stmt2);
-		  def_stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt));
-		  if (is_gimple_assign (def_stmt2)
+		  def_stmt2 =
+		    dyn_cast <gassign *> (SSA_NAME_DEF_STMT (
+					    gimple_assign_rhs1 (def_stmt)));
+		  if (def_stmt2
 		      && can_propagate_from (def_stmt2)
 		      && (gimple_assign_rhs_code (def_stmt2) == POINTER_PLUS_EXPR
 			  || gimple_assign_rhs_code (def_stmt2) == PLUS_EXPR)
@@ -2732,8 +2734,8 @@ associate_plusminus (gimple_stmt_iterator *gsi)
 
   if (rhs2 && TREE_CODE (rhs2) == SSA_NAME)
     {
-      gimple def_stmt = SSA_NAME_DEF_STMT (rhs2);
-      if (is_gimple_assign (def_stmt) && can_propagate_from (def_stmt))
+      gassign *def_stmt = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs2));
+      if (def_stmt && can_propagate_from (def_stmt))
 	{
 	  enum tree_code def_code = gimple_assign_rhs_code (def_stmt);
 	  if (def_code == PLUS_EXPR
@@ -2946,8 +2948,7 @@ associate_pointerplus_diff (gimple_stmt_iterator *gsi)
 static bool
 associate_pointerplus (gimple_stmt_iterator *gsi)
 {
-  gimple stmt = gsi_stmt (*gsi);
-  gimple def_stmt;
+  gassign *stmt = as_a <gassign *> (gsi_stmt (*gsi));
   tree ptr, off1, off2;
 
   if (associate_pointerplus_align (gsi)
@@ -2960,8 +2961,9 @@ associate_pointerplus (gimple_stmt_iterator *gsi)
   if (TREE_CODE (ptr) != SSA_NAME
       || !has_single_use (ptr))
     return false;
-  def_stmt = SSA_NAME_DEF_STMT (ptr);
-  if (!is_gimple_assign (def_stmt)
+
+  gassign *def_stmt = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (ptr));
+  if (!def_stmt
       || gimple_assign_rhs_code (def_stmt) != POINTER_PLUS_EXPR
       || !can_propagate_from (def_stmt))
     return false;
@@ -3247,7 +3249,7 @@ static bool
 simplify_bitfield_ref (gimple_stmt_iterator *gsi)
 {
   gimple stmt = gsi_stmt (*gsi);
-  gimple def_stmt;
+  gassign *def_stmt;
   tree op, op0, op1, op2;
   tree elem_type;
   unsigned idx, n, size;
@@ -3360,7 +3362,7 @@ static int
 simplify_permutation (gimple_stmt_iterator *gsi)
 {
   gimple stmt = gsi_stmt (*gsi);
-  gimple def_stmt;
+  gassign *def_stmt;
   tree op0, op1, op2, op3, arg0, arg1;
   enum tree_code code;
   bool single_use_op0 = false;
@@ -3430,7 +3432,7 @@ simplify_permutation (gimple_stmt_iterator *gsi)
 	    {
 	      enum tree_code code2;
 
-	      gimple def_stmt2 = get_prop_source_stmt (op1, true, NULL);
+	      gassign *def_stmt2 = get_prop_source_stmt (op1, true, NULL);
 	      if (!def_stmt2 || !can_propagate_from (def_stmt2))
 		return 0;
 
@@ -3471,7 +3473,7 @@ static bool
 simplify_vector_constructor (gimple_stmt_iterator *gsi)
 {
   gimple stmt = gsi_stmt (*gsi);
-  gimple def_stmt;
+  gassign *def_stmt;
   tree op, op2, orig, type, elem_type;
   unsigned elem_size, nelts, i;
   enum tree_code code;
@@ -3737,11 +3739,12 @@ pass_forwprop::execute (function *fun)
 	 Note we update GSI within the loop as necessary.  */
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
 	{
-	  gimple stmt = gsi_stmt (gsi);
+	  gassign *stmt;
 	  tree lhs, rhs;
 	  enum tree_code code;
 
-	  if (!is_gimple_assign (stmt))
+	  stmt = dyn_cast <gassign *> (gsi_stmt (gsi));
+	  if (!stmt)
 	    {
 	      gsi_next (&gsi);
 	      continue;
