1/* PR tree-optimization/47538 */
2
3struct S
4{
5  double a, b, *c;
6  unsigned long d;
7};
8
9__attribute__((noinline, noclone)) void
10foo (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
42int
43main (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}
74