aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-math-opts.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-05-13 12:27:18 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-05-13 12:27:18 +0000
commit8ab3bdac33672a2ec681e8d57869830fdcaffd0e (patch)
tree96009fea42a0010c478452c737b7da940e24955b /gcc/tree-ssa-math-opts.c
parent310aba3bbe9b1e053ec90d92ed5a58d24cde3b85 (diff)
downloadgcc-8ab3bdac33672a2ec681e8d57869830fdcaffd0e.zip
gcc-8ab3bdac33672a2ec681e8d57869830fdcaffd0e.tar.gz
gcc-8ab3bdac33672a2ec681e8d57869830fdcaffd0e.tar.bz2
re PR tree-optimization/42587 (bswap not recognized for memory)
2016-05-13 Richard Biener <rguenther@suse.de> PR tree-optimization/42587 * tree-ssa-math-opts.c (perform_symbolic_merge): Handle BIT_FIELD_REF. (find_bswap_or_nop_1): Likewise. (bswap_replace): Likewise. * gcc.dg/optimize-bswapsi-4.c: New testcase. From-SVN: r236204
Diffstat (limited to 'gcc/tree-ssa-math-opts.c')
-rw-r--r--gcc/tree-ssa-math-opts.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 3fcf24c..81688cd 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -2160,9 +2160,16 @@ perform_symbolic_merge (gimple *source_stmt1, struct symbolic_number *n1,
gimple *source_stmt;
struct symbolic_number *n_start;
+ tree rhs1 = gimple_assign_rhs1 (source_stmt1);
+ if (TREE_CODE (rhs1) == BIT_FIELD_REF)
+ rhs1 = TREE_OPERAND (rhs1, 0);
+ tree rhs2 = gimple_assign_rhs1 (source_stmt2);
+ if (TREE_CODE (rhs2) == BIT_FIELD_REF)
+ rhs2 = TREE_OPERAND (rhs2, 0);
+
/* Sources are different, cancel bswap if they are not memory location with
the same base (array, structure, ...). */
- if (gimple_assign_rhs1 (source_stmt1) != gimple_assign_rhs1 (source_stmt2))
+ if (rhs1 != rhs2)
{
uint64_t inc;
HOST_WIDE_INT start_sub, end_sub, end1, end2, end;
@@ -2285,6 +2292,39 @@ find_bswap_or_nop_1 (gimple *stmt, struct symbolic_number *n, int limit)
if (find_bswap_or_nop_load (stmt, rhs1, n))
return stmt;
+ /* Handle BIT_FIELD_REF. */
+ if (TREE_CODE (rhs1) == BIT_FIELD_REF
+ && TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME)
+ {
+ unsigned HOST_WIDE_INT bitsize = tree_to_uhwi (TREE_OPERAND (rhs1, 1));
+ unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (TREE_OPERAND (rhs1, 2));
+ if (bitpos % BITS_PER_UNIT == 0
+ && bitsize % BITS_PER_UNIT == 0
+ && init_symbolic_number (n, TREE_OPERAND (rhs1, 0)))
+ {
+ /* Shift. */
+ if (!do_shift_rotate (RSHIFT_EXPR, n, bitpos))
+ return NULL;
+
+ /* Mask. */
+ uint64_t mask = 0;
+ uint64_t tmp = (1 << BITS_PER_UNIT) - 1;
+ for (unsigned i = 0; i < bitsize / BITS_PER_UNIT;
+ i++, tmp <<= BITS_PER_UNIT)
+ mask |= (uint64_t) MARKER_MASK << (i * BITS_PER_MARKER);
+ n->n &= mask;
+
+ /* Convert. */
+ n->type = TREE_TYPE (rhs1);
+ if (!n->base_addr)
+ n->range = TYPE_PRECISION (n->type) / BITS_PER_UNIT;
+
+ return verify_symbolic_number_p (n, stmt) ? stmt : NULL;
+ }
+
+ return NULL;
+ }
+
if (TREE_CODE (rhs1) != SSA_NAME)
return NULL;
@@ -2683,6 +2723,8 @@ bswap_replace (gimple *cur_stmt, gimple *src_stmt, tree fndecl,
}
src = val_tmp;
}
+ else if (TREE_CODE (src) == BIT_FIELD_REF)
+ src = TREE_OPERAND (src, 0);
if (n->range == 16)
bswap_stats.found_16bit++;