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 (irange
&, tree_code
, const irange
&, const irange
&);
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 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
;
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
;
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
;
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 // Check op1 and op2 for compatibility.
142 bool operand_check_p (tree
, tree t1
, tree t2
) const final override
143 { return range_compatible_p (t1
, t2
); }
146 class operator_not_equal
: public range_operator
149 using range_operator::fold_range
;
150 using range_operator::op1_range
;
151 using range_operator::op2_range
;
152 using range_operator::op1_op2_relation
;
153 bool fold_range (irange
&r
, tree type
,
154 const irange
&op1
, const irange
&op2
,
155 relation_trio
= TRIO_VARYING
) const final override
;
156 bool fold_range (irange
&r
, tree type
,
157 const frange
&op1
, const frange
&op2
,
158 relation_trio rel
= TRIO_VARYING
) const final override
;
160 bool op1_range (irange
&r
, tree type
,
161 const irange
&lhs
, const irange
&op2
,
162 relation_trio
= TRIO_VARYING
) const final override
;
163 bool op1_range (frange
&r
, tree type
,
164 const irange
&lhs
, const frange
&op2
,
165 relation_trio
= TRIO_VARYING
) const final override
;
167 bool op2_range (irange
&r
, tree type
,
168 const irange
&lhs
, const irange
&op1
,
169 relation_trio
= TRIO_VARYING
) const final override
;
170 bool op2_range (frange
&r
, tree type
,
171 const irange
&lhs
, const frange
&op1
,
172 relation_trio
= TRIO_VARYING
) const final override
;
174 relation_kind
op1_op2_relation (const irange
&lhs
, const irange
&,
175 const irange
&) const final override
;
176 relation_kind
op1_op2_relation (const irange
&lhs
, const frange
&,
177 const frange
&) const final override
;
178 void update_bitmask (irange
&r
, const irange
&lh
,
179 const irange
&rh
) const final override
;
180 // Check op1 and op2 for compatibility.
181 bool operand_check_p (tree
, tree t1
, tree t2
) const final override
182 { return range_compatible_p (t1
, t2
); }
185 class operator_lt
: public range_operator
188 using range_operator::fold_range
;
189 using range_operator::op1_range
;
190 using range_operator::op2_range
;
191 using range_operator::op1_op2_relation
;
192 bool fold_range (irange
&r
, tree type
,
193 const irange
&op1
, const irange
&op2
,
194 relation_trio
= TRIO_VARYING
) const final override
;
195 bool fold_range (irange
&r
, tree type
,
196 const frange
&op1
, const frange
&op2
,
197 relation_trio
= TRIO_VARYING
) const final override
;
198 bool op1_range (irange
&r
, tree type
,
199 const irange
&lhs
, const irange
&op2
,
200 relation_trio
= TRIO_VARYING
) const final override
;
201 bool op1_range (frange
&r
, tree type
,
202 const irange
&lhs
, const frange
&op2
,
203 relation_trio
= TRIO_VARYING
) const final override
;
204 bool op2_range (irange
&r
, tree type
,
205 const irange
&lhs
, const irange
&op1
,
206 relation_trio
= TRIO_VARYING
) const final override
;
207 bool op2_range (frange
&r
, tree type
,
208 const irange
&lhs
, const frange
&op1
,
209 relation_trio
= TRIO_VARYING
) const final override
;
210 relation_kind
op1_op2_relation (const irange
&lhs
, const irange
&,
211 const irange
&) const final override
;
212 relation_kind
op1_op2_relation (const irange
&lhs
, const frange
&,
213 const frange
&) const final override
;
214 void update_bitmask (irange
&r
, const irange
&lh
,
215 const irange
&rh
) const final override
;
216 // Check op1 and op2 for compatibility.
217 bool operand_check_p (tree
, tree t1
, tree t2
) const final override
218 { return range_compatible_p (t1
, t2
); }
221 class operator_le
: public range_operator
224 using range_operator::fold_range
;
225 using range_operator::op1_range
;
226 using range_operator::op2_range
;
227 using range_operator::op1_op2_relation
;
228 bool fold_range (irange
&r
, tree type
,
229 const irange
&op1
, const irange
&op2
,
230 relation_trio
= TRIO_VARYING
) const final override
;
231 bool fold_range (irange
&r
, tree type
,
232 const frange
&op1
, const frange
&op2
,
233 relation_trio rel
= TRIO_VARYING
) const final override
;
235 bool op1_range (irange
&r
, tree type
,
236 const irange
&lhs
, const irange
&op2
,
237 relation_trio
= TRIO_VARYING
) const final override
;
238 bool op1_range (frange
&r
, tree type
,
239 const irange
&lhs
, const frange
&op2
,
240 relation_trio rel
= TRIO_VARYING
) const final override
;
242 bool op2_range (irange
&r
, tree type
,
243 const irange
&lhs
, const irange
&op1
,
244 relation_trio
= TRIO_VARYING
) const final override
;
245 bool op2_range (frange
&r
, tree type
,
246 const irange
&lhs
, const frange
&op1
,
247 relation_trio rel
= TRIO_VARYING
) const final override
;
249 relation_kind
op1_op2_relation (const irange
&lhs
, const irange
&,
250 const irange
&) const final override
;
251 relation_kind
op1_op2_relation (const irange
&lhs
, const frange
&,
252 const frange
&) const final override
;
253 void update_bitmask (irange
&r
, const irange
&lh
,
254 const irange
&rh
) const final override
;
255 // Check op1 and op2 for compatibility.
256 bool operand_check_p (tree
, tree t1
, tree t2
) const final override
257 { return range_compatible_p (t1
, t2
); }
260 class operator_gt
: public range_operator
263 using range_operator::fold_range
;
264 using range_operator::op1_range
;
265 using range_operator::op2_range
;
266 using range_operator::op1_op2_relation
;
267 bool fold_range (irange
&r
, tree type
,
268 const irange
&op1
, const irange
&op2
,
269 relation_trio
= TRIO_VARYING
) const final override
;
270 bool fold_range (irange
&r
, tree type
,
271 const frange
&op1
, const frange
&op2
,
272 relation_trio
= TRIO_VARYING
) const final override
;
274 bool op1_range (irange
&r
, tree type
,
275 const irange
&lhs
, const irange
&op2
,
276 relation_trio
= TRIO_VARYING
) const final override
;
277 bool op1_range (frange
&r
, tree type
,
278 const irange
&lhs
, const frange
&op2
,
279 relation_trio
= TRIO_VARYING
) const final override
;
281 bool op2_range (irange
&r
, tree type
,
282 const irange
&lhs
, const irange
&op1
,
283 relation_trio
= TRIO_VARYING
) const final override
;
284 bool op2_range (frange
&r
, tree type
,
285 const irange
&lhs
, const frange
&op1
,
286 relation_trio
= TRIO_VARYING
) const final override
;
287 relation_kind
op1_op2_relation (const irange
&lhs
, const irange
&,
288 const irange
&) const final override
;
289 relation_kind
op1_op2_relation (const irange
&lhs
, const frange
&,
290 const frange
&) const final override
;
291 void update_bitmask (irange
&r
, const irange
&lh
,
292 const irange
&rh
) const final override
;
293 // Check op1 and op2 for compatibility.
294 bool operand_check_p (tree
, tree t1
, tree t2
) const final override
295 { return range_compatible_p (t1
, t2
); }
298 class operator_ge
: public range_operator
301 using range_operator::fold_range
;
302 using range_operator::op1_range
;
303 using range_operator::op2_range
;
304 using range_operator::op1_op2_relation
;
305 bool fold_range (irange
&r
, tree type
,
306 const irange
&op1
, const irange
&op2
,
307 relation_trio
= TRIO_VARYING
) const final override
;
308 bool fold_range (irange
&r
, tree type
,
309 const frange
&op1
, const frange
&op2
,
310 relation_trio
= TRIO_VARYING
) const final override
;
312 bool op1_range (irange
&r
, tree type
,
313 const irange
&lhs
, const irange
&op2
,
314 relation_trio
= TRIO_VARYING
) const final override
;
315 bool op1_range (frange
&r
, tree type
,
316 const irange
&lhs
, const frange
&op2
,
317 relation_trio
= TRIO_VARYING
) const final override
;
319 bool op2_range (irange
&r
, tree type
,
320 const irange
&lhs
, const irange
&op1
,
321 relation_trio
= TRIO_VARYING
) const final override
;
322 bool op2_range (frange
&r
, tree type
,
323 const irange
&lhs
, const frange
&op1
,
324 relation_trio
= TRIO_VARYING
) const final override
;
326 relation_kind
op1_op2_relation (const irange
&lhs
, const irange
&,
327 const irange
&) const final override
;
328 relation_kind
op1_op2_relation (const irange
&lhs
, const frange
&,
329 const frange
&) const final override
;
330 void update_bitmask (irange
&r
, const irange
&lh
,
331 const irange
&rh
) const final override
;
332 // Check op1 and op2 for compatibility.
333 bool operand_check_p (tree
, tree t1
, tree t2
) const final override
334 { return range_compatible_p (t1
, t2
); }
337 class operator_identity
: public range_operator
340 using range_operator::fold_range
;
341 using range_operator::op1_range
;
342 using range_operator::lhs_op1_relation
;
343 bool fold_range (irange
&r
, tree type
,
344 const irange
&op1
, const irange
&op2
,
345 relation_trio rel
= TRIO_VARYING
) const final override
;
346 bool fold_range (frange
&r
, tree type ATTRIBUTE_UNUSED
,
347 const frange
&op1
, const frange
&op2 ATTRIBUTE_UNUSED
,
348 relation_trio
= TRIO_VARYING
) const final override
;
349 bool op1_range (irange
&r
, tree type
,
350 const irange
&lhs
, const irange
&op2
,
351 relation_trio rel
= TRIO_VARYING
) const final override
;
352 bool op1_range (frange
&r
, tree type ATTRIBUTE_UNUSED
,
353 const frange
&lhs
, const frange
&op2 ATTRIBUTE_UNUSED
,
354 relation_trio
= TRIO_VARYING
) const final override
;
355 relation_kind
lhs_op1_relation (const irange
&lhs
,
356 const irange
&op1
, const irange
&op2
,
357 relation_kind rel
) const final override
;
360 class operator_cst
: public range_operator
363 using range_operator::fold_range
;
364 bool fold_range (irange
&r
, tree type
,
365 const irange
&op1
, const irange
&op2
,
366 relation_trio rel
= TRIO_VARYING
) const final override
;
367 bool fold_range (frange
&r
, tree type
,
368 const frange
&op1
, const frange
&op2
,
369 relation_trio
= TRIO_VARYING
) const final override
;
373 class operator_cast
: public range_operator
376 using range_operator::fold_range
;
377 using range_operator::op1_range
;
378 using range_operator::lhs_op1_relation
;
379 bool fold_range (irange
&r
, tree type
,
380 const irange
&op1
, const irange
&op2
,
381 relation_trio rel
= TRIO_VARYING
) const final override
;
382 bool op1_range (irange
&r
, tree type
,
383 const irange
&lhs
, const irange
&op2
,
384 relation_trio rel
= TRIO_VARYING
) const final override
;
385 relation_kind
lhs_op1_relation (const irange
&lhs
,
386 const irange
&op1
, const irange
&op2
,
387 relation_kind
) const final override
;
388 void update_bitmask (irange
&r
, const irange
&lh
,
389 const irange
&rh
) const final override
;
391 bool truncating_cast_p (const irange
&inner
, const irange
&outer
) const;
392 bool inside_domain_p (const wide_int
&min
, const wide_int
&max
,
393 const irange
&outer
) const;
394 void fold_pair (irange
&r
, unsigned index
, const irange
&inner
,
395 const irange
&outer
) const;
398 class operator_plus
: public range_operator
401 using range_operator::op1_range
;
402 using range_operator::op2_range
;
403 using range_operator::lhs_op1_relation
;
404 using range_operator::lhs_op2_relation
;
405 bool op1_range (irange
&r
, tree type
,
406 const irange
&lhs
, const irange
&op2
,
407 relation_trio
) const final override
;
408 bool op1_range (frange
&r
, tree type
,
409 const frange
&lhs
, const frange
&op2
,
410 relation_trio
= TRIO_VARYING
) const final override
;
412 bool op2_range (irange
&r
, tree type
,
413 const irange
&lhs
, const irange
&op1
,
414 relation_trio
) const final override
;
415 bool op2_range (frange
&r
, tree type
,
416 const frange
&lhs
, const frange
&op1
,
417 relation_trio
= TRIO_VARYING
) const final override
;
419 relation_kind
lhs_op1_relation (const irange
&lhs
, const irange
&op1
,
421 relation_kind rel
) const final override
;
422 relation_kind
lhs_op2_relation (const irange
&lhs
, const irange
&op1
,
424 relation_kind rel
) const final override
;
425 void update_bitmask (irange
&r
, const irange
&lh
,
426 const irange
&rh
) const final override
;
428 virtual bool overflow_free_p (const irange
&lh
, const irange
&rh
,
429 relation_trio
= TRIO_VARYING
) const;
430 // Check compatibility of all operands.
431 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
432 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
434 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
435 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
436 const wide_int
&rh_ub
) const final override
;
437 void rv_fold (frange
&r
, tree type
,
438 const REAL_VALUE_TYPE
&lh_lb
, const REAL_VALUE_TYPE
&lh_ub
,
439 const REAL_VALUE_TYPE
&rh_lb
, const REAL_VALUE_TYPE
&rh_ub
,
440 relation_kind
) const final override
;
443 class operator_abs
: public range_operator
446 using range_operator::fold_range
;
447 using range_operator::op1_range
;
448 bool fold_range (frange
&r
, tree type
,
449 const frange
&op1
, const frange
&,
450 relation_trio
= TRIO_VARYING
) const final override
;
452 bool op1_range (irange
&r
, tree type
, const irange
&lhs
,
453 const irange
&op2
, relation_trio
) const final override
;
454 bool op1_range (frange
&r
, tree type
,
455 const frange
&lhs
, const frange
&op2
,
456 relation_trio rel
= TRIO_VARYING
) const final override
;
457 void update_bitmask (irange
&r
, const irange
&lh
,
458 const irange
&rh
) const final override
;
459 // Check compatibility of LHS and op1.
460 bool operand_check_p (tree t1
, tree t2
, tree
) const final override
461 { return range_compatible_p (t1
, t2
); }
463 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
464 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
465 const wide_int
&rh_ub
) const final override
;
469 class operator_minus
: public range_operator
472 using range_operator::fold_range
;
473 using range_operator::op1_range
;
474 using range_operator::op2_range
;
475 using range_operator::lhs_op1_relation
;
476 bool op1_range (irange
&r
, tree type
,
477 const irange
&lhs
, const irange
&op2
,
478 relation_trio
) const final override
;
479 bool op1_range (frange
&r
, tree type
,
480 const frange
&lhs
, const frange
&op2
,
481 relation_trio
= TRIO_VARYING
) const final override
;
483 bool op2_range (irange
&r
, tree type
,
484 const irange
&lhs
, const irange
&op1
,
485 relation_trio
) const final override
;
486 bool op2_range (frange
&r
, tree type
,
489 relation_trio
= TRIO_VARYING
) const final override
;
491 relation_kind
lhs_op1_relation (const irange
&lhs
,
492 const irange
&op1
, const irange
&op2
,
493 relation_kind rel
) const final override
;
494 bool op1_op2_relation_effect (irange
&lhs_range
, tree type
,
495 const irange
&op1_range
,
496 const irange
&op2_range
,
497 relation_kind rel
) const final override
;
498 void update_bitmask (irange
&r
, const irange
&lh
,
499 const irange
&rh
) const final override
;
501 virtual bool overflow_free_p (const irange
&lh
, const irange
&rh
,
502 relation_trio
= TRIO_VARYING
) const;
503 // Check compatibility of all operands.
504 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
505 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
507 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
508 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
509 const wide_int
&rh_ub
) const final override
;
510 void rv_fold (frange
&r
, tree type
,
511 const REAL_VALUE_TYPE
&lh_lb
, const REAL_VALUE_TYPE
&lh_ub
,
512 const REAL_VALUE_TYPE
&rh_lb
, const REAL_VALUE_TYPE
&rh_ub
,
513 relation_kind
) const final override
;
516 class operator_negate
: public range_operator
519 using range_operator::fold_range
;
520 using range_operator::op1_range
;
521 bool fold_range (irange
&r
, tree type
,
522 const irange
&op1
, const irange
&op2
,
523 relation_trio rel
= TRIO_VARYING
) const final override
;
524 bool fold_range (frange
&r
, tree type
,
525 const frange
&op1
, const frange
&op2
,
526 relation_trio
= TRIO_VARYING
) const final override
;
528 bool op1_range (irange
&r
, tree type
,
529 const irange
&lhs
, const irange
&op2
,
530 relation_trio rel
= TRIO_VARYING
) const final override
;
531 bool op1_range (frange
&r
, tree type
,
532 const frange
&lhs
, const frange
&op2
,
533 relation_trio rel
= TRIO_VARYING
) const final override
;
534 // Check compatibility of LHS and op1.
535 bool operand_check_p (tree t1
, tree t2
, tree
) const final override
536 { return range_compatible_p (t1
, t2
); }
540 class cross_product_operator
: public range_operator
543 virtual bool wi_op_overflows (wide_int
&r
,
546 const wide_int
&) const = 0;
547 void wi_cross_product (irange
&r
, tree type
,
548 const wide_int
&lh_lb
,
549 const wide_int
&lh_ub
,
550 const wide_int
&rh_lb
,
551 const wide_int
&rh_ub
) const;
554 class operator_mult
: public cross_product_operator
557 using range_operator::op1_range
;
558 using range_operator::op2_range
;
559 bool op1_range (irange
&r
, tree type
,
560 const irange
&lhs
, const irange
&op2
,
561 relation_trio
) const final override
;
562 bool op1_range (frange
&r
, tree type
,
563 const frange
&lhs
, const frange
&op2
,
564 relation_trio
= TRIO_VARYING
) const final override
;
566 bool op2_range (irange
&r
, tree type
,
567 const irange
&lhs
, const irange
&op1
,
568 relation_trio
) const final override
;
569 bool op2_range (frange
&r
, tree type
,
570 const frange
&lhs
, const frange
&op1
,
571 relation_trio
= TRIO_VARYING
) const final override
;
573 void update_bitmask (irange
&r
, const irange
&lh
,
574 const irange
&rh
) const final override
;
576 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
577 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
578 const wide_int
&rh_ub
) const final override
;
579 bool wi_op_overflows (wide_int
&res
, tree type
, const wide_int
&w0
,
580 const wide_int
&w1
) const final override
;
582 void rv_fold (frange
&r
, tree type
,
583 const REAL_VALUE_TYPE
&lh_lb
, const REAL_VALUE_TYPE
&lh_ub
,
584 const REAL_VALUE_TYPE
&rh_lb
, const REAL_VALUE_TYPE
&rh_ub
,
585 relation_kind kind
) const final override
;
586 virtual bool overflow_free_p (const irange
&lh
, const irange
&rh
,
587 relation_trio
= TRIO_VARYING
) const;
588 // Check compatibility of all operands.
589 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
590 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
593 class operator_addr_expr
: public range_operator
596 using range_operator::fold_range
;
597 using range_operator::op1_range
;
598 bool fold_range (irange
&r
, tree type
,
599 const irange
&op1
, const irange
&op2
,
600 relation_trio rel
= TRIO_VARYING
) const final override
;
601 bool op1_range (irange
&r
, tree type
,
602 const irange
&lhs
, const irange
&op2
,
603 relation_trio rel
= TRIO_VARYING
) const final override
;
606 class operator_bitwise_not
: public range_operator
609 using range_operator::fold_range
;
610 using range_operator::op1_range
;
611 bool fold_range (irange
&r
, tree type
,
612 const irange
&lh
, const irange
&rh
,
613 relation_trio rel
= TRIO_VARYING
) const final override
;
614 bool op1_range (irange
&r
, tree type
,
615 const irange
&lhs
, const irange
&op2
,
616 relation_trio rel
= TRIO_VARYING
) const final override
;
617 void update_bitmask (irange
&r
, const irange
&lh
,
618 const irange
&rh
) const final override
;
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
); }
624 class operator_bitwise_xor
: public range_operator
627 using range_operator::op1_range
;
628 using range_operator::op2_range
;
629 bool op1_range (irange
&r
, tree type
,
630 const irange
&lhs
, const irange
&op2
,
631 relation_trio rel
= TRIO_VARYING
) const final override
;
632 bool op2_range (irange
&r
, tree type
,
633 const irange
&lhs
, const irange
&op1
,
634 relation_trio rel
= TRIO_VARYING
) const final override
;
635 bool op1_op2_relation_effect (irange
&lhs_range
,
637 const irange
&op1_range
,
638 const irange
&op2_range
,
639 relation_kind rel
) const final override
;
640 void update_bitmask (irange
&r
, const irange
&lh
,
641 const irange
&rh
) const final override
;
642 // Check compatibility of all operands.
643 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
644 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
646 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
647 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
648 const wide_int
&rh_ub
) const final override
;
651 class operator_bitwise_and
: public range_operator
654 using range_operator::op1_range
;
655 using range_operator::op2_range
;
656 using range_operator::lhs_op1_relation
;
657 bool op1_range (irange
&r
, tree type
,
658 const irange
&lhs
, const irange
&op2
,
659 relation_trio rel
= TRIO_VARYING
) const override
;
660 bool op2_range (irange
&r
, tree type
,
661 const irange
&lhs
, const irange
&op1
,
662 relation_trio rel
= TRIO_VARYING
) const override
;
663 relation_kind
lhs_op1_relation (const irange
&lhs
,
664 const irange
&op1
, const irange
&op2
,
665 relation_kind
) const override
;
666 void update_bitmask (irange
&r
, const irange
&lh
,
667 const irange
&rh
) const override
;
668 // Check compatibility of all operands.
669 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
670 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
672 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
673 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
674 const wide_int
&rh_ub
) const override
;
675 void simple_op1_range_solver (irange
&r
, tree type
,
677 const irange
&op2
) const;
680 class operator_bitwise_or
: public range_operator
683 using range_operator::op1_range
;
684 using range_operator::op2_range
;
685 bool op1_range (irange
&r
, tree type
,
686 const irange
&lhs
, const irange
&op2
,
687 relation_trio rel
= TRIO_VARYING
) const override
;
688 bool op2_range (irange
&r
, tree type
,
689 const irange
&lhs
, const irange
&op1
,
690 relation_trio rel
= TRIO_VARYING
) const override
;
691 void update_bitmask (irange
&r
, const irange
&lh
,
692 const irange
&rh
) const override
;
693 // Check compatibility of all operands.
694 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
695 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
697 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
698 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
699 const wide_int
&rh_ub
) const override
;
702 class operator_min
: public range_operator
705 void update_bitmask (irange
&r
, const irange
&lh
,
706 const irange
&rh
) const override
;
707 // Check compatibility of all operands.
708 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
709 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
711 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
712 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
713 const wide_int
&rh_ub
) const override
;
716 class operator_max
: public range_operator
719 void update_bitmask (irange
&r
, const irange
&lh
,
720 const irange
&rh
) const override
;
721 // Check compatibility of all operands.
722 bool operand_check_p (tree t1
, tree t2
, tree t3
) const final override
723 { return range_compatible_p (t1
, t2
) && range_compatible_p (t1
, t3
); }
725 void wi_fold (irange
&r
, tree type
, const wide_int
&lh_lb
,
726 const wide_int
&lh_ub
, const wide_int
&rh_lb
,
727 const wide_int
&rh_ub
) const override
;
729 #endif // GCC_RANGE_OP_MIXED_H