gcc/ChangeLog.gimple-classes:
        * tree-ssa-math-opts.c (is_division_by): Replace is_gimple_assign
        with dyn_cast, introducing local gassign * "use_assign", using it
        in place of "use_stmt" for typesafety.
        (replace_reciprocal): Add a checked cast.
        (pass_cse_reciprocals::execute): Replace is_gimple_assign
        with dyn_cast, introducing local gassign * "assign_stmt", using it
        to eliminate "stmt" for typesafety.  Likewise replace local gimple
        "stmt2" with new local gassign * "assign_stmt2". Reintroduce local
        gimple "stmt" near the end for the FOR_EACH_IMM_USE_STMT loop,
        adding a checked cast.
        (find_bswap_or_nop_1): Strengthen return type and locals
        "source_stmt1" and "source_stmt2" from gimple to gassign *.
        Replace is_gimple_assign with a dyn_cast, introducing local
        gassign * "assign_stmt", using it in place of "stmt for
        typesafety.
        (find_bswap_or_nop): Strengthen return type and local
        "source_stmt" from gimple to gassign *.
        (bswap_replace): Likewise for params "cur_stmt" and "src_stmt".
        (pass_optimize_bswap::execute): Likewise for locals "src_stmt" and
        "cur_stmt", replacing an is_gimple_assign with a dyn_cast.
        (widening_mult_conversion_strippable_p): Likewise for param
        "stmt".
        (is_widening_mult_rhs_p): Replace is_gimple_assign with a
        dyn_cast, introducing local gassign * "assign_stmt" and using it
        in place of "stmt" for typesafety.
        (is_widening_mult_p): Strengthen param "stmt" from gimple to
        gassign *.
        (convert_mult_to_widen): Likewise.
        (convert_plusminus_to_widen): Likewise, also for locals
        "conv1_stmt", "conv2_stmt", "conv_stmt".  Replace is_gimple_assign
        calls with dyn_casts, using them to introduce local gassign *
        "rhs1_assign" and "rhs2_assign", using them in place of
        "rhs1_stmt" and "rhs2_stmt" in the regions where we know we have
        a GIMPLE_ASSIGN, adding gcc_assert to ensure that the gassign *
        is equal to their plain gimple counterparts where we assume this.
        (convert_mult_to_fma): Replace is_gimple_assigns with dyn_casts,
        introducing locals gassign * "use_assign" and using them in place
        of "use_stmt" for typesafety.  Similarly for the region where
        "use_stmt" is known to be a GIMPLE_ASSIGN, via a checked cast.
        (pass_optimize_widening_mul::execute): Replace is_gimple_assign
        with dyn_cast, introducing local gassign * "assign_stmt", using it
        to eliminate "stmt" for typesafety.
---
 gcc/ChangeLog.gimple-classes |  45 ++++++++++
 gcc/tree-ssa-math-opts.c     | 198 ++++++++++++++++++++++++-------------------
 2 files changed, 154 insertions(+), 89 deletions(-)

diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index 45e3bd7..f5d557c 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,5 +1,50 @@
 2014-11-06  David Malcolm  <dmalc...@redhat.com>
 
+       * tree-ssa-math-opts.c (is_division_by): Replace is_gimple_assign
+       with dyn_cast, introducing local gassign * "use_assign", using it
+       in place of "use_stmt" for typesafety.
+       (replace_reciprocal): Add a checked cast.
+       (pass_cse_reciprocals::execute): Replace is_gimple_assign
+       with dyn_cast, introducing local gassign * "assign_stmt", using it
+       to eliminate "stmt" for typesafety.  Likewise replace local gimple
+       "stmt2" with new local gassign * "assign_stmt2". Reintroduce local
+       gimple "stmt" near the end for the FOR_EACH_IMM_USE_STMT loop,
+       adding a checked cast.
+       (find_bswap_or_nop_1): Strengthen return type and locals
+       "source_stmt1" and "source_stmt2" from gimple to gassign *.
+       Replace is_gimple_assign with a dyn_cast, introducing local
+       gassign * "assign_stmt", using it in place of "stmt for
+       typesafety.
+       (find_bswap_or_nop): Strengthen return type and local
+       "source_stmt" from gimple to gassign *.
+       (bswap_replace): Likewise for params "cur_stmt" and "src_stmt".
+       (pass_optimize_bswap::execute): Likewise for locals "src_stmt" and
+       "cur_stmt", replacing an is_gimple_assign with a dyn_cast.
+       (widening_mult_conversion_strippable_p): Likewise for param
+       "stmt".
+       (is_widening_mult_rhs_p): Replace is_gimple_assign with a
+       dyn_cast, introducing local gassign * "assign_stmt" and using it
+       in place of "stmt" for typesafety.
+       (is_widening_mult_p): Strengthen param "stmt" from gimple to
+       gassign *.
+       (convert_mult_to_widen): Likewise.
+       (convert_plusminus_to_widen): Likewise, also for locals
+       "conv1_stmt", "conv2_stmt", "conv_stmt".  Replace is_gimple_assign
+       calls with dyn_casts, using them to introduce local gassign *
+       "rhs1_assign" and "rhs2_assign", using them in place of
+       "rhs1_stmt" and "rhs2_stmt" in the regions where we know we have
+       a GIMPLE_ASSIGN, adding gcc_assert to ensure that the gassign *
+       is equal to their plain gimple counterparts where we assume this.
+       (convert_mult_to_fma): Replace is_gimple_assigns with dyn_casts,
+       introducing locals gassign * "use_assign" and using them in place
+       of "use_stmt" for typesafety.  Similarly for the region where
+       "use_stmt" is known to be a GIMPLE_ASSIGN, via a checked cast.
+       (pass_optimize_widening_mul::execute): Replace is_gimple_assign
+       with dyn_cast, introducing local gassign * "assign_stmt", using it
+       to eliminate "stmt" for typesafety.
+
+2014-11-06  David Malcolm  <dmalc...@redhat.com>
+
        * tree-ssa-live.c (remove_unused_locals): Add a checked cast in
        region guarded by gimple_clobber_p.
 
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index be567e0..b98d584 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -343,13 +343,14 @@ compute_merit (struct occurrence *occ)
 static inline bool
 is_division_by (gimple use_stmt, tree def)
 {
-  return is_gimple_assign (use_stmt)
-        && gimple_assign_rhs_code (use_stmt) == RDIV_EXPR
-        && gimple_assign_rhs2 (use_stmt) == def
+  gassign *use_assign = dyn_cast <gassign *> (use_stmt);
+  return use_assign
+        && gimple_assign_rhs_code (use_assign) == RDIV_EXPR
+        && gimple_assign_rhs2 (use_assign) == def
         /* Do not recognize x / x as valid division, as we are getting
            confused later by replacing all immediate uses x in such
            a stmt.  */
-        && gimple_assign_rhs1 (use_stmt) != def;
+        && gimple_assign_rhs1 (use_assign) != def;
 }
 
 /* Walk the subset of the dominator tree rooted at OCC, setting the
@@ -429,7 +430,7 @@ replace_reciprocal (use_operand_p use_p)
       && occ->recip_def && use_stmt != occ->recip_def_stmt)
     {
       gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
-      gimple_assign_set_rhs_code (use_stmt, MULT_EXPR);
+      gimple_assign_set_rhs_code (as_a <gassign *> (use_stmt), MULT_EXPR);
       SET_USE (use_p, occ->recip_def);
       fold_stmt_inplace (&gsi);
       update_stmt (use_stmt);
@@ -607,13 +608,14 @@ pass_cse_reciprocals::execute (function *fun)
       for (gimple_stmt_iterator gsi = gsi_after_labels (bb); !gsi_end_p (gsi);
           gsi_next (&gsi))
         {
-         gimple stmt = gsi_stmt (gsi);
+         gassign *assign_stmt;
          tree fndecl;
 
-         if (is_gimple_assign (stmt)
-             && gimple_assign_rhs_code (stmt) == RDIV_EXPR)
+         assign_stmt = dyn_cast <gassign *> (gsi_stmt (gsi));
+         if (assign_stmt
+             && gimple_assign_rhs_code (assign_stmt) == RDIV_EXPR)
            {
-             tree arg1 = gimple_assign_rhs2 (stmt);
+             tree arg1 = gimple_assign_rhs2 (assign_stmt);
              gimple stmt1;
 
              if (TREE_CODE (arg1) != SSA_NAME)
@@ -648,10 +650,11 @@ pass_cse_reciprocals::execute (function *fun)
                      gimple stmt2 = USE_STMT (use_p);
                      if (is_gimple_debug (stmt2))
                        continue;
-                     if (!is_gimple_assign (stmt2)
-                         || gimple_assign_rhs_code (stmt2) != RDIV_EXPR
-                         || gimple_assign_rhs1 (stmt2) == arg1
-                         || gimple_assign_rhs2 (stmt2) != arg1)
+                     gassign *assign_stmt2 = dyn_cast <gassign *> (stmt2);
+                     if (!assign_stmt2
+                         || gimple_assign_rhs_code (assign_stmt2) != RDIV_EXPR
+                         || gimple_assign_rhs1 (assign_stmt2) == arg1
+                         || gimple_assign_rhs2 (assign_stmt2) != arg1)
                        {
                          fail = true;
                          break;
@@ -665,10 +668,12 @@ pass_cse_reciprocals::execute (function *fun)
                  update_stmt (stmt1);
                  reciprocal_stats.rfuncs_inserted++;
 
+                 gimple stmt;
                  FOR_EACH_IMM_USE_STMT (stmt, ui, arg1)
                    {
                      gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
-                     gimple_assign_set_rhs_code (stmt, MULT_EXPR);
+                     gimple_assign_set_rhs_code (as_a <gassign *> (stmt),
+                                                 MULT_EXPR);
                      fold_stmt_inplace (&gsi);
                      update_stmt (stmt);
                    }
@@ -1835,31 +1840,33 @@ find_bswap_or_nop_load (gimple stmt, tree ref, struct 
symbolic_number *n)
    rhs's first tree is the expression of the source operand and NULL
    otherwise.  */
 
-static gimple
+static gassign *
 find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit)
 {
   enum tree_code code;
   tree rhs1, rhs2 = NULL;
-  gimple rhs1_stmt, rhs2_stmt, source_stmt1;
+  gimple rhs1_stmt, rhs2_stmt;
+  gassign *source_stmt1;
   enum gimple_rhs_class rhs_class;
+  gassign *assign_stmt = dyn_cast <gassign *> (stmt);
 
-  if (!limit || !is_gimple_assign (stmt))
+  if (!limit || !assign_stmt)
     return NULL;
 
-  rhs1 = gimple_assign_rhs1 (stmt);
+  rhs1 = gimple_assign_rhs1 (assign_stmt);
 
-  if (find_bswap_or_nop_load (stmt, rhs1, n))
-    return stmt;
+  if (find_bswap_or_nop_load (assign_stmt, rhs1, n))
+    return assign_stmt;
 
   if (TREE_CODE (rhs1) != SSA_NAME)
     return NULL;
 
-  code = gimple_assign_rhs_code (stmt);
-  rhs_class = gimple_assign_rhs_class (stmt);
+  code = gimple_assign_rhs_code (assign_stmt);
+  rhs_class = gimple_assign_rhs_class (assign_stmt);
   rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
 
   if (rhs_class == GIMPLE_BINARY_RHS)
-    rhs2 = gimple_assign_rhs2 (stmt);
+    rhs2 = gimple_assign_rhs2 (assign_stmt);
 
   /* Handle unary rhs and binary rhs with integer constants as second
      operand.  */
@@ -1883,10 +1890,10 @@ find_bswap_or_nop_1 (gimple stmt, struct 
symbolic_number *n, int limit)
         we have to initialize the symbolic number.  */
       if (!source_stmt1)
        {
-         if (gimple_assign_load_p (stmt)
+         if (gimple_assign_load_p (assign_stmt)
              || !init_symbolic_number (n, rhs1))
            return NULL;
-         source_stmt1 = stmt;
+         source_stmt1 = assign_stmt;
        }
 
       switch (code)
@@ -1919,7 +1926,7 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number 
*n, int limit)
            int i, type_size, old_type_size;
            tree type;
 
-           type = gimple_expr_type (stmt);
+           type = gimple_expr_type (assign_stmt);
            type_size = TYPE_PRECISION (type);
            if (type_size % BITS_PER_UNIT != 0)
              return NULL;
@@ -1949,7 +1956,7 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number 
*n, int limit)
        default:
          return NULL;
        };
-      return verify_symbolic_number_p (n, stmt) ? source_stmt1 : NULL;
+      return verify_symbolic_number_p (n, assign_stmt) ? source_stmt1 : NULL;
     }
 
   /* Handle binary rhs.  */
@@ -1959,7 +1966,7 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number 
*n, int limit)
       int i, size;
       struct symbolic_number n1, n2;
       uint64_t mask;
-      gimple source_stmt2;
+      gassign *source_stmt2;
 
       if (code != BIT_IOR_EXPR)
        return NULL;
@@ -2064,7 +2071,7 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number 
*n, int limit)
            }
          n->n = n1.n | n2.n;
 
-         if (!verify_symbolic_number_p (n, stmt))
+         if (!verify_symbolic_number_p (n, assign_stmt))
            return NULL;
 
          break;
@@ -2084,7 +2091,7 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number 
*n, int limit)
    function returns a stmt whose rhs's first tree is the source
    expression.  */
 
-static gimple
+static gassign *
 find_bswap_or_nop (gimple stmt, struct symbolic_number *n, bool *bswap)
 {
 /* The number which the find_bswap_or_nop_1 result should match in order
@@ -2093,7 +2100,7 @@ find_bswap_or_nop (gimple stmt, struct symbolic_number 
*n, bool *bswap)
   uint64_t cmpxchg = CMPXCHG;
   uint64_t cmpnop = CMPNOP;
 
-  gimple source_stmt;
+  gassign *source_stmt;
   int limit;
 
   /* The last parameter determines the depth search limit.  It usually
@@ -2188,7 +2195,7 @@ public:
    some statistics.  */
 
 static bool
-bswap_replace (gimple cur_stmt, gimple_stmt_iterator gsi, gimple src_stmt,
+bswap_replace (gassign *cur_stmt, gimple_stmt_iterator gsi, gassign *src_stmt,
               tree fndecl, tree bswap_type, tree load_type,
               struct symbolic_number *n, bool bswap)
 {
@@ -2392,12 +2399,14 @@ pass_optimize_bswap::execute (function *fun)
         patterns, the wider variant wouldn't be detected.  */
       for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
         {
-         gimple src_stmt, cur_stmt = gsi_stmt (gsi);
+         gassign *src_stmt;
+         gassign *cur_stmt;
          tree fndecl = NULL_TREE, bswap_type = NULL_TREE, load_type;
          struct symbolic_number n;
          bool bswap;
 
-         if (!is_gimple_assign (cur_stmt)
+         cur_stmt = dyn_cast <gassign *> (gsi_stmt (gsi));
+         if (!cur_stmt
              || gimple_assign_rhs_code (cur_stmt) != BIT_IOR_EXPR)
            continue;
 
@@ -2472,7 +2481,7 @@ make_pass_optimize_bswap (gcc::context *ctxt)
 /* Return true if stmt is a type conversion operation that can be stripped
    when used in a widening multiply operation.  */
 static bool
-widening_mult_conversion_strippable_p (tree result_type, gimple stmt)
+widening_mult_conversion_strippable_p (tree result_type, gassign *stmt)
 {
   enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
 
@@ -2530,13 +2539,13 @@ is_widening_mult_rhs_p (tree type, tree rhs, tree 
*type_out,
   if (TREE_CODE (rhs) == SSA_NAME)
     {
       stmt = SSA_NAME_DEF_STMT (rhs);
-      if (is_gimple_assign (stmt))
+      if (gassign *assign_stmt = dyn_cast <gassign *> (stmt))
        {
-         if (! widening_mult_conversion_strippable_p (type, stmt))
+         if (! widening_mult_conversion_strippable_p (type, assign_stmt))
            rhs1 = rhs;
          else
            {
-             rhs1 = gimple_assign_rhs1 (stmt);
+             rhs1 = gimple_assign_rhs1 (assign_stmt);
 
              if (TREE_CODE (rhs1) == INTEGER_CST)
                {
@@ -2577,7 +2586,7 @@ is_widening_mult_rhs_p (tree type, tree rhs, tree 
*type_out,
    and *TYPE2_OUT would give the operands of the multiplication.  */
 
 static bool
-is_widening_mult_p (gimple stmt,
+is_widening_mult_p (gassign *stmt,
                    tree *type1_out, tree *rhs1_out,
                    tree *type2_out, tree *rhs2_out)
 {
@@ -2629,7 +2638,7 @@ is_widening_mult_p (gimple stmt,
    value is true iff we converted the statement.  */
 
 static bool
-convert_mult_to_widen (gimple stmt, gimple_stmt_iterator *gsi)
+convert_mult_to_widen (gassign *stmt, gimple_stmt_iterator *gsi)
 {
   tree lhs, rhs1, rhs2, type, type1, type2;
   enum insn_code handler;
@@ -2730,11 +2739,12 @@ convert_mult_to_widen (gimple stmt, 
gimple_stmt_iterator *gsi)
    is true iff we converted the statement.  */
 
 static bool
-convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple stmt,
+convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gassign *stmt,
                            enum tree_code code)
 {
   gimple rhs1_stmt = NULL, rhs2_stmt = NULL;
-  gimple conv1_stmt = NULL, conv2_stmt = NULL, conv_stmt;
+  gassign *rhs1_assign = NULL, *rhs2_assign = NULL;
+  gassign *conv1_stmt = NULL, *conv2_stmt = NULL, *conv_stmt;
   tree type, type1, type2, optype;
   tree lhs, rhs1, rhs2, mult_rhs1, mult_rhs2, add_rhs;
   enum tree_code rhs1_code = ERROR_MARK, rhs2_code = ERROR_MARK;
@@ -2763,15 +2773,17 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, 
gimple stmt,
   if (TREE_CODE (rhs1) == SSA_NAME)
     {
       rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
-      if (is_gimple_assign (rhs1_stmt))
-       rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
+      rhs1_assign = dyn_cast <gassign *> (rhs1_stmt);
+      if (rhs1_assign)
+       rhs1_code = gimple_assign_rhs_code (rhs1_assign);
     }
 
   if (TREE_CODE (rhs2) == SSA_NAME)
     {
       rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
-      if (is_gimple_assign (rhs2_stmt))
-       rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
+      rhs2_assign = dyn_cast <gassign *> (rhs2_stmt);
+      if (rhs2_assign)
+       rhs2_code = gimple_assign_rhs_code (rhs2_assign);
     }
 
   /* Allow for one conversion statement between the multiply
@@ -2781,26 +2793,28 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, 
gimple stmt,
      been folded before now.  */
   if (CONVERT_EXPR_CODE_P (rhs1_code))
     {
-      conv1_stmt = rhs1_stmt;
-      rhs1 = gimple_assign_rhs1 (rhs1_stmt);
+      conv1_stmt = rhs1_assign;
+      rhs1 = gimple_assign_rhs1 (rhs1_assign);
       if (TREE_CODE (rhs1) == SSA_NAME)
        {
          rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
-         if (is_gimple_assign (rhs1_stmt))
-           rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
+         rhs1_assign = dyn_cast <gassign *> (rhs1_stmt);
+         if (rhs1_assign)
+           rhs1_code = gimple_assign_rhs_code (rhs1_assign);
        }
       else
        return false;
     }
   if (CONVERT_EXPR_CODE_P (rhs2_code))
     {
-      conv2_stmt = rhs2_stmt;
-      rhs2 = gimple_assign_rhs1 (rhs2_stmt);
+      conv2_stmt = rhs2_assign;
+      rhs2 = gimple_assign_rhs1 (as_a <gassign *> (rhs2_stmt));
       if (TREE_CODE (rhs2) == SSA_NAME)
        {
          rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
-         if (is_gimple_assign (rhs2_stmt))
-           rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
+         rhs2_assign = dyn_cast <gassign *> (rhs2_stmt);
+         if (rhs2_assign)
+           rhs2_code = gimple_assign_rhs_code (rhs2_assign);
        }
       else
        return false;
@@ -2818,8 +2832,9 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, 
gimple stmt,
   if (code == PLUS_EXPR
       && (rhs1_code == MULT_EXPR || rhs1_code == WIDEN_MULT_EXPR))
     {
+      gcc_assert (rhs1_stmt == rhs1_assign);
       if (!has_single_use (rhs1)
-         || !is_widening_mult_p (rhs1_stmt, &type1, &mult_rhs1,
+         || !is_widening_mult_p (rhs1_assign, &type1, &mult_rhs1,
                                  &type2, &mult_rhs2))
        return false;
       add_rhs = rhs2;
@@ -2827,8 +2842,9 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, 
gimple stmt,
     }
   else if (rhs2_code == MULT_EXPR || rhs2_code == WIDEN_MULT_EXPR)
     {
+      gcc_assert (rhs2_stmt == rhs2_assign);
       if (!has_single_use (rhs2)
-         || !is_widening_mult_p (rhs2_stmt, &type1, &mult_rhs1,
+         || !is_widening_mult_p (rhs2_assign, &type1, &mult_rhs1,
                                  &type2, &mult_rhs2))
        return false;
       add_rhs = rhs1;
@@ -2998,10 +3014,11 @@ convert_mult_to_fma (gimple mul_stmt, tree op1, tree 
op2)
       if (gimple_bb (use_stmt) != gimple_bb (mul_stmt))
        return false;
 
-      if (!is_gimple_assign (use_stmt))
+      gassign *use_assign = dyn_cast <gassign *> (use_stmt);
+      if (!use_assign)
        return false;
 
-      use_code = gimple_assign_rhs_code (use_stmt);
+      use_code = gimple_assign_rhs_code (use_assign);
 
       /* A negate on the multiplication leads to FNMA.  */
       if (use_code == NEGATE_EXPR)
@@ -3009,11 +3026,11 @@ convert_mult_to_fma (gimple mul_stmt, tree op1, tree 
op2)
          ssa_op_iter iter;
          use_operand_p usep;
 
-         result = gimple_assign_lhs (use_stmt);
+         result = gimple_assign_lhs (use_assign);
 
          /* Make sure the negate statement becomes dead with this
             single transformation.  */
-         if (!single_imm_use (gimple_assign_lhs (use_stmt),
+         if (!single_imm_use (gimple_assign_lhs (use_assign),
                               &use_p, &neguse_stmt))
            return false;
 
@@ -3026,17 +3043,18 @@ convert_mult_to_fma (gimple mul_stmt, tree op1, tree 
op2)
          use_stmt = neguse_stmt;
          if (gimple_bb (use_stmt) != gimple_bb (mul_stmt))
            return false;
-         if (!is_gimple_assign (use_stmt))
+         use_assign = dyn_cast <gassign *> (use_stmt);
+         if (!use_assign)
            return false;
 
-         use_code = gimple_assign_rhs_code (use_stmt);
+         use_code = gimple_assign_rhs_code (use_assign);
          negate_p = true;
        }
 
       switch (use_code)
        {
        case MINUS_EXPR:
-         if (gimple_assign_rhs2 (use_stmt) == result)
+         if (gimple_assign_rhs2 (use_assign) == result)
            negate_p = !negate_p;
          break;
        case PLUS_EXPR:
@@ -3046,30 +3064,31 @@ convert_mult_to_fma (gimple mul_stmt, tree op1, tree 
op2)
          return false;
        }
 
-      /* If the subtrahend (gimple_assign_rhs2 (use_stmt)) is computed
+      /* If the subtrahend (gimple_assign_rhs2 (use_assign)) is computed
         by a MULT_EXPR that we'll visit later, we might be able to
         get a more profitable match with fnma.
         OTOH, if we don't, a negate / fma pair has likely lower latency
         that a mult / subtract pair.  */
       if (use_code == MINUS_EXPR && !negate_p
-         && gimple_assign_rhs1 (use_stmt) == result
+         && gimple_assign_rhs1 (use_assign) == result
          && optab_handler (fms_optab, TYPE_MODE (type)) == CODE_FOR_nothing
          && optab_handler (fnma_optab, TYPE_MODE (type)) != CODE_FOR_nothing)
        {
-         tree rhs2 = gimple_assign_rhs2 (use_stmt);
+         tree rhs2 = gimple_assign_rhs2 (use_assign);
 
          if (TREE_CODE (rhs2) == SSA_NAME)
            {
              gimple stmt2 = SSA_NAME_DEF_STMT (rhs2);
              if (has_single_use (rhs2)
                  && is_gimple_assign (stmt2)
-                 && gimple_assign_rhs_code (stmt2) == MULT_EXPR)
+                 && (gimple_assign_rhs_code (as_a <gassign *> (stmt2))
+                     == MULT_EXPR))
              return false;
            }
        }
 
       /* We can't handle a * b + a * b.  */
-      if (gimple_assign_rhs1 (use_stmt) == gimple_assign_rhs2 (use_stmt))
+      if (gimple_assign_rhs1 (use_assign) == gimple_assign_rhs2 (use_assign))
        return false;
 
       /* While it is possible to validate whether or not the exact form
@@ -3092,25 +3111,26 @@ convert_mult_to_fma (gimple mul_stmt, tree op1, tree 
op2)
       if (is_gimple_debug (use_stmt))
        continue;
 
-      use_code = gimple_assign_rhs_code (use_stmt);
+      gassign *use_assign = as_a <gassign *> (use_stmt);
+      use_code = gimple_assign_rhs_code (use_assign);
       if (use_code == NEGATE_EXPR)
        {
-         result = gimple_assign_lhs (use_stmt);
-         single_imm_use (gimple_assign_lhs (use_stmt), &use_p, &neguse_stmt);
+         result = gimple_assign_lhs (use_assign);
+         single_imm_use (gimple_assign_lhs (use_assign), &use_p, &neguse_stmt);
          gsi_remove (&gsi, true);
-         release_defs (use_stmt);
+         release_defs (use_assign);
 
-         use_stmt = neguse_stmt;
-         gsi = gsi_for_stmt (use_stmt);
-         use_code = gimple_assign_rhs_code (use_stmt);
+         use_assign = as_a <gassign *> (neguse_stmt);
+         gsi = gsi_for_stmt (use_assign);
+         use_code = gimple_assign_rhs_code (use_assign);
          negate_p = true;
        }
 
-      if (gimple_assign_rhs1 (use_stmt) == result)
+      if (gimple_assign_rhs1 (use_assign) == result)
        {
-         addop = gimple_assign_rhs2 (use_stmt);
+         addop = gimple_assign_rhs2 (use_assign);
          /* a * b - c -> a * b + (-c)  */
-         if (gimple_assign_rhs_code (use_stmt) == MINUS_EXPR)
+         if (gimple_assign_rhs_code (use_assign) == MINUS_EXPR)
            addop = force_gimple_operand_gsi (&gsi,
                                              build1 (NEGATE_EXPR,
                                                      type, addop),
@@ -3119,9 +3139,9 @@ convert_mult_to_fma (gimple mul_stmt, tree op1, tree op2)
        }
       else
        {
-         addop = gimple_assign_rhs1 (use_stmt);
+         addop = gimple_assign_rhs1 (use_assign);
          /* a - b * c -> (-b) * c + a */
-         if (gimple_assign_rhs_code (use_stmt) == MINUS_EXPR)
+         if (gimple_assign_rhs_code (use_assign) == MINUS_EXPR)
            negate_p = !negate_p;
        }
 
@@ -3133,7 +3153,7 @@ convert_mult_to_fma (gimple mul_stmt, tree op1, tree op2)
                                           GSI_SAME_STMT);
 
       fma_stmt = gimple_build_assign_with_ops (FMA_EXPR,
-                                              gimple_assign_lhs (use_stmt),
+                                              gimple_assign_lhs (use_assign),
                                               mulop1, op2,
                                               addop);
       gsi_replace (&gsi, fma_stmt, true);
@@ -3196,26 +3216,26 @@ pass_optimize_widening_mul::execute (function *fun)
          gimple stmt = gsi_stmt (gsi);
          enum tree_code code;
 
-         if (is_gimple_assign (stmt))
+         if (gassign *assign_stmt = dyn_cast <gassign *> (stmt))
            {
-             code = gimple_assign_rhs_code (stmt);
+             code = gimple_assign_rhs_code (assign_stmt);
              switch (code)
                {
                case MULT_EXPR:
-                 if (!convert_mult_to_widen (stmt, &gsi)
-                     && convert_mult_to_fma (stmt,
-                                             gimple_assign_rhs1 (stmt),
-                                             gimple_assign_rhs2 (stmt)))
+                 if (!convert_mult_to_widen (assign_stmt, &gsi)
+                     && convert_mult_to_fma (assign_stmt,
+                                             gimple_assign_rhs1 (assign_stmt),
+                                             gimple_assign_rhs2 (assign_stmt)))
                    {
                      gsi_remove (&gsi, true);
-                     release_defs (stmt);
+                     release_defs (assign_stmt);
                      continue;
                    }
                  break;
 
                case PLUS_EXPR:
                case MINUS_EXPR:
-                 convert_plusminus_to_widen (&gsi, stmt, code);
+                 convert_plusminus_to_widen (&gsi, assign_stmt, code);
                  break;
 
                default:;
-- 
1.7.11.7

Reply via email to