1/* { dg-do compile { target { ! { ia32 } } } } */
2/* { dg-options "-O2 -mx32 -maddress-mode=long" } */
3
4typedef struct rtx_def *rtx;
5enum rtx_code { MINUS };
6union rtunion_def {
7  rtx rt_rtx;
8};
9typedef union rtunion_def rtunion;
10struct rtx_def {
11  enum rtx_code code: 16;
12  union u {
13    rtunion fld[1];
14  }
15  u;
16};
17rtx simplify_binary_operation (enum rtx_code code, int mode,
18			       rtx op0, rtx op1);
19struct simplify_plus_minus_op_data {
20  rtx op;
21  short neg;
22};
23void simplify_plus_minus (enum rtx_code code, int mode, rtx op0, rtx op1)
24{
25  struct simplify_plus_minus_op_data ops[8];
26  rtx tem = (rtx) 0;
27  int n_ops = 2, input_ops = 2;
28  int changed, canonicalized = 0;
29  int i, j;
30  __builtin_memset (ops, 0, sizeof (ops));
31  do
32    {
33      changed = 0;
34      for (i = 0; i < n_ops; i++)
35	{
36	  rtx this_op = ops[i].op;
37	  int this_neg = ops[i].neg;
38	  enum rtx_code this_code = ((enum rtx_code) (this_op)->code);
39	  switch (this_code)
40	    {
41	    case MINUS:
42	      if (n_ops == 7)
43		return;
44	      n_ops++;
45	      input_ops++;
46	      changed = 1;
47	      canonicalized |= this_neg;
48	      break;
49	    }
50	}
51    }
52  while (changed);
53  do
54    {
55      j =  n_ops - 1;
56      for (i = n_ops - 1; j >= 0; j--)
57	{
58	  rtx lhs = ops[j].op, rhs = ops[i].op;
59	  int lneg = ops[j].neg, rneg = ops[i].neg;
60	  if (lhs != 0 && rhs != 0)
61	    {
62	      enum rtx_code ncode = MINUS;
63	      if (((enum rtx_code) (lhs)->code) == MINUS)
64		tem = simplify_binary_operation (ncode, mode, lhs, rhs);
65	      if (tem && ! (((enum rtx_code) (tem)->code) == MINUS
66			    && ((((((tem)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx) == lhs
67			    && ((((((tem)->u.fld[0]).rt_rtx))->u.fld[1]).rt_rtx) == rhs))
68		{
69		  lneg &= rneg;
70		  ops[i].op = tem;
71		  ops[i].neg = lneg;
72		  ops[j].op = (rtx) 0;
73		  changed = 1;
74		  canonicalized = 1;
75		}
76	    }
77	}
78      for (i = 0, j = 0; j < n_ops; j++)
79	if (ops[j].op)
80	  {
81	    ops[i] = ops[j];
82	    i++;
83	  }
84    }
85  while (changed);
86}
87