PR111048: Set arg_npatterns correctly.
[official-gcc.git] / gcc / range-op-float.cc
blobe30b489c410eb30aa88cad415f375cf789195e51
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 REAL_VALUE_TYPE lb, ub;
66 bool maybe_nan;
67 rv_fold (lb, ub, maybe_nan, type,
68 op1.lower_bound (), op1.upper_bound (),
69 op2.lower_bound (), op2.upper_bound (), trio.op1_op2 ());
71 // Handle possible NANs by saturating to the appropriate INF if only
72 // one end is a NAN. If both ends are a NAN, just return a NAN.
73 bool lb_nan = real_isnan (&lb);
74 bool ub_nan = real_isnan (&ub);
75 if (lb_nan && ub_nan)
77 r.set_nan (type);
78 return true;
80 if (lb_nan)
81 lb = dconstninf;
82 else if (ub_nan)
83 ub = dconstinf;
85 r.set (type, lb, ub);
87 if (lb_nan || ub_nan || maybe_nan
88 || op1.maybe_isnan ()
89 || op2.maybe_isnan ())
90 // Keep the default NAN (with a varying sign) set by the setter.
92 else
93 r.clear_nan ();
95 // If the result has overflowed and flag_trapping_math, folding this
96 // operation could elide an overflow or division by zero exception.
97 // Avoid returning a singleton +-INF, to keep the propagators (DOM
98 // and substitute_and_fold_engine) from folding. See PR107608.
99 if (flag_trapping_math
100 && MODE_HAS_INFINITIES (TYPE_MODE (type))
101 && r.known_isinf () && !op1.known_isinf () && !op2.known_isinf ())
103 REAL_VALUE_TYPE inf = r.lower_bound ();
104 if (real_isneg (&inf))
106 REAL_VALUE_TYPE min = real_min_representable (type);
107 r.set (type, inf, min);
109 else
111 REAL_VALUE_TYPE max = real_max_representable (type);
112 r.set (type, max, inf);
116 r.flush_denormals_to_zero ();
118 return true;
121 // For a given operation, fold two sets of ranges into [lb, ub].
122 // MAYBE_NAN is set to TRUE if, in addition to any result in LB or
123 // UB, the final range has the possibility of a NAN.
124 void
125 range_operator::rv_fold (REAL_VALUE_TYPE &lb,
126 REAL_VALUE_TYPE &ub,
127 bool &maybe_nan,
128 tree type ATTRIBUTE_UNUSED,
129 const REAL_VALUE_TYPE &lh_lb ATTRIBUTE_UNUSED,
130 const REAL_VALUE_TYPE &lh_ub ATTRIBUTE_UNUSED,
131 const REAL_VALUE_TYPE &rh_lb ATTRIBUTE_UNUSED,
132 const REAL_VALUE_TYPE &rh_ub ATTRIBUTE_UNUSED,
133 relation_kind) const
135 lb = dconstninf;
136 ub = dconstinf;
137 maybe_nan = true;
140 bool
141 range_operator::fold_range (irange &r ATTRIBUTE_UNUSED,
142 tree type ATTRIBUTE_UNUSED,
143 const frange &lh ATTRIBUTE_UNUSED,
144 const irange &rh ATTRIBUTE_UNUSED,
145 relation_trio) const
147 return false;
150 bool
151 range_operator::fold_range (irange &r ATTRIBUTE_UNUSED,
152 tree type ATTRIBUTE_UNUSED,
153 const frange &lh ATTRIBUTE_UNUSED,
154 const frange &rh ATTRIBUTE_UNUSED,
155 relation_trio) const
157 return false;
160 bool
161 range_operator::fold_range (frange &r ATTRIBUTE_UNUSED,
162 tree type ATTRIBUTE_UNUSED,
163 const irange &lh ATTRIBUTE_UNUSED,
164 const irange &rh ATTRIBUTE_UNUSED,
165 relation_trio) const
167 return false;
170 bool
171 range_operator::op1_range (frange &r ATTRIBUTE_UNUSED,
172 tree type ATTRIBUTE_UNUSED,
173 const frange &lhs ATTRIBUTE_UNUSED,
174 const frange &op2 ATTRIBUTE_UNUSED,
175 relation_trio) const
177 return false;
180 bool
181 range_operator::op1_range (frange &r ATTRIBUTE_UNUSED,
182 tree type ATTRIBUTE_UNUSED,
183 const irange &lhs ATTRIBUTE_UNUSED,
184 const frange &op2 ATTRIBUTE_UNUSED,
185 relation_trio) const
187 return false;
190 bool
191 range_operator::op2_range (frange &r ATTRIBUTE_UNUSED,
192 tree type ATTRIBUTE_UNUSED,
193 const frange &lhs ATTRIBUTE_UNUSED,
194 const frange &op1 ATTRIBUTE_UNUSED,
195 relation_trio) const
197 return false;
200 bool
201 range_operator::op2_range (frange &r ATTRIBUTE_UNUSED,
202 tree type ATTRIBUTE_UNUSED,
203 const irange &lhs ATTRIBUTE_UNUSED,
204 const frange &op1 ATTRIBUTE_UNUSED,
205 relation_trio) const
207 return false;
210 relation_kind
211 range_operator::lhs_op1_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::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED,
221 const frange &op1 ATTRIBUTE_UNUSED,
222 const frange &op2 ATTRIBUTE_UNUSED,
223 relation_kind) const
225 return VREL_VARYING;
228 relation_kind
229 range_operator::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
230 const frange &op1 ATTRIBUTE_UNUSED,
231 const frange &op2 ATTRIBUTE_UNUSED,
232 relation_kind) const
234 return VREL_VARYING;
237 relation_kind
238 range_operator::lhs_op2_relation (const frange &lhs ATTRIBUTE_UNUSED,
239 const frange &op1 ATTRIBUTE_UNUSED,
240 const frange &op2 ATTRIBUTE_UNUSED,
241 relation_kind) const
243 return VREL_VARYING;
246 relation_kind
247 range_operator::op1_op2_relation (const irange &,
248 const frange &,
249 const frange &) const
251 return VREL_VARYING;
255 relation_kind
256 range_operator::op1_op2_relation (const frange &,
257 const frange &,
258 const frange &) const
260 return VREL_VARYING;
263 // Return TRUE if OP1 and OP2 may be a NAN.
265 static inline bool
266 maybe_isnan (const frange &op1, const frange &op2)
268 return op1.maybe_isnan () || op2.maybe_isnan ();
271 // Floating version of relop_early_resolve that takes into account NAN
272 // and -ffinite-math-only.
274 static inline bool
275 frelop_early_resolve (irange &r, tree type,
276 const frange &op1, const frange &op2,
277 relation_trio rel, relation_kind my_rel)
279 // If either operand is undefined, return VARYING.
280 if (empty_range_varying (r, type, op1, op2))
281 return true;
283 // We can fold relations from the oracle when we know both operands
284 // are free of NANs, or when -ffinite-math-only.
285 return (!maybe_isnan (op1, op2)
286 && relop_early_resolve (r, type, op1, op2, rel, my_rel));
289 // Set VALUE to its next real value, or INF if the operation overflows.
291 void
292 frange_nextafter (enum machine_mode mode,
293 REAL_VALUE_TYPE &value,
294 const REAL_VALUE_TYPE &inf)
296 if (MODE_COMPOSITE_P (mode)
297 && (real_isdenormal (&value, mode) || real_iszero (&value)))
299 // IBM extended denormals only have DFmode precision.
300 REAL_VALUE_TYPE tmp, tmp2;
301 real_convert (&tmp2, DFmode, &value);
302 real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2, &inf);
303 real_convert (&value, mode, &tmp);
305 else
307 REAL_VALUE_TYPE tmp;
308 real_nextafter (&tmp, REAL_MODE_FORMAT (mode), &value, &inf);
309 value = tmp;
313 // Like real_arithmetic, but round the result to INF if the operation
314 // produced inexact results.
316 // ?? There is still one problematic case, i387. With
317 // -fexcess-precision=standard we perform most SF/DFmode arithmetic in
318 // XFmode (long_double_type_node), so that case is OK. But without
319 // -mfpmath=sse, all the SF/DFmode computations are in XFmode
320 // precision (64-bit mantissa) and only occasionally rounded to
321 // SF/DFmode (when storing into memory from the 387 stack). Maybe
322 // this is ok as well though it is just occasionally more precise. ??
324 void
325 frange_arithmetic (enum tree_code code, tree type,
326 REAL_VALUE_TYPE &result,
327 const REAL_VALUE_TYPE &op1,
328 const REAL_VALUE_TYPE &op2,
329 const REAL_VALUE_TYPE &inf)
331 REAL_VALUE_TYPE value;
332 enum machine_mode mode = TYPE_MODE (type);
333 bool mode_composite = MODE_COMPOSITE_P (mode);
335 bool inexact = real_arithmetic (&value, code, &op1, &op2);
336 real_convert (&result, mode, &value);
338 /* When rounding towards negative infinity, x + (-x) and
339 x - x is -0 rather than +0 real_arithmetic computes.
340 So, when we are looking for lower bound (inf is negative),
341 use -0 rather than +0. */
342 if (flag_rounding_math
343 && (code == PLUS_EXPR || code == MINUS_EXPR)
344 && !inexact
345 && real_iszero (&result)
346 && !real_isneg (&result)
347 && real_isneg (&inf))
349 REAL_VALUE_TYPE op2a = op2;
350 if (code == PLUS_EXPR)
351 op2a.sign ^= 1;
352 if (real_isneg (&op1) == real_isneg (&op2a) && real_equal (&op1, &op2a))
353 result.sign = 1;
356 // Be extra careful if there may be discrepancies between the
357 // compile and runtime results.
358 bool round = false;
359 if (mode_composite)
360 round = true;
361 else
363 bool low = real_isneg (&inf);
364 round = (low ? !real_less (&result, &value)
365 : !real_less (&value, &result));
366 if (real_isinf (&result, !low)
367 && !real_isinf (&value)
368 && !flag_rounding_math)
370 // Use just [+INF, +INF] rather than [MAX, +INF]
371 // even if value is larger than MAX and rounds to
372 // nearest to +INF. Similarly just [-INF, -INF]
373 // rather than [-INF, +MAX] even if value is smaller
374 // than -MAX and rounds to nearest to -INF.
375 // Unless INEXACT is true, in that case we need some
376 // extra buffer.
377 if (!inexact)
378 round = false;
379 else
381 REAL_VALUE_TYPE tmp = result, tmp2;
382 frange_nextafter (mode, tmp, inf);
383 // TMP is at this point the maximum representable
384 // number.
385 real_arithmetic (&tmp2, MINUS_EXPR, &value, &tmp);
386 if (real_isneg (&tmp2) != low
387 && (REAL_EXP (&tmp2) - REAL_EXP (&tmp)
388 >= 2 - REAL_MODE_FORMAT (mode)->p))
389 round = false;
393 if (round && (inexact || !real_identical (&result, &value)))
395 if (mode_composite
396 && (real_isdenormal (&result, mode) || real_iszero (&result)))
398 // IBM extended denormals only have DFmode precision.
399 REAL_VALUE_TYPE tmp, tmp2;
400 real_convert (&tmp2, DFmode, &value);
401 real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2, &inf);
402 real_convert (&result, mode, &tmp);
404 else
405 frange_nextafter (mode, result, inf);
407 if (mode_composite)
408 switch (code)
410 case PLUS_EXPR:
411 case MINUS_EXPR:
412 // ibm-ldouble-format documents 1ulp for + and -.
413 frange_nextafter (mode, result, inf);
414 break;
415 case MULT_EXPR:
416 // ibm-ldouble-format documents 2ulps for *.
417 frange_nextafter (mode, result, inf);
418 frange_nextafter (mode, result, inf);
419 break;
420 case RDIV_EXPR:
421 // ibm-ldouble-format documents 3ulps for /.
422 frange_nextafter (mode, result, inf);
423 frange_nextafter (mode, result, inf);
424 frange_nextafter (mode, result, inf);
425 break;
426 default:
427 break;
431 // Crop R to [-INF, MAX] where MAX is the maximum representable number
432 // for TYPE.
434 static inline void
435 frange_drop_inf (frange &r, tree type)
437 REAL_VALUE_TYPE max = real_max_representable (type);
438 frange tmp (type, r.lower_bound (), max);
439 r.intersect (tmp);
442 // Crop R to [MIN, +INF] where MIN is the minimum representable number
443 // for TYPE.
445 static inline void
446 frange_drop_ninf (frange &r, tree type)
448 REAL_VALUE_TYPE min = real_min_representable (type);
449 frange tmp (type, min, r.upper_bound ());
450 r.intersect (tmp);
453 // Crop R to [MIN, MAX] where MAX is the maximum representable number
454 // for TYPE and MIN the minimum representable number for TYPE.
456 static inline void
457 frange_drop_infs (frange &r, tree type)
459 REAL_VALUE_TYPE max = real_max_representable (type);
460 REAL_VALUE_TYPE min = real_min_representable (type);
461 frange tmp (type, min, max);
462 r.intersect (tmp);
465 // If zero is in R, make sure both -0.0 and +0.0 are in the range.
467 static inline void
468 frange_add_zeros (frange &r, tree type)
470 if (r.undefined_p () || r.known_isnan ())
471 return;
473 if (HONOR_SIGNED_ZEROS (type)
474 && (real_iszero (&r.lower_bound ()) || real_iszero (&r.upper_bound ())))
476 frange zero;
477 zero.set_zero (type);
478 r.union_ (zero);
482 // Build a range that is <= VAL and store it in R. Return TRUE if
483 // further changes may be needed for R, or FALSE if R is in its final
484 // form.
486 static bool
487 build_le (frange &r, tree type, const frange &val)
489 gcc_checking_assert (!val.known_isnan ());
491 REAL_VALUE_TYPE ninf = frange_val_min (type);
492 r.set (type, ninf, val.upper_bound ());
494 // Add both zeros if there's the possibility of zero equality.
495 frange_add_zeros (r, type);
497 return true;
500 // Build a range that is < VAL and store it in R. Return TRUE if
501 // further changes may be needed for R, or FALSE if R is in its final
502 // form.
504 static bool
505 build_lt (frange &r, tree type, const frange &val)
507 gcc_checking_assert (!val.known_isnan ());
509 // < -INF is outside the range.
510 if (real_isinf (&val.upper_bound (), 1))
512 if (HONOR_NANS (type))
513 r.set_nan (type);
514 else
515 r.set_undefined ();
516 return false;
519 REAL_VALUE_TYPE ninf = frange_val_min (type);
520 REAL_VALUE_TYPE prev = val.upper_bound ();
521 machine_mode mode = TYPE_MODE (type);
522 // Default to the conservatively correct closed ranges for
523 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
524 // !HONOR_INFINITIES, nextafter will yield -INF, but frange::set()
525 // will crop the range appropriately.
526 if (!MODE_COMPOSITE_P (mode))
527 frange_nextafter (mode, prev, ninf);
528 r.set (type, ninf, prev);
529 return true;
532 // Build a range that is >= VAL and store it in R. Return TRUE if
533 // further changes may be needed for R, or FALSE if R is in its final
534 // form.
536 static bool
537 build_ge (frange &r, tree type, const frange &val)
539 gcc_checking_assert (!val.known_isnan ());
541 REAL_VALUE_TYPE inf = frange_val_max (type);
542 r.set (type, val.lower_bound (), inf);
544 // Add both zeros if there's the possibility of zero equality.
545 frange_add_zeros (r, type);
547 return true;
550 // Build a range that is > VAL and store it in R. Return TRUE if
551 // further changes may be needed for R, or FALSE if R is in its final
552 // form.
554 static bool
555 build_gt (frange &r, tree type, const frange &val)
557 gcc_checking_assert (!val.known_isnan ());
559 // > +INF is outside the range.
560 if (real_isinf (&val.lower_bound (), 0))
562 if (HONOR_NANS (type))
563 r.set_nan (type);
564 else
565 r.set_undefined ();
566 return false;
569 REAL_VALUE_TYPE inf = frange_val_max (type);
570 REAL_VALUE_TYPE next = val.lower_bound ();
571 machine_mode mode = TYPE_MODE (type);
572 // Default to the conservatively correct closed ranges for
573 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
574 // !HONOR_INFINITIES, nextafter will yield +INF, but frange::set()
575 // will crop the range appropriately.
576 if (!MODE_COMPOSITE_P (mode))
577 frange_nextafter (mode, next, inf);
578 r.set (type, next, inf);
579 return true;
583 bool
584 operator_identity::fold_range (frange &r, tree, const frange &op1,
585 const frange &, relation_trio) const
587 r = op1;
588 return true;
591 bool
592 operator_identity::op1_range (frange &r, tree, const frange &lhs,
593 const frange &, relation_trio) const
595 r = lhs;
596 return true;
599 bool
600 operator_cst::fold_range (frange &r, tree, const frange &op1,
601 const frange &, relation_trio) const
603 r = op1;
604 return true;
607 bool
608 operator_equal::op2_range (frange &r, tree type,
609 const irange &lhs, const frange &op1,
610 relation_trio rel) const
612 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
615 bool
616 operator_equal::fold_range (irange &r, tree type,
617 const frange &op1, const frange &op2,
618 relation_trio rel) const
620 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_EQ))
621 return true;
623 if (op1.known_isnan () || op2.known_isnan ())
624 r = range_false (type);
625 // We can be sure the values are always equal or not if both ranges
626 // consist of a single value, and then compare them.
627 else if (op1.singleton_p () && op2.singleton_p ())
629 if (op1 == op2)
630 r = range_true (type);
631 // If one operand is -0.0 and other 0.0, they are still equal.
632 else if (real_iszero (&op1.lower_bound ())
633 && real_iszero (&op2.lower_bound ()))
634 r = range_true (type);
635 else
636 r = range_false (type);
638 else if (real_iszero (&op1.lower_bound ())
639 && real_iszero (&op1.upper_bound ())
640 && real_iszero (&op2.lower_bound ())
641 && real_iszero (&op2.upper_bound ())
642 && !maybe_isnan (op1, op2))
643 // [-0.0, 0.0] == [-0.0, 0.0] or similar.
644 r = range_true (type);
645 else
647 // If ranges do not intersect, we know the range is not equal,
648 // otherwise we don't know anything for sure.
649 frange tmp = op1;
650 tmp.intersect (op2);
651 if (tmp.undefined_p ())
653 // If one range is [whatever, -0.0] and another
654 // [0.0, whatever2], we don't know anything either,
655 // because -0.0 == 0.0.
656 if ((real_iszero (&op1.upper_bound ())
657 && real_iszero (&op2.lower_bound ()))
658 || (real_iszero (&op1.lower_bound ())
659 && real_iszero (&op2.upper_bound ())))
660 r = range_true_and_false (type);
661 else
662 r = range_false (type);
664 else
665 r = range_true_and_false (type);
667 return true;
670 bool
671 operator_equal::op1_range (frange &r, tree type,
672 const irange &lhs,
673 const frange &op2,
674 relation_trio trio) const
676 relation_kind rel = trio.op1_op2 ();
677 switch (get_bool_state (r, lhs, type))
679 case BRS_TRUE:
680 // The TRUE side of x == NAN is unreachable.
681 if (op2.known_isnan ())
682 r.set_undefined ();
683 else
685 // If it's true, the result is the same as OP2.
686 r = op2;
687 // Add both zeros if there's the possibility of zero equality.
688 frange_add_zeros (r, type);
689 // The TRUE side of op1 == op2 implies op1 is !NAN.
690 r.clear_nan ();
692 break;
694 case BRS_FALSE:
695 // The FALSE side of op1 == op1 implies op1 is a NAN.
696 if (rel == VREL_EQ)
697 r.set_nan (type);
698 // On the FALSE side of x == NAN, we know nothing about x.
699 else if (op2.known_isnan ())
700 r.set_varying (type);
701 // If the result is false, the only time we know anything is
702 // if OP2 is a constant.
703 else if (op2.singleton_p ()
704 || (!op2.maybe_isnan () && op2.zero_p ()))
706 REAL_VALUE_TYPE tmp = op2.lower_bound ();
707 r.set (type, tmp, tmp, VR_ANTI_RANGE);
709 else
710 r.set_varying (type);
711 break;
713 default:
714 break;
716 return true;
719 // Check if the LHS range indicates a relation between OP1 and OP2.
721 relation_kind
722 operator_equal::op1_op2_relation (const irange &lhs, const frange &,
723 const frange &) const
725 if (lhs.undefined_p ())
726 return VREL_UNDEFINED;
728 // FALSE = op1 == op2 indicates NE_EXPR.
729 if (lhs.zero_p ())
730 return VREL_NE;
732 // TRUE = op1 == op2 indicates EQ_EXPR.
733 if (lhs.undefined_p () || !contains_zero_p (lhs))
734 return VREL_EQ;
735 return VREL_VARYING;
738 bool
739 operator_not_equal::fold_range (irange &r, tree type,
740 const frange &op1, const frange &op2,
741 relation_trio rel) const
743 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_NE))
744 return true;
746 // x != NAN is always TRUE.
747 if (op1.known_isnan () || op2.known_isnan ())
748 r = range_true (type);
749 // We can be sure the values are always equal or not if both ranges
750 // consist of a single value, and then compare them.
751 else if (op1.singleton_p () && op2.singleton_p ())
753 if (op1 == op2)
754 r = range_false (type);
755 // If one operand is -0.0 and other 0.0, they are still equal.
756 else if (real_iszero (&op1.lower_bound ())
757 && real_iszero (&op2.lower_bound ()))
758 r = range_false (type);
759 else
760 r = range_true (type);
762 else if (real_iszero (&op1.lower_bound ())
763 && real_iszero (&op1.upper_bound ())
764 && real_iszero (&op2.lower_bound ())
765 && real_iszero (&op2.upper_bound ())
766 && !maybe_isnan (op1, op2))
767 // [-0.0, 0.0] != [-0.0, 0.0] or similar.
768 r = range_false (type);
769 else
771 // If ranges do not intersect, we know the range is not equal,
772 // otherwise we don't know anything for sure.
773 frange tmp = op1;
774 tmp.intersect (op2);
775 if (tmp.undefined_p ())
777 // If one range is [whatever, -0.0] and another
778 // [0.0, whatever2], we don't know anything either,
779 // because -0.0 == 0.0.
780 if ((real_iszero (&op1.upper_bound ())
781 && real_iszero (&op2.lower_bound ()))
782 || (real_iszero (&op1.lower_bound ())
783 && real_iszero (&op2.upper_bound ())))
784 r = range_true_and_false (type);
785 else
786 r = range_true (type);
788 else
789 r = range_true_and_false (type);
791 return true;
794 bool
795 operator_not_equal::op1_range (frange &r, tree type,
796 const irange &lhs,
797 const frange &op2,
798 relation_trio trio) const
800 relation_kind rel = trio.op1_op2 ();
801 switch (get_bool_state (r, lhs, type))
803 case BRS_TRUE:
804 // If the result is true, the only time we know anything is if
805 // OP2 is a constant.
806 if (op2.singleton_p ())
808 // This is correct even if op1 is NAN, because the following
809 // range would be ~[tmp, tmp] with the NAN property set to
810 // maybe (VARYING).
811 REAL_VALUE_TYPE tmp = op2.lower_bound ();
812 r.set (type, tmp, tmp, VR_ANTI_RANGE);
814 // The TRUE side of op1 != op1 implies op1 is NAN.
815 else if (rel == VREL_EQ)
816 r.set_nan (type);
817 else
818 r.set_varying (type);
819 break;
821 case BRS_FALSE:
822 // The FALSE side of x != NAN is impossible.
823 if (op2.known_isnan ())
824 r.set_undefined ();
825 else
827 // If it's false, the result is the same as OP2.
828 r = op2;
829 // Add both zeros if there's the possibility of zero equality.
830 frange_add_zeros (r, type);
831 // The FALSE side of op1 != op2 implies op1 is !NAN.
832 r.clear_nan ();
834 break;
836 default:
837 break;
839 return true;
843 // Check if the LHS range indicates a relation between OP1 and OP2.
845 relation_kind
846 operator_not_equal::op1_op2_relation (const irange &lhs, const frange &,
847 const frange &) const
849 if (lhs.undefined_p ())
850 return VREL_UNDEFINED;
852 // FALSE = op1 != op2 indicates EQ_EXPR.
853 if (lhs.zero_p ())
854 return VREL_EQ;
856 // TRUE = op1 != op2 indicates NE_EXPR.
857 if (lhs.undefined_p () || !contains_zero_p (lhs))
858 return VREL_NE;
859 return VREL_VARYING;
862 bool
863 operator_lt::fold_range (irange &r, tree type,
864 const frange &op1, const frange &op2,
865 relation_trio rel) const
867 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_LT))
868 return true;
870 if (op1.known_isnan ()
871 || op2.known_isnan ()
872 || !real_less (&op1.lower_bound (), &op2.upper_bound ()))
873 r = range_false (type);
874 else if (!maybe_isnan (op1, op2)
875 && real_less (&op1.upper_bound (), &op2.lower_bound ()))
876 r = range_true (type);
877 else
878 r = range_true_and_false (type);
879 return true;
882 bool
883 operator_lt::op1_range (frange &r,
884 tree type,
885 const irange &lhs,
886 const frange &op2,
887 relation_trio) const
889 switch (get_bool_state (r, lhs, type))
891 case BRS_TRUE:
892 // The TRUE side of x < NAN is unreachable.
893 if (op2.known_isnan ())
894 r.set_undefined ();
895 else if (op2.undefined_p ())
896 return false;
897 else if (build_lt (r, type, op2))
899 r.clear_nan ();
900 // x < y implies x is not +INF.
901 frange_drop_inf (r, type);
903 break;
905 case BRS_FALSE:
906 // On the FALSE side of x < NAN, we know nothing about x.
907 if (op2.known_isnan () || op2.maybe_isnan ())
908 r.set_varying (type);
909 else
910 build_ge (r, type, op2);
911 break;
913 default:
914 break;
916 return true;
919 bool
920 operator_lt::op2_range (frange &r,
921 tree type,
922 const irange &lhs,
923 const frange &op1,
924 relation_trio) const
926 switch (get_bool_state (r, lhs, type))
928 case BRS_TRUE:
929 // The TRUE side of NAN < x is unreachable.
930 if (op1.known_isnan ())
931 r.set_undefined ();
932 else if (op1.undefined_p ())
933 return false;
934 else if (build_gt (r, type, op1))
936 r.clear_nan ();
937 // x < y implies y is not -INF.
938 frange_drop_ninf (r, type);
940 break;
942 case BRS_FALSE:
943 // On the FALSE side of NAN < x, we know nothing about x.
944 if (op1.known_isnan () || op1.maybe_isnan ())
945 r.set_varying (type);
946 else
947 build_le (r, type, op1);
948 break;
950 default:
951 break;
953 return true;
957 // Check if the LHS range indicates a relation between OP1 and OP2.
959 relation_kind
960 operator_lt::op1_op2_relation (const irange &lhs, const frange &,
961 const frange &) const
963 if (lhs.undefined_p ())
964 return VREL_UNDEFINED;
966 // FALSE = op1 < op2 indicates GE_EXPR.
967 if (lhs.zero_p ())
968 return VREL_GE;
970 // TRUE = op1 < op2 indicates LT_EXPR.
971 if (lhs.undefined_p () || !contains_zero_p (lhs))
972 return VREL_LT;
973 return VREL_VARYING;
976 bool
977 operator_le::fold_range (irange &r, tree type,
978 const frange &op1, const frange &op2,
979 relation_trio rel) const
981 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_LE))
982 return true;
984 if (op1.known_isnan ()
985 || op2.known_isnan ()
986 || !real_compare (LE_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
987 r = range_false (type);
988 else if (!maybe_isnan (op1, op2)
989 && real_compare (LE_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
990 r = range_true (type);
991 else
992 r = range_true_and_false (type);
993 return true;
996 bool
997 operator_le::op1_range (frange &r,
998 tree type,
999 const irange &lhs,
1000 const frange &op2,
1001 relation_trio) const
1003 switch (get_bool_state (r, lhs, type))
1005 case BRS_TRUE:
1006 // The TRUE side of x <= NAN is unreachable.
1007 if (op2.known_isnan ())
1008 r.set_undefined ();
1009 else if (op2.undefined_p ())
1010 return false;
1011 else if (build_le (r, type, op2))
1012 r.clear_nan ();
1013 break;
1015 case BRS_FALSE:
1016 // On the FALSE side of x <= NAN, we know nothing about x.
1017 if (op2.known_isnan () || op2.maybe_isnan ())
1018 r.set_varying (type);
1019 else
1020 build_gt (r, type, op2);
1021 break;
1023 default:
1024 break;
1026 return true;
1029 bool
1030 operator_le::op2_range (frange &r,
1031 tree type,
1032 const irange &lhs,
1033 const frange &op1,
1034 relation_trio) const
1036 switch (get_bool_state (r, lhs, type))
1038 case BRS_TRUE:
1039 // The TRUE side of NAN <= x is unreachable.
1040 if (op1.known_isnan ())
1041 r.set_undefined ();
1042 else if (op1.undefined_p ())
1043 return false;
1044 else if (build_ge (r, type, op1))
1045 r.clear_nan ();
1046 break;
1048 case BRS_FALSE:
1049 // On the FALSE side of NAN <= x, we know nothing about x.
1050 if (op1.known_isnan () || op1.maybe_isnan ())
1051 r.set_varying (type);
1052 else if (op1.undefined_p ())
1053 return false;
1054 else
1055 build_lt (r, type, op1);
1056 break;
1058 default:
1059 break;
1061 return true;
1064 // Check if the LHS range indicates a relation between OP1 and OP2.
1066 relation_kind
1067 operator_le::op1_op2_relation (const irange &lhs, const frange &,
1068 const frange &) const
1070 if (lhs.undefined_p ())
1071 return VREL_UNDEFINED;
1073 // FALSE = op1 <= op2 indicates GT_EXPR.
1074 if (lhs.zero_p ())
1075 return VREL_GT;
1077 // TRUE = op1 <= op2 indicates LE_EXPR.
1078 if (lhs.undefined_p () || !contains_zero_p (lhs))
1079 return VREL_LE;
1080 return VREL_VARYING;
1083 bool
1084 operator_gt::fold_range (irange &r, tree type,
1085 const frange &op1, const frange &op2,
1086 relation_trio rel) const
1088 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_GT))
1089 return true;
1091 if (op1.known_isnan ()
1092 || op2.known_isnan ()
1093 || !real_compare (GT_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
1094 r = range_false (type);
1095 else if (!maybe_isnan (op1, op2)
1096 && real_compare (GT_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
1097 r = range_true (type);
1098 else
1099 r = range_true_and_false (type);
1100 return true;
1103 bool
1104 operator_gt::op1_range (frange &r,
1105 tree type,
1106 const irange &lhs,
1107 const frange &op2,
1108 relation_trio) const
1110 switch (get_bool_state (r, lhs, type))
1112 case BRS_TRUE:
1113 // The TRUE side of x > NAN is unreachable.
1114 if (op2.known_isnan ())
1115 r.set_undefined ();
1116 else if (op2.undefined_p ())
1117 return false;
1118 else if (build_gt (r, type, op2))
1120 r.clear_nan ();
1121 // x > y implies x is not -INF.
1122 frange_drop_ninf (r, type);
1124 break;
1126 case BRS_FALSE:
1127 // On the FALSE side of x > NAN, we know nothing about x.
1128 if (op2.known_isnan () || op2.maybe_isnan ())
1129 r.set_varying (type);
1130 else if (op2.undefined_p ())
1131 return false;
1132 else
1133 build_le (r, type, op2);
1134 break;
1136 default:
1137 break;
1139 return true;
1142 bool
1143 operator_gt::op2_range (frange &r,
1144 tree type,
1145 const irange &lhs,
1146 const frange &op1,
1147 relation_trio) const
1149 switch (get_bool_state (r, lhs, type))
1151 case BRS_TRUE:
1152 // The TRUE side of NAN > x is unreachable.
1153 if (op1.known_isnan ())
1154 r.set_undefined ();
1155 else if (op1.undefined_p ())
1156 return false;
1157 else if (build_lt (r, type, op1))
1159 r.clear_nan ();
1160 // x > y implies y is not +INF.
1161 frange_drop_inf (r, type);
1163 break;
1165 case BRS_FALSE:
1166 // On The FALSE side of NAN > x, we know nothing about x.
1167 if (op1.known_isnan () || op1.maybe_isnan ())
1168 r.set_varying (type);
1169 else if (op1.undefined_p ())
1170 return false;
1171 else
1172 build_ge (r, type, op1);
1173 break;
1175 default:
1176 break;
1178 return true;
1181 // Check if the LHS range indicates a relation between OP1 and OP2.
1183 relation_kind
1184 operator_gt::op1_op2_relation (const irange &lhs, const frange &,
1185 const frange &) const
1187 if (lhs.undefined_p ())
1188 return VREL_UNDEFINED;
1190 // FALSE = op1 > op2 indicates LE_EXPR.
1191 if (lhs.zero_p ())
1192 return VREL_LE;
1194 // TRUE = op1 > op2 indicates GT_EXPR.
1195 if (!contains_zero_p (lhs))
1196 return VREL_GT;
1197 return VREL_VARYING;
1200 bool
1201 operator_ge::fold_range (irange &r, tree type,
1202 const frange &op1, const frange &op2,
1203 relation_trio rel) const
1205 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_GE))
1206 return true;
1208 if (op1.known_isnan ()
1209 || op2.known_isnan ()
1210 || !real_compare (GE_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
1211 r = range_false (type);
1212 else if (!maybe_isnan (op1, op2)
1213 && real_compare (GE_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
1214 r = range_true (type);
1215 else
1216 r = range_true_and_false (type);
1217 return true;
1220 bool
1221 operator_ge::op1_range (frange &r,
1222 tree type,
1223 const irange &lhs,
1224 const frange &op2,
1225 relation_trio) const
1227 switch (get_bool_state (r, lhs, type))
1229 case BRS_TRUE:
1230 // The TRUE side of x >= NAN is unreachable.
1231 if (op2.known_isnan ())
1232 r.set_undefined ();
1233 else if (op2.undefined_p ())
1234 return false;
1235 else if (build_ge (r, type, op2))
1236 r.clear_nan ();
1237 break;
1239 case BRS_FALSE:
1240 // On the FALSE side of x >= NAN, we know nothing about x.
1241 if (op2.known_isnan () || op2.maybe_isnan ())
1242 r.set_varying (type);
1243 else if (op2.undefined_p ())
1244 return false;
1245 else
1246 build_lt (r, type, op2);
1247 break;
1249 default:
1250 break;
1252 return true;
1255 bool
1256 operator_ge::op2_range (frange &r, tree type,
1257 const irange &lhs,
1258 const frange &op1,
1259 relation_trio) const
1261 switch (get_bool_state (r, lhs, type))
1263 case BRS_TRUE:
1264 // The TRUE side of NAN >= x is unreachable.
1265 if (op1.known_isnan ())
1266 r.set_undefined ();
1267 else if (op1.undefined_p ())
1268 return false;
1269 else if (build_le (r, type, op1))
1270 r.clear_nan ();
1271 break;
1273 case BRS_FALSE:
1274 // On the FALSE side of NAN >= x, we know nothing about x.
1275 if (op1.known_isnan () || op1.maybe_isnan ())
1276 r.set_varying (type);
1277 else if (op1.undefined_p ())
1278 return false;
1279 else
1280 build_gt (r, type, op1);
1281 break;
1283 default:
1284 break;
1286 return true;
1289 // Check if the LHS range indicates a relation between OP1 and OP2.
1291 relation_kind
1292 operator_ge::op1_op2_relation (const irange &lhs, const frange &,
1293 const frange &) const
1295 if (lhs.undefined_p ())
1296 return VREL_UNDEFINED;
1298 // FALSE = op1 >= op2 indicates LT_EXPR.
1299 if (lhs.zero_p ())
1300 return VREL_LT;
1302 // TRUE = op1 >= op2 indicates GE_EXPR.
1303 if (!contains_zero_p (lhs))
1304 return VREL_GE;
1305 return VREL_VARYING;
1308 // UNORDERED_EXPR comparison.
1310 class foperator_unordered : public range_operator
1312 using range_operator::fold_range;
1313 using range_operator::op1_range;
1314 using range_operator::op2_range;
1315 public:
1316 bool fold_range (irange &r, tree type,
1317 const frange &op1, const frange &op2,
1318 relation_trio = TRIO_VARYING) const final override;
1319 bool op1_range (frange &r, tree type,
1320 const irange &lhs, const frange &op2,
1321 relation_trio = TRIO_VARYING) const final override;
1322 bool op2_range (frange &r, tree type,
1323 const irange &lhs, const frange &op1,
1324 relation_trio rel = TRIO_VARYING) const final override
1326 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
1328 } fop_unordered;
1330 bool
1331 foperator_unordered::fold_range (irange &r, tree type,
1332 const frange &op1, const frange &op2,
1333 relation_trio) const
1335 // UNORDERED is TRUE if either operand is a NAN.
1336 if (op1.known_isnan () || op2.known_isnan ())
1337 r = range_true (type);
1338 // UNORDERED is FALSE if neither operand is a NAN.
1339 else if (!op1.maybe_isnan () && !op2.maybe_isnan ())
1340 r = range_false (type);
1341 else
1342 r = range_true_and_false (type);
1343 return true;
1346 bool
1347 foperator_unordered::op1_range (frange &r, tree type,
1348 const irange &lhs,
1349 const frange &op2,
1350 relation_trio trio) const
1352 relation_kind rel = trio.op1_op2 ();
1353 switch (get_bool_state (r, lhs, type))
1355 case BRS_TRUE:
1356 // Since at least one operand must be NAN, if one of them is
1357 // not, the other must be.
1358 if (rel == VREL_EQ || !op2.maybe_isnan ())
1359 r.set_nan (type);
1360 else
1361 r.set_varying (type);
1362 break;
1364 case BRS_FALSE:
1365 // A false UNORDERED means both operands are !NAN, so it's
1366 // impossible for op2 to be a NAN.
1367 if (op2.known_isnan ())
1368 r.set_undefined ();
1369 else
1371 r.set_varying (type);
1372 r.clear_nan ();
1374 break;
1376 default:
1377 break;
1379 return true;
1382 // ORDERED_EXPR comparison.
1384 class foperator_ordered : public range_operator
1386 using range_operator::fold_range;
1387 using range_operator::op1_range;
1388 using range_operator::op2_range;
1389 public:
1390 bool fold_range (irange &r, tree type,
1391 const frange &op1, const frange &op2,
1392 relation_trio = TRIO_VARYING) const final override;
1393 bool op1_range (frange &r, tree type,
1394 const irange &lhs, const frange &op2,
1395 relation_trio = TRIO_VARYING) const final override;
1396 bool op2_range (frange &r, tree type,
1397 const irange &lhs, const frange &op1,
1398 relation_trio rel = TRIO_VARYING) const final override
1400 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
1402 } fop_ordered;
1404 bool
1405 foperator_ordered::fold_range (irange &r, tree type,
1406 const frange &op1, const frange &op2,
1407 relation_trio) const
1409 if (op1.known_isnan () || op2.known_isnan ())
1410 r = range_false (type);
1411 else if (!op1.maybe_isnan () && !op2.maybe_isnan ())
1412 r = range_true (type);
1413 else
1414 r = range_true_and_false (type);
1415 return true;
1418 bool
1419 foperator_ordered::op1_range (frange &r, tree type,
1420 const irange &lhs,
1421 const frange &op2,
1422 relation_trio trio) const
1424 relation_kind rel = trio.op1_op2 ();
1425 switch (get_bool_state (r, lhs, type))
1427 case BRS_TRUE:
1428 // The TRUE side of ORDERED means both operands are !NAN, so
1429 // it's impossible for op2 to be a NAN.
1430 if (op2.known_isnan ())
1431 r.set_undefined ();
1432 else
1434 r.set_varying (type);
1435 r.clear_nan ();
1437 break;
1439 case BRS_FALSE:
1440 // The FALSE side of op1 ORDERED op1 implies op1 is NAN.
1441 if (rel == VREL_EQ)
1442 r.set_nan (type);
1443 else
1444 r.set_varying (type);
1445 break;
1447 default:
1448 break;
1450 return true;
1453 bool
1454 operator_negate::fold_range (frange &r, tree type,
1455 const frange &op1, const frange &op2,
1456 relation_trio) const
1458 if (empty_range_varying (r, type, op1, op2))
1459 return true;
1460 if (op1.known_isnan ())
1462 bool sign;
1463 if (op1.nan_signbit_p (sign))
1464 r.set_nan (type, !sign);
1465 else
1466 r.set_nan (type);
1467 return true;
1470 REAL_VALUE_TYPE lh_lb = op1.lower_bound ();
1471 REAL_VALUE_TYPE lh_ub = op1.upper_bound ();
1472 lh_lb = real_value_negate (&lh_lb);
1473 lh_ub = real_value_negate (&lh_ub);
1474 r.set (type, lh_ub, lh_lb);
1475 if (op1.maybe_isnan ())
1477 bool sign;
1478 if (op1.nan_signbit_p (sign))
1479 r.update_nan (!sign);
1480 else
1481 r.update_nan ();
1483 else
1484 r.clear_nan ();
1485 return true;
1488 bool
1489 operator_negate::op1_range (frange &r, tree type,
1490 const frange &lhs, const frange &op2,
1491 relation_trio rel) const
1493 return fold_range (r, type, lhs, op2, rel);
1496 bool
1497 operator_abs::fold_range (frange &r, tree type,
1498 const frange &op1, const frange &op2,
1499 relation_trio) const
1501 if (empty_range_varying (r, type, op1, op2))
1502 return true;
1503 if (op1.known_isnan ())
1505 r.set_nan (type, /*sign=*/false);
1506 return true;
1509 const REAL_VALUE_TYPE lh_lb = op1.lower_bound ();
1510 const REAL_VALUE_TYPE lh_ub = op1.upper_bound ();
1511 // Handle the easy case where everything is positive.
1512 if (real_compare (GE_EXPR, &lh_lb, &dconst0)
1513 && !real_iszero (&lh_lb, /*sign=*/true)
1514 && !op1.maybe_isnan (/*sign=*/true))
1516 r = op1;
1517 return true;
1520 REAL_VALUE_TYPE min = real_value_abs (&lh_lb);
1521 REAL_VALUE_TYPE max = real_value_abs (&lh_ub);
1522 // If the range contains zero then we know that the minimum value in the
1523 // range will be zero.
1524 if (real_compare (LE_EXPR, &lh_lb, &dconst0)
1525 && real_compare (GE_EXPR, &lh_ub, &dconst0))
1527 if (real_compare (GT_EXPR, &min, &max))
1528 max = min;
1529 min = dconst0;
1531 else
1533 // If the range was reversed, swap MIN and MAX.
1534 if (real_compare (GT_EXPR, &min, &max))
1535 std::swap (min, max);
1538 r.set (type, min, max);
1539 if (op1.maybe_isnan ())
1540 r.update_nan (/*sign=*/false);
1541 else
1542 r.clear_nan ();
1543 return true;
1546 bool
1547 operator_abs::op1_range (frange &r, tree type,
1548 const frange &lhs, const frange &op2,
1549 relation_trio) const
1551 if (empty_range_varying (r, type, lhs, op2))
1552 return true;
1553 if (lhs.known_isnan ())
1555 r.set_nan (type);
1556 return true;
1559 // Start with the positives because negatives are an impossible result.
1560 frange positives (type, dconst0, frange_val_max (type));
1561 positives.update_nan (/*sign=*/false);
1562 positives.intersect (lhs);
1563 r = positives;
1564 // Add -NAN if relevant.
1565 if (r.maybe_isnan ())
1567 frange neg_nan;
1568 neg_nan.set_nan (type, true);
1569 r.union_ (neg_nan);
1571 if (r.known_isnan () || r.undefined_p ())
1572 return true;
1573 // Then add the negative of each pair:
1574 // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
1575 frange negatives (type, real_value_negate (&positives.upper_bound ()),
1576 real_value_negate (&positives.lower_bound ()));
1577 negatives.clear_nan ();
1578 r.union_ (negatives);
1579 return true;
1582 class foperator_unordered_lt : public range_operator
1584 using range_operator::fold_range;
1585 using range_operator::op1_range;
1586 using range_operator::op2_range;
1587 public:
1588 bool fold_range (irange &r, tree type,
1589 const frange &op1, const frange &op2,
1590 relation_trio rel = TRIO_VARYING) const final override
1592 if (op1.known_isnan () || op2.known_isnan ())
1594 r = range_true (type);
1595 return true;
1597 frange op1_no_nan = op1;
1598 frange op2_no_nan = op2;
1599 if (op1.maybe_isnan ())
1600 op1_no_nan.clear_nan ();
1601 if (op2.maybe_isnan ())
1602 op2_no_nan.clear_nan ();
1603 if (!range_op_handler (LT_EXPR).fold_range (r, type, op1_no_nan,
1604 op2_no_nan, rel))
1605 return false;
1606 // The result is the same as the ordered version when the
1607 // comparison is true or when the operands cannot be NANs.
1608 if (!maybe_isnan (op1, op2) || r == range_true (type))
1609 return true;
1610 else
1612 r = range_true_and_false (type);
1613 return true;
1616 bool op1_range (frange &r, tree type,
1617 const irange &lhs,
1618 const frange &op2,
1619 relation_trio trio) const final override;
1620 bool op2_range (frange &r, tree type,
1621 const irange &lhs,
1622 const frange &op1,
1623 relation_trio trio) const final override;
1624 } fop_unordered_lt;
1626 bool
1627 foperator_unordered_lt::op1_range (frange &r, tree type,
1628 const irange &lhs,
1629 const frange &op2,
1630 relation_trio) const
1632 switch (get_bool_state (r, lhs, type))
1634 case BRS_TRUE:
1635 if (op2.known_isnan () || op2.maybe_isnan ())
1636 r.set_varying (type);
1637 else if (op2.undefined_p ())
1638 return false;
1639 else
1640 build_lt (r, type, op2);
1641 break;
1643 case BRS_FALSE:
1644 // A false UNORDERED_LT means both operands are !NAN, so it's
1645 // impossible for op2 to be a NAN.
1646 if (op2.known_isnan ())
1647 r.set_undefined ();
1648 else if (op2.undefined_p ())
1649 return false;
1650 else if (build_ge (r, type, op2))
1651 r.clear_nan ();
1652 break;
1654 default:
1655 break;
1657 return true;
1660 bool
1661 foperator_unordered_lt::op2_range (frange &r, tree type,
1662 const irange &lhs,
1663 const frange &op1,
1664 relation_trio) const
1666 switch (get_bool_state (r, lhs, type))
1668 case BRS_TRUE:
1669 if (op1.known_isnan () || op1.maybe_isnan ())
1670 r.set_varying (type);
1671 else if (op1.undefined_p ())
1672 return false;
1673 else
1674 build_gt (r, type, op1);
1675 break;
1677 case BRS_FALSE:
1678 // A false UNORDERED_LT means both operands are !NAN, so it's
1679 // impossible for op1 to be a NAN.
1680 if (op1.known_isnan ())
1681 r.set_undefined ();
1682 else if (op1.undefined_p ())
1683 return false;
1684 else if (build_le (r, type, op1))
1685 r.clear_nan ();
1686 break;
1688 default:
1689 break;
1691 return true;
1694 class foperator_unordered_le : public range_operator
1696 using range_operator::fold_range;
1697 using range_operator::op1_range;
1698 using range_operator::op2_range;
1699 public:
1700 bool fold_range (irange &r, tree type,
1701 const frange &op1, const frange &op2,
1702 relation_trio rel = TRIO_VARYING) const final override
1704 if (op1.known_isnan () || op2.known_isnan ())
1706 r = range_true (type);
1707 return true;
1709 frange op1_no_nan = op1;
1710 frange op2_no_nan = op2;
1711 if (op1.maybe_isnan ())
1712 op1_no_nan.clear_nan ();
1713 if (op2.maybe_isnan ())
1714 op2_no_nan.clear_nan ();
1715 if (!range_op_handler (LE_EXPR).fold_range (r, type, op1_no_nan,
1716 op2_no_nan, rel))
1717 return false;
1718 // The result is the same as the ordered version when the
1719 // comparison is true or when the operands cannot be NANs.
1720 if (!maybe_isnan (op1, op2) || r == range_true (type))
1721 return true;
1722 else
1724 r = range_true_and_false (type);
1725 return true;
1728 bool op1_range (frange &r, tree type,
1729 const irange &lhs, const frange &op2,
1730 relation_trio = TRIO_VARYING) const final override;
1731 bool op2_range (frange &r, tree type,
1732 const irange &lhs, const frange &op1,
1733 relation_trio = TRIO_VARYING) const final override;
1734 } fop_unordered_le;
1736 bool
1737 foperator_unordered_le::op1_range (frange &r, tree type,
1738 const irange &lhs, const frange &op2,
1739 relation_trio) const
1741 switch (get_bool_state (r, lhs, type))
1743 case BRS_TRUE:
1744 if (op2.known_isnan () || op2.maybe_isnan ())
1745 r.set_varying (type);
1746 else if (op2.undefined_p ())
1747 return false;
1748 else
1749 build_le (r, type, op2);
1750 break;
1752 case BRS_FALSE:
1753 // A false UNORDERED_LE means both operands are !NAN, so it's
1754 // impossible for op2 to be a NAN.
1755 if (op2.known_isnan ())
1756 r.set_undefined ();
1757 else if (build_gt (r, type, op2))
1758 r.clear_nan ();
1759 break;
1761 default:
1762 break;
1764 return true;
1767 bool
1768 foperator_unordered_le::op2_range (frange &r,
1769 tree type,
1770 const irange &lhs,
1771 const frange &op1,
1772 relation_trio) const
1774 switch (get_bool_state (r, lhs, type))
1776 case BRS_TRUE:
1777 if (op1.known_isnan () || op1.maybe_isnan ())
1778 r.set_varying (type);
1779 else if (op1.undefined_p ())
1780 return false;
1781 else
1782 build_ge (r, type, op1);
1783 break;
1785 case BRS_FALSE:
1786 // A false UNORDERED_LE means both operands are !NAN, so it's
1787 // impossible for op1 to be a NAN.
1788 if (op1.known_isnan ())
1789 r.set_undefined ();
1790 else if (op1.undefined_p ())
1791 return false;
1792 else if (build_lt (r, type, op1))
1793 r.clear_nan ();
1794 break;
1796 default:
1797 break;
1799 return true;
1802 class foperator_unordered_gt : public range_operator
1804 using range_operator::fold_range;
1805 using range_operator::op1_range;
1806 using range_operator::op2_range;
1807 public:
1808 bool fold_range (irange &r, tree type,
1809 const frange &op1, const frange &op2,
1810 relation_trio rel = TRIO_VARYING) const final override
1812 if (op1.known_isnan () || op2.known_isnan ())
1814 r = range_true (type);
1815 return true;
1817 frange op1_no_nan = op1;
1818 frange op2_no_nan = op2;
1819 if (op1.maybe_isnan ())
1820 op1_no_nan.clear_nan ();
1821 if (op2.maybe_isnan ())
1822 op2_no_nan.clear_nan ();
1823 if (!range_op_handler (GT_EXPR).fold_range (r, type, op1_no_nan,
1824 op2_no_nan, rel))
1825 return false;
1826 // The result is the same as the ordered version when the
1827 // comparison is true or when the operands cannot be NANs.
1828 if (!maybe_isnan (op1, op2) || r == range_true (type))
1829 return true;
1830 else
1832 r = range_true_and_false (type);
1833 return true;
1836 bool op1_range (frange &r, tree type,
1837 const irange &lhs, const frange &op2,
1838 relation_trio = TRIO_VARYING) const final override;
1839 bool op2_range (frange &r, tree type,
1840 const irange &lhs, const frange &op1,
1841 relation_trio = TRIO_VARYING) const final override;
1842 } fop_unordered_gt;
1844 bool
1845 foperator_unordered_gt::op1_range (frange &r,
1846 tree type,
1847 const irange &lhs,
1848 const frange &op2,
1849 relation_trio) const
1851 switch (get_bool_state (r, lhs, type))
1853 case BRS_TRUE:
1854 if (op2.known_isnan () || op2.maybe_isnan ())
1855 r.set_varying (type);
1856 else if (op2.undefined_p ())
1857 return false;
1858 else
1859 build_gt (r, type, op2);
1860 break;
1862 case BRS_FALSE:
1863 // A false UNORDERED_GT means both operands are !NAN, so it's
1864 // impossible for op2 to be a NAN.
1865 if (op2.known_isnan ())
1866 r.set_undefined ();
1867 else if (op2.undefined_p ())
1868 return false;
1869 else if (build_le (r, type, op2))
1870 r.clear_nan ();
1871 break;
1873 default:
1874 break;
1876 return true;
1879 bool
1880 foperator_unordered_gt::op2_range (frange &r,
1881 tree type,
1882 const irange &lhs,
1883 const frange &op1,
1884 relation_trio) const
1886 switch (get_bool_state (r, lhs, type))
1888 case BRS_TRUE:
1889 if (op1.known_isnan () || op1.maybe_isnan ())
1890 r.set_varying (type);
1891 else if (op1.undefined_p ())
1892 return false;
1893 else
1894 build_lt (r, type, op1);
1895 break;
1897 case BRS_FALSE:
1898 // A false UNORDERED_GT means both operands are !NAN, so it's
1899 // impossible for op1 to be a NAN.
1900 if (op1.known_isnan ())
1901 r.set_undefined ();
1902 else if (op1.undefined_p ())
1903 return false;
1904 else if (build_ge (r, type, op1))
1905 r.clear_nan ();
1906 break;
1908 default:
1909 break;
1911 return true;
1914 class foperator_unordered_ge : public range_operator
1916 using range_operator::fold_range;
1917 using range_operator::op1_range;
1918 using range_operator::op2_range;
1919 public:
1920 bool fold_range (irange &r, tree type,
1921 const frange &op1, const frange &op2,
1922 relation_trio rel = TRIO_VARYING) const final override
1924 if (op1.known_isnan () || op2.known_isnan ())
1926 r = range_true (type);
1927 return true;
1929 frange op1_no_nan = op1;
1930 frange op2_no_nan = op2;
1931 if (op1.maybe_isnan ())
1932 op1_no_nan.clear_nan ();
1933 if (op2.maybe_isnan ())
1934 op2_no_nan.clear_nan ();
1935 if (!range_op_handler (GE_EXPR).fold_range (r, type, op1_no_nan,
1936 op2_no_nan, rel))
1937 return false;
1938 // The result is the same as the ordered version when the
1939 // comparison is true or when the operands cannot be NANs.
1940 if (!maybe_isnan (op1, op2) || r == range_true (type))
1941 return true;
1942 else
1944 r = range_true_and_false (type);
1945 return true;
1948 bool op1_range (frange &r, tree type,
1949 const irange &lhs, const frange &op2,
1950 relation_trio = TRIO_VARYING) const final override;
1951 bool op2_range (frange &r, tree type,
1952 const irange &lhs, const frange &op1,
1953 relation_trio = TRIO_VARYING) const final override;
1954 } fop_unordered_ge;
1956 bool
1957 foperator_unordered_ge::op1_range (frange &r,
1958 tree type,
1959 const irange &lhs,
1960 const frange &op2,
1961 relation_trio) const
1963 switch (get_bool_state (r, lhs, type))
1965 case BRS_TRUE:
1966 if (op2.known_isnan () || op2.maybe_isnan ())
1967 r.set_varying (type);
1968 else if (op2.undefined_p ())
1969 return false;
1970 else
1971 build_ge (r, type, op2);
1972 break;
1974 case BRS_FALSE:
1975 // A false UNORDERED_GE means both operands are !NAN, so it's
1976 // impossible for op2 to be a NAN.
1977 if (op2.known_isnan ())
1978 r.set_undefined ();
1979 else if (op2.undefined_p ())
1980 return false;
1981 else if (build_lt (r, type, op2))
1982 r.clear_nan ();
1983 break;
1985 default:
1986 break;
1988 return true;
1991 bool
1992 foperator_unordered_ge::op2_range (frange &r, tree type,
1993 const irange &lhs,
1994 const frange &op1,
1995 relation_trio) const
1997 switch (get_bool_state (r, lhs, type))
1999 case BRS_TRUE:
2000 if (op1.known_isnan () || op1.maybe_isnan ())
2001 r.set_varying (type);
2002 else if (op1.undefined_p ())
2003 return false;
2004 else
2005 build_le (r, type, op1);
2006 break;
2008 case BRS_FALSE:
2009 // A false UNORDERED_GE means both operands are !NAN, so it's
2010 // impossible for op1 to be a NAN.
2011 if (op1.known_isnan ())
2012 r.set_undefined ();
2013 else if (op1.undefined_p ())
2014 return false;
2015 else if (build_gt (r, type, op1))
2016 r.clear_nan ();
2017 break;
2019 default:
2020 break;
2022 return true;
2025 class foperator_unordered_equal : public range_operator
2027 using range_operator::fold_range;
2028 using range_operator::op1_range;
2029 using range_operator::op2_range;
2030 public:
2031 bool fold_range (irange &r, tree type,
2032 const frange &op1, const frange &op2,
2033 relation_trio rel = TRIO_VARYING) const final override
2035 if (op1.known_isnan () || op2.known_isnan ())
2037 r = range_true (type);
2038 return true;
2040 frange op1_no_nan = op1;
2041 frange op2_no_nan = op2;
2042 if (op1.maybe_isnan ())
2043 op1_no_nan.clear_nan ();
2044 if (op2.maybe_isnan ())
2045 op2_no_nan.clear_nan ();
2046 if (!range_op_handler (EQ_EXPR).fold_range (r, type, op1_no_nan,
2047 op2_no_nan, rel))
2048 return false;
2049 // The result is the same as the ordered version when the
2050 // comparison is true or when the operands cannot be NANs.
2051 if (!maybe_isnan (op1, op2) || r == range_true (type))
2052 return true;
2053 else
2055 r = range_true_and_false (type);
2056 return true;
2059 bool op1_range (frange &r, tree type,
2060 const irange &lhs, const frange &op2,
2061 relation_trio = TRIO_VARYING) const final override;
2062 bool op2_range (frange &r, tree type,
2063 const irange &lhs, const frange &op1,
2064 relation_trio rel = TRIO_VARYING) const final override
2066 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
2068 } fop_unordered_equal;
2070 bool
2071 foperator_unordered_equal::op1_range (frange &r, tree type,
2072 const irange &lhs,
2073 const frange &op2,
2074 relation_trio) const
2076 switch (get_bool_state (r, lhs, type))
2078 case BRS_TRUE:
2079 // If it's true, the result is the same as OP2 plus a NAN.
2080 r = op2;
2081 // Add both zeros if there's the possibility of zero equality.
2082 frange_add_zeros (r, type);
2083 // Add the possibility of a NAN.
2084 r.update_nan ();
2085 break;
2087 case BRS_FALSE:
2088 // A false UNORDERED_EQ means both operands are !NAN, so it's
2089 // impossible for op2 to be a NAN.
2090 if (op2.known_isnan ())
2091 r.set_undefined ();
2092 else
2094 // The false side indicates !NAN and not equal. We can at least
2095 // represent !NAN.
2096 r.set_varying (type);
2097 r.clear_nan ();
2099 break;
2101 default:
2102 break;
2104 return true;
2107 class foperator_ltgt : public range_operator
2109 using range_operator::fold_range;
2110 using range_operator::op1_range;
2111 using range_operator::op2_range;
2112 public:
2113 bool fold_range (irange &r, tree type,
2114 const frange &op1, const frange &op2,
2115 relation_trio rel = TRIO_VARYING) const final override
2117 if (op1.known_isnan () || op2.known_isnan ())
2119 r = range_false (type);
2120 return true;
2122 frange op1_no_nan = op1;
2123 frange op2_no_nan = op2;
2124 if (op1.maybe_isnan ())
2125 op1_no_nan.clear_nan ();
2126 if (op2.maybe_isnan ())
2127 op2_no_nan.clear_nan ();
2128 if (!range_op_handler (NE_EXPR).fold_range (r, type, op1_no_nan,
2129 op2_no_nan, rel))
2130 return false;
2131 // The result is the same as the ordered version when the
2132 // comparison is true or when the operands cannot be NANs.
2133 if (!maybe_isnan (op1, op2) || r == range_false (type))
2134 return true;
2135 else
2137 r = range_true_and_false (type);
2138 return true;
2141 bool op1_range (frange &r, tree type,
2142 const irange &lhs, const frange &op2,
2143 relation_trio = TRIO_VARYING) const final override;
2144 bool op2_range (frange &r, tree type,
2145 const irange &lhs, const frange &op1,
2146 relation_trio rel = TRIO_VARYING) const final override
2148 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
2150 } fop_ltgt;
2152 bool
2153 foperator_ltgt::op1_range (frange &r, tree type,
2154 const irange &lhs,
2155 const frange &op2,
2156 relation_trio) const
2158 switch (get_bool_state (r, lhs, type))
2160 case BRS_TRUE:
2161 // A true LTGT means both operands are !NAN, so it's
2162 // impossible for op2 to be a NAN.
2163 if (op2.known_isnan ())
2164 r.set_undefined ();
2165 else
2167 // The true side indicates !NAN and not equal. We can at least
2168 // represent !NAN.
2169 r.set_varying (type);
2170 r.clear_nan ();
2172 break;
2174 case BRS_FALSE:
2175 // If it's false, the result is the same as OP2 plus a NAN.
2176 r = op2;
2177 // Add both zeros if there's the possibility of zero equality.
2178 frange_add_zeros (r, type);
2179 // Add the possibility of a NAN.
2180 r.update_nan ();
2181 break;
2183 default:
2184 break;
2186 return true;
2189 // Final tweaks for float binary op op1_range/op2_range.
2190 // Return TRUE if the operation is performed and a valid range is available.
2192 static bool
2193 float_binary_op_range_finish (bool ret, frange &r, tree type,
2194 const frange &lhs, bool div_op2 = false)
2196 if (!ret)
2197 return false;
2199 // If we get a known NAN from reverse op, it means either that
2200 // the other operand was known NAN (in that case we know nothing),
2201 // or the reverse operation introduced a known NAN.
2202 // Say for lhs = op1 * op2 if lhs is [-0, +0] and op2 is too,
2203 // 0 / 0 is known NAN. Just punt in that case.
2204 // If NANs aren't honored, we get for 0 / 0 UNDEFINED, so punt as well.
2205 // Or if lhs is a known NAN, we also don't know anything.
2206 if (r.known_isnan () || lhs.known_isnan () || r.undefined_p ())
2208 r.set_varying (type);
2209 return true;
2212 // If lhs isn't NAN, then neither operand could be NAN,
2213 // even if the reverse operation does introduce a maybe_nan.
2214 if (!lhs.maybe_isnan ())
2216 r.clear_nan ();
2217 if (div_op2
2218 ? !(real_compare (LE_EXPR, &lhs.lower_bound (), &dconst0)
2219 && real_compare (GE_EXPR, &lhs.upper_bound (), &dconst0))
2220 : !(real_isinf (&lhs.lower_bound ())
2221 || real_isinf (&lhs.upper_bound ())))
2222 // For reverse + or - or * or op1 of /, if result is finite, then
2223 // r must be finite too, as X + INF or X - INF or X * INF or
2224 // INF / X is always +-INF or NAN. For op2 of /, if result is
2225 // non-zero and not NAN, r must be finite, as X / INF is always
2226 // 0 or NAN.
2227 frange_drop_infs (r, type);
2229 // If lhs is a maybe or known NAN, the operand could be
2230 // NAN.
2231 else
2232 r.update_nan ();
2233 return true;
2236 // True if [lb, ub] is [+-0, +-0].
2237 static bool
2238 zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2240 return real_iszero (&lb) && real_iszero (&ub);
2243 // True if +0 or -0 is in [lb, ub] range.
2244 static bool
2245 contains_zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2247 return (real_compare (LE_EXPR, &lb, &dconst0)
2248 && real_compare (GE_EXPR, &ub, &dconst0));
2251 // True if [lb, ub] is [-INF, -INF] or [+INF, +INF].
2252 static bool
2253 singleton_inf_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2255 return real_isinf (&lb) && real_isinf (&ub, real_isneg (&lb));
2258 // Return -1 if binary op result must have sign bit set,
2259 // 1 if binary op result must have sign bit clear,
2260 // 0 otherwise.
2261 // Sign bit of binary op result is exclusive or of the
2262 // operand's sign bits.
2263 static int
2264 signbit_known_p (const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
2265 const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub)
2267 if (real_isneg (&lh_lb) == real_isneg (&lh_ub)
2268 && real_isneg (&rh_lb) == real_isneg (&rh_ub))
2270 if (real_isneg (&lh_lb) == real_isneg (&rh_ub))
2271 return 1;
2272 else
2273 return -1;
2275 return 0;
2278 // Set [lb, ub] to [-0, -0], [-0, +0] or [+0, +0] depending on
2279 // signbit_known.
2280 static void
2281 zero_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2283 ub = lb = dconst0;
2284 if (signbit_known <= 0)
2285 lb = dconstm0;
2286 if (signbit_known < 0)
2287 ub = lb;
2290 // Set [lb, ub] to [-INF, -INF], [-INF, +INF] or [+INF, +INF] depending on
2291 // signbit_known.
2292 static void
2293 inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2295 if (signbit_known > 0)
2296 ub = lb = dconstinf;
2297 else if (signbit_known < 0)
2298 ub = lb = dconstninf;
2299 else
2301 lb = dconstninf;
2302 ub = dconstinf;
2306 // Set [lb, ub] to [-INF, -0], [-INF, +INF] or [+0, +INF] depending on
2307 // signbit_known.
2308 static void
2309 zero_to_inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2311 if (signbit_known > 0)
2313 lb = dconst0;
2314 ub = dconstinf;
2316 else if (signbit_known < 0)
2318 lb = dconstninf;
2319 ub = dconstm0;
2321 else
2323 lb = dconstninf;
2324 ub = dconstinf;
2328 /* Extend the LHS range by 1ulp in each direction. For op1_range
2329 or op2_range of binary operations just computing the inverse
2330 operation on ranges isn't sufficient. Consider e.g.
2331 [1., 1.] = op1 + [1., 1.]. op1's range is not [0., 0.], but
2332 [-0x1.0p-54, 0x1.0p-53] (when not -frounding-math), any value for
2333 which adding 1. to it results in 1. after rounding to nearest.
2334 So, for op1_range/op2_range extend the lhs range by 1ulp (or 0.5ulp)
2335 in each direction. See PR109008 for more details. */
2337 static frange
2338 float_widen_lhs_range (tree type, const frange &lhs)
2340 frange ret = lhs;
2341 if (lhs.known_isnan ())
2342 return ret;
2343 REAL_VALUE_TYPE lb = lhs.lower_bound ();
2344 REAL_VALUE_TYPE ub = lhs.upper_bound ();
2345 if (real_isfinite (&lb))
2347 frange_nextafter (TYPE_MODE (type), lb, dconstninf);
2348 if (real_isinf (&lb))
2350 /* For -DBL_MAX, instead of -Inf use
2351 nexttoward (-DBL_MAX, -LDBL_MAX) in a hypothetical
2352 wider type with the same mantissa precision but larger
2353 exponent range; it is outside of range of double values,
2354 but makes it clear it is just one ulp larger rather than
2355 infinite amount larger. */
2356 lb = dconstm1;
2357 SET_REAL_EXP (&lb, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
2359 if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)))
2361 /* If not -frounding-math nor IBM double double, actually widen
2362 just by 0.5ulp rather than 1ulp. */
2363 REAL_VALUE_TYPE tem;
2364 real_arithmetic (&tem, PLUS_EXPR, &lhs.lower_bound (), &lb);
2365 real_arithmetic (&lb, RDIV_EXPR, &tem, &dconst2);
2368 if (real_isfinite (&ub))
2370 frange_nextafter (TYPE_MODE (type), ub, dconstinf);
2371 if (real_isinf (&ub))
2373 /* For DBL_MAX similarly. */
2374 ub = dconst1;
2375 SET_REAL_EXP (&ub, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
2377 if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)))
2379 /* If not -frounding-math nor IBM double double, actually widen
2380 just by 0.5ulp rather than 1ulp. */
2381 REAL_VALUE_TYPE tem;
2382 real_arithmetic (&tem, PLUS_EXPR, &lhs.upper_bound (), &ub);
2383 real_arithmetic (&ub, RDIV_EXPR, &tem, &dconst2);
2386 /* Temporarily disable -ffinite-math-only, so that frange::set doesn't
2387 reduce the range back to real_min_representable (type) as lower bound
2388 or real_max_representable (type) as upper bound. */
2389 bool save_flag_finite_math_only = flag_finite_math_only;
2390 flag_finite_math_only = false;
2391 ret.set (type, lb, ub, lhs.get_nan_state ());
2392 flag_finite_math_only = save_flag_finite_math_only;
2393 return ret;
2396 bool
2397 operator_plus::op1_range (frange &r, tree type, const frange &lhs,
2398 const frange &op2, relation_trio) const
2400 if (lhs.undefined_p ())
2401 return false;
2402 range_op_handler minus (MINUS_EXPR);
2403 if (!minus)
2404 return false;
2405 frange wlhs = float_widen_lhs_range (type, lhs);
2406 return float_binary_op_range_finish (minus.fold_range (r, type, wlhs, op2),
2407 r, type, wlhs);
2410 bool
2411 operator_plus::op2_range (frange &r, tree type,
2412 const frange &lhs, const frange &op1,
2413 relation_trio) const
2415 return op1_range (r, type, lhs, op1);
2418 void
2419 operator_plus::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
2420 bool &maybe_nan, tree type,
2421 const REAL_VALUE_TYPE &lh_lb,
2422 const REAL_VALUE_TYPE &lh_ub,
2423 const REAL_VALUE_TYPE &rh_lb,
2424 const REAL_VALUE_TYPE &rh_ub,
2425 relation_kind) const
2427 frange_arithmetic (PLUS_EXPR, type, lb, lh_lb, rh_lb, dconstninf);
2428 frange_arithmetic (PLUS_EXPR, type, ub, lh_ub, rh_ub, dconstinf);
2430 // [-INF] + [+INF] = NAN
2431 if (real_isinf (&lh_lb, true) && real_isinf (&rh_ub, false))
2432 maybe_nan = true;
2433 // [+INF] + [-INF] = NAN
2434 else if (real_isinf (&lh_ub, false) && real_isinf (&rh_lb, true))
2435 maybe_nan = true;
2436 else
2437 maybe_nan = false;
2441 bool
2442 operator_minus::op1_range (frange &r, tree type,
2443 const frange &lhs, const frange &op2,
2444 relation_trio) const
2446 if (lhs.undefined_p ())
2447 return false;
2448 frange wlhs = float_widen_lhs_range (type, lhs);
2449 return float_binary_op_range_finish (
2450 range_op_handler (PLUS_EXPR).fold_range (r, type, wlhs, op2),
2451 r, type, wlhs);
2454 bool
2455 operator_minus::op2_range (frange &r, tree type,
2456 const frange &lhs, const frange &op1,
2457 relation_trio) const
2459 if (lhs.undefined_p ())
2460 return false;
2461 frange wlhs = float_widen_lhs_range (type, lhs);
2462 return float_binary_op_range_finish (fold_range (r, type, op1, wlhs),
2463 r, type, wlhs);
2466 void
2467 operator_minus::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
2468 bool &maybe_nan, tree type,
2469 const REAL_VALUE_TYPE &lh_lb,
2470 const REAL_VALUE_TYPE &lh_ub,
2471 const REAL_VALUE_TYPE &rh_lb,
2472 const REAL_VALUE_TYPE &rh_ub,
2473 relation_kind) const
2475 frange_arithmetic (MINUS_EXPR, type, lb, lh_lb, rh_ub, dconstninf);
2476 frange_arithmetic (MINUS_EXPR, type, ub, lh_ub, rh_lb, dconstinf);
2478 // [+INF] - [+INF] = NAN
2479 if (real_isinf (&lh_ub, false) && real_isinf (&rh_ub, false))
2480 maybe_nan = true;
2481 // [-INF] - [-INF] = NAN
2482 else if (real_isinf (&lh_lb, true) && real_isinf (&rh_lb, true))
2483 maybe_nan = true;
2484 else
2485 maybe_nan = false;
2489 // Given CP[0] to CP[3] floating point values rounded to -INF,
2490 // set LB to the smallest of them (treating -0 as smaller to +0).
2491 // Given CP[4] to CP[7] floating point values rounded to +INF,
2492 // set UB to the largest of them (treating -0 as smaller to +0).
2494 static void
2495 find_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
2496 const REAL_VALUE_TYPE (&cp)[8])
2498 lb = cp[0];
2499 ub = cp[4];
2500 for (int i = 1; i < 4; ++i)
2502 if (real_less (&cp[i], &lb)
2503 || (real_iszero (&lb) && real_isnegzero (&cp[i])))
2504 lb = cp[i];
2505 if (real_less (&ub, &cp[i + 4])
2506 || (real_isnegzero (&ub) && real_iszero (&cp[i + 4])))
2507 ub = cp[i + 4];
2512 bool
2513 operator_mult::op1_range (frange &r, tree type,
2514 const frange &lhs, const frange &op2,
2515 relation_trio) const
2517 if (lhs.undefined_p ())
2518 return false;
2519 range_op_handler rdiv (RDIV_EXPR);
2520 if (!rdiv)
2521 return false;
2522 frange wlhs = float_widen_lhs_range (type, lhs);
2523 bool ret = rdiv.fold_range (r, type, wlhs, op2);
2524 if (ret == false)
2525 return false;
2526 if (wlhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
2527 return float_binary_op_range_finish (ret, r, type, wlhs);
2528 const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
2529 const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
2530 const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
2531 const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
2532 if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op2_lb, op2_ub))
2533 || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
2534 && (real_isinf (&op2_lb) || real_isinf (&op2_ub))))
2536 // If both lhs and op2 could be zeros or both could be infinities,
2537 // we don't know anything about op1 except maybe for the sign
2538 // and perhaps if it can be NAN or not.
2539 REAL_VALUE_TYPE lb, ub;
2540 int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
2541 zero_to_inf_range (lb, ub, signbit_known);
2542 r.set (type, lb, ub);
2544 // Otherwise, if op2 is a singleton INF and lhs doesn't include INF,
2545 // or if lhs must be zero and op2 doesn't include zero, it would be
2546 // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF
2547 // range. Those are supersets of UNDEFINED, so let's keep that way.
2548 return float_binary_op_range_finish (ret, r, type, wlhs);
2551 bool
2552 operator_mult::op2_range (frange &r, tree type,
2553 const frange &lhs, const frange &op1,
2554 relation_trio) const
2556 return op1_range (r, type, lhs, op1);
2559 void
2560 operator_mult::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
2561 bool &maybe_nan, tree type,
2562 const REAL_VALUE_TYPE &lh_lb,
2563 const REAL_VALUE_TYPE &lh_ub,
2564 const REAL_VALUE_TYPE &rh_lb,
2565 const REAL_VALUE_TYPE &rh_ub,
2566 relation_kind kind) const
2568 bool is_square
2569 = (kind == VREL_EQ
2570 && real_equal (&lh_lb, &rh_lb)
2571 && real_equal (&lh_ub, &rh_ub)
2572 && real_isneg (&lh_lb) == real_isneg (&rh_lb)
2573 && real_isneg (&lh_ub) == real_isneg (&rh_ub));
2575 maybe_nan = false;
2576 // x * x never produces a new NAN and we only multiply the same
2577 // values, so the 0 * INF problematic cases never appear there.
2578 if (!is_square)
2580 // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN.
2581 if ((zero_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub))
2582 || (zero_p (rh_lb, rh_ub) && singleton_inf_p (lh_lb, lh_ub)))
2584 real_nan (&lb, "", 0, TYPE_MODE (type));
2585 ub = lb;
2586 maybe_nan = true;
2587 return;
2590 // Otherwise, if one range includes zero and the other ends with +-INF,
2591 // it is a maybe NAN.
2592 if ((contains_zero_p (lh_lb, lh_ub)
2593 && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
2594 || (contains_zero_p (rh_lb, rh_ub)
2595 && (real_isinf (&lh_lb) || real_isinf (&lh_ub))))
2597 maybe_nan = true;
2599 int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
2601 // If one of the ranges that includes INF is singleton
2602 // and the other range includes zero, the resulting
2603 // range is INF and NAN, because the 0 * INF boundary
2604 // case will be NAN, but already nextafter (0, 1) * INF
2605 // is INF.
2606 if (singleton_inf_p (lh_lb, lh_ub)
2607 || singleton_inf_p (rh_lb, rh_ub))
2608 return inf_range (lb, ub, signbit_known);
2610 // If one of the multiplicands must be zero, the resulting
2611 // range is +-0 and NAN.
2612 if (zero_p (lh_lb, lh_ub) || zero_p (rh_lb, rh_ub))
2613 return zero_range (lb, ub, signbit_known);
2615 // Otherwise one of the multiplicands could be
2616 // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF]
2617 // or similarly with different signs. 0.0 * DBL_MAX
2618 // is still 0.0, nextafter (0.0, 1.0) * INF is still INF,
2619 // so if the signs are always the same or always different,
2620 // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING.
2621 return zero_to_inf_range (lb, ub, signbit_known);
2625 REAL_VALUE_TYPE cp[8];
2626 // Do a cross-product. At this point none of the multiplications
2627 // should produce a NAN.
2628 frange_arithmetic (MULT_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
2629 frange_arithmetic (MULT_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
2630 if (is_square)
2632 // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub)
2633 // as maximum and -0.0 as minimum if 0.0 is in the range,
2634 // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub).
2635 // -0.0 rather than 0.0 because VREL_EQ doesn't prove that
2636 // x and y are bitwise equal, just that they compare equal.
2637 if (contains_zero_p (lh_lb, lh_ub))
2639 if (real_isneg (&lh_lb) == real_isneg (&lh_ub))
2640 cp[1] = dconst0;
2641 else
2642 cp[1] = dconstm0;
2644 else
2645 cp[1] = cp[0];
2646 cp[2] = cp[0];
2647 cp[5] = cp[4];
2648 cp[6] = cp[4];
2650 else
2652 frange_arithmetic (MULT_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
2653 frange_arithmetic (MULT_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
2654 frange_arithmetic (MULT_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
2655 frange_arithmetic (MULT_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
2657 frange_arithmetic (MULT_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
2658 frange_arithmetic (MULT_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);
2660 find_range (lb, ub, cp);
2664 class foperator_div : public range_operator
2666 using range_operator::op1_range;
2667 using range_operator::op2_range;
2668 public:
2669 virtual bool op1_range (frange &r, tree type,
2670 const frange &lhs,
2671 const frange &op2,
2672 relation_trio = TRIO_VARYING) const final override
2674 if (lhs.undefined_p ())
2675 return false;
2676 frange wlhs = float_widen_lhs_range (type, lhs);
2677 bool ret = range_op_handler (MULT_EXPR).fold_range (r, type, wlhs, op2);
2678 if (!ret)
2679 return ret;
2680 if (wlhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
2681 return float_binary_op_range_finish (ret, r, type, wlhs);
2682 const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
2683 const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
2684 const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
2685 const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
2686 if ((contains_zero_p (lhs_lb, lhs_ub)
2687 && (real_isinf (&op2_lb) || real_isinf (&op2_ub)))
2688 || ((contains_zero_p (op2_lb, op2_ub))
2689 && (real_isinf (&lhs_lb) || real_isinf (&lhs_ub))))
2691 // If both lhs could be zero and op2 infinity or vice versa,
2692 // we don't know anything about op1 except maybe for the sign
2693 // and perhaps if it can be NAN or not.
2694 REAL_VALUE_TYPE lb, ub;
2695 int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
2696 zero_to_inf_range (lb, ub, signbit_known);
2697 r.set (type, lb, ub);
2699 return float_binary_op_range_finish (ret, r, type, wlhs);
2701 virtual bool op2_range (frange &r, tree type,
2702 const frange &lhs,
2703 const frange &op1,
2704 relation_trio = TRIO_VARYING) const final override
2706 if (lhs.undefined_p ())
2707 return false;
2708 frange wlhs = float_widen_lhs_range (type, lhs);
2709 bool ret = fold_range (r, type, op1, wlhs);
2710 if (!ret)
2711 return ret;
2712 if (wlhs.known_isnan () || op1.known_isnan () || op1.undefined_p ())
2713 return float_binary_op_range_finish (ret, r, type, wlhs, true);
2714 const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
2715 const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
2716 const REAL_VALUE_TYPE &op1_lb = op1.lower_bound ();
2717 const REAL_VALUE_TYPE &op1_ub = op1.upper_bound ();
2718 if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op1_lb, op1_ub))
2719 || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
2720 && (real_isinf (&op1_lb) || real_isinf (&op1_ub))))
2722 // If both lhs and op1 could be zeros or both could be infinities,
2723 // we don't know anything about op2 except maybe for the sign
2724 // and perhaps if it can be NAN or not.
2725 REAL_VALUE_TYPE lb, ub;
2726 int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op1_lb, op1_ub);
2727 zero_to_inf_range (lb, ub, signbit_known);
2728 r.set (type, lb, ub);
2730 return float_binary_op_range_finish (ret, r, type, wlhs, true);
2732 private:
2733 void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan,
2734 tree type,
2735 const REAL_VALUE_TYPE &lh_lb,
2736 const REAL_VALUE_TYPE &lh_ub,
2737 const REAL_VALUE_TYPE &rh_lb,
2738 const REAL_VALUE_TYPE &rh_ub,
2739 relation_kind) const final override
2741 // +-0.0 / +-0.0 or +-INF / +-INF is a known NAN.
2742 if ((zero_p (lh_lb, lh_ub) && zero_p (rh_lb, rh_ub))
2743 || (singleton_inf_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub)))
2745 real_nan (&lb, "", 0, TYPE_MODE (type));
2746 ub = lb;
2747 maybe_nan = true;
2748 return;
2751 // If +-0.0 is in both ranges, it is a maybe NAN.
2752 if (contains_zero_p (lh_lb, lh_ub) && contains_zero_p (rh_lb, rh_ub))
2753 maybe_nan = true;
2754 // If +-INF is in both ranges, it is a maybe NAN.
2755 else if ((real_isinf (&lh_lb) || real_isinf (&lh_ub))
2756 && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
2757 maybe_nan = true;
2758 else
2759 maybe_nan = false;
2761 int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
2763 // If dividend must be zero, the range is just +-0
2764 // (including if the divisor is +-INF).
2765 // If divisor must be +-INF, the range is just +-0
2766 // (including if the dividend is zero).
2767 if (zero_p (lh_lb, lh_ub) || singleton_inf_p (rh_lb, rh_ub))
2768 return zero_range (lb, ub, signbit_known);
2770 // If divisor must be zero, the range is just +-INF
2771 // (including if the dividend is +-INF).
2772 // If dividend must be +-INF, the range is just +-INF
2773 // (including if the dividend is zero).
2774 if (zero_p (rh_lb, rh_ub) || singleton_inf_p (lh_lb, lh_ub))
2775 return inf_range (lb, ub, signbit_known);
2777 // Otherwise if both operands may be zero, divisor could be
2778 // nextafter(0.0, +-1.0) and dividend +-0.0
2779 // in which case result is going to INF or vice versa and
2780 // result +0.0. So, all we can say for that case is if the
2781 // signs of divisor and dividend are always the same we have
2782 // [+0.0, +INF], if they are always different we have
2783 // [-INF, -0.0]. If they vary, VARYING.
2784 // If both may be +-INF, divisor could be INF and dividend FLT_MAX,
2785 // in which case result is going to INF or vice versa and
2786 // result +0.0. So, all we can say for that case is if the
2787 // signs of divisor and dividend are always the same we have
2788 // [+0.0, +INF], if they are always different we have
2789 // [-INF, -0.0]. If they vary, VARYING.
2790 if (maybe_nan)
2791 return zero_to_inf_range (lb, ub, signbit_known);
2793 REAL_VALUE_TYPE cp[8];
2794 // Do a cross-division. At this point none of the divisions should
2795 // produce a NAN.
2796 frange_arithmetic (RDIV_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
2797 frange_arithmetic (RDIV_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
2798 frange_arithmetic (RDIV_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
2799 frange_arithmetic (RDIV_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
2800 frange_arithmetic (RDIV_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
2801 frange_arithmetic (RDIV_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
2802 frange_arithmetic (RDIV_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
2803 frange_arithmetic (RDIV_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);
2805 find_range (lb, ub, cp);
2807 // If divisor may be zero (but is not known to be only zero),
2808 // and dividend can't be zero, the range can go up to -INF or +INF
2809 // depending on the signs.
2810 if (contains_zero_p (rh_lb, rh_ub))
2812 if (signbit_known <= 0)
2813 real_inf (&lb, true);
2814 if (signbit_known >= 0)
2815 real_inf (&ub, false);
2818 } fop_div;
2821 // Initialize any float operators to the primary table
2823 void
2824 range_op_table::initialize_float_ops ()
2826 set (UNLE_EXPR, fop_unordered_le);
2827 set (UNLT_EXPR, fop_unordered_lt);
2828 set (UNGE_EXPR, fop_unordered_ge);
2829 set (UNGT_EXPR, fop_unordered_gt);
2830 set (UNEQ_EXPR, fop_unordered_equal);
2831 set (ORDERED_EXPR, fop_ordered);
2832 set (UNORDERED_EXPR, fop_unordered);
2833 set (LTGT_EXPR, fop_ltgt);
2834 set (RDIV_EXPR, fop_div);
2837 #if CHECKING_P
2838 #include "selftest.h"
2840 namespace selftest
2843 // Build an frange from string endpoints.
2845 static inline frange
2846 frange_float (const char *lb, const char *ub, tree type = float_type_node)
2848 REAL_VALUE_TYPE min, max;
2849 gcc_assert (real_from_string (&min, lb) == 0);
2850 gcc_assert (real_from_string (&max, ub) == 0);
2851 return frange (type, min, max);
2854 void
2855 range_op_float_tests ()
2857 frange r, r0, r1;
2858 frange trange (float_type_node);
2860 // negate([-5, +10]) => [-10, 5]
2861 r0 = frange_float ("-5", "10");
2862 range_op_handler (NEGATE_EXPR).fold_range (r, float_type_node, r0, trange);
2863 ASSERT_EQ (r, frange_float ("-10", "5"));
2865 // negate([0, 1] -NAN) => [-1, -0] +NAN
2866 r0 = frange_float ("0", "1");
2867 r0.update_nan (true);
2868 range_op_handler (NEGATE_EXPR).fold_range (r, float_type_node, r0, trange);
2869 r1 = frange_float ("-1", "-0");
2870 r1.update_nan (false);
2871 ASSERT_EQ (r, r1);
2873 // [-INF,+INF] + [-INF,+INF] could be a NAN.
2874 range_op_handler plus (PLUS_EXPR);
2875 r0.set_varying (float_type_node);
2876 r1.set_varying (float_type_node);
2877 r0.clear_nan ();
2878 r1.clear_nan ();
2879 plus.fold_range (r, float_type_node, r0, r1);
2880 if (HONOR_NANS (float_type_node))
2881 ASSERT_TRUE (r.maybe_isnan ());
2884 } // namespace selftest
2886 #endif // CHECKING_P