xfail dg-final "Sunk statements: 5" on hppa*64*-*-*
[official-gcc.git] / gcc / testsuite / gcc.dg / tree-ssa / ssa-sink-18.c
blobb199df26a0f6fcbc7ce3a0071f5619e1f08ce579
1 /* { dg-do compile } */
2 /* { dg-options "-O2 -fdump-tree-sink2-stats" } */
3 /* { dg-require-effective-target int32plus } */
5 #include <stdint.h>
7 #define HLOG 16
8 #define MAX_LIT (1 << 5)
9 typedef const uint8_t *LZF_HSLOT;
10 typedef LZF_HSLOT LZF_STATE[1 << (HLOG)];
12 int
13 compute_on_bytes (uint8_t *in_data, int in_len, uint8_t *out_data, int out_len)
15 LZF_STATE htab;
17 uint8_t *ip = in_data;
18 uint8_t *op = out_data;
19 uint8_t *in_end = ip + in_len;
20 uint8_t *out_end = op + out_len;
21 uint8_t *ref;
23 unsigned long off;
24 unsigned int hval;
25 int lit;
27 if (!in_len || !out_len)
28 return 0;
30 lit = 0;
31 op++;
32 hval = (((ip[0]) << 8) | ip[1]);
34 while (ip < in_end - 2)
36 uint8_t *hslot;
38 hval = (((hval) << 8) | ip[2]);
39 hslot = (uint8_t*)(htab + (((hval >> (3 * 8 - 16)) - hval * 5) & ((1 << (16)) - 1)));
41 ref = *hslot + in_data;
42 *hslot = ip - in_data;
44 if (1 && (off = ip - ref - 1) < (1 << 13) && ref > in_data
45 && ref[2] == ip[2]
46 && ((ref[1] << 8) | ref[0]) == ((ip[1] << 8) | ip[0]))
48 unsigned int len = 2;
49 unsigned int maxlen = in_end - ip - len;
50 maxlen
51 = maxlen > ((1 << 8) + (1 << 3)) ? ((1 << 8) + (1 << 3)) : maxlen;
53 if ((op + 3 + 1 >= out_end) != 0)
54 if (op - !lit + 3 + 1 >= out_end)
55 return 0;
57 op[-lit - 1] = lit - 1;
58 op -= !lit;
60 for (;;)
62 if (maxlen > 16)
64 len++;
65 if (ref[len] != ip[len])
66 break;
67 len++;
68 if (ref[len] != ip[len])
69 break;
70 len++;
71 if (ref[len] != ip[len])
72 break;
73 len++;
74 if (ref[len] != ip[len])
75 break;
77 len++;
78 if (ref[len] != ip[len])
79 break;
80 len++;
81 if (ref[len] != ip[len])
82 break;
83 len++;
84 if (ref[len] != ip[len])
85 break;
86 len++;
87 if (ref[len] != ip[len])
88 break;
90 len++;
91 if (ref[len] != ip[len])
92 break;
93 len++;
94 if (ref[len] != ip[len])
95 break;
96 len++;
97 if (ref[len] != ip[len])
98 break;
99 len++;
100 if (ref[len] != ip[len])
101 break;
103 len++;
104 if (ref[len] != ip[len])
105 break;
106 len++;
107 if (ref[len] != ip[len])
108 break;
109 len++;
110 if (ref[len] != ip[len])
111 break;
112 len++;
113 if (ref[len] != ip[len])
114 break;
119 len++;
121 while (len < maxlen && ip[len] == ref[len]);
123 break;
126 len -= 2;
127 ip++;
129 if (len < 7)
131 *op++ = (off >> 8) + (len << 5);
133 else
135 *op++ = (off >> 8) + (7 << 5);
136 *op++ = len - 7;
138 *op++ = off;
139 lit = 0;
140 op++;
141 ip += len + 1;
143 if (ip >= in_end - 2)
144 break;
146 --ip;
147 --ip;
149 hval = (((ip[0]) << 8) | ip[1]);
150 hval = (((hval) << 8) | ip[2]);
151 htab[(((hval >> (3 * 8 - 16)) - hval * 5) & ((1 << (16)) - 1))]
152 = (LZF_HSLOT)(ip - in_data);
153 ip++;
155 hval = (((hval) << 8) | ip[2]);
156 htab[(((hval >> (3 * 8 - 16)) - hval * 5) & ((1 << (16)) - 1))]
157 = (LZF_HSLOT)(ip - in_data);
158 ip++;
160 else
162 if (op >= out_end)
163 return 0;
165 lit++;
166 *op++ = *ip++;
168 if (lit == (1 << 5))
170 op[-lit - 1] = lit - 1;
171 lit = 0;
172 op++;
176 if (op + 3 > out_end) /* at most 3 bytes can be missing here */
177 return 0;
179 while (ip < in_end)
181 lit++;
182 *op++ = *ip++;
183 if (lit == MAX_LIT)
185 op[-lit - 1] = lit - 1; /* stop run */
186 lit = 0;
187 op++; /* start run */
191 op[-lit - 1] = lit - 1; /* end run */
192 op -= !lit; /* undo run if length is zero */
194 return op - out_data;
197 /* For this case, pass sink2 sinks statements from hot loop header to loop
198 exits after gimple loop optimizations, which generates instructions executed
199 each iteration in loop, but the results are used outside of loop:
200 With -m64,
201 "Sinking op_230 = op_244 + 2;
202 from bb 63 to bb 94
203 Sinking _367 = (uint8_t *) _320;
204 from bb 31 to bb 90
205 Sinking _320 = _321 + ivtmp.25_326;
206 from bb 31 to bb 90
207 Sinking _321 = (unsigned long) ip_229;
208 from bb 31 to bb 90
209 Sinking len_158 = _322 + 4294967295;
210 from bb 31 to bb 33"
211 When -m32, Power and X86 will sink 3 instructions, but arm ilp32 couldn't
212 sink due to ivopts chooses two IV candidates instead of one, which is
213 expected, so this case is restricted to lp64 only so far. This different
214 ivopts choice affects riscv64 as well, probably because it also lacks
215 base+index addressing modes, so the ip[len] address computation can't be
216 made from the IV computation above. powerpc64le similarly is affected. */
218 /* { dg-final { scan-tree-dump-times "Sunk statements: 5" 1 "sink2" { target lp64 xfail { riscv64-*-* powerpc64le-*-* hppa*64*-*-* } } } } */