Bug 41598 - bootstrap *using* lto fails
Summary: bootstrap *using* lto fails
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: lto (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: 4.5.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-10-05 23:11 UTC by Rafael Avila de Espindola
Modified: 2009-10-16 14:30 UTC (History)
5 users (show)

See Also:
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 (8.49 KB, application/octet-stream)
2009-10-05 23:12 UTC, Rafael Avila de Espindola
Details
testcase (8.93 KB, application/octet-stream)
2009-10-05 23:12 UTC, Rafael Avila de Espindola
Details
testcase (81 bytes, text/x-chdr)
2009-10-06 13:55 UTC, Rafael Avila de Espindola
Details
testcase (176 bytes, application/octet-stream)
2009-10-06 13:56 UTC, Rafael Avila de Espindola
Details
testcase (319 bytes, application/octet-stream)
2009-10-06 13:56 UTC, Rafael Avila de Espindola
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Rafael Avila de Espindola 2009-10-05 23:11:54 UTC
To reproduce with the delta reduced test

cc1 dwarf2out.i -quiet -O2 -flto -o dwarf2out.s
as -V -Qy -o dwarf2out.o dwarf2out.s
cc1 c-decl.i -quiet -O2  -flto -o c-decl.s 
as -V -Qy -o c-decl.o c-decl.s
lto1 -quiet -O2 c-decl.o dwarf2out.o -o /dev/null

Produces:
------------------------------------------------
In function 'gt_pch_p_20VEC_die_arg_entry_gc':
lto1: error: type mismatch in address expression
union tree_node * *

union tree_node *

D.2877_8 = &x_3->base.vec[i0_1].arg;

lto1: internal compiler error: verify_stmts failed
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
------------------------------------------------------
Comment 1 Rafael Avila de Espindola 2009-10-05 23:12:19 UTC
Created attachment 18716 [details]
testcase
Comment 2 Rafael Avila de Espindola 2009-10-05 23:12:38 UTC
Created attachment 18717 [details]
testcase
Comment 3 Richard Biener 2009-10-06 10:15:59 UTC
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?
Comment 4 Rafael Avila de Espindola 2009-10-06 12:37:29 UTC
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.
Comment 5 Richard Biener 2009-10-06 12:45:17 UTC
Further reducing into an obviously equivalent header appreciated.
Comment 6 Rafael Avila de Espindola 2009-10-06 13:55:52 UTC
Created attachment 18722 [details]
testcase
Comment 7 Rafael Avila de Espindola 2009-10-06 13:56:12 UTC
Created attachment 18723 [details]
testcase
Comment 8 Rafael Avila de Espindola 2009-10-06 13:56:28 UTC
Created attachment 18724 [details]
testcase
Comment 9 Richard Biener 2009-10-11 15:13:41 UTC
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?
Comment 10 Richard Biener 2009-10-11 15:33:12 UTC
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);
}
Comment 11 pinskia@gmail.com 2009-10-11 17:48:29 UTC
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
Comment 12 Rafael Avila de Espindola 2009-10-12 21:02:05 UTC
(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.

Comment 13 rguenther@suse.de 2009-10-12 21:03:56 UTC
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.
Comment 14 Richard Biener 2009-10-16 14:30:29 UTC
This particular problem seems to be fixed.  I'll add a testcase.
Comment 15 Richard Biener 2009-10-16 14:43:09 UTC
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