https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127201
Bug ID: 127201
Summary: dr_may_alias_p ignores DR_PTR_INFO, emitting runtime
alias checks for provably disjoint references
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: ptomsich at gcc dot gnu.org
Target Milestone: ---
Created attachment 65489
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65489&action=edit
proposed patch
ptr_derefs_may_alias_p treats "no points-to information" as "may alias".
However, passes that run after the last points-to computation create new
pointer SSA names with no SSA_NAME_PTR_INFO. We observed this in PRE
materialising a load. The the
vectorizer can then no longer disambiguate these new names, causing versioning
of the loop with runtime alias checks that are provably unnecessary.
Note that all the needed alias information is available: the same pointer was
originally (i.e., before given a new SSA name) analyzed and dr_analyze_alias
recorded it in DR_PTR_INFO.
Testcase (reduced from SPEC2026's palm), compiled with -O3 -ffast-math:
struct desc { double *data; long span; };
struct desc g;
int lo, hi;
double res;
void
f (int c)
{
int n = hi - lo + 2;
double t[n], u[n]; /* VLAs -> __builtin_alloca_with_align */
/* g.data is loaded on both arms, so PRE materialises it as a fresh
"pretmp" pointer SSA name -- after the last points-to run. */
if (c)
res = g.data[0];
else
res = g.data[1];
for (int k = 2; k < n - 2; k++)
{
u[k] = g.data[k + 1] + g.data[k];
t[k] = u[k] * (37.0 * (g.data[k + 1] + g.data[k])
- 8.0 * (g.data[k + 2] + g.data[k - 1]));
}
double s = 0;
for (int k = 2; k < n - 2; k++)
s += t[k] + u[k];
res += s;
}
t and u are local VLAs whose address never escapes; g.data points to
non-local, escaped memory. The two categories are disjoint so no runtime check
is needed; yet, trunk emits them:
$ gcc -O3 -ffast-math -fdump-tree-vect-details -c t.c
$ grep -c "versioning for alias required" t.c.*t.vect
16
each of the form "global-derived pointer vs VLA":
missed: versioning for alias required: can't determine dependence between
*_16 and (*t.3_49)[k_63]
-fdump-tree-ifcvt-alias shows the missing PT:
# PT = { D.4524 }
# ALIGN = 8, MISALIGN = 0
t.3_49 = __builtin_alloca_with_align (_7, 64);
# PT = { D.4525 }
# ALIGN = 8, MISALIGN = 0
u.5_51 = __builtin_alloca_with_align (_7, 64);
...
pretmp_117 = g.data; <- no "# PT" line at all
If we delete the "if (c) ... else ..." block, the base then stays on its
orginal name (_6 = g.data) and the the PT solution survives.
A proposed patch (dr_may_alias_p checks the already recorded DR_PTR_INFO) is
attached.
Confirmed against f96a6b0bb573cd2ceb1936dd0c886f2e3520c275 for
aarch64-unknown-linux-gnu today.