1 /* { dg-do compile } */
2 /* { dg-options "-O2 -fdump-tree-sink2-stats" } */
3 /* { dg-require-effective-target int32plus } */
8 #define MAX_LIT (1 << 5)
9 typedef const uint8_t *LZF_HSLOT
;
10 typedef LZF_HSLOT LZF_STATE
[1 << (HLOG
)];
13 compute_on_bytes (uint8_t *in_data
, int in_len
, uint8_t *out_data
, int out_len
)
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
;
27 if (!in_len
|| !out_len
)
32 hval
= (((ip
[0]) << 8) | ip
[1]);
34 while (ip
< in_end
- 2)
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
46 && ((ref
[1] << 8) | ref
[0]) == ((ip
[1] << 8) | ip
[0]))
49 unsigned int maxlen
= in_end
- ip
- len
;
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
)
57 op
[-lit
- 1] = lit
- 1;
65 if (ref
[len
] != ip
[len
])
68 if (ref
[len
] != ip
[len
])
71 if (ref
[len
] != ip
[len
])
74 if (ref
[len
] != ip
[len
])
78 if (ref
[len
] != ip
[len
])
81 if (ref
[len
] != ip
[len
])
84 if (ref
[len
] != ip
[len
])
87 if (ref
[len
] != ip
[len
])
91 if (ref
[len
] != ip
[len
])
94 if (ref
[len
] != ip
[len
])
97 if (ref
[len
] != ip
[len
])
100 if (ref
[len
] != ip
[len
])
104 if (ref
[len
] != ip
[len
])
107 if (ref
[len
] != ip
[len
])
110 if (ref
[len
] != ip
[len
])
113 if (ref
[len
] != ip
[len
])
121 while (len
< maxlen
&& ip
[len
] == ref
[len
]);
131 *op
++ = (off
>> 8) + (len
<< 5);
135 *op
++ = (off
>> 8) + (7 << 5);
143 if (ip
>= in_end
- 2)
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
);
155 hval
= (((hval
) << 8) | ip
[2]);
156 htab
[(((hval
>> (3 * 8 - 16)) - hval
* 5) & ((1 << (16)) - 1))]
157 = (LZF_HSLOT
)(ip
- in_data
);
170 op
[-lit
- 1] = lit
- 1;
176 if (op
+ 3 > out_end
) /* at most 3 bytes can be missing here */
185 op
[-lit
- 1] = lit
- 1; /* stop run */
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:
201 "Sinking op_230 = op_244 + 2;
203 Sinking _367 = (uint8_t *) _320;
205 Sinking _320 = _321 + ivtmp.25_326;
207 Sinking _321 = (unsigned long) ip_229;
209 Sinking len_158 = _322 + 4294967295;
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*-*-* } } } } */