https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37810

--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #2)
> The original testcase (from an IRC discussion) reduced to a C testcase is:
> 
> struct A {
>   int n;
>   int m;
> };
> 
> void g();
> 
> void test (struct A* iter)
> {
>   struct A end = { 0, 0 };
>   while (iter->n != end.n)
>     {
>       iter->n = iter->n + 1;
>       if (iter->n == iter->m)
>         g();
>     }
> }
> 
> where there is an optimization possibility to sink the store to iter->n to
> before the call and apply load-store motion to iter->n for the remaining
> loop.

So to clarify the desired code would look like

void test (struct A* iter)
{
  struct A end = { 0, 0 };
  int tem = iter->n;
  while (tem != end.n)
    {
      tem = tem + 1;
      if (tem == iter->m)
        {
          iter->n = tem;
          g();
          tem = iter->n;
        }
    }
  iter->n = tem;
}

PRE does half of the job, but then sinking would need to duplicate the store
on the loop exit, something it currently cannot do (the logic is to duplicate
to two places less frequently executed).

Reply via email to