When we remove __builtin_pow statements as part of reassociation, we
have to unlink the associated VDEF.  We've always done this when we
directly remove the statement.  However, in reassociation the statements
are sometimes modified in place instead of removed, potentially leaving
one or more dangling VUSEs.  This patch solves the problem by unlinking
the VDEF when the statement's operands are added to the ops list.

Bootstrapped and regression tested on powerpc64-unknown-linux-gnu with
no new regressions.  The new test case is the code that exposed the
problem in PR56321.  Ok for trunk?

Thanks,
Bill


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);


Reply via email to