1  /* PR rtl-optimization/49390 */
       2  
       3  struct S { unsigned int s1; unsigned int s2; };
       4  struct T { unsigned int t1; struct S t2; };
       5  struct U { unsigned short u1; unsigned short u2; };
       6  struct V { struct U v1; struct T v2; };
       7  struct S a;
       8  char *b;
       9  union { char b[64]; struct V v; } u;
      10  volatile int v;
      11  extern void abort (void);
      12  
      13  __attribute__((noinline, noclone)) void
      14  foo (int x, void *y, unsigned int z, unsigned int w)
      15  {
      16    if (x != 4 || y != (void *) &u.v.v2)
      17      abort ();
      18    v = z + w;
      19    v = 16384;
      20  }
      21  
      22  __attribute__((noinline, noclone)) void
      23  bar (struct S x)
      24  {
      25    v = x.s1;
      26    v = x.s2;
      27  }
      28  
      29  __attribute__((noinline, noclone)) int
      30  baz (struct S *x)
      31  {
      32    v = x->s1;
      33    v = x->s2;
      34    v = 0;
      35    return v + 1;
      36  }
      37  
      38  __attribute__((noinline, noclone)) void
      39  test (struct S *c)
      40  {
      41    struct T *d;
      42    struct S e = a;
      43    unsigned int f, g;
      44    if (c == 0)
      45      c = &e;
      46    else
      47      {
      48        if (c->s2 % 8192 <= 15 || (8192 - c->s2 % 8192) <= 31)
      49  	foo (1, 0, c->s1, c->s2);
      50      }
      51    if (!baz (c))
      52      return;
      53    g = (((struct U *) b)->u2 & 2) ? 32 : __builtin_offsetof (struct V, v2);
      54    f = c->s2 % 8192;
      55    if (f == 0)
      56      {
      57        e.s2 += g;
      58        f = g;
      59      }
      60    else if (f < g)
      61      {
      62        foo (2, 0, c->s1, c->s2);
      63        return;
      64      }
      65    if ((((struct U *) b)->u2 & 1) && f == g)
      66      {
      67        bar (*c);
      68        foo (3, 0, c->s1, c->s2);
      69        return;
      70      }
      71    d = (struct T *) (b + c->s2 % 8192);
      72    if (d->t2.s1 >= c->s1 && (d->t2.s1 != c->s1 || d->t2.s2 >= c->s2))
      73      foo (4, d, c->s1, c->s2);
      74    return;
      75  }
      76  
      77  int
      78  main ()
      79  {
      80    struct S *c = 0;
      81    asm ("" : "+r" (c) : "r" (&a));
      82    u.v.v2.t2.s1 = 8192;
      83    b = u.b;
      84    test (c);
      85    if (v != 16384)
      86      abort ();
      87    return 0;
      88  }