Hi, Firefox build ICEs in ipa-devirt (types_same_for_odr) not being able to establish ODR equivalency for non-polymorphic types. This is because ipa-prop and ipa-cp does call get_binfo_at_offset where it really wants to propagate on types and offsets. Before this is fixed this patch avoids the ICE by not doing the propagation when we don't know what to do.
Bootstrapped/regtested x86_64-linux, comitted. Honza * ipa-prop.c (ipa_binfo_from_known_type_jfunc): In LTO do not walk non-polymorphic types. * ipa-cp.c (ipa_get_jf_ancestor_result): Likewise. * ipa-devirt.c (types_same_for_odr): Do not explode when one of types is not polymorphic. Index: ipa-prop.c =================================================================== --- ipa-prop.c (revision 212457) +++ ipa-prop.c (working copy) @@ -560,6 +560,19 @@ ipa_binfo_from_known_type_jfunc (struct if (!base_binfo) return NULL_TREE; + /* FIXME: At LTO we can't propagate to non-polymorphic type, because + we have no ODR equivalency on those. This should be fixed by + propagating on types rather than binfos that would make type + matching here unnecesary. */ + if (in_lto_p + && (TREE_CODE (jfunc->value.known_type.component_type) != RECORD_TYPE + || !TYPE_BINFO (jfunc->value.known_type.component_type) + || !BINFO_VTABLE (TYPE_BINFO (jfunc->value.known_type.component_type)))) + { + if (!jfunc->value.known_type.offset) + return base_binfo; + return NULL; + } return get_binfo_at_offset (base_binfo, jfunc->value.known_type.offset, jfunc->value.known_type.component_type); Index: ipa-cp.c =================================================================== --- ipa-cp.c (revision 212457) +++ ipa-cp.c (working copy) @@ -789,6 +789,19 @@ ipa_get_jf_ancestor_result (struct ipa_j { if (!ipa_get_jf_ancestor_type_preserved (jfunc)) return NULL; + /* FIXME: At LTO we can't propagate to non-polymorphic type, because + we have no ODR equivalency on those. This should be fixed by + propagating on types rather than binfos that would make type + matching here unnecesary. */ + if (in_lto_p + && (TREE_CODE (ipa_get_jf_ancestor_type (jfunc)) != RECORD_TYPE + || !TYPE_BINFO (ipa_get_jf_ancestor_type (jfunc)) + || !BINFO_VTABLE (TYPE_BINFO (ipa_get_jf_ancestor_type (jfunc))))) + { + if (!ipa_get_jf_ancestor_offset (jfunc)) + return input; + return NULL; + } return get_binfo_at_offset (input, ipa_get_jf_ancestor_offset (jfunc), ipa_get_jf_ancestor_type (jfunc)); Index: ipa-devirt.c =================================================================== --- ipa-devirt.c (revision 212457) +++ ipa-devirt.c (working copy) @@ -341,6 +341,20 @@ types_same_for_odr (const_tree type1, co || type_in_anonymous_namespace_p (type2)) return false; + /* See if types are obvoiusly different (i.e. different codes + or polymorphis wrt non-polymorphic). This is not strictly correct + for ODR violating programs, but we can't do better without streaming + ODR names. */ + if (TREE_CODE (type1) != TREE_CODE (type2)) + return false; + if (TREE_CODE (type1) == RECORD_TYPE + && (TYPE_BINFO (type1) == NULL_TREE) != (TYPE_BINFO (type1) == NULL_TREE)) + return false; + if (TREE_CODE (type1) == RECORD_TYPE && TYPE_BINFO (type1) + && (BINFO_VTABLE (TYPE_BINFO (type1)) == NULL_TREE) + != (BINFO_VTABLE (TYPE_BINFO (type2)) == NULL_TREE)) + return false; + /* At the moment we have no way to establish ODR equivlaence at LTO other than comparing virtual table pointrs of polymorphic types. Eventually we should start saving mangled names in TYPE_NAME.