diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-12-05 23:24:08 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2007-12-05 23:24:08 +0100 |
commit | 517ddae96b847521c7761f74bb9ac522ed70f038 (patch) | |
tree | d91874c1661fc111f66e2b41c03740a7db664cb9 | |
parent | e8608df46e1f096a942e0fff741fcdf2d9120df0 (diff) | |
download | gcc-517ddae96b847521c7761f74bb9ac522ed70f038.zip gcc-517ddae96b847521c7761f74bb9ac522ed70f038.tar.gz gcc-517ddae96b847521c7761f74bb9ac522ed70f038.tar.bz2 |
re PR middle-end/34337 (Internal error while building gtkwhiteboardc.c from pidgin 2.3.0)
PR middle-end/34337
* fold-const.c (fold_binary) <case BIT_IOR_EXPR>: Don't minimize
number of bits set in C1 if a mode mask for some mode can be used
instead.
* gcc.c-torture/execute/20071205-1.c: New test.
From-SVN: r130635
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/fold-const.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20071205-1.c | 17 |
4 files changed, 54 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index da6a6c3..189286b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2007-12-05 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/34337 + * fold-const.c (fold_binary) <case BIT_IOR_EXPR>: Don't minimize + number of bits set in C1 if a mode mask for some mode can be used + instead. + 2007-12-05 Bernhard Fischer <aldot@gcc.gnu.org> * varasm.c (merge_weak, weak_finish, assemble_alias): Commentary typo diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 1502994..8519e68 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -10570,8 +10570,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) && TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) { - unsigned HOST_WIDE_INT hi1, lo1, hi2, lo2, mlo, mhi; - int width = TYPE_PRECISION (type); + unsigned HOST_WIDE_INT hi1, lo1, hi2, lo2, hi3, lo3, mlo, mhi; + int width = TYPE_PRECISION (type), w; hi1 = TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1)); lo1 = TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)); hi2 = TREE_INT_CST_HIGH (arg1); @@ -10599,16 +10599,35 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) return fold_build2 (BIT_IOR_EXPR, type, TREE_OPERAND (arg0, 0), arg1); - /* Minimize the number of bits set in C1, i.e. C1 := C1 & ~C2. */ + /* Minimize the number of bits set in C1, i.e. C1 := C1 & ~C2, + unless (C1 & ~C2) | (C2 & C3) for some C3 is a mask of some + mode which allows further optimizations. */ hi1 &= mhi; lo1 &= mlo; - if ((hi1 & ~hi2) != hi1 || (lo1 & ~lo2) != lo1) + hi2 &= mhi; + lo2 &= mlo; + hi3 = hi1 & ~hi2; + lo3 = lo1 & ~lo2; + for (w = BITS_PER_UNIT; + w <= width && w <= HOST_BITS_PER_WIDE_INT; + w <<= 1) + { + unsigned HOST_WIDE_INT mask + = (unsigned HOST_WIDE_INT) -1 >> (HOST_BITS_PER_WIDE_INT - w); + if (((lo1 | lo2) & mask) == mask + && (lo1 & ~mask) == 0 && hi1 == 0) + { + hi3 = 0; + lo3 = mask; + break; + } + } + if (hi3 != hi1 || lo3 != lo1) return fold_build2 (BIT_IOR_EXPR, type, fold_build2 (BIT_AND_EXPR, type, TREE_OPERAND (arg0, 0), build_int_cst_wide (type, - lo1 & ~lo2, - hi1 & ~hi2)), + lo3, hi3)), arg1); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1acb944..70aa1df 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-12-05 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/34337 + * gcc.c-torture/execute/20071205-1.c: New test. + 2007-12-05 Kaz Kojima <kkojima@gcc.gnu.org> * gfortran.dg/module_nan.f90: Add -mieee for sh. diff --git a/gcc/testsuite/gcc.c-torture/execute/20071205-1.c b/gcc/testsuite/gcc.c-torture/execute/20071205-1.c new file mode 100644 index 0000000..fa19ec0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20071205-1.c @@ -0,0 +1,17 @@ +/* PR middle-end/34337 */ + +extern void abort (void); + +int +foo (int x) +{ + return ((x << 8) & 65535) | 255; +} + +int +main (void) +{ + if (foo (0x32) != 0x32ff || foo (0x174) != 0x74ff) + abort (); + return 0; +} |