diff options
author | Andreas Krebbel <Andreas.Krebbel@de.ibm.com> | 2010-03-11 13:51:00 +0000 |
---|---|---|
committer | Andreas Krebbel <krebbel@gcc.gnu.org> | 2010-03-11 13:51:00 +0000 |
commit | b509e1fcea9c6ba2dcaaee5159e19f65b407f031 (patch) | |
tree | c84727d77a7e581856cf026478be48395776d00b /gcc/tree-ssa-math-opts.c | |
parent | 108ba00bcf8c2e98a1c097687b52f66f7e772306 (diff) | |
download | gcc-b509e1fcea9c6ba2dcaaee5159e19f65b407f031.zip gcc-b509e1fcea9c6ba2dcaaee5159e19f65b407f031.tar.gz gcc-b509e1fcea9c6ba2dcaaee5159e19f65b407f031.tar.bz2 |
re PR tree-optimization/43280 (gcc4.5 -m32 -O2: misoptimizes sha256!)
2010-03-11 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
PR tree-optimization/43280
* tree-ssa-math-opts.c (find_bswap_1): Modify symbolic number generation.
Move calculation of size out of the if branch.
(find_bswap): Modify compare number generation.
2010-03-11 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* gcc.dg/optimize-bswapdi-1.c: Add OpenSSL bswap variant.
* gcc.dg/pr43280.c: New testcase.
From-SVN: r157386
Diffstat (limited to 'gcc/tree-ssa-math-opts.c')
-rw-r--r-- | gcc/tree-ssa-math-opts.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index c46a57f..d38df8d 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -940,15 +940,18 @@ find_bswap_1 (gimple stmt, struct symbolic_number *n, int limit) { /* Set up the symbolic number N by setting each byte to a value between 1 and the byte size of rhs1. The highest - order byte is set to 1 and the lowest order byte to - n.size. */ + order byte is set to n->size and the lowest order + byte to 1. */ n->size = TYPE_PRECISION (TREE_TYPE (rhs1)); if (n->size % BITS_PER_UNIT != 0) return NULL_TREE; n->size /= BITS_PER_UNIT; n->n = (sizeof (HOST_WIDEST_INT) < 8 ? 0 : - (unsigned HOST_WIDEST_INT)0x01020304 << 32 | 0x05060708); - n->n >>= (sizeof (HOST_WIDEST_INT) - n->size) * BITS_PER_UNIT; + (unsigned HOST_WIDEST_INT)0x08070605 << 32 | 0x04030201); + + if (n->size < (int)sizeof (HOST_WIDEST_INT)) + n->n &= ((unsigned HOST_WIDEST_INT)1 << + (n->size * BITS_PER_UNIT)) - 1; source_expr1 = rhs1; } @@ -988,9 +991,9 @@ find_bswap_1 (gimple stmt, struct symbolic_number *n, int limit) { /* If STMT casts to a smaller type mask out the bits not belonging to the target type. */ - n->size = type_size / BITS_PER_UNIT; n->n &= ((unsigned HOST_WIDEST_INT)1 << type_size) - 1; } + n->size = type_size / BITS_PER_UNIT; } break; default: @@ -1051,11 +1054,11 @@ static tree find_bswap (gimple stmt) { /* The number which the find_bswap result should match in order to - have a full byte swap. The insignificant bytes are masked out - before using it. */ + have a full byte swap. The number is shifted to the left according + to the size of the symbolic number before using it. */ unsigned HOST_WIDEST_INT cmp = sizeof (HOST_WIDEST_INT) < 8 ? 0 : - (unsigned HOST_WIDEST_INT)0x08070605 << 32 | 0x04030201; + (unsigned HOST_WIDEST_INT)0x01020304 << 32 | 0x05060708; struct symbolic_number n; tree source_expr; @@ -1079,7 +1082,7 @@ find_bswap (gimple stmt) ((unsigned HOST_WIDEST_INT)1 << (n.size * BITS_PER_UNIT)) - 1; n.n &= mask; - cmp &= mask; + cmp >>= (sizeof (HOST_WIDEST_INT) - n.size) * BITS_PER_UNIT; } /* A complete byte swap should make the symbolic number to start |