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] Improvements to tree_expr_nonnegative_p


Many thanks to Hakan Hjort for enquiring whether GCC can currently
optimize fabs(fabs(x) op fabs(y)) where op is addition, multiplication
or division.  Investigating further it transpires that it doesn't for
addition and multiplication.  It looks like tree_expr_nonnegative_p
was originally designed to primarily handle integer expressions, where
the perils of overflow means that x*y may be negative even though both
x and y are non-negative.  Floating point arithmetic on the other hand
doesn't suffer from this problem.

The following patch adds support for real constants, addition,
multiplication and squaring to tree_expr_nonnegative_p.  In the
not so far distant future, my plan is to replace all of this with
interval analysis (value range bounds)...

The following patch has been tested on i686-pc-linux-gnu with a
full "make bootstrap", all languages except treelang, and regression
tested with a top-level "make -k check" with no new failures.

Ok for mainline?


2003-06-07  Roger Sayle  <roger@eyesopen.com>

	* fold-const.c (tree_expr_nonnegative_p): Add support for
	floating point constants, addition and multiplication.

	* gcc.dg/builtins-20.c: New test case.


Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.255
diff -c -3 -p -r1.255 fold-const.c
*** fold-const.c	6 Jun 2003 12:36:22 -0000	1.255
--- fold-const.c	7 Jun 2003 14:37:40 -0000
*************** tree_expr_nonnegative_p (t)
*** 7882,7890 ****
  	 C[LT]Z_DEFINED_VALUE_AT_ZERO is set, since what we're
  	 computing here is a user-visible property.  */
        return 0;
!
      case INTEGER_CST:
        return tree_int_cst_sgn (t) >= 0;
      case TRUNC_DIV_EXPR:
      case CEIL_DIV_EXPR:
      case FLOOR_DIV_EXPR:
--- 7882,7910 ----
  	 C[LT]Z_DEFINED_VALUE_AT_ZERO is set, since what we're
  	 computing here is a user-visible property.  */
        return 0;
!
      case INTEGER_CST:
        return tree_int_cst_sgn (t) >= 0;
+
+     case REAL_CST:
+       return ! REAL_VALUE_NEGATIVE (TREE_REAL_CST (t));
+
+     case PLUS_EXPR:
+       return FLOAT_TYPE_P (TREE_TYPE (t))
+ 	     && tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
+ 	     && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
+
+     case MULT_EXPR:
+       if (FLOAT_TYPE_P (TREE_TYPE (t)))
+ 	{
+ 	  /* x * x for floating point x is always non-negative.  */
+ 	  if (operand_equal_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1), 0))
+ 	    return 1;
+ 	  return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
+ 		 && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
+ 	}
+       return 0;
+
      case TRUNC_DIV_EXPR:
      case CEIL_DIV_EXPR:
      case FLOOR_DIV_EXPR:


/* Copyright (C) 2003  Free Software Foundation.

   Verify that built-in math function constant folding doesn't
   cause any problems for the compiler.

   Written by Roger Sayle, 16th August 2002.  */

/* { dg-do compile } */
/* { dg-options "-O2 -ffast-math" } */

double test1(double x)
{
  return fabs(x*x);
}

double test2(double x)
{
  return fabs(sqrt(x)+2.0);
}

double test3(double x)
{
  return fabs(3.0*exp(x));
}

float test1f(float x)
{
  return fabsf(x*x);
}

float test2f(float x)
{
  return fabsf(sqrtf(x)+2.0f);
}

float test3f(float x)
{
  return fabsf(3.0f*expf(x));
}

long double test1l(long double x)
{
  return fabsl(x*x);
}

long double test2l(long double x)
{
  return fabsl(sqrtl(x)+2.0l);
}

long double test3l(long double x)
{
  return fabsl(3.0l*expl(x));
}


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


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