1 /* PR tree-optimization/33136 */
2 /* { dg-do run } */
3 /* { dg-options "-O2" } */
4 
5 extern void abort (void);
6 
7 struct S
8 {
9   void *a;
10   int b[3];
11   double *c;
12 };
13 static double d, e;
14 
15 static struct S s;
16 
17 static int *
18 __attribute__((noinline, const))
foo(void)19 foo (void)
20 {
21   return (int *) &s.b;
22 }
23 
24 double *
25 __attribute__((noinline))
bar(double ** f)26 bar (double **f)
27 {
28   s.c = &d;
29   *f = &e;
30   /* As nothing ever takes the address of any double * field in struct S,
31      the write to *f can't alias with the s.c field.  */
32   return s.c;
33 }
34 
35 int
36 __attribute__((noinline))
baz(int * x)37 baz (int *x)
38 {
39   s.b[0] = 1;
40   *x = 4;
41   /* Function foo takes address of an int array field in struct S,
42      so *x can alias with the s.b field (and it does in this testcase).  */
43   return s.b[0];
44 }
45 
46 int
47 __attribute__((noinline))
t(void)48 t (void)
49 {
50   double *f = (double *) 0;
51   return 10 * (bar (&f) != &d) + baz (foo ());
52 }
53 
54 int
main(void)55 main (void)
56 {
57   if (t () != 4)
58     abort ();
59   return 0;
60 }
61