Hi, this is a variant of testcase I have comitted. Once Martin implements SRA part, we could add next variant that drops -fno-tree-sra.
It seems odd that constant propagation only happens in fre3. I woud expect fre1 to discover this already. The IL before fre1 and 3 differs only by: test () { struct foo foo; struct bar * barptr.0_1; struct foo * fooptr.1_2; - struct bar * barptr.2_3; - int _8; + int _7; - <bb 2> : + <bb 2> [local count: 1073741824]: foo.val = 0; barptr.0_1 = barptr; barptr.0_1->val2 = 123; fooptr.1_2 = fooptr; *fooptr.1_2 = foo; - barptr.2_3 = barptr; - _8 = barptr.2_3->val2; + _7 = barptr.0_1->val2; foo ={v} {CLOBBER}; - return _8; + return _7; } Why VN is not able to optimize the barptr access and lookup through it at once? It looks that could potentially save some need to re-run GVN since it is common to store pointers to memory and use them multiple times to access other pointers. * tree-ssa/alias-access-spath-1.c: new testcase. Index: gcc.dg/tree-ssa/alias-access-path-1.c =================================================================== --- gcc.dg/tree-ssa/alias-access-path-1.c (nonexistent) +++ gcc.dg/tree-ssa/alias-access-path-1.c (working copy) @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-fre3 -fno-tree-sra" } */ +struct foo +{ + int val; +} *fooptr; +struct bar +{ + struct foo foo; + int val2; +} *barptr; +int +test () +{ + struct foo foo = { 0 }; + barptr->val2 = 123; + *fooptr = foo; + return barptr->val2; +} + +/* { dg-final { scan-tree-dump-times "return 123" 1 "fre3"} } */