http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59448

            Bug ID: 59448
           Summary: ARM code generation doesn't respect C11
                    address-dependency
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: algrant at acm dot org

int f2(int const *p, int const *q)
  {
    int flag = *p;
    return flag ? *(q + flag - flag) : 0;
  }

The evaluation *(q + flag - flag) is ordered after *p by 5.1.2.4#14;
writing it this way is a recognized way of forcing the ordering.
AArch64 GCC 4.8 -O2 --std=c11 generates

f2:
        ldr     w2, [x0]
        mov     w0, 0
        cbz     w2, .L2
        ldr     w0, [x1]
.L2

which doesn't preserve the ordering in the target memory model.
The compiler needs to introduce an address dependency, e.g.

        and     w2, w2, #0
        ldr     w0, [x1, w2]

or insert a memory barrier instruction.  According to the target
architecture's own rules, this is sufficient to order the loads.

In general, the C source-level address dependency (defined by the 
syntactic rules of 5.1.2.4#14) might not involve arithmetic.
For example:

  inline int makedep(int flag, ...) { return flag; }  // variadic

  int f3(int const *p, int const *q) {
    int flag = *p;
    return flag ? makedep(*q, flag) : 0;
  }

An access might even be formally dependent on multiple expressions.
The compiler just has to keep track.

Reply via email to