1/* Header file for mixed range operator class.
2 Copyright (C) 2017-2023 Free Software Foundation, Inc.
3 Contributed by Andrew MacLeod <amacleod@redhat.com>
4 and Aldy Hernandez <aldyh@redhat.com>.
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
21
22#ifndef GCC_RANGE_OP_MIXED_H
23#define GCC_RANGE_OP_MIXED_H
24
25void update_known_bitmask (irange &, tree_code, const irange &, const irange &);
26bool minus_op1_op2_relation_effect (irange &lhs_range, tree type,
27 const irange &, const irange &,
28 relation_kind rel);
29
30
31// Return TRUE if 0 is within [WMIN, WMAX].
32
33inline bool
34wi_includes_zero_p (tree type, const wide_int &wmin, const wide_int &wmax)
35{
36 signop sign = TYPE_SIGN (type);
37 return wi::le_p (x: wmin, y: 0, sgn: sign) && wi::ge_p (x: wmax, y: 0, sgn: sign);
38}
39
40// Return TRUE if [WMIN, WMAX] is the singleton 0.
41
42inline bool
43wi_zero_p (tree type, const wide_int &wmin, const wide_int &wmax)
44{
45 unsigned prec = TYPE_PRECISION (type);
46 return wmin == wmax && wi::eq_p (x: wmin, y: wi::zero (precision: prec));
47}
48
49
50enum bool_range_state { BRS_FALSE, BRS_TRUE, BRS_EMPTY, BRS_FULL };
51bool_range_state get_bool_state (vrange &r, const vrange &lhs, tree val_type);
52
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.
57
58inline bool
59empty_range_varying (vrange &r, tree type,
60 const vrange &op1, const vrange & op2)
61{
62 if (op1.undefined_p () || op2.undefined_p ())
63 {
64 r.set_varying (type);
65 return true;
66 }
67 else
68 return false;
69}
70
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.
75
76inline bool
77relop_early_resolve (irange &r, tree type, const vrange &op1,
78 const vrange &op2, relation_trio trio,
79 relation_kind my_rel)
80{
81 relation_kind rel = trio.op1_op2 ();
82 // If known relation is a complete subset of this relation, always true.
83 if (relation_union (r1: rel, r2: my_rel) == my_rel)
84 {
85 r = range_true (type);
86 return true;
87 }
88
89 // If known relation has no subset of this relation, always false.
90 if (relation_intersect (r1: rel, r2: my_rel) == VREL_UNDEFINED)
91 {
92 r = range_false (type);
93 return true;
94 }
95
96 // If either operand is undefined, return VARYING.
97 if (empty_range_varying (r, type, op1, op2))
98 return true;
99
100 return false;
101}
102
103// ----------------------------------------------------------------------
104// Mixed Mode Operators.
105// ----------------------------------------------------------------------
106
107class operator_equal : public range_operator
108{
109public:
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 bool fold_range (irange &r, tree type,
115 const irange &op1, const irange &op2,
116 relation_trio = TRIO_VARYING) const final override;
117 bool fold_range (irange &r, tree type,
118 const frange &op1, const frange &op2,
119 relation_trio = TRIO_VARYING) const final override;
120
121 bool op1_range (irange &r, tree type,
122 const irange &lhs, const irange &val,
123 relation_trio = TRIO_VARYING) const final override;
124 bool op1_range (frange &r, tree type,
125 const irange &lhs, const frange &op2,
126 relation_trio = TRIO_VARYING) const final override;
127
128 bool op2_range (irange &r, tree type,
129 const irange &lhs, const irange &val,
130 relation_trio = TRIO_VARYING) const final override;
131 bool op2_range (frange &r, tree type,
132 const irange &lhs, const frange &op1,
133 relation_trio rel = TRIO_VARYING) const final override;
134
135 relation_kind op1_op2_relation (const irange &lhs, const irange &,
136 const irange &) const final override;
137 relation_kind op1_op2_relation (const irange &lhs, const frange &,
138 const frange &) const final override;
139 void update_bitmask (irange &r, const irange &lh,
140 const irange &rh) const final override;
141};
142
143class operator_not_equal : public range_operator
144{
145public:
146 using range_operator::fold_range;
147 using range_operator::op1_range;
148 using range_operator::op2_range;
149 using range_operator::op1_op2_relation;
150 bool fold_range (irange &r, tree type,
151 const irange &op1, const irange &op2,
152 relation_trio = TRIO_VARYING) const final override;
153 bool fold_range (irange &r, tree type,
154 const frange &op1, const frange &op2,
155 relation_trio rel = TRIO_VARYING) const final override;
156
157 bool op1_range (irange &r, tree type,
158 const irange &lhs, const irange &op2,
159 relation_trio = TRIO_VARYING) const final override;
160 bool op1_range (frange &r, tree type,
161 const irange &lhs, const frange &op2,
162 relation_trio = TRIO_VARYING) const final override;
163
164 bool op2_range (irange &r, tree type,
165 const irange &lhs, const irange &op1,
166 relation_trio = TRIO_VARYING) const final override;
167 bool op2_range (frange &r, tree type,
168 const irange &lhs, const frange &op1,
169 relation_trio = TRIO_VARYING) const final override;
170
171 relation_kind op1_op2_relation (const irange &lhs, const irange &,
172 const irange &) const final override;
173 relation_kind op1_op2_relation (const irange &lhs, const frange &,
174 const frange &) const final override;
175 void update_bitmask (irange &r, const irange &lh,
176 const irange &rh) const final override;
177};
178
179class operator_lt : public range_operator
180{
181public:
182 using range_operator::fold_range;
183 using range_operator::op1_range;
184 using range_operator::op2_range;
185 using range_operator::op1_op2_relation;
186 bool fold_range (irange &r, tree type,
187 const irange &op1, const irange &op2,
188 relation_trio = TRIO_VARYING) const final override;
189 bool fold_range (irange &r, tree type,
190 const frange &op1, const frange &op2,
191 relation_trio = TRIO_VARYING) const final override;
192 bool op1_range (irange &r, tree type,
193 const irange &lhs, const irange &op2,
194 relation_trio = TRIO_VARYING) const final override;
195 bool op1_range (frange &r, tree type,
196 const irange &lhs, const frange &op2,
197 relation_trio = TRIO_VARYING) const final override;
198 bool op2_range (irange &r, tree type,
199 const irange &lhs, const irange &op1,
200 relation_trio = TRIO_VARYING) const final override;
201 bool op2_range (frange &r, tree type,
202 const irange &lhs, const frange &op1,
203 relation_trio = TRIO_VARYING) const final override;
204 relation_kind op1_op2_relation (const irange &lhs, const irange &,
205 const irange &) const final override;
206 relation_kind op1_op2_relation (const irange &lhs, const frange &,
207 const frange &) const final override;
208 void update_bitmask (irange &r, const irange &lh,
209 const irange &rh) const final override;
210};
211
212class operator_le : public range_operator
213{
214public:
215 using range_operator::fold_range;
216 using range_operator::op1_range;
217 using range_operator::op2_range;
218 using range_operator::op1_op2_relation;
219 bool fold_range (irange &r, tree type,
220 const irange &op1, const irange &op2,
221 relation_trio = TRIO_VARYING) const final override;
222 bool fold_range (irange &r, tree type,
223 const frange &op1, const frange &op2,
224 relation_trio rel = TRIO_VARYING) const final override;
225
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 (frange &r, tree type,
230 const irange &lhs, const frange &op2,
231 relation_trio rel = TRIO_VARYING) const final override;
232
233 bool op2_range (irange &r, tree type,
234 const irange &lhs, const irange &op1,
235 relation_trio = TRIO_VARYING) const final override;
236 bool op2_range (frange &r, tree type,
237 const irange &lhs, const frange &op1,
238 relation_trio rel = TRIO_VARYING) const final override;
239
240 relation_kind op1_op2_relation (const irange &lhs, const irange &,
241 const irange &) const final override;
242 relation_kind op1_op2_relation (const irange &lhs, const frange &,
243 const frange &) const final override;
244 void update_bitmask (irange &r, const irange &lh,
245 const irange &rh) const final override;
246};
247
248class operator_gt : public range_operator
249{
250public:
251 using range_operator::fold_range;
252 using range_operator::op1_range;
253 using range_operator::op2_range;
254 using range_operator::op1_op2_relation;
255 bool fold_range (irange &r, tree type,
256 const irange &op1, const irange &op2,
257 relation_trio = TRIO_VARYING) const final override;
258 bool fold_range (irange &r, tree type,
259 const frange &op1, const frange &op2,
260 relation_trio = TRIO_VARYING) const final override;
261
262 bool op1_range (irange &r, tree type,
263 const irange &lhs, const irange &op2,
264 relation_trio = TRIO_VARYING) const final override;
265 bool op1_range (frange &r, tree type,
266 const irange &lhs, const frange &op2,
267 relation_trio = TRIO_VARYING) const final override;
268
269 bool op2_range (irange &r, tree type,
270 const irange &lhs, const irange &op1,
271 relation_trio = TRIO_VARYING) const final override;
272 bool op2_range (frange &r, tree type,
273 const irange &lhs, const frange &op1,
274 relation_trio = TRIO_VARYING) const final override;
275 relation_kind op1_op2_relation (const irange &lhs, const irange &,
276 const irange &) const final override;
277 relation_kind op1_op2_relation (const irange &lhs, const frange &,
278 const frange &) const final override;
279 void update_bitmask (irange &r, const irange &lh,
280 const irange &rh) const final override;
281};
282
283class operator_ge : public range_operator
284{
285public:
286 using range_operator::fold_range;
287 using range_operator::op1_range;
288 using range_operator::op2_range;
289 using range_operator::op1_op2_relation;
290 bool fold_range (irange &r, tree type,
291 const irange &op1, const irange &op2,
292 relation_trio = TRIO_VARYING) const final override;
293 bool fold_range (irange &r, tree type,
294 const frange &op1, const frange &op2,
295 relation_trio = TRIO_VARYING) const final override;
296
297 bool op1_range (irange &r, tree type,
298 const irange &lhs, const irange &op2,
299 relation_trio = TRIO_VARYING) const final override;
300 bool op1_range (frange &r, tree type,
301 const irange &lhs, const frange &op2,
302 relation_trio = TRIO_VARYING) const final override;
303
304 bool op2_range (irange &r, tree type,
305 const irange &lhs, const irange &op1,
306 relation_trio = TRIO_VARYING) const final override;
307 bool op2_range (frange &r, tree type,
308 const irange &lhs, const frange &op1,
309 relation_trio = TRIO_VARYING) const final override;
310
311 relation_kind op1_op2_relation (const irange &lhs, const irange &,
312 const irange &) const final override;
313 relation_kind op1_op2_relation (const irange &lhs, const frange &,
314 const frange &) const final override;
315 void update_bitmask (irange &r, const irange &lh,
316 const irange &rh) const final override;
317};
318
319class operator_identity : public range_operator
320{
321public:
322 using range_operator::fold_range;
323 using range_operator::op1_range;
324 using range_operator::lhs_op1_relation;
325 bool fold_range (irange &r, tree type,
326 const irange &op1, const irange &op2,
327 relation_trio rel = TRIO_VARYING) const final override;
328 bool fold_range (frange &r, tree type ATTRIBUTE_UNUSED,
329 const frange &op1, const frange &op2 ATTRIBUTE_UNUSED,
330 relation_trio = TRIO_VARYING) const final override;
331 bool op1_range (irange &r, tree type,
332 const irange &lhs, const irange &op2,
333 relation_trio rel = TRIO_VARYING) const final override;
334 bool op1_range (frange &r, tree type ATTRIBUTE_UNUSED,
335 const frange &lhs, const frange &op2 ATTRIBUTE_UNUSED,
336 relation_trio = TRIO_VARYING) const final override;
337 relation_kind lhs_op1_relation (const irange &lhs,
338 const irange &op1, const irange &op2,
339 relation_kind rel) const final override;
340};
341
342class operator_cst : public range_operator
343{
344public:
345 using range_operator::fold_range;
346 bool fold_range (irange &r, tree type,
347 const irange &op1, const irange &op2,
348 relation_trio rel = TRIO_VARYING) const final override;
349 bool fold_range (frange &r, tree type,
350 const frange &op1, const frange &op2,
351 relation_trio = TRIO_VARYING) const final override;
352};
353
354
355class operator_cast: public range_operator
356{
357public:
358 using range_operator::fold_range;
359 using range_operator::op1_range;
360 using range_operator::lhs_op1_relation;
361 bool fold_range (irange &r, tree type,
362 const irange &op1, const irange &op2,
363 relation_trio rel = TRIO_VARYING) const final override;
364 bool op1_range (irange &r, tree type,
365 const irange &lhs, const irange &op2,
366 relation_trio rel = TRIO_VARYING) const final override;
367 relation_kind lhs_op1_relation (const irange &lhs,
368 const irange &op1, const irange &op2,
369 relation_kind) const final override;
370 void update_bitmask (irange &r, const irange &lh,
371 const irange &rh) const final override;
372private:
373 bool truncating_cast_p (const irange &inner, const irange &outer) const;
374 bool inside_domain_p (const wide_int &min, const wide_int &max,
375 const irange &outer) const;
376 void fold_pair (irange &r, unsigned index, const irange &inner,
377 const irange &outer) const;
378};
379
380class operator_plus : public range_operator
381{
382public:
383 using range_operator::op1_range;
384 using range_operator::op2_range;
385 using range_operator::lhs_op1_relation;
386 using range_operator::lhs_op2_relation;
387 bool op1_range (irange &r, tree type,
388 const irange &lhs, const irange &op2,
389 relation_trio) const final override;
390 bool op1_range (frange &r, tree type,
391 const frange &lhs, const frange &op2,
392 relation_trio = TRIO_VARYING) const final override;
393
394 bool op2_range (irange &r, tree type,
395 const irange &lhs, const irange &op1,
396 relation_trio) const final override;
397 bool op2_range (frange &r, tree type,
398 const frange &lhs, const frange &op1,
399 relation_trio = TRIO_VARYING) const final override;
400
401 relation_kind lhs_op1_relation (const irange &lhs, const irange &op1,
402 const irange &op2,
403 relation_kind rel) const final override;
404 relation_kind lhs_op2_relation (const irange &lhs, const irange &op1,
405 const irange &op2,
406 relation_kind rel) const final override;
407 void update_bitmask (irange &r, const irange &lh,
408 const irange &rh) const final override;
409
410 virtual bool overflow_free_p (const irange &lh, const irange &rh,
411 relation_trio = TRIO_VARYING) const;
412
413private:
414 void wi_fold (irange &r, tree type, const wide_int &lh_lb,
415 const wide_int &lh_ub, const wide_int &rh_lb,
416 const wide_int &rh_ub) const final override;
417 void rv_fold (frange &r, tree type,
418 const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
419 const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub,
420 relation_kind) const final override;
421};
422
423class operator_abs : public range_operator
424{
425 public:
426 using range_operator::fold_range;
427 using range_operator::op1_range;
428 bool fold_range (frange &r, tree type,
429 const frange &op1, const frange &,
430 relation_trio = TRIO_VARYING) const final override;
431
432 bool op1_range (irange &r, tree type, const irange &lhs,
433 const irange &op2, relation_trio) const final override;
434 bool op1_range (frange &r, tree type,
435 const frange &lhs, const frange &op2,
436 relation_trio rel = TRIO_VARYING) const final override;
437 void update_bitmask (irange &r, const irange &lh,
438 const irange &rh) const final override;
439private:
440 void wi_fold (irange &r, tree type, const wide_int &lh_lb,
441 const wide_int &lh_ub, const wide_int &rh_lb,
442 const wide_int &rh_ub) const final override;
443
444};
445
446class operator_minus : public range_operator
447{
448public:
449 using range_operator::fold_range;
450 using range_operator::op1_range;
451 using range_operator::op2_range;
452 using range_operator::lhs_op1_relation;
453 bool op1_range (irange &r, tree type,
454 const irange &lhs, const irange &op2,
455 relation_trio) const final override;
456 bool op1_range (frange &r, tree type,
457 const frange &lhs, const frange &op2,
458 relation_trio = TRIO_VARYING) const final override;
459
460 bool op2_range (irange &r, tree type,
461 const irange &lhs, const irange &op1,
462 relation_trio) const final override;
463 bool op2_range (frange &r, tree type,
464 const frange &lhs,
465 const frange &op1,
466 relation_trio = TRIO_VARYING) const final override;
467
468 relation_kind lhs_op1_relation (const irange &lhs,
469 const irange &op1, const irange &op2,
470 relation_kind rel) const final override;
471 bool op1_op2_relation_effect (irange &lhs_range, tree type,
472 const irange &op1_range,
473 const irange &op2_range,
474 relation_kind rel) const final override;
475 void update_bitmask (irange &r, const irange &lh,
476 const irange &rh) const final override;
477
478 virtual bool overflow_free_p (const irange &lh, const irange &rh,
479 relation_trio = TRIO_VARYING) const;
480
481private:
482 void wi_fold (irange &r, tree type, const wide_int &lh_lb,
483 const wide_int &lh_ub, const wide_int &rh_lb,
484 const wide_int &rh_ub) const final override;
485 void rv_fold (frange &r, tree type,
486 const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
487 const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub,
488 relation_kind) const final override;
489};
490
491class operator_negate : public range_operator
492{
493 public:
494 using range_operator::fold_range;
495 using range_operator::op1_range;
496 bool fold_range (irange &r, tree type,
497 const irange &op1, const irange &op2,
498 relation_trio rel = TRIO_VARYING) const final override;
499 bool fold_range (frange &r, tree type,
500 const frange &op1, const frange &op2,
501 relation_trio = TRIO_VARYING) const final override;
502
503 bool op1_range (irange &r, tree type,
504 const irange &lhs, const irange &op2,
505 relation_trio rel = TRIO_VARYING) const final override;
506 bool op1_range (frange &r, tree type,
507 const frange &lhs, const frange &op2,
508 relation_trio rel = TRIO_VARYING) const final override;
509};
510
511
512class cross_product_operator : public range_operator
513{
514public:
515 virtual bool wi_op_overflows (wide_int &r,
516 tree type,
517 const wide_int &,
518 const wide_int &) const = 0;
519 void wi_cross_product (irange &r, tree type,
520 const wide_int &lh_lb,
521 const wide_int &lh_ub,
522 const wide_int &rh_lb,
523 const wide_int &rh_ub) const;
524};
525
526class operator_mult : public cross_product_operator
527{
528public:
529 using range_operator::op1_range;
530 using range_operator::op2_range;
531 bool op1_range (irange &r, tree type,
532 const irange &lhs, const irange &op2,
533 relation_trio) const final override;
534 bool op1_range (frange &r, tree type,
535 const frange &lhs, const frange &op2,
536 relation_trio = TRIO_VARYING) const final override;
537
538 bool op2_range (irange &r, tree type,
539 const irange &lhs, const irange &op1,
540 relation_trio) const final override;
541 bool op2_range (frange &r, tree type,
542 const frange &lhs, const frange &op1,
543 relation_trio = TRIO_VARYING) const final override;
544
545 void update_bitmask (irange &r, const irange &lh,
546 const irange &rh) const final override;
547
548 void wi_fold (irange &r, tree type, const wide_int &lh_lb,
549 const wide_int &lh_ub, const wide_int &rh_lb,
550 const wide_int &rh_ub) const final override;
551 bool wi_op_overflows (wide_int &res, tree type, const wide_int &w0,
552 const wide_int &w1) const final override;
553
554 void rv_fold (frange &r, tree type,
555 const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
556 const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub,
557 relation_kind kind) const final override;
558 virtual bool overflow_free_p (const irange &lh, const irange &rh,
559 relation_trio = TRIO_VARYING) const;
560
561};
562
563class operator_addr_expr : public range_operator
564{
565public:
566 using range_operator::fold_range;
567 using range_operator::op1_range;
568 bool fold_range (irange &r, tree type,
569 const irange &op1, const irange &op2,
570 relation_trio rel = TRIO_VARYING) const final override;
571 bool op1_range (irange &r, tree type,
572 const irange &lhs, const irange &op2,
573 relation_trio rel = TRIO_VARYING) const final override;
574};
575
576class operator_bitwise_not : public range_operator
577{
578public:
579 using range_operator::fold_range;
580 using range_operator::op1_range;
581 bool fold_range (irange &r, tree type,
582 const irange &lh, const irange &rh,
583 relation_trio rel = TRIO_VARYING) const final override;
584 bool op1_range (irange &r, tree type,
585 const irange &lhs, const irange &op2,
586 relation_trio rel = TRIO_VARYING) const final override;
587 void update_bitmask (irange &r, const irange &lh,
588 const irange &rh) const final override;
589};
590
591class operator_bitwise_xor : public range_operator
592{
593public:
594 using range_operator::op1_range;
595 using range_operator::op2_range;
596 bool op1_range (irange &r, tree type,
597 const irange &lhs, const irange &op2,
598 relation_trio rel = TRIO_VARYING) const final override;
599 bool op2_range (irange &r, tree type,
600 const irange &lhs, const irange &op1,
601 relation_trio rel = TRIO_VARYING) const final override;
602 bool op1_op2_relation_effect (irange &lhs_range,
603 tree type,
604 const irange &op1_range,
605 const irange &op2_range,
606 relation_kind rel) const final override;
607 void update_bitmask (irange &r, const irange &lh,
608 const irange &rh) const final override;
609private:
610 void wi_fold (irange &r, tree type, const wide_int &lh_lb,
611 const wide_int &lh_ub, const wide_int &rh_lb,
612 const wide_int &rh_ub) const final override;
613};
614
615class operator_bitwise_and : public range_operator
616{
617public:
618 using range_operator::op1_range;
619 using range_operator::op2_range;
620 using range_operator::lhs_op1_relation;
621 bool op1_range (irange &r, tree type,
622 const irange &lhs, const irange &op2,
623 relation_trio rel = TRIO_VARYING) const override;
624 bool op2_range (irange &r, tree type,
625 const irange &lhs, const irange &op1,
626 relation_trio rel = TRIO_VARYING) const override;
627 relation_kind lhs_op1_relation (const irange &lhs,
628 const irange &op1, const irange &op2,
629 relation_kind) const override;
630 void update_bitmask (irange &r, const irange &lh,
631 const irange &rh) const override;
632protected:
633 void wi_fold (irange &r, tree type, const wide_int &lh_lb,
634 const wide_int &lh_ub, const wide_int &rh_lb,
635 const wide_int &rh_ub) const override;
636 void simple_op1_range_solver (irange &r, tree type,
637 const irange &lhs,
638 const irange &op2) const;
639};
640
641class operator_bitwise_or : public range_operator
642{
643public:
644 using range_operator::op1_range;
645 using range_operator::op2_range;
646 bool op1_range (irange &r, tree type,
647 const irange &lhs, const irange &op2,
648 relation_trio rel = TRIO_VARYING) const override;
649 bool op2_range (irange &r, tree type,
650 const irange &lhs, const irange &op1,
651 relation_trio rel = TRIO_VARYING) const override;
652 void update_bitmask (irange &r, const irange &lh,
653 const irange &rh) const override;
654protected:
655 void wi_fold (irange &r, tree type, const wide_int &lh_lb,
656 const wide_int &lh_ub, const wide_int &rh_lb,
657 const wide_int &rh_ub) const override;
658};
659
660class operator_min : public range_operator
661{
662public:
663 void update_bitmask (irange &r, const irange &lh,
664 const irange &rh) const override;
665protected:
666 void wi_fold (irange &r, tree type, const wide_int &lh_lb,
667 const wide_int &lh_ub, const wide_int &rh_lb,
668 const wide_int &rh_ub) const override;
669};
670
671class operator_max : public range_operator
672{
673public:
674 void update_bitmask (irange &r, const irange &lh,
675 const irange &rh) const override;
676protected:
677 void wi_fold (irange &r, tree type, const wide_int &lh_lb,
678 const wide_int &lh_ub, const wide_int &rh_lb,
679 const wide_int &rh_ub) const override;
680};
681#endif // GCC_RANGE_OP_MIXED_H
682

source code of gcc/range-op-mixed.h