There were more omissions in how zero_one_operation works with the new
way of processing negates in the context of multiplication chains.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.  CPU 2006
build in progress as well.

Richard.

2016-05-24  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/71230
        * tree-ssa-reassoc.c (zero_one_operation): Handle negate special ops.

        * gcc.dg/torture/pr71230.c: New testcase.
        * g++.dg/torture/pr71230.C: Likewise.

Index: gcc/tree-ssa-reassoc.c
===================================================================
*** gcc/tree-ssa-reassoc.c      (revision 236630)
--- gcc/tree-ssa-reassoc.c      (working copy)
*************** zero_one_operation (tree *def, enum tree
*** 1189,1200 ****
      {
        tree name;
  
!       if (opcode == MULT_EXPR
!         && stmt_is_power_of_op (stmt, op))
        {
!         if (decrement_power (stmt) == 1)
!           propagate_op_to_single_use (op, stmt, def);
!         return;
        }
  
        name = gimple_assign_rhs1 (stmt);
--- 1191,1210 ----
      {
        tree name;
  
!       if (opcode == MULT_EXPR)
        {
!         if (stmt_is_power_of_op (stmt, op))
!           {
!             if (decrement_power (stmt) == 1)
!               propagate_op_to_single_use (op, stmt, def);
!             return;
!           }
!         else if (gimple_assign_rhs_code (stmt) == NEGATE_EXPR
!                  && gimple_assign_rhs1 (stmt) == op)
!           {
!             propagate_op_to_single_use (op, stmt, def);
!             return;
!           }
        }
  
        name = gimple_assign_rhs1 (stmt);
*************** zero_one_operation (tree *def, enum tree
*** 1213,1219 ****
        }
  
        /* We might have a multiply of two __builtin_pow* calls, and
!        the operand might be hiding in the rightmost one.  */
        if (opcode == MULT_EXPR
          && gimple_assign_rhs_code (stmt) == opcode
          && TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME
--- 1223,1230 ----
        }
  
        /* We might have a multiply of two __builtin_pow* calls, and
!        the operand might be hiding in the rightmost one.  Likewise
!        this can happen for a negate.  */
        if (opcode == MULT_EXPR
          && gimple_assign_rhs_code (stmt) == opcode
          && TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME
*************** zero_one_operation (tree *def, enum tree
*** 1226,1231 ****
--- 1237,1249 ----
                propagate_op_to_single_use (op, stmt2, def);
              return;
            }
+         else if (is_gimple_assign (stmt2)
+                  && gimple_assign_rhs_code (stmt2) == NEGATE_EXPR
+                  && gimple_assign_rhs1 (stmt2) == op)
+           {
+             propagate_op_to_single_use (op, stmt2, def);
+             return;
+           }
        }
  
        /* Continue walking the chain.  */
Index: gcc/testsuite/gcc.dg/torture/pr71230.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr71230.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr71230.c      (working copy)
***************
*** 0 ****
--- 1,25 ----
+ /* { dg-do compile } */
+ /* { dg-additional-options "-ffast-math" } */
+ 
+ void metric_carttosphere(int *cctk_lsh, double txz, double tyz, double txx,
+                        double tzz, double sint, double cosp, double cost,
+                        double tyy, double sinp, double txy, double *grp,
+                        double *grq, double *r)
+ {
+   int i;
+   for(i=0; i<cctk_lsh[0]*cctk_lsh[1]*cctk_lsh[2]; i++)
+     {
+       grq[i] = (cost*tyy*((sinp)*(sinp))*sint+
+               2*cosp*cost*txy*sinp*sint-
+               cost*tzz*sint+ 
+               ((cosp)*(cosp))*cost*txx*sint+
+               2*((cost)*(cost))*tyz*sinp-
+               tyz*sinp+
+               2*cosp*((cost)*(cost))*txz-
+               cosp*txz)*r[i];
+       grp[i] = ((-txy*((sinp)*(sinp))+
+                (cosp*tyy-cosp*txx)*sinp+
+                ((cosp)*(cosp))*txy)*sint-
+               cost*txz*sinp+cosp*cost*tyz);
+     }
+ }
Index: gcc/testsuite/g++.dg/torture/pr71230.C
===================================================================
--- gcc/testsuite/g++.dg/torture/pr71230.C      (revision 0)
+++ gcc/testsuite/g++.dg/torture/pr71230.C      (working copy)
@@ -0,0 +1,31 @@
+// { dg-do compile }
+// { dg-additional-options "-ffast-math" }
+
+template <int rank, int dim> class Tensor;
+template <int dim> class Point {
+public:
+    Point (const double x, const double y, const double z);
+    double operator () (const unsigned int index) const;
+};
+template <int celldim, int dim> class TriaObjectAccessor  {
+    Point<dim> & vertex (const unsigned int i) const;
+    Point<dim> barycenter (double, double, double, double, double) const;
+};
+template <> Point<3> TriaObjectAccessor<3, 3>::barycenter (double s6, double 
s7, double s1, double s2, double s3) const
+{
+    const double x[8] = {
+       vertex(0)(0),    vertex(1)(0),    vertex(2)(0),    vertex(3)(0),    
vertex(4)(0),    vertex(5)(0),    vertex(6)(0),    vertex(7)(0) };
+    const double y[8] = {
+       vertex(0)(1),    vertex(1)(1),    vertex(2)(1),    vertex(3)(1),    
vertex(4)(1),    vertex(5)(1),    vertex(6)(1),    vertex(7)(1) };
+    const double z[8] = {
+       vertex(0)(2),    vertex(1)(2),    vertex(2)(2),    vertex(3)(2),    
vertex(4)(2),    vertex(5)(2),    vertex(6)(2),    vertex(7)(2) };
+    double s4, s5, s8;
+    const double unknown0 = s1*s2;
+    const double unknown1 = s1*s2;
+    s8 = -z[2]*x[1]*y[2]*z[5]+z[2]*y[1]*x[2]*z[5]-z[2]*z[1]*x[2]*y[5]+z[2]*z   
     
[1]*x[5]*y[2]+2.0*y[5]*x[7]*z[4]*z[4]-y[1]*x[2]*z[0]*z[0]+x[0]*y[3]*z[7]*z[7]   
     
-2.0*z[5]*z[5]*x[4]*y[1]+2.0*z[5]*z[5]*x[1]*y[4]+z[5]*z[5]*x[0]*y[4]-2.0*z[2]*z 
       
[2]*x[1]*y[3]+2.0*z[2]*z[2]*x[3]*y[1]-x[0]*y[4]*z[7]*z[7]-y[0]*x[3]*z[7]*z[7]+x 
       [1]*y[0]*z[5]*z[5];
+    s5 = s8+z[2]*x[6]*y[2]*z[5]-z[2]*x[5]*y[2]*z[6]-z[2]*x[2]*y[3]*z[7]-x[2]*  
      
y[3]*z[7]*z[7]+2.0*z[2]*x[2]*y[3]*z[1]-z[2]*y[2]*x[3]*z[0]+z[2]*y[2]*x[0]*z[3]- 
       
z[2]*x[2]*y[0]*z[3]-z[7]*y[2]*x[7]*z[3]+z[7]*z[2]*x[7]*y[3]+z[7]*x[2]*y[7]*z[3] 
       +z[6]*y[1]*x[2]*z[5]-z[6]*x[1]*y[2]*z[5]+z[5]*x[1]*y[5]*z[2]+s6+s7;
+    s4 = 1/s5;
+    s2 = s3*s4;
+    const double unknown2 = s1*s2;
+    return Point<3> (unknown0, unknown1, unknown2);
+}

Reply via email to