summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorphython <phython@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-20 03:30:58 +0000
committerphython <phython@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-20 03:30:58 +0000
commit8040d1c5b709efbb7114f788e44b4099cb9a8190 (patch)
tree1deede4acfc6d0df887b5c1c33abf9c83e1ea611
parentc75b4594282e6b33803b8332acba704d057f8d97 (diff)
downloadgcc-8040d1c5b709efbb7114f788e44b4099cb9a8190.tar.gz
2005-07-19 James A. Morrison <phython@gcc.gnu.org>
* fold-const.c (tree_expr_nonnegative_p): Only return true for ABS_EXPR when flag_wrapv is false because of INT_MIN. (tree_expr_nonzero_p): Always call tree_expr_nonzero_p on the argument of an ABS_EXPR. (fold_unary): Always fold ABS_EXPR<ABS_EXPR<x>> into ABS_EXPR<x>. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102184 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/fold-const.c12
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/fold-abs-1.c7
-rw-r--r--gcc/testsuite/gcc.dg/fold-abs-2.c17
-rw-r--r--gcc/testsuite/gcc.dg/fold-abs-3.c9
6 files changed, 56 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 88073eb9e1a..f37b254fcae 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2005-07-19 James A. Morrison <phython@gcc.gnu.org>
+
+ * fold-const.c (tree_expr_nonnegative_p): Only return true for
+ ABS_EXPR when flag_wrapv is false because of INT_MIN.
+ (tree_expr_nonzero_p): Always call tree_expr_nonzero_p on the argument
+ of an ABS_EXPR.
+ (fold_unary): Always fold ABS_EXPR<ABS_EXPR<x>> into
+ ABS_EXPR<x>.
+
2005-07-20 Giovanni Bajo <giovannibajo@libero.it>
Make CONSTRUCTOR use VEC to store initializers.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 273a912d4e4..e9d88d1e6c3 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -6827,7 +6827,8 @@ fold_unary (enum tree_code code, tree type, tree op0)
TREE_TYPE (targ0),
targ0));
}
- else if (tree_expr_nonnegative_p (arg0))
+ /* ABS_EXPR<ABS_EXPR<x>> = ABS_EXPR<x> even if flag_wrapv is on. */
+ else if (tree_expr_nonnegative_p (arg0) || TREE_CODE (arg0) == ABS_EXPR)
return arg0;
/* Strip sign ops from argument. */
@@ -10527,7 +10528,11 @@ tree_expr_nonnegative_p (tree t)
switch (TREE_CODE (t))
{
case ABS_EXPR:
- return 1;
+ /* We can't return 1 if flag_wrapv is set because
+ ABS_EXPR<INT_MIN> = INT_MIN. */
+ if (!flag_wrapv)
+ return 1;
+ break;
case INTEGER_CST:
return tree_int_cst_sgn (t) >= 0;
@@ -10804,8 +10809,7 @@ tree_expr_nonzero_p (tree t)
switch (TREE_CODE (t))
{
case ABS_EXPR:
- if (!TYPE_UNSIGNED (type) && !flag_wrapv)
- return tree_expr_nonzero_p (TREE_OPERAND (t, 0));
+ return tree_expr_nonzero_p (TREE_OPERAND (t, 0));
case INTEGER_CST:
/* We used to test for !integer_zerop here. This does not work correctly
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5d69c6faca4..043d5128019 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2005-07-19 James A. Morrison <phython@gcc.gnu.org>
+
+ * gcc.dg/fold-abs-1.c: New test.
+ * gcc.dg/fold-abs-2.c: New test.
+ * gcc.dg/fold-abs-3.c: New test.
+
2005-07-20 Giovanni Bajo <giovannibajo@libero.it>
Make CONSTRUCTOR use VEC to store initializers.
diff --git a/gcc/testsuite/gcc.dg/fold-abs-1.c b/gcc/testsuite/gcc.dg/fold-abs-1.c
new file mode 100644
index 00000000000..2e69a207577
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-abs-1.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fwrapv" } */
+#define ABS(x) (x > 0 ? x : -x)
+int f (int a, int b) {
+ if ((ABS(a) | b) != 0) return 1;
+ else return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/fold-abs-2.c b/gcc/testsuite/gcc.dg/fold-abs-2.c
new file mode 100644
index 00000000000..6291d7e5384
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-abs-2.c
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-options "-O1 -fwrapv" } */
+#include <limits.h>
+void exit (int);
+void abort ();
+#define ABS(x) (x > 0 ? x : -x)
+int f (int a) {
+ if (ABS(a) >= 0) return 1;
+ else return 0;
+}
+
+int main (int argc, char *argv[]) {
+ if (f(INT_MIN))
+ abort ();
+ else
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/fold-abs-3.c b/gcc/testsuite/gcc.dg/fold-abs-3.c
new file mode 100644
index 00000000000..d151a8d7aec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-abs-3.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-gimple -fwrapv" } */
+#define ABS(x) (x > 0 ? x : -x)
+int f (int a) {
+ return ABS (ABS(a));
+}
+
+/* { dg-final { scan-tree-dump-times "ABS" 1 "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */