Commit 3cc272c1 by Thomas Preud'homme Committed by Thomas Preud'homme

re PR tree-optimization/61328 (valgrind finds problem in find_bswap_or_nop_1)

2014-06-03  Thomas Preud'homme  <thomas.preudhomme@arm.com>

	PR tree-optimization/61328
	* tree-ssa-math-opts.c (init_symbolic_number): Extract symbolic number
        initialization from find_bswap_or_nop_1.
        (find_bswap_or_nop_1): Test return value of find_bswap_or_nop_1 stored
        in source_expr2 before using the size value the function sets. Also
        make use of init_symbolic_number () in both the old place and
        find_bswap_or_nop_load () to avoid reading uninitialized memory when
        doing recursion in the GIMPLE_BINARY_RHS case.

From-SVN: r211166
parent 597c6315
2014-06-03 Thomas Preud'homme <thomas.preudhomme@arm.com>
PR tree-optimization/61328
* tree-ssa-math-opts.c (init_symbolic_number): Extract symbolic number
initialization from find_bswap_or_nop_1.
(find_bswap_or_nop_1): Test return value of find_bswap_or_nop_1 stored
in source_expr2 before using the size value the function sets. Also
make use of init_symbolic_number () in both the old place and
find_bswap_or_nop_load () to avoid reading uninitialized memory when
doing recursion in the GIMPLE_BINARY_RHS case.
2014-06-03 Richard Biener <rguenther@suse.de> 2014-06-03 Richard Biener <rguenther@suse.de>
PR tree-optimization/61383 PR tree-optimization/61383
......
...@@ -1702,6 +1702,30 @@ verify_symbolic_number_p (struct symbolic_number *n, gimple stmt) ...@@ -1702,6 +1702,30 @@ verify_symbolic_number_p (struct symbolic_number *n, gimple stmt)
return true; return true;
} }
/* Initialize the symbolic number N for the bswap pass from the base element
SRC manipulated by the bitwise OR expression. */
static bool
init_symbolic_number (struct symbolic_number *n, tree src)
{
n->base_addr = n->offset = n->alias_set = n->vuse = NULL_TREE;
/* 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 n->size and the
lowest order byte to 1. */
n->size = TYPE_PRECISION (TREE_TYPE (src));
if (n->size % BITS_PER_UNIT != 0)
return false;
n->size /= BITS_PER_UNIT;
n->range = n->size;
n->n = CMPNOP;
if (n->size < (int)sizeof (int64_t))
n->n &= ((uint64_t)1 << (n->size * BITS_PER_UNIT)) - 1;
return true;
}
/* Check if STMT might be a byte swap or a nop from a memory source and returns /* Check if STMT might be a byte swap or a nop from a memory source and returns
the answer. If so, REF is that memory source and the base of the memory area the answer. If so, REF is that memory source and the base of the memory area
accessed and the offset of the access from that base are recorded in N. */ accessed and the offset of the access from that base are recorded in N. */
...@@ -1714,26 +1738,27 @@ find_bswap_or_nop_load (gimple stmt, tree ref, struct symbolic_number *n) ...@@ -1714,26 +1738,27 @@ find_bswap_or_nop_load (gimple stmt, tree ref, struct symbolic_number *n)
HOST_WIDE_INT bitsize, bitpos; HOST_WIDE_INT bitsize, bitpos;
enum machine_mode mode; enum machine_mode mode;
int unsignedp, volatilep; int unsignedp, volatilep;
tree offset, base_addr;
if (!gimple_assign_load_p (stmt) || gimple_has_volatile_ops (stmt)) if (!gimple_assign_load_p (stmt) || gimple_has_volatile_ops (stmt))
return false; return false;
n->base_addr = get_inner_reference (ref, &bitsize, &bitpos, &n->offset, base_addr = get_inner_reference (ref, &bitsize, &bitpos, &offset, &mode,
&mode, &unsignedp, &volatilep, false); &unsignedp, &volatilep, false);
if (TREE_CODE (n->base_addr) == MEM_REF) if (TREE_CODE (base_addr) == MEM_REF)
{ {
offset_int bit_offset = 0; offset_int bit_offset = 0;
tree off = TREE_OPERAND (n->base_addr, 1); tree off = TREE_OPERAND (base_addr, 1);
if (!integer_zerop (off)) if (!integer_zerop (off))
{ {
offset_int boff, coff = mem_ref_offset (n->base_addr); offset_int boff, coff = mem_ref_offset (base_addr);
boff = wi::lshift (coff, LOG2_BITS_PER_UNIT); boff = wi::lshift (coff, LOG2_BITS_PER_UNIT);
bit_offset += boff; bit_offset += boff;
} }
n->base_addr = TREE_OPERAND (n->base_addr, 0); base_addr = TREE_OPERAND (base_addr, 0);
/* Avoid returning a negative bitpos as this may wreak havoc later. */ /* Avoid returning a negative bitpos as this may wreak havoc later. */
if (wi::neg_p (bit_offset)) if (wi::neg_p (bit_offset))
...@@ -1744,11 +1769,11 @@ find_bswap_or_nop_load (gimple stmt, tree ref, struct symbolic_number *n) ...@@ -1744,11 +1769,11 @@ find_bswap_or_nop_load (gimple stmt, tree ref, struct symbolic_number *n)
Subtract it to BIT_OFFSET and add it (scaled) to OFFSET. */ Subtract it to BIT_OFFSET and add it (scaled) to OFFSET. */
bit_offset -= tem; bit_offset -= tem;
tem = wi::arshift (tem, LOG2_BITS_PER_UNIT); tem = wi::arshift (tem, LOG2_BITS_PER_UNIT);
if (n->offset) if (offset)
n->offset = size_binop (PLUS_EXPR, n->offset, offset = size_binop (PLUS_EXPR, offset,
wide_int_to_tree (sizetype, tem)); wide_int_to_tree (sizetype, tem));
else else
n->offset = wide_int_to_tree (sizetype, tem); offset = wide_int_to_tree (sizetype, tem);
} }
bitpos += bit_offset.to_shwi (); bitpos += bit_offset.to_shwi ();
...@@ -1759,6 +1784,9 @@ find_bswap_or_nop_load (gimple stmt, tree ref, struct symbolic_number *n) ...@@ -1759,6 +1784,9 @@ find_bswap_or_nop_load (gimple stmt, tree ref, struct symbolic_number *n)
if (bitsize % BITS_PER_UNIT) if (bitsize % BITS_PER_UNIT)
return false; return false;
init_symbolic_number (n, ref);
n->base_addr = base_addr;
n->offset = offset;
n->bytepos = bitpos / BITS_PER_UNIT; n->bytepos = bitpos / BITS_PER_UNIT;
n->alias_set = reference_alias_ptr_type (ref); n->alias_set = reference_alias_ptr_type (ref);
n->vuse = gimple_vuse (stmt); n->vuse = gimple_vuse (stmt);
...@@ -1817,28 +1845,12 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit) ...@@ -1817,28 +1845,12 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit)
/* If find_bswap_or_nop_1 returned NULL, STMT is a leaf node and /* If find_bswap_or_nop_1 returned NULL, STMT is a leaf node and
we have to initialize the symbolic number. */ we have to initialize the symbolic number. */
if (!source_expr1 || gimple_assign_load_p (rhs1_stmt)) if (!source_expr1)
{ {
/* Set up the symbolic number N by setting each byte to a if (gimple_assign_load_p (stmt)
value between 1 and the byte size of rhs1. The highest || !init_symbolic_number (n, rhs1))
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; return NULL_TREE;
n->size /= BITS_PER_UNIT; source_expr1 = rhs1;
n->range = n->size;
n->n = CMPNOP;
if (n->size < (int)sizeof (int64_t))
n->n &= ((uint64_t)1 <<
(n->size * BITS_PER_UNIT)) - 1;
if (!source_expr1)
{
n->base_addr = n->offset = n->alias_set = n->vuse = NULL_TREE;
source_expr1 = rhs1;
}
} }
switch (code) switch (code)
...@@ -1916,7 +1928,10 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit) ...@@ -1916,7 +1928,10 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit)
source_expr2 = find_bswap_or_nop_1 (rhs2_stmt, &n2, limit - 1); source_expr2 = find_bswap_or_nop_1 (rhs2_stmt, &n2, limit - 1);
if (n1.size != n2.size || !source_expr2) if (!source_expr2)
return NULL_TREE;
if (n1.size != n2.size)
return NULL_TREE; return NULL_TREE;
if (!n1.vuse != !n2.vuse || if (!n1.vuse != !n2.vuse ||
......
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