https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126605
Bug ID: 126605
Summary: Do not version for alignment when the runtime check
cannot hold
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: ktkachov at gcc dot gnu.org
Target Milestone: ---
vect_create_cond_for_align_checks builds either
"(a_1 | ... | a_n) & mask == 0" or "((a_1 ^ a_2) | ...) & mask == 0" over
the references recorded in LOOP_VINFO_MAY_MISALIGN_STMTS. Both forms
require every checked address to have the same value modulo the target
alignment. Nothing verified that such a value exists.
An early break over a two-field struct splits the loads into two
interleaving groups over the same base, four bytes apart, and both group
leaders are recorded for the runtime check. The condition then asks for p
and p + 4 to be 32-byte aligned at the same time, which no address
satisfies, so the vector loop is emitted, reported as vectorized, costed,
and never entered.
For
struct P { int a, b; };
int allequal (const struct P *x, const struct P *y, long n)
{
for (long i = 0; i < n; i++)
if (x[i].a != y[i].a || x[i].b != y[i].b)
return 0;
return 1;
}
aarch64 -O3 emits a guaranteed-taken guard in front of unreachable vector
code
add x3, x1, 4
add x4, x0, 4
orr x3, x1, x3
orr x4, x0, x4
orr x3, x3, x4
tst x3, 31
bne .L14
[30 instructions of vector loop]