[Bug tree-optimization/126793] New: Store merging vs ivopts
"ktkachov at gcc dot gnu.org via Gcc-bugs" <[email protected]>
| Newsgroups | gmane.comp.gcc.bugs |
|---|---|
| Message-ID | <[email protected]/bugzilla/> |
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126793
Bug ID: 126793
Summary: Store merging vs ivopts
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: enhancement
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: ktkachov at gcc dot gnu.org
Target Milestone: ---
/* The destination is an induction variable, so ivopts turns each store
into a TARGET_MEM_REF with a different base pointer. */
void
foo1 (__SIZE_TYPE__ n, unsigned char *p, const __UINT32_TYPE__ *src)
{
for (__SIZE_TYPE__ i = 0; i < n; i++, p += 4)
{
__UINT32_TYPE__ w = src[i];
p[0] = w;
p[1] = w >> 8;
p[2] = w >> 16;
p[3] = w >> 24;
}
}
/* Same through a global array, where the TARGET_MEM_REF has a symbol
base. */
unsigned char g[4096];
void
foo2 (__SIZE_TYPE__ n, const __UINT32_TYPE__ *src)
{
for (__SIZE_TYPE__ i = 0; i < n; i++)
{
__UINT32_TYPE__ w = src[i];
g[4 * i] = w;
g[4 * i + 1] = w >> 8;
g[4 * i + 2] = w >> 16;
g[4 * i + 3] = w >> 24;
}
}
on aarch64 GCC at -O2 generates:
foo1:
cbz x0, .L1
lsl x0, x0, 2
add x8, x1, 1
add x7, x1, 2
add x6, x1, 3
mov w3, 0
.L3:
ldr w4, [x2, x3]
strb w4, [x1, x3]
lsr w5, w4, 8
strb w5, [x8, x3]
lsr w5, w4, 16
strb w5, [x7, x3]
lsr w4, w4, 24
strb w4, [x6, x3]
add x3, x3, 4
cmp x0, x3
bne .L3
.L1:
ret
foo2:
cbz x0, .L9
adrp x3, g
add x3, x3, :lo12:g
mov w4, 0
.L11:
ldr w2, [x1, x4, lsl 2]
add x4, x4, 1
strb w2, [x3]
add x3, x3, 4
lsr w5, w2, 8
strb w5, [x3, -3]
lsr w5, w2, 16
lsr w2, w2, 24
strb w5, [x3, -2]
strb w2, [x3, -1]
cmp x0, x4
bne .L11
.L9:
ret
g:
.zero 4096
I would have expected store merging to kick in, but because ivopts rewrites
loop memory references into TARGET_MEM_REFs the store merging pass doesn't
handle them.