This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fold ABS_EXPR < 0, pr14303/pr15784
- From: ja2morri at csclub dot uwaterloo dot ca (James A. Morrison)
- To: gcc-patches at gcc dot gnu dot org
- Date: 12 Feb 2005 21:34:50 -0500
- Subject: 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" } } */