1  /* PR tree-optimization/47538 */
       2  
       3  struct S
       4  {
       5    double a, b, *c;
       6    unsigned long d;
       7  };
       8  
       9  __attribute__((noinline, noclone)) void
      10  foo (struct S *x, const struct S *y)
      11  {
      12    const unsigned long n = y->d + 1;
      13    const double m = 0.25 * (y->b - y->a);
      14    x->a = y->a;
      15    x->b = y->b;
      16    if (n == 1)
      17      {
      18        x->c[0] = 0.;
      19      }
      20    else if (n == 2)
      21      {
      22        x->c[1] = m * y->c[0];
      23        x->c[0] = 2.0 * x->c[1];
      24      }
      25    else
      26      {
      27        double o = 0.0, p = 1.0;
      28        unsigned long i;
      29  
      30        for (i = 1; i <= n - 2; i++)
      31  	{
      32  	  x->c[i] = m * (y->c[i - 1] - y->c[i + 1]) / (double) i;
      33  	  o += p * x->c[i];
      34  	  p = -p;
      35  	}
      36        x->c[n - 1] = m * y->c[n - 2] / (n - 1.0);
      37        o += p * x->c[n - 1];
      38        x->c[0] = 2.0 * o;
      39      }
      40  }
      41  
      42  int
      43  main (void)
      44  {
      45    struct S x, y;
      46    double c[4] = { 10, 20, 30, 40 }, d[4], e[4] = { 118, 118, 118, 118 };
      47  
      48    y.a = 10;
      49    y.b = 6;
      50    y.c = c;
      51    x.c = d;
      52    y.d = 3;
      53    __builtin_memcpy (d, e, sizeof d);
      54    foo (&x, &y);
      55    if (d[0] != 0 || d[1] != 20 || d[2] != 10 || d[3] != -10)
      56      __builtin_abort ();
      57    y.d = 2;
      58    __builtin_memcpy (d, e, sizeof d);
      59    foo (&x, &y);
      60    if (d[0] != 60 || d[1] != 20 || d[2] != -10 || d[3] != 118)
      61      __builtin_abort ();
      62    y.d = 1;
      63    __builtin_memcpy (d, e, sizeof d);
      64    foo (&x, &y);
      65    if (d[0] != -20 || d[1] != -10 || d[2] != 118 || d[3] != 118)
      66      __builtin_abort ();
      67    y.d = 0;
      68    __builtin_memcpy (d, e, sizeof d);
      69    foo (&x, &y);
      70    if (d[0] != 0 || d[1] != 118 || d[2] != 118 || d[3] != 118)
      71      __builtin_abort ();
      72    return 0;
      73  }