middle-end/110495 - avoid associating constants with (VL) vectors
[official-gcc.git] / gcc / range-op-float.cc
blob238a3262d2be77cb9bbca4844929b4d79dee15f6
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 frange &lhs ATTRIBUTE_UNUSED) const
249 return VREL_VARYING;
252 // Return TRUE if OP1 and OP2 may be a NAN.
254 static inline bool
255 maybe_isnan (const frange &op1, const frange &op2)
257 return op1.maybe_isnan () || op2.maybe_isnan ();
260 // Floating version of relop_early_resolve that takes into account NAN
261 // and -ffinite-math-only.
263 static inline bool
264 frelop_early_resolve (irange &r, tree type,
265 const frange &op1, const frange &op2,
266 relation_trio rel, relation_kind my_rel)
268 // If either operand is undefined, return VARYING.
269 if (empty_range_varying (r, type, op1, op2))
270 return true;
272 // We can fold relations from the oracle when we know both operands
273 // are free of NANs, or when -ffinite-math-only.
274 return (!maybe_isnan (op1, op2)
275 && relop_early_resolve (r, type, op1, op2, rel, my_rel));
278 // Set VALUE to its next real value, or INF if the operation overflows.
280 void
281 frange_nextafter (enum machine_mode mode,
282 REAL_VALUE_TYPE &value,
283 const REAL_VALUE_TYPE &inf)
285 if (MODE_COMPOSITE_P (mode)
286 && (real_isdenormal (&value, mode) || real_iszero (&value)))
288 // IBM extended denormals only have DFmode precision.
289 REAL_VALUE_TYPE tmp, tmp2;
290 real_convert (&tmp2, DFmode, &value);
291 real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2, &inf);
292 real_convert (&value, mode, &tmp);
294 else
296 REAL_VALUE_TYPE tmp;
297 real_nextafter (&tmp, REAL_MODE_FORMAT (mode), &value, &inf);
298 value = tmp;
302 // Like real_arithmetic, but round the result to INF if the operation
303 // produced inexact results.
305 // ?? There is still one problematic case, i387. With
306 // -fexcess-precision=standard we perform most SF/DFmode arithmetic in
307 // XFmode (long_double_type_node), so that case is OK. But without
308 // -mfpmath=sse, all the SF/DFmode computations are in XFmode
309 // precision (64-bit mantissa) and only occasionally rounded to
310 // SF/DFmode (when storing into memory from the 387 stack). Maybe
311 // this is ok as well though it is just occasionally more precise. ??
313 void
314 frange_arithmetic (enum tree_code code, tree type,
315 REAL_VALUE_TYPE &result,
316 const REAL_VALUE_TYPE &op1,
317 const REAL_VALUE_TYPE &op2,
318 const REAL_VALUE_TYPE &inf)
320 REAL_VALUE_TYPE value;
321 enum machine_mode mode = TYPE_MODE (type);
322 bool mode_composite = MODE_COMPOSITE_P (mode);
324 bool inexact = real_arithmetic (&value, code, &op1, &op2);
325 real_convert (&result, mode, &value);
327 // Be extra careful if there may be discrepancies between the
328 // compile and runtime results.
329 bool round = false;
330 if (mode_composite)
331 round = true;
332 else
334 bool low = real_isneg (&inf);
335 round = (low ? !real_less (&result, &value)
336 : !real_less (&value, &result));
337 if (real_isinf (&result, !low)
338 && !real_isinf (&value)
339 && !flag_rounding_math)
341 // Use just [+INF, +INF] rather than [MAX, +INF]
342 // even if value is larger than MAX and rounds to
343 // nearest to +INF. Similarly just [-INF, -INF]
344 // rather than [-INF, +MAX] even if value is smaller
345 // than -MAX and rounds to nearest to -INF.
346 // Unless INEXACT is true, in that case we need some
347 // extra buffer.
348 if (!inexact)
349 round = false;
350 else
352 REAL_VALUE_TYPE tmp = result, tmp2;
353 frange_nextafter (mode, tmp, inf);
354 // TMP is at this point the maximum representable
355 // number.
356 real_arithmetic (&tmp2, MINUS_EXPR, &value, &tmp);
357 if (real_isneg (&tmp2) != low
358 && (REAL_EXP (&tmp2) - REAL_EXP (&tmp)
359 >= 2 - REAL_MODE_FORMAT (mode)->p))
360 round = false;
364 if (round && (inexact || !real_identical (&result, &value)))
366 if (mode_composite
367 && (real_isdenormal (&result, mode) || real_iszero (&result)))
369 // IBM extended denormals only have DFmode precision.
370 REAL_VALUE_TYPE tmp, tmp2;
371 real_convert (&tmp2, DFmode, &value);
372 real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2, &inf);
373 real_convert (&result, mode, &tmp);
375 else
376 frange_nextafter (mode, result, inf);
378 if (mode_composite)
379 switch (code)
381 case PLUS_EXPR:
382 case MINUS_EXPR:
383 // ibm-ldouble-format documents 1ulp for + and -.
384 frange_nextafter (mode, result, inf);
385 break;
386 case MULT_EXPR:
387 // ibm-ldouble-format documents 2ulps for *.
388 frange_nextafter (mode, result, inf);
389 frange_nextafter (mode, result, inf);
390 break;
391 case RDIV_EXPR:
392 // ibm-ldouble-format documents 3ulps for /.
393 frange_nextafter (mode, result, inf);
394 frange_nextafter (mode, result, inf);
395 frange_nextafter (mode, result, inf);
396 break;
397 default:
398 break;
402 // Crop R to [-INF, MAX] where MAX is the maximum representable number
403 // for TYPE.
405 static inline void
406 frange_drop_inf (frange &r, tree type)
408 REAL_VALUE_TYPE max = real_max_representable (type);
409 frange tmp (type, r.lower_bound (), max);
410 r.intersect (tmp);
413 // Crop R to [MIN, +INF] where MIN is the minimum representable number
414 // for TYPE.
416 static inline void
417 frange_drop_ninf (frange &r, tree type)
419 REAL_VALUE_TYPE min = real_min_representable (type);
420 frange tmp (type, min, r.upper_bound ());
421 r.intersect (tmp);
424 // Crop R to [MIN, MAX] where MAX is the maximum representable number
425 // for TYPE and MIN the minimum representable number for TYPE.
427 static inline void
428 frange_drop_infs (frange &r, tree type)
430 REAL_VALUE_TYPE max = real_max_representable (type);
431 REAL_VALUE_TYPE min = real_min_representable (type);
432 frange tmp (type, min, max);
433 r.intersect (tmp);
436 // If zero is in R, make sure both -0.0 and +0.0 are in the range.
438 static inline void
439 frange_add_zeros (frange &r, tree type)
441 if (r.undefined_p () || r.known_isnan ())
442 return;
444 if (HONOR_SIGNED_ZEROS (type)
445 && (real_iszero (&r.lower_bound ()) || real_iszero (&r.upper_bound ())))
447 frange zero;
448 zero.set_zero (type);
449 r.union_ (zero);
453 // Build a range that is <= VAL and store it in R. Return TRUE if
454 // further changes may be needed for R, or FALSE if R is in its final
455 // form.
457 static bool
458 build_le (frange &r, tree type, const frange &val)
460 gcc_checking_assert (!val.known_isnan ());
462 REAL_VALUE_TYPE ninf = frange_val_min (type);
463 r.set (type, ninf, val.upper_bound ());
465 // Add both zeros if there's the possibility of zero equality.
466 frange_add_zeros (r, type);
468 return true;
471 // Build a range that is < VAL and store it in R. Return TRUE if
472 // further changes may be needed for R, or FALSE if R is in its final
473 // form.
475 static bool
476 build_lt (frange &r, tree type, const frange &val)
478 gcc_checking_assert (!val.known_isnan ());
480 // < -INF is outside the range.
481 if (real_isinf (&val.upper_bound (), 1))
483 if (HONOR_NANS (type))
484 r.set_nan (type);
485 else
486 r.set_undefined ();
487 return false;
490 REAL_VALUE_TYPE ninf = frange_val_min (type);
491 REAL_VALUE_TYPE prev = val.upper_bound ();
492 machine_mode mode = TYPE_MODE (type);
493 // Default to the conservatively correct closed ranges for
494 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
495 // !HONOR_INFINITIES, nextafter will yield -INF, but frange::set()
496 // will crop the range appropriately.
497 if (!MODE_COMPOSITE_P (mode))
498 frange_nextafter (mode, prev, ninf);
499 r.set (type, ninf, prev);
500 return true;
503 // Build a range that is >= VAL and store it in R. Return TRUE if
504 // further changes may be needed for R, or FALSE if R is in its final
505 // form.
507 static bool
508 build_ge (frange &r, tree type, const frange &val)
510 gcc_checking_assert (!val.known_isnan ());
512 REAL_VALUE_TYPE inf = frange_val_max (type);
513 r.set (type, val.lower_bound (), inf);
515 // Add both zeros if there's the possibility of zero equality.
516 frange_add_zeros (r, type);
518 return true;
521 // Build a range that is > VAL and store it in R. Return TRUE if
522 // further changes may be needed for R, or FALSE if R is in its final
523 // form.
525 static bool
526 build_gt (frange &r, tree type, const frange &val)
528 gcc_checking_assert (!val.known_isnan ());
530 // > +INF is outside the range.
531 if (real_isinf (&val.lower_bound (), 0))
533 if (HONOR_NANS (type))
534 r.set_nan (type);
535 else
536 r.set_undefined ();
537 return false;
540 REAL_VALUE_TYPE inf = frange_val_max (type);
541 REAL_VALUE_TYPE next = val.lower_bound ();
542 machine_mode mode = TYPE_MODE (type);
543 // Default to the conservatively correct closed ranges for
544 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
545 // !HONOR_INFINITIES, nextafter will yield +INF, but frange::set()
546 // will crop the range appropriately.
547 if (!MODE_COMPOSITE_P (mode))
548 frange_nextafter (mode, next, inf);
549 r.set (type, next, inf);
550 return true;
554 bool
555 operator_identity::fold_range (frange &r, tree, const frange &op1,
556 const frange &, relation_trio) const
558 r = op1;
559 return true;
562 bool
563 operator_identity::op1_range (frange &r, tree, const frange &lhs,
564 const frange &, relation_trio) const
566 r = lhs;
567 return true;
570 bool
571 operator_cst::fold_range (frange &r, tree, const frange &op1,
572 const frange &, relation_trio) const
574 r = op1;
575 return true;
578 bool
579 operator_equal::op2_range (frange &r, tree type,
580 const irange &lhs, const frange &op1,
581 relation_trio rel) const
583 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
586 bool
587 operator_equal::fold_range (irange &r, tree type,
588 const frange &op1, const frange &op2,
589 relation_trio rel) const
591 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_EQ))
592 return true;
594 if (op1.known_isnan () || op2.known_isnan ())
595 r = range_false (type);
596 // We can be sure the values are always equal or not if both ranges
597 // consist of a single value, and then compare them.
598 else if (op1.singleton_p () && op2.singleton_p ())
600 if (op1 == op2)
601 r = range_true (type);
602 // If one operand is -0.0 and other 0.0, they are still equal.
603 else if (real_iszero (&op1.lower_bound ())
604 && real_iszero (&op2.lower_bound ()))
605 r = range_true (type);
606 else
607 r = range_false (type);
609 else if (real_iszero (&op1.lower_bound ())
610 && real_iszero (&op1.upper_bound ())
611 && real_iszero (&op2.lower_bound ())
612 && real_iszero (&op2.upper_bound ())
613 && !maybe_isnan (op1, op2))
614 // [-0.0, 0.0] == [-0.0, 0.0] or similar.
615 r = range_true (type);
616 else
618 // If ranges do not intersect, we know the range is not equal,
619 // otherwise we don't know anything for sure.
620 frange tmp = op1;
621 tmp.intersect (op2);
622 if (tmp.undefined_p ())
624 // If one range is [whatever, -0.0] and another
625 // [0.0, whatever2], we don't know anything either,
626 // because -0.0 == 0.0.
627 if ((real_iszero (&op1.upper_bound ())
628 && real_iszero (&op2.lower_bound ()))
629 || (real_iszero (&op1.lower_bound ())
630 && real_iszero (&op2.upper_bound ())))
631 r = range_true_and_false (type);
632 else
633 r = range_false (type);
635 else
636 r = range_true_and_false (type);
638 return true;
641 bool
642 operator_equal::op1_range (frange &r, tree type,
643 const irange &lhs,
644 const frange &op2,
645 relation_trio trio) const
647 relation_kind rel = trio.op1_op2 ();
648 switch (get_bool_state (r, lhs, type))
650 case BRS_TRUE:
651 // The TRUE side of x == NAN is unreachable.
652 if (op2.known_isnan ())
653 r.set_undefined ();
654 else
656 // If it's true, the result is the same as OP2.
657 r = op2;
658 // Add both zeros if there's the possibility of zero equality.
659 frange_add_zeros (r, type);
660 // The TRUE side of op1 == op2 implies op1 is !NAN.
661 r.clear_nan ();
663 break;
665 case BRS_FALSE:
666 // The FALSE side of op1 == op1 implies op1 is a NAN.
667 if (rel == VREL_EQ)
668 r.set_nan (type);
669 // On the FALSE side of x == NAN, we know nothing about x.
670 else if (op2.known_isnan ())
671 r.set_varying (type);
672 // If the result is false, the only time we know anything is
673 // if OP2 is a constant.
674 else if (op2.singleton_p ()
675 || (!op2.maybe_isnan () && op2.zero_p ()))
677 REAL_VALUE_TYPE tmp = op2.lower_bound ();
678 r.set (type, tmp, tmp, VR_ANTI_RANGE);
680 else
681 r.set_varying (type);
682 break;
684 default:
685 break;
687 return true;
690 bool
691 operator_not_equal::fold_range (irange &r, tree type,
692 const frange &op1, const frange &op2,
693 relation_trio rel) const
695 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_NE))
696 return true;
698 // x != NAN is always TRUE.
699 if (op1.known_isnan () || op2.known_isnan ())
700 r = range_true (type);
701 // We can be sure the values are always equal or not if both ranges
702 // consist of a single value, and then compare them.
703 else if (op1.singleton_p () && op2.singleton_p ())
705 if (op1 == op2)
706 r = range_false (type);
707 // If one operand is -0.0 and other 0.0, they are still equal.
708 else if (real_iszero (&op1.lower_bound ())
709 && real_iszero (&op2.lower_bound ()))
710 r = range_false (type);
711 else
712 r = range_true (type);
714 else if (real_iszero (&op1.lower_bound ())
715 && real_iszero (&op1.upper_bound ())
716 && real_iszero (&op2.lower_bound ())
717 && real_iszero (&op2.upper_bound ())
718 && !maybe_isnan (op1, op2))
719 // [-0.0, 0.0] != [-0.0, 0.0] or similar.
720 r = range_false (type);
721 else
723 // If ranges do not intersect, we know the range is not equal,
724 // otherwise we don't know anything for sure.
725 frange tmp = op1;
726 tmp.intersect (op2);
727 if (tmp.undefined_p ())
729 // If one range is [whatever, -0.0] and another
730 // [0.0, whatever2], we don't know anything either,
731 // because -0.0 == 0.0.
732 if ((real_iszero (&op1.upper_bound ())
733 && real_iszero (&op2.lower_bound ()))
734 || (real_iszero (&op1.lower_bound ())
735 && real_iszero (&op2.upper_bound ())))
736 r = range_true_and_false (type);
737 else
738 r = range_true (type);
740 else
741 r = range_true_and_false (type);
743 return true;
746 bool
747 operator_not_equal::op1_range (frange &r, tree type,
748 const irange &lhs,
749 const frange &op2,
750 relation_trio trio) const
752 relation_kind rel = trio.op1_op2 ();
753 switch (get_bool_state (r, lhs, type))
755 case BRS_TRUE:
756 // If the result is true, the only time we know anything is if
757 // OP2 is a constant.
758 if (op2.singleton_p ())
760 // This is correct even if op1 is NAN, because the following
761 // range would be ~[tmp, tmp] with the NAN property set to
762 // maybe (VARYING).
763 REAL_VALUE_TYPE tmp = op2.lower_bound ();
764 r.set (type, tmp, tmp, VR_ANTI_RANGE);
766 // The TRUE side of op1 != op1 implies op1 is NAN.
767 else if (rel == VREL_EQ)
768 r.set_nan (type);
769 else
770 r.set_varying (type);
771 break;
773 case BRS_FALSE:
774 // The FALSE side of x != NAN is impossible.
775 if (op2.known_isnan ())
776 r.set_undefined ();
777 else
779 // If it's false, the result is the same as OP2.
780 r = op2;
781 // Add both zeros if there's the possibility of zero equality.
782 frange_add_zeros (r, type);
783 // The FALSE side of op1 != op2 implies op1 is !NAN.
784 r.clear_nan ();
786 break;
788 default:
789 break;
791 return true;
794 bool
795 operator_lt::fold_range (irange &r, tree type,
796 const frange &op1, const frange &op2,
797 relation_trio rel) const
799 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_LT))
800 return true;
802 if (op1.known_isnan ()
803 || op2.known_isnan ()
804 || !real_less (&op1.lower_bound (), &op2.upper_bound ()))
805 r = range_false (type);
806 else if (!maybe_isnan (op1, op2)
807 && real_less (&op1.upper_bound (), &op2.lower_bound ()))
808 r = range_true (type);
809 else
810 r = range_true_and_false (type);
811 return true;
814 bool
815 operator_lt::op1_range (frange &r,
816 tree type,
817 const irange &lhs,
818 const frange &op2,
819 relation_trio) const
821 switch (get_bool_state (r, lhs, type))
823 case BRS_TRUE:
824 // The TRUE side of x < NAN is unreachable.
825 if (op2.known_isnan ())
826 r.set_undefined ();
827 else if (op2.undefined_p ())
828 return false;
829 else if (build_lt (r, type, op2))
831 r.clear_nan ();
832 // x < y implies x is not +INF.
833 frange_drop_inf (r, type);
835 break;
837 case BRS_FALSE:
838 // On the FALSE side of x < NAN, we know nothing about x.
839 if (op2.known_isnan () || op2.maybe_isnan ())
840 r.set_varying (type);
841 else
842 build_ge (r, type, op2);
843 break;
845 default:
846 break;
848 return true;
851 bool
852 operator_lt::op2_range (frange &r,
853 tree type,
854 const irange &lhs,
855 const frange &op1,
856 relation_trio) const
858 switch (get_bool_state (r, lhs, type))
860 case BRS_TRUE:
861 // The TRUE side of NAN < x is unreachable.
862 if (op1.known_isnan ())
863 r.set_undefined ();
864 else if (op1.undefined_p ())
865 return false;
866 else if (build_gt (r, type, op1))
868 r.clear_nan ();
869 // x < y implies y is not -INF.
870 frange_drop_ninf (r, type);
872 break;
874 case BRS_FALSE:
875 // On the FALSE side of NAN < x, we know nothing about x.
876 if (op1.known_isnan () || op1.maybe_isnan ())
877 r.set_varying (type);
878 else
879 build_le (r, type, op1);
880 break;
882 default:
883 break;
885 return true;
888 bool
889 operator_le::fold_range (irange &r, tree type,
890 const frange &op1, const frange &op2,
891 relation_trio rel) const
893 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_LE))
894 return true;
896 if (op1.known_isnan ()
897 || op2.known_isnan ()
898 || !real_compare (LE_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
899 r = range_false (type);
900 else if (!maybe_isnan (op1, op2)
901 && real_compare (LE_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
902 r = range_true (type);
903 else
904 r = range_true_and_false (type);
905 return true;
908 bool
909 operator_le::op1_range (frange &r,
910 tree type,
911 const irange &lhs,
912 const frange &op2,
913 relation_trio) const
915 switch (get_bool_state (r, lhs, type))
917 case BRS_TRUE:
918 // The TRUE side of x <= NAN is unreachable.
919 if (op2.known_isnan ())
920 r.set_undefined ();
921 else if (op2.undefined_p ())
922 return false;
923 else if (build_le (r, type, op2))
924 r.clear_nan ();
925 break;
927 case BRS_FALSE:
928 // On the FALSE side of x <= NAN, we know nothing about x.
929 if (op2.known_isnan () || op2.maybe_isnan ())
930 r.set_varying (type);
931 else
932 build_gt (r, type, op2);
933 break;
935 default:
936 break;
938 return true;
941 bool
942 operator_le::op2_range (frange &r,
943 tree type,
944 const irange &lhs,
945 const frange &op1,
946 relation_trio) const
948 switch (get_bool_state (r, lhs, type))
950 case BRS_TRUE:
951 // The TRUE side of NAN <= x is unreachable.
952 if (op1.known_isnan ())
953 r.set_undefined ();
954 else if (op1.undefined_p ())
955 return false;
956 else if (build_ge (r, type, op1))
957 r.clear_nan ();
958 break;
960 case BRS_FALSE:
961 // On the FALSE side of NAN <= x, we know nothing about x.
962 if (op1.known_isnan () || op1.maybe_isnan ())
963 r.set_varying (type);
964 else if (op1.undefined_p ())
965 return false;
966 else
967 build_lt (r, type, op1);
968 break;
970 default:
971 break;
973 return true;
976 bool
977 operator_gt::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_GT))
982 return true;
984 if (op1.known_isnan ()
985 || op2.known_isnan ()
986 || !real_compare (GT_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
987 r = range_false (type);
988 else if (!maybe_isnan (op1, op2)
989 && real_compare (GT_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
990 r = range_true (type);
991 else
992 r = range_true_and_false (type);
993 return true;
996 bool
997 operator_gt::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_gt (r, type, op2))
1013 r.clear_nan ();
1014 // x > y implies x is not -INF.
1015 frange_drop_ninf (r, type);
1017 break;
1019 case BRS_FALSE:
1020 // On the FALSE side of x > NAN, we know nothing about x.
1021 if (op2.known_isnan () || op2.maybe_isnan ())
1022 r.set_varying (type);
1023 else if (op2.undefined_p ())
1024 return false;
1025 else
1026 build_le (r, type, op2);
1027 break;
1029 default:
1030 break;
1032 return true;
1035 bool
1036 operator_gt::op2_range (frange &r,
1037 tree type,
1038 const irange &lhs,
1039 const frange &op1,
1040 relation_trio) const
1042 switch (get_bool_state (r, lhs, type))
1044 case BRS_TRUE:
1045 // The TRUE side of NAN > x is unreachable.
1046 if (op1.known_isnan ())
1047 r.set_undefined ();
1048 else if (op1.undefined_p ())
1049 return false;
1050 else if (build_lt (r, type, op1))
1052 r.clear_nan ();
1053 // x > y implies y is not +INF.
1054 frange_drop_inf (r, type);
1056 break;
1058 case BRS_FALSE:
1059 // On The FALSE side of NAN > x, we know nothing about x.
1060 if (op1.known_isnan () || op1.maybe_isnan ())
1061 r.set_varying (type);
1062 else if (op1.undefined_p ())
1063 return false;
1064 else
1065 build_ge (r, type, op1);
1066 break;
1068 default:
1069 break;
1071 return true;
1074 bool
1075 operator_ge::fold_range (irange &r, tree type,
1076 const frange &op1, const frange &op2,
1077 relation_trio rel) const
1079 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_GE))
1080 return true;
1082 if (op1.known_isnan ()
1083 || op2.known_isnan ()
1084 || !real_compare (GE_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
1085 r = range_false (type);
1086 else if (!maybe_isnan (op1, op2)
1087 && real_compare (GE_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
1088 r = range_true (type);
1089 else
1090 r = range_true_and_false (type);
1091 return true;
1094 bool
1095 operator_ge::op1_range (frange &r,
1096 tree type,
1097 const irange &lhs,
1098 const frange &op2,
1099 relation_trio) const
1101 switch (get_bool_state (r, lhs, type))
1103 case BRS_TRUE:
1104 // The TRUE side of x >= NAN is unreachable.
1105 if (op2.known_isnan ())
1106 r.set_undefined ();
1107 else if (op2.undefined_p ())
1108 return false;
1109 else if (build_ge (r, type, op2))
1110 r.clear_nan ();
1111 break;
1113 case BRS_FALSE:
1114 // On the FALSE side of x >= NAN, we know nothing about x.
1115 if (op2.known_isnan () || op2.maybe_isnan ())
1116 r.set_varying (type);
1117 else if (op2.undefined_p ())
1118 return false;
1119 else
1120 build_lt (r, type, op2);
1121 break;
1123 default:
1124 break;
1126 return true;
1129 bool
1130 operator_ge::op2_range (frange &r, tree type,
1131 const irange &lhs,
1132 const frange &op1,
1133 relation_trio) const
1135 switch (get_bool_state (r, lhs, type))
1137 case BRS_TRUE:
1138 // The TRUE side of NAN >= x is unreachable.
1139 if (op1.known_isnan ())
1140 r.set_undefined ();
1141 else if (op1.undefined_p ())
1142 return false;
1143 else if (build_le (r, type, op1))
1144 r.clear_nan ();
1145 break;
1147 case BRS_FALSE:
1148 // On the FALSE side of NAN >= x, we know nothing about x.
1149 if (op1.known_isnan () || op1.maybe_isnan ())
1150 r.set_varying (type);
1151 else if (op1.undefined_p ())
1152 return false;
1153 else
1154 build_gt (r, type, op1);
1155 break;
1157 default:
1158 break;
1160 return true;
1163 // UNORDERED_EXPR comparison.
1165 class foperator_unordered : public range_operator
1167 using range_operator::fold_range;
1168 using range_operator::op1_range;
1169 using range_operator::op2_range;
1170 public:
1171 bool fold_range (irange &r, tree type,
1172 const frange &op1, const frange &op2,
1173 relation_trio = TRIO_VARYING) const final override;
1174 bool op1_range (frange &r, tree type,
1175 const irange &lhs, const frange &op2,
1176 relation_trio = TRIO_VARYING) const final override;
1177 bool op2_range (frange &r, tree type,
1178 const irange &lhs, const frange &op1,
1179 relation_trio rel = TRIO_VARYING) const final override
1181 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
1183 } fop_unordered;
1185 bool
1186 foperator_unordered::fold_range (irange &r, tree type,
1187 const frange &op1, const frange &op2,
1188 relation_trio) const
1190 // UNORDERED is TRUE if either operand is a NAN.
1191 if (op1.known_isnan () || op2.known_isnan ())
1192 r = range_true (type);
1193 // UNORDERED is FALSE if neither operand is a NAN.
1194 else if (!op1.maybe_isnan () && !op2.maybe_isnan ())
1195 r = range_false (type);
1196 else
1197 r = range_true_and_false (type);
1198 return true;
1201 bool
1202 foperator_unordered::op1_range (frange &r, tree type,
1203 const irange &lhs,
1204 const frange &op2,
1205 relation_trio trio) const
1207 relation_kind rel = trio.op1_op2 ();
1208 switch (get_bool_state (r, lhs, type))
1210 case BRS_TRUE:
1211 // Since at least one operand must be NAN, if one of them is
1212 // not, the other must be.
1213 if (rel == VREL_EQ || !op2.maybe_isnan ())
1214 r.set_nan (type);
1215 else
1216 r.set_varying (type);
1217 break;
1219 case BRS_FALSE:
1220 // A false UNORDERED means both operands are !NAN, so it's
1221 // impossible for op2 to be a NAN.
1222 if (op2.known_isnan ())
1223 r.set_undefined ();
1224 else
1226 r.set_varying (type);
1227 r.clear_nan ();
1229 break;
1231 default:
1232 break;
1234 return true;
1237 // ORDERED_EXPR comparison.
1239 class foperator_ordered : public range_operator
1241 using range_operator::fold_range;
1242 using range_operator::op1_range;
1243 using range_operator::op2_range;
1244 public:
1245 bool fold_range (irange &r, tree type,
1246 const frange &op1, const frange &op2,
1247 relation_trio = TRIO_VARYING) const final override;
1248 bool op1_range (frange &r, tree type,
1249 const irange &lhs, const frange &op2,
1250 relation_trio = TRIO_VARYING) const final override;
1251 bool op2_range (frange &r, tree type,
1252 const irange &lhs, const frange &op1,
1253 relation_trio rel = TRIO_VARYING) const final override
1255 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
1257 } fop_ordered;
1259 bool
1260 foperator_ordered::fold_range (irange &r, tree type,
1261 const frange &op1, const frange &op2,
1262 relation_trio) const
1264 if (op1.known_isnan () || op2.known_isnan ())
1265 r = range_false (type);
1266 else if (!op1.maybe_isnan () && !op2.maybe_isnan ())
1267 r = range_true (type);
1268 else
1269 r = range_true_and_false (type);
1270 return true;
1273 bool
1274 foperator_ordered::op1_range (frange &r, tree type,
1275 const irange &lhs,
1276 const frange &op2,
1277 relation_trio trio) const
1279 relation_kind rel = trio.op1_op2 ();
1280 switch (get_bool_state (r, lhs, type))
1282 case BRS_TRUE:
1283 // The TRUE side of ORDERED means both operands are !NAN, so
1284 // it's impossible for op2 to be a NAN.
1285 if (op2.known_isnan ())
1286 r.set_undefined ();
1287 else
1289 r.set_varying (type);
1290 r.clear_nan ();
1292 break;
1294 case BRS_FALSE:
1295 // The FALSE side of op1 ORDERED op1 implies op1 is NAN.
1296 if (rel == VREL_EQ)
1297 r.set_nan (type);
1298 else
1299 r.set_varying (type);
1300 break;
1302 default:
1303 break;
1305 return true;
1308 bool
1309 operator_negate::fold_range (frange &r, tree type,
1310 const frange &op1, const frange &op2,
1311 relation_trio) const
1313 if (empty_range_varying (r, type, op1, op2))
1314 return true;
1315 if (op1.known_isnan ())
1317 bool sign;
1318 if (op1.nan_signbit_p (sign))
1319 r.set_nan (type, !sign);
1320 else
1321 r.set_nan (type);
1322 return true;
1325 REAL_VALUE_TYPE lh_lb = op1.lower_bound ();
1326 REAL_VALUE_TYPE lh_ub = op1.upper_bound ();
1327 lh_lb = real_value_negate (&lh_lb);
1328 lh_ub = real_value_negate (&lh_ub);
1329 r.set (type, lh_ub, lh_lb);
1330 if (op1.maybe_isnan ())
1332 bool sign;
1333 if (op1.nan_signbit_p (sign))
1334 r.update_nan (!sign);
1335 else
1336 r.update_nan ();
1338 else
1339 r.clear_nan ();
1340 return true;
1343 bool
1344 operator_negate::op1_range (frange &r, tree type,
1345 const frange &lhs, const frange &op2,
1346 relation_trio rel) const
1348 return fold_range (r, type, lhs, op2, rel);
1351 bool
1352 operator_abs::fold_range (frange &r, tree type,
1353 const frange &op1, const frange &op2,
1354 relation_trio) const
1356 if (empty_range_varying (r, type, op1, op2))
1357 return true;
1358 if (op1.known_isnan ())
1360 r.set_nan (type, /*sign=*/false);
1361 return true;
1364 const REAL_VALUE_TYPE lh_lb = op1.lower_bound ();
1365 const REAL_VALUE_TYPE lh_ub = op1.upper_bound ();
1366 // Handle the easy case where everything is positive.
1367 if (real_compare (GE_EXPR, &lh_lb, &dconst0)
1368 && !real_iszero (&lh_lb, /*sign=*/true)
1369 && !op1.maybe_isnan (/*sign=*/true))
1371 r = op1;
1372 return true;
1375 REAL_VALUE_TYPE min = real_value_abs (&lh_lb);
1376 REAL_VALUE_TYPE max = real_value_abs (&lh_ub);
1377 // If the range contains zero then we know that the minimum value in the
1378 // range will be zero.
1379 if (real_compare (LE_EXPR, &lh_lb, &dconst0)
1380 && real_compare (GE_EXPR, &lh_ub, &dconst0))
1382 if (real_compare (GT_EXPR, &min, &max))
1383 max = min;
1384 min = dconst0;
1386 else
1388 // If the range was reversed, swap MIN and MAX.
1389 if (real_compare (GT_EXPR, &min, &max))
1390 std::swap (min, max);
1393 r.set (type, min, max);
1394 if (op1.maybe_isnan ())
1395 r.update_nan (/*sign=*/false);
1396 else
1397 r.clear_nan ();
1398 return true;
1401 bool
1402 operator_abs::op1_range (frange &r, tree type,
1403 const frange &lhs, const frange &op2,
1404 relation_trio) const
1406 if (empty_range_varying (r, type, lhs, op2))
1407 return true;
1408 if (lhs.known_isnan ())
1410 r.set_nan (type);
1411 return true;
1414 // Start with the positives because negatives are an impossible result.
1415 frange positives (type, dconst0, frange_val_max (type));
1416 positives.update_nan (/*sign=*/false);
1417 positives.intersect (lhs);
1418 r = positives;
1419 // Add -NAN if relevant.
1420 if (r.maybe_isnan ())
1422 frange neg_nan;
1423 neg_nan.set_nan (type, true);
1424 r.union_ (neg_nan);
1426 if (r.known_isnan () || r.undefined_p ())
1427 return true;
1428 // Then add the negative of each pair:
1429 // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
1430 frange negatives (type, real_value_negate (&positives.upper_bound ()),
1431 real_value_negate (&positives.lower_bound ()));
1432 negatives.clear_nan ();
1433 r.union_ (negatives);
1434 return true;
1437 class foperator_unordered_lt : public range_operator
1439 using range_operator::fold_range;
1440 using range_operator::op1_range;
1441 using range_operator::op2_range;
1442 public:
1443 bool fold_range (irange &r, tree type,
1444 const frange &op1, const frange &op2,
1445 relation_trio rel = TRIO_VARYING) const final override
1447 if (op1.known_isnan () || op2.known_isnan ())
1449 r = range_true (type);
1450 return true;
1452 frange op1_no_nan = op1;
1453 frange op2_no_nan = op2;
1454 if (op1.maybe_isnan ())
1455 op1_no_nan.clear_nan ();
1456 if (op2.maybe_isnan ())
1457 op2_no_nan.clear_nan ();
1458 if (!range_op_handler (LT_EXPR).fold_range (r, type, op1_no_nan,
1459 op2_no_nan, rel))
1460 return false;
1461 // The result is the same as the ordered version when the
1462 // comparison is true or when the operands cannot be NANs.
1463 if (!maybe_isnan (op1, op2) || r == range_true (type))
1464 return true;
1465 else
1467 r = range_true_and_false (type);
1468 return true;
1471 bool op1_range (frange &r, tree type,
1472 const irange &lhs,
1473 const frange &op2,
1474 relation_trio trio) const final override;
1475 bool op2_range (frange &r, tree type,
1476 const irange &lhs,
1477 const frange &op1,
1478 relation_trio trio) const final override;
1479 } fop_unordered_lt;
1481 bool
1482 foperator_unordered_lt::op1_range (frange &r, tree type,
1483 const irange &lhs,
1484 const frange &op2,
1485 relation_trio) const
1487 switch (get_bool_state (r, lhs, type))
1489 case BRS_TRUE:
1490 if (op2.known_isnan () || op2.maybe_isnan ())
1491 r.set_varying (type);
1492 else if (op2.undefined_p ())
1493 return false;
1494 else
1495 build_lt (r, type, op2);
1496 break;
1498 case BRS_FALSE:
1499 // A false UNORDERED_LT means both operands are !NAN, so it's
1500 // impossible for op2 to be a NAN.
1501 if (op2.known_isnan ())
1502 r.set_undefined ();
1503 else if (op2.undefined_p ())
1504 return false;
1505 else if (build_ge (r, type, op2))
1506 r.clear_nan ();
1507 break;
1509 default:
1510 break;
1512 return true;
1515 bool
1516 foperator_unordered_lt::op2_range (frange &r, tree type,
1517 const irange &lhs,
1518 const frange &op1,
1519 relation_trio) const
1521 switch (get_bool_state (r, lhs, type))
1523 case BRS_TRUE:
1524 if (op1.known_isnan () || op1.maybe_isnan ())
1525 r.set_varying (type);
1526 else if (op1.undefined_p ())
1527 return false;
1528 else
1529 build_gt (r, type, op1);
1530 break;
1532 case BRS_FALSE:
1533 // A false UNORDERED_LT means both operands are !NAN, so it's
1534 // impossible for op1 to be a NAN.
1535 if (op1.known_isnan ())
1536 r.set_undefined ();
1537 else if (op1.undefined_p ())
1538 return false;
1539 else if (build_le (r, type, op1))
1540 r.clear_nan ();
1541 break;
1543 default:
1544 break;
1546 return true;
1549 class foperator_unordered_le : public range_operator
1551 using range_operator::fold_range;
1552 using range_operator::op1_range;
1553 using range_operator::op2_range;
1554 public:
1555 bool fold_range (irange &r, tree type,
1556 const frange &op1, const frange &op2,
1557 relation_trio rel = TRIO_VARYING) const final override
1559 if (op1.known_isnan () || op2.known_isnan ())
1561 r = range_true (type);
1562 return true;
1564 frange op1_no_nan = op1;
1565 frange op2_no_nan = op2;
1566 if (op1.maybe_isnan ())
1567 op1_no_nan.clear_nan ();
1568 if (op2.maybe_isnan ())
1569 op2_no_nan.clear_nan ();
1570 if (!range_op_handler (LE_EXPR).fold_range (r, type, op1_no_nan,
1571 op2_no_nan, rel))
1572 return false;
1573 // The result is the same as the ordered version when the
1574 // comparison is true or when the operands cannot be NANs.
1575 if (!maybe_isnan (op1, op2) || r == range_true (type))
1576 return true;
1577 else
1579 r = range_true_and_false (type);
1580 return true;
1583 bool op1_range (frange &r, tree type,
1584 const irange &lhs, const frange &op2,
1585 relation_trio = TRIO_VARYING) const final override;
1586 bool op2_range (frange &r, tree type,
1587 const irange &lhs, const frange &op1,
1588 relation_trio = TRIO_VARYING) const final override;
1589 } fop_unordered_le;
1591 bool
1592 foperator_unordered_le::op1_range (frange &r, tree type,
1593 const irange &lhs, const frange &op2,
1594 relation_trio) const
1596 switch (get_bool_state (r, lhs, type))
1598 case BRS_TRUE:
1599 if (op2.known_isnan () || op2.maybe_isnan ())
1600 r.set_varying (type);
1601 else if (op2.undefined_p ())
1602 return false;
1603 else
1604 build_le (r, type, op2);
1605 break;
1607 case BRS_FALSE:
1608 // A false UNORDERED_LE means both operands are !NAN, so it's
1609 // impossible for op2 to be a NAN.
1610 if (op2.known_isnan ())
1611 r.set_undefined ();
1612 else if (build_gt (r, type, op2))
1613 r.clear_nan ();
1614 break;
1616 default:
1617 break;
1619 return true;
1622 bool
1623 foperator_unordered_le::op2_range (frange &r,
1624 tree type,
1625 const irange &lhs,
1626 const frange &op1,
1627 relation_trio) const
1629 switch (get_bool_state (r, lhs, type))
1631 case BRS_TRUE:
1632 if (op1.known_isnan () || op1.maybe_isnan ())
1633 r.set_varying (type);
1634 else if (op1.undefined_p ())
1635 return false;
1636 else
1637 build_ge (r, type, op1);
1638 break;
1640 case BRS_FALSE:
1641 // A false UNORDERED_LE means both operands are !NAN, so it's
1642 // impossible for op1 to be a NAN.
1643 if (op1.known_isnan ())
1644 r.set_undefined ();
1645 else if (op1.undefined_p ())
1646 return false;
1647 else if (build_lt (r, type, op1))
1648 r.clear_nan ();
1649 break;
1651 default:
1652 break;
1654 return true;
1657 class foperator_unordered_gt : public range_operator
1659 using range_operator::fold_range;
1660 using range_operator::op1_range;
1661 using range_operator::op2_range;
1662 public:
1663 bool fold_range (irange &r, tree type,
1664 const frange &op1, const frange &op2,
1665 relation_trio rel = TRIO_VARYING) const final override
1667 if (op1.known_isnan () || op2.known_isnan ())
1669 r = range_true (type);
1670 return true;
1672 frange op1_no_nan = op1;
1673 frange op2_no_nan = op2;
1674 if (op1.maybe_isnan ())
1675 op1_no_nan.clear_nan ();
1676 if (op2.maybe_isnan ())
1677 op2_no_nan.clear_nan ();
1678 if (!range_op_handler (GT_EXPR).fold_range (r, type, op1_no_nan,
1679 op2_no_nan, rel))
1680 return false;
1681 // The result is the same as the ordered version when the
1682 // comparison is true or when the operands cannot be NANs.
1683 if (!maybe_isnan (op1, op2) || r == range_true (type))
1684 return true;
1685 else
1687 r = range_true_and_false (type);
1688 return true;
1691 bool op1_range (frange &r, tree type,
1692 const irange &lhs, const frange &op2,
1693 relation_trio = TRIO_VARYING) const final override;
1694 bool op2_range (frange &r, tree type,
1695 const irange &lhs, const frange &op1,
1696 relation_trio = TRIO_VARYING) const final override;
1697 } fop_unordered_gt;
1699 bool
1700 foperator_unordered_gt::op1_range (frange &r,
1701 tree type,
1702 const irange &lhs,
1703 const frange &op2,
1704 relation_trio) const
1706 switch (get_bool_state (r, lhs, type))
1708 case BRS_TRUE:
1709 if (op2.known_isnan () || op2.maybe_isnan ())
1710 r.set_varying (type);
1711 else if (op2.undefined_p ())
1712 return false;
1713 else
1714 build_gt (r, type, op2);
1715 break;
1717 case BRS_FALSE:
1718 // A false UNORDERED_GT means both operands are !NAN, so it's
1719 // impossible for op2 to be a NAN.
1720 if (op2.known_isnan ())
1721 r.set_undefined ();
1722 else if (op2.undefined_p ())
1723 return false;
1724 else if (build_le (r, type, op2))
1725 r.clear_nan ();
1726 break;
1728 default:
1729 break;
1731 return true;
1734 bool
1735 foperator_unordered_gt::op2_range (frange &r,
1736 tree type,
1737 const irange &lhs,
1738 const frange &op1,
1739 relation_trio) const
1741 switch (get_bool_state (r, lhs, type))
1743 case BRS_TRUE:
1744 if (op1.known_isnan () || op1.maybe_isnan ())
1745 r.set_varying (type);
1746 else if (op1.undefined_p ())
1747 return false;
1748 else
1749 build_lt (r, type, op1);
1750 break;
1752 case BRS_FALSE:
1753 // A false UNORDERED_GT means both operands are !NAN, so it's
1754 // impossible for op1 to be a NAN.
1755 if (op1.known_isnan ())
1756 r.set_undefined ();
1757 else if (op1.undefined_p ())
1758 return false;
1759 else if (build_ge (r, type, op1))
1760 r.clear_nan ();
1761 break;
1763 default:
1764 break;
1766 return true;
1769 class foperator_unordered_ge : public range_operator
1771 using range_operator::fold_range;
1772 using range_operator::op1_range;
1773 using range_operator::op2_range;
1774 public:
1775 bool fold_range (irange &r, tree type,
1776 const frange &op1, const frange &op2,
1777 relation_trio rel = TRIO_VARYING) const final override
1779 if (op1.known_isnan () || op2.known_isnan ())
1781 r = range_true (type);
1782 return true;
1784 frange op1_no_nan = op1;
1785 frange op2_no_nan = op2;
1786 if (op1.maybe_isnan ())
1787 op1_no_nan.clear_nan ();
1788 if (op2.maybe_isnan ())
1789 op2_no_nan.clear_nan ();
1790 if (!range_op_handler (GE_EXPR).fold_range (r, type, op1_no_nan,
1791 op2_no_nan, rel))
1792 return false;
1793 // The result is the same as the ordered version when the
1794 // comparison is true or when the operands cannot be NANs.
1795 if (!maybe_isnan (op1, op2) || r == range_true (type))
1796 return true;
1797 else
1799 r = range_true_and_false (type);
1800 return true;
1803 bool op1_range (frange &r, tree type,
1804 const irange &lhs, const frange &op2,
1805 relation_trio = TRIO_VARYING) const final override;
1806 bool op2_range (frange &r, tree type,
1807 const irange &lhs, const frange &op1,
1808 relation_trio = TRIO_VARYING) const final override;
1809 } fop_unordered_ge;
1811 bool
1812 foperator_unordered_ge::op1_range (frange &r,
1813 tree type,
1814 const irange &lhs,
1815 const frange &op2,
1816 relation_trio) const
1818 switch (get_bool_state (r, lhs, type))
1820 case BRS_TRUE:
1821 if (op2.known_isnan () || op2.maybe_isnan ())
1822 r.set_varying (type);
1823 else if (op2.undefined_p ())
1824 return false;
1825 else
1826 build_ge (r, type, op2);
1827 break;
1829 case BRS_FALSE:
1830 // A false UNORDERED_GE means both operands are !NAN, so it's
1831 // impossible for op2 to be a NAN.
1832 if (op2.known_isnan ())
1833 r.set_undefined ();
1834 else if (op2.undefined_p ())
1835 return false;
1836 else if (build_lt (r, type, op2))
1837 r.clear_nan ();
1838 break;
1840 default:
1841 break;
1843 return true;
1846 bool
1847 foperator_unordered_ge::op2_range (frange &r, tree type,
1848 const irange &lhs,
1849 const frange &op1,
1850 relation_trio) const
1852 switch (get_bool_state (r, lhs, type))
1854 case BRS_TRUE:
1855 if (op1.known_isnan () || op1.maybe_isnan ())
1856 r.set_varying (type);
1857 else if (op1.undefined_p ())
1858 return false;
1859 else
1860 build_le (r, type, op1);
1861 break;
1863 case BRS_FALSE:
1864 // A false UNORDERED_GE means both operands are !NAN, so it's
1865 // impossible for op1 to be a NAN.
1866 if (op1.known_isnan ())
1867 r.set_undefined ();
1868 else if (op1.undefined_p ())
1869 return false;
1870 else if (build_gt (r, type, op1))
1871 r.clear_nan ();
1872 break;
1874 default:
1875 break;
1877 return true;
1880 class foperator_unordered_equal : public range_operator
1882 using range_operator::fold_range;
1883 using range_operator::op1_range;
1884 using range_operator::op2_range;
1885 public:
1886 bool fold_range (irange &r, tree type,
1887 const frange &op1, const frange &op2,
1888 relation_trio rel = TRIO_VARYING) const final override
1890 if (op1.known_isnan () || op2.known_isnan ())
1892 r = range_true (type);
1893 return true;
1895 frange op1_no_nan = op1;
1896 frange op2_no_nan = op2;
1897 if (op1.maybe_isnan ())
1898 op1_no_nan.clear_nan ();
1899 if (op2.maybe_isnan ())
1900 op2_no_nan.clear_nan ();
1901 if (!range_op_handler (EQ_EXPR).fold_range (r, type, op1_no_nan,
1902 op2_no_nan, rel))
1903 return false;
1904 // The result is the same as the ordered version when the
1905 // comparison is true or when the operands cannot be NANs.
1906 if (!maybe_isnan (op1, op2) || r == range_true (type))
1907 return true;
1908 else
1910 r = range_true_and_false (type);
1911 return true;
1914 bool op1_range (frange &r, tree type,
1915 const irange &lhs, const frange &op2,
1916 relation_trio = TRIO_VARYING) const final override;
1917 bool op2_range (frange &r, tree type,
1918 const irange &lhs, const frange &op1,
1919 relation_trio rel = TRIO_VARYING) const final override
1921 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
1923 } fop_unordered_equal;
1925 bool
1926 foperator_unordered_equal::op1_range (frange &r, tree type,
1927 const irange &lhs,
1928 const frange &op2,
1929 relation_trio) const
1931 switch (get_bool_state (r, lhs, type))
1933 case BRS_TRUE:
1934 // If it's true, the result is the same as OP2 plus a NAN.
1935 r = op2;
1936 // Add both zeros if there's the possibility of zero equality.
1937 frange_add_zeros (r, type);
1938 // Add the possibility of a NAN.
1939 r.update_nan ();
1940 break;
1942 case BRS_FALSE:
1943 // A false UNORDERED_EQ means both operands are !NAN, so it's
1944 // impossible for op2 to be a NAN.
1945 if (op2.known_isnan ())
1946 r.set_undefined ();
1947 else
1949 // The false side indicates !NAN and not equal. We can at least
1950 // represent !NAN.
1951 r.set_varying (type);
1952 r.clear_nan ();
1954 break;
1956 default:
1957 break;
1959 return true;
1962 class foperator_ltgt : public range_operator
1964 using range_operator::fold_range;
1965 using range_operator::op1_range;
1966 using range_operator::op2_range;
1967 public:
1968 bool fold_range (irange &r, tree type,
1969 const frange &op1, const frange &op2,
1970 relation_trio rel = TRIO_VARYING) const final override
1972 if (op1.known_isnan () || op2.known_isnan ())
1974 r = range_false (type);
1975 return true;
1977 frange op1_no_nan = op1;
1978 frange op2_no_nan = op2;
1979 if (op1.maybe_isnan ())
1980 op1_no_nan.clear_nan ();
1981 if (op2.maybe_isnan ())
1982 op2_no_nan.clear_nan ();
1983 if (!range_op_handler (NE_EXPR).fold_range (r, type, op1_no_nan,
1984 op2_no_nan, rel))
1985 return false;
1986 // The result is the same as the ordered version when the
1987 // comparison is true or when the operands cannot be NANs.
1988 if (!maybe_isnan (op1, op2) || r == range_false (type))
1989 return true;
1990 else
1992 r = range_true_and_false (type);
1993 return true;
1996 bool op1_range (frange &r, tree type,
1997 const irange &lhs, const frange &op2,
1998 relation_trio = TRIO_VARYING) const final override;
1999 bool op2_range (frange &r, tree type,
2000 const irange &lhs, const frange &op1,
2001 relation_trio rel = TRIO_VARYING) const final override
2003 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
2005 } fop_ltgt;
2007 bool
2008 foperator_ltgt::op1_range (frange &r, tree type,
2009 const irange &lhs,
2010 const frange &op2,
2011 relation_trio) const
2013 switch (get_bool_state (r, lhs, type))
2015 case BRS_TRUE:
2016 // A true LTGT means both operands are !NAN, so it's
2017 // impossible for op2 to be a NAN.
2018 if (op2.known_isnan ())
2019 r.set_undefined ();
2020 else
2022 // The true side indicates !NAN and not equal. We can at least
2023 // represent !NAN.
2024 r.set_varying (type);
2025 r.clear_nan ();
2027 break;
2029 case BRS_FALSE:
2030 // If it's false, the result is the same as OP2 plus a NAN.
2031 r = op2;
2032 // Add both zeros if there's the possibility of zero equality.
2033 frange_add_zeros (r, type);
2034 // Add the possibility of a NAN.
2035 r.update_nan ();
2036 break;
2038 default:
2039 break;
2041 return true;
2044 // Final tweaks for float binary op op1_range/op2_range.
2045 // Return TRUE if the operation is performed and a valid range is available.
2047 static bool
2048 float_binary_op_range_finish (bool ret, frange &r, tree type,
2049 const frange &lhs, bool div_op2 = false)
2051 if (!ret)
2052 return false;
2054 // If we get a known NAN from reverse op, it means either that
2055 // the other operand was known NAN (in that case we know nothing),
2056 // or the reverse operation introduced a known NAN.
2057 // Say for lhs = op1 * op2 if lhs is [-0, +0] and op2 is too,
2058 // 0 / 0 is known NAN. Just punt in that case.
2059 // If NANs aren't honored, we get for 0 / 0 UNDEFINED, so punt as well.
2060 // Or if lhs is a known NAN, we also don't know anything.
2061 if (r.known_isnan () || lhs.known_isnan () || r.undefined_p ())
2063 r.set_varying (type);
2064 return true;
2067 // If lhs isn't NAN, then neither operand could be NAN,
2068 // even if the reverse operation does introduce a maybe_nan.
2069 if (!lhs.maybe_isnan ())
2071 r.clear_nan ();
2072 if (div_op2
2073 ? !(real_compare (LE_EXPR, &lhs.lower_bound (), &dconst0)
2074 && real_compare (GE_EXPR, &lhs.upper_bound (), &dconst0))
2075 : !(real_isinf (&lhs.lower_bound ())
2076 || real_isinf (&lhs.upper_bound ())))
2077 // For reverse + or - or * or op1 of /, if result is finite, then
2078 // r must be finite too, as X + INF or X - INF or X * INF or
2079 // INF / X is always +-INF or NAN. For op2 of /, if result is
2080 // non-zero and not NAN, r must be finite, as X / INF is always
2081 // 0 or NAN.
2082 frange_drop_infs (r, type);
2084 // If lhs is a maybe or known NAN, the operand could be
2085 // NAN.
2086 else
2087 r.update_nan ();
2088 return true;
2091 // True if [lb, ub] is [+-0, +-0].
2092 static bool
2093 zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2095 return real_iszero (&lb) && real_iszero (&ub);
2098 // True if +0 or -0 is in [lb, ub] range.
2099 static bool
2100 contains_zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2102 return (real_compare (LE_EXPR, &lb, &dconst0)
2103 && real_compare (GE_EXPR, &ub, &dconst0));
2106 // True if [lb, ub] is [-INF, -INF] or [+INF, +INF].
2107 static bool
2108 singleton_inf_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2110 return real_isinf (&lb) && real_isinf (&ub, real_isneg (&lb));
2113 // Return -1 if binary op result must have sign bit set,
2114 // 1 if binary op result must have sign bit clear,
2115 // 0 otherwise.
2116 // Sign bit of binary op result is exclusive or of the
2117 // operand's sign bits.
2118 static int
2119 signbit_known_p (const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
2120 const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub)
2122 if (real_isneg (&lh_lb) == real_isneg (&lh_ub)
2123 && real_isneg (&rh_lb) == real_isneg (&rh_ub))
2125 if (real_isneg (&lh_lb) == real_isneg (&rh_ub))
2126 return 1;
2127 else
2128 return -1;
2130 return 0;
2133 // Set [lb, ub] to [-0, -0], [-0, +0] or [+0, +0] depending on
2134 // signbit_known.
2135 static void
2136 zero_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2138 ub = lb = dconst0;
2139 if (signbit_known <= 0)
2140 lb = dconstm0;
2141 if (signbit_known < 0)
2142 ub = lb;
2145 // Set [lb, ub] to [-INF, -INF], [-INF, +INF] or [+INF, +INF] depending on
2146 // signbit_known.
2147 static void
2148 inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2150 if (signbit_known > 0)
2151 ub = lb = dconstinf;
2152 else if (signbit_known < 0)
2153 ub = lb = dconstninf;
2154 else
2156 lb = dconstninf;
2157 ub = dconstinf;
2161 // Set [lb, ub] to [-INF, -0], [-INF, +INF] or [+0, +INF] depending on
2162 // signbit_known.
2163 static void
2164 zero_to_inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2166 if (signbit_known > 0)
2168 lb = dconst0;
2169 ub = dconstinf;
2171 else if (signbit_known < 0)
2173 lb = dconstninf;
2174 ub = dconstm0;
2176 else
2178 lb = dconstninf;
2179 ub = dconstinf;
2183 /* Extend the LHS range by 1ulp in each direction. For op1_range
2184 or op2_range of binary operations just computing the inverse
2185 operation on ranges isn't sufficient. Consider e.g.
2186 [1., 1.] = op1 + [1., 1.]. op1's range is not [0., 0.], but
2187 [-0x1.0p-54, 0x1.0p-53] (when not -frounding-math), any value for
2188 which adding 1. to it results in 1. after rounding to nearest.
2189 So, for op1_range/op2_range extend the lhs range by 1ulp (or 0.5ulp)
2190 in each direction. See PR109008 for more details. */
2192 static frange
2193 float_widen_lhs_range (tree type, const frange &lhs)
2195 frange ret = lhs;
2196 if (lhs.known_isnan ())
2197 return ret;
2198 REAL_VALUE_TYPE lb = lhs.lower_bound ();
2199 REAL_VALUE_TYPE ub = lhs.upper_bound ();
2200 if (real_isfinite (&lb))
2202 frange_nextafter (TYPE_MODE (type), lb, dconstninf);
2203 if (real_isinf (&lb))
2205 /* For -DBL_MAX, instead of -Inf use
2206 nexttoward (-DBL_MAX, -LDBL_MAX) in a hypothetical
2207 wider type with the same mantissa precision but larger
2208 exponent range; it is outside of range of double values,
2209 but makes it clear it is just one ulp larger rather than
2210 infinite amount larger. */
2211 lb = dconstm1;
2212 SET_REAL_EXP (&lb, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
2214 if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)))
2216 /* If not -frounding-math nor IBM double double, actually widen
2217 just by 0.5ulp rather than 1ulp. */
2218 REAL_VALUE_TYPE tem;
2219 real_arithmetic (&tem, PLUS_EXPR, &lhs.lower_bound (), &lb);
2220 real_arithmetic (&lb, RDIV_EXPR, &tem, &dconst2);
2223 if (real_isfinite (&ub))
2225 frange_nextafter (TYPE_MODE (type), ub, dconstinf);
2226 if (real_isinf (&ub))
2228 /* For DBL_MAX similarly. */
2229 ub = dconst1;
2230 SET_REAL_EXP (&ub, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
2232 if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)))
2234 /* If not -frounding-math nor IBM double double, actually widen
2235 just by 0.5ulp rather than 1ulp. */
2236 REAL_VALUE_TYPE tem;
2237 real_arithmetic (&tem, PLUS_EXPR, &lhs.upper_bound (), &ub);
2238 real_arithmetic (&ub, RDIV_EXPR, &tem, &dconst2);
2241 /* Temporarily disable -ffinite-math-only, so that frange::set doesn't
2242 reduce the range back to real_min_representable (type) as lower bound
2243 or real_max_representable (type) as upper bound. */
2244 bool save_flag_finite_math_only = flag_finite_math_only;
2245 flag_finite_math_only = false;
2246 ret.set (type, lb, ub, lhs.get_nan_state ());
2247 flag_finite_math_only = save_flag_finite_math_only;
2248 return ret;
2251 bool
2252 operator_plus::op1_range (frange &r, tree type, const frange &lhs,
2253 const frange &op2, relation_trio) const
2255 if (lhs.undefined_p ())
2256 return false;
2257 range_op_handler minus (MINUS_EXPR);
2258 if (!minus)
2259 return false;
2260 frange wlhs = float_widen_lhs_range (type, lhs);
2261 return float_binary_op_range_finish (minus.fold_range (r, type, wlhs, op2),
2262 r, type, wlhs);
2265 bool
2266 operator_plus::op2_range (frange &r, tree type,
2267 const frange &lhs, const frange &op1,
2268 relation_trio) const
2270 return op1_range (r, type, lhs, op1);
2273 void
2274 operator_plus::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
2275 bool &maybe_nan, tree type,
2276 const REAL_VALUE_TYPE &lh_lb,
2277 const REAL_VALUE_TYPE &lh_ub,
2278 const REAL_VALUE_TYPE &rh_lb,
2279 const REAL_VALUE_TYPE &rh_ub,
2280 relation_kind) const
2282 frange_arithmetic (PLUS_EXPR, type, lb, lh_lb, rh_lb, dconstninf);
2283 frange_arithmetic (PLUS_EXPR, type, ub, lh_ub, rh_ub, dconstinf);
2285 // [-INF] + [+INF] = NAN
2286 if (real_isinf (&lh_lb, true) && real_isinf (&rh_ub, false))
2287 maybe_nan = true;
2288 // [+INF] + [-INF] = NAN
2289 else if (real_isinf (&lh_ub, false) && real_isinf (&rh_lb, true))
2290 maybe_nan = true;
2291 else
2292 maybe_nan = false;
2296 bool
2297 operator_minus::op1_range (frange &r, tree type,
2298 const frange &lhs, const frange &op2,
2299 relation_trio) const
2301 if (lhs.undefined_p ())
2302 return false;
2303 frange wlhs = float_widen_lhs_range (type, lhs);
2304 return float_binary_op_range_finish (
2305 range_op_handler (PLUS_EXPR).fold_range (r, type, wlhs, op2),
2306 r, type, wlhs);
2309 bool
2310 operator_minus::op2_range (frange &r, tree type,
2311 const frange &lhs, const frange &op1,
2312 relation_trio) const
2314 if (lhs.undefined_p ())
2315 return false;
2316 frange wlhs = float_widen_lhs_range (type, lhs);
2317 return float_binary_op_range_finish (fold_range (r, type, op1, wlhs),
2318 r, type, wlhs);
2321 void
2322 operator_minus::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
2323 bool &maybe_nan, tree type,
2324 const REAL_VALUE_TYPE &lh_lb,
2325 const REAL_VALUE_TYPE &lh_ub,
2326 const REAL_VALUE_TYPE &rh_lb,
2327 const REAL_VALUE_TYPE &rh_ub,
2328 relation_kind) const
2330 frange_arithmetic (MINUS_EXPR, type, lb, lh_lb, rh_ub, dconstninf);
2331 frange_arithmetic (MINUS_EXPR, type, ub, lh_ub, rh_lb, dconstinf);
2333 // [+INF] - [+INF] = NAN
2334 if (real_isinf (&lh_ub, false) && real_isinf (&rh_ub, false))
2335 maybe_nan = true;
2336 // [-INF] - [-INF] = NAN
2337 else if (real_isinf (&lh_lb, true) && real_isinf (&rh_lb, true))
2338 maybe_nan = true;
2339 else
2340 maybe_nan = false;
2344 // Given CP[0] to CP[3] floating point values rounded to -INF,
2345 // set LB to the smallest of them (treating -0 as smaller to +0).
2346 // Given CP[4] to CP[7] floating point values rounded to +INF,
2347 // set UB to the largest of them (treating -0 as smaller to +0).
2349 static void
2350 find_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
2351 const REAL_VALUE_TYPE (&cp)[8])
2353 lb = cp[0];
2354 ub = cp[4];
2355 for (int i = 1; i < 4; ++i)
2357 if (real_less (&cp[i], &lb)
2358 || (real_iszero (&lb) && real_isnegzero (&cp[i])))
2359 lb = cp[i];
2360 if (real_less (&ub, &cp[i + 4])
2361 || (real_isnegzero (&ub) && real_iszero (&cp[i + 4])))
2362 ub = cp[i + 4];
2367 bool
2368 operator_mult::op1_range (frange &r, tree type,
2369 const frange &lhs, const frange &op2,
2370 relation_trio) const
2372 if (lhs.undefined_p ())
2373 return false;
2374 range_op_handler rdiv (RDIV_EXPR);
2375 if (!rdiv)
2376 return false;
2377 frange wlhs = float_widen_lhs_range (type, lhs);
2378 bool ret = rdiv.fold_range (r, type, wlhs, op2);
2379 if (ret == false)
2380 return false;
2381 if (wlhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
2382 return float_binary_op_range_finish (ret, r, type, wlhs);
2383 const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
2384 const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
2385 const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
2386 const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
2387 if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op2_lb, op2_ub))
2388 || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
2389 && (real_isinf (&op2_lb) || real_isinf (&op2_ub))))
2391 // If both lhs and op2 could be zeros or both could be infinities,
2392 // we don't know anything about op1 except maybe for the sign
2393 // and perhaps if it can be NAN or not.
2394 REAL_VALUE_TYPE lb, ub;
2395 int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
2396 zero_to_inf_range (lb, ub, signbit_known);
2397 r.set (type, lb, ub);
2399 // Otherwise, if op2 is a singleton INF and lhs doesn't include INF,
2400 // or if lhs must be zero and op2 doesn't include zero, it would be
2401 // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF
2402 // range. Those are supersets of UNDEFINED, so let's keep that way.
2403 return float_binary_op_range_finish (ret, r, type, wlhs);
2406 bool
2407 operator_mult::op2_range (frange &r, tree type,
2408 const frange &lhs, const frange &op1,
2409 relation_trio) const
2411 return op1_range (r, type, lhs, op1);
2414 void
2415 operator_mult::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
2416 bool &maybe_nan, tree type,
2417 const REAL_VALUE_TYPE &lh_lb,
2418 const REAL_VALUE_TYPE &lh_ub,
2419 const REAL_VALUE_TYPE &rh_lb,
2420 const REAL_VALUE_TYPE &rh_ub,
2421 relation_kind kind) const
2423 bool is_square
2424 = (kind == VREL_EQ
2425 && real_equal (&lh_lb, &rh_lb)
2426 && real_equal (&lh_ub, &rh_ub)
2427 && real_isneg (&lh_lb) == real_isneg (&rh_lb)
2428 && real_isneg (&lh_ub) == real_isneg (&rh_ub));
2430 maybe_nan = false;
2431 // x * x never produces a new NAN and we only multiply the same
2432 // values, so the 0 * INF problematic cases never appear there.
2433 if (!is_square)
2435 // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN.
2436 if ((zero_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub))
2437 || (zero_p (rh_lb, rh_ub) && singleton_inf_p (lh_lb, lh_ub)))
2439 real_nan (&lb, "", 0, TYPE_MODE (type));
2440 ub = lb;
2441 maybe_nan = true;
2442 return;
2445 // Otherwise, if one range includes zero and the other ends with +-INF,
2446 // it is a maybe NAN.
2447 if ((contains_zero_p (lh_lb, lh_ub)
2448 && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
2449 || (contains_zero_p (rh_lb, rh_ub)
2450 && (real_isinf (&lh_lb) || real_isinf (&lh_ub))))
2452 maybe_nan = true;
2454 int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
2456 // If one of the ranges that includes INF is singleton
2457 // and the other range includes zero, the resulting
2458 // range is INF and NAN, because the 0 * INF boundary
2459 // case will be NAN, but already nextafter (0, 1) * INF
2460 // is INF.
2461 if (singleton_inf_p (lh_lb, lh_ub)
2462 || singleton_inf_p (rh_lb, rh_ub))
2463 return inf_range (lb, ub, signbit_known);
2465 // If one of the multiplicands must be zero, the resulting
2466 // range is +-0 and NAN.
2467 if (zero_p (lh_lb, lh_ub) || zero_p (rh_lb, rh_ub))
2468 return zero_range (lb, ub, signbit_known);
2470 // Otherwise one of the multiplicands could be
2471 // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF]
2472 // or similarly with different signs. 0.0 * DBL_MAX
2473 // is still 0.0, nextafter (0.0, 1.0) * INF is still INF,
2474 // so if the signs are always the same or always different,
2475 // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING.
2476 return zero_to_inf_range (lb, ub, signbit_known);
2480 REAL_VALUE_TYPE cp[8];
2481 // Do a cross-product. At this point none of the multiplications
2482 // should produce a NAN.
2483 frange_arithmetic (MULT_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
2484 frange_arithmetic (MULT_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
2485 if (is_square)
2487 // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub)
2488 // as maximum and -0.0 as minimum if 0.0 is in the range,
2489 // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub).
2490 // -0.0 rather than 0.0 because VREL_EQ doesn't prove that
2491 // x and y are bitwise equal, just that they compare equal.
2492 if (contains_zero_p (lh_lb, lh_ub))
2494 if (real_isneg (&lh_lb) == real_isneg (&lh_ub))
2495 cp[1] = dconst0;
2496 else
2497 cp[1] = dconstm0;
2499 else
2500 cp[1] = cp[0];
2501 cp[2] = cp[0];
2502 cp[5] = cp[4];
2503 cp[6] = cp[4];
2505 else
2507 frange_arithmetic (MULT_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
2508 frange_arithmetic (MULT_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
2509 frange_arithmetic (MULT_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
2510 frange_arithmetic (MULT_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
2512 frange_arithmetic (MULT_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
2513 frange_arithmetic (MULT_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);
2515 find_range (lb, ub, cp);
2519 class foperator_div : public range_operator
2521 using range_operator::op1_range;
2522 using range_operator::op2_range;
2523 public:
2524 virtual bool op1_range (frange &r, tree type,
2525 const frange &lhs,
2526 const frange &op2,
2527 relation_trio = TRIO_VARYING) const final override
2529 if (lhs.undefined_p ())
2530 return false;
2531 frange wlhs = float_widen_lhs_range (type, lhs);
2532 bool ret = range_op_handler (MULT_EXPR).fold_range (r, type, wlhs, op2);
2533 if (!ret)
2534 return ret;
2535 if (wlhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
2536 return float_binary_op_range_finish (ret, r, type, wlhs);
2537 const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
2538 const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
2539 const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
2540 const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
2541 if ((contains_zero_p (lhs_lb, lhs_ub)
2542 && (real_isinf (&op2_lb) || real_isinf (&op2_ub)))
2543 || ((contains_zero_p (op2_lb, op2_ub))
2544 && (real_isinf (&lhs_lb) || real_isinf (&lhs_ub))))
2546 // If both lhs could be zero and op2 infinity or vice versa,
2547 // we don't know anything about op1 except maybe for the sign
2548 // and perhaps if it can be NAN or not.
2549 REAL_VALUE_TYPE lb, ub;
2550 int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
2551 zero_to_inf_range (lb, ub, signbit_known);
2552 r.set (type, lb, ub);
2554 return float_binary_op_range_finish (ret, r, type, wlhs);
2556 virtual bool op2_range (frange &r, tree type,
2557 const frange &lhs,
2558 const frange &op1,
2559 relation_trio = TRIO_VARYING) const final override
2561 if (lhs.undefined_p ())
2562 return false;
2563 frange wlhs = float_widen_lhs_range (type, lhs);
2564 bool ret = fold_range (r, type, op1, wlhs);
2565 if (!ret)
2566 return ret;
2567 if (wlhs.known_isnan () || op1.known_isnan () || op1.undefined_p ())
2568 return float_binary_op_range_finish (ret, r, type, wlhs, true);
2569 const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
2570 const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
2571 const REAL_VALUE_TYPE &op1_lb = op1.lower_bound ();
2572 const REAL_VALUE_TYPE &op1_ub = op1.upper_bound ();
2573 if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op1_lb, op1_ub))
2574 || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
2575 && (real_isinf (&op1_lb) || real_isinf (&op1_ub))))
2577 // If both lhs and op1 could be zeros or both could be infinities,
2578 // we don't know anything about op2 except maybe for the sign
2579 // and perhaps if it can be NAN or not.
2580 REAL_VALUE_TYPE lb, ub;
2581 int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op1_lb, op1_ub);
2582 zero_to_inf_range (lb, ub, signbit_known);
2583 r.set (type, lb, ub);
2585 return float_binary_op_range_finish (ret, r, type, wlhs, true);
2587 private:
2588 void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan,
2589 tree type,
2590 const REAL_VALUE_TYPE &lh_lb,
2591 const REAL_VALUE_TYPE &lh_ub,
2592 const REAL_VALUE_TYPE &rh_lb,
2593 const REAL_VALUE_TYPE &rh_ub,
2594 relation_kind) const final override
2596 // +-0.0 / +-0.0 or +-INF / +-INF is a known NAN.
2597 if ((zero_p (lh_lb, lh_ub) && zero_p (rh_lb, rh_ub))
2598 || (singleton_inf_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub)))
2600 real_nan (&lb, "", 0, TYPE_MODE (type));
2601 ub = lb;
2602 maybe_nan = true;
2603 return;
2606 // If +-0.0 is in both ranges, it is a maybe NAN.
2607 if (contains_zero_p (lh_lb, lh_ub) && contains_zero_p (rh_lb, rh_ub))
2608 maybe_nan = true;
2609 // If +-INF is in both ranges, it is a maybe NAN.
2610 else if ((real_isinf (&lh_lb) || real_isinf (&lh_ub))
2611 && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
2612 maybe_nan = true;
2613 else
2614 maybe_nan = false;
2616 int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
2618 // If dividend must be zero, the range is just +-0
2619 // (including if the divisor is +-INF).
2620 // If divisor must be +-INF, the range is just +-0
2621 // (including if the dividend is zero).
2622 if (zero_p (lh_lb, lh_ub) || singleton_inf_p (rh_lb, rh_ub))
2623 return zero_range (lb, ub, signbit_known);
2625 // If divisor must be zero, the range is just +-INF
2626 // (including if the dividend is +-INF).
2627 // If dividend must be +-INF, the range is just +-INF
2628 // (including if the dividend is zero).
2629 if (zero_p (rh_lb, rh_ub) || singleton_inf_p (lh_lb, lh_ub))
2630 return inf_range (lb, ub, signbit_known);
2632 // Otherwise if both operands may be zero, divisor could be
2633 // nextafter(0.0, +-1.0) and dividend +-0.0
2634 // in which case result is going to INF or vice versa and
2635 // result +0.0. So, all we can say for that case is if the
2636 // signs of divisor and dividend are always the same we have
2637 // [+0.0, +INF], if they are always different we have
2638 // [-INF, -0.0]. If they vary, VARYING.
2639 // If both may be +-INF, divisor could be INF and dividend FLT_MAX,
2640 // in which case result is going to INF or vice versa and
2641 // result +0.0. So, all we can say for that case is if the
2642 // signs of divisor and dividend are always the same we have
2643 // [+0.0, +INF], if they are always different we have
2644 // [-INF, -0.0]. If they vary, VARYING.
2645 if (maybe_nan)
2646 return zero_to_inf_range (lb, ub, signbit_known);
2648 REAL_VALUE_TYPE cp[8];
2649 // Do a cross-division. At this point none of the divisions should
2650 // produce a NAN.
2651 frange_arithmetic (RDIV_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
2652 frange_arithmetic (RDIV_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
2653 frange_arithmetic (RDIV_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
2654 frange_arithmetic (RDIV_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
2655 frange_arithmetic (RDIV_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
2656 frange_arithmetic (RDIV_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
2657 frange_arithmetic (RDIV_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
2658 frange_arithmetic (RDIV_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);
2660 find_range (lb, ub, cp);
2662 // If divisor may be zero (but is not known to be only zero),
2663 // and dividend can't be zero, the range can go up to -INF or +INF
2664 // depending on the signs.
2665 if (contains_zero_p (rh_lb, rh_ub))
2667 if (signbit_known <= 0)
2668 real_inf (&lb, true);
2669 if (signbit_known >= 0)
2670 real_inf (&ub, false);
2673 } fop_div;
2676 // Initialize any float operators to the primary table
2678 void
2679 range_op_table::initialize_float_ops ()
2681 set (UNLE_EXPR, fop_unordered_le);
2682 set (UNLT_EXPR, fop_unordered_lt);
2683 set (UNGE_EXPR, fop_unordered_ge);
2684 set (UNGT_EXPR, fop_unordered_gt);
2685 set (UNEQ_EXPR, fop_unordered_equal);
2686 set (ORDERED_EXPR, fop_ordered);
2687 set (UNORDERED_EXPR, fop_unordered);
2688 set (LTGT_EXPR, fop_ltgt);
2689 set (RDIV_EXPR, fop_div);
2692 #if CHECKING_P
2693 #include "selftest.h"
2695 namespace selftest
2698 // Build an frange from string endpoints.
2700 static inline frange
2701 frange_float (const char *lb, const char *ub, tree type = float_type_node)
2703 REAL_VALUE_TYPE min, max;
2704 gcc_assert (real_from_string (&min, lb) == 0);
2705 gcc_assert (real_from_string (&max, ub) == 0);
2706 return frange (type, min, max);
2709 void
2710 range_op_float_tests ()
2712 frange r, r0, r1;
2713 frange trange (float_type_node);
2715 // negate([-5, +10]) => [-10, 5]
2716 r0 = frange_float ("-5", "10");
2717 range_op_handler (NEGATE_EXPR).fold_range (r, float_type_node, r0, trange);
2718 ASSERT_EQ (r, frange_float ("-10", "5"));
2720 // negate([0, 1] -NAN) => [-1, -0] +NAN
2721 r0 = frange_float ("0", "1");
2722 r0.update_nan (true);
2723 range_op_handler (NEGATE_EXPR).fold_range (r, float_type_node, r0, trange);
2724 r1 = frange_float ("-1", "-0");
2725 r1.update_nan (false);
2726 ASSERT_EQ (r, r1);
2728 // [-INF,+INF] + [-INF,+INF] could be a NAN.
2729 range_op_handler plus (PLUS_EXPR);
2730 r0.set_varying (float_type_node);
2731 r1.set_varying (float_type_node);
2732 r0.clear_nan ();
2733 r1.clear_nan ();
2734 plus.fold_range (r, float_type_node, r0, r1);
2735 if (HONOR_NANS (float_type_node))
2736 ASSERT_TRUE (r.maybe_isnan ());
2739 } // namespace selftest
2741 #endif // CHECKING_P