On Fri, 14 Jun 2019, Jan Hubicka wrote: > > > > I think this is still error-prone since we look past > > VIEW_CONVERT_EXPRs in the path so we happily disambiguate, > > say, > > > > struct X { int e; int d; }; > > struct Y { int d; int e; }; > > > > VIEW_CONVERT<X>(p->b).d > > VIEW_CONVERT<Y>(q->b).e > > > > where in reality only the access paths from the base up to > > the first view-conversion are relevant for path-based > > analysis. > > > > So upon seeing a VIEW_CONVERT (or BIT_FIELD_REF which > > has the same issue) simply truncate the vector. > > > > As said, it's a pre-existing issue but you are extending > > things to possibly handle more stuff... > > > > Otherwise looks good. > OK, i added the check and also managed to construct testcase that we do > not optimize otherwise. > > I think same view convert bug ought to exist also in > aliasing_component_refs_p and IMO ao_ref_alias set should also look > for VCEs otherwise I can't make sense of > > /* First defer to TBAA if possible. */ > if (tbaa_p > && flag_strict_aliasing > && !alias_sets_conflict_p (ao_ref_alias_set (ref1), > ao_ref_alias_set (ref2))) > return false;
get_alias_set already handles VCEs properly. Btw I've said BIT_FIELD_REF has the same issue but you didn't include that case below. Richard. > Honza > > * gcc.dg/tree-ssa/alias-access-path-2.c: New testcase. > > * tree-ssa-alias.c (alias_stats): Add > nonoverlapping_component_refs_p_may_alias, > nonoverlapping_component_refs_p_no_alias, > nonoverlapping_component_refs_of_decl_p_may_alias, > nonoverlapping_component_refs_of_decl_p_no_alias. > (dump_alias_stats): Dump them. > (nonoverlapping_component_refs_of_decl_p): Add stats. > (nonoverlapping_component_refs_p): Add stats; do not stop on first > ARRAY_REF. > > Index: testsuite/gcc.dg/tree-ssa/alias-access-path-2.c > =================================================================== > --- testsuite/gcc.dg/tree-ssa/alias-access-path-2.c (nonexistent) > +++ testsuite/gcc.dg/tree-ssa/alias-access-path-2.c (working copy) > @@ -0,0 +1,22 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-fre3" } */ > +struct a { > + int val; > +}; > +struct b { > + struct a a[10],a2[10]; > +}; > +struct c { > + struct b b[10]; > +} *cptr; > + > +struct d {struct c c;} *dptr; > + > +int > +test (int i, int j, int k, int l) > +{ > + cptr->b[i].a[j].val=123; > + dptr->c.b[k].a2[l].val=2; > + return cptr->b[i].a[j].val; > +} > +/* { dg-final { scan-tree-dump-times "return 123" 1 "fre3"} } */ > Index: tree-ssa-alias.c > =================================================================== > --- tree-ssa-alias.c (revision 272283) > +++ tree-ssa-alias.c (working copy) > @@ -100,6 +100,10 @@ static struct { > unsigned HOST_WIDE_INT call_may_clobber_ref_p_no_alias; > unsigned HOST_WIDE_INT aliasing_component_refs_p_may_alias; > unsigned HOST_WIDE_INT aliasing_component_refs_p_no_alias; > + unsigned HOST_WIDE_INT nonoverlapping_component_refs_p_may_alias; > + unsigned HOST_WIDE_INT nonoverlapping_component_refs_p_no_alias; > + unsigned HOST_WIDE_INT nonoverlapping_component_refs_of_decl_p_may_alias; > + unsigned HOST_WIDE_INT nonoverlapping_component_refs_of_decl_p_no_alias; > } alias_stats; > > void > @@ -124,7 +128,19 @@ dump_alias_stats (FILE *s) > alias_stats.call_may_clobber_ref_p_no_alias, > alias_stats.call_may_clobber_ref_p_no_alias > + alias_stats.call_may_clobber_ref_p_may_alias); > - fprintf (s, " aliasing_component_ref_p: " > + fprintf (s, " nonoverlapping_component_refs_p: " > + HOST_WIDE_INT_PRINT_DEC" disambiguations, " > + HOST_WIDE_INT_PRINT_DEC" queries\n", > + alias_stats.nonoverlapping_component_refs_p_no_alias, > + alias_stats.nonoverlapping_component_refs_p_no_alias > + + alias_stats.nonoverlapping_component_refs_p_may_alias); > + fprintf (s, " nonoverlapping_component_refs_of_decl_p: " > + HOST_WIDE_INT_PRINT_DEC" disambiguations, " > + HOST_WIDE_INT_PRINT_DEC" queries\n", > + alias_stats.nonoverlapping_component_refs_of_decl_p_no_alias, > + alias_stats.nonoverlapping_component_refs_of_decl_p_no_alias > + + alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias); > + fprintf (s, " aliasing_component_refs_p: " > HOST_WIDE_INT_PRINT_DEC" disambiguations, " > HOST_WIDE_INT_PRINT_DEC" queries\n", > alias_stats.aliasing_component_refs_p_no_alias, > @@ -1047,7 +1063,10 @@ nonoverlapping_component_refs_of_decl_p > if (TREE_CODE (ref1) == MEM_REF) > { > if (!integer_zerop (TREE_OPERAND (ref1, 1))) > - return false; > + { > + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; > + return false; > + } > ref1 = TREE_OPERAND (TREE_OPERAND (ref1, 0), 0); > } > > @@ -1060,7 +1079,10 @@ nonoverlapping_component_refs_of_decl_p > if (TREE_CODE (ref2) == MEM_REF) > { > if (!integer_zerop (TREE_OPERAND (ref2, 1))) > - return false; > + { > + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; > + return false; > + } > ref2 = TREE_OPERAND (TREE_OPERAND (ref2, 0), 0); > } > > @@ -1080,7 +1102,10 @@ nonoverlapping_component_refs_of_decl_p > do > { > if (component_refs1.is_empty ()) > - return false; > + { > + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; > + return false; > + } > ref1 = component_refs1.pop (); > } > while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref1, 0)))); > @@ -1088,7 +1113,10 @@ nonoverlapping_component_refs_of_decl_p > do > { > if (component_refs2.is_empty ()) > - return false; > + { > + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; > + return false; > + } > ref2 = component_refs2.pop (); > } > while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref2, 0)))); > @@ -1096,7 +1124,10 @@ nonoverlapping_component_refs_of_decl_p > /* Beware of BIT_FIELD_REF. */ > if (TREE_CODE (ref1) != COMPONENT_REF > || TREE_CODE (ref2) != COMPONENT_REF) > - return false; > + { > + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; > + return false; > + } > > tree field1 = TREE_OPERAND (ref1, 1); > tree field2 = TREE_OPERAND (ref2, 1); > @@ -1109,7 +1140,10 @@ nonoverlapping_component_refs_of_decl_p > > /* We cannot disambiguate fields in a union or qualified union. */ > if (type1 != type2 || TREE_CODE (type1) != RECORD_TYPE) > - return false; > + { > + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; > + return false; > + } > > if (field1 != field2) > { > @@ -1117,15 +1151,23 @@ nonoverlapping_component_refs_of_decl_p > same. */ > if (DECL_BIT_FIELD_REPRESENTATIVE (field1) == field2 > || DECL_BIT_FIELD_REPRESENTATIVE (field2) == field1) > - return false; > + { > + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; > + return false; > + } > /* Different fields of the same record type cannot overlap. > ??? Bitfields can overlap at RTL level so punt on them. */ > if (DECL_BIT_FIELD (field1) && DECL_BIT_FIELD (field2)) > - return false; > + { > + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; > + return false; > + } > + ++alias_stats.nonoverlapping_component_refs_of_decl_p_no_alias; > return true; > } > } > > + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; > return false; > } > > @@ -1154,40 +1196,67 @@ nonoverlapping_component_refs_p (const_t > { > if (!flag_strict_aliasing > || !x || !y > - || TREE_CODE (x) != COMPONENT_REF > - || TREE_CODE (y) != COMPONENT_REF) > - return false; > + || !handled_component_p (x) > + || !handled_component_p (y)) > + { > + ++alias_stats.nonoverlapping_component_refs_p_may_alias; > + return false; > + } > > auto_vec<const_tree, 16> fieldsx; > - while (TREE_CODE (x) == COMPONENT_REF) > + while (handled_component_p (x)) > { > - tree field = TREE_OPERAND (x, 1); > - tree type = DECL_FIELD_CONTEXT (field); > - if (TREE_CODE (type) == RECORD_TYPE) > - fieldsx.safe_push (field); > + if (TREE_CODE (x) == COMPONENT_REF) > + { > + tree field = TREE_OPERAND (x, 1); > + tree type = DECL_FIELD_CONTEXT (field); > + if (TREE_CODE (type) == RECORD_TYPE) > + fieldsx.safe_push (field); > + } > + else if (TREE_CODE (x) == VIEW_CONVERT_EXPR) > + fieldsx.truncate (0); > x = TREE_OPERAND (x, 0); > } > if (fieldsx.length () == 0) > return false; > auto_vec<const_tree, 16> fieldsy; > - while (TREE_CODE (y) == COMPONENT_REF) > + while (handled_component_p (y)) > { > - tree field = TREE_OPERAND (y, 1); > - tree type = DECL_FIELD_CONTEXT (field); > - if (TREE_CODE (type) == RECORD_TYPE) > - fieldsy.safe_push (TREE_OPERAND (y, 1)); > + if (TREE_CODE (y) == COMPONENT_REF) > + { > + tree field = TREE_OPERAND (y, 1); > + tree type = DECL_FIELD_CONTEXT (field); > + if (TREE_CODE (type) == RECORD_TYPE) > + fieldsy.safe_push (TREE_OPERAND (y, 1)); > + } > + else if (TREE_CODE (y) == VIEW_CONVERT_EXPR) > + fieldsx.truncate (0); > y = TREE_OPERAND (y, 0); > } > if (fieldsy.length () == 0) > - return false; > + { > + ++alias_stats.nonoverlapping_component_refs_p_may_alias; > + return false; > + } > > /* Most common case first. */ > if (fieldsx.length () == 1 > && fieldsy.length () == 1) > - return ((DECL_FIELD_CONTEXT (fieldsx[0]) > - == DECL_FIELD_CONTEXT (fieldsy[0])) > - && fieldsx[0] != fieldsy[0] > - && !(DECL_BIT_FIELD (fieldsx[0]) && DECL_BIT_FIELD (fieldsy[0]))); > + { > + if ((DECL_FIELD_CONTEXT (fieldsx[0]) > + == DECL_FIELD_CONTEXT (fieldsy[0])) > + && fieldsx[0] != fieldsy[0] > + && !(DECL_BIT_FIELD (fieldsx[0]) && DECL_BIT_FIELD (fieldsy[0]))) > + { > + ++alias_stats.nonoverlapping_component_refs_p_no_alias; > + return true; > + } > + else > + { > + ++alias_stats.nonoverlapping_component_refs_p_may_alias; > + return false; > + } > + } > > if (fieldsx.length () == 2) > { > @@ -1222,11 +1291,18 @@ nonoverlapping_component_refs_p (const_t > same. */ > if (DECL_BIT_FIELD_REPRESENTATIVE (fieldx) == fieldy > || DECL_BIT_FIELD_REPRESENTATIVE (fieldy) == fieldx) > - return false; > + { > + ++alias_stats.nonoverlapping_component_refs_p_may_alias; > + return false; > + } > /* Different fields of the same record type cannot overlap. > ??? Bitfields can overlap at RTL level so punt on them. */ > if (DECL_BIT_FIELD (fieldx) && DECL_BIT_FIELD (fieldy)) > - return false; > + { > + ++alias_stats.nonoverlapping_component_refs_p_may_alias; > + return false; > + } > + ++alias_stats.nonoverlapping_component_refs_p_no_alias; > return true; > } > } > @@ -1245,6 +1321,7 @@ nonoverlapping_component_refs_p (const_t > } > while (1); > > + ++alias_stats.nonoverlapping_component_refs_p_may_alias; > return false; > } > > -- Richard Biener <rguent...@suse.de> SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG Nürnberg)