diff mbox

[PR,79905] ICE with vector_type

Message ID f93202b6-dc3e-b41d-29e8-5182cc1ce3a7@acm.org
State New
Headers show

Commit Message

Nathan Sidwell April 3, 2017, 7:03 p.m. UTC
Bill,
can you give this patch a spin please? I've smoke tested it on a ppc64le 
x-compiler, but don't have one to run executables.  regression testing 
on an x86_64-linux system is ok.

The DEPENDENT_TYPE_VALID_P thing is a red herring.

It is the canonical type table's equal function considering most types 
with different TYPE_NAMEs to be different.  Now, you might think that 
only applies to things like RECORD_TYPE, but no,  wchar_t is different 
from plain int, for example.

However, as you can see there's already a get-out for COMPLEX_TYPE, and 
I think the same is needed for VECTOR_TYPE.

Both set_underlying_type and rs6000 set the builtin vector type's 
TYPE_NAME, and so one constructed via applying 
__attribute__((vector_size(16))) will never match.   And it should.

nathan

Comments

Richard Biener April 4, 2017, 8:27 a.m. UTC | #1
On Mon, Apr 3, 2017 at 9:03 PM, Nathan Sidwell <nathan@acm.org> wrote:
> Bill,
> can you give this patch a spin please? I've smoke tested it on a ppc64le
> x-compiler, but don't have one to run executables.  regression testing on an
> x86_64-linux system is ok.
>
> The DEPENDENT_TYPE_VALID_P thing is a red herring.
>
> It is the canonical type table's equal function considering most types with
> different TYPE_NAMEs to be different.  Now, you might think that only
> applies to things like RECORD_TYPE, but no,  wchar_t is different from plain
> int, for example.
>
> However, as you can see there's already a get-out for COMPLEX_TYPE, and I
> think the same is needed for VECTOR_TYPE.

Hmm, but that is essentially a hack given that build_complex_type does things
it shouldn't (assign a name to the type).  make_vector_type doesn't do that so
it shouldn't get such special-handing.

> Both set_underlying_type and rs6000 set the builtin vector type's TYPE_NAME,
> and so one constructed via applying __attribute__((vector_size(16))) will
> never match.   And it should.

why?  They only need to share the canonical type not the type node itself
(unless their name is the same, of course).

Now -- that name comparing is somewhat odd.  We hash type "variants"
with different names the same (so setting the name after inserting sth into
the hash is allowed, but it will overwrite the old entry so any unnamed uses
up to now get a type with a name...).  I guess we'd be better off leaving
only unnamed types in the hash and building a type variant whenever we
add a name to such type.

Richard.


> nathan
> --
> Nathan Sidwell
>
Nathan Sidwell April 4, 2017, 11:31 a.m. UTC | #2
On 04/04/2017 04:27 AM, Richard Biener wrote:
> On Mon, Apr 3, 2017 at 9:03 PM, Nathan Sidwell <nathan@acm.org> wrote:

>> However, as you can see there's already a get-out for COMPLEX_TYPE, and I
>> think the same is needed for VECTOR_TYPE.
>
> Hmm, but that is essentially a hack given that build_complex_type does things
> it shouldn't (assign a name to the type).

Oh, didn't know that.

>> Both set_underlying_type and rs6000 set the builtin vector type's TYPE_NAME,
>> and so one constructed via applying __attribute__((vector_size(16))) will
>> never match.   And it should.
>
> why?  They only need to share the canonical type not the type node itself
> (unless their name is the same, of course).

Correct, that's what I meant.  the canonical type equal function must 
match a just-consed vector with the already-hashed builtin.

> Now -- that name comparing is somewhat odd.  We hash type "variants"
> with different names the same (so setting the name after inserting sth into
> the hash is allowed, but it will overwrite the old entry so any unnamed uses
> up to now get a type with a name...).  I guess we'd be better off leaving
> only unnamed types in the hash and building a type variant whenever we
> add a name to such type.

Right, the name matching surprised me, and my first attempt was to 
remove it.  but that breaks wchar_t.  wchar_t is the same representation 
as int (pedantically, some integral type), but is a distinct type (in 
C++ at least, I don't think C cares).  The canonical type system records 
language-level distinctness, not representation distinctness.

The difference between wchar_t and vector types is the only way to get a 
type the same as wchar_t is to use 'wchar_t' (so we have to start with a 
type at least as canonical as what we want).  Whereas vector types are 
constructed via applying attributes to some underlying scalar type (so 
we have to go find the canonical type).

It would therefore seem that this code in set_underlying_type 
(c-common.c) is wrong:
   if (DECL_IS_BUILTIN (x) && TREE_CODE (TREE_TYPE (x)) != ARRAY_TYPE)
     {
       if (TYPE_NAME (TREE_TYPE (x)) == 0)
	TYPE_NAME (TREE_TYPE (x)) = x;
     }

And this rs6000.c code is totally bogus:
   tdecl = add_builtin_type ("__vector unsigned int", 
unsigned_V4SI_type_node);
   TYPE_NAME (unsigned_V4SI_type_node) = tdecl; <-- this line

(note that at this point, add_builtin_type has already set the TYPE_NAME 
via set_underlying type)

For C++'s creation of the wchar_t node, we'd need to special case 
setting the node's name in some way?

[char16_t and char32_t have the same distinctness property as wchar_t. 
I think that's the complete set]

nathan
Richard Biener April 4, 2017, 1 p.m. UTC | #3
On Tue, Apr 4, 2017 at 1:31 PM, Nathan Sidwell <nathan@acm.org> wrote:
> On 04/04/2017 04:27 AM, Richard Biener wrote:
>>
>> On Mon, Apr 3, 2017 at 9:03 PM, Nathan Sidwell <nathan@acm.org> wrote:
>
>
>>> However, as you can see there's already a get-out for COMPLEX_TYPE, and I
>>> think the same is needed for VECTOR_TYPE.
>>
>>
>> Hmm, but that is essentially a hack given that build_complex_type does
>> things
>> it shouldn't (assign a name to the type).
>
>
> Oh, didn't know that.
>
>>> Both set_underlying_type and rs6000 set the builtin vector type's
>>> TYPE_NAME,
>>> and so one constructed via applying __attribute__((vector_size(16))) will
>>> never match.   And it should.
>>
>>
>> why?  They only need to share the canonical type not the type node itself
>> (unless their name is the same, of course).
>
>
> Correct, that's what I meant.  the canonical type equal function must match
> a just-consed vector with the already-hashed builtin.
>
>> Now -- that name comparing is somewhat odd.  We hash type "variants"
>> with different names the same (so setting the name after inserting sth
>> into
>> the hash is allowed, but it will overwrite the old entry so any unnamed
>> uses
>> up to now get a type with a name...).  I guess we'd be better off leaving
>> only unnamed types in the hash and building a type variant whenever we
>> add a name to such type.
>
>
> Right, the name matching surprised me, and my first attempt was to remove
> it.  but that breaks wchar_t.  wchar_t is the same representation as int
> (pedantically, some integral type), but is a distinct type (in C++ at least,
> I don't think C cares).  The canonical type system records language-level
> distinctness, not representation distinctness.
>
> The difference between wchar_t and vector types is the only way to get a
> type the same as wchar_t is to use 'wchar_t' (so we have to start with a
> type at least as canonical as what we want).  Whereas vector types are
> constructed via applying attributes to some underlying scalar type (so we
> have to go find the canonical type).
>
> It would therefore seem that this code in set_underlying_type (c-common.c)
> is wrong:
>   if (DECL_IS_BUILTIN (x) && TREE_CODE (TREE_TYPE (x)) != ARRAY_TYPE)
>     {
>       if (TYPE_NAME (TREE_TYPE (x)) == 0)
>         TYPE_NAME (TREE_TYPE (x)) = x;
>     }

This is quite a fragile area -- you also have to watch dwarf2out.c.  Most of the
TYPE_NAME "hacks" are to make debuginfo happy.

> And this rs6000.c code is totally bogus:
>   tdecl = add_builtin_type ("__vector unsigned int",
> unsigned_V4SI_type_node);
>   TYPE_NAME (unsigned_V4SI_type_node) = tdecl; <-- this line

Yeah, not sure what that like is for -- add_builtin_type properly adds a name.
Note it may be again to make debuginfo happy ;)

tree
add_builtin_type (const char *name, tree type)
{
  tree   id = get_identifier (name);
  tree decl = build_decl (BUILTINS_LOCATION, TYPE_DECL, id, type);
  return lang_hooks.decls.pushdecl (decl);
}

this seems to miss setting TYPE_NAME (type) = decl - oh, that may be
what set_underlying_type does via the langhook.

> (note that at this point, add_builtin_type has already set the TYPE_NAME via
> set_underlying type)
>
> For C++'s creation of the wchar_t node, we'd need to special case setting
> the node's name in some way?
>
> [char16_t and char32_t have the same distinctness property as wchar_t. I
> think that's the complete set]

At this point I'd rather restrict fiddling in this fragile area in
rs6000.c only ;)

Does removing the TYPE_NAME setting fix things?

Richard.

> nathan
>
> --
> Nathan Sidwell
diff mbox

Patch

Index: tree.c
===================================================================
--- tree.c	(revision 246647)
+++ tree.c	(working copy)
@@ -7005,10 +7005,11 @@  type_cache_hasher::equal (type_hash *a,
   if (a->hash != b->hash
       || TREE_CODE (a->type) != TREE_CODE (b->type)
       || TREE_TYPE (a->type) != TREE_TYPE (b->type)
-      || !attribute_list_equal (TYPE_ATTRIBUTES (a->type),
-				 TYPE_ATTRIBUTES (b->type))
       || (TREE_CODE (a->type) != COMPLEX_TYPE
-          && TYPE_NAME (a->type) != TYPE_NAME (b->type)))
+	  && TREE_CODE (a->type) != VECTOR_TYPE
+          && TYPE_NAME (a->type) != TYPE_NAME (b->type))
+      || !attribute_list_equal (TYPE_ATTRIBUTES (a->type),
+				TYPE_ATTRIBUTES (b->type)))
     return 0;
 
   /* Be careful about comparing arrays before and after the element type