This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][no-undefined-overflow] Adjust negate_expr_p and friends


This tries to deal with *NV_EXPRs in negate_expr_p and friends.  I noticed

/* Determine whether an expression T can be cheaply negated using
   the function negate_expr without introducing undefined overflow.  */

and it indeed would be nice to have negate_expr_p return a consistent
tri-state - whether the negation does not overflow, whether the negation
is cheap or if non of this is true.  That would help to make foldings
involving negation preserve non-overflowness if possible.

-> That's now an entry on the TODO list in the wiki.

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

Richard.

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

	* fold-const.c (may_negate_without_overflow_p): Unsigned zero
	can be negated without overflow.
	(negate_expr_p): Handle *NV_EXPR.
	(fold_negate_expr): Likewise.
	(fold_binary): Avoid loosing non-overflow flag during
	A - B -> A + (-B) folding with constant B.

Index: no-undefined-overflow/gcc/fold-const.c
===================================================================
*** no-undefined-overflow.orig/gcc/fold-const.c	2009-03-10 17:59:58.000000000 +0100
--- no-undefined-overflow/gcc/fold-const.c	2009-03-12 10:48:54.000000000 +0100
*************** may_negate_without_overflow_p (const_tre
*** 1091,1097 ****
  
    type = TREE_TYPE (t);
    if (TYPE_UNSIGNED (type))
!     return false;
  
    prec = TYPE_PRECISION (type);
    if (prec > HOST_BITS_PER_WIDE_INT)
--- 1091,1097 ----
  
    type = TREE_TYPE (t);
    if (TYPE_UNSIGNED (type))
!     return integer_zerop (t);
  
    prec = TYPE_PRECISION (type);
    if (prec > HOST_BITS_PER_WIDE_INT)
*************** negate_expr_p (tree t)
*** 1135,1140 ****
--- 1135,1141 ----
      case FIXED_CST:
      case REAL_CST:
      case NEGATE_EXPR:
+     case NEGATENV_EXPR:
        return true;
  
      case COMPLEX_CST:
*************** negate_expr_p (tree t)
*** 1149,1154 ****
--- 1150,1156 ----
        return negate_expr_p (TREE_OPERAND (t, 0));
  
      case PLUS_EXPR:
+     case PLUSNV_EXPR:
        if (HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type))
  	  || HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
  	return false;
*************** negate_expr_p (tree t)
*** 1161,1166 ****
--- 1163,1169 ----
        return negate_expr_p (TREE_OPERAND (t, 0));
  
      case MINUS_EXPR:
+     case MINUSNV_EXPR:
        /* We can't turn -(A-B) into B-A when we honor signed zeros.  */
        return !HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type))
  	     && !HONOR_SIGNED_ZEROS (TYPE_MODE (type))
*************** negate_expr_p (tree t)
*** 1168,1173 ****
--- 1171,1177 ----
  				    TREE_OPERAND (t, 1));
  
      case MULT_EXPR:
+     case MULTNV_EXPR:
        if (TYPE_UNSIGNED (TREE_TYPE (t)))
          break;
  
*************** negate_expr_p (tree t)
*** 1192,1198 ****
        return negate_expr_p (TREE_OPERAND (t, 1))
               || negate_expr_p (TREE_OPERAND (t, 0));
  
!     case NOP_EXPR:
        /* Negate -((double)float) as (double)(-float).  */
        if (TREE_CODE (type) == REAL_TYPE)
  	{
--- 1196,1202 ----
        return negate_expr_p (TREE_OPERAND (t, 1))
               || negate_expr_p (TREE_OPERAND (t, 0));
  
!     CASE_CONVERT:
        /* Negate -((double)float) as (double)(-float).  */
        if (TREE_CODE (type) == REAL_TYPE)
  	{
*************** fold_negate_expr (tree t)
*** 1295,1300 ****
--- 1299,1305 ----
        return TREE_OPERAND (t, 0);
  
      case PLUS_EXPR:
+     case PLUSNV_EXPR:
        if (!HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type))
  	  && !HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
  	{
*************** fold_negate_expr (tree t)
*** 1319,1324 ****
--- 1324,1330 ----
        break;
  
      case MINUS_EXPR:
+     case MINUSNV_EXPR:
        /* - (A - B) -> B - A  */
        if (!HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type))
  	  && !HONOR_SIGNED_ZEROS (TYPE_MODE (type))
*************** fold_negate_expr (tree t)
*** 1328,1333 ****
--- 1334,1340 ----
        break;
  
      case MULT_EXPR:
+     case MULTNV_EXPR:
        if (TYPE_UNSIGNED (type))
          break;
  
*************** fold_negate_expr (tree t)
*** 1368,1374 ****
          }
        break;
  
!     case NOP_EXPR:
        /* Convert -((double)float) into (double)(-float).  */
        if (TREE_CODE (type) == REAL_TYPE)
  	{
--- 1375,1381 ----
          }
        break;
  
!     CASE_CONVERT:
        /* Convert -((double)float) into (double)(-float).  */
        if (TREE_CODE (type) == REAL_TYPE)
  	{
*************** fold_binary (enum tree_code code, tree t
*** 10478,10492 ****
  	return fold_convert (type, integer_zero_node);
  
        /* A - B -> A + (-B) if B is easily negatable.  */
!       if (negate_expr_p (arg1)
  	  && ((FLOAT_TYPE_P (type)
                 /* Avoid this transformation if B is a positive REAL_CST.  */
  	       && (TREE_CODE (arg1) != REAL_CST
  		   ||  REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1))))
  	      || INTEGRAL_TYPE_P (type)))
! 	return fold_build2 (PLUS_EXPR, type,
! 			    fold_convert (type, arg0),
! 			    fold_convert (type, negate_expr (arg1)));
  
        /* Try folding difference of addresses.  */
        {
--- 10485,10514 ----
  	return fold_convert (type, integer_zero_node);
  
        /* A - B -> A + (-B) if B is easily negatable.  */
!       if ((negate_expr_p (arg1)
! 	   /* Avoid negating constants if that would change overflow
! 	      behavior.  */
! 	   && (code == MINUS_EXPR
! 	       || TREE_CODE (arg1) != INTEGER_CST
! 	       || may_negate_without_overflow_p (arg1)))
  	  && ((FLOAT_TYPE_P (type)
                 /* Avoid this transformation if B is a positive REAL_CST.  */
  	       && (TREE_CODE (arg1) != REAL_CST
  		   ||  REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1))))
  	      || INTEGRAL_TYPE_P (type)))
! 	{
! 	  enum tree_code ncode = PLUS_EXPR;
! 	  /* If the original subtraction is signed and did not overflow
! 	     so does the new addition if the negation of arg1 does not
! 	     overflow (which we know for constants only).  */
! 	  if (code == MINUSNV_EXPR
! 	      && TREE_CODE (arg1) == INTEGER_CST
! 	      && !TYPE_UNSIGNED (type))
! 	    ncode = PLUSNV_EXPR;
! 	  return fold_build2 (ncode, type,
! 			      fold_convert (type, arg0),
! 			      fold_convert (type, negate_expr (arg1)));
! 	}
  
        /* Try folding difference of addresses.  */
        {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]