[Bug tree-optimization/73434] [6/7 Regression] Wrong code with casting, branches and aliasing
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Aug 12 11:28:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=73434
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
So it happens because we forward &objs[idx] into the dereference in the SCCVN
representation which messes up base_alias_set when re-constructing an ao_ref
from that. We get 3 vs. 4 here. And then in indirect_ref_may_alias_decl_p
we have:
/* When we are trying to disambiguate an access with a pointer dereference
as base versus one with a decl as base we can use both the size
of the decl and its dynamic type for extra disambiguation.
??? We do not know anything about the dynamic type of the decl
other than that its alias-set contains base2_alias_set as a subset
which does not help us here. */
/* As we know nothing useful about the dynamic type of the decl just
use the usual conflict check rather than a subset test.
??? We could introduce -fvery-strict-aliasing when the language
does not allow decls to have a dynamic type that differs from their
static type. Then we can check
!alias_set_subset_of (base1_alias_set, base2_alias_set) instead. */
if (base1_alias_set != base2_alias_set
&& !alias_sets_conflict_p (base1_alias_set, base2_alias_set))
return false;
thus this issue was likely introduced with vn_reference_maybe_forwprop_address
handling non-constant references. On the GCC 5 branch we have
addr_base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0),
&addr_offset);
if (!addr_base
|| TREE_CODE (addr_base) != MEM_REF)
return;
off += addr_offset;
off += mem_ref_offset (addr_base);
op->op0 = TREE_OPERAND (addr_base, 0);
so it preserves the original MEM_REF. But now:
/* If that didn't work because the address isn't invariant propagate
the reference tree from the address operation in case the current
dereference isn't offsetted. */
if (!addr_base
&& *i_p == ops->length () - 1
&& off == 0
/* This makes us disable this transform for PRE where the
reference ops might be also used for code insertion which
is invalid. */
&& default_vn_walk_kind == VN_WALKREWRITE)
{
auto_vec<vn_reference_op_s, 32> tem;
copy_reference_ops_from_ref (TREE_OPERAND (addr, 0), &tem);
ops->pop ();
ops->pop ();
ops->safe_splice (tem);
--*i_p;
return true;
so we replace it and lost alias info from the original MEM_REF.
I have a patch.
More information about the Gcc-bugs
mailing list