https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122624

--- Comment #14 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
My patch doesn't help (but guess it is desirable anyway).
There seems to be 11 distinct _BitInt(66) signed BITINT_TYPEs created during
the --param=ggc-min-expand=0 --param=ggc-min-heapsize=0 -O2 compilation (and
new_alias_set is called on these whenever we ask for alias info of those).
The question is why during the
BS_VAR_11D.4689 = *.LC1D.4701;
vs.
_1 = MEM[(unsigned _BitInt(66) *)_15];
TBAA comparison alias oracle returns that the two can't alias.
BS_VAR_11 has ARRAY_TYPE and that ARRAY_TYPE has recorded TYPE_ALIAS_SET of 4,
but
the TARGET_MEM_REF has just POINTER_TYPE to BITINT_TYPE and that BITINT_TYPE
doesn't have TYPE_ALIAS_SET set.

I think I now understand what happens:
1) the testcase only uses unsigned _BitInt(66), not signed _BitInt(66) aka
_BitInt(66)
2) at some point something calls get_alias_set on unsigned _BitInt(66) [10]
type,
   that does:
  else if (TREE_CODE (t) == ARRAY_TYPE
           && (!TYPE_NONALIASED_COMPONENT (t)
               || TYPE_STRUCTURAL_EQUALITY_P (t)))
    set = get_alias_set (TREE_TYPE (t));
   and recurses:
3)
  /* See if the language has special handling for this type.  */
  set = lang_hooks.get_alias_set (t);
  if (set != -1)
    return set;
4) c_common_get_alias_set does for the unsigned BITINT_TYPE:
  /* The C standard specifically allows aliasing between signed and
     unsigned variants of the same type.  We treat the signed
     variant as canonical.  */
  if ((TREE_CODE (t) == INTEGER_TYPE || TREE_CODE (t) == BITINT_TYPE)
      && TYPE_UNSIGNED (t))
    {
      tree t1 = c_common_signed_type (t);

      /* t1 == t can happen for boolean nodes which are always unsigned.  */
      if (t1 != t)
        return get_alias_set (t1);
    }
5) that creates new _BitInt(66) BITINT_TYPE, computes its alias set (4), stores
   it in its TYPE_ALIAS_SET, but note, nothing sets TYPE_ALIAS_SET of the t
type
   here (unsigned _BitInt(66)
6) in the caller (see 3), set is not -1, so we return without remembering it
7) in the caller (see 2), we get set = 4; and continue to
  TYPE_ALIAS_SET (t) = set;
   and so now we have the ARRAY_TYPE and _BitInt(66) BITINT_TYPE with
TYPE_ALIAS_SET
   set to 4, but not unsigned _BitInt(66) BITINT_TYPE
8) garbage collection happens, nothing really uses _BitInt(66), it is garbage
collected
9) later on we call get_alias_set on the unsigned _BitInt(66) type (created
just once);
   this does 3)-6) again, creates a new _BitInt(66) type because it doesn't
exist
   anymore, so compute different alias set for it
10) and no TBAA thinks the ARRAY_TYPE (with remembered earlier alias set) can't
alias
   with access through its element type
Now, the reason why we haven't seen this often without _BitInt is I guess that
we stick all the signed and unsigned normal types usually somewhere reachable
from GTY roots, but for BITINT_TYPE that is generally not the case.

So, I think
  /* The C standard specifically allows aliasing between signed and
     unsigned variants of the same type.  We treat the signed
     variant as canonical.  */
  if ((TREE_CODE (t) == INTEGER_TYPE || TREE_CODE (t) == BITINT_TYPE)
      && TYPE_UNSIGNED (t))
    {
      tree t1 = c_common_signed_type (t);

      /* t1 == t can happen for boolean nodes which are always unsigned.  */
      if (t1 != t)
        return get_alias_set (t1);
    }
needs to be updated, so that 1) it remembers the returned get_alias_set in
TYPE_ALIAS_SET (t) 2) that for !TYPE_UNSIGNED (t) for these it calls
c_common_unsigned_type and if t1 != t and TYPE_ALIAS_SET_KNOWN_P (t1) it
returns
that earlier alias set and also sets TYPE_ALIAS_SET.  Plus the above case
should
special case unsigned _BitInt(1) which doesn't have signed counterpart and
guess in that case we want to just return -1 so that the caller creates alias
set.

Reply via email to