On Tue, Nov 24, 2015 at 07:10:01AM +0100, Jan Hubicka wrote: > > On November 23, 2015 5:50:25 PM GMT+01:00, Jan Hubicka <hubi...@ucw.cz> > > wrote: > > >> > > >> I think it also causes the following and one related ICE > > >> > > >> FAIL: gcc.dg/vect/pr62021.c -flto -ffat-lto-objects (internal > > >compiler > > >> error) > > >> > > >> > > >/space/rguenther/src/svn/trunk3/gcc/testsuite/gcc.dg/vect/pr62021.c:7:1: > > > > > >> internal compiler error: in get_alias_set, at alias.c:880^M > > >> 0x7528a7 get_alias_set(tree_node*)^M > > >> /space/rguenther/src/svn/trunk3/gcc/alias.c:880^M > > > > > >Does this one reproduce with mainline? > > > > Yes, testsuite run on x86_64 > > > > All thee ICEs are on the sanity > > >check: > > >gcc_checking_assert (!in_lto_p || !type_with_alias_set_p (t)); > > >which check that in LTO all types that ought to have CANONICAL_TYPE > > >gets CANONICAL_TYPE > > >computed. ICE here probalby means that the type somehow bypassed LTO > > >canonical type merging > > >as well as the TYPE_CANONICAL=MAIN_VARIANT set in lto-streamer.c > > > * lto-streamer-in.c (lto_read_body_or_constructor): Set TYPE_CANONICAL > only for types where LTO sets them. > * tree.c (build_array_type_1): Do ont set TYPE_CANONICAL for LTO. > (make_vector_type): Likewise. > (gimple_canonical_types_compatible_p): Use canonical_type_used_p. > * tree.h (canonical_type_used_p): New inline. > * alias.c (get_alias_set): Handle structural equality for all > types that pass canonical_type_used_p. > (record_component_aliases): Look through all types with > record_component_aliases for possible pointers; sanity check that > the alias sets match. > > * lto.c (iterative_hash_canonical_type): Recruse for all types > which pass !canonical_type_used_p. > (gimple_register_canonical_type_1): Sanity check we do not compute > canonical type of anything with !canonical_type_used_p. > (gimple_register_canonical_type): Skip all types that are > !canonical_type_used_p
Hi, This patch introduces an ICE for an AArch64 testcase: FAIL: gcc.target/aarch64/advsimd-intrinsics/vstX_lane.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (internal compiler error) Excess errors: ...../gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vstX_lane.c:260:6: internal compiler error: in record_component_aliases, at alias.c:1219 0x5ae2a5 record_component_aliases(tree_node*) .../gcc/alias.c:1218 0x5aed46 get_alias_set(tree_node*) .../gcc/alias.c:1068 0x5afe2a get_deref_alias_set(tree_node*) .../gcc/alias.c:697 0x5ae408 get_alias_set(tree_node*) .../gcc/alias.c:845 0xb6bfd7 vn_reference_lookup(tree_node*, tree_node*, vn_lookup_kind, vn_reference_s**) .../gcc/tree-ssa-sccvn.c:2250 0xb7026f visit_reference_op_store .../gcc/tree-ssa-sccvn.c:3310 0xb7026f visit_use .../gcc/tree-ssa-sccvn.c:3558 0xb716b4 process_scc .../gcc/tree-ssa-sccvn.c:3800 0xb716b4 extract_and_process_scc_for_name .../gcc/tree-ssa-sccvn.c:3887 0xb716b4 DFS .../gcc/tree-ssa-sccvn.c:3939 0xb729db sccvn_dom_walker::before_dom_children(basic_block_def*) .../gcc/tree-ssa-sccvn.c:4427 0xec017f dom_walker::walk(basic_block_def*) .../gcc/domwalk.c:176 0xb73aaa run_scc_vn(vn_lookup_kind) .../gcc/tree-ssa-sccvn.c:4550 0xb48278 execute .../gcc/tree-ssa-pre.c:4891 Thanks, James > > Index: lto-streamer-in.c > =================================================================== > --- lto-streamer-in.c (revision 230718) > +++ lto-streamer-in.c (working copy) > @@ -1231,7 +1231,9 @@ lto_read_body_or_constructor (struct lto > if (TYPE_P (t)) > { > gcc_assert (TYPE_CANONICAL (t) == NULL_TREE); > - TYPE_CANONICAL (t) = TYPE_MAIN_VARIANT (t); > + if (type_with_alias_set_p (t) > + && canonical_type_used_p (t)) > + TYPE_CANONICAL (t) = TYPE_MAIN_VARIANT (t); > if (TYPE_MAIN_VARIANT (t) != t) > { > gcc_assert (TYPE_NEXT_VARIANT (t) == NULL_TREE); > Index: tree.c > =================================================================== > --- tree.c (revision 230718) > +++ tree.c (working copy) > @@ -8236,7 +8243,8 @@ build_array_type_1 (tree elt_type, tree > if (TYPE_CANONICAL (t) == t) > { > if (TYPE_STRUCTURAL_EQUALITY_P (elt_type) > - || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type))) > + || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type)) > + || in_lto_p) > SET_TYPE_STRUCTURAL_EQUALITY (t); > else if (TYPE_CANONICAL (elt_type) != elt_type > || (index_type && TYPE_CANONICAL (index_type) != index_type)) > @@ -9849,13 +9857,13 @@ make_vector_type (tree innertype, int nu > SET_TYPE_VECTOR_SUBPARTS (t, nunits); > SET_TYPE_MODE (t, mode); > > - if (TYPE_STRUCTURAL_EQUALITY_P (innertype)) > + if (TYPE_STRUCTURAL_EQUALITY_P (innertype) || in_lto_p) > SET_TYPE_STRUCTURAL_EQUALITY (t); > else if ((TYPE_CANONICAL (innertype) != innertype > || mode != VOIDmode) > && !VECTOR_BOOLEAN_TYPE_P (t)) > TYPE_CANONICAL (t) > - = make_vector_type (TYPE_CANONICAL (innertype), nunits, VOIDmode); > + = make_vector_type (TYPE_CANONICAL (innertype), nunits, VOIDmode); > > layout_type (t); > > @@ -13279,7 +13292,8 @@ gimple_canonical_types_compatible_p (con > TYPE_CANONICAL is more fine grained than the equivalnce we test (where > all pointers are considered equal. Be sure to not return false > negatives. */ > - gcc_checking_assert (!POINTER_TYPE_P (t1) && !POINTER_TYPE_P (t2)); > + gcc_checking_assert (canonical_type_used_p (t1) > + && canonical_type_used_p (t2)); > return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2); > } > > Index: tree.h > =================================================================== > --- tree.h (revision 230718) > +++ tree.h (working copy) > @@ -4807,7 +4807,9 @@ extern void DEBUG_FUNCTION verify_type ( > extern bool gimple_canonical_types_compatible_p (const_tree, const_tree, > bool trust_type_canonical = > true); > extern bool type_with_interoperable_signedness (const_tree); > -/* Return simplified tree code of type that is used for canonical type > merging. */ > + > +/* Return simplified tree code of type that is used for canonical type > + merging. */ > inline enum tree_code > tree_code_for_canonical_type_merging (enum tree_code code) > { > @@ -4829,6 +4831,23 @@ tree_code_for_canonical_type_merging (en > return code; > } > > +/* Return ture if get_alias_set care about TYPE_CANONICAL of given type. > + We don't define the types for pointers, arrays and vectors. The reason is > + that pointers are handled specially: ptr_type_node accesses conflict with > + accesses to all other pointers. This is done by alias.c. > + Because alias sets of arrays and vectors are the same as types of their > + elements, we can't compute canonical type either. Otherwise we could go > + form void *[10] to int *[10] (because they are equivalent for canonical > type > + machinery) and get wrong TBAA. */ > + > +inline bool > +canonical_type_used_p (const_tree t) > +{ > + return !(POINTER_TYPE_P (t) > + || TREE_CODE (t) == ARRAY_TYPE > + || TREE_CODE (t) == VECTOR_TYPE); > +} > + > #define tree_map_eq tree_map_base_eq > extern unsigned int tree_map_hash (const void *); > #define tree_map_marked_p tree_map_base_marked_p > Index: alias.c > =================================================================== > --- alias.c (revision 230718) > +++ alias.c (working copy) > @@ -869,11 +870,11 @@ get_alias_set (tree t) > set = lang_hooks.get_alias_set (t); > if (set != -1) > return set; > - /* Handle structure type equality for pointer types. This is easy > - to do, because the code bellow ignore canonical types on these anyway. > - This is important for LTO, where TYPE_CANONICAL for pointers can not > - be meaningfuly computed by the frotnend. */ > - if (!POINTER_TYPE_P (t)) > + /* Handle structure type equality for pointer types, arrays and > vectors. > + This is easy to do, because the code bellow ignore canonical types on > + these anyway. This is important for LTO, where TYPE_CANONICAL for > + pointers can not be meaningfuly computed by the frotnend. */ > + if (canonical_type_used_p (t)) > { > /* In LTO we set canonical types for all types where it makes > sense to do so. Double check we did not miss some type. */ > @@ -929,7 +931,9 @@ get_alias_set (tree t) > integer(kind=4)[4] the same alias set or not. > Just be pragmatic here and make sure the array and its element > type get the same alias set assigned. */ > - else if (TREE_CODE (t) == ARRAY_TYPE && !TYPE_NONALIASED_COMPONENT (t)) > + else if (TREE_CODE (t) == ARRAY_TYPE > + && (!TYPE_NONALIASED_COMPONENT (t) > + || TYPE_STRUCTURAL_EQUALITY_P (t))) > set = get_alias_set (TREE_TYPE (t)); > > /* From the former common C and C++ langhook implementation: > @@ -971,7 +975,10 @@ get_alias_set (tree t) > We also want to make pointer to array/vector equivalent to pointer to > its element (see the reasoning above). Skip all those types, too. */ > for (p = t; POINTER_TYPE_P (p) > - || (TREE_CODE (p) == ARRAY_TYPE && !TYPE_NONALIASED_COMPONENT (p)) > + || (TREE_CODE (p) == ARRAY_TYPE > + && (!TYPE_NONALIASED_COMPONENT (p) > + || !COMPLETE_TYPE_P (p) > + || TYPE_STRUCTURAL_EQUALITY_P (p))) > || TREE_CODE (p) == VECTOR_TYPE; > p = TREE_TYPE (p)) > { > @@ -1195,20 +1203,23 @@ record_component_aliases (tree type) > Accesses to it conflicts with accesses to any other pointer > type. */ > tree t = TREE_TYPE (field); > - if (in_lto_p) > + if (in_lto_p) > { > /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their > element type and that type has to be normalized to void *, > too, in the case it is a pointer. */ > - while ((TREE_CODE (t) == ARRAY_TYPE > - && (!COMPLETE_TYPE_P (t) > - || TYPE_NONALIASED_COMPONENT (t))) > - || TREE_CODE (t) == VECTOR_TYPE) > - t = TREE_TYPE (t); > + while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t)) > + { > + gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t)); > + t = TREE_TYPE (t); > + } > if (POINTER_TYPE_P (t)) > t = ptr_type_node; > + else if (flag_checking) > + gcc_checking_assert (get_alias_set (t) > + == get_alias_set (TREE_TYPE (field))); > } > - > + > record_alias_subset (superset, get_alias_set (t)); > } > break; > Index: lto/lto.c > =================================================================== > --- lto/lto.c (revision 230718) > +++ lto/lto.c (working copy) > @@ -389,9 +389,7 @@ iterative_hash_canonical_type (tree type > /* All type variants have same TYPE_CANONICAL. */ > type = TYPE_MAIN_VARIANT (type); > > - /* We do not compute TYPE_CANONICAl of POINTER_TYPE because the aliasing > - code never use it anyway. */ > - if (POINTER_TYPE_P (type)) > + if (!canonical_type_used_p (type)) > v = hash_canonical_type (type); > /* An already processed type. */ > else if (TYPE_CANONICAL (type)) > @@ -444,7 +442,7 @@ gimple_register_canonical_type_1 (tree t > > gcc_checking_assert (TYPE_P (t) && !TYPE_CANONICAL (t) > && type_with_alias_set_p (t) > - && !POINTER_TYPE_P (t)); > + && canonical_type_used_p (t)); > > slot = htab_find_slot_with_hash (gimple_canonical_types, t, hash, INSERT); > if (*slot) > @@ -477,7 +475,8 @@ gimple_register_canonical_type_1 (tree t > static void > gimple_register_canonical_type (tree t) > { > - if (TYPE_CANONICAL (t) || !type_with_alias_set_p (t) || POINTER_TYPE_P (t)) > + if (TYPE_CANONICAL (t) || !type_with_alias_set_p (t) > + || !canonical_type_used_p (t)) > return; > > /* Canonical types are same among all complete variants. */ >