Summary: | bootstrap *using* lto fails | ||
---|---|---|---|
Product: | gcc | Reporter: | Rafael Avila de Espindola <espindola> |
Component: | lto | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | espindola, gcc-bugs, laurent, rainer, rguenth |
Priority: | P3 | ||
Version: | 4.5.0 | ||
Target Milestone: | 4.5.0 | ||
Host: | x86_64-linux-gnu | Target: | x86_64-linux-gnu |
Build: | x86_64-linux-gnu | Known to work: | |
Known to fail: | Last reconfirmed: | 2009-10-11 15:13:42 | |
Attachments: |
testcase
testcase testcase testcase testcase |
Description
Rafael Avila de Espindola
2009-10-05 23:11:54 UTC
Created attachment 18716 [details]
testcase
Created attachment 18717 [details]
testcase
Can you specify how you bootstrapped with LTO (did you use the linker plugin and thus dragged in libbackend.a)? lto1: error: type mismatch in address expression union tree_node * * union tree_node * this is a missed type merging / completion. There are likely very many of this kind - can you try with type-checking disabled? I was trying to do a manual bootstrap. Just compiled a gcc with --disable-bootstrap --with-ld=gold and used that to try to build a new one: CC="$HOME/gcc/inst/bin/gcc -flto -use-linker-plugin" ../gcc-git/configure --enable-lto --enable-gold --with-ld=$HOME/binutils/inst/bin/ld --enable-languages=c --disable-bootstrap will try again with type-checking disabled. Further reducing into an obviously equivalent header appreciated. Created attachment 18722 [details]
testcase
Created attachment 18723 [details]
testcase
Created attachment 18724 [details]
testcase
Ok, so the issue here is that we have typedef struct VEC_constructor_elt_gc { } VEC_constructor_elt_gc; vs. typedef struct VEC_constructor_elt_gcx { } VEC_constructor_elt_gc; which causes us to not merge the two union tree_node types which are typedef union tree_node *tree; union tree_node { tree * use; VEC_constructor_elt_gc *elts; }; And in the end because we look through typedefs here: static hashval_t iterative_hash_type_name (tree type, hashval_t v) { tree name = TYPE_NAME (TYPE_MAIN_VARIANT (type)); Now this is necessary - we'd want to merge union tree_node { tree * use; struct VEC_constructor_elt_gc *elts; }; as well. So - this cannot be fixed by type merging, but instead together with what we need to fix TBAA issues for non-merged types we have to try to cover these issues as well. Now - a C language lawyer could chime in here and tell us if the above invokes undefined behavior. Short: typedef struct A {} T; typedef struct B {} T; is this valid cross translation-unit if T is used across units? Further reduced testcase: b.h --- typedef union tree_node *tree; union tree_node { tree * use; VEC_constructor_elt_gc *elts; }; t1.c: ----- typedef struct VEC_constructor_elt_gc { } VEC_constructor_elt_gc; #include "b.h" struct stmt_tree_s { tree x_cur_stmt_list; }; void *add_stmt (struct stmt_tree_s *x) { return &x->x_cur_stmt_list; } t2.c ---- typedef struct VEC_constructor_elt_gcx { } VEC_constructor_elt_gc; #include "b.h" struct gcc_target { void (* builtin_vec_perm) (tree*); }; extern struct gcc_target targetm; void dwarf2out_begin_prologue (tree t) { (*targetm.builtin_vec_perm) (&t); } struct die_arg_entry_struct { tree arg; }; void *gt_pch_p_20VEC_die_arg_entry_gc (struct die_arg_entry_struct *vec) { return &(vec->arg); } Subject: Re: bootstrap *using* lto fails On Sun, Oct 11, 2009 at 8:13 AM, rguenth at gcc dot gnu dot org <gcc-bugzilla@gcc.gnu.org> wrote: > is this valid cross translation-unit if T is used across units? Yes this is valid for C. In C, types are across TUs are not based on names. This is why the code for -combine was complex with respect of type equality. -- Pinski (In reply to comment #9) > Ok, so the issue here is that we have > > typedef struct VEC_constructor_elt_gc { } VEC_constructor_elt_gc; > > vs. > > typedef struct VEC_constructor_elt_gcx { } VEC_constructor_elt_gc; > > which causes us to not merge the two union tree_node types which are > > typedef union tree_node *tree; > union tree_node { > tree * use; > VEC_constructor_elt_gc *elts; > }; > > And in the end because we look through typedefs here: > > static hashval_t > iterative_hash_type_name (tree type, hashval_t v) > { > tree name = TYPE_NAME (TYPE_MAIN_VARIANT (type)); > > Now this is necessary - we'd want to merge > > union tree_node { > tree * use; > struct VEC_constructor_elt_gc *elts; > }; > > as well. > > So - this cannot be fixed by type merging, but instead together with what > we need to fix TBAA issues for non-merged types we have to try to cover > these issues as well. I am a bit confused why we cannot merge the types. If using structural equality, "struct VEC_constructor_elt_gc" and "struct VEC_constructor_elt_gcx" should be equivalent since they are both {}. With these being equivalent, the two typedefs defining VEC_constructor_elt_gc are equivalent and finally the two "union tree_node" also are. Subject: Re: bootstrap *using* lto fails
On Mon, 12 Oct 2009, espindola at google dot com wrote:
> ------- Comment #12 from espindola at google dot com 2009-10-12 21:02 -------
> (In reply to comment #9)
> > Ok, so the issue here is that we have
> >
> > typedef struct VEC_constructor_elt_gc { } VEC_constructor_elt_gc;
> >
> > vs.
> >
> > typedef struct VEC_constructor_elt_gcx { } VEC_constructor_elt_gc;
> >
> > which causes us to not merge the two union tree_node types which are
> >
> > typedef union tree_node *tree;
> > union tree_node {
> > tree * use;
> > VEC_constructor_elt_gc *elts;
> > };
> >
> > And in the end because we look through typedefs here:
> >
> > static hashval_t
> > iterative_hash_type_name (tree type, hashval_t v)
> > {
> > tree name = TYPE_NAME (TYPE_MAIN_VARIANT (type));
> >
> > Now this is necessary - we'd want to merge
> >
> > union tree_node {
> > tree * use;
> > struct VEC_constructor_elt_gc *elts;
> > };
> >
> > as well.
> >
> > So - this cannot be fixed by type merging, but instead together with what
> > we need to fix TBAA issues for non-merged types we have to try to cover
> > these issues as well.
>
> I am a bit confused why we cannot merge the types.
>
> If using structural equality, "struct VEC_constructor_elt_gc" and "struct
> VEC_constructor_elt_gcx" should be equivalent since they are both {}. With
> these being equivalent, the two typedefs defining VEC_constructor_elt_gc are
> equivalent and finally the two "union tree_node" also are.
We're not really using structural equality. I have patches to go
both ways (more structural equality and less), both cause some
regressions. So I'm digging somewhat further for now.
Richard.
This particular problem seems to be fixed. I'll add a testcase. Subject: Bug 41598 Author: rguenth Date: Fri Oct 16 14:42:47 2009 New Revision: 152904 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=152904 Log: 2009-10-16 Richard Guenther <rguenther@suse.de> PR lto/41598 * gcc.dg/lto/20091016-1_0.c: New testcase. * gcc.dg/lto/20091016-1_1.c: Likewise. * gcc.dg/lto/20091016-1_a.h: Likewise. Added: trunk/gcc/testsuite/gcc.dg/lto/20091016-1_0.c trunk/gcc/testsuite/gcc.dg/lto/20091016-1_1.c trunk/gcc/testsuite/gcc.dg/lto/20091016-1_a.h Modified: trunk/gcc/testsuite/ChangeLog |