On Mon, 5 Nov 2018, Jan Hubicka wrote:

> Hi,
> this patch fixes the miscompare I introduced to spec2006 GCC benchmark
> when build with LTO.
> The problem is that fld_incomplete_type_of builds new pointer type to
> incomplete type rather than complete but it ends up giving wrong type
> canonical.
> 
> This patch also improves TBAA with early opts because we do no lose info
> by producing incomplete variants. 
> Note that build_pointer_type may return existing type and in that case I
> overwrite TYPE_CANONICAL of it, but I believe it should be harmless
> because all pointers to a given type should have canonicals constructed
> same way.
> 
> lto-bootstrapped/regtested x86_64-linux.
> 
> Honza
>       * gcc.dg/lto/tbaa-1.c: New testcase.
>       * tree.c (fld_incomplete_type_of): Copy TYPE_CANONICAL while creating
>       pointer type.
> Index: testsuite/gcc.dg/lto/tbaa-1.c
> ===================================================================
> --- testsuite/gcc.dg/lto/tbaa-1.c     (nonexistent)
> +++ testsuite/gcc.dg/lto/tbaa-1.c     (working copy)
> @@ -0,0 +1,41 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -flto -fdump-tree-evrp" } */
> +typedef struct rtx_def *rtx;
> +typedef struct cselib_val_struct
> +{
> +  union
> +  {
> +  } u;
> +  struct elt_loc_list *locs;
> +}
> +cselib_val;
> +struct elt_loc_list
> +{
> +  struct elt_loc_list *next;
> +  rtx loc;
> +};
> +static int n_useless_values;
> +unchain_one_elt_loc_list (pl)
> +     struct elt_loc_list **pl;
> +{
> +  struct elt_loc_list *l = *pl;
> +  *pl = l->next;
> +}
> +
> +discard_useless_locs (x, info)
> +     void **x;
> +{
> +  cselib_val *v = (cselib_val *) * x;
> +  struct elt_loc_list **p = &v->locs;
> +  int had_locs = v->locs != 0;
> +  while (*p)
> +    {
> +      unchain_one_elt_loc_list (p);
> +      p = &(*p)->next;
> +    }
> +  if (had_locs && v->locs == 0)
> +    {
> +      n_useless_values++;
> +    }
> +}
> +/* { dg-final { scan-tree-dump-times "n_useless_values" 2 "evrp" } } */      
>            
> Index: tree.c
> ===================================================================
> --- tree.c    (revision 265766)
> +++ tree.c    (working copy)
> @@ -5146,6 +5146,7 @@ fld_incomplete_type_of (tree t, struct f
>         else
>           first = build_reference_type_for_mode (t2, TYPE_MODE (t),
>                                               TYPE_REF_CAN_ALIAS_ALL (t));
> +       TYPE_CANONICAL (first) = TYPE_CANONICAL (TYPE_MAIN_VARIANT (t));

Hmm, this _should_ be a no-op.  Can you, before that line, add

  gcc_assert (TYPE_CANONICAL (t2) != t2
              && TYPE_CANONICAL (t2) == TYPE_CANONICAL (TREE_TYPE (t)));

?  That is, the incomplete variant should share TYPE_CANONICAL with
the pointed-to type and be _not_ the canonical leader (otherwise
all other pointer types are bogus).


>         add_tree_to_fld_list (first, fld);
>         return fld_type_variant (first, t, fld);
>       }
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to