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 <[email protected]>
> > 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. */
>