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

Reply via email to