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.

Reply via email to