re PR tree-optimization/40921 (missed optimization: x + (-y * z * z) => x - y * z...
authorKugan Vivekanandarajah <kuganv@linaro.org>
Sun, 22 May 2016 08:13:13 +0000 (08:13 +0000)
committerKugan Vivekanandarajah <kugan@gcc.gnu.org>
Sun, 22 May 2016 08:13:13 +0000 (08:13 +0000)
gcc/testsuite/ChangeLog:

2016-05-22  Kugan Vivekanandarajah  <kuganv@linaro.org>

PR middle-end/40921
* gcc.dg/tree-ssa/pr40921.c: New test.

gcc/ChangeLog:

2016-05-22  Kugan Vivekanandarajah  <kuganv@linaro.org>

PR middle-end/40921
        * tree-ssa-reassoc.c (try_special_add_to_ops): New.
        (linearize_expr_tree): Call try_special_add_to_ops.
        (reassociate_bb): Convert MULT_EXPR by (-1) to NEGATE_EXPR.

From-SVN: r236564

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr40921.c [new file with mode: 0644]
gcc/tree-ssa-reassoc.c

index 7a9541406b9863a8fb0d37aea3cdf81e7433c0e9..7bdecf0ca919a9624acdb22e5e16a568ed82053b 100644 (file)
@@ -1,3 +1,10 @@
+2016-05-22  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+       PR middle-end/40921
+        * tree-ssa-reassoc.c (try_special_add_to_ops): New.
+        (linearize_expr_tree): Call try_special_add_to_ops.
+        (reassociate_bb): Convert MULT_EXPR by (-1) to NEGATE_EXPR.
+
 2016-05-21  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
 
        * config/avr/avr.c (avr_expand_prologue): Add INCOMING_FRAME_SP_OFFSET
index a409b88e95477a39f58b923bff76e20970323f0a..3ee60b1bf330b17caa555a6c34d9818e4fbb2ab6 100644 (file)
@@ -1,3 +1,8 @@
+2016-05-22  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+       PR middle-end/40921
+       * gcc.dg/tree-ssa/pr40921.c: New test.
+
 2016-05-20  Pitchumani Sivanupandi  <pitchumani.s@atmel.com>
 
        PR target/71103
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr40921.c b/gcc/testsuite/gcc.dg/tree-ssa/pr40921.c
new file mode 100644 (file)
index 0000000..3a5a23a
--- /dev/null
@@ -0,0 +1,26 @@
+
+/* { dg-do compile } */
+/* { dg-options "-O2  -fdump-tree-optimized -ffast-math" } */
+
+unsigned int foo (unsigned int x, unsigned int y, unsigned int z)
+{
+      return x + (-y * z * z);
+}
+
+float bar (float x, float y, float z)
+{
+      return x + (-y * z * z);
+}
+
+float bar2 (float x, float y, float z)
+{
+      return x + (-y * z * z * 5.0f);
+}
+
+float bar3 (float x, float y, float z)
+{
+      return x + (-y * x * -z);
+}
+
+
+/* { dg-final { scan-tree-dump-times "_* = -y_" 0 "optimized" } } */
index 3c718e9b20453f5c7b3d6b639e15f502fdd53fa8..798931fee7a3909d04806228327cb9390022647b 100644 (file)
@@ -4329,6 +4329,45 @@ acceptable_pow_call (gimple *stmt, tree *base, HOST_WIDE_INT *exponent)
   return true;
 }
 
+/* Try to derive and add operand entry for OP to *OPS.  Return false if
+   unsuccessful.  */
+
+static bool
+try_special_add_to_ops (vec<operand_entry *> *ops,
+                       enum tree_code code,
+                       tree op, gimple* def_stmt)
+{
+  tree base = NULL_TREE;
+  HOST_WIDE_INT exponent = 0;
+
+  if (TREE_CODE (op) != SSA_NAME)
+    return false;
+
+  if (code == MULT_EXPR
+      && acceptable_pow_call (def_stmt, &base, &exponent))
+    {
+      add_repeat_to_ops_vec (ops, base, exponent);
+      gimple_set_visited (def_stmt, true);
+      return true;
+    }
+  else if (code == MULT_EXPR
+          && is_gimple_assign (def_stmt)
+          && gimple_assign_rhs_code (def_stmt) == NEGATE_EXPR
+          && !HONOR_SNANS (TREE_TYPE (op))
+          && (!HONOR_SIGNED_ZEROS (TREE_TYPE (op))
+              || !COMPLEX_FLOAT_TYPE_P (TREE_TYPE (op))))
+    {
+      tree rhs1 = gimple_assign_rhs1 (def_stmt);
+      tree cst = build_minus_one_cst (TREE_TYPE (op));
+      add_to_ops_vec (ops, rhs1);
+      add_to_ops_vec (ops, cst);
+      gimple_set_visited (def_stmt, true);
+      return true;
+    }
+
+  return false;
+}
+
 /* Recursively linearize a binary expression that is the RHS of STMT.
    Place the operands of the expression tree in the vector named OPS.  */
 
@@ -4343,8 +4382,6 @@ linearize_expr_tree (vec<operand_entry *> *ops, gimple *stmt,
   bool binrhsisreassoc = false;
   enum tree_code rhscode = gimple_assign_rhs_code (stmt);
   struct loop *loop = loop_containing_stmt (stmt);
-  tree base = NULL_TREE;
-  HOST_WIDE_INT exponent = 0;
 
   if (set_visited)
     gimple_set_visited (stmt, true);
@@ -4380,24 +4417,10 @@ linearize_expr_tree (vec<operand_entry *> *ops, gimple *stmt,
 
       if (!binrhsisreassoc)
        {
-         if (rhscode == MULT_EXPR
-             && TREE_CODE (binrhs) == SSA_NAME
-             && acceptable_pow_call (binrhsdef, &base, &exponent))
-           {
-             add_repeat_to_ops_vec (ops, base, exponent);
-             gimple_set_visited (binrhsdef, true);
-           }
-         else
+         if (!try_special_add_to_ops (ops, rhscode, binrhs, binrhsdef))
            add_to_ops_vec (ops, binrhs);
 
-         if (rhscode == MULT_EXPR
-             && TREE_CODE (binlhs) == SSA_NAME
-             && acceptable_pow_call (binlhsdef, &base, &exponent))
-           {
-             add_repeat_to_ops_vec (ops, base, exponent);
-             gimple_set_visited (binlhsdef, true);
-           }
-         else
+         if (!try_special_add_to_ops (ops, rhscode, binlhs, binlhsdef))
            add_to_ops_vec (ops, binlhs);
 
          return;
@@ -4437,14 +4460,7 @@ linearize_expr_tree (vec<operand_entry *> *ops, gimple *stmt,
   linearize_expr_tree (ops, SSA_NAME_DEF_STMT (binlhs),
                       is_associative, set_visited);
 
-  if (rhscode == MULT_EXPR
-      && TREE_CODE (binrhs) == SSA_NAME
-      && acceptable_pow_call (SSA_NAME_DEF_STMT (binrhs), &base, &exponent))
-    {
-      add_repeat_to_ops_vec (ops, base, exponent);
-      gimple_set_visited (SSA_NAME_DEF_STMT (binrhs), true);
-    }
-  else
+  if (!try_special_add_to_ops (ops, rhscode, binrhs, binrhsdef))
     add_to_ops_vec (ops, binrhs);
 }
 
@@ -5208,6 +5224,24 @@ reassociate_bb (basic_block bb)
                    powi_result = attempt_builtin_powi (stmt, &ops);
                }
 
+             operand_entry *last;
+             bool negate_result = false;
+             if (ops.length () > 1
+                 && rhs_code == MULT_EXPR)
+               {
+                 last = ops.last ();
+                 if (((TREE_CODE (last->op) == INTEGER_CST
+                       && integer_minus_onep (last->op))
+                      || real_minus_onep (last->op))
+                     && !HONOR_SNANS (TREE_TYPE (lhs))
+                     && (!HONOR_SIGNED_ZEROS (TREE_TYPE (lhs))
+                         || !COMPLEX_FLOAT_TYPE_P (TREE_TYPE (lhs))))
+                   {
+                     ops.pop ();
+                     negate_result = true;
+                   }
+               }
+
              /* If the operand vector is now empty, all operands were 
                 consumed by the __builtin_powi optimization.  */
              if (ops.length () == 0)
@@ -5270,6 +5304,18 @@ reassociate_bb (basic_block bb)
                      gsi_insert_after (&gsi, mul_stmt, GSI_NEW_STMT);
                    }
                }
+
+             if (negate_result)
+               {
+                 stmt = SSA_NAME_DEF_STMT (lhs);
+                 tree tmp = make_ssa_name (TREE_TYPE (lhs));
+                 gimple_set_lhs (stmt, tmp);
+                 gassign *neg_stmt = gimple_build_assign (lhs, NEGATE_EXPR,
+                                                          tmp);
+                 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+                 gsi_insert_after (&gsi, neg_stmt, GSI_NEW_STMT);
+                 update_stmt (stmt);
+               }
            }
        }
     }