Hi, this patch makes aliasing_component_refs_p little bit stronger, especially with LTO increasing number of disambiguations on tramp3d by 2%.
It took me a while to uderstand that function so a bit summary what it does. Function analyzes chains of nested references like ref1: a.b.c.d.e ref2: c.d.f (Here I assume that type of a is a and type of b is b etc.) On such chains it looks for outermost common type (c) and then compares accesss c.d.e and c.d.f for range overlap. This is safe because we know that both copies of type c are either overlaping or completely different. Walk is done in both directions so ref1: c.d.f ref2: a.b.c.d.e Gives the same answer. In the final step it is assumed that the reference chains do not have common type and may reference one to another only if one is continuation of the other (with some intermediate steps omitted). So function is organized as follows 1) perform walk of ref1 looking for type of base of ref2. If we sucessful use base+offset oracle. 2) perform walk of ref2 looking for type of base of ref1 If we sucessful use base+offset oracle. 3) assume that chains are disjoiont and see of base type of one is subset of ref type of the other (i.e. one can be can be a continuation of the chain). Now same_type_for_tbaa can return -1 for some odd cases which include the case where TYPE_CANONICAL==NULL the function gives up. This is quite common with LTO because TYPE_CANONICAL is NULL for pointers, vectors and arrays and thus we often give up after the innermost reference. If the first walk in 1) terminates with -1 then it still makes sense to do the walk in 2) and see if the common type is found. If there is no common type we need to give up on the final test. I wonder if as an optimization we do not want to terminate the walk when one type is too small to hold the second. Bootstrapped/regtested x86_64-linux, OK? * tree-ssa-alias.c (aliasing_component_refs_p): Walk references both directions even if first walk fails. Index: tree-ssa-alias.c =================================================================== --- tree-ssa-alias.c (revision 270877) +++ tree-ssa-alias.c (working copy) @@ -814,10 +841,7 @@ aliasing_component_refs_p (tree ref1, && same_type_for_tbaa (TREE_TYPE (*refp), type1) == 0) refp = &TREE_OPERAND (*refp, 0); same_p = same_type_for_tbaa (TREE_TYPE (*refp), type1); - /* If we couldn't compare types we have to bail out. */ - if (same_p == -1) - return true; - else if (same_p == 1) + if (same_p == 1) { poly_int64 offadj, sztmp, msztmp; bool reverse; @@ -827,24 +851,31 @@ aliasing_component_refs_p (tree ref1, offset1 -= offadj; return ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2); } - /* If we didn't find a common base, try the other way around. */ - refp = &ref1; - while (handled_component_p (*refp) - && same_type_for_tbaa (TREE_TYPE (*refp), type2) == 0) - refp = &TREE_OPERAND (*refp, 0); - same_p = same_type_for_tbaa (TREE_TYPE (*refp), type2); - /* If we couldn't compare types we have to bail out. */ - if (same_p == -1) - return true; - else if (same_p == 1) + else { - poly_int64 offadj, sztmp, msztmp; - bool reverse; - get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp, &reverse); - offset1 -= offadj; - get_ref_base_and_extent (base2, &offadj, &sztmp, &msztmp, &reverse); - offset2 -= offadj; - return ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2); + int same_p2; + + /* If we didn't find a common base, try the other way around. */ + refp = &ref1; + while (handled_component_p (*refp) + && same_type_for_tbaa (TREE_TYPE (*refp), type2) == 0) + refp = &TREE_OPERAND (*refp, 0); + same_p2 = same_type_for_tbaa (TREE_TYPE (*refp), type2); + if (same_p2 == 1) + { + poly_int64 offadj, sztmp, msztmp; + bool reverse; + get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp, &reverse); + offset1 -= offadj; + get_ref_base_and_extent (base2, &offadj, &sztmp, &msztmp, &reverse); + offset2 -= offadj; + return ranges_maybe_overlap_p (offset1, max_size1, + offset2, max_size2); + } + /* In the remaining test we assume that there is no overlapping type + at all. So if we are unsure, we need to give up. */ + else if (same_p == -1 || same_p2 == -1) + return true; } /* If we have two type access paths B1.path1 and B2.path2 they may