https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85800
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |WAITING Last reconfirmed| |2018-05-16 CC| |rguenth at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- Hmm, I can't reproduce it because the arrays happen to be not adjacent for me. But if I change if (c1 == c2) // Always true if p and q have same integer representation. arr3[i] = arr1[i]; else arr3[i] = arr2[i]; to if (c1 == c2) // Always true if p and q have same integer representation. arr3[i] = arr2[i]; else arr3[i] = arr1[i]; I get 10 consistently. This is because then arr3 will indeed be A. Changing main to int main() { struct { int B[4]; int A[4]; } a; printf("%p %p\n", a.A, &a.B[4]); store_10_to_p(a.A, &a.B[4]); printf("%d\n", a.A[0]); return 0; } also makes it work reliably for me. I guess at -O3 you get store_10_to_p inlined. You can try changing the function to void __attribute__((noinline,noclone)) store_10_to_p(int *p, int *q) { to see if that makes any difference. As said, I don't see any bug here.