[PATCH][no-undefined-overflow] More comparison folding

Richard Guenther rguenther@suse.de
Tue Mar 10 16:59:00 GMT 2009


This re-enables &a + o <=> &b + o folding for NV variants.  It also
adds POINTER_PLUSNV_EXPR to strip_nv (whoops) and adjusts DOM to
value-number NV and non-NV variants the same (DOM doesn't do insertions,
so this is safe).

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

Richard.

2009-03-10  Richard Guenther  <rguenther@suse.de>

	* fold-const.c (fold_comparison): Adjust address comparison
	folding.
	* tree.h (strip_nv): Also strip POINTER_PLUSNV_EXPR.
	* tree-ssa-dom.c (initialize_hash_element): Treat *NV_EXPR the
	same as non-NV_EXPR variants for value-numbering.
	(simple_iv_increment_p): Handle *NV_EXPR.

Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	2009-03-10 14:48:39.000000000 +0100
--- gcc/fold-const.c	2009-03-10 16:58:33.000000000 +0100
*************** fold_comparison (enum tree_code code, tr
*** 8946,8959 ****
    if (POINTER_TYPE_P (TREE_TYPE (arg0))
        && (TREE_CODE (arg0) == ADDR_EXPR
  	  || TREE_CODE (arg1) == ADDR_EXPR
! 	  || TREE_CODE (arg0) == POINTER_PLUS_EXPR
! 	  || TREE_CODE (arg1) == POINTER_PLUS_EXPR))
      {
        tree base0, base1, offset0 = NULL_TREE, offset1 = NULL_TREE;
        HOST_WIDE_INT bitsize, bitpos0 = 0, bitpos1 = 0;
        enum machine_mode mode;
        int volatilep, unsignedp;
        bool indirect_base0 = false, indirect_base1 = false;
  
        /* Get base and offset for the access.  Strip ADDR_EXPR for
  	 get_inner_reference, but put it back by stripping INDIRECT_REF
--- 8946,8960 ----
    if (POINTER_TYPE_P (TREE_TYPE (arg0))
        && (TREE_CODE (arg0) == ADDR_EXPR
  	  || TREE_CODE (arg1) == ADDR_EXPR
! 	  || POINTER_PLUS_EXPR_P (arg0)
! 	  || POINTER_PLUS_EXPR_P (arg1)))
      {
        tree base0, base1, offset0 = NULL_TREE, offset1 = NULL_TREE;
        HOST_WIDE_INT bitsize, bitpos0 = 0, bitpos1 = 0;
        enum machine_mode mode;
        int volatilep, unsignedp;
        bool indirect_base0 = false, indirect_base1 = false;
+       bool no_overflow = true;
  
        /* Get base and offset for the access.  Strip ADDR_EXPR for
  	 get_inner_reference, but put it back by stripping INDIRECT_REF
*************** fold_comparison (enum tree_code code, tr
*** 8970,8977 ****
  	  else
  	    indirect_base0 = true;
  	}
!       else if (TREE_CODE (arg0) == POINTER_PLUS_EXPR)
  	{
  	  base0 = TREE_OPERAND (arg0, 0);
  	  offset0 = TREE_OPERAND (arg0, 1);
  	}
--- 8971,8980 ----
  	  else
  	    indirect_base0 = true;
  	}
!       else if (POINTER_PLUS_EXPR_P (arg0))
  	{
+ 	  if (TREE_CODE (arg0) == POINTER_PLUS_EXPR)
+ 	    no_overflow = false;
  	  base0 = TREE_OPERAND (arg0, 0);
  	  offset0 = TREE_OPERAND (arg0, 1);
  	}
*************** fold_comparison (enum tree_code code, tr
*** 8987,8994 ****
  	  else
  	    indirect_base1 = true;
  	}
!       else if (TREE_CODE (arg1) == POINTER_PLUS_EXPR)
  	{
  	  base1 = TREE_OPERAND (arg1, 0);
  	  offset1 = TREE_OPERAND (arg1, 1);
  	}
--- 8990,8999 ----
  	  else
  	    indirect_base1 = true;
  	}
!       else if (POINTER_PLUS_EXPR_P (arg1))
  	{
+ 	  if (TREE_CODE (arg1) == POINTER_PLUS_EXPR)
+ 	    no_overflow = false;
  	  base1 = TREE_OPERAND (arg1, 0);
  	  offset1 = TREE_OPERAND (arg1, 1);
  	}
*************** fold_comparison (enum tree_code code, tr
*** 9004,9011 ****
  		   && operand_equal_p (offset0, offset1, 0)))
  	      && (code == EQ_EXPR
  		  || code == NE_EXPR
! 		  || POINTER_TYPE_OVERFLOW_UNDEFINED))
! 		
  	    {
  	      if (code != EQ_EXPR
  		  && code != NE_EXPR
--- 9009,9015 ----
  		   && operand_equal_p (offset0, offset1, 0)))
  	      && (code == EQ_EXPR
  		  || code == NE_EXPR
! 		  || no_overflow))
  	    {
  	      if (code != EQ_EXPR
  		  && code != NE_EXPR
*************** fold_comparison (enum tree_code code, tr
*** 9043,9049 ****
  	     6.5.6/8 and /9 with respect to the signed ptrdiff_t.  */
  	  else if (bitpos0 == bitpos1
  		   && ((code == EQ_EXPR || code == NE_EXPR)
! 		       || POINTER_TYPE_OVERFLOW_UNDEFINED))
  	    {
  	      tree signed_size_type_node;
  	      signed_size_type_node = signed_type_for (size_type_node);
--- 9047,9053 ----
  	     6.5.6/8 and /9 with respect to the signed ptrdiff_t.  */
  	  else if (bitpos0 == bitpos1
  		   && ((code == EQ_EXPR || code == NE_EXPR)
! 		       || no_overflow))
  	    {
  	      tree signed_size_type_node;
  	      signed_size_type_node = signed_type_for (size_type_node);
Index: gcc/tree.h
===================================================================
*** gcc/tree.h	(revision 144722)
--- gcc/tree.h	(working copy)
*************** strip_nv (enum tree_code code)
*** 207,212 ****
--- 207,214 ----
      {
      case NEGATENV_EXPR:
        return NEGATE_EXPR;
+     case POINTER_PLUSNV_EXPR:
+       return POINTER_PLUS_EXPR;
      case PLUSNV_EXPR:
        return PLUS_EXPR;
      case MINUSNV_EXPR:
Index: gcc/tree-ssa-dom.c
===================================================================
*** gcc/tree-ssa-dom.c	(revision 144676)
--- gcc/tree-ssa-dom.c	(working copy)
*************** initialize_hash_element (gimple stmt, tr
*** 223,229 ****
  
    if (code == GIMPLE_ASSIGN)
      {
!       enum tree_code subcode = gimple_assign_rhs_code (stmt);
  
        expr->type = NULL_TREE;
        
--- 223,229 ----
  
    if (code == GIMPLE_ASSIGN)
      {
!       enum tree_code subcode = strip_nv (gimple_assign_rhs_code (stmt));
  
        expr->type = NULL_TREE;
        
*************** simple_iv_increment_p (gimple stmt)
*** 1567,1574 ****
    if (TREE_CODE (lhs) != SSA_NAME)
      return false;
  
!   if (gimple_assign_rhs_code (stmt) != PLUS_EXPR
!       && gimple_assign_rhs_code (stmt) != MINUS_EXPR)
      return false;
  
    preinc = gimple_assign_rhs1 (stmt);
--- 1567,1574 ----
    if (TREE_CODE (lhs) != SSA_NAME)
      return false;
  
!   if (!PLUS_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
!       && !MINUS_EXPR_CODE_P (gimple_assign_rhs_code (stmt)))
      return false;
  
    preinc = gimple_assign_rhs1 (stmt);



More information about the Gcc-patches mailing list