This fixes PR49078 by restricting the assert in get_alias_set to the case where it matters. We know that how types generated during optimization have TYPE_CANONICAL computed differs from what the LTO machinery does, the patch documents that and reverts a previous attempt to fix parts of this inconsistency.
LTO profile-bootstrapped and tested on x86_64-unknown-linux-gnu, SPEC 2k6 built, applied to trunk. Richard. 2011-05-24 Richard Guenther <rguent...@suse.de> PR bootstrap/49078 * gimple.c (gimple_register_canonical_type): Revert previous change. * alias.c (get_alias_set): Only assert that TYPE_CANONICAL does not for a tree for the case where it matters. Cache pointer-type alias-sets. Index: gcc/gimple.c =================================================================== --- gcc/gimple.c (revision 174106) +++ gcc/gimple.c (working copy) @@ -4779,7 +4802,12 @@ gimple_canonical_type_eq (const void *p1 /* Register type T in the global type table gimple_types. If another type T', compatible with T, already existed in gimple_types then return T', otherwise return T. This is used by - LTO to merge identical types read from different TUs. */ + LTO to merge identical types read from different TUs. + + ??? This merging does not exactly match how the tree.c middle-end + functions will assign TYPE_CANONICAL when new types are created + during optimization (which at least happens for pointer and array + types). */ tree gimple_register_canonical_type (tree t) @@ -4800,25 +4828,6 @@ gimple_register_canonical_type (tree t) if (TYPE_CANONICAL (t)) return TYPE_CANONICAL (t); - /* For pointer and reference types do as the middle-end does - the - canonical type is a pointer to the canonical pointed-to type. */ - if (TREE_CODE (t) == POINTER_TYPE) - { - TYPE_CANONICAL (t) - = build_pointer_type_for_mode - (gimple_register_canonical_type (TREE_TYPE (t)), - TYPE_MODE (t), TYPE_REF_CAN_ALIAS_ALL (t)); - return TYPE_CANONICAL (t); - } - else if (TREE_CODE (t) == REFERENCE_TYPE) - { - TYPE_CANONICAL (t) - = build_reference_type_for_mode - (gimple_register_canonical_type (TREE_TYPE (t)), - TYPE_MODE (t), TYPE_REF_CAN_ALIAS_ALL (t)); - return TYPE_CANONICAL (t); - } - if (gimple_canonical_types == NULL) gimple_canonical_types = htab_create_ggc (16381, gimple_canonical_type_hash, gimple_canonical_type_eq, 0); Index: gcc/alias.c =================================================================== --- gcc/alias.c (revision 174106) +++ gcc/alias.c (working copy) @@ -709,10 +709,8 @@ get_alias_set (tree t) t = TYPE_CANONICAL (t); - /* Canonical types shouldn't form a tree nor should the canonical - type require structural equality checks. */ - gcc_checking_assert (TYPE_CANONICAL (t) == t - && !TYPE_STRUCTURAL_EQUALITY_P (t)); + /* The canonical type should not require structural equality checks. */ + gcc_checking_assert (!TYPE_STRUCTURAL_EQUALITY_P (t)); /* If this is a type with a known alias set, return it. */ if (TYPE_ALIAS_SET_KNOWN_P (t)) @@ -813,11 +811,19 @@ get_alias_set (tree t) That's simple and avoids all the above problems. */ else if (POINTER_TYPE_P (t) && t != ptr_type_node) - return get_alias_set (ptr_type_node); + set = get_alias_set (ptr_type_node); /* Otherwise make a new alias set for this type. */ else - set = new_alias_set (); + { + /* Each canonical type gets its own alias set, so canonical types + shouldn't form a tree. It doesn't really matter for types + we handle specially above, so only check it where it possibly + would result in a bogus alias set. */ + gcc_checking_assert (TYPE_CANONICAL (t) == t); + + set = new_alias_set (); + } TYPE_ALIAS_SET (t) = set;