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.