| Summary: | [12 Regression] Missed CSE after lowering of &MEM[ptr_1 + CST] | ||
|---|---|---|---|
| Product: | gcc | Reporter: | Richard Biener <rguenth> |
| Component: | tree-optimization | Assignee: | Richard Biener <rguenth> |
| Status: | ASSIGNED --- | ||
| Severity: | normal | CC: | alastair.j.irving, dimhen, pinskia |
| Priority: | P2 | Keywords: | missed-optimization |
| Version: | 12.0 | ||
| Target Milestone: | 13.5 | ||
| See Also: | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90663 | ||
| Host: | Target: | ||
| Build: | Known to work: | 13.0 | |
| Known to fail: | Last reconfirmed: | 2022-01-21 00:00:00 | |
| Attachments: | untested patch | ||
|
Description
Richard Biener
2022-01-21 13:01:20 UTC
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. GCC 13.4 is being released, retargeting bugs to GCC 13.5. |