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)
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/>. */
23 #include "coretypes.h"
25 #include "insn-codes.h"
30 #include "tree-pass.h"
32 #include "optabs-tree.h"
33 #include "gimple-pretty-print.h"
34 #include "diagnostic-core.h"
36 #include "fold-const.h"
37 #include "stor-layout.h"
40 #include "gimple-iterator.h"
41 #include "gimple-fold.h"
43 #include "gimple-walk.h"
46 #include "value-relation.h"
49 // Default definitions for floating point operators.
52 range_operator_float::fold_range (frange
&r
, tree type
,
53 const frange
&op1
, const frange
&op2
,
54 relation_trio trio
) const
56 if (empty_range_varying (r
, type
, op1
, op2
))
58 if (op1
.known_isnan () || op2
.known_isnan ())
60 r
.set_nan (op1
.type ());
64 REAL_VALUE_TYPE lb
, ub
;
66 rv_fold (lb
, ub
, maybe_nan
, type
,
67 op1
.lower_bound (), op1
.upper_bound (),
68 op2
.lower_bound (), op2
.upper_bound (), trio
.op1_op2 ());
70 // Handle possible NANs by saturating to the appropriate INF if only
71 // one end is a NAN. If both ends are a NAN, just return a NAN.
72 bool lb_nan
= real_isnan (&lb
);
73 bool ub_nan
= real_isnan (&ub
);
86 if (lb_nan
|| ub_nan
|| maybe_nan
88 || op2
.maybe_isnan ())
89 // Keep the default NAN (with a varying sign) set by the setter.
94 // If the result has overflowed and flag_trapping_math, folding this
95 // operation could elide an overflow or division by zero exception.
96 // Avoid returning a singleton +-INF, to keep the propagators (DOM
97 // and substitute_and_fold_engine) from folding. See PR107608.
98 if (flag_trapping_math
99 && MODE_HAS_INFINITIES (TYPE_MODE (type
))
100 && r
.known_isinf () && !op1
.known_isinf () && !op2
.known_isinf ())
102 REAL_VALUE_TYPE inf
= r
.lower_bound ();
103 if (real_isneg (&inf
))
105 REAL_VALUE_TYPE min
= real_min_representable (type
);
106 r
.set (type
, inf
, min
);
110 REAL_VALUE_TYPE max
= real_max_representable (type
);
111 r
.set (type
, max
, inf
);
115 r
.flush_denormals_to_zero ();
120 // For a given operation, fold two sets of ranges into [lb, ub].
121 // MAYBE_NAN is set to TRUE if, in addition to any result in LB or
122 // UB, the final range has the possibility of a NAN.
124 range_operator_float::rv_fold (REAL_VALUE_TYPE
&lb
,
127 tree type ATTRIBUTE_UNUSED
,
128 const REAL_VALUE_TYPE
&lh_lb ATTRIBUTE_UNUSED
,
129 const REAL_VALUE_TYPE
&lh_ub ATTRIBUTE_UNUSED
,
130 const REAL_VALUE_TYPE
&rh_lb ATTRIBUTE_UNUSED
,
131 const REAL_VALUE_TYPE
&rh_ub ATTRIBUTE_UNUSED
,
140 range_operator_float::fold_range (irange
&r ATTRIBUTE_UNUSED
,
141 tree type ATTRIBUTE_UNUSED
,
142 const frange
&lh ATTRIBUTE_UNUSED
,
143 const irange
&rh ATTRIBUTE_UNUSED
,
150 range_operator_float::fold_range (irange
&r ATTRIBUTE_UNUSED
,
151 tree type ATTRIBUTE_UNUSED
,
152 const frange
&lh ATTRIBUTE_UNUSED
,
153 const frange
&rh ATTRIBUTE_UNUSED
,
160 range_operator_float::op1_range (frange
&r ATTRIBUTE_UNUSED
,
161 tree type ATTRIBUTE_UNUSED
,
162 const frange
&lhs ATTRIBUTE_UNUSED
,
163 const frange
&op2 ATTRIBUTE_UNUSED
,
170 range_operator_float::op1_range (frange
&r ATTRIBUTE_UNUSED
,
171 tree type ATTRIBUTE_UNUSED
,
172 const irange
&lhs ATTRIBUTE_UNUSED
,
173 const frange
&op2 ATTRIBUTE_UNUSED
,
180 range_operator_float::op2_range (frange
&r ATTRIBUTE_UNUSED
,
181 tree type ATTRIBUTE_UNUSED
,
182 const frange
&lhs ATTRIBUTE_UNUSED
,
183 const frange
&op1 ATTRIBUTE_UNUSED
,
190 range_operator_float::op2_range (frange
&r ATTRIBUTE_UNUSED
,
191 tree type ATTRIBUTE_UNUSED
,
192 const irange
&lhs ATTRIBUTE_UNUSED
,
193 const frange
&op1 ATTRIBUTE_UNUSED
,
200 range_operator_float::lhs_op1_relation (const frange
&lhs ATTRIBUTE_UNUSED
,
201 const frange
&op1 ATTRIBUTE_UNUSED
,
202 const frange
&op2 ATTRIBUTE_UNUSED
,
209 range_operator_float::lhs_op1_relation (const irange
&lhs ATTRIBUTE_UNUSED
,
210 const frange
&op1 ATTRIBUTE_UNUSED
,
211 const frange
&op2 ATTRIBUTE_UNUSED
,
218 range_operator_float::lhs_op2_relation (const irange
&lhs ATTRIBUTE_UNUSED
,
219 const frange
&op1 ATTRIBUTE_UNUSED
,
220 const frange
&op2 ATTRIBUTE_UNUSED
,
227 range_operator_float::lhs_op2_relation (const frange
&lhs ATTRIBUTE_UNUSED
,
228 const frange
&op1 ATTRIBUTE_UNUSED
,
229 const frange
&op2 ATTRIBUTE_UNUSED
,
236 range_operator_float::op1_op2_relation (const irange
&lhs ATTRIBUTE_UNUSED
) const
242 range_operator_float::op1_op2_relation (const frange
&lhs ATTRIBUTE_UNUSED
) const
247 // Return TRUE if OP1 and OP2 may be a NAN.
250 maybe_isnan (const frange
&op1
, const frange
&op2
)
252 return op1
.maybe_isnan () || op2
.maybe_isnan ();
255 // Floating version of relop_early_resolve that takes into account NAN
256 // and -ffinite-math-only.
259 frelop_early_resolve (irange
&r
, tree type
,
260 const frange
&op1
, const frange
&op2
,
261 relation_trio rel
, relation_kind my_rel
)
263 // If either operand is undefined, return VARYING.
264 if (empty_range_varying (r
, type
, op1
, op2
))
267 // We can fold relations from the oracle when we know both operands
268 // are free of NANs, or when -ffinite-math-only.
269 return (!maybe_isnan (op1
, op2
)
270 && relop_early_resolve (r
, type
, op1
, op2
, rel
, my_rel
));
273 // Set VALUE to its next real value, or INF if the operation overflows.
276 frange_nextafter (enum machine_mode mode
,
277 REAL_VALUE_TYPE
&value
,
278 const REAL_VALUE_TYPE
&inf
)
280 if (MODE_COMPOSITE_P (mode
)
281 && (real_isdenormal (&value
, mode
) || real_iszero (&value
)))
283 // IBM extended denormals only have DFmode precision.
284 REAL_VALUE_TYPE tmp
, tmp2
;
285 real_convert (&tmp2
, DFmode
, &value
);
286 real_nextafter (&tmp
, REAL_MODE_FORMAT (DFmode
), &tmp2
, &inf
);
287 real_convert (&value
, mode
, &tmp
);
292 real_nextafter (&tmp
, REAL_MODE_FORMAT (mode
), &value
, &inf
);
297 // Like real_arithmetic, but round the result to INF if the operation
298 // produced inexact results.
300 // ?? There is still one problematic case, i387. With
301 // -fexcess-precision=standard we perform most SF/DFmode arithmetic in
302 // XFmode (long_double_type_node), so that case is OK. But without
303 // -mfpmath=sse, all the SF/DFmode computations are in XFmode
304 // precision (64-bit mantissa) and only occasionally rounded to
305 // SF/DFmode (when storing into memory from the 387 stack). Maybe
306 // this is ok as well though it is just occasionally more precise. ??
309 frange_arithmetic (enum tree_code code
, tree type
,
310 REAL_VALUE_TYPE
&result
,
311 const REAL_VALUE_TYPE
&op1
,
312 const REAL_VALUE_TYPE
&op2
,
313 const REAL_VALUE_TYPE
&inf
)
315 REAL_VALUE_TYPE value
;
316 enum machine_mode mode
= TYPE_MODE (type
);
317 bool mode_composite
= MODE_COMPOSITE_P (mode
);
319 bool inexact
= real_arithmetic (&value
, code
, &op1
, &op2
);
320 real_convert (&result
, mode
, &value
);
322 // Be extra careful if there may be discrepancies between the
323 // compile and runtime results.
329 bool low
= real_isneg (&inf
);
330 round
= (low
? !real_less (&result
, &value
)
331 : !real_less (&value
, &result
));
332 if (real_isinf (&result
, !low
)
333 && !real_isinf (&value
)
334 && !flag_rounding_math
)
336 // Use just [+INF, +INF] rather than [MAX, +INF]
337 // even if value is larger than MAX and rounds to
338 // nearest to +INF. Similarly just [-INF, -INF]
339 // rather than [-INF, +MAX] even if value is smaller
340 // than -MAX and rounds to nearest to -INF.
341 // Unless INEXACT is true, in that case we need some
347 REAL_VALUE_TYPE tmp
= result
, tmp2
;
348 frange_nextafter (mode
, tmp
, inf
);
349 // TMP is at this point the maximum representable
351 real_arithmetic (&tmp2
, MINUS_EXPR
, &value
, &tmp
);
352 if (real_isneg (&tmp2
) != low
353 && (REAL_EXP (&tmp2
) - REAL_EXP (&tmp
)
354 >= 2 - REAL_MODE_FORMAT (mode
)->p
))
359 if (round
&& (inexact
|| !real_identical (&result
, &value
)))
362 && (real_isdenormal (&result
, mode
) || real_iszero (&result
)))
364 // IBM extended denormals only have DFmode precision.
365 REAL_VALUE_TYPE tmp
, tmp2
;
366 real_convert (&tmp2
, DFmode
, &value
);
367 real_nextafter (&tmp
, REAL_MODE_FORMAT (DFmode
), &tmp2
, &inf
);
368 real_convert (&result
, mode
, &tmp
);
371 frange_nextafter (mode
, result
, inf
);
378 // ibm-ldouble-format documents 1ulp for + and -.
379 frange_nextafter (mode
, result
, inf
);
382 // ibm-ldouble-format documents 2ulps for *.
383 frange_nextafter (mode
, result
, inf
);
384 frange_nextafter (mode
, result
, inf
);
387 // ibm-ldouble-format documents 3ulps for /.
388 frange_nextafter (mode
, result
, inf
);
389 frange_nextafter (mode
, result
, inf
);
390 frange_nextafter (mode
, result
, inf
);
397 // Crop R to [-INF, MAX] where MAX is the maximum representable number
401 frange_drop_inf (frange
&r
, tree type
)
403 REAL_VALUE_TYPE max
= real_max_representable (type
);
404 frange
tmp (type
, r
.lower_bound (), max
);
408 // Crop R to [MIN, +INF] where MIN is the minimum representable number
412 frange_drop_ninf (frange
&r
, tree type
)
414 REAL_VALUE_TYPE min
= real_min_representable (type
);
415 frange
tmp (type
, min
, r
.upper_bound ());
419 // Crop R to [MIN, MAX] where MAX is the maximum representable number
420 // for TYPE and MIN the minimum representable number for TYPE.
423 frange_drop_infs (frange
&r
, tree type
)
425 REAL_VALUE_TYPE max
= real_max_representable (type
);
426 REAL_VALUE_TYPE min
= real_min_representable (type
);
427 frange
tmp (type
, min
, max
);
431 // If zero is in R, make sure both -0.0 and +0.0 are in the range.
434 frange_add_zeros (frange
&r
, tree type
)
436 if (r
.undefined_p () || r
.known_isnan ())
439 if (HONOR_SIGNED_ZEROS (type
)
440 && (real_iszero (&r
.lower_bound ()) || real_iszero (&r
.upper_bound ())))
443 zero
.set_zero (type
);
448 // Build a range that is <= VAL and store it in R. Return TRUE if
449 // further changes may be needed for R, or FALSE if R is in its final
453 build_le (frange
&r
, tree type
, const frange
&val
)
455 gcc_checking_assert (!val
.known_isnan ());
457 REAL_VALUE_TYPE ninf
= frange_val_min (type
);
458 r
.set (type
, ninf
, val
.upper_bound ());
460 // Add both zeros if there's the possibility of zero equality.
461 frange_add_zeros (r
, type
);
466 // Build a range that is < VAL and store it in R. Return TRUE if
467 // further changes may be needed for R, or FALSE if R is in its final
471 build_lt (frange
&r
, tree type
, const frange
&val
)
473 gcc_checking_assert (!val
.known_isnan ());
475 // < -INF is outside the range.
476 if (real_isinf (&val
.upper_bound (), 1))
478 if (HONOR_NANS (type
))
485 REAL_VALUE_TYPE ninf
= frange_val_min (type
);
486 REAL_VALUE_TYPE prev
= val
.upper_bound ();
487 machine_mode mode
= TYPE_MODE (type
);
488 // Default to the conservatively correct closed ranges for
489 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
490 // !HONOR_INFINITIES, nextafter will yield -INF, but frange::set()
491 // will crop the range appropriately.
492 if (!MODE_COMPOSITE_P (mode
))
493 frange_nextafter (mode
, prev
, ninf
);
494 r
.set (type
, ninf
, prev
);
498 // Build a range that is >= VAL and store it in R. Return TRUE if
499 // further changes may be needed for R, or FALSE if R is in its final
503 build_ge (frange
&r
, tree type
, const frange
&val
)
505 gcc_checking_assert (!val
.known_isnan ());
507 REAL_VALUE_TYPE inf
= frange_val_max (type
);
508 r
.set (type
, val
.lower_bound (), inf
);
510 // Add both zeros if there's the possibility of zero equality.
511 frange_add_zeros (r
, type
);
516 // Build a range that is > VAL and store it in R. Return TRUE if
517 // further changes may be needed for R, or FALSE if R is in its final
521 build_gt (frange
&r
, tree type
, const frange
&val
)
523 gcc_checking_assert (!val
.known_isnan ());
525 // > +INF is outside the range.
526 if (real_isinf (&val
.lower_bound (), 0))
528 if (HONOR_NANS (type
))
535 REAL_VALUE_TYPE inf
= frange_val_max (type
);
536 REAL_VALUE_TYPE next
= val
.lower_bound ();
537 machine_mode mode
= TYPE_MODE (type
);
538 // Default to the conservatively correct closed ranges for
539 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
540 // !HONOR_INFINITIES, nextafter will yield +INF, but frange::set()
541 // will crop the range appropriately.
542 if (!MODE_COMPOSITE_P (mode
))
543 frange_nextafter (mode
, next
, inf
);
544 r
.set (type
, next
, inf
);
549 class foperator_identity
: public range_operator_float
551 using range_operator_float::fold_range
;
552 using range_operator_float::op1_range
;
554 bool fold_range (frange
&r
, tree type ATTRIBUTE_UNUSED
,
555 const frange
&op1
, const frange
&op2 ATTRIBUTE_UNUSED
,
556 relation_trio
= TRIO_VARYING
) const final override
561 bool op1_range (frange
&r
, tree type ATTRIBUTE_UNUSED
,
562 const frange
&lhs
, const frange
&op2 ATTRIBUTE_UNUSED
,
563 relation_trio
= TRIO_VARYING
) const final override
571 class foperator_equal
: public range_operator_float
573 using range_operator_float::fold_range
;
574 using range_operator_float::op1_range
;
575 using range_operator_float::op2_range
;
576 using range_operator_float::op1_op2_relation
;
578 bool fold_range (irange
&r
, tree type
,
579 const frange
&op1
, const frange
&op2
,
580 relation_trio
= TRIO_VARYING
) const final override
;
581 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
583 return equal_op1_op2_relation (lhs
);
585 bool op1_range (frange
&r
, tree type
,
586 const irange
&lhs
, const frange
&op2
,
587 relation_trio
= TRIO_VARYING
) const final override
;
588 bool op2_range (frange
&r
, tree type
,
589 const irange
&lhs
, const frange
&op1
,
590 relation_trio rel
= TRIO_VARYING
) const final override
592 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
597 foperator_equal::fold_range (irange
&r
, tree type
,
598 const frange
&op1
, const frange
&op2
,
599 relation_trio rel
) const
601 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_EQ
))
604 if (op1
.known_isnan () || op2
.known_isnan ())
605 r
= range_false (type
);
606 // We can be sure the values are always equal or not if both ranges
607 // consist of a single value, and then compare them.
608 else if (op1
.singleton_p () && op2
.singleton_p ())
611 r
= range_true (type
);
612 // If one operand is -0.0 and other 0.0, they are still equal.
613 else if (real_iszero (&op1
.lower_bound ())
614 && real_iszero (&op2
.lower_bound ()))
615 r
= range_true (type
);
617 r
= range_false (type
);
619 else if (real_iszero (&op1
.lower_bound ())
620 && real_iszero (&op1
.upper_bound ())
621 && real_iszero (&op2
.lower_bound ())
622 && real_iszero (&op2
.upper_bound ())
623 && !maybe_isnan (op1
, op2
))
624 // [-0.0, 0.0] == [-0.0, 0.0] or similar.
625 r
= range_true (type
);
628 // If ranges do not intersect, we know the range is not equal,
629 // otherwise we don't know anything for sure.
632 if (tmp
.undefined_p ())
634 // If one range is [whatever, -0.0] and another
635 // [0.0, whatever2], we don't know anything either,
636 // because -0.0 == 0.0.
637 if ((real_iszero (&op1
.upper_bound ())
638 && real_iszero (&op2
.lower_bound ()))
639 || (real_iszero (&op1
.lower_bound ())
640 && real_iszero (&op2
.upper_bound ())))
641 r
= range_true_and_false (type
);
643 r
= range_false (type
);
646 r
= range_true_and_false (type
);
652 foperator_equal::op1_range (frange
&r
, tree type
,
655 relation_trio trio
) const
657 relation_kind rel
= trio
.op1_op2 ();
658 switch (get_bool_state (r
, lhs
, type
))
661 // The TRUE side of x == NAN is unreachable.
662 if (op2
.known_isnan ())
666 // If it's true, the result is the same as OP2.
668 // Add both zeros if there's the possibility of zero equality.
669 frange_add_zeros (r
, type
);
670 // The TRUE side of op1 == op2 implies op1 is !NAN.
676 // The FALSE side of op1 == op1 implies op1 is a NAN.
679 // On the FALSE side of x == NAN, we know nothing about x.
680 else if (op2
.known_isnan ())
681 r
.set_varying (type
);
682 // If the result is false, the only time we know anything is
683 // if OP2 is a constant.
684 else if (op2
.singleton_p ()
685 || (!op2
.maybe_isnan () && op2
.zero_p ()))
687 REAL_VALUE_TYPE tmp
= op2
.lower_bound ();
688 r
.set (type
, tmp
, tmp
, VR_ANTI_RANGE
);
691 r
.set_varying (type
);
700 class foperator_not_equal
: public range_operator_float
702 using range_operator_float::fold_range
;
703 using range_operator_float::op1_range
;
704 using range_operator_float::op1_op2_relation
;
706 bool fold_range (irange
&r
, tree type
,
707 const frange
&op1
, const frange
&op2
,
708 relation_trio rel
= TRIO_VARYING
) const final override
;
709 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
711 return not_equal_op1_op2_relation (lhs
);
713 bool op1_range (frange
&r
, tree type
,
714 const irange
&lhs
, const frange
&op2
,
715 relation_trio
= TRIO_VARYING
) const final override
;
719 foperator_not_equal::fold_range (irange
&r
, tree type
,
720 const frange
&op1
, const frange
&op2
,
721 relation_trio rel
) const
723 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_NE
))
726 // x != NAN is always TRUE.
727 if (op1
.known_isnan () || op2
.known_isnan ())
728 r
= range_true (type
);
729 // We can be sure the values are always equal or not if both ranges
730 // consist of a single value, and then compare them.
731 else if (op1
.singleton_p () && op2
.singleton_p ())
734 r
= range_false (type
);
735 // If one operand is -0.0 and other 0.0, they are still equal.
736 else if (real_iszero (&op1
.lower_bound ())
737 && real_iszero (&op2
.lower_bound ()))
738 r
= range_false (type
);
740 r
= range_true (type
);
742 else if (real_iszero (&op1
.lower_bound ())
743 && real_iszero (&op1
.upper_bound ())
744 && real_iszero (&op2
.lower_bound ())
745 && real_iszero (&op2
.upper_bound ())
746 && !maybe_isnan (op1
, op2
))
747 // [-0.0, 0.0] != [-0.0, 0.0] or similar.
748 r
= range_false (type
);
751 // If ranges do not intersect, we know the range is not equal,
752 // otherwise we don't know anything for sure.
755 if (tmp
.undefined_p ())
757 // If one range is [whatever, -0.0] and another
758 // [0.0, whatever2], we don't know anything either,
759 // because -0.0 == 0.0.
760 if ((real_iszero (&op1
.upper_bound ())
761 && real_iszero (&op2
.lower_bound ()))
762 || (real_iszero (&op1
.lower_bound ())
763 && real_iszero (&op2
.upper_bound ())))
764 r
= range_true_and_false (type
);
766 r
= range_true (type
);
769 r
= range_true_and_false (type
);
775 foperator_not_equal::op1_range (frange
&r
, tree type
,
778 relation_trio trio
) const
780 relation_kind rel
= trio
.op1_op2 ();
781 switch (get_bool_state (r
, lhs
, type
))
784 // If the result is true, the only time we know anything is if
785 // OP2 is a constant.
786 if (op2
.singleton_p ())
788 // This is correct even if op1 is NAN, because the following
789 // range would be ~[tmp, tmp] with the NAN property set to
791 REAL_VALUE_TYPE tmp
= op2
.lower_bound ();
792 r
.set (type
, tmp
, tmp
, VR_ANTI_RANGE
);
794 // The TRUE side of op1 != op1 implies op1 is NAN.
795 else if (rel
== VREL_EQ
)
798 r
.set_varying (type
);
802 // The FALSE side of x != NAN is impossible.
803 if (op2
.known_isnan ())
807 // If it's false, the result is the same as OP2.
809 // Add both zeros if there's the possibility of zero equality.
810 frange_add_zeros (r
, type
);
811 // The FALSE side of op1 != op2 implies op1 is !NAN.
822 class foperator_lt
: public range_operator_float
824 using range_operator_float::fold_range
;
825 using range_operator_float::op1_range
;
826 using range_operator_float::op2_range
;
827 using range_operator_float::op1_op2_relation
;
829 bool fold_range (irange
&r
, tree type
,
830 const frange
&op1
, const frange
&op2
,
831 relation_trio
= TRIO_VARYING
) const final override
;
832 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
834 return lt_op1_op2_relation (lhs
);
836 bool op1_range (frange
&r
, tree type
,
837 const irange
&lhs
, const frange
&op2
,
838 relation_trio
= TRIO_VARYING
) const final override
;
839 bool op2_range (frange
&r
, tree type
,
840 const irange
&lhs
, const frange
&op1
,
841 relation_trio
= TRIO_VARYING
) const final override
;
845 foperator_lt::fold_range (irange
&r
, tree type
,
846 const frange
&op1
, const frange
&op2
,
847 relation_trio rel
) const
849 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_LT
))
852 if (op1
.known_isnan ()
853 || op2
.known_isnan ()
854 || !real_less (&op1
.lower_bound (), &op2
.upper_bound ()))
855 r
= range_false (type
);
856 else if (!maybe_isnan (op1
, op2
)
857 && real_less (&op1
.upper_bound (), &op2
.lower_bound ()))
858 r
= range_true (type
);
860 r
= range_true_and_false (type
);
865 foperator_lt::op1_range (frange
&r
,
871 switch (get_bool_state (r
, lhs
, type
))
874 // The TRUE side of x < NAN is unreachable.
875 if (op2
.known_isnan ())
877 else if (op2
.undefined_p ())
879 else if (build_lt (r
, type
, op2
))
882 // x < y implies x is not +INF.
883 frange_drop_inf (r
, type
);
888 // On the FALSE side of x < NAN, we know nothing about x.
889 if (op2
.known_isnan () || op2
.maybe_isnan ())
890 r
.set_varying (type
);
892 build_ge (r
, type
, op2
);
902 foperator_lt::op2_range (frange
&r
,
908 switch (get_bool_state (r
, lhs
, type
))
911 // The TRUE side of NAN < x is unreachable.
912 if (op1
.known_isnan ())
914 else if (op1
.undefined_p ())
916 else if (build_gt (r
, type
, op1
))
919 // x < y implies y is not -INF.
920 frange_drop_ninf (r
, type
);
925 // On the FALSE side of NAN < x, we know nothing about x.
926 if (op1
.known_isnan () || op1
.maybe_isnan ())
927 r
.set_varying (type
);
929 build_le (r
, type
, op1
);
938 class foperator_le
: public range_operator_float
940 using range_operator_float::fold_range
;
941 using range_operator_float::op1_range
;
942 using range_operator_float::op2_range
;
943 using range_operator_float::op1_op2_relation
;
945 bool fold_range (irange
&r
, tree type
,
946 const frange
&op1
, const frange
&op2
,
947 relation_trio rel
= TRIO_VARYING
) const final override
;
948 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
950 return le_op1_op2_relation (lhs
);
952 bool op1_range (frange
&r
, tree type
,
953 const irange
&lhs
, const frange
&op2
,
954 relation_trio rel
= TRIO_VARYING
) const final override
;
955 bool op2_range (frange
&r
, tree type
,
956 const irange
&lhs
, const frange
&op1
,
957 relation_trio rel
= TRIO_VARYING
) const final override
;
961 foperator_le::fold_range (irange
&r
, tree type
,
962 const frange
&op1
, const frange
&op2
,
963 relation_trio rel
) const
965 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_LE
))
968 if (op1
.known_isnan ()
969 || op2
.known_isnan ()
970 || !real_compare (LE_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
971 r
= range_false (type
);
972 else if (!maybe_isnan (op1
, op2
)
973 && real_compare (LE_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
974 r
= range_true (type
);
976 r
= range_true_and_false (type
);
981 foperator_le::op1_range (frange
&r
,
987 switch (get_bool_state (r
, lhs
, type
))
990 // The TRUE side of x <= NAN is unreachable.
991 if (op2
.known_isnan ())
993 else if (op2
.undefined_p ())
995 else if (build_le (r
, type
, op2
))
1000 // On the FALSE side of x <= NAN, we know nothing about x.
1001 if (op2
.known_isnan () || op2
.maybe_isnan ())
1002 r
.set_varying (type
);
1004 build_gt (r
, type
, op2
);
1014 foperator_le::op2_range (frange
&r
,
1018 relation_trio
) const
1020 switch (get_bool_state (r
, lhs
, type
))
1023 // The TRUE side of NAN <= x is unreachable.
1024 if (op1
.known_isnan ())
1026 else if (op1
.undefined_p ())
1028 else if (build_ge (r
, type
, op1
))
1033 // On the FALSE side of NAN <= x, we know nothing about x.
1034 if (op1
.known_isnan () || op1
.maybe_isnan ())
1035 r
.set_varying (type
);
1036 else if (op1
.undefined_p ())
1039 build_lt (r
, type
, op1
);
1048 class foperator_gt
: public range_operator_float
1050 using range_operator_float::fold_range
;
1051 using range_operator_float::op1_range
;
1052 using range_operator_float::op2_range
;
1053 using range_operator_float::op1_op2_relation
;
1055 bool fold_range (irange
&r
, tree type
,
1056 const frange
&op1
, const frange
&op2
,
1057 relation_trio
= TRIO_VARYING
) const final override
;
1058 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
1060 return gt_op1_op2_relation (lhs
);
1062 bool op1_range (frange
&r
, tree type
,
1063 const irange
&lhs
, const frange
&op2
,
1064 relation_trio
= TRIO_VARYING
) const final override
;
1065 bool op2_range (frange
&r
, tree type
,
1066 const irange
&lhs
, const frange
&op1
,
1067 relation_trio
= TRIO_VARYING
) const final override
;
1071 foperator_gt::fold_range (irange
&r
, tree type
,
1072 const frange
&op1
, const frange
&op2
,
1073 relation_trio rel
) const
1075 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_GT
))
1078 if (op1
.known_isnan ()
1079 || op2
.known_isnan ()
1080 || !real_compare (GT_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
1081 r
= range_false (type
);
1082 else if (!maybe_isnan (op1
, op2
)
1083 && real_compare (GT_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
1084 r
= range_true (type
);
1086 r
= range_true_and_false (type
);
1091 foperator_gt::op1_range (frange
&r
,
1095 relation_trio
) const
1097 switch (get_bool_state (r
, lhs
, type
))
1100 // The TRUE side of x > NAN is unreachable.
1101 if (op2
.known_isnan ())
1103 else if (op2
.undefined_p ())
1105 else if (build_gt (r
, type
, op2
))
1108 // x > y implies x is not -INF.
1109 frange_drop_ninf (r
, type
);
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 ())
1120 build_le (r
, type
, op2
);
1130 foperator_gt::op2_range (frange
&r
,
1134 relation_trio
) const
1136 switch (get_bool_state (r
, lhs
, type
))
1139 // The TRUE side of NAN > x is unreachable.
1140 if (op1
.known_isnan ())
1142 else if (op1
.undefined_p ())
1144 else if (build_lt (r
, type
, op1
))
1147 // x > y implies y is not +INF.
1148 frange_drop_inf (r
, type
);
1153 // On The FALSE side of NAN > x, we know nothing about x.
1154 if (op1
.known_isnan () || op1
.maybe_isnan ())
1155 r
.set_varying (type
);
1156 else if (op1
.undefined_p ())
1159 build_ge (r
, type
, op1
);
1168 class foperator_ge
: public range_operator_float
1170 using range_operator_float::fold_range
;
1171 using range_operator_float::op1_range
;
1172 using range_operator_float::op2_range
;
1173 using range_operator_float::op1_op2_relation
;
1175 bool fold_range (irange
&r
, tree type
,
1176 const frange
&op1
, const frange
&op2
,
1177 relation_trio
= TRIO_VARYING
) const final override
;
1178 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
1180 return ge_op1_op2_relation (lhs
);
1182 bool op1_range (frange
&r
, tree type
,
1183 const irange
&lhs
, const frange
&op2
,
1184 relation_trio
= TRIO_VARYING
) const final override
;
1185 bool op2_range (frange
&r
, tree type
,
1186 const irange
&lhs
, const frange
&op1
,
1187 relation_trio
= TRIO_VARYING
) const final override
;
1191 foperator_ge::fold_range (irange
&r
, tree type
,
1192 const frange
&op1
, const frange
&op2
,
1193 relation_trio rel
) const
1195 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_GE
))
1198 if (op1
.known_isnan ()
1199 || op2
.known_isnan ()
1200 || !real_compare (GE_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
1201 r
= range_false (type
);
1202 else if (!maybe_isnan (op1
, op2
)
1203 && real_compare (GE_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
1204 r
= range_true (type
);
1206 r
= range_true_and_false (type
);
1211 foperator_ge::op1_range (frange
&r
,
1215 relation_trio
) const
1217 switch (get_bool_state (r
, lhs
, type
))
1220 // The TRUE side of x >= NAN is unreachable.
1221 if (op2
.known_isnan ())
1223 else if (op2
.undefined_p ())
1225 else if (build_ge (r
, type
, op2
))
1230 // On the FALSE side of x >= NAN, we know nothing about x.
1231 if (op2
.known_isnan () || op2
.maybe_isnan ())
1232 r
.set_varying (type
);
1233 else if (op2
.undefined_p ())
1236 build_lt (r
, type
, op2
);
1246 foperator_ge::op2_range (frange
&r
, tree type
,
1249 relation_trio
) const
1251 switch (get_bool_state (r
, lhs
, type
))
1254 // The TRUE side of NAN >= x is unreachable.
1255 if (op1
.known_isnan ())
1257 else if (op1
.undefined_p ())
1259 else if (build_le (r
, type
, op1
))
1264 // On the FALSE side of NAN >= x, we know nothing about x.
1265 if (op1
.known_isnan () || op1
.maybe_isnan ())
1266 r
.set_varying (type
);
1267 else if (op1
.undefined_p ())
1270 build_gt (r
, type
, op1
);
1279 // UNORDERED_EXPR comparison.
1281 class foperator_unordered
: public range_operator_float
1283 using range_operator_float::fold_range
;
1284 using range_operator_float::op1_range
;
1285 using range_operator_float::op2_range
;
1287 bool fold_range (irange
&r
, tree type
,
1288 const frange
&op1
, const frange
&op2
,
1289 relation_trio
= TRIO_VARYING
) const final override
;
1290 bool op1_range (frange
&r
, tree type
,
1291 const irange
&lhs
, const frange
&op2
,
1292 relation_trio
= TRIO_VARYING
) const final override
;
1293 bool op2_range (frange
&r
, tree type
,
1294 const irange
&lhs
, const frange
&op1
,
1295 relation_trio rel
= TRIO_VARYING
) const final override
1297 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
1302 foperator_unordered::fold_range (irange
&r
, tree type
,
1303 const frange
&op1
, const frange
&op2
,
1304 relation_trio
) const
1306 // UNORDERED is TRUE if either operand is a NAN.
1307 if (op1
.known_isnan () || op2
.known_isnan ())
1308 r
= range_true (type
);
1309 // UNORDERED is FALSE if neither operand is a NAN.
1310 else if (!op1
.maybe_isnan () && !op2
.maybe_isnan ())
1311 r
= range_false (type
);
1313 r
= range_true_and_false (type
);
1318 foperator_unordered::op1_range (frange
&r
, tree type
,
1321 relation_trio trio
) const
1323 relation_kind rel
= trio
.op1_op2 ();
1324 switch (get_bool_state (r
, lhs
, type
))
1327 // Since at least one operand must be NAN, if one of them is
1328 // not, the other must be.
1329 if (rel
== VREL_EQ
|| !op2
.maybe_isnan ())
1332 r
.set_varying (type
);
1336 // A false UNORDERED means both operands are !NAN, so it's
1337 // impossible for op2 to be a NAN.
1338 if (op2
.known_isnan ())
1342 r
.set_varying (type
);
1353 // ORDERED_EXPR comparison.
1355 class foperator_ordered
: public range_operator_float
1357 using range_operator_float::fold_range
;
1358 using range_operator_float::op1_range
;
1359 using range_operator_float::op2_range
;
1361 bool fold_range (irange
&r
, tree type
,
1362 const frange
&op1
, const frange
&op2
,
1363 relation_trio
= TRIO_VARYING
) const final override
;
1364 bool op1_range (frange
&r
, tree type
,
1365 const irange
&lhs
, const frange
&op2
,
1366 relation_trio
= TRIO_VARYING
) const final override
;
1367 bool op2_range (frange
&r
, tree type
,
1368 const irange
&lhs
, const frange
&op1
,
1369 relation_trio rel
= TRIO_VARYING
) const final override
1371 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
1376 foperator_ordered::fold_range (irange
&r
, tree type
,
1377 const frange
&op1
, const frange
&op2
,
1378 relation_trio
) const
1380 if (op1
.known_isnan () || op2
.known_isnan ())
1381 r
= range_false (type
);
1382 else if (!op1
.maybe_isnan () && !op2
.maybe_isnan ())
1383 r
= range_true (type
);
1385 r
= range_true_and_false (type
);
1390 foperator_ordered::op1_range (frange
&r
, tree type
,
1393 relation_trio trio
) const
1395 relation_kind rel
= trio
.op1_op2 ();
1396 switch (get_bool_state (r
, lhs
, type
))
1399 // The TRUE side of ORDERED means both operands are !NAN, so
1400 // it's impossible for op2 to be a NAN.
1401 if (op2
.known_isnan ())
1405 r
.set_varying (type
);
1411 // The FALSE side of op1 ORDERED op1 implies op1 is NAN.
1415 r
.set_varying (type
);
1424 class foperator_negate
: public range_operator_float
1426 using range_operator_float::fold_range
;
1427 using range_operator_float::op1_range
;
1429 bool fold_range (frange
&r
, tree type
,
1430 const frange
&op1
, const frange
&op2
,
1431 relation_trio
= TRIO_VARYING
) const final override
1433 if (empty_range_varying (r
, type
, op1
, op2
))
1435 if (op1
.known_isnan ())
1438 if (op1
.nan_signbit_p (sign
))
1439 r
.set_nan (type
, !sign
);
1445 REAL_VALUE_TYPE lh_lb
= op1
.lower_bound ();
1446 REAL_VALUE_TYPE lh_ub
= op1
.upper_bound ();
1447 lh_lb
= real_value_negate (&lh_lb
);
1448 lh_ub
= real_value_negate (&lh_ub
);
1449 r
.set (type
, lh_ub
, lh_lb
);
1450 if (op1
.maybe_isnan ())
1453 if (op1
.nan_signbit_p (sign
))
1454 r
.update_nan (!sign
);
1462 bool op1_range (frange
&r
, tree type
,
1463 const frange
&lhs
, const frange
&op2
,
1464 relation_trio rel
= TRIO_VARYING
) const final override
1466 return fold_range (r
, type
, lhs
, op2
, rel
);
1470 class foperator_abs
: public range_operator_float
1472 using range_operator_float::fold_range
;
1473 using range_operator_float::op1_range
;
1475 bool fold_range (frange
&r
, tree type
,
1476 const frange
&op1
, const frange
&,
1477 relation_trio
= TRIO_VARYING
) const final override
;
1478 bool op1_range (frange
&r
, tree type
,
1479 const frange
&lhs
, const frange
&op2
,
1480 relation_trio rel
= TRIO_VARYING
) const final override
;
1484 foperator_abs::fold_range (frange
&r
, tree type
,
1485 const frange
&op1
, const frange
&op2
,
1486 relation_trio
) const
1488 if (empty_range_varying (r
, type
, op1
, op2
))
1490 if (op1
.known_isnan ())
1492 r
.set_nan (type
, /*sign=*/false);
1496 const REAL_VALUE_TYPE lh_lb
= op1
.lower_bound ();
1497 const REAL_VALUE_TYPE lh_ub
= op1
.upper_bound ();
1498 // Handle the easy case where everything is positive.
1499 if (real_compare (GE_EXPR
, &lh_lb
, &dconst0
)
1500 && !real_iszero (&lh_lb
, /*sign=*/true)
1501 && !op1
.maybe_isnan (/*sign=*/true))
1507 REAL_VALUE_TYPE min
= real_value_abs (&lh_lb
);
1508 REAL_VALUE_TYPE max
= real_value_abs (&lh_ub
);
1509 // If the range contains zero then we know that the minimum value in the
1510 // range will be zero.
1511 if (real_compare (LE_EXPR
, &lh_lb
, &dconst0
)
1512 && real_compare (GE_EXPR
, &lh_ub
, &dconst0
))
1514 if (real_compare (GT_EXPR
, &min
, &max
))
1520 // If the range was reversed, swap MIN and MAX.
1521 if (real_compare (GT_EXPR
, &min
, &max
))
1522 std::swap (min
, max
);
1525 r
.set (type
, min
, max
);
1526 if (op1
.maybe_isnan ())
1527 r
.update_nan (/*sign=*/false);
1534 foperator_abs::op1_range (frange
&r
, tree type
,
1535 const frange
&lhs
, const frange
&op2
,
1536 relation_trio
) const
1538 if (empty_range_varying (r
, type
, lhs
, op2
))
1540 if (lhs
.known_isnan ())
1546 // Start with the positives because negatives are an impossible result.
1547 frange
positives (type
, dconst0
, frange_val_max (type
));
1548 positives
.update_nan (/*sign=*/false);
1549 positives
.intersect (lhs
);
1551 // Add -NAN if relevant.
1552 if (r
.maybe_isnan ())
1555 neg_nan
.set_nan (type
, true);
1558 if (r
.known_isnan () || r
.undefined_p ())
1560 // Then add the negative of each pair:
1561 // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
1562 frange
negatives (type
, real_value_negate (&positives
.upper_bound ()),
1563 real_value_negate (&positives
.lower_bound ()));
1564 negatives
.clear_nan ();
1565 r
.union_ (negatives
);
1569 class foperator_unordered_lt
: public range_operator_float
1571 using range_operator_float::fold_range
;
1572 using range_operator_float::op1_range
;
1573 using range_operator_float::op2_range
;
1575 bool fold_range (irange
&r
, tree type
,
1576 const frange
&op1
, const frange
&op2
,
1577 relation_trio rel
= TRIO_VARYING
) const final override
1579 if (op1
.known_isnan () || op2
.known_isnan ())
1581 r
= range_true (type
);
1584 frange op1_no_nan
= op1
;
1585 frange op2_no_nan
= op2
;
1586 if (op1
.maybe_isnan ())
1587 op1_no_nan
.clear_nan ();
1588 if (op2
.maybe_isnan ())
1589 op2_no_nan
.clear_nan ();
1590 if (!fop_lt
.fold_range (r
, type
, op1_no_nan
, op2_no_nan
, rel
))
1592 // The result is the same as the ordered version when the
1593 // comparison is true or when the operands cannot be NANs.
1594 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1598 r
= range_true_and_false (type
);
1602 bool op1_range (frange
&r
, tree type
,
1605 relation_trio trio
) const final override
;
1606 bool op2_range (frange
&r
, tree type
,
1609 relation_trio trio
) const final override
;
1613 foperator_unordered_lt::op1_range (frange
&r
, tree type
,
1616 relation_trio
) const
1618 switch (get_bool_state (r
, lhs
, type
))
1621 if (op2
.known_isnan () || op2
.maybe_isnan ())
1622 r
.set_varying (type
);
1623 else if (op2
.undefined_p ())
1626 build_lt (r
, type
, op2
);
1630 // A false UNORDERED_LT means both operands are !NAN, so it's
1631 // impossible for op2 to be a NAN.
1632 if (op2
.known_isnan ())
1634 else if (op2
.undefined_p ())
1636 else if (build_ge (r
, type
, op2
))
1647 foperator_unordered_lt::op2_range (frange
&r
, tree type
,
1650 relation_trio
) const
1652 switch (get_bool_state (r
, lhs
, type
))
1655 if (op1
.known_isnan () || op1
.maybe_isnan ())
1656 r
.set_varying (type
);
1657 else if (op1
.undefined_p ())
1660 build_gt (r
, type
, op1
);
1664 // A false UNORDERED_LT means both operands are !NAN, so it's
1665 // impossible for op1 to be a NAN.
1666 if (op1
.known_isnan ())
1668 else if (op1
.undefined_p ())
1670 else if (build_le (r
, type
, op1
))
1680 class foperator_unordered_le
: public range_operator_float
1682 using range_operator_float::fold_range
;
1683 using range_operator_float::op1_range
;
1684 using range_operator_float::op2_range
;
1686 bool fold_range (irange
&r
, tree type
,
1687 const frange
&op1
, const frange
&op2
,
1688 relation_trio rel
= TRIO_VARYING
) const final override
1690 if (op1
.known_isnan () || op2
.known_isnan ())
1692 r
= range_true (type
);
1695 frange op1_no_nan
= op1
;
1696 frange op2_no_nan
= op2
;
1697 if (op1
.maybe_isnan ())
1698 op1_no_nan
.clear_nan ();
1699 if (op2
.maybe_isnan ())
1700 op2_no_nan
.clear_nan ();
1701 if (!fop_le
.fold_range (r
, type
, op1_no_nan
, op2_no_nan
, rel
))
1703 // The result is the same as the ordered version when the
1704 // comparison is true or when the operands cannot be NANs.
1705 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1709 r
= range_true_and_false (type
);
1713 bool op1_range (frange
&r
, tree type
,
1714 const irange
&lhs
, const frange
&op2
,
1715 relation_trio
= TRIO_VARYING
) const final override
;
1716 bool op2_range (frange
&r
, tree type
,
1717 const irange
&lhs
, const frange
&op1
,
1718 relation_trio
= TRIO_VARYING
) const final override
;
1722 foperator_unordered_le::op1_range (frange
&r
, tree type
,
1723 const irange
&lhs
, const frange
&op2
,
1724 relation_trio
) const
1726 switch (get_bool_state (r
, lhs
, type
))
1729 if (op2
.known_isnan () || op2
.maybe_isnan ())
1730 r
.set_varying (type
);
1731 else if (op2
.undefined_p ())
1734 build_le (r
, type
, op2
);
1738 // A false UNORDERED_LE means both operands are !NAN, so it's
1739 // impossible for op2 to be a NAN.
1740 if (op2
.known_isnan ())
1742 else if (build_gt (r
, type
, op2
))
1753 foperator_unordered_le::op2_range (frange
&r
,
1757 relation_trio
) const
1759 switch (get_bool_state (r
, lhs
, type
))
1762 if (op1
.known_isnan () || op1
.maybe_isnan ())
1763 r
.set_varying (type
);
1764 else if (op1
.undefined_p ())
1767 build_ge (r
, type
, op1
);
1771 // A false UNORDERED_LE means both operands are !NAN, so it's
1772 // impossible for op1 to be a NAN.
1773 if (op1
.known_isnan ())
1775 else if (op1
.undefined_p ())
1777 else if (build_lt (r
, type
, op1
))
1787 class foperator_unordered_gt
: public range_operator_float
1789 using range_operator_float::fold_range
;
1790 using range_operator_float::op1_range
;
1791 using range_operator_float::op2_range
;
1793 bool fold_range (irange
&r
, tree type
,
1794 const frange
&op1
, const frange
&op2
,
1795 relation_trio rel
= TRIO_VARYING
) const final override
1797 if (op1
.known_isnan () || op2
.known_isnan ())
1799 r
= range_true (type
);
1802 frange op1_no_nan
= op1
;
1803 frange op2_no_nan
= op2
;
1804 if (op1
.maybe_isnan ())
1805 op1_no_nan
.clear_nan ();
1806 if (op2
.maybe_isnan ())
1807 op2_no_nan
.clear_nan ();
1808 if (!fop_gt
.fold_range (r
, type
, op1_no_nan
, op2_no_nan
, rel
))
1810 // The result is the same as the ordered version when the
1811 // comparison is true or when the operands cannot be NANs.
1812 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1816 r
= range_true_and_false (type
);
1820 bool op1_range (frange
&r
, tree type
,
1821 const irange
&lhs
, const frange
&op2
,
1822 relation_trio
= TRIO_VARYING
) const final override
;
1823 bool op2_range (frange
&r
, tree type
,
1824 const irange
&lhs
, const frange
&op1
,
1825 relation_trio
= TRIO_VARYING
) const final override
;
1829 foperator_unordered_gt::op1_range (frange
&r
,
1833 relation_trio
) const
1835 switch (get_bool_state (r
, lhs
, type
))
1838 if (op2
.known_isnan () || op2
.maybe_isnan ())
1839 r
.set_varying (type
);
1840 else if (op2
.undefined_p ())
1843 build_gt (r
, type
, op2
);
1847 // A false UNORDERED_GT means both operands are !NAN, so it's
1848 // impossible for op2 to be a NAN.
1849 if (op2
.known_isnan ())
1851 else if (op2
.undefined_p ())
1853 else if (build_le (r
, type
, op2
))
1864 foperator_unordered_gt::op2_range (frange
&r
,
1868 relation_trio
) const
1870 switch (get_bool_state (r
, lhs
, type
))
1873 if (op1
.known_isnan () || op1
.maybe_isnan ())
1874 r
.set_varying (type
);
1875 else if (op1
.undefined_p ())
1878 build_lt (r
, type
, op1
);
1882 // A false UNORDERED_GT means both operands are !NAN, so it's
1883 // impossible for op1 to be a NAN.
1884 if (op1
.known_isnan ())
1886 else if (op1
.undefined_p ())
1888 else if (build_ge (r
, type
, op1
))
1898 class foperator_unordered_ge
: public range_operator_float
1900 using range_operator_float::fold_range
;
1901 using range_operator_float::op1_range
;
1902 using range_operator_float::op2_range
;
1904 bool fold_range (irange
&r
, tree type
,
1905 const frange
&op1
, const frange
&op2
,
1906 relation_trio rel
= TRIO_VARYING
) const final override
1908 if (op1
.known_isnan () || op2
.known_isnan ())
1910 r
= range_true (type
);
1913 frange op1_no_nan
= op1
;
1914 frange op2_no_nan
= op2
;
1915 if (op1
.maybe_isnan ())
1916 op1_no_nan
.clear_nan ();
1917 if (op2
.maybe_isnan ())
1918 op2_no_nan
.clear_nan ();
1919 if (!fop_ge
.fold_range (r
, type
, op1_no_nan
, op2_no_nan
, rel
))
1921 // The result is the same as the ordered version when the
1922 // comparison is true or when the operands cannot be NANs.
1923 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1927 r
= range_true_and_false (type
);
1931 bool op1_range (frange
&r
, tree type
,
1932 const irange
&lhs
, const frange
&op2
,
1933 relation_trio
= TRIO_VARYING
) const final override
;
1934 bool op2_range (frange
&r
, tree type
,
1935 const irange
&lhs
, const frange
&op1
,
1936 relation_trio
= TRIO_VARYING
) const final override
;
1940 foperator_unordered_ge::op1_range (frange
&r
,
1944 relation_trio
) const
1946 switch (get_bool_state (r
, lhs
, type
))
1949 if (op2
.known_isnan () || op2
.maybe_isnan ())
1950 r
.set_varying (type
);
1951 else if (op2
.undefined_p ())
1954 build_ge (r
, type
, op2
);
1958 // A false UNORDERED_GE means both operands are !NAN, so it's
1959 // impossible for op2 to be a NAN.
1960 if (op2
.known_isnan ())
1962 else if (op2
.undefined_p ())
1964 else if (build_lt (r
, type
, op2
))
1975 foperator_unordered_ge::op2_range (frange
&r
, tree type
,
1978 relation_trio
) const
1980 switch (get_bool_state (r
, lhs
, type
))
1983 if (op1
.known_isnan () || op1
.maybe_isnan ())
1984 r
.set_varying (type
);
1985 else if (op1
.undefined_p ())
1988 build_le (r
, type
, op1
);
1992 // A false UNORDERED_GE means both operands are !NAN, so it's
1993 // impossible for op1 to be a NAN.
1994 if (op1
.known_isnan ())
1996 else if (op1
.undefined_p ())
1998 else if (build_gt (r
, type
, op1
))
2008 class foperator_unordered_equal
: public range_operator_float
2010 using range_operator_float::fold_range
;
2011 using range_operator_float::op1_range
;
2012 using range_operator_float::op2_range
;
2014 bool fold_range (irange
&r
, tree type
,
2015 const frange
&op1
, const frange
&op2
,
2016 relation_trio rel
= TRIO_VARYING
) const final override
2018 if (op1
.known_isnan () || op2
.known_isnan ())
2020 r
= range_true (type
);
2023 frange op1_no_nan
= op1
;
2024 frange op2_no_nan
= op2
;
2025 if (op1
.maybe_isnan ())
2026 op1_no_nan
.clear_nan ();
2027 if (op2
.maybe_isnan ())
2028 op2_no_nan
.clear_nan ();
2029 if (!fop_equal
.fold_range (r
, type
, op1_no_nan
, op2_no_nan
, rel
))
2031 // The result is the same as the ordered version when the
2032 // comparison is true or when the operands cannot be NANs.
2033 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
2037 r
= range_true_and_false (type
);
2041 bool op1_range (frange
&r
, tree type
,
2042 const irange
&lhs
, const frange
&op2
,
2043 relation_trio
= TRIO_VARYING
) const final override
;
2044 bool op2_range (frange
&r
, tree type
,
2045 const irange
&lhs
, const frange
&op1
,
2046 relation_trio rel
= TRIO_VARYING
) const final override
2048 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
2050 } fop_unordered_equal
;
2053 foperator_unordered_equal::op1_range (frange
&r
, tree type
,
2056 relation_trio
) const
2058 switch (get_bool_state (r
, lhs
, type
))
2061 // If it's true, the result is the same as OP2 plus a NAN.
2063 // Add both zeros if there's the possibility of zero equality.
2064 frange_add_zeros (r
, type
);
2065 // Add the possibility of a NAN.
2070 // A false UNORDERED_EQ means both operands are !NAN, so it's
2071 // impossible for op2 to be a NAN.
2072 if (op2
.known_isnan ())
2076 // The false side indicates !NAN and not equal. We can at least
2078 r
.set_varying (type
);
2089 class foperator_ltgt
: public range_operator_float
2091 using range_operator_float::fold_range
;
2092 using range_operator_float::op1_range
;
2093 using range_operator_float::op2_range
;
2095 bool fold_range (irange
&r
, tree type
,
2096 const frange
&op1
, const frange
&op2
,
2097 relation_trio rel
= TRIO_VARYING
) const final override
2099 if (op1
.known_isnan () || op2
.known_isnan ())
2101 r
= range_false (type
);
2104 frange op1_no_nan
= op1
;
2105 frange op2_no_nan
= op2
;
2106 if (op1
.maybe_isnan ())
2107 op1_no_nan
.clear_nan ();
2108 if (op2
.maybe_isnan ())
2109 op2_no_nan
.clear_nan ();
2110 if (!fop_not_equal
.fold_range (r
, type
, op1_no_nan
, op2_no_nan
, rel
))
2112 // The result is the same as the ordered version when the
2113 // comparison is true or when the operands cannot be NANs.
2114 if (!maybe_isnan (op1
, op2
) || r
== range_false (type
))
2118 r
= range_true_and_false (type
);
2122 bool op1_range (frange
&r
, tree type
,
2123 const irange
&lhs
, const frange
&op2
,
2124 relation_trio
= TRIO_VARYING
) const final override
;
2125 bool op2_range (frange
&r
, tree type
,
2126 const irange
&lhs
, const frange
&op1
,
2127 relation_trio rel
= TRIO_VARYING
) const final override
2129 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
2134 foperator_ltgt::op1_range (frange
&r
, tree type
,
2137 relation_trio
) const
2139 switch (get_bool_state (r
, lhs
, type
))
2142 // A true LTGT means both operands are !NAN, so it's
2143 // impossible for op2 to be a NAN.
2144 if (op2
.known_isnan ())
2148 // The true side indicates !NAN and not equal. We can at least
2150 r
.set_varying (type
);
2156 // If it's false, the result is the same as OP2 plus a NAN.
2158 // Add both zeros if there's the possibility of zero equality.
2159 frange_add_zeros (r
, type
);
2160 // Add the possibility of a NAN.
2170 // Final tweaks for float binary op op1_range/op2_range.
2171 // Return TRUE if the operation is performed and a valid range is available.
2174 float_binary_op_range_finish (bool ret
, frange
&r
, tree type
,
2175 const frange
&lhs
, bool div_op2
= false)
2180 // If we get a known NAN from reverse op, it means either that
2181 // the other operand was known NAN (in that case we know nothing),
2182 // or the reverse operation introduced a known NAN.
2183 // Say for lhs = op1 * op2 if lhs is [-0, +0] and op2 is too,
2184 // 0 / 0 is known NAN. Just punt in that case.
2185 // If NANs aren't honored, we get for 0 / 0 UNDEFINED, so punt as well.
2186 // Or if lhs is a known NAN, we also don't know anything.
2187 if (r
.known_isnan () || lhs
.known_isnan () || r
.undefined_p ())
2189 r
.set_varying (type
);
2193 // If lhs isn't NAN, then neither operand could be NAN,
2194 // even if the reverse operation does introduce a maybe_nan.
2195 if (!lhs
.maybe_isnan ())
2199 ? !(real_compare (LE_EXPR
, &lhs
.lower_bound (), &dconst0
)
2200 && real_compare (GE_EXPR
, &lhs
.upper_bound (), &dconst0
))
2201 : !(real_isinf (&lhs
.lower_bound ())
2202 || real_isinf (&lhs
.upper_bound ())))
2203 // For reverse + or - or * or op1 of /, if result is finite, then
2204 // r must be finite too, as X + INF or X - INF or X * INF or
2205 // INF / X is always +-INF or NAN. For op2 of /, if result is
2206 // non-zero and not NAN, r must be finite, as X / INF is always
2208 frange_drop_infs (r
, type
);
2210 // If lhs is a maybe or known NAN, the operand could be
2217 // True if [lb, ub] is [+-0, +-0].
2219 zero_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
2221 return real_iszero (&lb
) && real_iszero (&ub
);
2224 // True if +0 or -0 is in [lb, ub] range.
2226 contains_zero_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
2228 return (real_compare (LE_EXPR
, &lb
, &dconst0
)
2229 && real_compare (GE_EXPR
, &ub
, &dconst0
));
2232 // True if [lb, ub] is [-INF, -INF] or [+INF, +INF].
2234 singleton_inf_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
2236 return real_isinf (&lb
) && real_isinf (&ub
, real_isneg (&lb
));
2239 // Return -1 if binary op result must have sign bit set,
2240 // 1 if binary op result must have sign bit clear,
2242 // Sign bit of binary op result is exclusive or of the
2243 // operand's sign bits.
2245 signbit_known_p (const REAL_VALUE_TYPE
&lh_lb
, const REAL_VALUE_TYPE
&lh_ub
,
2246 const REAL_VALUE_TYPE
&rh_lb
, const REAL_VALUE_TYPE
&rh_ub
)
2248 if (real_isneg (&lh_lb
) == real_isneg (&lh_ub
)
2249 && real_isneg (&rh_lb
) == real_isneg (&rh_ub
))
2251 if (real_isneg (&lh_lb
) == real_isneg (&rh_ub
))
2259 // Set [lb, ub] to [-0, -0], [-0, +0] or [+0, +0] depending on
2262 zero_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
2265 if (signbit_known
<= 0)
2266 lb
= real_value_negate (&dconst0
);
2267 if (signbit_known
< 0)
2271 // Set [lb, ub] to [-INF, -INF], [-INF, +INF] or [+INF, +INF] depending on
2274 inf_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
2276 if (signbit_known
> 0)
2277 ub
= lb
= dconstinf
;
2278 else if (signbit_known
< 0)
2279 ub
= lb
= dconstninf
;
2287 // Set [lb, ub] to [-INF, -0], [-INF, +INF] or [+0, +INF] depending on
2290 zero_to_inf_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
2292 if (signbit_known
> 0)
2297 else if (signbit_known
< 0)
2300 ub
= real_value_negate (&dconst0
);
2309 /* Extend the LHS range by 1ulp in each direction. For op1_range
2310 or op2_range of binary operations just computing the inverse
2311 operation on ranges isn't sufficient. Consider e.g.
2312 [1., 1.] = op1 + [1., 1.]. op1's range is not [0., 0.], but
2313 [-0x1.0p-54, 0x1.0p-53] (when not -frounding-math), any value for
2314 which adding 1. to it results in 1. after rounding to nearest.
2315 So, for op1_range/op2_range extend the lhs range by 1ulp (or 0.5ulp)
2316 in each direction. See PR109008 for more details. */
2319 float_widen_lhs_range (tree type
, const frange
&lhs
)
2322 if (lhs
.known_isnan ())
2324 REAL_VALUE_TYPE lb
= lhs
.lower_bound ();
2325 REAL_VALUE_TYPE ub
= lhs
.upper_bound ();
2326 if (real_isfinite (&lb
))
2328 frange_nextafter (TYPE_MODE (type
), lb
, dconstninf
);
2329 if (real_isinf (&lb
))
2331 /* For -DBL_MAX, instead of -Inf use
2332 nexttoward (-DBL_MAX, -LDBL_MAX) in a hypothetical
2333 wider type with the same mantissa precision but larger
2334 exponent range; it is outside of range of double values,
2335 but makes it clear it is just one ulp larger rather than
2336 infinite amount larger. */
2338 SET_REAL_EXP (&lb
, FLOAT_MODE_FORMAT (TYPE_MODE (type
))->emax
+ 1);
2340 if (!flag_rounding_math
&& !MODE_COMPOSITE_P (TYPE_MODE (type
)))
2342 /* If not -frounding-math nor IBM double double, actually widen
2343 just by 0.5ulp rather than 1ulp. */
2344 REAL_VALUE_TYPE tem
;
2345 real_arithmetic (&tem
, PLUS_EXPR
, &lhs
.lower_bound (), &lb
);
2346 real_arithmetic (&lb
, RDIV_EXPR
, &tem
, &dconst2
);
2349 if (real_isfinite (&ub
))
2351 frange_nextafter (TYPE_MODE (type
), ub
, dconstinf
);
2352 if (real_isinf (&ub
))
2354 /* For DBL_MAX similarly. */
2356 SET_REAL_EXP (&ub
, FLOAT_MODE_FORMAT (TYPE_MODE (type
))->emax
+ 1);
2358 if (!flag_rounding_math
&& !MODE_COMPOSITE_P (TYPE_MODE (type
)))
2360 /* If not -frounding-math nor IBM double double, actually widen
2361 just by 0.5ulp rather than 1ulp. */
2362 REAL_VALUE_TYPE tem
;
2363 real_arithmetic (&tem
, PLUS_EXPR
, &lhs
.upper_bound (), &ub
);
2364 real_arithmetic (&ub
, RDIV_EXPR
, &tem
, &dconst2
);
2367 /* Temporarily disable -ffinite-math-only, so that frange::set doesn't
2368 reduce the range back to real_min_representable (type) as lower bound
2369 or real_max_representable (type) as upper bound. */
2370 bool save_flag_finite_math_only
= flag_finite_math_only
;
2371 flag_finite_math_only
= false;
2372 ret
.set (type
, lb
, ub
, lhs
.get_nan_state ());
2373 flag_finite_math_only
= save_flag_finite_math_only
;
2377 class foperator_plus
: public range_operator_float
2379 using range_operator_float::op1_range
;
2380 using range_operator_float::op2_range
;
2382 virtual bool op1_range (frange
&r
, tree type
,
2385 relation_trio
= TRIO_VARYING
) const final override
2387 if (lhs
.undefined_p ())
2389 range_op_handler
minus (MINUS_EXPR
, type
);
2392 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2393 return float_binary_op_range_finish (minus
.fold_range (r
, type
, wlhs
, op2
),
2396 virtual bool op2_range (frange
&r
, tree type
,
2399 relation_trio
= TRIO_VARYING
) const final override
2401 return op1_range (r
, type
, lhs
, op1
);
2404 void rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, bool &maybe_nan
,
2406 const REAL_VALUE_TYPE
&lh_lb
,
2407 const REAL_VALUE_TYPE
&lh_ub
,
2408 const REAL_VALUE_TYPE
&rh_lb
,
2409 const REAL_VALUE_TYPE
&rh_ub
,
2410 relation_kind
) const final override
2412 frange_arithmetic (PLUS_EXPR
, type
, lb
, lh_lb
, rh_lb
, dconstninf
);
2413 frange_arithmetic (PLUS_EXPR
, type
, ub
, lh_ub
, rh_ub
, dconstinf
);
2415 // [-INF] + [+INF] = NAN
2416 if (real_isinf (&lh_lb
, true) && real_isinf (&rh_ub
, false))
2418 // [+INF] + [-INF] = NAN
2419 else if (real_isinf (&lh_ub
, false) && real_isinf (&rh_lb
, true))
2427 class foperator_minus
: public range_operator_float
2429 using range_operator_float::op1_range
;
2430 using range_operator_float::op2_range
;
2432 virtual bool op1_range (frange
&r
, tree type
,
2435 relation_trio
= TRIO_VARYING
) const final override
2437 if (lhs
.undefined_p ())
2439 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2440 return float_binary_op_range_finish (fop_plus
.fold_range (r
, type
, wlhs
,
2444 virtual bool op2_range (frange
&r
, tree type
,
2447 relation_trio
= TRIO_VARYING
) const final override
2449 if (lhs
.undefined_p ())
2451 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2452 return float_binary_op_range_finish (fold_range (r
, type
, op1
, wlhs
),
2456 void rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, bool &maybe_nan
,
2458 const REAL_VALUE_TYPE
&lh_lb
,
2459 const REAL_VALUE_TYPE
&lh_ub
,
2460 const REAL_VALUE_TYPE
&rh_lb
,
2461 const REAL_VALUE_TYPE
&rh_ub
,
2462 relation_kind
) const final override
2464 frange_arithmetic (MINUS_EXPR
, type
, lb
, lh_lb
, rh_ub
, dconstninf
);
2465 frange_arithmetic (MINUS_EXPR
, type
, ub
, lh_ub
, rh_lb
, dconstinf
);
2467 // [+INF] - [+INF] = NAN
2468 if (real_isinf (&lh_ub
, false) && real_isinf (&rh_ub
, false))
2470 // [-INF] - [-INF] = NAN
2471 else if (real_isinf (&lh_lb
, true) && real_isinf (&rh_lb
, true))
2479 class foperator_mult_div_base
: public range_operator_float
2482 // Given CP[0] to CP[3] floating point values rounded to -INF,
2483 // set LB to the smallest of them (treating -0 as smaller to +0).
2484 // Given CP[4] to CP[7] floating point values rounded to +INF,
2485 // set UB to the largest of them (treating -0 as smaller to +0).
2486 static void find_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
,
2487 const REAL_VALUE_TYPE (&cp
)[8])
2491 for (int i
= 1; i
< 4; ++i
)
2493 if (real_less (&cp
[i
], &lb
)
2494 || (real_iszero (&lb
) && real_isnegzero (&cp
[i
])))
2496 if (real_less (&ub
, &cp
[i
+ 4])
2497 || (real_isnegzero (&ub
) && real_iszero (&cp
[i
+ 4])))
2504 class foperator_mult
: public foperator_mult_div_base
2506 using range_operator_float::op1_range
;
2507 using range_operator_float::op2_range
;
2509 virtual bool op1_range (frange
&r
, tree type
,
2512 relation_trio
= TRIO_VARYING
) const final override
2514 if (lhs
.undefined_p ())
2516 range_op_handler
rdiv (RDIV_EXPR
, type
);
2519 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2520 bool ret
= rdiv
.fold_range (r
, type
, wlhs
, op2
);
2523 if (wlhs
.known_isnan () || op2
.known_isnan () || op2
.undefined_p ())
2524 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2525 const REAL_VALUE_TYPE
&lhs_lb
= wlhs
.lower_bound ();
2526 const REAL_VALUE_TYPE
&lhs_ub
= wlhs
.upper_bound ();
2527 const REAL_VALUE_TYPE
&op2_lb
= op2
.lower_bound ();
2528 const REAL_VALUE_TYPE
&op2_ub
= op2
.upper_bound ();
2529 if ((contains_zero_p (lhs_lb
, lhs_ub
) && contains_zero_p (op2_lb
, op2_ub
))
2530 || ((real_isinf (&lhs_lb
) || real_isinf (&lhs_ub
))
2531 && (real_isinf (&op2_lb
) || real_isinf (&op2_ub
))))
2533 // If both lhs and op2 could be zeros or both could be infinities,
2534 // we don't know anything about op1 except maybe for the sign
2535 // and perhaps if it can be NAN or not.
2536 REAL_VALUE_TYPE lb
, ub
;
2537 int signbit_known
= signbit_known_p (lhs_lb
, lhs_ub
, op2_lb
, op2_ub
);
2538 zero_to_inf_range (lb
, ub
, signbit_known
);
2539 r
.set (type
, lb
, ub
);
2541 // Otherwise, if op2 is a singleton INF and lhs doesn't include INF,
2542 // or if lhs must be zero and op2 doesn't include zero, it would be
2543 // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF
2544 // range. Those are supersets of UNDEFINED, so let's keep that way.
2545 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2547 virtual bool op2_range (frange
&r
, tree type
,
2550 relation_trio
= TRIO_VARYING
) const final override
2552 return op1_range (r
, type
, lhs
, op1
);
2555 void rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, bool &maybe_nan
,
2557 const REAL_VALUE_TYPE
&lh_lb
,
2558 const REAL_VALUE_TYPE
&lh_ub
,
2559 const REAL_VALUE_TYPE
&rh_lb
,
2560 const REAL_VALUE_TYPE
&rh_ub
,
2561 relation_kind kind
) const final override
2565 && real_equal (&lh_lb
, &rh_lb
)
2566 && real_equal (&lh_ub
, &rh_ub
)
2567 && real_isneg (&lh_lb
) == real_isneg (&rh_lb
)
2568 && real_isneg (&lh_ub
) == real_isneg (&rh_ub
));
2571 // x * x never produces a new NAN and we only multiply the same
2572 // values, so the 0 * INF problematic cases never appear there.
2575 // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN.
2576 if ((zero_p (lh_lb
, lh_ub
) && singleton_inf_p (rh_lb
, rh_ub
))
2577 || (zero_p (rh_lb
, rh_ub
) && singleton_inf_p (lh_lb
, lh_ub
)))
2579 real_nan (&lb
, "", 0, TYPE_MODE (type
));
2585 // Otherwise, if one range includes zero and the other ends with +-INF,
2586 // it is a maybe NAN.
2587 if ((contains_zero_p (lh_lb
, lh_ub
)
2588 && (real_isinf (&rh_lb
) || real_isinf (&rh_ub
)))
2589 || (contains_zero_p (rh_lb
, rh_ub
)
2590 && (real_isinf (&lh_lb
) || real_isinf (&lh_ub
))))
2594 int signbit_known
= signbit_known_p (lh_lb
, lh_ub
, rh_lb
, rh_ub
);
2596 // If one of the ranges that includes INF is singleton
2597 // and the other range includes zero, the resulting
2598 // range is INF and NAN, because the 0 * INF boundary
2599 // case will be NAN, but already nextafter (0, 1) * INF
2601 if (singleton_inf_p (lh_lb
, lh_ub
)
2602 || singleton_inf_p (rh_lb
, rh_ub
))
2603 return inf_range (lb
, ub
, signbit_known
);
2605 // If one of the multiplicands must be zero, the resulting
2606 // range is +-0 and NAN.
2607 if (zero_p (lh_lb
, lh_ub
) || zero_p (rh_lb
, rh_ub
))
2608 return zero_range (lb
, ub
, signbit_known
);
2610 // Otherwise one of the multiplicands could be
2611 // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF]
2612 // or similarly with different signs. 0.0 * DBL_MAX
2613 // is still 0.0, nextafter (0.0, 1.0) * INF is still INF,
2614 // so if the signs are always the same or always different,
2615 // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING.
2616 return zero_to_inf_range (lb
, ub
, signbit_known
);
2620 REAL_VALUE_TYPE cp
[8];
2621 // Do a cross-product. At this point none of the multiplications
2622 // should produce a NAN.
2623 frange_arithmetic (MULT_EXPR
, type
, cp
[0], lh_lb
, rh_lb
, dconstninf
);
2624 frange_arithmetic (MULT_EXPR
, type
, cp
[4], lh_lb
, rh_lb
, dconstinf
);
2627 // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub)
2628 // as maximum and -0.0 as minimum if 0.0 is in the range,
2629 // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub).
2630 // -0.0 rather than 0.0 because VREL_EQ doesn't prove that
2631 // x and y are bitwise equal, just that they compare equal.
2632 if (contains_zero_p (lh_lb
, lh_ub
))
2634 if (real_isneg (&lh_lb
) == real_isneg (&lh_ub
))
2637 cp
[1] = real_value_negate (&dconst0
);
2647 frange_arithmetic (MULT_EXPR
, type
, cp
[1], lh_lb
, rh_ub
, dconstninf
);
2648 frange_arithmetic (MULT_EXPR
, type
, cp
[5], lh_lb
, rh_ub
, dconstinf
);
2649 frange_arithmetic (MULT_EXPR
, type
, cp
[2], lh_ub
, rh_lb
, dconstninf
);
2650 frange_arithmetic (MULT_EXPR
, type
, cp
[6], lh_ub
, rh_lb
, dconstinf
);
2652 frange_arithmetic (MULT_EXPR
, type
, cp
[3], lh_ub
, rh_ub
, dconstninf
);
2653 frange_arithmetic (MULT_EXPR
, type
, cp
[7], lh_ub
, rh_ub
, dconstinf
);
2655 find_range (lb
, ub
, cp
);
2660 class foperator_div
: public foperator_mult_div_base
2662 using range_operator_float::op1_range
;
2663 using range_operator_float::op2_range
;
2665 virtual bool op1_range (frange
&r
, tree type
,
2668 relation_trio
= TRIO_VARYING
) const final override
2670 if (lhs
.undefined_p ())
2672 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2673 bool ret
= fop_mult
.fold_range (r
, type
, wlhs
, op2
);
2676 if (wlhs
.known_isnan () || op2
.known_isnan () || op2
.undefined_p ())
2677 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2678 const REAL_VALUE_TYPE
&lhs_lb
= wlhs
.lower_bound ();
2679 const REAL_VALUE_TYPE
&lhs_ub
= wlhs
.upper_bound ();
2680 const REAL_VALUE_TYPE
&op2_lb
= op2
.lower_bound ();
2681 const REAL_VALUE_TYPE
&op2_ub
= op2
.upper_bound ();
2682 if ((contains_zero_p (lhs_lb
, lhs_ub
)
2683 && (real_isinf (&op2_lb
) || real_isinf (&op2_ub
)))
2684 || ((contains_zero_p (op2_lb
, op2_ub
))
2685 && (real_isinf (&lhs_lb
) || real_isinf (&lhs_ub
))))
2687 // If both lhs could be zero and op2 infinity or vice versa,
2688 // we don't know anything about op1 except maybe for the sign
2689 // and perhaps if it can be NAN or not.
2690 REAL_VALUE_TYPE lb
, ub
;
2691 int signbit_known
= signbit_known_p (lhs_lb
, lhs_ub
, op2_lb
, op2_ub
);
2692 zero_to_inf_range (lb
, ub
, signbit_known
);
2693 r
.set (type
, lb
, ub
);
2695 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2697 virtual bool op2_range (frange
&r
, tree type
,
2700 relation_trio
= TRIO_VARYING
) const final override
2702 if (lhs
.undefined_p ())
2704 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2705 bool ret
= fold_range (r
, type
, op1
, wlhs
);
2708 if (wlhs
.known_isnan () || op1
.known_isnan () || op1
.undefined_p ())
2709 return float_binary_op_range_finish (ret
, r
, type
, wlhs
, true);
2710 const REAL_VALUE_TYPE
&lhs_lb
= wlhs
.lower_bound ();
2711 const REAL_VALUE_TYPE
&lhs_ub
= wlhs
.upper_bound ();
2712 const REAL_VALUE_TYPE
&op1_lb
= op1
.lower_bound ();
2713 const REAL_VALUE_TYPE
&op1_ub
= op1
.upper_bound ();
2714 if ((contains_zero_p (lhs_lb
, lhs_ub
) && contains_zero_p (op1_lb
, op1_ub
))
2715 || ((real_isinf (&lhs_lb
) || real_isinf (&lhs_ub
))
2716 && (real_isinf (&op1_lb
) || real_isinf (&op1_ub
))))
2718 // If both lhs and op1 could be zeros or both could be infinities,
2719 // we don't know anything about op2 except maybe for the sign
2720 // and perhaps if it can be NAN or not.
2721 REAL_VALUE_TYPE lb
, ub
;
2722 int signbit_known
= signbit_known_p (lhs_lb
, lhs_ub
, op1_lb
, op1_ub
);
2723 zero_to_inf_range (lb
, ub
, signbit_known
);
2724 r
.set (type
, lb
, ub
);
2726 return float_binary_op_range_finish (ret
, r
, type
, wlhs
, true);
2729 void rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, bool &maybe_nan
,
2731 const REAL_VALUE_TYPE
&lh_lb
,
2732 const REAL_VALUE_TYPE
&lh_ub
,
2733 const REAL_VALUE_TYPE
&rh_lb
,
2734 const REAL_VALUE_TYPE
&rh_ub
,
2735 relation_kind
) const final override
2737 // +-0.0 / +-0.0 or +-INF / +-INF is a known NAN.
2738 if ((zero_p (lh_lb
, lh_ub
) && zero_p (rh_lb
, rh_ub
))
2739 || (singleton_inf_p (lh_lb
, lh_ub
) && singleton_inf_p (rh_lb
, rh_ub
)))
2741 real_nan (&lb
, "", 0, TYPE_MODE (type
));
2747 // If +-0.0 is in both ranges, it is a maybe NAN.
2748 if (contains_zero_p (lh_lb
, lh_ub
) && contains_zero_p (rh_lb
, rh_ub
))
2750 // If +-INF is in both ranges, it is a maybe NAN.
2751 else if ((real_isinf (&lh_lb
) || real_isinf (&lh_ub
))
2752 && (real_isinf (&rh_lb
) || real_isinf (&rh_ub
)))
2757 int signbit_known
= signbit_known_p (lh_lb
, lh_ub
, rh_lb
, rh_ub
);
2759 // If dividend must be zero, the range is just +-0
2760 // (including if the divisor is +-INF).
2761 // If divisor must be +-INF, the range is just +-0
2762 // (including if the dividend is zero).
2763 if (zero_p (lh_lb
, lh_ub
) || singleton_inf_p (rh_lb
, rh_ub
))
2764 return zero_range (lb
, ub
, signbit_known
);
2766 // If divisor must be zero, the range is just +-INF
2767 // (including if the dividend is +-INF).
2768 // If dividend must be +-INF, the range is just +-INF
2769 // (including if the dividend is zero).
2770 if (zero_p (rh_lb
, rh_ub
) || singleton_inf_p (lh_lb
, lh_ub
))
2771 return inf_range (lb
, ub
, signbit_known
);
2773 // Otherwise if both operands may be zero, divisor could be
2774 // nextafter(0.0, +-1.0) and dividend +-0.0
2775 // in which case result is going to INF or vice versa and
2776 // result +0.0. So, all we can say for that case is if the
2777 // signs of divisor and dividend are always the same we have
2778 // [+0.0, +INF], if they are always different we have
2779 // [-INF, -0.0]. If they vary, VARYING.
2780 // If both may be +-INF, divisor could be INF and dividend FLT_MAX,
2781 // in which case result is going to INF or vice versa and
2782 // result +0.0. So, all we can say for that case is if the
2783 // signs of divisor and dividend are always the same we have
2784 // [+0.0, +INF], if they are always different we have
2785 // [-INF, -0.0]. If they vary, VARYING.
2787 return zero_to_inf_range (lb
, ub
, signbit_known
);
2789 REAL_VALUE_TYPE cp
[8];
2790 // Do a cross-division. At this point none of the divisions should
2792 frange_arithmetic (RDIV_EXPR
, type
, cp
[0], lh_lb
, rh_lb
, dconstninf
);
2793 frange_arithmetic (RDIV_EXPR
, type
, cp
[1], lh_lb
, rh_ub
, dconstninf
);
2794 frange_arithmetic (RDIV_EXPR
, type
, cp
[2], lh_ub
, rh_lb
, dconstninf
);
2795 frange_arithmetic (RDIV_EXPR
, type
, cp
[3], lh_ub
, rh_ub
, dconstninf
);
2796 frange_arithmetic (RDIV_EXPR
, type
, cp
[4], lh_lb
, rh_lb
, dconstinf
);
2797 frange_arithmetic (RDIV_EXPR
, type
, cp
[5], lh_lb
, rh_ub
, dconstinf
);
2798 frange_arithmetic (RDIV_EXPR
, type
, cp
[6], lh_ub
, rh_lb
, dconstinf
);
2799 frange_arithmetic (RDIV_EXPR
, type
, cp
[7], lh_ub
, rh_ub
, dconstinf
);
2801 find_range (lb
, ub
, cp
);
2803 // If divisor may be zero (but is not known to be only zero),
2804 // and dividend can't be zero, the range can go up to -INF or +INF
2805 // depending on the signs.
2806 if (contains_zero_p (rh_lb
, rh_ub
))
2808 if (signbit_known
<= 0)
2809 real_inf (&lb
, true);
2810 if (signbit_known
>= 0)
2811 real_inf (&ub
, false);
2816 // Instantiate a range_op_table for floating point operations.
2817 static floating_op_table global_floating_table
;
2819 // Pointer to the float table so the dispatch code can access it.
2820 floating_op_table
*floating_tree_table
= &global_floating_table
;
2822 floating_op_table::floating_op_table ()
2824 set (SSA_NAME
, fop_identity
);
2825 set (PAREN_EXPR
, fop_identity
);
2826 set (OBJ_TYPE_REF
, fop_identity
);
2827 set (REAL_CST
, fop_identity
);
2829 // All the relational operators are expected to work, because the
2830 // calculation of ranges on outgoing edges expect the handlers to be
2832 set (EQ_EXPR
, fop_equal
);
2833 set (NE_EXPR
, fop_not_equal
);
2834 set (LT_EXPR
, fop_lt
);
2835 set (LE_EXPR
, fop_le
);
2836 set (GT_EXPR
, fop_gt
);
2837 set (GE_EXPR
, fop_ge
);
2838 set (UNLE_EXPR
, fop_unordered_le
);
2839 set (UNLT_EXPR
, fop_unordered_lt
);
2840 set (UNGE_EXPR
, fop_unordered_ge
);
2841 set (UNGT_EXPR
, fop_unordered_gt
);
2842 set (UNEQ_EXPR
, fop_unordered_equal
);
2843 set (ORDERED_EXPR
, fop_ordered
);
2844 set (UNORDERED_EXPR
, fop_unordered
);
2845 set (LTGT_EXPR
, fop_ltgt
);
2847 set (ABS_EXPR
, fop_abs
);
2848 set (NEGATE_EXPR
, fop_negate
);
2849 set (PLUS_EXPR
, fop_plus
);
2850 set (MINUS_EXPR
, fop_minus
);
2851 set (MULT_EXPR
, fop_mult
);
2852 set (RDIV_EXPR
, fop_div
);
2855 // Return a pointer to the range_operator_float instance, if there is
2856 // one associated with tree_code CODE.
2858 range_operator_float
*
2859 floating_op_table::operator[] (enum tree_code code
)
2861 return m_range_tree
[code
];
2864 // Add OP to the handler table for CODE.
2867 floating_op_table::set (enum tree_code code
, range_operator_float
&op
)
2869 gcc_checking_assert (m_range_tree
[code
] == NULL
);
2870 m_range_tree
[code
] = &op
;
2874 #include "selftest.h"
2879 // Build an frange from string endpoints.
2882 frange_float (const char *lb
, const char *ub
, tree type
= float_type_node
)
2884 REAL_VALUE_TYPE min
, max
;
2885 gcc_assert (real_from_string (&min
, lb
) == 0);
2886 gcc_assert (real_from_string (&max
, ub
) == 0);
2887 return frange (type
, min
, max
);
2891 range_op_float_tests ()
2894 frange
trange (float_type_node
);
2896 // negate([-5, +10]) => [-10, 5]
2897 r0
= frange_float ("-5", "10");
2898 fop_negate
.fold_range (r
, float_type_node
, r0
, trange
);
2899 ASSERT_EQ (r
, frange_float ("-10", "5"));
2901 // negate([0, 1] -NAN) => [-1, -0] +NAN
2902 r0
= frange_float ("0", "1");
2903 r0
.update_nan (true);
2904 fop_negate
.fold_range (r
, float_type_node
, r0
, trange
);
2905 r1
= frange_float ("-1", "-0");
2906 r1
.update_nan (false);
2909 // [-INF,+INF] + [-INF,+INF] could be a NAN.
2910 range_op_handler
plus (PLUS_EXPR
, float_type_node
);
2911 r0
.set_varying (float_type_node
);
2912 r1
.set_varying (float_type_node
);
2915 plus
.fold_range (r
, float_type_node
, r0
, r1
);
2916 if (HONOR_NANS (float_type_node
))
2917 ASSERT_TRUE (r
.maybe_isnan ());
2920 } // namespace selftest
2922 #endif // CHECKING_P