On Tue, 28 Feb 2023, Jakub Jelinek wrote:

> Hi!
> 
> Without LTO, TYPE_POINTER_TO/TYPE_REFERENCE_TO chains are only maintained
> inside of build_{pointer,reference}_type_for_mode and those routines
> ensure that the pointer/reference type added to the chain is really
> unqualified (including address space), without extra user alignment
> and has just one entry for each of the TYPE_MODE/TYPE_REF_CAN_ALIAS_ALL
> pair (unless something would modify the types in place, but that would
> be wrong).

Is that so?  I can't find any code verifying that (verify_type?).
Of course build_{pointer,reference}_type_for_mode will always build
unqualified pointers, but then the LTO code does

  /* The following reconstructs the pointer chains
     of the new pointed-to type if we are a main variant.  We do
     not stream those so they are broken before fixup.  */
  if (TREE_CODE (t) == POINTER_TYPE
      && TYPE_MAIN_VARIANT (t) == t)
    {
      TYPE_NEXT_PTR_TO (t) = TYPE_POINTER_TO (TREE_TYPE (t));
      TYPE_POINTER_TO (TREE_TYPE (t)) = t;
    }
  else if (TREE_CODE (t) == REFERENCE_TYPE
           && TYPE_MAIN_VARIANT (t) == t)
    {
      TYPE_NEXT_REF_TO (t) = TYPE_REFERENCE_TO (TREE_TYPE (t));
      TYPE_REFERENCE_TO (TREE_TYPE (t)) = t;
    }

which was supposed to ensure only putting unqualified pointers
(not pointed to types!) to the chain.  So to me the question is
rather why a type with TYPE_USER_ALIGN is a the main variant - that's
what looks wrong here?

Richard.

> Now, LTO adds stuff to these chains in lto_fixup_prevailing_type but
> doesn't guarantee that.  The testcase in the PR (which I'm not including
> for testsuite because when (I hope) the aarch64 backend bug will be fixed,
> the testcase would work either way) shows a case where user has
> TYPE_USER_ALIGN type with very high alignment, as there aren't enough
> pointers to float in the code left that one becomes the prevailing one,
> lto_fixup_prevailing_type puts it into the TYPE_POINTER_TO chain of
> float and later on during expansion of __builtin_cexpif expander
> uses build_pointer_type (float_type_node) to emit a sincosf call and
> instead of getting a normal pointer type gets this non-standard one.
> 
> The following patch fixes that by not adding into those chains
> qualified or user aligned types and by making sure that some type
> for the TYPE_MODE/TYPE_REF_CAN_ALIAS_ALL combination (e.g. from lto1
> initialization) isn't there already before adding a new one.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> 2023-02-28  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR target/108910
>       * lto-common.cc (lto_fixup_prevailing_type): Don't add t to
>       TYPE_POINTER_TO or TYPE_REFERENCE_TO chain if it has non-zero
>       TYPE_QUALS, or TYPE_USER_ALIGN or some other type with the
>       same TYPE_MODE and TYPE_REF_CAN_ALIAS_ALL flag is already
>       present.
> 
> --- gcc/lto/lto-common.cc.jj  2023-01-16 11:52:16.165732856 +0100
> +++ gcc/lto/lto-common.cc     2023-02-28 01:42:51.006764018 +0100
> @@ -984,21 +984,35 @@ lto_fixup_prevailing_type (tree t)
>        TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (mv);
>        TYPE_NEXT_VARIANT (mv) = t;
>      }
> -
> -  /* The following reconstructs the pointer chains
> -     of the new pointed-to type if we are a main variant.  We do
> -     not stream those so they are broken before fixup.  */
> -  if (TREE_CODE (t) == POINTER_TYPE
> -      && TYPE_MAIN_VARIANT (t) == t)
> -    {
> -      TYPE_NEXT_PTR_TO (t) = TYPE_POINTER_TO (TREE_TYPE (t));
> -      TYPE_POINTER_TO (TREE_TYPE (t)) = t;
> -    }
> -  else if (TREE_CODE (t) == REFERENCE_TYPE
> -        && TYPE_MAIN_VARIANT (t) == t)
> +  else if (!TYPE_QUALS (t) && !TYPE_USER_ALIGN (t))
>      {
> -      TYPE_NEXT_REF_TO (t) = TYPE_REFERENCE_TO (TREE_TYPE (t));
> -      TYPE_REFERENCE_TO (TREE_TYPE (t)) = t;
> +      /* The following reconstructs the pointer chains
> +      of the new pointed-to type if we are a main variant.  We do
> +      not stream those so they are broken before fixup.
> +      Don't add it if despite being main variant it is
> +      qualified or user aligned type.  Don't add it if there
> +      is something in the chain already.  */
> +      tree *p = NULL;
> +      if (TREE_CODE (t) == POINTER_TYPE)
> +     p = &TYPE_POINTER_TO (TREE_TYPE (t));
> +      else if (TREE_CODE (t) == REFERENCE_TYPE)
> +     p = &TYPE_REFERENCE_TO (TREE_TYPE (t));
> +      if (p)
> +     {
> +       tree t2;
> +       for (t2 = *p; t2; t2 = TYPE_NEXT_PTR_TO (t2))
> +         if (TYPE_MODE (t2) == TYPE_MODE (t)
> +             && TYPE_REF_CAN_ALIAS_ALL (t2) == TYPE_REF_CAN_ALIAS_ALL (t))
> +           break;
> +       if (t2 == NULL_TREE)
> +         {
> +           if (TREE_CODE (t) == POINTER_TYPE)
> +             TYPE_NEXT_PTR_TO (t) = *p;
> +           else
> +             TYPE_NEXT_REF_TO (t) = *p;
> +           *p = t;
> +         }
> +     }
>      }
>  }
>  
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg,
Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman;
HRB 36809 (AG Nuernberg)

Reply via email to