On Fri, 6 Feb 2026, Jakub Jelinek wrote:

> On Fri, Feb 06, 2026 at 10:52:49AM +0100, Richard Biener wrote:
> > > --- gcc/alias.cc.jj       2026-02-05 15:34:14.545990112 +0100
> > > +++ gcc/alias.cc  2026-02-05 15:54:32.762394480 +0100
> > > @@ -948,7 +948,12 @@ get_alias_set (tree t)
> > >    else
> > >      {
> > >        t = TYPE_CANONICAL (t);
> > > -      gcc_checking_assert (!TYPE_STRUCTURAL_EQUALITY_P (t));
> > > +      gcc_checking_assert (TYPE_CANONICAL (t) == t);
> > > +      if (t != TYPE_MAIN_VARIANT (t))
> > > + {
> > > +   t = TYPE_MAIN_VARIANT (t);
> > 
> > We already did
> > 
> >   /* Variant qualifiers don't affect the alias set, so get the main
> >      variant.  */
> >   t = TYPE_MAIN_VARIANT (t);
> > 
> > at the start.  I'd rather not do this, is this really necessary?
> 
> Unfortunately yes.
> The first t = TYPE_MAIN_VARIANT (t) will look through say typedefs
> or cv quals (if they would be there, for C/C++ on array types they aren't
> except for the array_as_string hack).  So, given say
> typedef volatile int A [2] __attribute__((may_alias));
> typedef A B;
> that goes from B to volatile int [2] __attribute__((may_alias)), but
> doesn't go further because it is a distinct type copy.
> Then t = TYPE_CANONICAL (t); goes from that
> volatile int [2] __attribute__((may_alias)) to volatile int [2],
> i.e. for FE canonical representation of that, and the second
> t = TYPE_MAIN_VARIANT (t);
> goes from volatile int [2] to int [2].
> 
> > But I'm a bit confused now.  So we have const int * being its own
> > canonical type and a variant of int *.  All fine.  But the canonical
> > type of  'int *' (a main variant) can now be, say 'const int *'?
> 
> I think pointers behave differently from array types, I think for
> typedef const int *__attribute__((may_alias)) const T;
> T a;
> TYPE_MAIN_VARIANT (T) is const int *__attribute__((may_alias))
> (because again, attribute variants are distinct types),
> TYPE_CANONICAL (T) is const int *const (TYPE_CANONICAL wants to
> preserve cv quals but ignores attributes or typedefs etc.).
> TYPE_CANONICAL (TYPE_MAIN_VARIANT (T)) is const int * which is
> its own TYPE_MAIN_VARIANT.
> 
> The problem is I think only with ARRAY_TYPEs.
> For POINTER_TYPEs etc., const int *const has main variant of
> const int * rather than int *.  For ARRAY_TYPEs in C/C++,
> const int[2] has main variant int[2] rather than const int[2].
> 
> > That means that get_alias should swap TYPE_MAIN_VARIANT and
> > TYPE_CANONICAL punning?  What happens whe TYPE_STRUCTURAL_EQUALITY (t)?
> 
> No, we need all 3 I'm afraid.  If you want, this third step could be
> asserted only for ARRAY_TYPEs.

Hmm, I see.

The patch is OK with me.

Thanks,
Richard.

> > Can we assert that TYPE_STRUCRTURAL_EQUALITY (TYPE_MAIN_VARIANT (t))?
> 
> TYPE_STRUCTURAL_EQUALITY_P is just NULL TYPE_CANONICAL.  Either
> all similar (quals/attrs etc.) types use structural equality, or all
> use canonical types.
> > 
> > IIRC when the middle-end re-computes TYPE_CANONICAL it does so only
> > for main variants (and we only stream the TYPE_MAIN_VARIANT pointers,
> > re-building variant chains at stream-in).  lto/lto-common.cc has
> > 
> >   /* Canonical types are same among all complete variants.  */
> >   if (TYPE_CANONICAL (TYPE_MAIN_VARIANT (t)))
> >     TYPE_CANONICAL (t) = TYPE_CANONICAL (TYPE_MAIN_VARIANT (t));
> >   else
> >     {
> >       hashval_t h = hash_canonical_type (TYPE_MAIN_VARIANT (t));
> >       gimple_register_canonical_type_1 (TYPE_MAIN_VARIANT (t), h);
> >       TYPE_CANONICAL (t) = TYPE_CANONICAL (TYPE_MAIN_VARIANT (t));
> > 
> > I guess with the old scheme the order of TYPE_CANONICAL/TYPE_MAIN_VARIANT
> > punning doesn't matter, nor with how LTO re-computes it.  But with
> > the C/C++ way it would matter unless you iterate one more time.
> > 
> > There is tree-ssa-alias.cc:same_type_for_tbaa which probably needs
> > updating for this as well (but it's only a missed optimization there
> > I guess).  Possibly similarly types_equal_for_same_type_for_tbaa_p.
> 
> Seems same_type_for_tbaa just punts on ARRAY_TYPES:
> 1016    /* Compare the canonical types.  */
> 1017    if (TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2))
> 1018      return 1;
> 1019  
> 1020    /* ??? Array types are not properly unified in all cases as we have
> 1021       spurious changes in the index types for example.  Removing this
> 1022       causes all sorts of problems with the Fortran frontend.  */
> 1023    if (TREE_CODE (type1) == ARRAY_TYPE
> 1024        && TREE_CODE (type2) == ARRAY_TYPE)
> 1025      return -1;
> 
>       Jakub
> 
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to