hppa: Export main in pr104869.C on hpux
[official-gcc.git] / gcc / range-op-float.cc
blob75816942f8cea0736493fe8af81fc30c621dc4b8
1 /* Floating point range operators.
2 Copyright (C) 2022-2023 Free Software Foundation, Inc.
3 Contributed by Aldy Hernandez <aldyh@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "insn-codes.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "gimple.h"
29 #include "cfghooks.h"
30 #include "tree-pass.h"
31 #include "ssa.h"
32 #include "optabs-tree.h"
33 #include "gimple-pretty-print.h"
34 #include "diagnostic-core.h"
35 #include "flags.h"
36 #include "fold-const.h"
37 #include "stor-layout.h"
38 #include "calls.h"
39 #include "cfganal.h"
40 #include "gimple-iterator.h"
41 #include "gimple-fold.h"
42 #include "tree-eh.h"
43 #include "gimple-walk.h"
44 #include "tree-cfg.h"
45 #include "wide-int.h"
46 #include "value-relation.h"
47 #include "range-op.h"
48 #include "range-op-mixed.h"
50 // Default definitions for floating point operators.
52 bool
53 range_operator::fold_range (frange &r, tree type,
54 const frange &op1, const frange &op2,
55 relation_trio trio) const
57 if (empty_range_varying (r, type, op1, op2))
58 return true;
59 if (op1.known_isnan () || op2.known_isnan ())
61 r.set_nan (type);
62 return true;
65 rv_fold (r, type,
66 op1.lower_bound (), op1.upper_bound (),
67 op2.lower_bound (), op2.upper_bound (), trio.op1_op2 ());
69 if (r.known_isnan ())
70 return true;
71 if (op1.maybe_isnan () || op2.maybe_isnan ())
72 r.update_nan ();
74 // If the result has overflowed and flag_trapping_math, folding this
75 // operation could elide an overflow or division by zero exception.
76 // Avoid returning a singleton +-INF, to keep the propagators (DOM
77 // and substitute_and_fold_engine) from folding. See PR107608.
78 if (flag_trapping_math
79 && MODE_HAS_INFINITIES (TYPE_MODE (type))
80 && r.known_isinf () && !op1.known_isinf () && !op2.known_isinf ())
82 REAL_VALUE_TYPE inf = r.lower_bound ();
83 if (real_isneg (&inf))
85 REAL_VALUE_TYPE min = real_min_representable (type);
86 r.set (type, inf, min);
88 else
90 REAL_VALUE_TYPE max = real_max_representable (type);
91 r.set (type, max, inf);
95 r.flush_denormals_to_zero ();
97 return true;
100 // For a given operation, fold two sets of ranges into [lb, ub].
101 // MAYBE_NAN is set to TRUE if, in addition to any result in LB or
102 // UB, the final range has the possibility of a NAN.
103 void
104 range_operator::rv_fold (frange &r, tree type,
105 const REAL_VALUE_TYPE &,
106 const REAL_VALUE_TYPE &,
107 const REAL_VALUE_TYPE &,
108 const REAL_VALUE_TYPE &, relation_kind) const
110 r.set (type, dconstninf, dconstinf, nan_state (true));
113 bool
114 range_operator::fold_range (irange &r ATTRIBUTE_UNUSED,
115 tree type ATTRIBUTE_UNUSED,
116 const frange &lh ATTRIBUTE_UNUSED,
117 const irange &rh ATTRIBUTE_UNUSED,
118 relation_trio) const
120 return false;
123 bool
124 range_operator::fold_range (irange &r ATTRIBUTE_UNUSED,
125 tree type ATTRIBUTE_UNUSED,
126 const frange &lh ATTRIBUTE_UNUSED,
127 const frange &rh ATTRIBUTE_UNUSED,
128 relation_trio) const
130 return false;
133 bool
134 range_operator::fold_range (frange &r ATTRIBUTE_UNUSED,
135 tree type ATTRIBUTE_UNUSED,
136 const irange &lh ATTRIBUTE_UNUSED,
137 const irange &rh ATTRIBUTE_UNUSED,
138 relation_trio) const
140 return false;
143 bool
144 range_operator::op1_range (frange &r ATTRIBUTE_UNUSED,
145 tree type ATTRIBUTE_UNUSED,
146 const frange &lhs ATTRIBUTE_UNUSED,
147 const frange &op2 ATTRIBUTE_UNUSED,
148 relation_trio) const
150 return false;
153 bool
154 range_operator::op1_range (frange &r ATTRIBUTE_UNUSED,
155 tree type ATTRIBUTE_UNUSED,
156 const irange &lhs ATTRIBUTE_UNUSED,
157 const frange &op2 ATTRIBUTE_UNUSED,
158 relation_trio) const
160 return false;
163 bool
164 range_operator::op2_range (frange &r ATTRIBUTE_UNUSED,
165 tree type ATTRIBUTE_UNUSED,
166 const frange &lhs ATTRIBUTE_UNUSED,
167 const frange &op1 ATTRIBUTE_UNUSED,
168 relation_trio) const
170 return false;
173 bool
174 range_operator::op2_range (frange &r ATTRIBUTE_UNUSED,
175 tree type ATTRIBUTE_UNUSED,
176 const irange &lhs ATTRIBUTE_UNUSED,
177 const frange &op1 ATTRIBUTE_UNUSED,
178 relation_trio) const
180 return false;
183 relation_kind
184 range_operator::lhs_op1_relation (const frange &lhs ATTRIBUTE_UNUSED,
185 const frange &op1 ATTRIBUTE_UNUSED,
186 const frange &op2 ATTRIBUTE_UNUSED,
187 relation_kind) const
189 return VREL_VARYING;
192 relation_kind
193 range_operator::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED,
194 const frange &op1 ATTRIBUTE_UNUSED,
195 const frange &op2 ATTRIBUTE_UNUSED,
196 relation_kind) const
198 return VREL_VARYING;
201 relation_kind
202 range_operator::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
203 const frange &op1 ATTRIBUTE_UNUSED,
204 const frange &op2 ATTRIBUTE_UNUSED,
205 relation_kind) const
207 return VREL_VARYING;
210 relation_kind
211 range_operator::lhs_op2_relation (const frange &lhs ATTRIBUTE_UNUSED,
212 const frange &op1 ATTRIBUTE_UNUSED,
213 const frange &op2 ATTRIBUTE_UNUSED,
214 relation_kind) const
216 return VREL_VARYING;
219 relation_kind
220 range_operator::op1_op2_relation (const irange &,
221 const frange &,
222 const frange &) const
224 return VREL_VARYING;
228 relation_kind
229 range_operator::op1_op2_relation (const frange &,
230 const frange &,
231 const frange &) const
233 return VREL_VARYING;
236 // Return TRUE if OP1 and OP2 may be a NAN.
238 static inline bool
239 maybe_isnan (const frange &op1, const frange &op2)
241 return op1.maybe_isnan () || op2.maybe_isnan ();
244 // Floating point version of relop_early_resolve that takes NANs into
245 // account.
247 // For relation opcodes, first try to see if the supplied relation
248 // forces a true or false result, and return that.
249 // Then check for undefined operands. If none of this applies,
250 // return false.
252 // TRIO are the relations between operands as they appear in the IL.
253 // MY_REL is the relation that corresponds to the operator being
254 // folded. For example, when attempting to fold x_3 == y_5, MY_REL is
255 // VREL_EQ, and if the statement is dominated by x_3 > y_5, then
256 // TRIO.op1_op2() is VREL_GT.
258 static inline bool
259 frelop_early_resolve (irange &r, tree type,
260 const frange &op1, const frange &op2,
261 relation_trio trio, relation_kind my_rel)
263 relation_kind rel = trio.op1_op2 ();
265 // If known relation is a complete subset of this relation, always
266 // return true. However, avoid doing this when NAN is a possibility
267 // as we'll incorrectly fold conditions:
269 // if (x_3 >= y_5)
270 // ;
271 // else
272 // ;; With NANs the relation here is basically VREL_UNLT, so we
273 // ;; can't fold the following:
274 // if (x_3 < y_5)
275 if (!maybe_isnan (op1, op2) && relation_union (rel, my_rel) == my_rel)
277 r = range_true (type);
278 return true;
281 // If known relation has no subset of this relation, always false.
282 if (relation_intersect (rel, my_rel) == VREL_UNDEFINED)
284 r = range_false (type);
285 return true;
288 // If either operand is undefined, return VARYING.
289 if (empty_range_varying (r, type, op1, op2))
290 return true;
292 return false;
295 // Set VALUE to its next real value, or INF if the operation overflows.
297 void
298 frange_nextafter (enum machine_mode mode,
299 REAL_VALUE_TYPE &value,
300 const REAL_VALUE_TYPE &inf)
302 if (MODE_COMPOSITE_P (mode)
303 && (real_isdenormal (&value, mode) || real_iszero (&value)))
305 // IBM extended denormals only have DFmode precision.
306 REAL_VALUE_TYPE tmp, tmp2;
307 real_convert (&tmp2, DFmode, &value);
308 real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2, &inf);
309 real_convert (&value, mode, &tmp);
311 else
313 REAL_VALUE_TYPE tmp;
314 real_nextafter (&tmp, REAL_MODE_FORMAT (mode), &value, &inf);
315 value = tmp;
319 // Like real_arithmetic, but round the result to INF if the operation
320 // produced inexact results.
322 // ?? There is still one problematic case, i387. With
323 // -fexcess-precision=standard we perform most SF/DFmode arithmetic in
324 // XFmode (long_double_type_node), so that case is OK. But without
325 // -mfpmath=sse, all the SF/DFmode computations are in XFmode
326 // precision (64-bit mantissa) and only occasionally rounded to
327 // SF/DFmode (when storing into memory from the 387 stack). Maybe
328 // this is ok as well though it is just occasionally more precise. ??
330 void
331 frange_arithmetic (enum tree_code code, tree type,
332 REAL_VALUE_TYPE &result,
333 const REAL_VALUE_TYPE &op1,
334 const REAL_VALUE_TYPE &op2,
335 const REAL_VALUE_TYPE &inf)
337 REAL_VALUE_TYPE value;
338 enum machine_mode mode = TYPE_MODE (type);
339 bool mode_composite = MODE_COMPOSITE_P (mode);
341 bool inexact = real_arithmetic (&value, code, &op1, &op2);
342 real_convert (&result, mode, &value);
344 /* When rounding towards negative infinity, x + (-x) and
345 x - x is -0 rather than +0 real_arithmetic computes.
346 So, when we are looking for lower bound (inf is negative),
347 use -0 rather than +0. */
348 if (flag_rounding_math
349 && (code == PLUS_EXPR || code == MINUS_EXPR)
350 && !inexact
351 && real_iszero (&result)
352 && !real_isneg (&result)
353 && real_isneg (&inf))
355 REAL_VALUE_TYPE op2a = op2;
356 if (code == PLUS_EXPR)
357 op2a.sign ^= 1;
358 if (real_isneg (&op1) == real_isneg (&op2a) && real_equal (&op1, &op2a))
359 result.sign = 1;
362 // Be extra careful if there may be discrepancies between the
363 // compile and runtime results.
364 bool round = false;
365 if (mode_composite)
366 round = true;
367 else
369 bool low = real_isneg (&inf);
370 round = (low ? !real_less (&result, &value)
371 : !real_less (&value, &result));
372 if (real_isinf (&result, !low)
373 && !real_isinf (&value)
374 && !flag_rounding_math)
376 // Use just [+INF, +INF] rather than [MAX, +INF]
377 // even if value is larger than MAX and rounds to
378 // nearest to +INF. Similarly just [-INF, -INF]
379 // rather than [-INF, +MAX] even if value is smaller
380 // than -MAX and rounds to nearest to -INF.
381 // Unless INEXACT is true, in that case we need some
382 // extra buffer.
383 if (!inexact)
384 round = false;
385 else
387 REAL_VALUE_TYPE tmp = result, tmp2;
388 frange_nextafter (mode, tmp, inf);
389 // TMP is at this point the maximum representable
390 // number.
391 real_arithmetic (&tmp2, MINUS_EXPR, &value, &tmp);
392 if (real_isneg (&tmp2) != low
393 && (REAL_EXP (&tmp2) - REAL_EXP (&tmp)
394 >= 2 - REAL_MODE_FORMAT (mode)->p))
395 round = false;
399 if (round && (inexact || !real_identical (&result, &value)))
401 if (mode_composite
402 && (real_isdenormal (&result, mode) || real_iszero (&result)))
404 // IBM extended denormals only have DFmode precision.
405 REAL_VALUE_TYPE tmp, tmp2;
406 real_convert (&tmp2, DFmode, &value);
407 real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2, &inf);
408 real_convert (&result, mode, &tmp);
410 else
411 frange_nextafter (mode, result, inf);
413 if (mode_composite)
414 switch (code)
416 case PLUS_EXPR:
417 case MINUS_EXPR:
418 // ibm-ldouble-format documents 1ulp for + and -.
419 frange_nextafter (mode, result, inf);
420 break;
421 case MULT_EXPR:
422 // ibm-ldouble-format documents 2ulps for *.
423 frange_nextafter (mode, result, inf);
424 frange_nextafter (mode, result, inf);
425 break;
426 case RDIV_EXPR:
427 // ibm-ldouble-format documents 3ulps for /.
428 frange_nextafter (mode, result, inf);
429 frange_nextafter (mode, result, inf);
430 frange_nextafter (mode, result, inf);
431 break;
432 default:
433 break;
437 // Crop R to [-INF, MAX] where MAX is the maximum representable number
438 // for TYPE.
440 static inline void
441 frange_drop_inf (frange &r, tree type)
443 REAL_VALUE_TYPE max = real_max_representable (type);
444 frange tmp (type, r.lower_bound (), max);
445 r.intersect (tmp);
448 // Crop R to [MIN, +INF] where MIN is the minimum representable number
449 // for TYPE.
451 static inline void
452 frange_drop_ninf (frange &r, tree type)
454 REAL_VALUE_TYPE min = real_min_representable (type);
455 frange tmp (type, min, r.upper_bound ());
456 r.intersect (tmp);
459 // Crop R to [MIN, MAX] where MAX is the maximum representable number
460 // for TYPE and MIN the minimum representable number for TYPE.
462 static inline void
463 frange_drop_infs (frange &r, tree type)
465 REAL_VALUE_TYPE max = real_max_representable (type);
466 REAL_VALUE_TYPE min = real_min_representable (type);
467 frange tmp (type, min, max);
468 r.intersect (tmp);
471 // If zero is in R, make sure both -0.0 and +0.0 are in the range.
473 static inline void
474 frange_add_zeros (frange &r, tree type)
476 if (r.undefined_p () || r.known_isnan ())
477 return;
479 if (HONOR_SIGNED_ZEROS (type)
480 && (real_iszero (&r.lower_bound ()) || real_iszero (&r.upper_bound ())))
482 frange zero;
483 zero.set_zero (type);
484 r.union_ (zero);
488 // Build a range that is <= VAL and store it in R. Return TRUE if
489 // further changes may be needed for R, or FALSE if R is in its final
490 // form.
492 static bool
493 build_le (frange &r, tree type, const frange &val)
495 gcc_checking_assert (!val.known_isnan ());
497 REAL_VALUE_TYPE ninf = frange_val_min (type);
498 r.set (type, ninf, val.upper_bound ());
500 // Add both zeros if there's the possibility of zero equality.
501 frange_add_zeros (r, type);
503 return true;
506 // Build a range that is < VAL and store it in R. Return TRUE if
507 // further changes may be needed for R, or FALSE if R is in its final
508 // form.
510 static bool
511 build_lt (frange &r, tree type, const frange &val)
513 gcc_checking_assert (!val.known_isnan ());
515 // < -INF is outside the range.
516 if (real_isinf (&val.upper_bound (), 1))
518 if (HONOR_NANS (type))
519 r.set_nan (type);
520 else
521 r.set_undefined ();
522 return false;
525 REAL_VALUE_TYPE ninf = frange_val_min (type);
526 REAL_VALUE_TYPE prev = val.upper_bound ();
527 machine_mode mode = TYPE_MODE (type);
528 // Default to the conservatively correct closed ranges for
529 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
530 // !HONOR_INFINITIES, nextafter will yield -INF, but frange::set()
531 // will crop the range appropriately.
532 if (!MODE_COMPOSITE_P (mode))
533 frange_nextafter (mode, prev, ninf);
534 r.set (type, ninf, prev);
535 return true;
538 // Build a range that is >= VAL and store it in R. Return TRUE if
539 // further changes may be needed for R, or FALSE if R is in its final
540 // form.
542 static bool
543 build_ge (frange &r, tree type, const frange &val)
545 gcc_checking_assert (!val.known_isnan ());
547 REAL_VALUE_TYPE inf = frange_val_max (type);
548 r.set (type, val.lower_bound (), inf);
550 // Add both zeros if there's the possibility of zero equality.
551 frange_add_zeros (r, type);
553 return true;
556 // Build a range that is > VAL and store it in R. Return TRUE if
557 // further changes may be needed for R, or FALSE if R is in its final
558 // form.
560 static bool
561 build_gt (frange &r, tree type, const frange &val)
563 gcc_checking_assert (!val.known_isnan ());
565 // > +INF is outside the range.
566 if (real_isinf (&val.lower_bound (), 0))
568 if (HONOR_NANS (type))
569 r.set_nan (type);
570 else
571 r.set_undefined ();
572 return false;
575 REAL_VALUE_TYPE inf = frange_val_max (type);
576 REAL_VALUE_TYPE next = val.lower_bound ();
577 machine_mode mode = TYPE_MODE (type);
578 // Default to the conservatively correct closed ranges for
579 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
580 // !HONOR_INFINITIES, nextafter will yield +INF, but frange::set()
581 // will crop the range appropriately.
582 if (!MODE_COMPOSITE_P (mode))
583 frange_nextafter (mode, next, inf);
584 r.set (type, next, inf);
585 return true;
589 bool
590 operator_identity::fold_range (frange &r, tree, const frange &op1,
591 const frange &, relation_trio) const
593 r = op1;
594 return true;
597 bool
598 operator_identity::op1_range (frange &r, tree, const frange &lhs,
599 const frange &, relation_trio) const
601 r = lhs;
602 return true;
605 bool
606 operator_cst::fold_range (frange &r, tree, const frange &op1,
607 const frange &, relation_trio) const
609 r = op1;
610 return true;
613 bool
614 operator_equal::op2_range (frange &r, tree type,
615 const irange &lhs, const frange &op1,
616 relation_trio rel) const
618 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
621 bool
622 operator_equal::fold_range (irange &r, tree type,
623 const frange &op1, const frange &op2,
624 relation_trio rel) const
626 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_EQ))
627 return true;
629 if (op1.known_isnan () || op2.known_isnan ())
630 r = range_false (type);
631 // We can be sure the values are always equal or not if both ranges
632 // consist of a single value, and then compare them.
633 else if (op1.singleton_p () && op2.singleton_p ())
635 if (op1 == op2)
636 r = range_true (type);
637 // If one operand is -0.0 and other 0.0, they are still equal.
638 else if (real_iszero (&op1.lower_bound ())
639 && real_iszero (&op2.lower_bound ()))
640 r = range_true (type);
641 else
642 r = range_false (type);
644 else if (real_iszero (&op1.lower_bound ())
645 && real_iszero (&op1.upper_bound ())
646 && real_iszero (&op2.lower_bound ())
647 && real_iszero (&op2.upper_bound ())
648 && !maybe_isnan (op1, op2))
649 // [-0.0, 0.0] == [-0.0, 0.0] or similar.
650 r = range_true (type);
651 else
653 // If ranges do not intersect, we know the range is not equal,
654 // otherwise we don't know anything for sure.
655 frange tmp = op1;
656 tmp.intersect (op2);
657 if (tmp.undefined_p ())
659 // If one range is [whatever, -0.0] and another
660 // [0.0, whatever2], we don't know anything either,
661 // because -0.0 == 0.0.
662 if ((real_iszero (&op1.upper_bound ())
663 && real_iszero (&op2.lower_bound ()))
664 || (real_iszero (&op1.lower_bound ())
665 && real_iszero (&op2.upper_bound ())))
666 r = range_true_and_false (type);
667 else
668 r = range_false (type);
670 else
671 r = range_true_and_false (type);
673 return true;
676 bool
677 operator_equal::op1_range (frange &r, tree type,
678 const irange &lhs,
679 const frange &op2,
680 relation_trio trio) const
682 relation_kind rel = trio.op1_op2 ();
683 switch (get_bool_state (r, lhs, type))
685 case BRS_TRUE:
686 // The TRUE side of x == NAN is unreachable.
687 if (op2.known_isnan ())
688 r.set_undefined ();
689 else
691 // If it's true, the result is the same as OP2.
692 r = op2;
693 // Add both zeros if there's the possibility of zero equality.
694 frange_add_zeros (r, type);
695 // The TRUE side of op1 == op2 implies op1 is !NAN.
696 r.clear_nan ();
698 break;
700 case BRS_FALSE:
701 // The FALSE side of op1 == op1 implies op1 is a NAN.
702 if (rel == VREL_EQ)
703 r.set_nan (type);
704 // On the FALSE side of x == NAN, we know nothing about x.
705 else if (op2.known_isnan ())
706 r.set_varying (type);
707 // If the result is false, the only time we know anything is
708 // if OP2 is a constant.
709 else if (op2.singleton_p ()
710 || (!op2.maybe_isnan () && op2.zero_p ()))
712 REAL_VALUE_TYPE tmp = op2.lower_bound ();
713 r.set (type, tmp, tmp, VR_ANTI_RANGE);
715 else
716 r.set_varying (type);
717 break;
719 default:
720 break;
722 return true;
725 // Check if the LHS range indicates a relation between OP1 and OP2.
727 relation_kind
728 operator_equal::op1_op2_relation (const irange &lhs, const frange &,
729 const frange &) const
731 if (lhs.undefined_p ())
732 return VREL_UNDEFINED;
734 // FALSE = op1 == op2 indicates NE_EXPR.
735 if (lhs.zero_p ())
736 return VREL_NE;
738 // TRUE = op1 == op2 indicates EQ_EXPR.
739 if (!contains_zero_p (lhs))
740 return VREL_EQ;
741 return VREL_VARYING;
744 bool
745 operator_not_equal::fold_range (irange &r, tree type,
746 const frange &op1, const frange &op2,
747 relation_trio trio) const
749 relation_kind rel = trio.op1_op2 ();
751 // VREL_NE & NE_EXPR is always true, even with NANs.
752 if (rel == VREL_NE)
754 r = range_true (type);
755 return true;
757 if (rel == VREL_EQ && maybe_isnan (op1, op2))
759 // Avoid frelop_early_resolve() below as it could fold to FALSE
760 // without regards to NANs. This would be incorrect if trying
761 // to fold x_5 != x_5 without prior knowledge of NANs.
763 else if (frelop_early_resolve (r, type, op1, op2, trio, VREL_NE))
764 return true;
766 // x != NAN is always TRUE.
767 if (op1.known_isnan () || op2.known_isnan ())
768 r = range_true (type);
769 // We can be sure the values are always equal or not if both ranges
770 // consist of a single value, and then compare them.
771 else if (op1.singleton_p () && op2.singleton_p ())
773 if (op1 == op2)
774 r = range_false (type);
775 // If one operand is -0.0 and other 0.0, they are still equal.
776 else if (real_iszero (&op1.lower_bound ())
777 && real_iszero (&op2.lower_bound ()))
778 r = range_false (type);
779 else
780 r = range_true (type);
782 else if (real_iszero (&op1.lower_bound ())
783 && real_iszero (&op1.upper_bound ())
784 && real_iszero (&op2.lower_bound ())
785 && real_iszero (&op2.upper_bound ())
786 && !maybe_isnan (op1, op2))
787 // [-0.0, 0.0] != [-0.0, 0.0] or similar.
788 r = range_false (type);
789 else
791 // If ranges do not intersect, we know the range is not equal,
792 // otherwise we don't know anything for sure.
793 frange tmp = op1;
794 tmp.intersect (op2);
795 if (tmp.undefined_p ())
797 // If one range is [whatever, -0.0] and another
798 // [0.0, whatever2], we don't know anything either,
799 // because -0.0 == 0.0.
800 if ((real_iszero (&op1.upper_bound ())
801 && real_iszero (&op2.lower_bound ()))
802 || (real_iszero (&op1.lower_bound ())
803 && real_iszero (&op2.upper_bound ())))
804 r = range_true_and_false (type);
805 else
806 r = range_true (type);
808 else
809 r = range_true_and_false (type);
811 return true;
814 bool
815 operator_not_equal::op1_range (frange &r, tree type,
816 const irange &lhs,
817 const frange &op2,
818 relation_trio trio) const
820 relation_kind rel = trio.op1_op2 ();
821 switch (get_bool_state (r, lhs, type))
823 case BRS_TRUE:
824 // If the result is true, the only time we know anything is if
825 // OP2 is a constant.
826 if (op2.singleton_p ())
828 // This is correct even if op1 is NAN, because the following
829 // range would be ~[tmp, tmp] with the NAN property set to
830 // maybe (VARYING).
831 REAL_VALUE_TYPE tmp = op2.lower_bound ();
832 r.set (type, tmp, tmp, VR_ANTI_RANGE);
834 // The TRUE side of op1 != op1 implies op1 is NAN.
835 else if (rel == VREL_EQ)
836 r.set_nan (type);
837 else
838 r.set_varying (type);
839 break;
841 case BRS_FALSE:
842 // The FALSE side of x != NAN is impossible.
843 if (op2.known_isnan ())
844 r.set_undefined ();
845 else
847 // If it's false, the result is the same as OP2.
848 r = op2;
849 // Add both zeros if there's the possibility of zero equality.
850 frange_add_zeros (r, type);
851 // The FALSE side of op1 != op2 implies op1 is !NAN.
852 r.clear_nan ();
854 break;
856 default:
857 break;
859 return true;
862 bool
863 operator_not_equal::op2_range (frange &r, tree type,
864 const irange &lhs,
865 const frange &op1,
866 relation_trio trio) const
868 return op1_range (r, type, lhs, op1, trio);
871 // Check if the LHS range indicates a relation between OP1 and OP2.
873 relation_kind
874 operator_not_equal::op1_op2_relation (const irange &lhs, const frange &,
875 const frange &) const
877 if (lhs.undefined_p ())
878 return VREL_UNDEFINED;
880 // FALSE = op1 != op2 indicates EQ_EXPR.
881 if (lhs.zero_p ())
882 return VREL_EQ;
884 // TRUE = op1 != op2 indicates NE_EXPR.
885 if (!contains_zero_p (lhs))
886 return VREL_NE;
887 return VREL_VARYING;
890 bool
891 operator_lt::fold_range (irange &r, tree type,
892 const frange &op1, const frange &op2,
893 relation_trio trio) const
895 if (frelop_early_resolve (r, type, op1, op2, trio, VREL_LT))
896 return true;
898 if (op1.known_isnan ()
899 || op2.known_isnan ()
900 || !real_less (&op1.lower_bound (), &op2.upper_bound ()))
901 r = range_false (type);
902 else if (!maybe_isnan (op1, op2)
903 && real_less (&op1.upper_bound (), &op2.lower_bound ()))
904 r = range_true (type);
905 else
906 r = range_true_and_false (type);
907 return true;
910 bool
911 operator_lt::op1_range (frange &r,
912 tree type,
913 const irange &lhs,
914 const frange &op2,
915 relation_trio) const
917 switch (get_bool_state (r, lhs, type))
919 case BRS_TRUE:
920 // The TRUE side of x < NAN is unreachable.
921 if (op2.known_isnan ())
922 r.set_undefined ();
923 else if (op2.undefined_p ())
924 return false;
925 else if (build_lt (r, type, op2))
927 r.clear_nan ();
928 // x < y implies x is not +INF.
929 frange_drop_inf (r, type);
931 break;
933 case BRS_FALSE:
934 // On the FALSE side of x < NAN, we know nothing about x.
935 if (op2.maybe_isnan ())
936 r.set_varying (type);
937 else
938 build_ge (r, type, op2);
939 break;
941 default:
942 break;
944 return true;
947 bool
948 operator_lt::op2_range (frange &r,
949 tree type,
950 const irange &lhs,
951 const frange &op1,
952 relation_trio) const
954 switch (get_bool_state (r, lhs, type))
956 case BRS_TRUE:
957 // The TRUE side of NAN < x is unreachable.
958 if (op1.known_isnan ())
959 r.set_undefined ();
960 else if (op1.undefined_p ())
961 return false;
962 else if (build_gt (r, type, op1))
964 r.clear_nan ();
965 // x < y implies y is not -INF.
966 frange_drop_ninf (r, type);
968 break;
970 case BRS_FALSE:
971 // On the FALSE side of NAN < x, we know nothing about x.
972 if (op1.maybe_isnan ())
973 r.set_varying (type);
974 else
975 build_le (r, type, op1);
976 break;
978 default:
979 break;
981 return true;
985 // Check if the LHS range indicates a relation between OP1 and OP2.
987 relation_kind
988 operator_lt::op1_op2_relation (const irange &lhs, const frange &,
989 const frange &) const
991 if (lhs.undefined_p ())
992 return VREL_UNDEFINED;
994 // FALSE = op1 < op2 indicates GE_EXPR.
995 if (lhs.zero_p ())
996 return VREL_GE;
998 // TRUE = op1 < op2 indicates LT_EXPR.
999 if (!contains_zero_p (lhs))
1000 return VREL_LT;
1001 return VREL_VARYING;
1004 bool
1005 operator_le::fold_range (irange &r, tree type,
1006 const frange &op1, const frange &op2,
1007 relation_trio rel) const
1009 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_LE))
1010 return true;
1012 if (op1.known_isnan ()
1013 || op2.known_isnan ()
1014 || !real_compare (LE_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
1015 r = range_false (type);
1016 else if (!maybe_isnan (op1, op2)
1017 && real_compare (LE_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
1018 r = range_true (type);
1019 else
1020 r = range_true_and_false (type);
1021 return true;
1024 bool
1025 operator_le::op1_range (frange &r,
1026 tree type,
1027 const irange &lhs,
1028 const frange &op2,
1029 relation_trio) const
1031 switch (get_bool_state (r, lhs, type))
1033 case BRS_TRUE:
1034 // The TRUE side of x <= NAN is unreachable.
1035 if (op2.known_isnan ())
1036 r.set_undefined ();
1037 else if (op2.undefined_p ())
1038 return false;
1039 else if (build_le (r, type, op2))
1040 r.clear_nan ();
1041 break;
1043 case BRS_FALSE:
1044 // On the FALSE side of x <= NAN, we know nothing about x.
1045 if (op2.maybe_isnan ())
1046 r.set_varying (type);
1047 else
1048 build_gt (r, type, op2);
1049 break;
1051 default:
1052 break;
1054 return true;
1057 bool
1058 operator_le::op2_range (frange &r,
1059 tree type,
1060 const irange &lhs,
1061 const frange &op1,
1062 relation_trio) const
1064 switch (get_bool_state (r, lhs, type))
1066 case BRS_TRUE:
1067 // The TRUE side of NAN <= x is unreachable.
1068 if (op1.known_isnan ())
1069 r.set_undefined ();
1070 else if (op1.undefined_p ())
1071 return false;
1072 else if (build_ge (r, type, op1))
1073 r.clear_nan ();
1074 break;
1076 case BRS_FALSE:
1077 // On the FALSE side of NAN <= x, we know nothing about x.
1078 if (op1.maybe_isnan ())
1079 r.set_varying (type);
1080 else if (op1.undefined_p ())
1081 return false;
1082 else
1083 build_lt (r, type, op1);
1084 break;
1086 default:
1087 break;
1089 return true;
1092 // Check if the LHS range indicates a relation between OP1 and OP2.
1094 relation_kind
1095 operator_le::op1_op2_relation (const irange &lhs, const frange &,
1096 const frange &) const
1098 if (lhs.undefined_p ())
1099 return VREL_UNDEFINED;
1101 // FALSE = op1 <= op2 indicates GT_EXPR.
1102 if (lhs.zero_p ())
1103 return VREL_GT;
1105 // TRUE = op1 <= op2 indicates LE_EXPR.
1106 if (!contains_zero_p (lhs))
1107 return VREL_LE;
1108 return VREL_VARYING;
1111 bool
1112 operator_gt::fold_range (irange &r, tree type,
1113 const frange &op1, const frange &op2,
1114 relation_trio trio) const
1116 if (frelop_early_resolve (r, type, op1, op2, trio, VREL_GT))
1117 return true;
1119 if (op1.known_isnan ()
1120 || op2.known_isnan ()
1121 || !real_compare (GT_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
1122 r = range_false (type);
1123 else if (!maybe_isnan (op1, op2)
1124 && real_compare (GT_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
1125 r = range_true (type);
1126 else
1127 r = range_true_and_false (type);
1128 return true;
1131 bool
1132 operator_gt::op1_range (frange &r,
1133 tree type,
1134 const irange &lhs,
1135 const frange &op2,
1136 relation_trio) const
1138 switch (get_bool_state (r, lhs, type))
1140 case BRS_TRUE:
1141 // The TRUE side of x > NAN is unreachable.
1142 if (op2.known_isnan ())
1143 r.set_undefined ();
1144 else if (op2.undefined_p ())
1145 return false;
1146 else if (build_gt (r, type, op2))
1148 r.clear_nan ();
1149 // x > y implies x is not -INF.
1150 frange_drop_ninf (r, type);
1152 break;
1154 case BRS_FALSE:
1155 // On the FALSE side of x > NAN, we know nothing about x.
1156 if (op2.maybe_isnan ())
1157 r.set_varying (type);
1158 else if (op2.undefined_p ())
1159 return false;
1160 else
1161 build_le (r, type, op2);
1162 break;
1164 default:
1165 break;
1167 return true;
1170 bool
1171 operator_gt::op2_range (frange &r,
1172 tree type,
1173 const irange &lhs,
1174 const frange &op1,
1175 relation_trio) const
1177 switch (get_bool_state (r, lhs, type))
1179 case BRS_TRUE:
1180 // The TRUE side of NAN > x is unreachable.
1181 if (op1.known_isnan ())
1182 r.set_undefined ();
1183 else if (op1.undefined_p ())
1184 return false;
1185 else if (build_lt (r, type, op1))
1187 r.clear_nan ();
1188 // x > y implies y is not +INF.
1189 frange_drop_inf (r, type);
1191 break;
1193 case BRS_FALSE:
1194 // On The FALSE side of NAN > x, we know nothing about x.
1195 if (op1.maybe_isnan ())
1196 r.set_varying (type);
1197 else if (op1.undefined_p ())
1198 return false;
1199 else
1200 build_ge (r, type, op1);
1201 break;
1203 default:
1204 break;
1206 return true;
1209 // Check if the LHS range indicates a relation between OP1 and OP2.
1211 relation_kind
1212 operator_gt::op1_op2_relation (const irange &lhs, const frange &,
1213 const frange &) const
1215 if (lhs.undefined_p ())
1216 return VREL_UNDEFINED;
1218 // FALSE = op1 > op2 indicates LE_EXPR.
1219 if (lhs.zero_p ())
1220 return VREL_LE;
1222 // TRUE = op1 > op2 indicates GT_EXPR.
1223 if (!contains_zero_p (lhs))
1224 return VREL_GT;
1225 return VREL_VARYING;
1228 bool
1229 operator_ge::fold_range (irange &r, tree type,
1230 const frange &op1, const frange &op2,
1231 relation_trio rel) const
1233 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_GE))
1234 return true;
1236 if (op1.known_isnan ()
1237 || op2.known_isnan ()
1238 || !real_compare (GE_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
1239 r = range_false (type);
1240 else if (!maybe_isnan (op1, op2)
1241 && real_compare (GE_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
1242 r = range_true (type);
1243 else
1244 r = range_true_and_false (type);
1245 return true;
1248 bool
1249 operator_ge::op1_range (frange &r,
1250 tree type,
1251 const irange &lhs,
1252 const frange &op2,
1253 relation_trio) const
1255 switch (get_bool_state (r, lhs, type))
1257 case BRS_TRUE:
1258 // The TRUE side of x >= NAN is unreachable.
1259 if (op2.known_isnan ())
1260 r.set_undefined ();
1261 else if (op2.undefined_p ())
1262 return false;
1263 else if (build_ge (r, type, op2))
1264 r.clear_nan ();
1265 break;
1267 case BRS_FALSE:
1268 // On the FALSE side of x >= NAN, we know nothing about x.
1269 if (op2.maybe_isnan ())
1270 r.set_varying (type);
1271 else if (op2.undefined_p ())
1272 return false;
1273 else
1274 build_lt (r, type, op2);
1275 break;
1277 default:
1278 break;
1280 return true;
1283 bool
1284 operator_ge::op2_range (frange &r, tree type,
1285 const irange &lhs,
1286 const frange &op1,
1287 relation_trio) const
1289 switch (get_bool_state (r, lhs, type))
1291 case BRS_TRUE:
1292 // The TRUE side of NAN >= x is unreachable.
1293 if (op1.known_isnan ())
1294 r.set_undefined ();
1295 else if (op1.undefined_p ())
1296 return false;
1297 else if (build_le (r, type, op1))
1298 r.clear_nan ();
1299 break;
1301 case BRS_FALSE:
1302 // On the FALSE side of NAN >= x, we know nothing about x.
1303 if (op1.maybe_isnan ())
1304 r.set_varying (type);
1305 else if (op1.undefined_p ())
1306 return false;
1307 else
1308 build_gt (r, type, op1);
1309 break;
1311 default:
1312 break;
1314 return true;
1317 // Check if the LHS range indicates a relation between OP1 and OP2.
1319 relation_kind
1320 operator_ge::op1_op2_relation (const irange &lhs, const frange &,
1321 const frange &) const
1323 if (lhs.undefined_p ())
1324 return VREL_UNDEFINED;
1326 // FALSE = op1 >= op2 indicates LT_EXPR.
1327 if (lhs.zero_p ())
1328 return VREL_LT;
1330 // TRUE = op1 >= op2 indicates GE_EXPR.
1331 if (!contains_zero_p (lhs))
1332 return VREL_GE;
1333 return VREL_VARYING;
1336 // UNORDERED_EXPR comparison.
1338 class foperator_unordered : public range_operator
1340 using range_operator::fold_range;
1341 using range_operator::op1_range;
1342 using range_operator::op2_range;
1343 public:
1344 bool fold_range (irange &r, tree type,
1345 const frange &op1, const frange &op2,
1346 relation_trio = TRIO_VARYING) const final override;
1347 bool op1_range (frange &r, tree type,
1348 const irange &lhs, const frange &op2,
1349 relation_trio = TRIO_VARYING) const final override;
1350 bool op2_range (frange &r, tree type,
1351 const irange &lhs, const frange &op1,
1352 relation_trio rel = TRIO_VARYING) const final override
1354 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
1356 } fop_unordered;
1358 bool
1359 foperator_unordered::fold_range (irange &r, tree type,
1360 const frange &op1, const frange &op2,
1361 relation_trio) const
1363 // UNORDERED is TRUE if either operand is a NAN.
1364 if (op1.known_isnan () || op2.known_isnan ())
1365 r = range_true (type);
1366 // UNORDERED is FALSE if neither operand is a NAN.
1367 else if (!op1.maybe_isnan () && !op2.maybe_isnan ())
1368 r = range_false (type);
1369 else
1370 r = range_true_and_false (type);
1371 return true;
1374 bool
1375 foperator_unordered::op1_range (frange &r, tree type,
1376 const irange &lhs,
1377 const frange &op2,
1378 relation_trio trio) const
1380 relation_kind rel = trio.op1_op2 ();
1381 switch (get_bool_state (r, lhs, type))
1383 case BRS_TRUE:
1384 // Since at least one operand must be NAN, if one of them is
1385 // not, the other must be.
1386 if (rel == VREL_EQ || !op2.maybe_isnan ())
1387 r.set_nan (type);
1388 else
1389 r.set_varying (type);
1390 break;
1392 case BRS_FALSE:
1393 // A false UNORDERED means both operands are !NAN, so it's
1394 // impossible for op2 to be a NAN.
1395 if (op2.known_isnan ())
1396 r.set_undefined ();
1397 else
1399 r.set_varying (type);
1400 r.clear_nan ();
1402 break;
1404 default:
1405 break;
1407 return true;
1410 // ORDERED_EXPR comparison.
1412 class foperator_ordered : public range_operator
1414 using range_operator::fold_range;
1415 using range_operator::op1_range;
1416 using range_operator::op2_range;
1417 public:
1418 bool fold_range (irange &r, tree type,
1419 const frange &op1, const frange &op2,
1420 relation_trio = TRIO_VARYING) const final override;
1421 bool op1_range (frange &r, tree type,
1422 const irange &lhs, const frange &op2,
1423 relation_trio = TRIO_VARYING) const final override;
1424 bool op2_range (frange &r, tree type,
1425 const irange &lhs, const frange &op1,
1426 relation_trio rel = TRIO_VARYING) const final override
1428 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
1430 } fop_ordered;
1432 bool
1433 foperator_ordered::fold_range (irange &r, tree type,
1434 const frange &op1, const frange &op2,
1435 relation_trio) const
1437 if (op1.known_isnan () || op2.known_isnan ())
1438 r = range_false (type);
1439 else if (!op1.maybe_isnan () && !op2.maybe_isnan ())
1440 r = range_true (type);
1441 else
1442 r = range_true_and_false (type);
1443 return true;
1446 bool
1447 foperator_ordered::op1_range (frange &r, tree type,
1448 const irange &lhs,
1449 const frange &op2,
1450 relation_trio trio) const
1452 relation_kind rel = trio.op1_op2 ();
1453 switch (get_bool_state (r, lhs, type))
1455 case BRS_TRUE:
1456 // The TRUE side of ORDERED means both operands are !NAN, so
1457 // it's impossible for op2 to be a NAN.
1458 if (op2.known_isnan ())
1459 r.set_undefined ();
1460 else
1462 r.set_varying (type);
1463 r.clear_nan ();
1465 break;
1467 case BRS_FALSE:
1468 // The FALSE side of op1 ORDERED op1 implies op1 is NAN.
1469 if (rel == VREL_EQ)
1470 r.set_nan (type);
1471 else
1472 r.set_varying (type);
1473 break;
1475 default:
1476 break;
1478 return true;
1481 bool
1482 operator_negate::fold_range (frange &r, tree type,
1483 const frange &op1, const frange &op2,
1484 relation_trio) const
1486 if (empty_range_varying (r, type, op1, op2))
1487 return true;
1488 if (op1.known_isnan ())
1490 bool sign;
1491 if (op1.nan_signbit_p (sign))
1492 r.set_nan (type, !sign);
1493 else
1494 r.set_nan (type);
1495 return true;
1498 REAL_VALUE_TYPE lh_lb = op1.lower_bound ();
1499 REAL_VALUE_TYPE lh_ub = op1.upper_bound ();
1500 lh_lb = real_value_negate (&lh_lb);
1501 lh_ub = real_value_negate (&lh_ub);
1502 r.set (type, lh_ub, lh_lb);
1503 if (op1.maybe_isnan ())
1505 bool sign;
1506 if (op1.nan_signbit_p (sign))
1507 r.update_nan (!sign);
1508 else
1509 r.update_nan ();
1511 else
1512 r.clear_nan ();
1513 return true;
1516 bool
1517 operator_negate::op1_range (frange &r, tree type,
1518 const frange &lhs, const frange &op2,
1519 relation_trio rel) const
1521 return fold_range (r, type, lhs, op2, rel);
1524 bool
1525 operator_abs::fold_range (frange &r, tree type,
1526 const frange &op1, const frange &op2,
1527 relation_trio) const
1529 if (empty_range_varying (r, type, op1, op2))
1530 return true;
1531 if (op1.known_isnan ())
1533 r.set_nan (type, /*sign=*/false);
1534 return true;
1537 const REAL_VALUE_TYPE lh_lb = op1.lower_bound ();
1538 const REAL_VALUE_TYPE lh_ub = op1.upper_bound ();
1539 // Handle the easy case where everything is positive.
1540 if (real_compare (GE_EXPR, &lh_lb, &dconst0)
1541 && !real_iszero (&lh_lb, /*sign=*/true)
1542 && !op1.maybe_isnan (/*sign=*/true))
1544 r = op1;
1545 return true;
1548 REAL_VALUE_TYPE min = real_value_abs (&lh_lb);
1549 REAL_VALUE_TYPE max = real_value_abs (&lh_ub);
1550 // If the range contains zero then we know that the minimum value in the
1551 // range will be zero.
1552 if (real_compare (LE_EXPR, &lh_lb, &dconst0)
1553 && real_compare (GE_EXPR, &lh_ub, &dconst0))
1555 if (real_compare (GT_EXPR, &min, &max))
1556 max = min;
1557 min = dconst0;
1559 else
1561 // If the range was reversed, swap MIN and MAX.
1562 if (real_compare (GT_EXPR, &min, &max))
1563 std::swap (min, max);
1566 r.set (type, min, max);
1567 if (op1.maybe_isnan ())
1568 r.update_nan (/*sign=*/false);
1569 else
1570 r.clear_nan ();
1571 return true;
1574 bool
1575 operator_abs::op1_range (frange &r, tree type,
1576 const frange &lhs, const frange &op2,
1577 relation_trio) const
1579 if (empty_range_varying (r, type, lhs, op2))
1580 return true;
1581 if (lhs.known_isnan ())
1583 r.set_nan (type);
1584 return true;
1587 // Start with the positives because negatives are an impossible result.
1588 frange positives (type, dconst0, frange_val_max (type));
1589 positives.update_nan (/*sign=*/false);
1590 positives.intersect (lhs);
1591 r = positives;
1592 // Add -NAN if relevant.
1593 if (r.maybe_isnan ())
1595 frange neg_nan;
1596 neg_nan.set_nan (type, true);
1597 r.union_ (neg_nan);
1599 if (r.known_isnan () || r.undefined_p ())
1600 return true;
1601 // Then add the negative of each pair:
1602 // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
1603 frange negatives (type, real_value_negate (&positives.upper_bound ()),
1604 real_value_negate (&positives.lower_bound ()));
1605 negatives.clear_nan ();
1606 r.union_ (negatives);
1607 return true;
1610 class foperator_unordered_lt : public range_operator
1612 using range_operator::fold_range;
1613 using range_operator::op1_range;
1614 using range_operator::op2_range;
1615 public:
1616 bool fold_range (irange &r, tree type,
1617 const frange &op1, const frange &op2,
1618 relation_trio trio = TRIO_VARYING) const final override
1620 if (op1.known_isnan () || op2.known_isnan ())
1622 r = range_true (type);
1623 return true;
1625 frange op1_no_nan = op1;
1626 frange op2_no_nan = op2;
1627 if (op1.maybe_isnan ())
1628 op1_no_nan.clear_nan ();
1629 if (op2.maybe_isnan ())
1630 op2_no_nan.clear_nan ();
1631 if (!range_op_handler (LT_EXPR).fold_range (r, type, op1_no_nan,
1632 op2_no_nan, trio))
1633 return false;
1634 // The result is the same as the ordered version when the
1635 // comparison is true or when the operands cannot be NANs.
1636 if (!maybe_isnan (op1, op2) || r == range_true (type))
1637 return true;
1638 else
1640 r = range_true_and_false (type);
1641 return true;
1644 bool op1_range (frange &r, tree type,
1645 const irange &lhs,
1646 const frange &op2,
1647 relation_trio trio) const final override;
1648 bool op2_range (frange &r, tree type,
1649 const irange &lhs,
1650 const frange &op1,
1651 relation_trio trio) const final override;
1652 } fop_unordered_lt;
1654 bool
1655 foperator_unordered_lt::op1_range (frange &r, tree type,
1656 const irange &lhs,
1657 const frange &op2,
1658 relation_trio) const
1660 switch (get_bool_state (r, lhs, type))
1662 case BRS_TRUE:
1663 if (op2.maybe_isnan ())
1664 r.set_varying (type);
1665 else if (op2.undefined_p ())
1666 return false;
1667 else
1668 build_lt (r, type, op2);
1669 break;
1671 case BRS_FALSE:
1672 // A false UNORDERED_LT means both operands are !NAN, so it's
1673 // impossible for op2 to be a NAN.
1674 if (op2.known_isnan ())
1675 r.set_undefined ();
1676 else if (op2.undefined_p ())
1677 return false;
1678 else if (build_ge (r, type, op2))
1679 r.clear_nan ();
1680 break;
1682 default:
1683 break;
1685 return true;
1688 bool
1689 foperator_unordered_lt::op2_range (frange &r, tree type,
1690 const irange &lhs,
1691 const frange &op1,
1692 relation_trio) const
1694 switch (get_bool_state (r, lhs, type))
1696 case BRS_TRUE:
1697 if (op1.maybe_isnan ())
1698 r.set_varying (type);
1699 else if (op1.undefined_p ())
1700 return false;
1701 else
1702 build_gt (r, type, op1);
1703 break;
1705 case BRS_FALSE:
1706 // A false UNORDERED_LT means both operands are !NAN, so it's
1707 // impossible for op1 to be a NAN.
1708 if (op1.known_isnan ())
1709 r.set_undefined ();
1710 else if (op1.undefined_p ())
1711 return false;
1712 else if (build_le (r, type, op1))
1713 r.clear_nan ();
1714 break;
1716 default:
1717 break;
1719 return true;
1722 class foperator_unordered_le : public range_operator
1724 using range_operator::fold_range;
1725 using range_operator::op1_range;
1726 using range_operator::op2_range;
1727 public:
1728 bool fold_range (irange &r, tree type,
1729 const frange &op1, const frange &op2,
1730 relation_trio trio = TRIO_VARYING) const final override
1732 if (op1.known_isnan () || op2.known_isnan ())
1734 r = range_true (type);
1735 return true;
1737 frange op1_no_nan = op1;
1738 frange op2_no_nan = op2;
1739 if (op1.maybe_isnan ())
1740 op1_no_nan.clear_nan ();
1741 if (op2.maybe_isnan ())
1742 op2_no_nan.clear_nan ();
1743 if (!range_op_handler (LE_EXPR).fold_range (r, type, op1_no_nan,
1744 op2_no_nan, trio))
1745 return false;
1746 // The result is the same as the ordered version when the
1747 // comparison is true or when the operands cannot be NANs.
1748 if (!maybe_isnan (op1, op2) || r == range_true (type))
1749 return true;
1750 else
1752 r = range_true_and_false (type);
1753 return true;
1756 bool op1_range (frange &r, tree type,
1757 const irange &lhs, const frange &op2,
1758 relation_trio = TRIO_VARYING) const final override;
1759 bool op2_range (frange &r, tree type,
1760 const irange &lhs, const frange &op1,
1761 relation_trio = TRIO_VARYING) const final override;
1762 } fop_unordered_le;
1764 bool
1765 foperator_unordered_le::op1_range (frange &r, tree type,
1766 const irange &lhs, const frange &op2,
1767 relation_trio) const
1769 switch (get_bool_state (r, lhs, type))
1771 case BRS_TRUE:
1772 if (op2.maybe_isnan ())
1773 r.set_varying (type);
1774 else if (op2.undefined_p ())
1775 return false;
1776 else
1777 build_le (r, type, op2);
1778 break;
1780 case BRS_FALSE:
1781 // A false UNORDERED_LE means both operands are !NAN, so it's
1782 // impossible for op2 to be a NAN.
1783 if (op2.known_isnan ())
1784 r.set_undefined ();
1785 else if (build_gt (r, type, op2))
1786 r.clear_nan ();
1787 break;
1789 default:
1790 break;
1792 return true;
1795 bool
1796 foperator_unordered_le::op2_range (frange &r,
1797 tree type,
1798 const irange &lhs,
1799 const frange &op1,
1800 relation_trio) const
1802 switch (get_bool_state (r, lhs, type))
1804 case BRS_TRUE:
1805 if (op1.maybe_isnan ())
1806 r.set_varying (type);
1807 else if (op1.undefined_p ())
1808 return false;
1809 else
1810 build_ge (r, type, op1);
1811 break;
1813 case BRS_FALSE:
1814 // A false UNORDERED_LE means both operands are !NAN, so it's
1815 // impossible for op1 to be a NAN.
1816 if (op1.known_isnan ())
1817 r.set_undefined ();
1818 else if (op1.undefined_p ())
1819 return false;
1820 else if (build_lt (r, type, op1))
1821 r.clear_nan ();
1822 break;
1824 default:
1825 break;
1827 return true;
1830 class foperator_unordered_gt : public range_operator
1832 using range_operator::fold_range;
1833 using range_operator::op1_range;
1834 using range_operator::op2_range;
1835 public:
1836 bool fold_range (irange &r, tree type,
1837 const frange &op1, const frange &op2,
1838 relation_trio trio = TRIO_VARYING) const final override
1840 if (op1.known_isnan () || op2.known_isnan ())
1842 r = range_true (type);
1843 return true;
1845 frange op1_no_nan = op1;
1846 frange op2_no_nan = op2;
1847 if (op1.maybe_isnan ())
1848 op1_no_nan.clear_nan ();
1849 if (op2.maybe_isnan ())
1850 op2_no_nan.clear_nan ();
1851 if (!range_op_handler (GT_EXPR).fold_range (r, type, op1_no_nan,
1852 op2_no_nan, trio))
1853 return false;
1854 // The result is the same as the ordered version when the
1855 // comparison is true or when the operands cannot be NANs.
1856 if (!maybe_isnan (op1, op2) || r == range_true (type))
1857 return true;
1858 else
1860 r = range_true_and_false (type);
1861 return true;
1864 bool op1_range (frange &r, tree type,
1865 const irange &lhs, const frange &op2,
1866 relation_trio = TRIO_VARYING) const final override;
1867 bool op2_range (frange &r, tree type,
1868 const irange &lhs, const frange &op1,
1869 relation_trio = TRIO_VARYING) const final override;
1870 } fop_unordered_gt;
1872 bool
1873 foperator_unordered_gt::op1_range (frange &r,
1874 tree type,
1875 const irange &lhs,
1876 const frange &op2,
1877 relation_trio) const
1879 switch (get_bool_state (r, lhs, type))
1881 case BRS_TRUE:
1882 if (op2.maybe_isnan ())
1883 r.set_varying (type);
1884 else if (op2.undefined_p ())
1885 return false;
1886 else
1887 build_gt (r, type, op2);
1888 break;
1890 case BRS_FALSE:
1891 // A false UNORDERED_GT means both operands are !NAN, so it's
1892 // impossible for op2 to be a NAN.
1893 if (op2.known_isnan ())
1894 r.set_undefined ();
1895 else if (op2.undefined_p ())
1896 return false;
1897 else if (build_le (r, type, op2))
1898 r.clear_nan ();
1899 break;
1901 default:
1902 break;
1904 return true;
1907 bool
1908 foperator_unordered_gt::op2_range (frange &r,
1909 tree type,
1910 const irange &lhs,
1911 const frange &op1,
1912 relation_trio) const
1914 switch (get_bool_state (r, lhs, type))
1916 case BRS_TRUE:
1917 if (op1.maybe_isnan ())
1918 r.set_varying (type);
1919 else if (op1.undefined_p ())
1920 return false;
1921 else
1922 build_lt (r, type, op1);
1923 break;
1925 case BRS_FALSE:
1926 // A false UNORDERED_GT means both operands are !NAN, so it's
1927 // impossible for op1 to be a NAN.
1928 if (op1.known_isnan ())
1929 r.set_undefined ();
1930 else if (op1.undefined_p ())
1931 return false;
1932 else if (build_ge (r, type, op1))
1933 r.clear_nan ();
1934 break;
1936 default:
1937 break;
1939 return true;
1942 class foperator_unordered_ge : public range_operator
1944 using range_operator::fold_range;
1945 using range_operator::op1_range;
1946 using range_operator::op2_range;
1947 public:
1948 bool fold_range (irange &r, tree type,
1949 const frange &op1, const frange &op2,
1950 relation_trio trio = TRIO_VARYING) const final override
1952 if (op1.known_isnan () || op2.known_isnan ())
1954 r = range_true (type);
1955 return true;
1957 frange op1_no_nan = op1;
1958 frange op2_no_nan = op2;
1959 if (op1.maybe_isnan ())
1960 op1_no_nan.clear_nan ();
1961 if (op2.maybe_isnan ())
1962 op2_no_nan.clear_nan ();
1963 if (!range_op_handler (GE_EXPR).fold_range (r, type, op1_no_nan,
1964 op2_no_nan, trio))
1965 return false;
1966 // The result is the same as the ordered version when the
1967 // comparison is true or when the operands cannot be NANs.
1968 if (!maybe_isnan (op1, op2) || r == range_true (type))
1969 return true;
1970 else
1972 r = range_true_and_false (type);
1973 return true;
1976 bool op1_range (frange &r, tree type,
1977 const irange &lhs, const frange &op2,
1978 relation_trio = TRIO_VARYING) const final override;
1979 bool op2_range (frange &r, tree type,
1980 const irange &lhs, const frange &op1,
1981 relation_trio = TRIO_VARYING) const final override;
1982 } fop_unordered_ge;
1984 bool
1985 foperator_unordered_ge::op1_range (frange &r,
1986 tree type,
1987 const irange &lhs,
1988 const frange &op2,
1989 relation_trio) const
1991 switch (get_bool_state (r, lhs, type))
1993 case BRS_TRUE:
1994 if (op2.maybe_isnan ())
1995 r.set_varying (type);
1996 else if (op2.undefined_p ())
1997 return false;
1998 else
1999 build_ge (r, type, op2);
2000 break;
2002 case BRS_FALSE:
2003 // A false UNORDERED_GE means both operands are !NAN, so it's
2004 // impossible for op2 to be a NAN.
2005 if (op2.known_isnan ())
2006 r.set_undefined ();
2007 else if (op2.undefined_p ())
2008 return false;
2009 else if (build_lt (r, type, op2))
2010 r.clear_nan ();
2011 break;
2013 default:
2014 break;
2016 return true;
2019 bool
2020 foperator_unordered_ge::op2_range (frange &r, tree type,
2021 const irange &lhs,
2022 const frange &op1,
2023 relation_trio) const
2025 switch (get_bool_state (r, lhs, type))
2027 case BRS_TRUE:
2028 if (op1.maybe_isnan ())
2029 r.set_varying (type);
2030 else if (op1.undefined_p ())
2031 return false;
2032 else
2033 build_le (r, type, op1);
2034 break;
2036 case BRS_FALSE:
2037 // A false UNORDERED_GE means both operands are !NAN, so it's
2038 // impossible for op1 to be a NAN.
2039 if (op1.known_isnan ())
2040 r.set_undefined ();
2041 else if (op1.undefined_p ())
2042 return false;
2043 else if (build_gt (r, type, op1))
2044 r.clear_nan ();
2045 break;
2047 default:
2048 break;
2050 return true;
2053 class foperator_unordered_equal : public range_operator
2055 using range_operator::fold_range;
2056 using range_operator::op1_range;
2057 using range_operator::op2_range;
2058 public:
2059 bool fold_range (irange &r, tree type,
2060 const frange &op1, const frange &op2,
2061 relation_trio trio = TRIO_VARYING) const final override
2063 if (op1.known_isnan () || op2.known_isnan ())
2065 r = range_true (type);
2066 return true;
2068 frange op1_no_nan = op1;
2069 frange op2_no_nan = op2;
2070 if (op1.maybe_isnan ())
2071 op1_no_nan.clear_nan ();
2072 if (op2.maybe_isnan ())
2073 op2_no_nan.clear_nan ();
2074 if (!range_op_handler (EQ_EXPR).fold_range (r, type, op1_no_nan,
2075 op2_no_nan, trio))
2076 return false;
2077 // The result is the same as the ordered version when the
2078 // comparison is true or when the operands cannot be NANs.
2079 if (!maybe_isnan (op1, op2) || r == range_true (type))
2080 return true;
2081 else
2083 r = range_true_and_false (type);
2084 return true;
2087 bool op1_range (frange &r, tree type,
2088 const irange &lhs, const frange &op2,
2089 relation_trio = TRIO_VARYING) const final override;
2090 bool op2_range (frange &r, tree type,
2091 const irange &lhs, const frange &op1,
2092 relation_trio rel = TRIO_VARYING) const final override
2094 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
2096 } fop_unordered_equal;
2098 bool
2099 foperator_unordered_equal::op1_range (frange &r, tree type,
2100 const irange &lhs,
2101 const frange &op2,
2102 relation_trio) const
2104 switch (get_bool_state (r, lhs, type))
2106 case BRS_TRUE:
2107 // If it's true, the result is the same as OP2 plus a NAN.
2108 r = op2;
2109 // Add both zeros if there's the possibility of zero equality.
2110 frange_add_zeros (r, type);
2111 // Add the possibility of a NAN.
2112 r.update_nan ();
2113 break;
2115 case BRS_FALSE:
2116 // A false UNORDERED_EQ means both operands are !NAN, so it's
2117 // impossible for op2 to be a NAN.
2118 if (op2.known_isnan ())
2119 r.set_undefined ();
2120 else
2122 // The false side indicates !NAN and not equal. We can at least
2123 // represent !NAN.
2124 r.set_varying (type);
2125 r.clear_nan ();
2127 break;
2129 default:
2130 break;
2132 return true;
2135 class foperator_ltgt : public range_operator
2137 using range_operator::fold_range;
2138 using range_operator::op1_range;
2139 using range_operator::op2_range;
2140 public:
2141 bool fold_range (irange &r, tree type,
2142 const frange &op1, const frange &op2,
2143 relation_trio trio = TRIO_VARYING) const final override
2145 if (op1.known_isnan () || op2.known_isnan ())
2147 r = range_false (type);
2148 return true;
2150 frange op1_no_nan = op1;
2151 frange op2_no_nan = op2;
2152 if (op1.maybe_isnan ())
2153 op1_no_nan.clear_nan ();
2154 if (op2.maybe_isnan ())
2155 op2_no_nan.clear_nan ();
2156 if (!range_op_handler (NE_EXPR).fold_range (r, type, op1_no_nan,
2157 op2_no_nan, trio))
2158 return false;
2159 // The result is the same as the ordered version when the
2160 // comparison is true or when the operands cannot be NANs.
2161 if (!maybe_isnan (op1, op2) || r == range_false (type))
2162 return true;
2163 else
2165 r = range_true_and_false (type);
2166 return true;
2169 bool op1_range (frange &r, tree type,
2170 const irange &lhs, const frange &op2,
2171 relation_trio = TRIO_VARYING) const final override;
2172 bool op2_range (frange &r, tree type,
2173 const irange &lhs, const frange &op1,
2174 relation_trio rel = TRIO_VARYING) const final override
2176 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
2178 } fop_ltgt;
2180 bool
2181 foperator_ltgt::op1_range (frange &r, tree type,
2182 const irange &lhs,
2183 const frange &op2,
2184 relation_trio) const
2186 switch (get_bool_state (r, lhs, type))
2188 case BRS_TRUE:
2189 // A true LTGT means both operands are !NAN, so it's
2190 // impossible for op2 to be a NAN.
2191 if (op2.known_isnan ())
2192 r.set_undefined ();
2193 else
2195 // The true side indicates !NAN and not equal. We can at least
2196 // represent !NAN.
2197 r.set_varying (type);
2198 r.clear_nan ();
2200 break;
2202 case BRS_FALSE:
2203 // If it's false, the result is the same as OP2 plus a NAN.
2204 r = op2;
2205 // Add both zeros if there's the possibility of zero equality.
2206 frange_add_zeros (r, type);
2207 // Add the possibility of a NAN.
2208 r.update_nan ();
2209 break;
2211 default:
2212 break;
2214 return true;
2217 // Final tweaks for float binary op op1_range/op2_range.
2218 // Return TRUE if the operation is performed and a valid range is available.
2220 static bool
2221 float_binary_op_range_finish (bool ret, frange &r, tree type,
2222 const frange &lhs, bool div_op2 = false)
2224 if (!ret)
2225 return false;
2227 // If we get a known NAN from reverse op, it means either that
2228 // the other operand was known NAN (in that case we know nothing),
2229 // or the reverse operation introduced a known NAN.
2230 // Say for lhs = op1 * op2 if lhs is [-0, +0] and op2 is too,
2231 // 0 / 0 is known NAN. Just punt in that case.
2232 // If NANs aren't honored, we get for 0 / 0 UNDEFINED, so punt as well.
2233 // Or if lhs is a known NAN, we also don't know anything.
2234 if (r.known_isnan () || lhs.known_isnan () || r.undefined_p ())
2236 r.set_varying (type);
2237 return true;
2240 // If lhs isn't NAN, then neither operand could be NAN,
2241 // even if the reverse operation does introduce a maybe_nan.
2242 if (!lhs.maybe_isnan ())
2244 r.clear_nan ();
2245 if (div_op2
2246 ? !(real_compare (LE_EXPR, &lhs.lower_bound (), &dconst0)
2247 && real_compare (GE_EXPR, &lhs.upper_bound (), &dconst0))
2248 : !(real_isinf (&lhs.lower_bound ())
2249 || real_isinf (&lhs.upper_bound ())))
2250 // For reverse + or - or * or op1 of /, if result is finite, then
2251 // r must be finite too, as X + INF or X - INF or X * INF or
2252 // INF / X is always +-INF or NAN. For op2 of /, if result is
2253 // non-zero and not NAN, r must be finite, as X / INF is always
2254 // 0 or NAN.
2255 frange_drop_infs (r, type);
2257 // If lhs is a maybe or known NAN, the operand could be
2258 // NAN.
2259 else
2260 r.update_nan ();
2261 return true;
2264 // True if [lb, ub] is [+-0, +-0].
2265 static bool
2266 zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2268 return real_iszero (&lb) && real_iszero (&ub);
2271 // True if +0 or -0 is in [lb, ub] range.
2272 static bool
2273 contains_zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2275 return (real_compare (LE_EXPR, &lb, &dconst0)
2276 && real_compare (GE_EXPR, &ub, &dconst0));
2279 // True if [lb, ub] is [-INF, -INF] or [+INF, +INF].
2280 static bool
2281 singleton_inf_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2283 return real_isinf (&lb) && real_isinf (&ub, real_isneg (&lb));
2286 // Return -1 if binary op result must have sign bit set,
2287 // 1 if binary op result must have sign bit clear,
2288 // 0 otherwise.
2289 // Sign bit of binary op result is exclusive or of the
2290 // operand's sign bits.
2291 static int
2292 signbit_known_p (const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
2293 const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub)
2295 if (real_isneg (&lh_lb) == real_isneg (&lh_ub)
2296 && real_isneg (&rh_lb) == real_isneg (&rh_ub))
2298 if (real_isneg (&lh_lb) == real_isneg (&rh_ub))
2299 return 1;
2300 else
2301 return -1;
2303 return 0;
2306 // Set [lb, ub] to [-0, -0], [-0, +0] or [+0, +0] depending on
2307 // signbit_known.
2308 static void
2309 zero_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2311 ub = lb = dconst0;
2312 if (signbit_known <= 0)
2313 lb = dconstm0;
2314 if (signbit_known < 0)
2315 ub = lb;
2318 // Set [lb, ub] to [-INF, -INF], [-INF, +INF] or [+INF, +INF] depending on
2319 // signbit_known.
2320 static void
2321 inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2323 if (signbit_known > 0)
2324 ub = lb = dconstinf;
2325 else if (signbit_known < 0)
2326 ub = lb = dconstninf;
2327 else
2329 lb = dconstninf;
2330 ub = dconstinf;
2334 // Set [lb, ub] to [-INF, -0], [-INF, +INF] or [+0, +INF] depending on
2335 // signbit_known.
2336 static void
2337 zero_to_inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2339 if (signbit_known > 0)
2341 lb = dconst0;
2342 ub = dconstinf;
2344 else if (signbit_known < 0)
2346 lb = dconstninf;
2347 ub = dconstm0;
2349 else
2351 lb = dconstninf;
2352 ub = dconstinf;
2356 /* Extend the LHS range by 1ulp in each direction. For op1_range
2357 or op2_range of binary operations just computing the inverse
2358 operation on ranges isn't sufficient. Consider e.g.
2359 [1., 1.] = op1 + [1., 1.]. op1's range is not [0., 0.], but
2360 [-0x1.0p-54, 0x1.0p-53] (when not -frounding-math), any value for
2361 which adding 1. to it results in 1. after rounding to nearest.
2362 So, for op1_range/op2_range extend the lhs range by 1ulp (or 0.5ulp)
2363 in each direction. See PR109008 for more details. */
2365 static frange
2366 float_widen_lhs_range (tree type, const frange &lhs)
2368 frange ret = lhs;
2369 if (lhs.known_isnan ())
2370 return ret;
2371 REAL_VALUE_TYPE lb = lhs.lower_bound ();
2372 REAL_VALUE_TYPE ub = lhs.upper_bound ();
2373 if (real_isfinite (&lb))
2375 frange_nextafter (TYPE_MODE (type), lb, dconstninf);
2376 if (real_isinf (&lb))
2378 /* For -DBL_MAX, instead of -Inf use
2379 nexttoward (-DBL_MAX, -LDBL_MAX) in a hypothetical
2380 wider type with the same mantissa precision but larger
2381 exponent range; it is outside of range of double values,
2382 but makes it clear it is just one ulp larger rather than
2383 infinite amount larger. */
2384 lb = dconstm1;
2385 SET_REAL_EXP (&lb, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
2387 if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)))
2389 /* If not -frounding-math nor IBM double double, actually widen
2390 just by 0.5ulp rather than 1ulp. */
2391 REAL_VALUE_TYPE tem;
2392 real_arithmetic (&tem, PLUS_EXPR, &lhs.lower_bound (), &lb);
2393 real_arithmetic (&lb, RDIV_EXPR, &tem, &dconst2);
2396 if (real_isfinite (&ub))
2398 frange_nextafter (TYPE_MODE (type), ub, dconstinf);
2399 if (real_isinf (&ub))
2401 /* For DBL_MAX similarly. */
2402 ub = dconst1;
2403 SET_REAL_EXP (&ub, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
2405 if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)))
2407 /* If not -frounding-math nor IBM double double, actually widen
2408 just by 0.5ulp rather than 1ulp. */
2409 REAL_VALUE_TYPE tem;
2410 real_arithmetic (&tem, PLUS_EXPR, &lhs.upper_bound (), &ub);
2411 real_arithmetic (&ub, RDIV_EXPR, &tem, &dconst2);
2414 /* Temporarily disable -ffinite-math-only, so that frange::set doesn't
2415 reduce the range back to real_min_representable (type) as lower bound
2416 or real_max_representable (type) as upper bound. */
2417 bool save_flag_finite_math_only = flag_finite_math_only;
2418 flag_finite_math_only = false;
2419 ret.set (type, lb, ub, lhs.get_nan_state ());
2420 flag_finite_math_only = save_flag_finite_math_only;
2421 return ret;
2424 bool
2425 operator_plus::op1_range (frange &r, tree type, const frange &lhs,
2426 const frange &op2, relation_trio) const
2428 if (lhs.undefined_p ())
2429 return false;
2430 range_op_handler minus (MINUS_EXPR);
2431 if (!minus)
2432 return false;
2433 frange wlhs = float_widen_lhs_range (type, lhs);
2434 return float_binary_op_range_finish (minus.fold_range (r, type, wlhs, op2),
2435 r, type, wlhs);
2438 bool
2439 operator_plus::op2_range (frange &r, tree type,
2440 const frange &lhs, const frange &op1,
2441 relation_trio) const
2443 return op1_range (r, type, lhs, op1);
2446 void
2447 operator_plus::rv_fold (frange &r, tree type,
2448 const REAL_VALUE_TYPE &lh_lb,
2449 const REAL_VALUE_TYPE &lh_ub,
2450 const REAL_VALUE_TYPE &rh_lb,
2451 const REAL_VALUE_TYPE &rh_ub,
2452 relation_kind) const
2454 REAL_VALUE_TYPE lb, ub;
2455 bool maybe_nan = false;
2457 frange_arithmetic (PLUS_EXPR, type, lb, lh_lb, rh_lb, dconstninf);
2458 frange_arithmetic (PLUS_EXPR, type, ub, lh_ub, rh_ub, dconstinf);
2460 // [-INF] + [+INF] = NAN
2461 if (real_isinf (&lh_lb, true) && real_isinf (&rh_ub, false))
2462 maybe_nan = true;
2463 // [+INF] + [-INF] = NAN
2464 else if (real_isinf (&lh_ub, false) && real_isinf (&rh_lb, true))
2465 maybe_nan = true;
2467 // Handle possible NANs by saturating to the appropriate INF if only
2468 // one end is a NAN. If both ends are a NAN, just return a NAN.
2469 bool lb_nan = real_isnan (&lb);
2470 bool ub_nan = real_isnan (&ub);
2471 if (lb_nan && ub_nan)
2473 r.set_nan (type);
2474 return;
2476 if (lb_nan)
2477 lb = dconstninf;
2478 else if (ub_nan)
2479 ub = dconstinf;
2480 r.set (type, lb, ub, nan_state (maybe_nan));
2484 bool
2485 operator_minus::op1_range (frange &r, tree type,
2486 const frange &lhs, const frange &op2,
2487 relation_trio) const
2489 if (lhs.undefined_p ())
2490 return false;
2491 frange wlhs = float_widen_lhs_range (type, lhs);
2492 return float_binary_op_range_finish (
2493 range_op_handler (PLUS_EXPR).fold_range (r, type, wlhs, op2),
2494 r, type, wlhs);
2497 bool
2498 operator_minus::op2_range (frange &r, tree type,
2499 const frange &lhs, const frange &op1,
2500 relation_trio) const
2502 if (lhs.undefined_p ())
2503 return false;
2504 frange wlhs = float_widen_lhs_range (type, lhs);
2505 return float_binary_op_range_finish (fold_range (r, type, op1, wlhs),
2506 r, type, wlhs);
2509 void
2510 operator_minus::rv_fold (frange &r, tree type,
2511 const REAL_VALUE_TYPE &lh_lb,
2512 const REAL_VALUE_TYPE &lh_ub,
2513 const REAL_VALUE_TYPE &rh_lb,
2514 const REAL_VALUE_TYPE &rh_ub,
2515 relation_kind) const
2517 REAL_VALUE_TYPE lb, ub;
2518 bool maybe_nan = false;
2520 frange_arithmetic (MINUS_EXPR, type, lb, lh_lb, rh_ub, dconstninf);
2521 frange_arithmetic (MINUS_EXPR, type, ub, lh_ub, rh_lb, dconstinf);
2523 // [+INF] - [+INF] = NAN
2524 if (real_isinf (&lh_ub, false) && real_isinf (&rh_ub, false))
2525 maybe_nan = true;
2526 // [-INF] - [-INF] = NAN
2527 else if (real_isinf (&lh_lb, true) && real_isinf (&rh_lb, true))
2528 maybe_nan = true;
2530 // Handle possible NANs by saturating to the appropriate INF if only
2531 // one end is a NAN. If both ends are a NAN, just return a NAN.
2532 bool lb_nan = real_isnan (&lb);
2533 bool ub_nan = real_isnan (&ub);
2534 if (lb_nan && ub_nan)
2536 r.set_nan (type);
2537 return;
2539 if (lb_nan)
2540 lb = dconstninf;
2541 else if (ub_nan)
2542 ub = dconstinf;
2543 r.set (type, lb, ub, nan_state (maybe_nan));
2547 // Given CP[0] to CP[3] floating point values rounded to -INF,
2548 // set LB to the smallest of them (treating -0 as smaller to +0).
2549 // Given CP[4] to CP[7] floating point values rounded to +INF,
2550 // set UB to the largest of them (treating -0 as smaller to +0).
2552 static void
2553 find_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
2554 const REAL_VALUE_TYPE (&cp)[8])
2556 lb = cp[0];
2557 ub = cp[4];
2558 for (int i = 1; i < 4; ++i)
2560 if (real_less (&cp[i], &lb)
2561 || (real_iszero (&lb) && real_isnegzero (&cp[i])))
2562 lb = cp[i];
2563 if (real_less (&ub, &cp[i + 4])
2564 || (real_isnegzero (&ub) && real_iszero (&cp[i + 4])))
2565 ub = cp[i + 4];
2570 bool
2571 operator_mult::op1_range (frange &r, tree type,
2572 const frange &lhs, const frange &op2,
2573 relation_trio) const
2575 if (lhs.undefined_p ())
2576 return false;
2577 range_op_handler rdiv (RDIV_EXPR);
2578 if (!rdiv)
2579 return false;
2580 frange wlhs = float_widen_lhs_range (type, lhs);
2581 bool ret = rdiv.fold_range (r, type, wlhs, op2);
2582 if (ret == false)
2583 return false;
2584 if (wlhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
2585 return float_binary_op_range_finish (ret, r, type, wlhs);
2586 const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
2587 const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
2588 const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
2589 const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
2590 if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op2_lb, op2_ub))
2591 || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
2592 && (real_isinf (&op2_lb) || real_isinf (&op2_ub))))
2594 // If both lhs and op2 could be zeros or both could be infinities,
2595 // we don't know anything about op1 except maybe for the sign
2596 // and perhaps if it can be NAN or not.
2597 REAL_VALUE_TYPE lb, ub;
2598 int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
2599 zero_to_inf_range (lb, ub, signbit_known);
2600 r.set (type, lb, ub);
2602 // Otherwise, if op2 is a singleton INF and lhs doesn't include INF,
2603 // or if lhs must be zero and op2 doesn't include zero, it would be
2604 // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF
2605 // range. Those are supersets of UNDEFINED, so let's keep that way.
2606 return float_binary_op_range_finish (ret, r, type, wlhs);
2609 bool
2610 operator_mult::op2_range (frange &r, tree type,
2611 const frange &lhs, const frange &op1,
2612 relation_trio) const
2614 return op1_range (r, type, lhs, op1);
2617 void
2618 operator_mult::rv_fold (frange &r, tree type,
2619 const REAL_VALUE_TYPE &lh_lb,
2620 const REAL_VALUE_TYPE &lh_ub,
2621 const REAL_VALUE_TYPE &rh_lb,
2622 const REAL_VALUE_TYPE &rh_ub,
2623 relation_kind kind) const
2625 bool is_square
2626 = (kind == VREL_EQ
2627 && real_equal (&lh_lb, &rh_lb)
2628 && real_equal (&lh_ub, &rh_ub)
2629 && real_isneg (&lh_lb) == real_isneg (&rh_lb)
2630 && real_isneg (&lh_ub) == real_isneg (&rh_ub));
2631 REAL_VALUE_TYPE lb, ub;
2632 bool maybe_nan = false;
2633 // x * x never produces a new NAN and we only multiply the same
2634 // values, so the 0 * INF problematic cases never appear there.
2635 if (!is_square)
2637 // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN.
2638 if ((zero_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub))
2639 || (zero_p (rh_lb, rh_ub) && singleton_inf_p (lh_lb, lh_ub)))
2641 r.set_nan (type);
2642 return;
2645 // Otherwise, if one range includes zero and the other ends with +-INF,
2646 // it is a maybe NAN.
2647 if ((contains_zero_p (lh_lb, lh_ub)
2648 && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
2649 || (contains_zero_p (rh_lb, rh_ub)
2650 && (real_isinf (&lh_lb) || real_isinf (&lh_ub))))
2652 maybe_nan = true;
2654 int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
2656 // If one of the ranges that includes INF is singleton
2657 // and the other range includes zero, the resulting
2658 // range is INF and NAN, because the 0 * INF boundary
2659 // case will be NAN, but already nextafter (0, 1) * INF
2660 // is INF.
2661 if (singleton_inf_p (lh_lb, lh_ub)
2662 || singleton_inf_p (rh_lb, rh_ub))
2664 inf_range (lb, ub, signbit_known);
2665 r.set (type, lb, ub, nan_state (true));
2666 return;
2669 // If one of the multiplicands must be zero, the resulting
2670 // range is +-0 and NAN.
2671 if (zero_p (lh_lb, lh_ub) || zero_p (rh_lb, rh_ub))
2673 zero_range (lb, ub, signbit_known);
2674 r.set (type, lb, ub, nan_state (true));
2675 return;
2678 // Otherwise one of the multiplicands could be
2679 // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF]
2680 // or similarly with different signs. 0.0 * DBL_MAX
2681 // is still 0.0, nextafter (0.0, 1.0) * INF is still INF,
2682 // so if the signs are always the same or always different,
2683 // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING.
2684 zero_to_inf_range (lb, ub, signbit_known);
2685 r.set (type, lb, ub, nan_state (true));
2686 return;
2690 REAL_VALUE_TYPE cp[8];
2691 // Do a cross-product. At this point none of the multiplications
2692 // should produce a NAN.
2693 frange_arithmetic (MULT_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
2694 frange_arithmetic (MULT_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
2695 if (is_square)
2697 // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub)
2698 // as maximum and -0.0 as minimum if 0.0 is in the range,
2699 // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub).
2700 // -0.0 rather than 0.0 because VREL_EQ doesn't prove that
2701 // x and y are bitwise equal, just that they compare equal.
2702 if (contains_zero_p (lh_lb, lh_ub))
2704 if (real_isneg (&lh_lb) == real_isneg (&lh_ub))
2705 cp[1] = dconst0;
2706 else
2707 cp[1] = dconstm0;
2709 else
2710 cp[1] = cp[0];
2711 cp[2] = cp[0];
2712 cp[5] = cp[4];
2713 cp[6] = cp[4];
2715 else
2717 frange_arithmetic (MULT_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
2718 frange_arithmetic (MULT_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
2719 frange_arithmetic (MULT_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
2720 frange_arithmetic (MULT_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
2722 frange_arithmetic (MULT_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
2723 frange_arithmetic (MULT_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);
2725 find_range (lb, ub, cp);
2727 gcc_checking_assert (!real_isnan (&lb));
2728 gcc_checking_assert (!real_isnan (&ub));
2729 r.set (type, lb, ub, nan_state (maybe_nan));
2733 class foperator_div : public range_operator
2735 using range_operator::op1_range;
2736 using range_operator::op2_range;
2737 public:
2738 virtual bool op1_range (frange &r, tree type,
2739 const frange &lhs,
2740 const frange &op2,
2741 relation_trio = TRIO_VARYING) const final override
2743 if (lhs.undefined_p ())
2744 return false;
2745 frange wlhs = float_widen_lhs_range (type, lhs);
2746 bool ret = range_op_handler (MULT_EXPR).fold_range (r, type, wlhs, op2);
2747 if (!ret)
2748 return ret;
2749 if (wlhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
2750 return float_binary_op_range_finish (ret, r, type, wlhs);
2751 const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
2752 const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
2753 const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
2754 const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
2755 if ((contains_zero_p (lhs_lb, lhs_ub)
2756 && (real_isinf (&op2_lb) || real_isinf (&op2_ub)))
2757 || ((contains_zero_p (op2_lb, op2_ub))
2758 && (real_isinf (&lhs_lb) || real_isinf (&lhs_ub))))
2760 // If both lhs could be zero and op2 infinity or vice versa,
2761 // we don't know anything about op1 except maybe for the sign
2762 // and perhaps if it can be NAN or not.
2763 REAL_VALUE_TYPE lb, ub;
2764 int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
2765 zero_to_inf_range (lb, ub, signbit_known);
2766 r.set (type, lb, ub);
2768 return float_binary_op_range_finish (ret, r, type, wlhs);
2770 virtual bool op2_range (frange &r, tree type,
2771 const frange &lhs,
2772 const frange &op1,
2773 relation_trio = TRIO_VARYING) const final override
2775 if (lhs.undefined_p ())
2776 return false;
2777 frange wlhs = float_widen_lhs_range (type, lhs);
2778 bool ret = fold_range (r, type, op1, wlhs);
2779 if (!ret)
2780 return ret;
2781 if (wlhs.known_isnan () || op1.known_isnan () || op1.undefined_p ())
2782 return float_binary_op_range_finish (ret, r, type, wlhs, true);
2783 const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
2784 const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
2785 const REAL_VALUE_TYPE &op1_lb = op1.lower_bound ();
2786 const REAL_VALUE_TYPE &op1_ub = op1.upper_bound ();
2787 if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op1_lb, op1_ub))
2788 || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
2789 && (real_isinf (&op1_lb) || real_isinf (&op1_ub))))
2791 // If both lhs and op1 could be zeros or both could be infinities,
2792 // we don't know anything about op2 except maybe for the sign
2793 // and perhaps if it can be NAN or not.
2794 REAL_VALUE_TYPE lb, ub;
2795 int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op1_lb, op1_ub);
2796 zero_to_inf_range (lb, ub, signbit_known);
2797 r.set (type, lb, ub);
2799 return float_binary_op_range_finish (ret, r, type, wlhs, true);
2801 private:
2802 void rv_fold (frange &r, tree type,
2803 const REAL_VALUE_TYPE &lh_lb,
2804 const REAL_VALUE_TYPE &lh_ub,
2805 const REAL_VALUE_TYPE &rh_lb,
2806 const REAL_VALUE_TYPE &rh_ub,
2807 relation_kind) const final override
2809 // +-0.0 / +-0.0 or +-INF / +-INF is a known NAN.
2810 if ((zero_p (lh_lb, lh_ub) && zero_p (rh_lb, rh_ub))
2811 || (singleton_inf_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub)))
2813 r.set_nan (type);
2814 return;
2817 REAL_VALUE_TYPE lb, ub;
2818 bool maybe_nan = false;
2819 // If +-0.0 is in both ranges, it is a maybe NAN.
2820 if (contains_zero_p (lh_lb, lh_ub) && contains_zero_p (rh_lb, rh_ub))
2821 maybe_nan = true;
2822 // If +-INF is in both ranges, it is a maybe NAN.
2823 else if ((real_isinf (&lh_lb) || real_isinf (&lh_ub))
2824 && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
2825 maybe_nan = true;
2827 int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
2829 // If dividend must be zero, the range is just +-0
2830 // (including if the divisor is +-INF).
2831 // If divisor must be +-INF, the range is just +-0
2832 // (including if the dividend is zero).
2833 if (zero_p (lh_lb, lh_ub) || singleton_inf_p (rh_lb, rh_ub))
2835 zero_range (lb, ub, signbit_known);
2836 r.set (type, lb, ub, nan_state (maybe_nan));
2837 return;
2840 // If divisor must be zero, the range is just +-INF
2841 // (including if the dividend is +-INF).
2842 // If dividend must be +-INF, the range is just +-INF
2843 // (including if the dividend is zero).
2844 if (zero_p (rh_lb, rh_ub) || singleton_inf_p (lh_lb, lh_ub))
2846 inf_range (lb, ub, signbit_known);
2847 r.set (type, lb, ub, nan_state (maybe_nan));
2848 return;
2851 // Otherwise if both operands may be zero, divisor could be
2852 // nextafter(0.0, +-1.0) and dividend +-0.0
2853 // in which case result is going to INF or vice versa and
2854 // result +0.0. So, all we can say for that case is if the
2855 // signs of divisor and dividend are always the same we have
2856 // [+0.0, +INF], if they are always different we have
2857 // [-INF, -0.0]. If they vary, VARYING.
2858 // If both may be +-INF, divisor could be INF and dividend FLT_MAX,
2859 // in which case result is going to INF or vice versa and
2860 // result +0.0. So, all we can say for that case is if the
2861 // signs of divisor and dividend are always the same we have
2862 // [+0.0, +INF], if they are always different we have
2863 // [-INF, -0.0]. If they vary, VARYING.
2864 if (maybe_nan)
2866 zero_to_inf_range (lb, ub, signbit_known);
2867 r.set (type, lb, ub, nan_state (maybe_nan));
2868 return;
2871 REAL_VALUE_TYPE cp[8];
2872 // Do a cross-division. At this point none of the divisions should
2873 // produce a NAN.
2874 frange_arithmetic (RDIV_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
2875 frange_arithmetic (RDIV_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
2876 frange_arithmetic (RDIV_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
2877 frange_arithmetic (RDIV_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
2878 frange_arithmetic (RDIV_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
2879 frange_arithmetic (RDIV_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
2880 frange_arithmetic (RDIV_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
2881 frange_arithmetic (RDIV_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);
2883 find_range (lb, ub, cp);
2885 // If divisor may be zero (but is not known to be only zero),
2886 // and dividend can't be zero, the range can go up to -INF or +INF
2887 // depending on the signs.
2888 if (contains_zero_p (rh_lb, rh_ub))
2890 if (signbit_known <= 0)
2891 real_inf (&lb, true);
2892 if (signbit_known >= 0)
2893 real_inf (&ub, false);
2896 gcc_checking_assert (!real_isnan (&lb));
2897 gcc_checking_assert (!real_isnan (&ub));
2898 r.set (type, lb, ub, nan_state (maybe_nan));
2900 } fop_div;
2903 // Initialize any float operators to the primary table
2905 void
2906 range_op_table::initialize_float_ops ()
2908 set (UNLE_EXPR, fop_unordered_le);
2909 set (UNLT_EXPR, fop_unordered_lt);
2910 set (UNGE_EXPR, fop_unordered_ge);
2911 set (UNGT_EXPR, fop_unordered_gt);
2912 set (UNEQ_EXPR, fop_unordered_equal);
2913 set (ORDERED_EXPR, fop_ordered);
2914 set (UNORDERED_EXPR, fop_unordered);
2915 set (LTGT_EXPR, fop_ltgt);
2916 set (RDIV_EXPR, fop_div);
2919 #if CHECKING_P
2920 #include "selftest.h"
2922 namespace selftest
2925 // Build an frange from string endpoints.
2927 static inline frange
2928 frange_float (const char *lb, const char *ub, tree type = float_type_node)
2930 REAL_VALUE_TYPE min, max;
2931 gcc_assert (real_from_string (&min, lb) == 0);
2932 gcc_assert (real_from_string (&max, ub) == 0);
2933 return frange (type, min, max);
2936 void
2937 range_op_float_tests ()
2939 frange r, r0, r1;
2940 frange trange (float_type_node);
2942 // negate([-5, +10]) => [-10, 5]
2943 r0 = frange_float ("-5", "10");
2944 range_op_handler (NEGATE_EXPR).fold_range (r, float_type_node, r0, trange);
2945 ASSERT_EQ (r, frange_float ("-10", "5"));
2947 // negate([0, 1] -NAN) => [-1, -0] +NAN
2948 r0 = frange_float ("0", "1");
2949 r0.update_nan (true);
2950 range_op_handler (NEGATE_EXPR).fold_range (r, float_type_node, r0, trange);
2951 r1 = frange_float ("-1", "-0");
2952 r1.update_nan (false);
2953 ASSERT_EQ (r, r1);
2955 // [-INF,+INF] + [-INF,+INF] could be a NAN.
2956 range_op_handler plus (PLUS_EXPR);
2957 r0.set_varying (float_type_node);
2958 r1.set_varying (float_type_node);
2959 r0.clear_nan ();
2960 r1.clear_nan ();
2961 plus.fold_range (r, float_type_node, r0, r1);
2962 if (HONOR_NANS (float_type_node))
2963 ASSERT_TRUE (r.maybe_isnan ());
2966 } // namespace selftest
2968 #endif // CHECKING_P