| /* PR tree-optimization/47538 */ |
| |
| struct S |
| { |
| double a, b, *c; |
| unsigned long d; |
| }; |
| |
| __attribute__((noinline, noclone)) void |
| foo (struct S *x, const struct S *y) |
| { |
| const unsigned long n = y->d + 1; |
| const double m = 0.25 * (y->b - y->a); |
| x->a = y->a; |
| x->b = y->b; |
| if (n == 1) |
| { |
| x->c[0] = 0.; |
| } |
| else if (n == 2) |
| { |
| x->c[1] = m * y->c[0]; |
| x->c[0] = 2.0 * x->c[1]; |
| } |
| else |
| { |
| double o = 0.0, p = 1.0; |
| unsigned long i; |
| |
| for (i = 1; i <= n - 2; i++) |
| { |
| x->c[i] = m * (y->c[i - 1] - y->c[i + 1]) / (double) i; |
| o += p * x->c[i]; |
| p = -p; |
| } |
| x->c[n - 1] = m * y->c[n - 2] / (n - 1.0); |
| o += p * x->c[n - 1]; |
| x->c[0] = 2.0 * o; |
| } |
| } |
| |
| int |
| main (void) |
| { |
| struct S x, y; |
| double c[4] = { 10, 20, 30, 40 }, d[4], e[4] = { 118, 118, 118, 118 }; |
| |
| y.a = 10; |
| y.b = 6; |
| y.c = c; |
| x.c = d; |
| y.d = 3; |
| __builtin_memcpy (d, e, sizeof d); |
| foo (&x, &y); |
| if (d[0] != 0 || d[1] != 20 || d[2] != 10 || d[3] != -10) |
| __builtin_abort (); |
| y.d = 2; |
| __builtin_memcpy (d, e, sizeof d); |
| foo (&x, &y); |
| if (d[0] != 60 || d[1] != 20 || d[2] != -10 || d[3] != 118) |
| __builtin_abort (); |
| y.d = 1; |
| __builtin_memcpy (d, e, sizeof d); |
| foo (&x, &y); |
| if (d[0] != -20 || d[1] != -10 || d[2] != 118 || d[3] != 118) |
| __builtin_abort (); |
| y.d = 0; |
| __builtin_memcpy (d, e, sizeof d); |
| foo (&x, &y); |
| if (d[0] != 0 || d[1] != 118 || d[2] != 118 || d[3] != 118) |
| __builtin_abort (); |
| return 0; |
| } |