1 /* { dg-do run } */
2 /* { dg-options "-O2" } */
3 
4 void abort ();
5 
6 typedef struct _Node
7 {
8   struct _Node *next, *prev;
9 } Node;
10 
append(Node * q,Node * p)11 void __attribute__ ((noinline)) append (Node * q, Node * p)
12 {
13   p->next = q;
14   p->prev = q;
15   q->next = p;
16   q->prev = p;
17 }
18 
19 inline void
swap(Node ** a,Node ** b)20 swap (Node ** a, Node ** b)
21 {
22   Node *tmp = *a;
23   *a = *b;
24   *b = tmp;
25 }
26 
27 /* Miscompilation seems to happen here. If one removes the if condition
28    (which should be true) the program works fine.  */
29 void
ListSwap(Node * x,Node * y)30 ListSwap (Node * x, Node * y)
31 {
32   Node *tmp;
33   if (x->next)
34     {
35       swap (&x->next, &y->next);
36       swap (&x->prev, &y->prev);
37       x->next->prev = x->prev->next = x;
38       y->next->prev = y->prev->next = y;
39     }
40 }
41 
42 int
main()43 main ()
44 {
45   Node A, A1, B, B1;
46 
47   append (&A, &A1);
48   append (&B, &B1);
49 
50   ListSwap (&A, &B);
51 
52   if (&A != A.next->prev)
53     abort ();
54 
55   return 0;
56 }
57