In the testcase of PR99673 we can see <bb 2> [local count: 1073741824]: _13 = &MEM[(struct B *)pc_2(D) + 1B].i; .ASAN_CHECK (6, _13, 4, 4); _1 = MEM[(struct B *)pc_2(D) + 1B].i; _14 = &pd_4(D)->i; .ASAN_CHECK (7, _14, 4, 4); pd_4(D)->i = _1; _9 = (sizetype) i_6(D); _10 = _9 * 16; _11 = _10 + 4; _12 = pc_2(D) + 1; psa_7 = _12 + _11; f (psa_7); and FRE5 is not CSEing _12 to _13.
I will have a look.
Testcase that did not regress: struct S { int i; }; void foo (int *); void bar (char *p) { foo (&((struct S *)(p + 1))->i); foo ((int *)(p + 1)); } Testcase that did regress (use -fgimple): struct S { int i; }; void foo (int *); void __GIMPLE (ssa) bar (char * p) { int * D_1997; int * _2; char * _3; __BB(2): _2 = &__MEM <struct S> ((struct S *)p_5(D) + _Literal (struct S *) 1).i; foo (_2); _3 = &__MEM <int> ((struct S *)p_5(D) + _Literal (struct S *)1); foo (_3); return; } it regressed because forwprop now rewrites one of the &MEMs: --- t.c.033t.ccp1 2022-01-21 14:12:01.392883591 +0100 +++ t.c.034t.forwprop1 2022-01-21 14:12:01.392883591 +0100 @@ -10,7 +10,7 @@ <bb 2> : _2_6 = &MEM[(struct S *)p_5(D) + 1B].i; foo (_2_6); - _3_9 = &MEM[(struct S *)p_5(D) + 1B]; + _3_9 = p_5(D) + 1; foo (_3_9); return;
Right my original version of the lowering handled this. I guess we need to handle the case where we have a handled reference too. But that would regress PR 99673 again. I will take a look this weekend.
Btw, in VN it would be nice to handle struct S { int i; }; int i; int bar (char *p) { char *q = p + 1; i = 1; char *r = (char *)&(((struct S *)&p[i])->i); return q == r; } the main issue here is that this is vn_reference vs. vn_nary handling and this transitions from vn_reference to possibly vn_nary with valueization. For VN &MEM[p + 1] was more canonical and we could go back to this when seeing pointer-plus -- at least when lookup & simplification does not produce a redundancy. Handling this in VN only and only when inlining is complete might also avoid regressing the testcase again.
(In reply to Richard Biener from comment #4) > Btw, in VN it would be nice to handle > > struct S { int i; }; > > int i; > int bar (char *p) > { > char *q = p + 1; > i = 1; > char *r = (char *)&(((struct S *)&p[i])->i); > return q == r; > } Rather the following struct S { int a[4]; }; int i; int bar (struct S *p) { char *q = (char *)p + 4; i = 1; int *r = &((struct S *)p)->a[i]; return q == (char *)r; } > the main issue here is that this is vn_reference vs. vn_nary handling and > this > transitions from vn_reference to possibly vn_nary with valueization. For VN > &MEM[p + 1] was more canonical and we could go back to this when seeing > pointer-plus -- at least when lookup & simplification does not produce a > redundancy. > > Handling this in VN only and only when inlining is complete might also avoid > regressing the testcase again. The adjusted testcase is folded in forwprop after inlining which handles p+4 == &p->a[1]
Created attachment 52293 [details] untested patch Like this - it unfortunately regresses the diagnostic case in PR99673 again but should leave early __builtin_object_size untouched.
The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:ee1cb43bc76de800efa0ade687b0cd28e62a5f82 commit r13-137-gee1cb43bc76de800efa0ade687b0cd28e62a5f82 Author: Richard Biener <rguenther@suse.de> Date: Wed Jan 26 15:34:54 2022 +0100 tree-optimization/104162 - CSE of &MEM[ptr].a[i] and ptr + CST This adds the capability to value-numbering of treating complex address expressions where the offset becomes invariant as equal to a POINTER_PLUS_EXPR. This restores CSE that is now prevented by early lowering of &MEM[ptr + CST] to a POINTER_PLUS_EXPR. Unfortunately this regresses gcc.dg/asan/pr99673.c again, so the testcase is adjusted accordingly. 2022-01-26 Richard Biener <rguenther@suse.de> PR tree-optimization/104162 * tree-ssa-sccvn.cc (vn_reference_lookup): Handle &MEM[_1 + 5].a[i] like a POINTER_PLUS_EXPR if the offset becomes invariant. (vn_reference_insert): Likewise. * gcc.dg/tree-ssa/ssa-fre-99.c: New testcase. * gcc.dg/asan/pr99673.c: Adjust.
*** Bug 108074 has been marked as a duplicate of this bug. ***
GCC 13.1 is being released, retargeting bugs to GCC 13.2.
GCC 13.2 is being released, retargeting bugs to GCC 13.3.
GCC 13.3 is being released, retargeting bugs to GCC 13.4.