diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/fold-const.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr32461-1.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr32461-2.c | 26 |
4 files changed, 75 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8406d5f..679e5fa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2007-06-24 Sebastian Pop <sebpop@gmail.com> + + PR middle-end/32461 + * fold-const.c (fold_binary): Strip nops of operand 0 + of BIT_NOT_EXPR before calling operand_equal_p. + * testsuite/gcc.dg/tree-ssa/pr32461-1.c: New. + * testsuite/gcc.dg/tree-ssa/pr32461-2.c: New. + 2007-06-23 Mark Mitchell <mark@codesourcery.com> * doc/extend.texi: Document that dllimport and dllexport imply diff --git a/gcc/fold-const.c b/gcc/fold-const.c index cd8d386..e2d57c9 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -9260,21 +9260,31 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) /* ~X + X is -1. */ if (TREE_CODE (arg0) == BIT_NOT_EXPR - && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0) && !TYPE_OVERFLOW_TRAPS (type)) { - t1 = build_int_cst_type (type, -1); - return omit_one_operand (type, t1, arg1); + tree tem = TREE_OPERAND (arg0, 0); + + STRIP_NOPS (tem); + if (operand_equal_p (tem, arg1, 0)) + { + t1 = build_int_cst_type (type, -1); + return omit_one_operand (type, t1, arg1); + } } /* X + ~X is -1. */ if (TREE_CODE (arg1) == BIT_NOT_EXPR - && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0) && !TYPE_OVERFLOW_TRAPS (type)) { - t1 = build_int_cst_type (type, -1); - return omit_one_operand (type, t1, arg0); - } + tree tem = TREE_OPERAND (arg1, 0); + + STRIP_NOPS (tem); + if (operand_equal_p (arg0, tem, 0)) + { + t1 = build_int_cst_type (type, -1); + return omit_one_operand (type, t1, arg0); + } + } /* If we are adding two BIT_AND_EXPR's, both of which are and'ing with a constant, and the two constants have no bits in common, diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr32461-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr32461-1.c new file mode 100644 index 0000000..6e06988 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr32461-1.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +typedef struct +{ + unsigned exp[256]; +} +expbap_t; + +void +a52_bit_allocate (expbap_t * expbap) +{ + int i; + unsigned *exp = expbap->exp; + char *bap; + + while (i < 3 || exp[i] > exp[i - 1]); + + do { + if (exp[i + 1] == exp[i]) + bap[i] = 0; + i++; + } while (i < 20); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr32461-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr32461-2.c new file mode 100644 index 0000000..81ee6ae --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr32461-2.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +typedef struct +{ + unsigned char exp[256]; +} +expbap_t; + +void +a52_bit_allocate (expbap_t * expbap) +{ + int i; + unsigned char *exp = expbap->exp; + int lowcomp; + + do + { + if (exp[i + 1] == exp[i] - 2) + lowcomp = 384; + else if (lowcomp && (exp[i + 1] > exp[i])) + lowcomp -= 64; + i++; + } + while ((i < 3) || ((i < 7) && (exp[i] > exp[i - 1]))); +} |