> I don't think it works like this, peeling arrays/vectors from > types individually instead of in lock-step? > > I think for better testing coverage you want to force > TYPE_STRUCTURAL_EQUALITY on all types here - this shouldn't > make things invalid but otherwise these code-paths are not > tested very well.
Here is coverage of the function compiling tramp3d with -flto. All the paths through are relatively frequent. Most of time we call function for case where type1 and type2 have same main variants. Out of 1.5m remaining cases approx 30k are pointers/arrays and go the structural walk which in 17k cases goes to mismatched pointer types. 2k cases are considered equivalent because of canonical check and 126k cases we disprove equivalence. -: 780:/* Return 1 if TYPE1 and TYPE2 are to be considered equivalent for the -: 781: purpose of TBAA. Return 0 if they are distinct and -1 if we cannot -: 782: decide. */ -: 783: -: 784:static inline int 669818: 785:same_type_for_tbaa (tree type1, tree type2) -: 786:{ 669818: 787: type1 = TYPE_MAIN_VARIANT (type1); 669818: 788: type2 = TYPE_MAIN_VARIANT (type2); -: 789: -: 790: /* If same_type_for_tbaa returns true we make an assumption that pointers to -: 791: TYPE1 and TYPE2 can either point to same copy of the type or completely -: 792: different. -: 793: -: 794: This is not necessarily true for arrays where overlap can be partial -: 795: as in gcc.dg/torture/alias-2.c. So we can only prove that arrays are -: 796: disjoint becuase they are derived from different types but we can not -: 797: prove they are same. -: 798: -: 799: On the other hand for pointers we can always consider them to be same -: 800: unless we can prove that pointed-to types are different. -: 801: -: 802: So normally return values are -: 803: 0 if types are known to be different -: 804: 1 if types are same and there is no partial overlap -: 805: -1 otherwise. -: 806: -: 807: However if comparing two pointers return values are -: 808: 0 if pointed to types are known to be different -: 809: 1 otherwise (because partial overlaps do not happen). -: 810: -: 811: If comparing array or vector to other type return values are -: 812: 0 if types array/vector are derived from are known to be different -: 813: -1 otherwise (to watch for partial overlaps). */ -: 814: 669818: 815: bool in_ptr = false; 669818: 816: bool in_array = false; -: 817: 669818: 818: if (type1 == type2) 515089: 819: return 1; -: 820: -: 821: /* Do structural comparsion for types that have no canonical types in LTO. */ 162119: 822: while (TYPE_STRUCTURAL_EQUALITY_P (type1) 162119: 823: || TYPE_STRUCTURAL_EQUALITY_P (type2)) -: 824: { -: 825: /* Pointer types are same if they point to same types. */ 30761: 826: if (POINTER_TYPE_P (type1) && POINTER_TYPE_P (type2)) -: 827: { 4662: 828: type1 = TYPE_MAIN_VARIANT (TREE_TYPE (type1)); 4662: 829: type2 = TYPE_MAIN_VARIANT (TREE_TYPE (type2)); 4662: 830: if (!in_array) 4662: 831: in_ptr = true; -: 832: } -: 833: /* Peel out arrays and vector to compare inner types. */ 52198: 834: else if ((TREE_CODE (type1) == ARRAY_TYPE 23728: 835: || TREE_CODE (type1) == VECTOR_TYPE) 49827: 836: && TYPE_STRUCTURAL_EQUALITY_P (type1)) -: 837: { 2371: 838: type1 = TYPE_MAIN_VARIANT (TREE_TYPE (type1)); 2371: 839: if (!in_ptr) 2371: 840: in_array = true; -: 841: } 47456: 842: else if ((TREE_CODE (type2) == ARRAY_TYPE 21042: 843: || TREE_CODE (type2) == VECTOR_TYPE) 44770: 844: && TYPE_STRUCTURAL_EQUALITY_P (type2)) -: 845: { 2686: 846: type2 = TYPE_MAIN_VARIANT (TREE_TYPE (type2)); 2686: 847: if (!in_ptr) 2686: 848: in_array = true; -: 849: } -: 850: else -: 851: { 21042: 852: if (POINTER_TYPE_P (type1) != POINTER_TYPE_P (type2)) 17208: 853: return 0; 3834*: 854: return in_ptr ? 1 : -1; -: 855: } -: 856: 9719: 857: if (type1 == type2) 2329: 858: return in_array ? -1 : 1; -: 859: } -: 860: -: 861: /* Compare the canonical types. */ 131358: 862: if (TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2)) 2604*: 863: return in_array ? -1 : 1; -: 864: -: 865: /* ??? Array types are not properly unified in all cases as we have -: 866: spurious changes in the index types for example. Removing this -: 867: causes all sorts of problems with the Fortran frontend. */ 128754: 868: if (TREE_CODE (type1) == ARRAY_TYPE #####: 869: && TREE_CODE (type2) == ARRAY_TYPE) #####: 870: return in_ptr ? 1 : -1; -: 871: -: 872: /* ??? In Ada, an lvalue of an unconstrained type can be used to access an -: 873: object of one of its constrained subtypes, e.g. when a function with an -: 874: unconstrained parameter passed by reference is called on an object and -: 875: inlined. But, even in the case of a fixed size, type and subtypes are -: 876: not equivalent enough as to share the same TYPE_CANONICAL, since this -: 877: would mean that conversions between them are useless, whereas they are -: 878: not (e.g. type and subtypes can have different modes). So, in the end, -: 879: they are only guaranteed to have the same alias set. */ 128754: 880: if (get_alias_set (type1) == get_alias_set (type2)) 1950*: 881: return in_ptr ? 1 : -1; -: 882: -: 883: /* The types are known to be not equal. */ 126804: 884: return 0; -: 885:} Here is profile with unpatched version -: 780:/* Return 1 if TYPE1 and TYPE2 are to be considered equivalent for the -: 781: purpose of TBAA. Return 0 if they are distinct and -1 if we cannot -: 782: decide. */ -: 783: -: 784:static inline int 610943: 785:same_type_for_tbaa (tree type1, tree type2) -: 786:{ 610943: 787: type1 = TYPE_MAIN_VARIANT (type1); 610943: 788: type2 = TYPE_MAIN_VARIANT (type2); -: 789: -: 790: /* If we would have to do structural comparison bail out. */ 610943: 791: if (TYPE_STRUCTURAL_EQUALITY_P (type1) 610943: 792: || TYPE_STRUCTURAL_EQUALITY_P (type2)) 36090: 793: return -1; -: 794: -: 795: /* Compare the canonical types. */ 574853: 796: if (TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2)) 452828: 797: return 1; -: 798: -: 799: /* ??? Array types are not properly unified in all cases as we have -: 800: spurious changes in the index types for example. Removing this -: 801: causes all sorts of problems with the Fortran frontend. */ 122025: 802: if (TREE_CODE (type1) == ARRAY_TYPE #####: 803: && TREE_CODE (type2) == ARRAY_TYPE) #####: 804: return -1; -: 805: -: 806: /* ??? In Ada, an lvalue of an unconstrained type can be used to access an -: 807: object of one of its constrained subtypes, e.g. when a function with an -: 808: unconstrained parameter passed by reference is called on an object and -: 809: inlined. But, even in the case of a fixed size, type and subtypes are -: 810: not equivalent enough as to share the same TYPE_CANONICAL, since this -: 811: would mean that conversions between them are useless, whereas they are -: 812: not (e.g. type and subtypes can have different modes). So, in the end, -: 813: they are only guaranteed to have the same alias set. */ 122025: 814: if (get_alias_set (type1) == get_alias_set (type2)) 1945: 815: return -1; -: 816: -: 817: /* The types are known to be not equal. */ 120080: 818: return 0; -: 819:} I have started bootstrap where the pointer and array walks are forced even for non-lto builds. Honza