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;
}

Reply via email to