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]

Fold ABS_EXPR < 0, pr14303/pr15784


 Hi,

   This patch adds some more folding.  It was bootstrapped and tested by
Steven on  {i686,x86_64,ia64,ppc,ppc64}-suse-linux-gnu, I can also confirm
that it bootstraps and passes the attached tests on sparc64-linux.

 Ok for mainline?

-- 
Thanks,
Jim

http://www.student.cs.uwaterloo.ca/~ja2morri/
http://phython.blogspot.com
http://open.nit.ca/wiki/?page=jim

2005-02-11  James A. Morrison  <phython@gcc.gnu.org>

	PR tree-optimization/14303
	PR tree-optimization/15784
	* fold-const.c (fold): Fold ABS_EXPR<x> >= 0 to true, when possible.
	Fold ABS_EXPR<x> < 0 to false.  Fold ABS_EXPR<x> == 0 to x == 0 and
	ABS_EXPR<x> != 0 to x != 0.

Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.504
diff -u -p -r1.504 fold-const.c
--- fold-const.c	9 Feb 2005 21:56:18 -0000	1.504
+++ fold-const.c	11 Feb 2005 05:10:14 -0000
@@ -8777,6 +8777,29 @@ fold (tree expr)
 			     build2 (LE_EXPR, type,
 				     TREE_OPERAND (arg0, 0), arg1)));
 
+      /* Convert ABS_EXPR<x> >= 0 to true.  */
+      else if (code == GE_EXPR
+	       && tree_expr_nonnegative_p (arg0)
+	       && ! TREE_SIDE_EFFECTS (arg0)
+	       && (integer_zerop (arg1)
+		   || (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
+                       && real_zerop (arg1))))
+	return constant_boolean_node (true, type);
+
+      /* Convert ABS_EXPR<x> < 0 to false.  */
+      else if (code == LT_EXPR
+	       && tree_expr_nonnegative_p (arg0)
+	       && ! TREE_SIDE_EFFECTS (arg0)
+	       && (integer_zerop (arg1) || real_zerop (arg1)))
+	return constant_boolean_node (false, type);
+
+      /* Convert ABS_EXPR<x> == 0 or ABS_EXPR<x> != 0 to x == 0 or x != 0.  */
+      else if ((code == EQ_EXPR || code == NE_EXPR)
+	       && TREE_CODE (arg0) == ABS_EXPR
+	       && ! TREE_SIDE_EFFECTS (arg0)
+	       && (integer_zerop (arg1) || real_zerop (arg1)))
+	return fold (build2 (code, type, TREE_OPERAND (arg0, 0), arg1));
+
       /* If this is an EQ or NE comparison with zero and ARG0 is
 	 (1 << foo) & bar, convert it to (bar >> foo) & 1.  Both require
 	 two operations, but the latter can be done in one less insn
/* { dg-do compile } */
/* { dg-options "-fdump-tree-generic" } */
/* Test for folding abs(x) where appropriate.  */
#define abs(x) x > 0 ? x : -x
extern double fabs (double);

int a (int x) {
	return (abs(x)) >= 0;
}

int b (int x) {
	return (abs(x)) == 0;
}

int c (int x) {
	return (abs(x)) != 0;
}

int d (int x) {
	return 0 != (abs(x));
}

int e (int x) {
	return 0 == (abs(x));
}

int f (int x) {
	return 0 <= (abs(x));
}

int g (int x) {
	return 0 > (abs(x));
}

int h (float x) {
	return 0.0 > fabs(x);
}

int i (float x) {
	return fabs(x) == -0.0;
}
/* { dg-final { scan-tree-dump-times "ABS_EXPR" 0 "generic" } } */
/* { dg-do compile } */
/* { dg-options "-fdump-tree-generic -ffast-math" } */
/* Test for folding abs(x) where appropriate.  */
#define abs(x) x > 0 ? x : -x
extern double fabs (double);

int a (float x) {
	return fabs(x) >= 0.0;
}

/* { dg-final { scan-tree-dump-times "ABS_EXPR" 0 "generic" } } */
/* { dg-do compile } */
/* { dg-options "-fdump-tree-generic" } */
/* Test for folding abs(x) where appropriate.  */
#define abs(x) x > 0 ? x : -x
extern double fabs (double);

int a (float x) {
	return fabs(x) >= 0.0;
}

/* { dg-final { scan-tree-dump-times "ABS_EXPR" 1 "generic" } } */

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