1 /* Header file for mixed range operator class.
2 Copyright (C) 2017-2024 Free Software Foundation, Inc.
3 Contributed by Andrew MacLeod <amacleod@redhat.com>
4 and Aldy Hernandez <aldyh@redhat.com>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #ifndef GCC_RANGE_OP_MIXED_H
23 #define GCC_RANGE_OP_MIXED_H
25 void update_known_bitmask (vrange
&, tree_code
, const vrange
&, const vrange
&);
26 bool minus_op1_op2_relation_effect (irange
&lhs_range
, tree type
,
27 const irange
&, const irange
&,
31 // Return TRUE if 0 is within [WMIN, WMAX].
34 wi_includes_zero_p (tree type
, const wide_int
&wmin
, const wide_int
&wmax
)
36 signop sign
= TYPE_SIGN (type
);
37 return wi::le_p (wmin
, 0, sign
) && wi::ge_p (wmax
, 0, sign
);
40 // Return TRUE if [WMIN, WMAX] is the singleton 0.
43 wi_zero_p (tree type
, const wide_int
&wmin
, const wide_int
&wmax
)
45 unsigned prec
= TYPE_PRECISION (type
);
46 return wmin
== wmax
&& wi::eq_p (wmin
, wi::zero (prec
));
50 enum bool_range_state
{ BRS_FALSE
, BRS_TRUE
, BRS_EMPTY
, BRS_FULL
};
51 bool_range_state
get_bool_state (vrange
&r
, const vrange
&lhs
, tree val_type
);
53 // If the range of either op1 or op2 is undefined, set the result to
54 // varying and return TRUE. If the caller truly cares about a result,
55 // they should pass in a varying if it has an undefined that it wants
56 // treated as a varying.
59 empty_range_varying (vrange
&r
, tree type
,
60 const vrange
&op1
, const vrange
& op2
)
62 if (op1
.undefined_p () || op2
.undefined_p ())
71 // For relation opcodes, first try to see if the supplied relation
72 // forces a true or false result, and return that.
73 // Then check for undefined operands. If none of this applies,
77 relop_early_resolve (irange
&r
, tree type
, const vrange
&op1
,
78 const vrange
&op2
, relation_trio trio
,
81 relation_kind rel
= trio
.op1_op2 ();
82 // If known relation is a complete subset of this relation, always true.
83 if (relation_union (rel
, my_rel
) == my_rel
)
85 r
= range_true (type
);
89 // If known relation has no subset of this relation, always false.
90 if (relation_intersect (rel
, my_rel
) == VREL_UNDEFINED
)
92 r
= range_false (type
);
96 // If either operand is undefined, return VARYING.
97 if (empty_range_varying (r
, type
, op1
, op2
))
103 // ----------------------------------------------------------------------
104 // Mixed Mode Operators.
105 // ----------------------------------------------------------------------
107 class operator_equal
: public range_operator
110 using range_operator::fold_range
;
111 using range_operator::op1_range
;
112 using range_operator::op2_range
;
113 using range_operator::op1_op2_relation
;
114 using range_operator::update_bitmask
;
115 bool fold_range (irange
&r
, tree type
,
116 const irange
&op1
, const irange
&op2
,
117 relation_trio
= TRIO_VARYING
) const final override
;
118 bool fold_range (irange
&r
, tree type
,
119 const prange
&op1
, const prange
&op2
,
120 relation_trio
= TRIO_VARYING
) const final override
;
121 bool fold_range (irange
&r
, tree type
,
122 const frange
&op1
, const frange
&op2
,
123 relation_trio
= TRIO_VARYING
) const final override
;
125 bool op1_range (irange
&r
, tree type
,
126 const irange
&lhs
, const irange
&val
,
127 relation_trio
= TRIO_VARYING
) const final override
;
128 bool op1_range (prange
&r
, tree type
,
129 const irange
&lhs
, const prange
&val
,
130 relation_trio
= TRIO_VARYING
) const final override
;
131 bool op1_range (frange
&r
, tree type
,
132 const irange
&lhs
, const frange
&op2
,
133 relation_trio
= TRIO_VARYING
) const final override
;
135 bool op2_range (irange
&r
, tree type
,
136 const irange
&lhs
, const irange
&val
,
137 relation_trio
= TRIO_VARYING
) const final override
;
138 bool op2_range (prange
&r
, tree type
,
139 const irange
&lhs
, const prange
&val
,
140 relation_trio
= TRIO_VARYING
) const final override
;
141 bool op2_range (frange
&r
, tree type
,
142 const irange
&lhs
, const frange
&op1
,
143 relation_trio rel
= TRIO_VARYING
) const final override
;
145 relation_kind
op1_op2_relation (const irange
&lhs
, const irange
&,
146 const irange
&) const final override
;
147 relation_kind
op1_op2_relation (const irange
&lhs
, const prange
&,
148 const prange
&) const final override
;
149 relation_kind
op1_op2_relation (const irange
&lhs
, const frange
&,
150 const frange
&) const final override
;
151 void update_bitmask (irange
&r
, const irange
&lh
,
152 const irange
&rh
) const final override
;
153 // Check op1 and op2 for compatibility.
154 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
155 { return range_compatible_p (t2
, t3
) && INTEGRAL_TYPE_P (t1
); }
158 class operator_not_equal
: public range_operator
161 using range_operator::fold_range
;
162 using range_operator::op1_range
;
163 using range_operator::op2_range
;
164 using range_operator::op1_op2_relation
;
165 using range_operator::update_bitmask
;
166 bool fold_range (irange
&r
, tree type
,
167 const irange
&op1
, const irange
&op2
,
168 relation_trio
= TRIO_VARYING
) const final override
;
169 bool fold_range (irange
&r
, tree type
,
170 const prange
&op1
, const prange
&op2
,
171 relation_trio rel
= TRIO_VARYING
) const final override
;
172 bool fold_range (irange
&r
, tree type
,
173 const frange
&op1
, const frange
&op2
,
174 relation_trio rel
= TRIO_VARYING
) const final override
;
176 bool op1_range (irange
&r
, tree type
,
177 const irange
&lhs
, const irange
&op2
,
178 relation_trio
= TRIO_VARYING
) const final override
;
179 bool op1_range (prange
&r
, tree type
,
180 const irange
&lhs
, const prange
&op2
,
181 relation_trio
= TRIO_VARYING
) const final override
;
182 bool op1_range (frange
&r
, tree type
,
183 const irange
&lhs
, const frange
&op2
,
184 relation_trio
= TRIO_VARYING
) const final override
;
186 bool op2_range (irange
&r
, tree type
,
187 const irange
&lhs
, const irange
&op1
,
188 relation_trio
= TRIO_VARYING
) const final override
;
189 bool op2_range (prange
&r
, tree type
,
190 const irange
&lhs
, const prange
&op1
,
191 relation_trio
= TRIO_VARYING
) const final override
;
192 bool op2_range (frange
&r
, tree type
,
193 const irange
&lhs
, const frange
&op1
,
194 relation_trio
= TRIO_VARYING
) const final override
;
196 relation_kind
op1_op2_relation (const irange
&lhs
, const irange
&,
197 const irange
&) const final override
;
198 relation_kind
op1_op2_relation (const irange
&lhs
, const prange
&,
199 const prange
&) const final override
;
200 relation_kind
op1_op2_relation (const irange
&lhs
, const frange
&,
201 const frange
&) const final override
;
202 void update_bitmask (irange
&r
, const irange
&lh
,
203 const irange
&rh
) const final override
;
204 // Check op1 and op2 for compatibility.
205 bool operand_check_p (tree t0
, tree t1
, tree t2
) const final override
206 { return range_compatible_p (t1
, t2
) && INTEGRAL_TYPE_P (t0
); }
209 class operator_lt
: public range_operator
212 using range_operator::fold_range
;
213 using range_operator::op1_range
;
214 using range_operator::op2_range
;
215 using range_operator::op1_op2_relation
;
216 using range_operator::update_bitmask
;
217 bool fold_range (irange
&r
, tree type
,
218 const irange
&op1
, const irange
&op2
,
219 relation_trio
= TRIO_VARYING
) const final override
;
220 bool fold_range (irange
&r
, tree type
,
221 const prange
&op1
, const prange
&op2
,
222 relation_trio
= TRIO_VARYING
) const final override
;
223 bool fold_range (irange
&r
, tree type
,
224 const frange
&op1
, const frange
&op2
,
225 relation_trio
= TRIO_VARYING
) const final override
;
226 bool op1_range (irange
&r
, tree type
,
227 const irange
&lhs
, const irange
&op2
,
228 relation_trio
= TRIO_VARYING
) const final override
;
229 bool op1_range (prange
&r
, tree type
,
230 const irange
&lhs
, const prange
&op2
,
231 relation_trio
= TRIO_VARYING
) const final override
;
232 bool op1_range (frange
&r
, tree type
,
233 const irange
&lhs
, const frange
&op2
,
234 relation_trio
= TRIO_VARYING
) const final override
;
235 bool op2_range (irange
&r
, tree type
,
236 const irange
&lhs
, const irange
&op1
,
237 relation_trio
= TRIO_VARYING
) const final override
;
238 bool op2_range (prange
&r
, tree type
,
239 const irange
&lhs
, const prange
&op1
,
240 relation_trio
= TRIO_VARYING
) const final override
;
241 bool op2_range (frange
&r
, tree type
,
242 const irange
&lhs
, const frange
&op1
,
243 relation_trio
= TRIO_VARYING
) const final override
;
244 relation_kind
op1_op2_relation (const irange
&lhs
, const irange
&,
245 const irange
&) const final override
;
246 relation_kind
op1_op2_relation (const irange
&lhs
, const prange
&,
247 const prange
&) const final override
;
248 relation_kind
op1_op2_relation (const irange
&lhs
, const frange
&,
249 const frange
&) const final override
;
250 void update_bitmask (irange
&r
, const irange
&lh
,
251 const irange
&rh
) const final override
;
252 // Check op1 and op2 for compatibility.
253 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
254 { return range_compatible_p (t2
, t3
) && INTEGRAL_TYPE_P (t1
); }
257 class operator_le
: public range_operator
260 using range_operator::fold_range
;
261 using range_operator::op1_range
;
262 using range_operator::op2_range
;
263 using range_operator::op1_op2_relation
;
264 using range_operator::update_bitmask
;
265 bool fold_range (irange
&r
, tree type
,
266 const irange
&op1
, const irange
&op2
,
267 relation_trio
= TRIO_VARYING
) const final override
;
268 bool fold_range (irange
&r
, tree type
,
269 const prange
&op1
, const prange
&op2
,
270 relation_trio
= TRIO_VARYING
) const final override
;
271 bool fold_range (irange
&r
, tree type
,
272 const frange
&op1
, const frange
&op2
,
273 relation_trio rel
= TRIO_VARYING
) const final override
;
275 bool op1_range (irange
&r
, tree type
,
276 const irange
&lhs
, const irange
&op2
,
277 relation_trio
= TRIO_VARYING
) const final override
;
278 bool op1_range (prange
&r
, tree type
,
279 const irange
&lhs
, const prange
&op2
,
280 relation_trio
= TRIO_VARYING
) const final override
;
281 bool op1_range (frange
&r
, tree type
,
282 const irange
&lhs
, const frange
&op2
,
283 relation_trio rel
= TRIO_VARYING
) const final override
;
285 bool op2_range (irange
&r
, tree type
,
286 const irange
&lhs
, const irange
&op1
,
287 relation_trio
= TRIO_VARYING
) const final override
;
288 bool op2_range (prange
&r
, tree type
,
289 const irange
&lhs
, const prange
&op1
,
290 relation_trio
= TRIO_VARYING
) const final override
;
291 bool op2_range (frange
&r
, tree type
,
292 const irange
&lhs
, const frange
&op1
,
293 relation_trio rel
= TRIO_VARYING
) const final override
;
295 relation_kind
op1_op2_relation (const irange
&lhs
, const irange
&,
296 const irange
&) const final override
;
297 relation_kind
op1_op2_relation (const irange
&lhs
, const prange
&,
298 const prange
&) const final override
;
299 relation_kind
op1_op2_relation (const irange
&lhs
, const frange
&,
300 const frange
&) const final override
;
301 void update_bitmask (irange
&r
, const irange
&lh
,
302 const irange
&rh
) const final override
;
303 // Check op1 and op2 for compatibility.
304 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
305 { return range_compatible_p (t2
, t3
) && INTEGRAL_TYPE_P (t1
); }
308 class operator_gt
: public range_operator
311 using range_operator::fold_range
;
312 using range_operator::op1_range
;
313 using range_operator::op2_range
;
314 using range_operator::op1_op2_relation
;
315 using range_operator::update_bitmask
;
316 bool fold_range (irange
&r
, tree type
,
317 const irange
&op1
, const irange
&op2
,
318 relation_trio
= TRIO_VARYING
) const final override
;
319 bool fold_range (irange
&r
, tree type
,
320 const prange
&op1
, const prange
&op2
,
321 relation_trio
= TRIO_VARYING
) const final override
;
322 bool fold_range (irange
&r
, tree type
,
323 const frange
&op1
, const frange
&op2
,
324 relation_trio
= TRIO_VARYING
) const final override
;
326 bool op1_range (irange
&r
, tree type
,
327 const irange
&lhs
, const irange
&op2
,
328 relation_trio
= TRIO_VARYING
) const final override
;
329 bool op1_range (prange
&r
, tree type
,
330 const irange
&lhs
, const prange
&op2
,
331 relation_trio
= TRIO_VARYING
) const final override
;
332 bool op1_range (frange
&r
, tree type
,
333 const irange
&lhs
, const frange
&op2
,
334 relation_trio
= TRIO_VARYING
) const final override
;
336 bool op2_range (irange
&r
, tree type
,
337 const irange
&lhs
, const irange
&op1
,
338 relation_trio
= TRIO_VARYING
) const final override
;
339 bool op2_range (prange
&r
, tree type
,
340 const irange
&lhs
, const prange
&op1
,
341 relation_trio
= TRIO_VARYING
) const final override
;
342 bool op2_range (frange
&r
, tree type
,
343 const irange
&lhs
, const frange
&op1
,
344 relation_trio
= TRIO_VARYING
) const final override
;
345 relation_kind
op1_op2_relation (const irange
&lhs
, const irange
&,
346 const irange
&) const final override
;
347 relation_kind
op1_op2_relation (const irange
&lhs
, const prange
&,
348 const prange
&) const final override
;
349 relation_kind
op1_op2_relation (const irange
&lhs
, const frange
&,
350 const frange
&) const final override
;
351 void update_bitmask (irange
&r
, const irange
&lh
,
352 const irange
&rh
) const final override
;
353 // Check op1 and op2 for compatibility.
354 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
355 { return range_compatible_p (t2
, t3
) && INTEGRAL_TYPE_P (t1
); }
358 class operator_ge
: public range_operator
361 using range_operator::fold_range
;
362 using range_operator::op1_range
;
363 using range_operator::op2_range
;
364 using range_operator::op1_op2_relation
;
365 using range_operator::update_bitmask
;
366 bool fold_range (irange
&r
, tree type
,
367 const irange
&op1
, const irange
&op2
,
368 relation_trio
= TRIO_VARYING
) const final override
;
369 bool fold_range (irange
&r
, tree type
,
370 const prange
&op1
, const prange
&op2
,
371 relation_trio
= TRIO_VARYING
) const final override
;
372 bool fold_range (irange
&r
, tree type
,
373 const frange
&op1
, const frange
&op2
,
374 relation_trio
= TRIO_VARYING
) const final override
;
376 bool op1_range (irange
&r
, tree type
,
377 const irange
&lhs
, const irange
&op2
,
378 relation_trio
= TRIO_VARYING
) const final override
;
379 bool op1_range (prange
&r
, tree type
,
380 const irange
&lhs
, const prange
&op2
,
381 relation_trio
= TRIO_VARYING
) const final override
;
382 bool op1_range (frange
&r
, tree type
,
383 const irange
&lhs
, const frange
&op2
,
384 relation_trio
= TRIO_VARYING
) const final override
;
386 bool op2_range (irange
&r
, tree type
,
387 const irange
&lhs
, const irange
&op1
,
388 relation_trio
= TRIO_VARYING
) const final override
;
389 bool op2_range (prange
&r
, tree type
,
390 const irange
&lhs
, const prange
&op1
,
391 relation_trio
= TRIO_VARYING
) const final override
;
392 bool op2_range (frange
&r
, tree type
,
393 const irange
&lhs
, const frange
&op1
,
394 relation_trio
= TRIO_VARYING
) const final override
;
396 relation_kind
op1_op2_relation (const irange
&lhs
, const irange
&,
397 const irange
&) const final override
;
398 relation_kind
op1_op2_relation (const irange
&lhs
, const prange
&,
399 const prange
&) const final override
;
400 relation_kind
op1_op2_relation (const irange
&lhs
, const frange
&,
401 const frange
&) const final override
;
402 void update_bitmask (irange
&r
, const irange
&lh
,
403 const irange
&rh
) const final override
;
404 // Check op1 and op2 for compatibility.
405 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
406 { return range_compatible_p (t2
, t3
) && INTEGRAL_TYPE_P (t1
); }
409 class operator_identity
: public range_operator
412 using range_operator::fold_range
;
413 using range_operator::op1_range
;
414 using range_operator::lhs_op1_relation
;
415 bool fold_range (irange
&r
, tree type
,
416 const irange
&op1
, const irange
&op2
,
417 relation_trio rel
= TRIO_VARYING
) const final override
;
418 bool fold_range (prange
&r
, tree type
,
419 const prange
&op1
, const prange
&op2
,
420 relation_trio rel
= TRIO_VARYING
) const final override
;
421 bool fold_range (frange
&r
, tree type ATTRIBUTE_UNUSED
,
422 const frange
&op1
, const frange
&op2 ATTRIBUTE_UNUSED
,
423 relation_trio
= TRIO_VARYING
) const final override
;
424 bool op1_range (irange
&r
, tree type
,
425 const irange
&lhs
, const irange
&op2
,
426 relation_trio rel
= TRIO_VARYING
) const final override
;
427 bool op1_range (prange
&r
, tree type
,
428 const prange
&lhs
, const prange
&op2
,
429 relation_trio rel
= TRIO_VARYING
) const final override
;
430 bool op1_range (frange
&r
, tree type ATTRIBUTE_UNUSED
,
431 const frange
&lhs
, const frange
&op2 ATTRIBUTE_UNUSED
,
432 relation_trio
= TRIO_VARYING
) const final override
;
433 relation_kind
lhs_op1_relation (const irange
&lhs
,
434 const irange
&op1
, const irange
&op2
,
435 relation_kind rel
) const final override
;
436 relation_kind
lhs_op1_relation (const prange
&lhs
,
437 const prange
&op1
, const prange
&op2
,
438 relation_kind rel
) const final override
;
441 class operator_cst
: public range_operator
444 using range_operator::fold_range
;
445 bool fold_range (irange
&r
, tree type
,
446 const irange
&op1
, const irange
&op2
,
447 relation_trio rel
= TRIO_VARYING
) const final override
;
448 bool fold_range (prange
&r
, tree type
,
449 const prange
&op1
, const prange
&op2
,
450 relation_trio rel
= TRIO_VARYING
) const final override
;
451 bool fold_range (frange
&r
, tree type
,
452 const frange
&op1
, const frange
&op2
,
453 relation_trio
= TRIO_VARYING
) const final override
;
457 class operator_cast
: public range_operator
460 using range_operator::fold_range
;
461 using range_operator::op1_range
;
462 using range_operator::lhs_op1_relation
;
463 using range_operator::update_bitmask
;
464 bool fold_range (irange
&r
, tree type
,
465 const irange
&op1
, const irange
&op2
,
466 relation_trio rel
= TRIO_VARYING
) const final override
;
467 bool fold_range (prange
&r
, tree type
,
468 const prange
&op1
, const prange
&op2
,
469 relation_trio rel
= TRIO_VARYING
) const final override
;
470 bool fold_range (irange
&r
, tree type
,
471 const prange
&op1
, const irange
&op2
,
472 relation_trio rel
= TRIO_VARYING
) const final override
;
473 bool fold_range (prange
&r
, tree type
,
474 const irange
&op1
, const prange
&op2
,
475 relation_trio rel
= TRIO_VARYING
) const final override
;
476 bool op1_range (irange
&r
, tree type
,
477 const irange
&lhs
, const irange
&op2
,
478 relation_trio rel
= TRIO_VARYING
) const final override
;
479 bool op1_range (prange
&r
, tree type
,
480 const prange
&lhs
, const prange
&op2
,
481 relation_trio rel
= TRIO_VARYING
) const final override
;
482 bool op1_range (irange
&r
, tree type
,
483 const prange
&lhs
, const irange
&op2
,
484 relation_trio rel
= TRIO_VARYING
) const final override
;
485 bool op1_range (prange
&r
, tree type
,
486 const irange
&lhs
, const prange
&op2
,
487 relation_trio rel
= TRIO_VARYING
) const final override
;
488 relation_kind
lhs_op1_relation (const irange
&lhs
,
489 const irange
&op1
, const irange
&op2
,
490 relation_kind
) const final override
;
491 relation_kind
lhs_op1_relation (const prange
&lhs
,
492 const prange
&op1
, const prange
&op2
,
493 relation_kind
) const final override
;
494 relation_kind
lhs_op1_relation (const prange
&lhs
,
495 const irange
&op1
, const irange
&op2
,
496 relation_kind
) const final override
;
497 relation_kind
lhs_op1_relation (const irange
&lhs
,
498 const prange
&op1
, const prange
&op2
,
499 relation_kind
) const final override
;
500 void update_bitmask (irange
&r
, const irange
&lh
,
501 const irange
&rh
) const final override
;
503 bool truncating_cast_p (const irange
&inner
, const irange
&outer
) const;
504 bool inside_domain_p (const wide_int
&min
, const wide_int
&max
,
505 const irange
&outer
) const;
506 void fold_pair (irange
&r
, unsigned index
, const irange
&inner
,
507 const irange
&outer
) const;
510 class operator_plus
: public range_operator
513 using range_operator::op1_range
;
514 using range_operator::op2_range
;
515 using range_operator::lhs_op1_relation
;
516 using range_operator::lhs_op2_relation
;
517 using range_operator::update_bitmask
;
518 bool op1_range (irange
&r
, tree type
,
519 const irange
&lhs
, const irange
&op2
,
520 relation_trio
) const final override
;
521 bool op1_range (frange
&r
, tree type
,
522 const frange
&lhs
, const frange
&op2
,
523 relation_trio
= TRIO_VARYING
) const final override
;
525 bool op2_range (irange
&r
, tree type
,
526 const irange
&lhs
, const irange
&op1
,
527 relation_trio
) const final override
;
528 bool op2_range (frange
&r
, tree type
,
529 const frange
&lhs
, const frange
&op1
,
530 relation_trio
= TRIO_VARYING
) const final override
;
532 relation_kind
lhs_op1_relation (const irange
&lhs
, const irange
&op1
,
534 relation_kind rel
) const final override
;
535 relation_kind
lhs_op2_relation (const irange
&lhs
, const irange
&op1
,
537 relation_kind rel
) const final override
;
538 void update_bitmask (irange
&r
, const irange
&lh
,
539 const irange
&rh
) const final override
;
541 virtual bool overflow_free_p (const irange
&lh
, const irange
&rh
,
542 relation_trio
= TRIO_VARYING
) const;
543 // Check compatibility of all operands.
544 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
545 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
547 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
548 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
549 const wide_int
&rh_ub
) const final override
;
550 void rv_fold (frange
&r
, tree type
,
551 const REAL_VALUE_TYPE
&lh_lb
, const REAL_VALUE_TYPE
&lh_ub
,
552 const REAL_VALUE_TYPE
&rh_lb
, const REAL_VALUE_TYPE
&rh_ub
,
553 relation_kind
) const final override
;
556 class operator_abs
: public range_operator
559 using range_operator::fold_range
;
560 using range_operator::op1_range
;
561 using range_operator::update_bitmask
;
562 bool fold_range (frange
&r
, tree type
,
563 const frange
&op1
, const frange
&,
564 relation_trio
= TRIO_VARYING
) const final override
;
566 bool op1_range (irange
&r
, tree type
, const irange
&lhs
,
567 const irange
&op2
, relation_trio
) const final override
;
568 bool op1_range (frange
&r
, tree type
,
569 const frange
&lhs
, const frange
&op2
,
570 relation_trio rel
= TRIO_VARYING
) const final override
;
571 void update_bitmask (irange
&r
, const irange
&lh
,
572 const irange
&rh
) const final override
;
573 // Check compatibility of LHS and op1.
574 bool operand_check_p (tree t1
, tree t2
, tree
) const final override
575 { return range_compatible_p (t1
, t2
); }
577 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
578 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
579 const wide_int
&rh_ub
) const final override
;
583 class operator_minus
: public range_operator
586 using range_operator::fold_range
;
587 using range_operator::op1_range
;
588 using range_operator::op2_range
;
589 using range_operator::lhs_op1_relation
;
590 using range_operator::op1_op2_relation_effect
;
591 using range_operator::update_bitmask
;
592 bool op1_range (irange
&r
, tree type
,
593 const irange
&lhs
, const irange
&op2
,
594 relation_trio
) const final override
;
595 bool op1_range (frange
&r
, tree type
,
596 const frange
&lhs
, const frange
&op2
,
597 relation_trio
= TRIO_VARYING
) const final override
;
599 bool op2_range (irange
&r
, tree type
,
600 const irange
&lhs
, const irange
&op1
,
601 relation_trio
) const final override
;
602 bool op2_range (frange
&r
, tree type
,
605 relation_trio
= TRIO_VARYING
) const final override
;
607 relation_kind
lhs_op1_relation (const irange
&lhs
,
608 const irange
&op1
, const irange
&op2
,
609 relation_kind rel
) const final override
;
610 bool op1_op2_relation_effect (irange
&lhs_range
, tree type
,
611 const irange
&op1_range
,
612 const irange
&op2_range
,
613 relation_kind rel
) const final override
;
614 void update_bitmask (irange
&r
, const irange
&lh
,
615 const irange
&rh
) const final override
;
617 virtual bool overflow_free_p (const irange
&lh
, const irange
&rh
,
618 relation_trio
= TRIO_VARYING
) const;
619 // Check compatibility of all operands.
620 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
621 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
623 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
624 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
625 const wide_int
&rh_ub
) const final override
;
626 void rv_fold (frange
&r
, tree type
,
627 const REAL_VALUE_TYPE
&lh_lb
, const REAL_VALUE_TYPE
&lh_ub
,
628 const REAL_VALUE_TYPE
&rh_lb
, const REAL_VALUE_TYPE
&rh_ub
,
629 relation_kind
) const final override
;
632 class operator_negate
: public range_operator
635 using range_operator::fold_range
;
636 using range_operator::op1_range
;
637 bool fold_range (irange
&r
, tree type
,
638 const irange
&op1
, const irange
&op2
,
639 relation_trio rel
= TRIO_VARYING
) const final override
;
640 bool fold_range (frange
&r
, tree type
,
641 const frange
&op1
, const frange
&op2
,
642 relation_trio
= TRIO_VARYING
) const final override
;
644 bool op1_range (irange
&r
, tree type
,
645 const irange
&lhs
, const irange
&op2
,
646 relation_trio rel
= TRIO_VARYING
) const final override
;
647 bool op1_range (frange
&r
, tree type
,
648 const frange
&lhs
, const frange
&op2
,
649 relation_trio rel
= TRIO_VARYING
) const final override
;
650 // Check compatibility of LHS and op1.
651 bool operand_check_p (tree t1
, tree t2
, tree
) const final override
652 { return range_compatible_p (t1
, t2
); }
656 class cross_product_operator
: public range_operator
659 virtual bool wi_op_overflows (wide_int
&r
,
662 const wide_int
&) const = 0;
663 void wi_cross_product (irange
&r
, tree type
,
664 const wide_int
&lh_lb
,
665 const wide_int
&lh_ub
,
666 const wide_int
&rh_lb
,
667 const wide_int
&rh_ub
) const;
670 class operator_mult
: public cross_product_operator
673 using range_operator::op1_range
;
674 using range_operator::op2_range
;
675 using range_operator::update_bitmask
;
676 bool op1_range (irange
&r
, tree type
,
677 const irange
&lhs
, const irange
&op2
,
678 relation_trio
) const final override
;
679 bool op1_range (frange
&r
, tree type
,
680 const frange
&lhs
, const frange
&op2
,
681 relation_trio
= TRIO_VARYING
) const final override
;
683 bool op2_range (irange
&r
, tree type
,
684 const irange
&lhs
, const irange
&op1
,
685 relation_trio
) const final override
;
686 bool op2_range (frange
&r
, tree type
,
687 const frange
&lhs
, const frange
&op1
,
688 relation_trio
= TRIO_VARYING
) const final override
;
690 void update_bitmask (irange
&r
, const irange
&lh
,
691 const irange
&rh
) const final override
;
693 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
694 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
695 const wide_int
&rh_ub
) const final override
;
696 bool wi_op_overflows (wide_int
&res
, tree type
, const wide_int
&w0
,
697 const wide_int
&w1
) const final override
;
699 void rv_fold (frange
&r
, tree type
,
700 const REAL_VALUE_TYPE
&lh_lb
, const REAL_VALUE_TYPE
&lh_ub
,
701 const REAL_VALUE_TYPE
&rh_lb
, const REAL_VALUE_TYPE
&rh_ub
,
702 relation_kind kind
) const final override
;
703 virtual bool overflow_free_p (const irange
&lh
, const irange
&rh
,
704 relation_trio
= TRIO_VARYING
) const;
705 // Check compatibility of all operands.
706 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
707 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
710 class operator_addr_expr
: public range_operator
713 using range_operator::fold_range
;
714 using range_operator::op1_range
;
715 bool fold_range (irange
&r
, tree type
,
716 const irange
&op1
, const irange
&op2
,
717 relation_trio rel
= TRIO_VARYING
) const final override
;
718 bool op1_range (irange
&r
, tree type
,
719 const irange
&lhs
, const irange
&op2
,
720 relation_trio rel
= TRIO_VARYING
) const final override
;
721 bool op1_range (prange
&r
, tree type
,
722 const prange
&lhs
, const prange
&op2
,
723 relation_trio rel
= TRIO_VARYING
) const final override
;
726 class operator_bitwise_not
: public range_operator
729 using range_operator::fold_range
;
730 using range_operator::op1_range
;
731 using range_operator::update_bitmask
;
732 bool fold_range (irange
&r
, tree type
,
733 const irange
&lh
, const irange
&rh
,
734 relation_trio rel
= TRIO_VARYING
) const final override
;
735 bool op1_range (irange
&r
, tree type
,
736 const irange
&lhs
, const irange
&op2
,
737 relation_trio rel
= TRIO_VARYING
) const final override
;
738 void update_bitmask (irange
&r
, const irange
&lh
,
739 const irange
&rh
) const final override
;
740 // Check compatibility of all operands.
741 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
742 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
745 class operator_bitwise_xor
: public range_operator
748 using range_operator::op1_range
;
749 using range_operator::op2_range
;
750 using range_operator::op1_op2_relation_effect
;
751 using range_operator::update_bitmask
;
752 bool op1_range (irange
&r
, tree type
,
753 const irange
&lhs
, const irange
&op2
,
754 relation_trio rel
= TRIO_VARYING
) const final override
;
755 bool op2_range (irange
&r
, tree type
,
756 const irange
&lhs
, const irange
&op1
,
757 relation_trio rel
= TRIO_VARYING
) const final override
;
758 bool op1_op2_relation_effect (irange
&lhs_range
,
760 const irange
&op1_range
,
761 const irange
&op2_range
,
762 relation_kind rel
) const final override
;
763 void update_bitmask (irange
&r
, const irange
&lh
,
764 const irange
&rh
) const final override
;
765 // Check compatibility of all operands.
766 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
767 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
769 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
770 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
771 const wide_int
&rh_ub
) const final override
;
774 class operator_bitwise_and
: public range_operator
777 using range_operator::fold_range
;
778 using range_operator::op1_range
;
779 using range_operator::op2_range
;
780 using range_operator::lhs_op1_relation
;
781 using range_operator::update_bitmask
;
782 bool fold_range (prange
&r
, tree type
,
785 relation_trio
) const final override
;
786 bool op1_range (irange
&r
, tree type
,
787 const irange
&lhs
, const irange
&op2
,
788 relation_trio rel
= TRIO_VARYING
) const override
;
789 bool op2_range (irange
&r
, tree type
,
790 const irange
&lhs
, const irange
&op1
,
791 relation_trio rel
= TRIO_VARYING
) const override
;
792 relation_kind
lhs_op1_relation (const irange
&lhs
,
793 const irange
&op1
, const irange
&op2
,
794 relation_kind
) const override
;
795 void update_bitmask (irange
&r
, const irange
&lh
,
796 const irange
&rh
) const override
;
797 // Check compatibility of all operands.
798 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
799 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
801 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
802 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
803 const wide_int
&rh_ub
) const override
;
804 void simple_op1_range_solver (irange
&r
, tree type
,
806 const irange
&op2
) const;
809 class operator_bitwise_or
: public range_operator
812 using range_operator::op1_range
;
813 using range_operator::op2_range
;
814 using range_operator::update_bitmask
;
815 bool op1_range (irange
&r
, tree type
,
816 const irange
&lhs
, const irange
&op2
,
817 relation_trio rel
= TRIO_VARYING
) const override
;
818 bool op2_range (irange
&r
, tree type
,
819 const irange
&lhs
, const irange
&op1
,
820 relation_trio rel
= TRIO_VARYING
) const override
;
821 void update_bitmask (irange
&r
, const irange
&lh
,
822 const irange
&rh
) const override
;
823 // Check compatibility of all operands.
824 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
825 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
827 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
828 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
829 const wide_int
&rh_ub
) const override
;
832 class operator_min
: public range_operator
835 using range_operator::fold_range
;
836 using range_operator::update_bitmask
;
837 bool fold_range (prange
&r
, tree type
,
840 relation_trio
) const final override
;
841 void update_bitmask (irange
&r
, const irange
&lh
,
842 const irange
&rh
) const override
;
843 // Check compatibility of all operands.
844 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
845 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
847 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
848 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
849 const wide_int
&rh_ub
) const override
;
852 class operator_max
: public range_operator
855 using range_operator::fold_range
;
856 using range_operator::update_bitmask
;
857 bool fold_range (prange
&r
, tree type
,
860 relation_trio
) const final override
;
861 void update_bitmask (irange
&r
, const irange
&lh
,
862 const irange
&rh
) const override
;
863 // Check compatibility of all operands.
864 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
865 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
867 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
868 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
869 const wide_int
&rh_ub
) const override
;
871 #endif // GCC_RANGE_OP_MIXED_H