aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJames A. Morrison <phython@gcc.gnu.org>2005-07-20 03:30:58 +0000
committerJames A. Morrison <phython@gcc.gnu.org>2005-07-20 03:30:58 +0000
commit1ade5842af034a0f4e9d606b17ee3ea64375d78a (patch)
tree1deede4acfc6d0df887b5c1c33abf9c83e1ea611 /gcc
parent4038c495fc9685efdb400b36848627daab979e78 (diff)
downloadgcc-1ade5842af034a0f4e9d606b17ee3ea64375d78a.zip
gcc-1ade5842af034a0f4e9d606b17ee3ea64375d78a.tar.gz
gcc-1ade5842af034a0f4e9d606b17ee3ea64375d78a.tar.bz2
fold-const.c (tree_expr_nonnegative_p): Only return true for ABS_EXPR when flag_wrapv is false because of INT_MIN.
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>. From-SVN: r102184
Diffstat (limited to 'gcc')
-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 88073eb..f37b254 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 273a912..e9d88d1 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 5d69c6f..043d512 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 0000000..2e69a20
--- /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 0000000..6291d7e
--- /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 0000000..d151a8d
--- /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" } } */