Commit a1d8947a by Jakub Jelinek Committed by Jakub Jelinek

re PR c++/34949 (Dead code in empty destructors.)

	PR c++/34949
	* tree-ssa-alias.c (stmt_kills_ref_p_1): If base != ref->base
	and both of them are MEM_REFs, just compare first argument for
	equality and attempt to deal even with differing offsets.

From-SVN: r197370
parent 5d751b0c
2013-04-02 Jakub Jelinek <jakub@redhat.com>
PR c++/34949
* tree-ssa-alias.c (stmt_kills_ref_p_1): If base != ref->base
and both of them are MEM_REFs, just compare first argument for
equality and attempt to deal even with differing offsets.
PR c++/34949
* tree-cfg.c (verify_gimple_assign_single): Allow lhs
of gimple_clobber_p to be MEM_REF.
* gimplify.c (gimplify_modify_expr): Gimplify *to_p of
......
......@@ -1889,20 +1889,50 @@ stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref)
&& !stmt_can_throw_internal (stmt))
{
tree base, lhs = gimple_get_lhs (stmt);
HOST_WIDE_INT size, offset, max_size;
HOST_WIDE_INT size, offset, max_size, ref_offset = ref->offset;
base = get_ref_base_and_extent (lhs, &offset, &size, &max_size);
/* We can get MEM[symbol: sZ, index: D.8862_1] here,
so base == ref->base does not always hold. */
if (base == ref->base)
if (base != ref->base)
{
/* For a must-alias check we need to be able to constrain
the access properly. */
if (size != -1 && size == max_size)
/* If both base and ref->base are MEM_REFs, only compare the
first operand, and if the second operand isn't equal constant,
try to add the offsets into offset and ref_offset. */
if (TREE_CODE (base) == MEM_REF && TREE_CODE (ref->base) == MEM_REF
&& TREE_OPERAND (base, 0) == TREE_OPERAND (ref->base, 0))
{
if (offset <= ref->offset
&& offset + size >= ref->offset + ref->max_size)
return true;
if (!tree_int_cst_equal (TREE_OPERAND (base, 0),
TREE_OPERAND (ref->base, 0)))
{
double_int off1 = mem_ref_offset (base);
off1 = off1.alshift (BITS_PER_UNIT == 8
? 3 : exact_log2 (BITS_PER_UNIT),
HOST_BITS_PER_DOUBLE_INT);
off1 = off1 + double_int::from_shwi (offset);
double_int off2 = mem_ref_offset (ref->base);
off2 = off2.alshift (BITS_PER_UNIT == 8
? 3 : exact_log2 (BITS_PER_UNIT),
HOST_BITS_PER_DOUBLE_INT);
off2 = off2 + double_int::from_shwi (ref_offset);
if (off1.fits_shwi () && off2.fits_shwi ())
{
offset = off1.to_shwi ();
ref_offset = off2.to_shwi ();
}
else
size = -1;
}
}
else
size = -1;
}
/* For a must-alias check we need to be able to constrain
the access properly. */
if (size != -1 && size == max_size)
{
if (offset <= ref_offset
&& offset + size >= ref_offset + ref->max_size)
return true;
}
}
......
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