OSDN Git Service

Backported from mainline
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.c-torture / execute / pr47538.c
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 }