public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix PR69983
@ 2016-03-01 13:34 Richard Biener
  0 siblings, 0 replies; 4+ messages in thread
From: Richard Biener @ 2016-03-01 13:34 UTC (permalink / raw)
  To: gcc-patches


I am testing the following patch to fix PR69983 - SCEV was confused
by a PRE inserted PHI node where it checks for equality of the
evolution of all edges.  After my SCEV fix these have conversions
which are not handled by eq_evolutions_p.

I've noticed the function misses any type compatibility check
and operand_equal_p on INTEGER_CSTs will ignore types.

Also it will give up on SSA names or ADDR_EXPRs which can
occur in both the evolution and init part of SCEVs.  So simply
fall back to operand_equal_p for all bits where we don't expect
any further embeded CHRECs (operand_equal_p does no handle
TREE_CHREC currently).

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2016-03-01  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/69983
	* tree-chrec.c (eq_evolutions_p): Handle conversions, compare
	types and fall back to operand_equal_p.

Index: gcc/tree-chrec.c
===================================================================
*** gcc/tree-chrec.c	(revision 233840)
--- gcc/tree-chrec.c	(working copy)
*************** eq_evolutions_p (const_tree chrec0, cons
*** 1468,1478 ****
    if (chrec0 == chrec1)
      return true;
  
    switch (TREE_CODE (chrec0))
      {
-     case INTEGER_CST:
-       return operand_equal_p (chrec0, chrec1, 0);
- 
      case POLYNOMIAL_CHREC:
        return (CHREC_VARIABLE (chrec0) == CHREC_VARIABLE (chrec1)
  	      && eq_evolutions_p (CHREC_LEFT (chrec0), CHREC_LEFT (chrec1))
--- 1468,1478 ----
    if (chrec0 == chrec1)
      return true;
  
+   if (! types_compatible_p (TREE_TYPE (chrec0), TREE_TYPE (chrec1)))
+     return false;
+ 
    switch (TREE_CODE (chrec0))
      {
      case POLYNOMIAL_CHREC:
        return (CHREC_VARIABLE (chrec0) == CHREC_VARIABLE (chrec1)
  	      && eq_evolutions_p (CHREC_LEFT (chrec0), CHREC_LEFT (chrec1))
*************** eq_evolutions_p (const_tree chrec0, cons
*** 1487,1494 ****
  	  && eq_evolutions_p (TREE_OPERAND (chrec0, 1),
  			      TREE_OPERAND (chrec1, 1));
  
      default:
!       return false;
      }
  }
  
--- 1487,1498 ----
  	  && eq_evolutions_p (TREE_OPERAND (chrec0, 1),
  			      TREE_OPERAND (chrec1, 1));
  
+     CASE_CONVERT:
+       return eq_evolutions_p (TREE_OPERAND (chrec0, 0),
+ 			      TREE_OPERAND (chrec1, 0));
+ 
      default:
!       return operand_equal_p (chrec0, chrec1, 0);
      }
  }
  

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Fix PR69983
  2016-02-29 15:45 ` Jakub Jelinek
@ 2016-03-01  8:31   ` Richard Biener
  0 siblings, 0 replies; 4+ messages in thread
From: Richard Biener @ 2016-03-01  8:31 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches

On Mon, 29 Feb 2016, Jakub Jelinek wrote:

> On Mon, Feb 29, 2016 at 04:26:12PM +0100, Richard Biener wrote:
> > *************** 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;
> > + 	}
> > +     }
> 
> This will not work if you have:
>   x_1 = (nop) x_0;
>   x_2 = (nop) x_1;
> and op1 is x_1 and op2 is x_2 (but will work
> if op1 is x_2 and op1 is x_1).

Hmm, I expected CSE / nop combining to always simplify the above
but yes, given we want to catch IVOPTs introduced expressions here
and no CSE / forwprop between it and the reassoc it makes sense
to catch that as well.

> Wouldn't it be better to also remember the original
> tree orig_op1 = op1;
> at the beginning and in the last comparison do
> if (op1 == op2 || orig_op1 == op2)
> ?

Will do as followup now.

Thanks,
Richard.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Fix PR69983
  2016-02-29 15:26 Richard Biener
@ 2016-02-29 15:45 ` Jakub Jelinek
  2016-03-01  8:31   ` Richard Biener
  0 siblings, 1 reply; 4+ messages in thread
From: Jakub Jelinek @ 2016-02-29 15:45 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

On Mon, Feb 29, 2016 at 04:26:12PM +0100, Richard Biener wrote:
> *************** 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;
> + 	}
> +     }

This will not work if you have:
  x_1 = (nop) x_0;
  x_2 = (nop) x_1;
and op1 is x_1 and op2 is x_2 (but will work
if op1 is x_2 and op1 is x_1).
Wouldn't it be better to also remember the original
tree orig_op1 = op1;
at the beginning and in the last comparison do
if (op1 == op2 || orig_op1 == op2)
?

	Jakub

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] Fix PR69983
@ 2016-02-29 15:26 Richard Biener
  2016-02-29 15:45 ` Jakub Jelinek
  0 siblings, 1 reply; 4+ messages in thread
From: Richard Biener @ 2016-02-29 15:26 UTC (permalink / raw)
  To: gcc-patches


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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-03-01 13:34 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-01 13:34 [PATCH] Fix PR69983 Richard Biener
  -- strict thread matches above, loose matches on Subject: below --
2016-02-29 15:26 Richard Biener
2016-02-29 15:45 ` Jakub Jelinek
2016-03-01  8:31   ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).