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)