// { dg-require-effective-target freorder }
/* { dg-options "-O2 -g -fno-peel-loops" } */
struct page {
  int i;
} global;
__attribute__((noinline)) static struct page* find_page1 (int i)
{
  if ( i< 150)
      return 0;
  global.i = i;
  return &global;
}
__attribute__((noinline)) static struct page* find_page2 (int i)
{
  global.i = i;
  return &global;
}
volatile int ii;
__attribute__((noinline)) static int zero (void)
{
  return ii;
}
static inline int uptodate (struct page* p)
{
  return (p->i < 709);
}
static struct page* bar(int i)
{
  struct page *page;
repeat:
  page = find_page1 (i);
  if (!page) {
    page = find_page2 (i);
    if (!page)
      return 0;
    if (zero () ) {
      zero ();
      goto repeat;
    }
  }
  return page;
}
__attribute__((noinline)) int foo (int n)
{
  struct page *page;
retry:
  page = bar (n);
  if (page == 0)
    return 0;
  if (uptodate (page))
    goto out;
   zero ();
   if (page->i < 0) {
     zero ();
     goto retry;
   }
out:
   return 1;
}
__attribute__((noinline)) int hot (void)
{
  int i;
  int sum = 0;
  for (i = 0; i < 433038; i++)
    sum+=i;
  return sum;
}
int main(void)
{
  int i;
  global.i = hot ();
  for (i = 0; i < 858; i++)
    foo (i);
  return 0;
}