Daily bump.
[official-gcc.git] / gcc / range-op-mixed.h
blobcc1db2f677581d51818753c9ce829338c67aed9e
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
11 version.
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
16 for more details.
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 &,
28 relation_kind rel);
31 // Return TRUE if 0 is within [WMIN, WMAX].
33 inline bool
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.
42 inline bool
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.
58 inline bool
59 empty_range_varying (vrange &r, tree type,
60 const vrange &op1, const vrange & op2)
62 if (op1.undefined_p () || op2.undefined_p ())
64 r.set_varying (type);
65 return true;
67 else
68 return false;
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,
74 // return false.
76 inline bool
77 relop_early_resolve (irange &r, tree type, const vrange &op1,
78 const vrange &op2, relation_trio trio,
79 relation_kind my_rel)
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);
86 return true;
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);
93 return true;
96 // If either operand is undefined, return VARYING.
97 if (empty_range_varying (r, type, op1, op2))
98 return true;
100 return false;
103 // ----------------------------------------------------------------------
104 // Mixed Mode Operators.
105 // ----------------------------------------------------------------------
107 class operator_equal : public range_operator
109 public:
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
160 public:
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
211 public:
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
259 public:
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
310 public:
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
360 public:
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
411 public:
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
443 public:
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
459 public:
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;
502 private:
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
512 public:
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,
533 const irange &op2,
534 relation_kind rel) const final override;
535 relation_kind lhs_op2_relation (const irange &lhs, const irange &op1,
536 const irange &op2,
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); }
546 private:
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
558 public:
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); }
576 private:
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
585 public:
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,
603 const frange &lhs,
604 const frange &op1,
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); }
622 private:
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
634 public:
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
658 public:
659 virtual bool wi_op_overflows (wide_int &r,
660 tree type,
661 const wide_int &,
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
672 public:
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
712 public:
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
728 public:
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
747 public:
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,
759 tree type,
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); }
768 private:
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
776 public:
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,
783 const prange &op1,
784 const prange &op2,
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); }
800 protected:
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,
805 const irange &lhs,
806 const irange &op2) const;
809 class operator_bitwise_or : public range_operator
811 public:
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); }
826 protected:
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
834 public:
835 using range_operator::fold_range;
836 using range_operator::update_bitmask;
837 bool fold_range (prange &r, tree type,
838 const prange &op1,
839 const prange &op2,
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); }
846 protected:
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
854 public:
855 using range_operator::fold_range;
856 using range_operator::update_bitmask;
857 bool fold_range (prange &r, tree type,
858 const prange &op1,
859 const prange &op2,
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); }
866 protected:
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