From 89a6fcda688b6ac8df4d0a70e448556b88758582 Mon Sep 17 00:00:00 2001 From: phython Date: Mon, 18 Apr 2005 15:18:21 +0000 Subject: [PATCH] 2005-04-18 James A. Morrison PR tree-optimization/20922 * fold-const.c (fold_binary): Fold X - c > X and X + c < X to false. Fold X + c >= X and fold X - c <= X to true. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@98321 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++ gcc/fold-const.c | 71 ++++++++++++++++++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 10 ++++++ gcc/testsuite/gcc.dg/pr20922-1.c | 38 +++++++++++++++++++++ gcc/testsuite/gcc.dg/pr20922-2.c | 18 ++++++++++ gcc/testsuite/gcc.dg/pr20922-3.c | 33 +++++++++++++++++++ gcc/testsuite/gcc.dg/pr20922-4.c | 38 +++++++++++++++++++++ gcc/testsuite/gcc.dg/pr20922-5.c | 23 +++++++++++++ gcc/testsuite/gcc.dg/pr20922-6.c | 33 +++++++++++++++++++ 9 files changed, 270 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr20922-1.c create mode 100644 gcc/testsuite/gcc.dg/pr20922-2.c create mode 100644 gcc/testsuite/gcc.dg/pr20922-3.c create mode 100644 gcc/testsuite/gcc.dg/pr20922-4.c create mode 100644 gcc/testsuite/gcc.dg/pr20922-5.c create mode 100644 gcc/testsuite/gcc.dg/pr20922-6.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 706e324..f1e108d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2005-04-18 James A. Morrison + PR tree-optimization/20922 + * fold-const.c (fold_binary): Fold X - c > X and X + c < X to false. + Fold X + c >= X and fold X - c <= X to true. + +2005-04-18 James A. Morrison + * config/ia64/unwind-ia64.c (emergency_reg_state_free): Make an unsigned int. (emergency_labeled_state_free): Likewise. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 3899fda..1e1ecc1 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -8848,6 +8848,77 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) } } + /* Transform comparisons of the form X +- C CMP X. */ + if ((code != EQ_EXPR && code != NE_EXPR) + && (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR) + && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0) + && ((TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST + && !HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))) + || (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST + && !TYPE_UNSIGNED (TREE_TYPE (arg1)) + && !(flag_wrapv || flag_trapv)))) + { + tree arg01 = TREE_OPERAND (arg0, 1); + enum tree_code code0 = TREE_CODE (arg0); + int is_positive; + + if (TREE_CODE (arg01) == REAL_CST) + is_positive = REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg01)) ? -1 : 1; + else + is_positive = tree_int_cst_sgn (arg01); + + /* (X - c) > X becomes false. */ + if (code == GT_EXPR + && ((code0 == MINUS_EXPR && is_positive >= 0) + || (code0 == PLUS_EXPR && is_positive <= 0))) + return constant_boolean_node (0, type); + + /* Likewise (X + c) < X becomes false. */ + if (code == LT_EXPR + && ((code0 == PLUS_EXPR && is_positive >= 0) + || (code0 == MINUS_EXPR && is_positive <= 0))) + return constant_boolean_node (0, type); + + /* Convert (X - c) <= X to true. */ + if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))) + && code == LE_EXPR + && ((code0 == MINUS_EXPR && is_positive >= 0) + || (code0 == PLUS_EXPR && is_positive <= 0))) + return constant_boolean_node (1, type); + + /* Convert (X + c) >= X to true. */ + if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))) + && code == GE_EXPR + && ((code0 == PLUS_EXPR && is_positive >= 0) + || (code0 == MINUS_EXPR && is_positive <= 0))) + return constant_boolean_node (1, type); + + if (TREE_CODE (arg01) == INTEGER_CST) + { + /* Convert X + c > X and X - c < X to true for integers. */ + if (code == GT_EXPR + && ((code0 == PLUS_EXPR && is_positive > 0) + || (code0 == MINUS_EXPR && is_positive < 0))) + return constant_boolean_node (1, type); + + if (code == LT_EXPR + && ((code0 == MINUS_EXPR && is_positive > 0) + || (code0 == PLUS_EXPR && is_positive < 0))) + return constant_boolean_node (1, type); + + /* Convert X + c <= X and X - c >= X to false for integers. */ + if (code == LE_EXPR + && ((code0 == PLUS_EXPR && is_positive > 0) + || (code0 == MINUS_EXPR && is_positive < 0))) + return constant_boolean_node (0, type); + + if (code == GE_EXPR + && ((code0 == MINUS_EXPR && is_positive > 0) + || (code0 == PLUS_EXPR && is_positive < 0))) + return constant_boolean_node (0, type); + } + } + if (FLOAT_TYPE_P (TREE_TYPE (arg0))) { tree targ0 = strip_float_extensions (arg0); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1dd0db7..81e1aa7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2005-04-18 James A. Morrison + + PR tree-optimization/20922 + * gcc.dg/pr20922-1.c: New test. + * gcc.dg/pr20922-2.c: New test. + * gcc.dg/pr20922-3.c: New test. + * gcc.dg/pr20922-4.c: New test. + * gcc.dg/pr20922-5.c: New test. + * gcc.dg/pr20922-6.c: New test. + 2005-04-11 Francois-Xavier Coudert PR libfortran/20950 diff --git a/gcc/testsuite/gcc.dg/pr20922-1.c b/gcc/testsuite/gcc.dg/pr20922-1.c new file mode 100644 index 0000000..c016356 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr20922-1.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-fno-wrapv -fdump-tree-generic" } */ +int f(int i) +{ + return (i - 2) > i; +} + +int g(int i) +{ + return (i + 2) < i; +} + +int h(int i) +{ + return (i + (-2)) > i; +} + +int j(int i) +{ + return (i - (-2)) < i; +} + +int x(double i) +{ + return (i - 2.0) > i; +} + +int y(double i) +{ + return (i + 2.0) < i; +} + +int z(double i) +{ + return (i + (-2.0)) > i; +} +/* { dg-final { scan-tree-dump-times " = 0" 7 "generic" } } */ +/* { dg-final { cleanup-tree-dump "generic" } } */ diff --git a/gcc/testsuite/gcc.dg/pr20922-2.c b/gcc/testsuite/gcc.dg/pr20922-2.c new file mode 100644 index 0000000..3c4380f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr20922-2.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-fwrapv -fdump-tree-generic" } */ +int f (int i) +{ + return (i - 2) > i; +} + +int g (int i) +{ + return (i + 2) < i; +} + +int h (double i) +{ + return (i + 2.0) <= i; +} +/* { dg-final { scan-tree-dump-times " = 0" 0 "generic" } } */ +/* { dg-final { cleanup-tree-dump "generic" } } */ diff --git a/gcc/testsuite/gcc.dg/pr20922-3.c b/gcc/testsuite/gcc.dg/pr20922-3.c new file mode 100644 index 0000000..476eb54 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr20922-3.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-ffast-math -fno-wrapv -fdump-tree-generic" } */ +int f(int i) +{ + return (i - 2) <= i; +} + +int g(int i) +{ + return (i + 2) >= i; +} + +int h(int i) +{ + return (i + (-2)) <= i; +} + +int x(double i) +{ + return (i - 2.0) <= i; +} + +int y(double i) +{ + return (i + 2.0) >= i; +} + +int z(double i) +{ + return (i + (-2.0)) <= i; +} +/* { dg-final { scan-tree-dump-times " = 1" 6 "generic" } } */ +/* { dg-final { cleanup-tree-dump "generic" } } */ diff --git a/gcc/testsuite/gcc.dg/pr20922-4.c b/gcc/testsuite/gcc.dg/pr20922-4.c new file mode 100644 index 0000000..664a62f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr20922-4.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-fno-wrapv -fdump-tree-generic" } */ +int f(int i) +{ + return i < (i - 2); +} + +int g(int i) +{ + return i > (i + 2); +} + +int h(int i) +{ + return i < (i + (-2)); +} + +int j(int i) +{ + return i > (i - (-2)); +} + +int x(double i) +{ + return i < (i - 2.0); +} + +int y(double i) +{ + return i > (i + 2.0); +} + +int z(double i) +{ + return i < (i + (-2.0)); +} +/* { dg-final { scan-tree-dump-times " = 0" 7 "generic" } } */ +/* { dg-final { cleanup-tree-dump "generic" } } */ diff --git a/gcc/testsuite/gcc.dg/pr20922-5.c b/gcc/testsuite/gcc.dg/pr20922-5.c new file mode 100644 index 0000000..7377bad --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr20922-5.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-fsignaling-nans -fwrapv -fdump-tree-generic" } */ +int f(int i) +{ + return i < (i - 2); +} + +int g(int i) +{ + return i > (i + 2); +} + +int h (double i) +{ + return i >= i + 2.0; +} + +int j (double i) +{ + return i > i + 2.0; +} +/* { dg-final { scan-tree-dump-times " = 0" 0 "generic" } } */ +/* { dg-final { cleanup-tree-dump "generic" } } */ diff --git a/gcc/testsuite/gcc.dg/pr20922-6.c b/gcc/testsuite/gcc.dg/pr20922-6.c new file mode 100644 index 0000000..ff1d519 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr20922-6.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-ffast-math -fno-wrapv -fdump-tree-generic" } */ +int f(int i) +{ + return i >= (i - 2); +} + +int g(int i) +{ + return i <= (i + 2); +} + +int h(int i) +{ + return i >= (i + (-2)); +} + +int x(double i) +{ + return i >= (i - 2.0); +} + +int y(double i) +{ + return i <= (i + 2.0); +} + +int z(double i) +{ + return i >= (i + (-2.0)); +} +/* { dg-final { scan-tree-dump-times " = 1" 6 "generic" } } */ +/* { dg-final { cleanup-tree-dump "generic" } } */ -- 2.7.4