diff options
author | Richard Biener <rguenther@suse.de> | 2016-05-13 12:27:18 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2016-05-13 12:27:18 +0000 |
commit | 8ab3bdac33672a2ec681e8d57869830fdcaffd0e (patch) | |
tree | 96009fea42a0010c478452c737b7da940e24955b /gcc/tree-ssa-math-opts.c | |
parent | 310aba3bbe9b1e053ec90d92ed5a58d24cde3b85 (diff) | |
download | gcc-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.c | 44 |
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++; |