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)); add_tree_to_fld_list (first, fld); return fld_type_variant (first, t, fld); }