Index: gcc/testsuite/gcc.dg/tree-ssa/pr56321.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/pr56321.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/pr56321.c	(revision 0)
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -ffast-math -fdump-tree-optimized" } */
+
+float foo(int n)
+{                              
+  return ((2.0*n*n)/3.0+2.0*n);   
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_pow" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " \\* " 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " \\+ " 1 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
Index: gcc/tree-ssa-reassoc.c
===================================================================
--- gcc/tree-ssa-reassoc.c	(revision 196053)
+++ gcc/tree-ssa-reassoc.c	(working copy)
@@ -3386,6 +3386,10 @@ linearize_expr_tree (vec<operand_entry_t> *ops, gi
 	    {
 	      add_repeat_to_ops_vec (ops, base, exponent);
 	      gimple_set_visited (binrhsdef, true);
+	      // We may not physically remove the call later because
+	      // stmts are preferably modified in place.  But we have
+	      // to remove any VDEF associated with the call regardless.
+	      unlink_stmt_vdef (binrhsdef);
 	    }
 	  else
 	    add_to_ops_vec (ops, binrhs);
@@ -3396,6 +3400,10 @@ linearize_expr_tree (vec<operand_entry_t> *ops, gi
 	    {
 	      add_repeat_to_ops_vec (ops, base, exponent);
 	      gimple_set_visited (binlhsdef, true);
+	      // We may not physically remove the call later because
+	      // stmts are preferably modified in place.  But we have
+	      // to remove any VDEF associated with the call regardless.
+	      unlink_stmt_vdef (binlhsdef);
 	    }
 	  else
 	    add_to_ops_vec (ops, binlhs);
@@ -3445,6 +3453,10 @@ linearize_expr_tree (vec<operand_entry_t> *ops, gi
     {
       add_repeat_to_ops_vec (ops, base, exponent);
       gimple_set_visited (SSA_NAME_DEF_STMT (binrhs), true);
+      // We may not physically remove the call later because
+      // stmts are preferably modified in place.  But we have
+      // to remove any VDEF associated with the call regardless.
+      unlink_stmt_vdef (SSA_NAME_DEF_STMT (binrhs));
     }
   else
     add_to_ops_vec (ops, binrhs);
