https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64319
Bug ID: 64319
Summary: add alias runtime check to remove load after load
redundancy
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: spop at gcc dot gnu.org
Looking at the code generated at -O3 for the following function, we have to
load "*a" twice because "a" may alias "b":
$ cat foo.c
int foo(int *a, int *b)
{
*a = 1;
(*b)++;
return *a;
}
Here is the code generated for aarch64 (for illustration only, ie., this is not
an aarch64 bug):
$ gcc foo.c -O3 -S -o -
[...]
foo:
mov w2, 1
str w2, [x0]
ldr w2, [x1]
add w2, w2, 1
str w2, [x1]
ldr w0, [x0]
ret
GCC could insert a runtime check to disambiguate the two pointers: in
principle, we should obtain better code on both branches, because the compiler
knows something more about the program in each case.
$ cat bar.c
int bar(int *a, int *b)
{
if (a == b)
{
*a = 1;
(*b)++;
return *a;
}
*a = 1;
(*b)++;
return *a;
}
GCC does optimize correctly the case "a==b" and still has an optimization
problem in the case "a!=b". Here is the code generated for aarch64:
bar:
cmp x0, x1
beq .L6
mov w2, 1
str w2, [x0]
ldr w2, [x1]
add w2, w2, 1
str w2, [x1]
ldr w0, [x0] <-- this load should be replaced by a "mov w0, 1"
because we know "x1 != x0" on this branch.
ret
.L6:
mov w1, 2
str w1, [x0]
mov w0, w1
ret