https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57359
--- Comment #17 from Richard Biener <rguenth at gcc dot gnu.org> --- We'd need to peel the last iteration as the following shows. This also means it is not enough to prove the loop actually iterates. Peeling the last iteration means we have to be able to identify that iteration. Alternatively, we might be able to re-issue all stores from the last iteration up until the exit on the exit edge though if there are conditional stores on this path this might prove interesting. There's always the option to not apply store-motion here of course. extern void abort(); typedef int A; typedef float B; void __attribute__((noinline,noclone)) foo(A *p, B *q, long unk) { for (long i = 0; i < unk; ++i) { *p = 1; q[i] = 42; } } int main(void) { char *mem = __builtin_malloc (sizeof (A) * 5); foo((A *)mem + 4, (B *)mem, 5); if (*((B *)mem + 4) != 42) abort(); return 0; }