https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57359
--- Comment #13 from rguenther at suse dot de <rguenther at suse dot de> --- On Tue, 24 Oct 2017, ch3root at openwall dot com wrote: > I've also converted the testcase to allocated memory: > > ---------------------------------------------------------------------- > #include <stdlib.h> > #include <stdio.h> > > __attribute__((__noinline__,__noclone__)) > void test(int *pi, long *pl, int k, int *pa) > { > for (int i = 0; i < 3; i++) { > pl[k] = // something that doesn't change but have to be calculated > *pa; // something that potentially can be changed by assignment to *pi > *pi = 0; > } > } > > int main(void) > { > int *pi = malloc(10); > int a = 1; > > test(pi, (void *)pi, 0, &a); > > printf("%d\n", *pi); > } Thanks for the unobfuscated testcase, this indeed shows exactly the issue I mention (store motion sinking a store across another store). The *pa load prevents store-motion from also moving the *pi store which would mitigate this issue (in a way earlier fix we ensured the stores on exit are done in the original order). Testcase for the testsuite that should fail on both big and little-endian: __attribute__((__noinline__,__noclone__)) void test(__INT32_TYPE__ *pi, __INT64_TYPE__ *pl, int k, __INT32_TYPE__ *pa) { for (int i = 0; i < 3; i++) { pl[k] = *pa; *pi = 1; } } int main() { __INT32_TYPE__ *pi = __builtin_malloc (10); __INT32_TYPE__ a = 2; test(pi, (void *)pi, 0, &a); if (*pi != 1) __builtin_abort (); return 0; }