> > Ah, no, of course not. I guess the early out here should be a > "ignore this match" instead.
Here is updated patch with a testcase I have re-tested on x86_64-linux and comitted. There are still few divergences left, I will debug them now. Again the testcase has extra wrapper in struct d to prevent oracle giving up earlier via overlaping_range_refs. Honza * tree-ssa-alias.c (nonoverlapping_component_refs_p): Do not give up on bitfields; continue searching for different refs appearing later. * gcc.dg/tree-ssa/alias-access-path-6.c: New testcase. Index: tree-ssa-alias.c =================================================================== --- tree-ssa-alias.c (revision 272510) +++ tree-ssa-alias.c (working copy) @@ -1350,19 +1350,16 @@ nonoverlapping_component_refs_p (const_t same. */ if (DECL_BIT_FIELD_REPRESENTATIVE (fieldx) == fieldy || DECL_BIT_FIELD_REPRESENTATIVE (fieldy) == fieldx) - { - ++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)) + else if (DECL_BIT_FIELD (fieldx) && DECL_BIT_FIELD (fieldy)) + ; + else { - ++alias_stats.nonoverlapping_component_refs_p_may_alias; - return false; + ++alias_stats.nonoverlapping_component_refs_p_no_alias; + return true; } - ++alias_stats.nonoverlapping_component_refs_p_no_alias; - return true; } } if (TYPE_UID (typex) < TYPE_UID (typey)) Index: testsuite/gcc.dg/tree-ssa/alias-access-path-6.c =================================================================== --- testsuite/gcc.dg/tree-ssa/alias-access-path-6.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/alias-access-path-6.c (working copy) @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +/* This tests that nonoveralpping_component_refs does not give up + on field delcs and continues looking to find mismatch between + a1 and a2. */ +struct a { + int a:3; + int b:3; +}; +struct b {struct a a1,a2;}; +struct c {struct b b[10];} *cptr; +struct d {struct c c;} *dptr; +int +test(int i,int j) +{ + cptr->b[i].a1.a=0; + dptr->c.b[j].a2.b=1; + return cptr->b[i].a1.a; +} +int +test2(int i,int j) +{ + cptr->b[i].a1.a=1; + dptr->c.b[j].a1.a=0; + return cptr->b[i].a1.a; +} +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-not "return 1" "optimized"} } */