Am Montag, dem 06.05.2024 um 09:00 +0200 schrieb Richard Biener:
> On Sat, 4 May 2024, Martin Uecker wrote:
> 
> > Am Freitag, dem 03.05.2024 um 21:16 +0200 schrieb Jakub Jelinek:
> > > > On Fri, May 03, 2024 at 09:11:20PM +0200, Martin Uecker wrote:
> > > > > > > > TYPE_CANONICAL as used by the middle-end cannot express this but
> > > > > > 
> > > > > > Hm. so how does it work now for arrays?
> > > > 
> > > > Do you have a testcase which doesn't work correctly with the arrays?
> > 
> > I am mostly trying to understand better how this works. But
> > if I am not mistaken, the following example would indeed
> > indicate that we do incorrect aliasing decisions for types
> > derived from arrays:
> > 
> > https://godbolt.org/z/rTsE3PhKc
> 
> This example is about pointer-to-array types, int (*)[2] and
> int (*)[1] are supposed to be compatible as in receive the same alias
> set. 

In C, char (*)[2] and char (*)[1] are not compatible. But with
COMPAT set, the example operates^1 with char (*)[] and char (*)[1]
which are compatible.  If we form equivalence classes, then
all three types would need to be treated as equivalent. 

^1 Actually, pointer to functions returning pointers
to arrays. Probably this example can still be simplified...

>  This is ensured by get_alias_set POINTER_TYPE_P handling,
> the alias set is supposed to be the same as that of int *.  It seems
> we do restrict the handling a bit, the code does
> 
>       /* Unnest all pointers and references.
>          We also want to make pointer to array/vector equivalent to 
> pointer to
>          its element (see the reasoning above). Skip all those types, too.  
> */
>       for (p = t; POINTER_TYPE_P (p)
>            || (TREE_CODE (p) == ARRAY_TYPE
>                && (!TYPE_NONALIASED_COMPONENT (p)
>                    || !COMPLETE_TYPE_P (p)
>                    || TYPE_STRUCTURAL_EQUALITY_P (p)))
>            || TREE_CODE (p) == VECTOR_TYPE;
>            p = TREE_TYPE (p))
> 
> where the comment doesn't exactly match the code - but C should
> never have TYPE_NONALIASED_COMPONENT (p).
> 
> But maybe I misread the example or it goes wrong elsewhere.

If I am not confusing myself too much, the example shows that
aliasing analysis treats the the types as incompatible in
both cases, because it does not reload *a with -O2. 

For char (*)[1] and char (*)[2] this would be correct (but an
implementation exploiting this would need to do structural
comparisons and not equivalence classes) but for 
char (*)[2] and char (*)[] it is not.

Martin


> 
> Richard.
> 
> > Martin
> > 
> > > > 
> > > > E.g. same_type_for_tbaa has
> > > >   type1 = TYPE_MAIN_VARIANT (type1);
> > > >   type2 = TYPE_MAIN_VARIANT (type2);
> > > > 
> > > >   /* Handle the most common case first.  */
> > > >   if (type1 == type2)
> > > >     return 1;
> > > > 
> > > >   /* If we would have to do structural comparison bail out.  */
> > > >   if (TYPE_STRUCTURAL_EQUALITY_P (type1)
> > > >       || TYPE_STRUCTURAL_EQUALITY_P (type2))
> > > >     return -1;
> > > > 
> > > >   /* Compare the canonical types.  */
> > > >   if (TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2))
> > > >     return 1;
> > > > 
> > > >   /* ??? Array types are not properly unified in all cases as we have
> > > >      spurious changes in the index types for example.  Removing this
> > > >      causes all sorts of problems with the Fortran frontend.  */
> > > >   if (TREE_CODE (type1) == ARRAY_TYPE
> > > >       && TREE_CODE (type2) == ARRAY_TYPE)
> > > >     return -1;
> > > > ...
> > > > and later compares alias sets and the like.
> > > > So, even if int[] and int[0] have different TYPE_CANONICAL, they
> > > > will be considered maybe the same.  Also, guess get_alias_set
> > > > has some ARRAY_TYPE handling...
> > > > 
> > > > Anyway, I think we should just go with Richi's patch.
> > > > 
> > > >         Jakub
> > > > 
> > 
> > 
> > 
> 

-- 
Univ.-Prof. Dr. rer. nat. Martin Uecker
Graz University of Technology
Institute of Biomedical Imaging


Reply via email to