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.