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
);
118 // For a given operation, fold two sets of ranges into [lb, ub].
119 // MAYBE_NAN is set to TRUE if, in addition to any result in LB or
120 // UB, the final range has the possiblity of a NAN.
122 range_operator_float::rv_fold (REAL_VALUE_TYPE
&lb
,
125 tree type ATTRIBUTE_UNUSED
,
126 const REAL_VALUE_TYPE
&lh_lb ATTRIBUTE_UNUSED
,
127 const REAL_VALUE_TYPE
&lh_ub ATTRIBUTE_UNUSED
,
128 const REAL_VALUE_TYPE
&rh_lb ATTRIBUTE_UNUSED
,
129 const REAL_VALUE_TYPE
&rh_ub ATTRIBUTE_UNUSED
,
138 range_operator_float::fold_range (irange
&r ATTRIBUTE_UNUSED
,
139 tree type ATTRIBUTE_UNUSED
,
140 const frange
&lh ATTRIBUTE_UNUSED
,
141 const irange
&rh ATTRIBUTE_UNUSED
,
148 range_operator_float::fold_range (irange
&r ATTRIBUTE_UNUSED
,
149 tree type ATTRIBUTE_UNUSED
,
150 const frange
&lh ATTRIBUTE_UNUSED
,
151 const frange
&rh ATTRIBUTE_UNUSED
,
158 range_operator_float::op1_range (frange
&r ATTRIBUTE_UNUSED
,
159 tree type ATTRIBUTE_UNUSED
,
160 const frange
&lhs ATTRIBUTE_UNUSED
,
161 const frange
&op2 ATTRIBUTE_UNUSED
,
168 range_operator_float::op1_range (frange
&r ATTRIBUTE_UNUSED
,
169 tree type ATTRIBUTE_UNUSED
,
170 const irange
&lhs ATTRIBUTE_UNUSED
,
171 const frange
&op2 ATTRIBUTE_UNUSED
,
178 range_operator_float::op2_range (frange
&r ATTRIBUTE_UNUSED
,
179 tree type ATTRIBUTE_UNUSED
,
180 const frange
&lhs ATTRIBUTE_UNUSED
,
181 const frange
&op1 ATTRIBUTE_UNUSED
,
188 range_operator_float::op2_range (frange
&r ATTRIBUTE_UNUSED
,
189 tree type ATTRIBUTE_UNUSED
,
190 const irange
&lhs ATTRIBUTE_UNUSED
,
191 const frange
&op1 ATTRIBUTE_UNUSED
,
198 range_operator_float::lhs_op1_relation (const frange
&lhs ATTRIBUTE_UNUSED
,
199 const frange
&op1 ATTRIBUTE_UNUSED
,
200 const frange
&op2 ATTRIBUTE_UNUSED
,
207 range_operator_float::lhs_op1_relation (const irange
&lhs ATTRIBUTE_UNUSED
,
208 const frange
&op1 ATTRIBUTE_UNUSED
,
209 const frange
&op2 ATTRIBUTE_UNUSED
,
216 range_operator_float::lhs_op2_relation (const irange
&lhs ATTRIBUTE_UNUSED
,
217 const frange
&op1 ATTRIBUTE_UNUSED
,
218 const frange
&op2 ATTRIBUTE_UNUSED
,
225 range_operator_float::lhs_op2_relation (const frange
&lhs ATTRIBUTE_UNUSED
,
226 const frange
&op1 ATTRIBUTE_UNUSED
,
227 const frange
&op2 ATTRIBUTE_UNUSED
,
234 range_operator_float::op1_op2_relation (const irange
&lhs ATTRIBUTE_UNUSED
) const
240 range_operator_float::op1_op2_relation (const frange
&lhs ATTRIBUTE_UNUSED
) const
245 // Return TRUE if OP1 and OP2 may be a NAN.
248 maybe_isnan (const frange
&op1
, const frange
&op2
)
250 return op1
.maybe_isnan () || op2
.maybe_isnan ();
253 // Floating version of relop_early_resolve that takes into account NAN
254 // and -ffinite-math-only.
257 frelop_early_resolve (irange
&r
, tree type
,
258 const frange
&op1
, const frange
&op2
,
259 relation_trio rel
, relation_kind my_rel
)
261 // If either operand is undefined, return VARYING.
262 if (empty_range_varying (r
, type
, op1
, op2
))
265 // We can fold relations from the oracle when we know both operands
266 // are free of NANs, or when -ffinite-math-only.
267 return (!maybe_isnan (op1
, op2
)
268 && relop_early_resolve (r
, type
, op1
, op2
, rel
, my_rel
));
271 // Set VALUE to its next real value, or INF if the operation overflows.
274 frange_nextafter (enum machine_mode mode
,
275 REAL_VALUE_TYPE
&value
,
276 const REAL_VALUE_TYPE
&inf
)
278 if (MODE_COMPOSITE_P (mode
)
279 && (real_isdenormal (&value
, mode
) || real_iszero (&value
)))
281 // IBM extended denormals only have DFmode precision.
282 REAL_VALUE_TYPE tmp
, tmp2
;
283 real_convert (&tmp2
, DFmode
, &value
);
284 real_nextafter (&tmp
, REAL_MODE_FORMAT (DFmode
), &tmp2
, &inf
);
285 real_convert (&value
, mode
, &tmp
);
290 real_nextafter (&tmp
, REAL_MODE_FORMAT (mode
), &value
, &inf
);
295 // Like real_arithmetic, but round the result to INF if the operation
296 // produced inexact results.
298 // ?? There is still one problematic case, i387. With
299 // -fexcess-precision=standard we perform most SF/DFmode arithmetic in
300 // XFmode (long_double_type_node), so that case is OK. But without
301 // -mfpmath=sse, all the SF/DFmode computations are in XFmode
302 // precision (64-bit mantissa) and only occassionally rounded to
303 // SF/DFmode (when storing into memory from the 387 stack). Maybe
304 // this is ok as well though it is just occassionally more precise. ??
307 frange_arithmetic (enum tree_code code
, tree type
,
308 REAL_VALUE_TYPE
&result
,
309 const REAL_VALUE_TYPE
&op1
,
310 const REAL_VALUE_TYPE
&op2
,
311 const REAL_VALUE_TYPE
&inf
)
313 REAL_VALUE_TYPE value
;
314 enum machine_mode mode
= TYPE_MODE (type
);
315 bool mode_composite
= MODE_COMPOSITE_P (mode
);
317 bool inexact
= real_arithmetic (&value
, code
, &op1
, &op2
);
318 real_convert (&result
, mode
, &value
);
320 // Be extra careful if there may be discrepancies between the
321 // compile and runtime results.
327 bool low
= real_isneg (&inf
);
328 round
= (low
? !real_less (&result
, &value
)
329 : !real_less (&value
, &result
));
330 if (real_isinf (&result
, !low
)
331 && !real_isinf (&value
)
332 && !flag_rounding_math
)
334 // Use just [+INF, +INF] rather than [MAX, +INF]
335 // even if value is larger than MAX and rounds to
336 // nearest to +INF. Similarly just [-INF, -INF]
337 // rather than [-INF, +MAX] even if value is smaller
338 // than -MAX and rounds to nearest to -INF.
339 // Unless INEXACT is true, in that case we need some
345 REAL_VALUE_TYPE tmp
= result
, tmp2
;
346 frange_nextafter (mode
, tmp
, inf
);
347 // TMP is at this point the maximum representable
349 real_arithmetic (&tmp2
, MINUS_EXPR
, &value
, &tmp
);
350 if (real_isneg (&tmp2
) != low
351 && (REAL_EXP (&tmp2
) - REAL_EXP (&tmp
)
352 >= 2 - REAL_MODE_FORMAT (mode
)->p
))
357 if (round
&& (inexact
|| !real_identical (&result
, &value
)))
360 && (real_isdenormal (&result
, mode
) || real_iszero (&result
)))
362 // IBM extended denormals only have DFmode precision.
363 REAL_VALUE_TYPE tmp
, tmp2
;
364 real_convert (&tmp2
, DFmode
, &value
);
365 real_nextafter (&tmp
, REAL_MODE_FORMAT (DFmode
), &tmp2
, &inf
);
366 real_convert (&result
, mode
, &tmp
);
369 frange_nextafter (mode
, result
, inf
);
376 // ibm-ldouble-format documents 1ulp for + and -.
377 frange_nextafter (mode
, result
, inf
);
380 // ibm-ldouble-format documents 2ulps for *.
381 frange_nextafter (mode
, result
, inf
);
382 frange_nextafter (mode
, result
, inf
);
385 // ibm-ldouble-format documents 3ulps for /.
386 frange_nextafter (mode
, result
, inf
);
387 frange_nextafter (mode
, result
, inf
);
388 frange_nextafter (mode
, result
, inf
);
395 // Crop R to [-INF, MAX] where MAX is the maximum representable number
399 frange_drop_inf (frange
&r
, tree type
)
401 REAL_VALUE_TYPE max
= real_max_representable (type
);
402 frange
tmp (type
, r
.lower_bound (), max
);
406 // Crop R to [MIN, +INF] where MIN is the minimum representable number
410 frange_drop_ninf (frange
&r
, tree type
)
412 REAL_VALUE_TYPE min
= real_min_representable (type
);
413 frange
tmp (type
, min
, r
.upper_bound ());
417 // Crop R to [MIN, MAX] where MAX is the maximum representable number
418 // for TYPE and MIN the minimum representable number for TYPE.
421 frange_drop_infs (frange
&r
, tree type
)
423 REAL_VALUE_TYPE max
= real_max_representable (type
);
424 REAL_VALUE_TYPE min
= real_min_representable (type
);
425 frange
tmp (type
, min
, max
);
429 // If zero is in R, make sure both -0.0 and +0.0 are in the range.
432 frange_add_zeros (frange
&r
, tree type
)
434 if (r
.undefined_p () || r
.known_isnan ())
437 if (HONOR_SIGNED_ZEROS (type
)
438 && (real_iszero (&r
.lower_bound ()) || real_iszero (&r
.upper_bound ())))
441 zero
.set_zero (type
);
446 // Build a range that is <= VAL and store it in R. Return TRUE if
447 // further changes may be needed for R, or FALSE if R is in its final
451 build_le (frange
&r
, tree type
, const frange
&val
)
453 gcc_checking_assert (!val
.known_isnan ());
455 REAL_VALUE_TYPE ninf
= frange_val_min (type
);
456 r
.set (type
, ninf
, val
.upper_bound ());
458 // Add both zeros if there's the possibility of zero equality.
459 frange_add_zeros (r
, type
);
464 // Build a range that is < VAL and store it in R. Return TRUE if
465 // further changes may be needed for R, or FALSE if R is in its final
469 build_lt (frange
&r
, tree type
, const frange
&val
)
471 gcc_checking_assert (!val
.known_isnan ());
473 // < -INF is outside the range.
474 if (real_isinf (&val
.upper_bound (), 1))
476 if (HONOR_NANS (type
))
483 REAL_VALUE_TYPE ninf
= frange_val_min (type
);
484 REAL_VALUE_TYPE prev
= val
.upper_bound ();
485 machine_mode mode
= TYPE_MODE (type
);
486 // Default to the conservatively correct closed ranges for
487 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
488 // !HONOR_INFINITIES, nextafter will yield -INF, but frange::set()
489 // will crop the range appropriately.
490 if (!MODE_COMPOSITE_P (mode
))
491 frange_nextafter (mode
, prev
, ninf
);
492 r
.set (type
, ninf
, prev
);
496 // Build a range that is >= VAL and store it in R. Return TRUE if
497 // further changes may be needed for R, or FALSE if R is in its final
501 build_ge (frange
&r
, tree type
, const frange
&val
)
503 gcc_checking_assert (!val
.known_isnan ());
505 REAL_VALUE_TYPE inf
= frange_val_max (type
);
506 r
.set (type
, val
.lower_bound (), inf
);
508 // Add both zeros if there's the possibility of zero equality.
509 frange_add_zeros (r
, type
);
514 // Build a range that is > VAL and store it in R. Return TRUE if
515 // further changes may be needed for R, or FALSE if R is in its final
519 build_gt (frange
&r
, tree type
, const frange
&val
)
521 gcc_checking_assert (!val
.known_isnan ());
523 // > +INF is outside the range.
524 if (real_isinf (&val
.lower_bound (), 0))
526 if (HONOR_NANS (type
))
533 REAL_VALUE_TYPE inf
= frange_val_max (type
);
534 REAL_VALUE_TYPE next
= val
.lower_bound ();
535 machine_mode mode
= TYPE_MODE (type
);
536 // Default to the conservatively correct closed ranges for
537 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
538 // !HONOR_INFINITIES, nextafter will yield +INF, but frange::set()
539 // will crop the range appropriately.
540 if (!MODE_COMPOSITE_P (mode
))
541 frange_nextafter (mode
, next
, inf
);
542 r
.set (type
, next
, inf
);
547 class foperator_identity
: public range_operator_float
549 using range_operator_float::fold_range
;
550 using range_operator_float::op1_range
;
552 bool fold_range (frange
&r
, tree type ATTRIBUTE_UNUSED
,
553 const frange
&op1
, const frange
&op2 ATTRIBUTE_UNUSED
,
554 relation_trio
= TRIO_VARYING
) const final override
559 bool op1_range (frange
&r
, tree type ATTRIBUTE_UNUSED
,
560 const frange
&lhs
, const frange
&op2 ATTRIBUTE_UNUSED
,
561 relation_trio
= TRIO_VARYING
) const final override
569 class foperator_equal
: public range_operator_float
571 using range_operator_float::fold_range
;
572 using range_operator_float::op1_range
;
573 using range_operator_float::op2_range
;
574 using range_operator_float::op1_op2_relation
;
576 bool fold_range (irange
&r
, tree type
,
577 const frange
&op1
, const frange
&op2
,
578 relation_trio
= TRIO_VARYING
) const final override
;
579 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
581 return equal_op1_op2_relation (lhs
);
583 bool op1_range (frange
&r
, tree type
,
584 const irange
&lhs
, const frange
&op2
,
585 relation_trio
= TRIO_VARYING
) const final override
;
586 bool op2_range (frange
&r
, tree type
,
587 const irange
&lhs
, const frange
&op1
,
588 relation_trio rel
= TRIO_VARYING
) const final override
590 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
595 foperator_equal::fold_range (irange
&r
, tree type
,
596 const frange
&op1
, const frange
&op2
,
597 relation_trio rel
) const
599 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_EQ
))
602 if (op1
.known_isnan () || op2
.known_isnan ())
603 r
= range_false (type
);
604 // We can be sure the values are always equal or not if both ranges
605 // consist of a single value, and then compare them.
606 else if (op1
.singleton_p () && op2
.singleton_p ())
609 r
= range_true (type
);
610 // If one operand is -0.0 and other 0.0, they are still equal.
611 else if (real_iszero (&op1
.lower_bound ())
612 && real_iszero (&op2
.lower_bound ()))
613 r
= range_true (type
);
615 r
= range_false (type
);
617 else if (!maybe_isnan (op1
, op2
))
619 // If ranges do not intersect, we know the range is not equal,
620 // otherwise we don't know anything for sure.
623 if (tmp
.undefined_p ())
625 // If one range is [whatever, -0.0] and another
626 // [0.0, whatever2], we don't know anything either,
627 // because -0.0 == 0.0.
628 if ((real_iszero (&op1
.upper_bound ())
629 && real_iszero (&op2
.lower_bound ()))
630 || (real_iszero (&op1
.lower_bound ())
631 && real_iszero (&op2
.upper_bound ())))
632 r
= range_true_and_false (type
);
634 r
= range_false (type
);
637 r
= range_true_and_false (type
);
640 r
= range_true_and_false (type
);
645 foperator_equal::op1_range (frange
&r
, tree type
,
648 relation_trio trio
) const
650 relation_kind rel
= trio
.op1_op2 ();
651 switch (get_bool_state (r
, lhs
, type
))
654 // The TRUE side of x == NAN is unreachable.
655 if (op2
.known_isnan ())
659 // If it's true, the result is the same as OP2.
661 // Add both zeros if there's the possibility of zero equality.
662 frange_add_zeros (r
, type
);
663 // The TRUE side of op1 == op2 implies op1 is !NAN.
669 // The FALSE side of op1 == op1 implies op1 is a NAN.
672 // On the FALSE side of x == NAN, we know nothing about x.
673 else if (op2
.known_isnan ())
674 r
.set_varying (type
);
675 // If the result is false, the only time we know anything is
676 // if OP2 is a constant.
677 else if (op2
.singleton_p ()
678 || (!op2
.maybe_isnan () && op2
.zero_p ()))
680 REAL_VALUE_TYPE tmp
= op2
.lower_bound ();
681 r
.set (type
, tmp
, tmp
, VR_ANTI_RANGE
);
684 r
.set_varying (type
);
693 class foperator_not_equal
: public range_operator_float
695 using range_operator_float::fold_range
;
696 using range_operator_float::op1_range
;
697 using range_operator_float::op1_op2_relation
;
699 bool fold_range (irange
&r
, tree type
,
700 const frange
&op1
, const frange
&op2
,
701 relation_trio rel
= TRIO_VARYING
) const final override
;
702 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
704 return not_equal_op1_op2_relation (lhs
);
706 bool op1_range (frange
&r
, tree type
,
707 const irange
&lhs
, const frange
&op2
,
708 relation_trio
= TRIO_VARYING
) const final override
;
712 foperator_not_equal::fold_range (irange
&r
, tree type
,
713 const frange
&op1
, const frange
&op2
,
714 relation_trio rel
) const
716 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_NE
))
719 // x != NAN is always TRUE.
720 if (op1
.known_isnan () || op2
.known_isnan ())
721 r
= range_true (type
);
722 // We can be sure the values are always equal or not if both ranges
723 // consist of a single value, and then compare them.
724 else if (op1
.singleton_p () && op2
.singleton_p ())
727 r
= range_false (type
);
728 // If one operand is -0.0 and other 0.0, they are still equal.
729 else if (real_iszero (&op1
.lower_bound ())
730 && real_iszero (&op2
.lower_bound ()))
731 r
= range_false (type
);
733 r
= range_true (type
);
735 else if (!maybe_isnan (op1
, op2
))
737 // If ranges do not intersect, we know the range is not equal,
738 // otherwise we don't know anything for sure.
741 if (tmp
.undefined_p ())
743 // If one range is [whatever, -0.0] and another
744 // [0.0, whatever2], we don't know anything either,
745 // because -0.0 == 0.0.
746 if ((real_iszero (&op1
.upper_bound ())
747 && real_iszero (&op2
.lower_bound ()))
748 || (real_iszero (&op1
.lower_bound ())
749 && real_iszero (&op2
.upper_bound ())))
750 r
= range_true_and_false (type
);
752 r
= range_true (type
);
755 r
= range_true_and_false (type
);
758 r
= range_true_and_false (type
);
763 foperator_not_equal::op1_range (frange
&r
, tree type
,
766 relation_trio trio
) const
768 relation_kind rel
= trio
.op1_op2 ();
769 switch (get_bool_state (r
, lhs
, type
))
772 // If the result is true, the only time we know anything is if
773 // OP2 is a constant.
774 if (op2
.singleton_p ())
776 // This is correct even if op1 is NAN, because the following
777 // range would be ~[tmp, tmp] with the NAN property set to
779 REAL_VALUE_TYPE tmp
= op2
.lower_bound ();
780 r
.set (type
, tmp
, tmp
, VR_ANTI_RANGE
);
782 // The TRUE side of op1 != op1 implies op1 is NAN.
783 else if (rel
== VREL_EQ
)
786 r
.set_varying (type
);
790 // The FALSE side of x != NAN is impossible.
791 if (op2
.known_isnan ())
795 // If it's false, the result is the same as OP2.
797 // Add both zeros if there's the possibility of zero equality.
798 frange_add_zeros (r
, type
);
799 // The FALSE side of op1 != op2 implies op1 is !NAN.
810 class foperator_lt
: public range_operator_float
812 using range_operator_float::fold_range
;
813 using range_operator_float::op1_range
;
814 using range_operator_float::op2_range
;
815 using range_operator_float::op1_op2_relation
;
817 bool fold_range (irange
&r
, tree type
,
818 const frange
&op1
, const frange
&op2
,
819 relation_trio
= TRIO_VARYING
) const final override
;
820 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
822 return lt_op1_op2_relation (lhs
);
824 bool op1_range (frange
&r
, tree type
,
825 const irange
&lhs
, const frange
&op2
,
826 relation_trio
= TRIO_VARYING
) const final override
;
827 bool op2_range (frange
&r
, tree type
,
828 const irange
&lhs
, const frange
&op1
,
829 relation_trio
= TRIO_VARYING
) const final override
;
833 foperator_lt::fold_range (irange
&r
, tree type
,
834 const frange
&op1
, const frange
&op2
,
835 relation_trio rel
) const
837 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_LT
))
840 if (op1
.known_isnan () || op2
.known_isnan ())
841 r
= range_false (type
);
842 else if (!maybe_isnan (op1
, op2
))
844 if (real_less (&op1
.upper_bound (), &op2
.lower_bound ()))
845 r
= range_true (type
);
846 else if (!real_less (&op1
.lower_bound (), &op2
.upper_bound ()))
847 r
= range_false (type
);
849 r
= range_true_and_false (type
);
852 r
= range_true_and_false (type
);
857 foperator_lt::op1_range (frange
&r
,
863 switch (get_bool_state (r
, lhs
, type
))
866 // The TRUE side of x < NAN is unreachable.
867 if (op2
.known_isnan ())
869 else if (op2
.undefined_p ())
871 else if (build_lt (r
, type
, op2
))
874 // x < y implies x is not +INF.
875 frange_drop_inf (r
, type
);
880 // On the FALSE side of x < NAN, we know nothing about x.
881 if (op2
.known_isnan ())
882 r
.set_varying (type
);
884 build_ge (r
, type
, op2
);
894 foperator_lt::op2_range (frange
&r
,
900 switch (get_bool_state (r
, lhs
, type
))
903 // The TRUE side of NAN < x is unreachable.
904 if (op1
.known_isnan ())
906 else if (op1
.undefined_p ())
908 else if (build_gt (r
, type
, op1
))
911 // x < y implies y is not -INF.
912 frange_drop_ninf (r
, type
);
917 // On the FALSE side of NAN < x, we know nothing about x.
918 if (op1
.known_isnan ())
919 r
.set_varying (type
);
921 build_le (r
, type
, op1
);
930 class foperator_le
: public range_operator_float
932 using range_operator_float::fold_range
;
933 using range_operator_float::op1_range
;
934 using range_operator_float::op2_range
;
935 using range_operator_float::op1_op2_relation
;
937 bool fold_range (irange
&r
, tree type
,
938 const frange
&op1
, const frange
&op2
,
939 relation_trio rel
= TRIO_VARYING
) const final override
;
940 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
942 return le_op1_op2_relation (lhs
);
944 bool op1_range (frange
&r
, tree type
,
945 const irange
&lhs
, const frange
&op2
,
946 relation_trio rel
= TRIO_VARYING
) const final override
;
947 bool op2_range (frange
&r
, tree type
,
948 const irange
&lhs
, const frange
&op1
,
949 relation_trio rel
= TRIO_VARYING
) const final override
;
953 foperator_le::fold_range (irange
&r
, tree type
,
954 const frange
&op1
, const frange
&op2
,
955 relation_trio rel
) const
957 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_LE
))
960 if (op1
.known_isnan () || op2
.known_isnan ())
961 r
= range_false (type
);
962 else if (!maybe_isnan (op1
, op2
))
964 if (real_compare (LE_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
965 r
= range_true (type
);
966 else if (!real_compare (LE_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
967 r
= range_false (type
);
969 r
= range_true_and_false (type
);
972 r
= range_true_and_false (type
);
977 foperator_le::op1_range (frange
&r
,
983 switch (get_bool_state (r
, lhs
, type
))
986 // The TRUE side of x <= NAN is unreachable.
987 if (op2
.known_isnan ())
989 else if (op2
.undefined_p ())
991 else if (build_le (r
, type
, op2
))
996 // On the FALSE side of x <= NAN, we know nothing about x.
997 if (op2
.known_isnan ())
998 r
.set_varying (type
);
1000 build_gt (r
, type
, op2
);
1010 foperator_le::op2_range (frange
&r
,
1014 relation_trio
) const
1016 switch (get_bool_state (r
, lhs
, type
))
1019 // The TRUE side of NAN <= x is unreachable.
1020 if (op1
.known_isnan ())
1022 else if (op1
.undefined_p ())
1024 else if (build_ge (r
, type
, op1
))
1029 // On the FALSE side of NAN <= x, we know nothing about x.
1030 if (op1
.known_isnan ())
1031 r
.set_varying (type
);
1032 else if (op1
.undefined_p ())
1035 build_lt (r
, type
, op1
);
1044 class foperator_gt
: public range_operator_float
1046 using range_operator_float::fold_range
;
1047 using range_operator_float::op1_range
;
1048 using range_operator_float::op2_range
;
1049 using range_operator_float::op1_op2_relation
;
1051 bool fold_range (irange
&r
, tree type
,
1052 const frange
&op1
, const frange
&op2
,
1053 relation_trio
= TRIO_VARYING
) const final override
;
1054 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
1056 return gt_op1_op2_relation (lhs
);
1058 bool op1_range (frange
&r
, tree type
,
1059 const irange
&lhs
, const frange
&op2
,
1060 relation_trio
= TRIO_VARYING
) const final override
;
1061 bool op2_range (frange
&r
, tree type
,
1062 const irange
&lhs
, const frange
&op1
,
1063 relation_trio
= TRIO_VARYING
) const final override
;
1067 foperator_gt::fold_range (irange
&r
, tree type
,
1068 const frange
&op1
, const frange
&op2
,
1069 relation_trio rel
) const
1071 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_GT
))
1074 if (op1
.known_isnan () || op2
.known_isnan ())
1075 r
= range_false (type
);
1076 else if (!maybe_isnan (op1
, op2
))
1078 if (real_compare (GT_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
1079 r
= range_true (type
);
1080 else if (!real_compare (GT_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
1081 r
= range_false (type
);
1083 r
= range_true_and_false (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 ())
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 ())
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 () || op2
.known_isnan ())
1199 r
= range_false (type
);
1200 else if (!maybe_isnan (op1
, op2
))
1202 if (real_compare (GE_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
1203 r
= range_true (type
);
1204 else if (!real_compare (GE_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
1205 r
= range_false (type
);
1207 r
= range_true_and_false (type
);
1210 r
= range_true_and_false (type
);
1215 foperator_ge::op1_range (frange
&r
,
1219 relation_trio
) const
1221 switch (get_bool_state (r
, lhs
, type
))
1224 // The TRUE side of x >= NAN is unreachable.
1225 if (op2
.known_isnan ())
1227 else if (op2
.undefined_p ())
1229 else if (build_ge (r
, type
, op2
))
1234 // On the FALSE side of x >= NAN, we know nothing about x.
1235 if (op2
.known_isnan ())
1236 r
.set_varying (type
);
1237 else if (op2
.undefined_p ())
1240 build_lt (r
, type
, op2
);
1250 foperator_ge::op2_range (frange
&r
, tree type
,
1253 relation_trio
) const
1255 switch (get_bool_state (r
, lhs
, type
))
1258 // The TRUE side of NAN >= x is unreachable.
1259 if (op1
.known_isnan ())
1261 else if (op1
.undefined_p ())
1263 else if (build_le (r
, type
, op1
))
1268 // On the FALSE side of NAN >= x, we know nothing about x.
1269 if (op1
.known_isnan ())
1270 r
.set_varying (type
);
1271 else if (op1
.undefined_p ())
1274 build_gt (r
, type
, op1
);
1283 // UNORDERED_EXPR comparison.
1285 class foperator_unordered
: public range_operator_float
1287 using range_operator_float::fold_range
;
1288 using range_operator_float::op1_range
;
1289 using range_operator_float::op2_range
;
1291 bool fold_range (irange
&r
, tree type
,
1292 const frange
&op1
, const frange
&op2
,
1293 relation_trio
= TRIO_VARYING
) const final override
;
1294 bool op1_range (frange
&r
, tree type
,
1295 const irange
&lhs
, const frange
&op2
,
1296 relation_trio
= TRIO_VARYING
) const final override
;
1297 bool op2_range (frange
&r
, tree type
,
1298 const irange
&lhs
, const frange
&op1
,
1299 relation_trio rel
= TRIO_VARYING
) const final override
1301 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
1306 foperator_unordered::fold_range (irange
&r
, tree type
,
1307 const frange
&op1
, const frange
&op2
,
1308 relation_trio
) const
1310 // UNORDERED is TRUE if either operand is a NAN.
1311 if (op1
.known_isnan () || op2
.known_isnan ())
1312 r
= range_true (type
);
1313 // UNORDERED is FALSE if neither operand is a NAN.
1314 else if (!op1
.maybe_isnan () && !op2
.maybe_isnan ())
1315 r
= range_false (type
);
1317 r
= range_true_and_false (type
);
1322 foperator_unordered::op1_range (frange
&r
, tree type
,
1325 relation_trio trio
) const
1327 relation_kind rel
= trio
.op1_op2 ();
1328 switch (get_bool_state (r
, lhs
, type
))
1331 // Since at least one operand must be NAN, if one of them is
1332 // not, the other must be.
1333 if (rel
== VREL_EQ
|| !op2
.maybe_isnan ())
1336 r
.set_varying (type
);
1340 // A false UNORDERED means both operands are !NAN, so it's
1341 // impossible for op2 to be a NAN.
1342 if (op2
.known_isnan ())
1346 r
.set_varying (type
);
1357 // ORDERED_EXPR comparison.
1359 class foperator_ordered
: public range_operator_float
1361 using range_operator_float::fold_range
;
1362 using range_operator_float::op1_range
;
1363 using range_operator_float::op2_range
;
1365 bool fold_range (irange
&r
, tree type
,
1366 const frange
&op1
, const frange
&op2
,
1367 relation_trio
= TRIO_VARYING
) const final override
;
1368 bool op1_range (frange
&r
, tree type
,
1369 const irange
&lhs
, const frange
&op2
,
1370 relation_trio
= TRIO_VARYING
) const final override
;
1371 bool op2_range (frange
&r
, tree type
,
1372 const irange
&lhs
, const frange
&op1
,
1373 relation_trio rel
= TRIO_VARYING
) const final override
1375 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
1380 foperator_ordered::fold_range (irange
&r
, tree type
,
1381 const frange
&op1
, const frange
&op2
,
1382 relation_trio
) const
1384 if (op1
.known_isnan () || op2
.known_isnan ())
1385 r
= range_false (type
);
1386 else if (!op1
.maybe_isnan () && !op2
.maybe_isnan ())
1387 r
= range_true (type
);
1389 r
= range_true_and_false (type
);
1394 foperator_ordered::op1_range (frange
&r
, tree type
,
1397 relation_trio trio
) const
1399 relation_kind rel
= trio
.op1_op2 ();
1400 switch (get_bool_state (r
, lhs
, type
))
1403 // The TRUE side of ORDERED means both operands are !NAN, so
1404 // it's impossible for op2 to be a NAN.
1405 if (op2
.known_isnan ())
1409 r
.set_varying (type
);
1415 // The FALSE side of op1 ORDERED op1 implies op1 is NAN.
1419 r
.set_varying (type
);
1428 class foperator_negate
: public range_operator_float
1430 using range_operator_float::fold_range
;
1431 using range_operator_float::op1_range
;
1433 bool fold_range (frange
&r
, tree type
,
1434 const frange
&op1
, const frange
&op2
,
1435 relation_trio
= TRIO_VARYING
) const final override
1437 if (empty_range_varying (r
, type
, op1
, op2
))
1439 if (op1
.known_isnan ())
1442 if (op1
.nan_signbit_p (sign
))
1443 r
.set_nan (type
, !sign
);
1449 REAL_VALUE_TYPE lh_lb
= op1
.lower_bound ();
1450 REAL_VALUE_TYPE lh_ub
= op1
.upper_bound ();
1451 lh_lb
= real_value_negate (&lh_lb
);
1452 lh_ub
= real_value_negate (&lh_ub
);
1453 r
.set (type
, lh_ub
, lh_lb
);
1454 if (op1
.maybe_isnan ())
1457 if (op1
.nan_signbit_p (sign
))
1458 r
.update_nan (!sign
);
1466 bool op1_range (frange
&r
, tree type
,
1467 const frange
&lhs
, const frange
&op2
,
1468 relation_trio rel
= TRIO_VARYING
) const final override
1470 return fold_range (r
, type
, lhs
, op2
, rel
);
1474 class foperator_abs
: public range_operator_float
1476 using range_operator_float::fold_range
;
1477 using range_operator_float::op1_range
;
1479 bool fold_range (frange
&r
, tree type
,
1480 const frange
&op1
, const frange
&,
1481 relation_trio
= TRIO_VARYING
) const final override
;
1482 bool op1_range (frange
&r
, tree type
,
1483 const frange
&lhs
, const frange
&op2
,
1484 relation_trio rel
= TRIO_VARYING
) const final override
;
1488 foperator_abs::fold_range (frange
&r
, tree type
,
1489 const frange
&op1
, const frange
&op2
,
1490 relation_trio
) const
1492 if (empty_range_varying (r
, type
, op1
, op2
))
1494 if (op1
.known_isnan ())
1496 r
.set_nan (type
, /*sign=*/false);
1500 const REAL_VALUE_TYPE lh_lb
= op1
.lower_bound ();
1501 const REAL_VALUE_TYPE lh_ub
= op1
.upper_bound ();
1502 // Handle the easy case where everything is positive.
1503 if (real_compare (GE_EXPR
, &lh_lb
, &dconst0
)
1504 && !real_iszero (&lh_lb
, /*sign=*/true)
1505 && !op1
.maybe_isnan (/*sign=*/true))
1511 REAL_VALUE_TYPE min
= real_value_abs (&lh_lb
);
1512 REAL_VALUE_TYPE max
= real_value_abs (&lh_ub
);
1513 // If the range contains zero then we know that the minimum value in the
1514 // range will be zero.
1515 if (real_compare (LE_EXPR
, &lh_lb
, &dconst0
)
1516 && real_compare (GE_EXPR
, &lh_ub
, &dconst0
))
1518 if (real_compare (GT_EXPR
, &min
, &max
))
1524 // If the range was reversed, swap MIN and MAX.
1525 if (real_compare (GT_EXPR
, &min
, &max
))
1526 std::swap (min
, max
);
1529 r
.set (type
, min
, max
);
1530 if (op1
.maybe_isnan ())
1531 r
.update_nan (/*sign=*/false);
1538 foperator_abs::op1_range (frange
&r
, tree type
,
1539 const frange
&lhs
, const frange
&op2
,
1540 relation_trio
) const
1542 if (empty_range_varying (r
, type
, lhs
, op2
))
1544 if (lhs
.known_isnan ())
1550 // Start with the positives because negatives are an impossible result.
1551 frange
positives (type
, dconst0
, frange_val_max (type
));
1552 positives
.update_nan (/*sign=*/false);
1553 positives
.intersect (lhs
);
1555 // Add -NAN if relevant.
1556 if (r
.maybe_isnan ())
1559 neg_nan
.set_nan (type
, true);
1562 if (r
.known_isnan () || r
.undefined_p ())
1564 // Then add the negative of each pair:
1565 // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
1566 frange
negatives (type
, real_value_negate (&positives
.upper_bound ()),
1567 real_value_negate (&positives
.lower_bound ()));
1568 negatives
.clear_nan ();
1569 r
.union_ (negatives
);
1573 class foperator_unordered_lt
: public range_operator_float
1575 using range_operator_float::fold_range
;
1576 using range_operator_float::op1_range
;
1577 using range_operator_float::op2_range
;
1579 bool fold_range (irange
&r
, tree type
,
1580 const frange
&op1
, const frange
&op2
,
1581 relation_trio rel
= TRIO_VARYING
) const final override
1583 if (op1
.known_isnan () || op2
.known_isnan ())
1585 r
= range_true (type
);
1588 if (!fop_lt
.fold_range (r
, type
, op1
, op2
, rel
))
1590 // The result is the same as the ordered version when the
1591 // comparison is true or when the operands cannot be NANs.
1592 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1596 r
= range_true_and_false (type
);
1600 bool op1_range (frange
&r
, tree type
,
1603 relation_trio trio
) const final override
;
1604 bool op2_range (frange
&r
, tree type
,
1607 relation_trio trio
) const final override
;
1611 foperator_unordered_lt::op1_range (frange
&r
, tree type
,
1614 relation_trio
) const
1616 switch (get_bool_state (r
, lhs
, type
))
1619 if (op2
.known_isnan ())
1620 r
.set_varying (type
);
1621 else if (op2
.undefined_p ())
1624 build_lt (r
, type
, op2
);
1628 // A false UNORDERED_LT means both operands are !NAN, so it's
1629 // impossible for op2 to be a NAN.
1630 if (op2
.known_isnan ())
1632 else if (op2
.undefined_p ())
1634 else if (build_ge (r
, type
, op2
))
1645 foperator_unordered_lt::op2_range (frange
&r
, tree type
,
1648 relation_trio
) const
1650 switch (get_bool_state (r
, lhs
, type
))
1653 if (op1
.known_isnan ())
1654 r
.set_varying (type
);
1655 else if (op1
.undefined_p ())
1658 build_gt (r
, type
, op1
);
1662 // A false UNORDERED_LT means both operands are !NAN, so it's
1663 // impossible for op1 to be a NAN.
1664 if (op1
.known_isnan ())
1666 else if (op1
.undefined_p ())
1668 else if (build_le (r
, type
, op1
))
1678 class foperator_unordered_le
: public range_operator_float
1680 using range_operator_float::fold_range
;
1681 using range_operator_float::op1_range
;
1682 using range_operator_float::op2_range
;
1684 bool fold_range (irange
&r
, tree type
,
1685 const frange
&op1
, const frange
&op2
,
1686 relation_trio rel
= TRIO_VARYING
) const final override
1688 if (op1
.known_isnan () || op2
.known_isnan ())
1690 r
= range_true (type
);
1693 if (!fop_le
.fold_range (r
, type
, op1
, op2
, rel
))
1695 // The result is the same as the ordered version when the
1696 // comparison is true or when the operands cannot be NANs.
1697 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1701 r
= range_true_and_false (type
);
1705 bool op1_range (frange
&r
, tree type
,
1706 const irange
&lhs
, const frange
&op2
,
1707 relation_trio
= TRIO_VARYING
) const final override
;
1708 bool op2_range (frange
&r
, tree type
,
1709 const irange
&lhs
, const frange
&op1
,
1710 relation_trio
= TRIO_VARYING
) const final override
;
1714 foperator_unordered_le::op1_range (frange
&r
, tree type
,
1715 const irange
&lhs
, const frange
&op2
,
1716 relation_trio
) const
1718 switch (get_bool_state (r
, lhs
, type
))
1721 if (op2
.known_isnan ())
1722 r
.set_varying (type
);
1723 else if (op2
.undefined_p ())
1726 build_le (r
, type
, op2
);
1730 // A false UNORDERED_LE means both operands are !NAN, so it's
1731 // impossible for op2 to be a NAN.
1732 if (op2
.known_isnan ())
1734 else if (build_gt (r
, type
, op2
))
1745 foperator_unordered_le::op2_range (frange
&r
,
1749 relation_trio
) const
1751 switch (get_bool_state (r
, lhs
, type
))
1754 if (op1
.known_isnan ())
1755 r
.set_varying (type
);
1756 else if (op1
.undefined_p ())
1759 build_ge (r
, type
, op1
);
1763 // A false UNORDERED_LE means both operands are !NAN, so it's
1764 // impossible for op1 to be a NAN.
1765 if (op1
.known_isnan ())
1767 else if (op1
.undefined_p ())
1769 else if (build_lt (r
, type
, op1
))
1779 class foperator_unordered_gt
: public range_operator_float
1781 using range_operator_float::fold_range
;
1782 using range_operator_float::op1_range
;
1783 using range_operator_float::op2_range
;
1785 bool fold_range (irange
&r
, tree type
,
1786 const frange
&op1
, const frange
&op2
,
1787 relation_trio rel
= TRIO_VARYING
) const final override
1789 if (op1
.known_isnan () || op2
.known_isnan ())
1791 r
= range_true (type
);
1794 if (!fop_gt
.fold_range (r
, type
, op1
, op2
, rel
))
1796 // The result is the same as the ordered version when the
1797 // comparison is true or when the operands cannot be NANs.
1798 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1802 r
= range_true_and_false (type
);
1806 bool op1_range (frange
&r
, tree type
,
1807 const irange
&lhs
, const frange
&op2
,
1808 relation_trio
= TRIO_VARYING
) const final override
;
1809 bool op2_range (frange
&r
, tree type
,
1810 const irange
&lhs
, const frange
&op1
,
1811 relation_trio
= TRIO_VARYING
) const final override
;
1815 foperator_unordered_gt::op1_range (frange
&r
,
1819 relation_trio
) const
1821 switch (get_bool_state (r
, lhs
, type
))
1824 if (op2
.known_isnan ())
1825 r
.set_varying (type
);
1826 else if (op2
.undefined_p ())
1829 build_gt (r
, type
, op2
);
1833 // A false UNORDERED_GT means both operands are !NAN, so it's
1834 // impossible for op2 to be a NAN.
1835 if (op2
.known_isnan ())
1837 else if (op2
.undefined_p ())
1839 else if (build_le (r
, type
, op2
))
1850 foperator_unordered_gt::op2_range (frange
&r
,
1854 relation_trio
) const
1856 switch (get_bool_state (r
, lhs
, type
))
1859 if (op1
.known_isnan ())
1860 r
.set_varying (type
);
1861 else if (op1
.undefined_p ())
1864 build_lt (r
, type
, op1
);
1868 // A false UNORDERED_GT means both operands are !NAN, so it's
1869 // impossible for op1 to be a NAN.
1870 if (op1
.known_isnan ())
1872 else if (op1
.undefined_p ())
1874 else if (build_ge (r
, type
, op1
))
1884 class foperator_unordered_ge
: public range_operator_float
1886 using range_operator_float::fold_range
;
1887 using range_operator_float::op1_range
;
1888 using range_operator_float::op2_range
;
1890 bool fold_range (irange
&r
, tree type
,
1891 const frange
&op1
, const frange
&op2
,
1892 relation_trio rel
= TRIO_VARYING
) const final override
1894 if (op1
.known_isnan () || op2
.known_isnan ())
1896 r
= range_true (type
);
1899 if (!fop_ge
.fold_range (r
, type
, op1
, op2
, rel
))
1901 // The result is the same as the ordered version when the
1902 // comparison is true or when the operands cannot be NANs.
1903 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1907 r
= range_true_and_false (type
);
1911 bool op1_range (frange
&r
, tree type
,
1912 const irange
&lhs
, const frange
&op2
,
1913 relation_trio
= TRIO_VARYING
) const final override
;
1914 bool op2_range (frange
&r
, tree type
,
1915 const irange
&lhs
, const frange
&op1
,
1916 relation_trio
= TRIO_VARYING
) const final override
;
1920 foperator_unordered_ge::op1_range (frange
&r
,
1924 relation_trio
) const
1926 switch (get_bool_state (r
, lhs
, type
))
1929 if (op2
.known_isnan ())
1930 r
.set_varying (type
);
1931 else if (op2
.undefined_p ())
1934 build_ge (r
, type
, op2
);
1938 // A false UNORDERED_GE means both operands are !NAN, so it's
1939 // impossible for op2 to be a NAN.
1940 if (op2
.known_isnan ())
1942 else if (op2
.undefined_p ())
1944 else if (build_lt (r
, type
, op2
))
1955 foperator_unordered_ge::op2_range (frange
&r
, tree type
,
1958 relation_trio
) const
1960 switch (get_bool_state (r
, lhs
, type
))
1963 if (op1
.known_isnan ())
1964 r
.set_varying (type
);
1965 else if (op1
.undefined_p ())
1968 build_le (r
, type
, op1
);
1972 // A false UNORDERED_GE means both operands are !NAN, so it's
1973 // impossible for op1 to be a NAN.
1974 if (op1
.known_isnan ())
1976 else if (op1
.undefined_p ())
1978 else if (build_gt (r
, type
, op1
))
1988 class foperator_unordered_equal
: public range_operator_float
1990 using range_operator_float::fold_range
;
1991 using range_operator_float::op1_range
;
1992 using range_operator_float::op2_range
;
1994 bool fold_range (irange
&r
, tree type
,
1995 const frange
&op1
, const frange
&op2
,
1996 relation_trio rel
= TRIO_VARYING
) const final override
1998 if (op1
.known_isnan () || op2
.known_isnan ())
2000 r
= range_true (type
);
2003 if (!fop_equal
.fold_range (r
, type
, op1
, op2
, rel
))
2005 // The result is the same as the ordered version when the
2006 // comparison is true or when the operands cannot be NANs.
2007 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
2011 r
= range_true_and_false (type
);
2015 bool op1_range (frange
&r
, tree type
,
2016 const irange
&lhs
, const frange
&op2
,
2017 relation_trio
= TRIO_VARYING
) const final override
;
2018 bool op2_range (frange
&r
, tree type
,
2019 const irange
&lhs
, const frange
&op1
,
2020 relation_trio rel
= TRIO_VARYING
) const final override
2022 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
2024 } fop_unordered_equal
;
2027 foperator_unordered_equal::op1_range (frange
&r
, tree type
,
2030 relation_trio
) const
2032 switch (get_bool_state (r
, lhs
, type
))
2035 // If it's true, the result is the same as OP2 plus a NAN.
2037 // Add both zeros if there's the possibility of zero equality.
2038 frange_add_zeros (r
, type
);
2039 // Add the posibility of a NAN.
2044 // A false UNORDERED_EQ means both operands are !NAN, so it's
2045 // impossible for op2 to be a NAN.
2046 if (op2
.known_isnan ())
2050 // The false side indictates !NAN and not equal. We can at least
2052 r
.set_varying (type
);
2063 // Final tweaks for float binary op op1_range/op2_range.
2064 // Return TRUE if the operation is performed and a valid range is available.
2067 float_binary_op_range_finish (bool ret
, frange
&r
, tree type
,
2068 const frange
&lhs
, bool div_op2
= false)
2073 // If we get a known NAN from reverse op, it means either that
2074 // the other operand was known NAN (in that case we know nothing),
2075 // or the reverse operation introduced a known NAN.
2076 // Say for lhs = op1 * op2 if lhs is [-0, +0] and op2 is too,
2077 // 0 / 0 is known NAN. Just punt in that case.
2078 // If NANs aren't honored, we get for 0 / 0 UNDEFINED, so punt as well.
2079 // Or if lhs is a known NAN, we also don't know anything.
2080 if (r
.known_isnan () || lhs
.known_isnan () || r
.undefined_p ())
2082 r
.set_varying (type
);
2086 // If lhs isn't NAN, then neither operand could be NAN,
2087 // even if the reverse operation does introduce a maybe_nan.
2088 if (!lhs
.maybe_isnan ())
2092 ? !(real_compare (LE_EXPR
, &lhs
.lower_bound (), &dconst0
)
2093 && real_compare (GE_EXPR
, &lhs
.upper_bound (), &dconst0
))
2094 : !(real_isinf (&lhs
.lower_bound ())
2095 || real_isinf (&lhs
.upper_bound ())))
2096 // For reverse + or - or * or op1 of /, if result is finite, then
2097 // r must be finite too, as X + INF or X - INF or X * INF or
2098 // INF / X is always +-INF or NAN. For op2 of /, if result is
2099 // non-zero and not NAN, r must be finite, as X / INF is always
2101 frange_drop_infs (r
, type
);
2103 // If lhs is a maybe or known NAN, the operand could be
2110 // True if [lb, ub] is [+-0, +-0].
2112 zero_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
2114 return real_iszero (&lb
) && real_iszero (&ub
);
2117 // True if +0 or -0 is in [lb, ub] range.
2119 contains_zero_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
2121 return (real_compare (LE_EXPR
, &lb
, &dconst0
)
2122 && real_compare (GE_EXPR
, &ub
, &dconst0
));
2125 // True if [lb, ub] is [-INF, -INF] or [+INF, +INF].
2127 singleton_inf_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
2129 return real_isinf (&lb
) && real_isinf (&ub
, real_isneg (&lb
));
2132 // Return -1 if binary op result must have sign bit set,
2133 // 1 if binary op result must have sign bit clear,
2135 // Sign bit of binary op result is exclusive or of the
2136 // operand's sign bits.
2138 signbit_known_p (const REAL_VALUE_TYPE
&lh_lb
, const REAL_VALUE_TYPE
&lh_ub
,
2139 const REAL_VALUE_TYPE
&rh_lb
, const REAL_VALUE_TYPE
&rh_ub
)
2141 if (real_isneg (&lh_lb
) == real_isneg (&lh_ub
)
2142 && real_isneg (&rh_lb
) == real_isneg (&rh_ub
))
2144 if (real_isneg (&lh_lb
) == real_isneg (&rh_ub
))
2152 // Set [lb, ub] to [-0, -0], [-0, +0] or [+0, +0] depending on
2155 zero_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
2158 if (signbit_known
<= 0)
2159 lb
= real_value_negate (&dconst0
);
2160 if (signbit_known
< 0)
2164 // Set [lb, ub] to [-INF, -INF], [-INF, +INF] or [+INF, +INF] depending on
2167 inf_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
2169 if (signbit_known
> 0)
2170 ub
= lb
= dconstinf
;
2171 else if (signbit_known
< 0)
2172 ub
= lb
= dconstninf
;
2180 // Set [lb, ub] to [-INF, -0], [-INF, +INF] or [+0, +INF] depending on
2183 zero_to_inf_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
2185 if (signbit_known
> 0)
2190 else if (signbit_known
< 0)
2193 ub
= real_value_negate (&dconst0
);
2202 class foperator_plus
: public range_operator_float
2204 using range_operator_float::op1_range
;
2205 using range_operator_float::op2_range
;
2207 virtual bool op1_range (frange
&r
, tree type
,
2210 relation_trio
= TRIO_VARYING
) const final override
2212 if (lhs
.undefined_p ())
2214 range_op_handler
minus (MINUS_EXPR
, type
);
2217 return float_binary_op_range_finish (minus
.fold_range (r
, type
, lhs
, op2
),
2220 virtual bool op2_range (frange
&r
, tree type
,
2223 relation_trio
= TRIO_VARYING
) const final override
2225 return op1_range (r
, type
, lhs
, op1
);
2228 void rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, bool &maybe_nan
,
2230 const REAL_VALUE_TYPE
&lh_lb
,
2231 const REAL_VALUE_TYPE
&lh_ub
,
2232 const REAL_VALUE_TYPE
&rh_lb
,
2233 const REAL_VALUE_TYPE
&rh_ub
,
2234 relation_kind
) const final override
2236 frange_arithmetic (PLUS_EXPR
, type
, lb
, lh_lb
, rh_lb
, dconstninf
);
2237 frange_arithmetic (PLUS_EXPR
, type
, ub
, lh_ub
, rh_ub
, dconstinf
);
2239 // [-INF] + [+INF] = NAN
2240 if (real_isinf (&lh_lb
, true) && real_isinf (&rh_ub
, false))
2242 // [+INF] + [-INF] = NAN
2243 else if (real_isinf (&lh_ub
, false) && real_isinf (&rh_lb
, true))
2251 class foperator_minus
: public range_operator_float
2253 using range_operator_float::op1_range
;
2254 using range_operator_float::op2_range
;
2256 virtual bool op1_range (frange
&r
, tree type
,
2259 relation_trio
= TRIO_VARYING
) const final override
2261 if (lhs
.undefined_p ())
2263 return float_binary_op_range_finish (fop_plus
.fold_range (r
, type
, lhs
,
2267 virtual bool op2_range (frange
&r
, tree type
,
2270 relation_trio
= TRIO_VARYING
) const final override
2272 if (lhs
.undefined_p ())
2274 return float_binary_op_range_finish (fold_range (r
, type
, op1
, lhs
),
2278 void rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, bool &maybe_nan
,
2280 const REAL_VALUE_TYPE
&lh_lb
,
2281 const REAL_VALUE_TYPE
&lh_ub
,
2282 const REAL_VALUE_TYPE
&rh_lb
,
2283 const REAL_VALUE_TYPE
&rh_ub
,
2284 relation_kind
) const final override
2286 frange_arithmetic (MINUS_EXPR
, type
, lb
, lh_lb
, rh_ub
, dconstninf
);
2287 frange_arithmetic (MINUS_EXPR
, type
, ub
, lh_ub
, rh_lb
, dconstinf
);
2289 // [+INF] - [+INF] = NAN
2290 if (real_isinf (&lh_ub
, false) && real_isinf (&rh_ub
, false))
2292 // [-INF] - [-INF] = NAN
2293 else if (real_isinf (&lh_lb
, true) && real_isinf (&rh_lb
, true))
2301 class foperator_mult_div_base
: public range_operator_float
2304 // Given CP[0] to CP[3] floating point values rounded to -INF,
2305 // set LB to the smallest of them (treating -0 as smaller to +0).
2306 // Given CP[4] to CP[7] floating point values rounded to +INF,
2307 // set UB to the largest of them (treating -0 as smaller to +0).
2308 static void find_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
,
2309 const REAL_VALUE_TYPE (&cp
)[8])
2313 for (int i
= 1; i
< 4; ++i
)
2315 if (real_less (&cp
[i
], &lb
)
2316 || (real_iszero (&lb
) && real_isnegzero (&cp
[i
])))
2318 if (real_less (&ub
, &cp
[i
+ 4])
2319 || (real_isnegzero (&ub
) && real_iszero (&cp
[i
+ 4])))
2326 class foperator_mult
: public foperator_mult_div_base
2328 using range_operator_float::op1_range
;
2329 using range_operator_float::op2_range
;
2331 virtual bool op1_range (frange
&r
, tree type
,
2334 relation_trio
= TRIO_VARYING
) const final override
2336 if (lhs
.undefined_p ())
2338 range_op_handler
rdiv (RDIV_EXPR
, type
);
2341 bool ret
= rdiv
.fold_range (r
, type
, lhs
, op2
);
2344 if (lhs
.known_isnan () || op2
.known_isnan () || op2
.undefined_p ())
2345 return float_binary_op_range_finish (ret
, r
, type
, lhs
);
2346 const REAL_VALUE_TYPE
&lhs_lb
= lhs
.lower_bound ();
2347 const REAL_VALUE_TYPE
&lhs_ub
= lhs
.upper_bound ();
2348 const REAL_VALUE_TYPE
&op2_lb
= op2
.lower_bound ();
2349 const REAL_VALUE_TYPE
&op2_ub
= op2
.upper_bound ();
2350 if ((contains_zero_p (lhs_lb
, lhs_ub
) && contains_zero_p (op2_lb
, op2_ub
))
2351 || ((real_isinf (&lhs_lb
) || real_isinf (&lhs_ub
))
2352 && (real_isinf (&op2_lb
) || real_isinf (&op2_ub
))))
2354 // If both lhs and op2 could be zeros or both could be infinities,
2355 // we don't know anything about op1 except maybe for the sign
2356 // and perhaps if it can be NAN or not.
2357 REAL_VALUE_TYPE lb
, ub
;
2358 int signbit_known
= signbit_known_p (lhs_lb
, lhs_ub
, op2_lb
, op2_ub
);
2359 zero_to_inf_range (lb
, ub
, signbit_known
);
2360 r
.set (type
, lb
, ub
);
2362 // Otherwise, if op2 is a singleton INF and lhs doesn't include INF,
2363 // or if lhs must be zero and op2 doesn't include zero, it would be
2364 // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF
2365 // range. Those are supersets of UNDEFINED, so let's keep that way.
2366 return float_binary_op_range_finish (ret
, r
, type
, lhs
);
2368 virtual bool op2_range (frange
&r
, tree type
,
2371 relation_trio
= TRIO_VARYING
) const final override
2373 return op1_range (r
, type
, lhs
, op1
);
2376 void rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, bool &maybe_nan
,
2378 const REAL_VALUE_TYPE
&lh_lb
,
2379 const REAL_VALUE_TYPE
&lh_ub
,
2380 const REAL_VALUE_TYPE
&rh_lb
,
2381 const REAL_VALUE_TYPE
&rh_ub
,
2382 relation_kind kind
) const final override
2386 && real_equal (&lh_lb
, &rh_lb
)
2387 && real_equal (&lh_ub
, &rh_ub
)
2388 && real_isneg (&lh_lb
) == real_isneg (&rh_lb
)
2389 && real_isneg (&lh_ub
) == real_isneg (&rh_ub
));
2392 // x * x never produces a new NAN and we only multiply the same
2393 // values, so the 0 * INF problematic cases never appear there.
2396 // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN.
2397 if ((zero_p (lh_lb
, lh_ub
) && singleton_inf_p (rh_lb
, rh_ub
))
2398 || (zero_p (rh_lb
, rh_ub
) && singleton_inf_p (lh_lb
, lh_ub
)))
2400 real_nan (&lb
, "", 0, TYPE_MODE (type
));
2406 // Otherwise, if one range includes zero and the other ends with +-INF,
2407 // it is a maybe NAN.
2408 if ((contains_zero_p (lh_lb
, lh_ub
)
2409 && (real_isinf (&rh_lb
) || real_isinf (&rh_ub
)))
2410 || (contains_zero_p (rh_lb
, rh_ub
)
2411 && (real_isinf (&lh_lb
) || real_isinf (&lh_ub
))))
2415 int signbit_known
= signbit_known_p (lh_lb
, lh_ub
, rh_lb
, rh_ub
);
2417 // If one of the ranges that includes INF is singleton
2418 // and the other range includes zero, the resulting
2419 // range is INF and NAN, because the 0 * INF boundary
2420 // case will be NAN, but already nextafter (0, 1) * INF
2422 if (singleton_inf_p (lh_lb
, lh_ub
)
2423 || singleton_inf_p (rh_lb
, rh_ub
))
2424 return inf_range (lb
, ub
, signbit_known
);
2426 // If one of the multiplicands must be zero, the resulting
2427 // range is +-0 and NAN.
2428 if (zero_p (lh_lb
, lh_ub
) || zero_p (rh_lb
, rh_ub
))
2429 return zero_range (lb
, ub
, signbit_known
);
2431 // Otherwise one of the multiplicands could be
2432 // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF]
2433 // or similarly with different signs. 0.0 * DBL_MAX
2434 // is still 0.0, nextafter (0.0, 1.0) * INF is still INF,
2435 // so if the signs are always the same or always different,
2436 // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING.
2437 return zero_to_inf_range (lb
, ub
, signbit_known
);
2441 REAL_VALUE_TYPE cp
[8];
2442 // Do a cross-product. At this point none of the multiplications
2443 // should produce a NAN.
2444 frange_arithmetic (MULT_EXPR
, type
, cp
[0], lh_lb
, rh_lb
, dconstninf
);
2445 frange_arithmetic (MULT_EXPR
, type
, cp
[4], lh_lb
, rh_lb
, dconstinf
);
2448 // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub)
2449 // as maximum and -0.0 as minimum if 0.0 is in the range,
2450 // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub).
2451 // -0.0 rather than 0.0 because VREL_EQ doesn't prove that
2452 // x and y are bitwise equal, just that they compare equal.
2453 if (contains_zero_p (lh_lb
, lh_ub
))
2455 if (real_isneg (&lh_lb
) == real_isneg (&lh_ub
))
2458 cp
[1] = real_value_negate (&dconst0
);
2468 frange_arithmetic (MULT_EXPR
, type
, cp
[1], lh_lb
, rh_ub
, dconstninf
);
2469 frange_arithmetic (MULT_EXPR
, type
, cp
[5], lh_lb
, rh_ub
, dconstinf
);
2470 frange_arithmetic (MULT_EXPR
, type
, cp
[2], lh_ub
, rh_lb
, dconstninf
);
2471 frange_arithmetic (MULT_EXPR
, type
, cp
[6], lh_ub
, rh_lb
, dconstinf
);
2473 frange_arithmetic (MULT_EXPR
, type
, cp
[3], lh_ub
, rh_ub
, dconstninf
);
2474 frange_arithmetic (MULT_EXPR
, type
, cp
[7], lh_ub
, rh_ub
, dconstinf
);
2476 find_range (lb
, ub
, cp
);
2481 class foperator_div
: public foperator_mult_div_base
2483 using range_operator_float::op1_range
;
2484 using range_operator_float::op2_range
;
2486 virtual bool op1_range (frange
&r
, tree type
,
2489 relation_trio
= TRIO_VARYING
) const final override
2491 if (lhs
.undefined_p ())
2493 bool ret
= fop_mult
.fold_range (r
, type
, lhs
, op2
);
2496 if (lhs
.known_isnan () || op2
.known_isnan () || op2
.undefined_p ())
2497 return float_binary_op_range_finish (ret
, r
, type
, lhs
);
2498 const REAL_VALUE_TYPE
&lhs_lb
= lhs
.lower_bound ();
2499 const REAL_VALUE_TYPE
&lhs_ub
= lhs
.upper_bound ();
2500 const REAL_VALUE_TYPE
&op2_lb
= op2
.lower_bound ();
2501 const REAL_VALUE_TYPE
&op2_ub
= op2
.upper_bound ();
2502 if ((contains_zero_p (lhs_lb
, lhs_ub
)
2503 && (real_isinf (&op2_lb
) || real_isinf (&op2_ub
)))
2504 || ((contains_zero_p (op2_lb
, op2_ub
))
2505 && (real_isinf (&lhs_lb
) || real_isinf (&lhs_ub
))))
2507 // If both lhs could be zero and op2 infinity or vice versa,
2508 // we don't know anything about op1 except maybe for the sign
2509 // and perhaps if it can be NAN or not.
2510 REAL_VALUE_TYPE lb
, ub
;
2511 int signbit_known
= signbit_known_p (lhs_lb
, lhs_ub
, op2_lb
, op2_ub
);
2512 zero_to_inf_range (lb
, ub
, signbit_known
);
2513 r
.set (type
, lb
, ub
);
2515 return float_binary_op_range_finish (ret
, r
, type
, lhs
);
2517 virtual bool op2_range (frange
&r
, tree type
,
2520 relation_trio
= TRIO_VARYING
) const final override
2522 if (lhs
.undefined_p ())
2524 bool ret
= fold_range (r
, type
, op1
, lhs
);
2527 if (lhs
.known_isnan () || op1
.known_isnan () || op1
.undefined_p ())
2528 return float_binary_op_range_finish (ret
, r
, type
, lhs
, true);
2529 const REAL_VALUE_TYPE
&lhs_lb
= lhs
.lower_bound ();
2530 const REAL_VALUE_TYPE
&lhs_ub
= lhs
.upper_bound ();
2531 const REAL_VALUE_TYPE
&op1_lb
= op1
.lower_bound ();
2532 const REAL_VALUE_TYPE
&op1_ub
= op1
.upper_bound ();
2533 if ((contains_zero_p (lhs_lb
, lhs_ub
) && contains_zero_p (op1_lb
, op1_ub
))
2534 || ((real_isinf (&lhs_lb
) || real_isinf (&lhs_ub
))
2535 && (real_isinf (&op1_lb
) || real_isinf (&op1_ub
))))
2537 // If both lhs and op1 could be zeros or both could be infinities,
2538 // we don't know anything about op2 except maybe for the sign
2539 // and perhaps if it can be NAN or not.
2540 REAL_VALUE_TYPE lb
, ub
;
2541 int signbit_known
= signbit_known_p (lhs_lb
, lhs_ub
, op1_lb
, op1_ub
);
2542 zero_to_inf_range (lb
, ub
, signbit_known
);
2543 r
.set (type
, lb
, ub
);
2545 return float_binary_op_range_finish (ret
, r
, type
, lhs
, true);
2548 void rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, bool &maybe_nan
,
2550 const REAL_VALUE_TYPE
&lh_lb
,
2551 const REAL_VALUE_TYPE
&lh_ub
,
2552 const REAL_VALUE_TYPE
&rh_lb
,
2553 const REAL_VALUE_TYPE
&rh_ub
,
2554 relation_kind
) const final override
2556 // +-0.0 / +-0.0 or +-INF / +-INF is a known NAN.
2557 if ((zero_p (lh_lb
, lh_ub
) && zero_p (rh_lb
, rh_ub
))
2558 || (singleton_inf_p (lh_lb
, lh_ub
) && singleton_inf_p (rh_lb
, rh_ub
)))
2560 real_nan (&lb
, "", 0, TYPE_MODE (type
));
2566 // If +-0.0 is in both ranges, it is a maybe NAN.
2567 if (contains_zero_p (lh_lb
, lh_ub
) && contains_zero_p (rh_lb
, rh_ub
))
2569 // If +-INF is in both ranges, it is a maybe NAN.
2570 else if ((real_isinf (&lh_lb
) || real_isinf (&lh_ub
))
2571 && (real_isinf (&rh_lb
) || real_isinf (&rh_ub
)))
2576 int signbit_known
= signbit_known_p (lh_lb
, lh_ub
, rh_lb
, rh_ub
);
2578 // If dividend must be zero, the range is just +-0
2579 // (including if the divisor is +-INF).
2580 // If divisor must be +-INF, the range is just +-0
2581 // (including if the dividend is zero).
2582 if (zero_p (lh_lb
, lh_ub
) || singleton_inf_p (rh_lb
, rh_ub
))
2583 return zero_range (lb
, ub
, signbit_known
);
2585 // If divisor must be zero, the range is just +-INF
2586 // (including if the dividend is +-INF).
2587 // If dividend must be +-INF, the range is just +-INF
2588 // (including if the dividend is zero).
2589 if (zero_p (rh_lb
, rh_ub
) || singleton_inf_p (lh_lb
, lh_ub
))
2590 return inf_range (lb
, ub
, signbit_known
);
2592 // Otherwise if both operands may be zero, divisor could be
2593 // nextafter(0.0, +-1.0) and dividend +-0.0
2594 // in which case result is going to INF or vice versa and
2595 // result +0.0. So, all we can say for that case is if the
2596 // signs of divisor and dividend are always the same we have
2597 // [+0.0, +INF], if they are always different we have
2598 // [-INF, -0.0]. If they vary, VARING.
2599 // If both may be +-INF, divisor could be INF and dividend FLT_MAX,
2600 // in which case result is going to INF or vice versa and
2601 // result +0.0. So, all we can say for that case is if the
2602 // signs of divisor and dividend are always the same we have
2603 // [+0.0, +INF], if they are always different we have
2604 // [-INF, -0.0]. If they vary, VARYING.
2606 return zero_to_inf_range (lb
, ub
, signbit_known
);
2608 REAL_VALUE_TYPE cp
[8];
2609 // Do a cross-division. At this point none of the divisions should
2611 frange_arithmetic (RDIV_EXPR
, type
, cp
[0], lh_lb
, rh_lb
, dconstninf
);
2612 frange_arithmetic (RDIV_EXPR
, type
, cp
[1], lh_lb
, rh_ub
, dconstninf
);
2613 frange_arithmetic (RDIV_EXPR
, type
, cp
[2], lh_ub
, rh_lb
, dconstninf
);
2614 frange_arithmetic (RDIV_EXPR
, type
, cp
[3], lh_ub
, rh_ub
, dconstninf
);
2615 frange_arithmetic (RDIV_EXPR
, type
, cp
[4], lh_lb
, rh_lb
, dconstinf
);
2616 frange_arithmetic (RDIV_EXPR
, type
, cp
[5], lh_lb
, rh_ub
, dconstinf
);
2617 frange_arithmetic (RDIV_EXPR
, type
, cp
[6], lh_ub
, rh_lb
, dconstinf
);
2618 frange_arithmetic (RDIV_EXPR
, type
, cp
[7], lh_ub
, rh_ub
, dconstinf
);
2620 find_range (lb
, ub
, cp
);
2622 // If divisor may be zero (but is not known to be only zero),
2623 // and dividend can't be zero, the range can go up to -INF or +INF
2624 // depending on the signs.
2625 if (contains_zero_p (rh_lb
, rh_ub
))
2627 if (signbit_known
<= 0)
2628 real_inf (&lb
, true);
2629 if (signbit_known
>= 0)
2630 real_inf (&ub
, false);
2635 // Instantiate a range_op_table for floating point operations.
2636 static floating_op_table global_floating_table
;
2638 // Pointer to the float table so the dispatch code can access it.
2639 floating_op_table
*floating_tree_table
= &global_floating_table
;
2641 floating_op_table::floating_op_table ()
2643 set (SSA_NAME
, fop_identity
);
2644 set (PAREN_EXPR
, fop_identity
);
2645 set (OBJ_TYPE_REF
, fop_identity
);
2646 set (REAL_CST
, fop_identity
);
2648 // All the relational operators are expected to work, because the
2649 // calculation of ranges on outgoing edges expect the handlers to be
2651 set (EQ_EXPR
, fop_equal
);
2652 set (NE_EXPR
, fop_not_equal
);
2653 set (LT_EXPR
, fop_lt
);
2654 set (LE_EXPR
, fop_le
);
2655 set (GT_EXPR
, fop_gt
);
2656 set (GE_EXPR
, fop_ge
);
2657 set (UNLE_EXPR
, fop_unordered_le
);
2658 set (UNLT_EXPR
, fop_unordered_lt
);
2659 set (UNGE_EXPR
, fop_unordered_ge
);
2660 set (UNGT_EXPR
, fop_unordered_gt
);
2661 set (UNEQ_EXPR
, fop_unordered_equal
);
2662 set (ORDERED_EXPR
, fop_ordered
);
2663 set (UNORDERED_EXPR
, fop_unordered
);
2665 set (ABS_EXPR
, fop_abs
);
2666 set (NEGATE_EXPR
, fop_negate
);
2667 set (PLUS_EXPR
, fop_plus
);
2668 set (MINUS_EXPR
, fop_minus
);
2669 set (MULT_EXPR
, fop_mult
);
2670 set (RDIV_EXPR
, fop_div
);
2673 // Return a pointer to the range_operator_float instance, if there is
2674 // one associated with tree_code CODE.
2676 range_operator_float
*
2677 floating_op_table::operator[] (enum tree_code code
)
2679 return m_range_tree
[code
];
2682 // Add OP to the handler table for CODE.
2685 floating_op_table::set (enum tree_code code
, range_operator_float
&op
)
2687 gcc_checking_assert (m_range_tree
[code
] == NULL
);
2688 m_range_tree
[code
] = &op
;
2692 #include "selftest.h"
2697 // Build an frange from string endpoints.
2700 frange_float (const char *lb
, const char *ub
, tree type
= float_type_node
)
2702 REAL_VALUE_TYPE min
, max
;
2703 gcc_assert (real_from_string (&min
, lb
) == 0);
2704 gcc_assert (real_from_string (&max
, ub
) == 0);
2705 return frange (type
, min
, max
);
2709 range_op_float_tests ()
2712 frange
trange (float_type_node
);
2714 // negate([-5, +10]) => [-10, 5]
2715 r0
= frange_float ("-5", "10");
2716 fop_negate
.fold_range (r
, float_type_node
, r0
, trange
);
2717 ASSERT_EQ (r
, frange_float ("-10", "5"));
2719 // negate([0, 1] -NAN) => [-1, -0] +NAN
2720 r0
= frange_float ("0", "1");
2721 r0
.update_nan (true);
2722 fop_negate
.fold_range (r
, float_type_node
, r0
, trange
);
2723 r1
= frange_float ("-1", "-0");
2724 r1
.update_nan (false);
2727 // [-INF,+INF] + [-INF,+INF] could be a NAN.
2728 range_op_handler
plus (PLUS_EXPR
, float_type_node
);
2729 r0
.set_varying (float_type_node
);
2730 r1
.set_varying (float_type_node
);
2733 plus
.fold_range (r
, float_type_node
, r0
, r1
);
2734 if (HONOR_NANS (float_type_node
))
2735 ASSERT_TRUE (r
.maybe_isnan ());
2738 } // namespace selftest
2740 #endif // CHECKING_P