Commit 8ab3bdac by Richard Biener Committed by Richard Biener

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
parent 310aba3b
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.
2016-05-13 Martin Liska <mliska@suse.cz>
* tree-vect-patterns.c (vect_recog_mask_conversion_pattern):
......
2016-05-13 Richard Biener <rguenther@suse.de>
PR tree-optimization/42587
* gcc.dg/optimize-bswapsi-4.c: New testcase.
2016-05-13 Martin Liska <mliska@suse.cz>
* g++.dg/tree-ssa/ivopts-3.C: Change test-case to follow
......
/* { dg-do compile } */
/* { dg-require-effective-target bswap32 } */
/* { dg-options "-O2 -fdump-tree-bswap" } */
/* { dg-additional-options "-march=z900" { target s390-*-* } } */
typedef unsigned char u8;
typedef unsigned int u32;
union __anonunion
{
u32 value;
u8 bytes[4];
};
u32
acpi_ut_dword_byte_swap (u32 value)
{
union __anonunion in;
in.value = value;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
return ((in.bytes[0] << 24) | (in.bytes[1] << 16)
| (in.bytes[2] << 8) | in.bytes[3]);
#else
return ((in.bytes[3] << 24) | (in.bytes[2] << 16)
| (in.bytes[1] << 8) | in.bytes[0]);
#endif
}
/* { dg-final { scan-tree-dump "32 bit bswap implementation found at" "bswap" } } */
......@@ -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++;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment