[PATCH] Fix PR69983

Richard Biener rguenther@suse.de
Mon Feb 29 15:26:00 GMT 2016


This fixes fallout of my SCEV correctness change where reassoc no longer
sees the ~A + A simplification opportunity due to casts that are in the 
way.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2016-02-29  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/69994
	* tree-ssa-reassoc.c (gimple_nop_conversion_p): New function.
	(get_unary_op): Look through nop conversions.
	(ops_equal_values_p): New function, look for equality diregarding
	nop conversions.
	(eliminate_plus_minus_pair): Use ops_equal_values_p
	(repropagate_negates): Do not use get_unary_op here.

Index: gcc/tree-ssa-reassoc.c
===================================================================
*** gcc/tree-ssa-reassoc.c	(revision 233803)
--- gcc/tree-ssa-reassoc.c	(working copy)
*************** is_reassociable_op (gimple *stmt, enum t
*** 605,610 ****
--- 605,625 ----
  }
  
  
+ /* Return true if STMT is a nop-conversion.  */
+ 
+ static bool
+ gimple_nop_conversion_p (gimple *stmt)
+ {
+   if (gassign *ass = dyn_cast <gassign *> (stmt))
+     {
+       if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (ass))
+ 	  && tree_nop_conversion_p (TREE_TYPE (gimple_assign_lhs (ass)),
+ 				    TREE_TYPE (gimple_assign_rhs1 (ass))))
+ 	return true;
+     }
+   return false;
+ }
+ 
  /* Given NAME, if NAME is defined by a unary operation OPCODE, return the
     operand of the negate operation.  Otherwise, return NULL.  */
  
*************** get_unary_op (tree name, enum tree_code
*** 613,618 ****
--- 628,638 ----
  {
    gimple *stmt = SSA_NAME_DEF_STMT (name);
  
+   /* Look through nop conversions (sign changes).  */
+   if (gimple_nop_conversion_p (stmt)
+       && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
+     stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
+ 
    if (!is_gimple_assign (stmt))
      return NULL_TREE;
  
*************** get_unary_op (tree name, enum tree_code
*** 621,626 ****
--- 641,680 ----
    return NULL_TREE;
  }
  
+ /* Return true if OP1 and OP2 have the same value if casted to either type.  */
+ 
+ static bool
+ ops_equal_values_p (tree op1, tree op2)
+ {
+   if (op1 == op2)
+     return true;
+ 
+   if (TREE_CODE (op1) == SSA_NAME)
+     {
+       gimple *stmt = SSA_NAME_DEF_STMT (op1);
+       if (gimple_nop_conversion_p (stmt))
+ 	{
+ 	  op1 = gimple_assign_rhs1 (stmt);
+ 	  if (op1 == op2)
+ 	    return true;
+ 	}
+     }
+ 
+   if (TREE_CODE (op2) == SSA_NAME)
+     {
+       gimple *stmt = SSA_NAME_DEF_STMT (op2);
+       if (gimple_nop_conversion_p (stmt))
+ 	{
+ 	  op2 = gimple_assign_rhs1 (stmt);
+ 	  if (op1 == op2)
+ 	    return true;
+ 	}
+     }
+ 
+   return false;
+ }
+ 
+ 
  /* If CURR and LAST are a pair of ops that OPCODE allows us to
     eliminate through equivalences, do so, remove them from OPS, and
     return true.  Otherwise, return false.  */
*************** eliminate_plus_minus_pair (enum tree_cod
*** 731,739 ****
         && oe->rank >= curr->rank - 1 ;
         i++)
      {
!       if (oe->op == negateop)
  	{
- 
  	  if (dump_file && (dump_flags & TDF_DETAILS))
  	    {
  	      fprintf (dump_file, "Equivalence: ");
--- 785,793 ----
         && oe->rank >= curr->rank - 1 ;
         i++)
      {
!       if (negateop
! 	  && ops_equal_values_p (oe->op, negateop))
  	{
  	  if (dump_file && (dump_flags & TDF_DETAILS))
  	    {
  	      fprintf (dump_file, "Equivalence: ");
*************** eliminate_plus_minus_pair (enum tree_cod
*** 750,756 ****
  
  	  return true;
  	}
!       else if (oe->op == notop)
  	{
  	  tree op_type = TREE_TYPE (oe->op);
  
--- 804,811 ----
  
  	  return true;
  	}
!       else if (notop
! 	       && ops_equal_values_p (oe->op, notop))
  	{
  	  tree op_type = TREE_TYPE (oe->op);
  
*************** eliminate_plus_minus_pair (enum tree_cod
*** 772,780 ****
  	}
      }
  
!   /* CURR->OP is a negate expr in a plus expr: save it for later
!      inspection in repropagate_negates().  */
!   if (negateop != NULL_TREE)
      plus_negates.safe_push (curr->op);
  
    return false;
--- 827,836 ----
  	}
      }
  
!   /* If CURR->OP is a negate expr without nop conversion in a plus expr:
!      save it for later inspection in repropagate_negates().  */
!   if (negateop != NULL_TREE
!       && gimple_assign_rhs_code (SSA_NAME_DEF_STMT (curr->op)) == NEGATE_EXPR)
      plus_negates.safe_push (curr->op);
  
    return false;
*************** repropagate_negates (void)
*** 4211,4217 ****
  	  if (gimple_assign_rhs2 (user) == negate)
  	    {
  	      tree rhs1 = gimple_assign_rhs1 (user);
! 	      tree rhs2 = get_unary_op (negate, NEGATE_EXPR);
  	      gimple_stmt_iterator gsi = gsi_for_stmt (user);
  	      gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, rhs1, rhs2);
  	      update_stmt (user);
--- 4267,4273 ----
  	  if (gimple_assign_rhs2 (user) == negate)
  	    {
  	      tree rhs1 = gimple_assign_rhs1 (user);
! 	      tree rhs2 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (negate));
  	      gimple_stmt_iterator gsi = gsi_for_stmt (user);
  	      gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, rhs1, rhs2);
  	      update_stmt (user);



More information about the Gcc-patches mailing list