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"
48 #include "range-op-mixed.h"
50 // Default definitions for floating point operators.
53 range_operator::fold_range (frange
&r
, tree type
,
54 const frange
&op1
, const frange
&op2
,
55 relation_trio trio
) const
57 if (empty_range_varying (r
, type
, op1
, op2
))
59 if (op1
.known_isnan () || op2
.known_isnan ())
66 op1
.lower_bound (), op1
.upper_bound (),
67 op2
.lower_bound (), op2
.upper_bound (), trio
.op1_op2 ());
71 if (op1
.maybe_isnan () || op2
.maybe_isnan ())
74 // If the result has overflowed and flag_trapping_math, folding this
75 // operation could elide an overflow or division by zero exception.
76 // Avoid returning a singleton +-INF, to keep the propagators (DOM
77 // and substitute_and_fold_engine) from folding. See PR107608.
78 if (flag_trapping_math
79 && MODE_HAS_INFINITIES (TYPE_MODE (type
))
80 && r
.known_isinf () && !op1
.known_isinf () && !op2
.known_isinf ())
82 REAL_VALUE_TYPE inf
= r
.lower_bound ();
83 if (real_isneg (&inf
))
85 REAL_VALUE_TYPE min
= real_min_representable (type
);
86 r
.set (type
, inf
, min
);
90 REAL_VALUE_TYPE max
= real_max_representable (type
);
91 r
.set (type
, max
, inf
);
95 r
.flush_denormals_to_zero ();
100 // For a given operation, fold two sets of ranges into [lb, ub].
101 // MAYBE_NAN is set to TRUE if, in addition to any result in LB or
102 // UB, the final range has the possibility of a NAN.
104 range_operator::rv_fold (frange
&r
, tree type
,
105 const REAL_VALUE_TYPE
&,
106 const REAL_VALUE_TYPE
&,
107 const REAL_VALUE_TYPE
&,
108 const REAL_VALUE_TYPE
&, relation_kind
) const
110 r
.set (type
, dconstninf
, dconstinf
, nan_state (true));
114 range_operator::fold_range (irange
&r ATTRIBUTE_UNUSED
,
115 tree type ATTRIBUTE_UNUSED
,
116 const frange
&lh ATTRIBUTE_UNUSED
,
117 const irange
&rh ATTRIBUTE_UNUSED
,
124 range_operator::fold_range (irange
&r ATTRIBUTE_UNUSED
,
125 tree type ATTRIBUTE_UNUSED
,
126 const frange
&lh ATTRIBUTE_UNUSED
,
127 const frange
&rh ATTRIBUTE_UNUSED
,
134 range_operator::fold_range (frange
&r ATTRIBUTE_UNUSED
,
135 tree type ATTRIBUTE_UNUSED
,
136 const irange
&lh ATTRIBUTE_UNUSED
,
137 const irange
&rh ATTRIBUTE_UNUSED
,
144 range_operator::op1_range (frange
&r ATTRIBUTE_UNUSED
,
145 tree type ATTRIBUTE_UNUSED
,
146 const frange
&lhs ATTRIBUTE_UNUSED
,
147 const frange
&op2 ATTRIBUTE_UNUSED
,
154 range_operator::op1_range (frange
&r ATTRIBUTE_UNUSED
,
155 tree type ATTRIBUTE_UNUSED
,
156 const irange
&lhs ATTRIBUTE_UNUSED
,
157 const frange
&op2 ATTRIBUTE_UNUSED
,
164 range_operator::op2_range (frange
&r ATTRIBUTE_UNUSED
,
165 tree type ATTRIBUTE_UNUSED
,
166 const frange
&lhs ATTRIBUTE_UNUSED
,
167 const frange
&op1 ATTRIBUTE_UNUSED
,
174 range_operator::op2_range (frange
&r ATTRIBUTE_UNUSED
,
175 tree type ATTRIBUTE_UNUSED
,
176 const irange
&lhs ATTRIBUTE_UNUSED
,
177 const frange
&op1 ATTRIBUTE_UNUSED
,
184 range_operator::lhs_op1_relation (const frange
&lhs ATTRIBUTE_UNUSED
,
185 const frange
&op1 ATTRIBUTE_UNUSED
,
186 const frange
&op2 ATTRIBUTE_UNUSED
,
193 range_operator::lhs_op1_relation (const irange
&lhs ATTRIBUTE_UNUSED
,
194 const frange
&op1 ATTRIBUTE_UNUSED
,
195 const frange
&op2 ATTRIBUTE_UNUSED
,
202 range_operator::lhs_op2_relation (const irange
&lhs ATTRIBUTE_UNUSED
,
203 const frange
&op1 ATTRIBUTE_UNUSED
,
204 const frange
&op2 ATTRIBUTE_UNUSED
,
211 range_operator::lhs_op2_relation (const frange
&lhs ATTRIBUTE_UNUSED
,
212 const frange
&op1 ATTRIBUTE_UNUSED
,
213 const frange
&op2 ATTRIBUTE_UNUSED
,
220 range_operator::op1_op2_relation (const irange
&,
222 const frange
&) const
229 range_operator::op1_op2_relation (const frange
&,
231 const frange
&) const
236 // Return TRUE if OP1 and OP2 may be a NAN.
239 maybe_isnan (const frange
&op1
, const frange
&op2
)
241 return op1
.maybe_isnan () || op2
.maybe_isnan ();
244 // Floating point version of relop_early_resolve that takes NANs into
247 // For relation opcodes, first try to see if the supplied relation
248 // forces a true or false result, and return that.
249 // Then check for undefined operands. If none of this applies,
252 // TRIO are the relations between operands as they appear in the IL.
253 // MY_REL is the relation that corresponds to the operator being
254 // folded. For example, when attempting to fold x_3 == y_5, MY_REL is
255 // VREL_EQ, and if the statement is dominated by x_3 > y_5, then
256 // TRIO.op1_op2() is VREL_GT.
259 frelop_early_resolve (irange
&r
, tree type
,
260 const frange
&op1
, const frange
&op2
,
261 relation_trio trio
, relation_kind my_rel
)
263 relation_kind rel
= trio
.op1_op2 ();
265 // If known relation is a complete subset of this relation, always
266 // return true. However, avoid doing this when NAN is a possibility
267 // as we'll incorrectly fold conditions:
272 // ;; With NANs the relation here is basically VREL_UNLT, so we
273 // ;; can't fold the following:
275 if (!maybe_isnan (op1
, op2
) && relation_union (rel
, my_rel
) == my_rel
)
277 r
= range_true (type
);
281 // If known relation has no subset of this relation, always false.
282 if (relation_intersect (rel
, my_rel
) == VREL_UNDEFINED
)
284 r
= range_false (type
);
288 // If either operand is undefined, return VARYING.
289 if (empty_range_varying (r
, type
, op1
, op2
))
295 // Set VALUE to its next real value, or INF if the operation overflows.
298 frange_nextafter (enum machine_mode mode
,
299 REAL_VALUE_TYPE
&value
,
300 const REAL_VALUE_TYPE
&inf
)
302 if (MODE_COMPOSITE_P (mode
)
303 && (real_isdenormal (&value
, mode
) || real_iszero (&value
)))
305 // IBM extended denormals only have DFmode precision.
306 REAL_VALUE_TYPE tmp
, tmp2
;
307 real_convert (&tmp2
, DFmode
, &value
);
308 real_nextafter (&tmp
, REAL_MODE_FORMAT (DFmode
), &tmp2
, &inf
);
309 real_convert (&value
, mode
, &tmp
);
314 real_nextafter (&tmp
, REAL_MODE_FORMAT (mode
), &value
, &inf
);
319 // Like real_arithmetic, but round the result to INF if the operation
320 // produced inexact results.
322 // ?? There is still one problematic case, i387. With
323 // -fexcess-precision=standard we perform most SF/DFmode arithmetic in
324 // XFmode (long_double_type_node), so that case is OK. But without
325 // -mfpmath=sse, all the SF/DFmode computations are in XFmode
326 // precision (64-bit mantissa) and only occasionally rounded to
327 // SF/DFmode (when storing into memory from the 387 stack). Maybe
328 // this is ok as well though it is just occasionally more precise. ??
331 frange_arithmetic (enum tree_code code
, tree type
,
332 REAL_VALUE_TYPE
&result
,
333 const REAL_VALUE_TYPE
&op1
,
334 const REAL_VALUE_TYPE
&op2
,
335 const REAL_VALUE_TYPE
&inf
)
337 REAL_VALUE_TYPE value
;
338 enum machine_mode mode
= TYPE_MODE (type
);
339 bool mode_composite
= MODE_COMPOSITE_P (mode
);
341 bool inexact
= real_arithmetic (&value
, code
, &op1
, &op2
);
342 real_convert (&result
, mode
, &value
);
344 /* When rounding towards negative infinity, x + (-x) and
345 x - x is -0 rather than +0 real_arithmetic computes.
346 So, when we are looking for lower bound (inf is negative),
347 use -0 rather than +0. */
348 if (flag_rounding_math
349 && (code
== PLUS_EXPR
|| code
== MINUS_EXPR
)
351 && real_iszero (&result
)
352 && !real_isneg (&result
)
353 && real_isneg (&inf
))
355 REAL_VALUE_TYPE op2a
= op2
;
356 if (code
== PLUS_EXPR
)
358 if (real_isneg (&op1
) == real_isneg (&op2a
) && real_equal (&op1
, &op2a
))
362 // Be extra careful if there may be discrepancies between the
363 // compile and runtime results.
369 bool low
= real_isneg (&inf
);
370 round
= (low
? !real_less (&result
, &value
)
371 : !real_less (&value
, &result
));
372 if (real_isinf (&result
, !low
)
373 && !real_isinf (&value
)
374 && !flag_rounding_math
)
376 // Use just [+INF, +INF] rather than [MAX, +INF]
377 // even if value is larger than MAX and rounds to
378 // nearest to +INF. Similarly just [-INF, -INF]
379 // rather than [-INF, +MAX] even if value is smaller
380 // than -MAX and rounds to nearest to -INF.
381 // Unless INEXACT is true, in that case we need some
387 REAL_VALUE_TYPE tmp
= result
, tmp2
;
388 frange_nextafter (mode
, tmp
, inf
);
389 // TMP is at this point the maximum representable
391 real_arithmetic (&tmp2
, MINUS_EXPR
, &value
, &tmp
);
392 if (real_isneg (&tmp2
) != low
393 && (REAL_EXP (&tmp2
) - REAL_EXP (&tmp
)
394 >= 2 - REAL_MODE_FORMAT (mode
)->p
))
399 if (round
&& (inexact
|| !real_identical (&result
, &value
)))
402 && (real_isdenormal (&result
, mode
) || real_iszero (&result
)))
404 // IBM extended denormals only have DFmode precision.
405 REAL_VALUE_TYPE tmp
, tmp2
;
406 real_convert (&tmp2
, DFmode
, &value
);
407 real_nextafter (&tmp
, REAL_MODE_FORMAT (DFmode
), &tmp2
, &inf
);
408 real_convert (&result
, mode
, &tmp
);
411 frange_nextafter (mode
, result
, inf
);
418 // ibm-ldouble-format documents 1ulp for + and -.
419 frange_nextafter (mode
, result
, inf
);
422 // ibm-ldouble-format documents 2ulps for *.
423 frange_nextafter (mode
, result
, inf
);
424 frange_nextafter (mode
, result
, inf
);
427 // ibm-ldouble-format documents 3ulps for /.
428 frange_nextafter (mode
, result
, inf
);
429 frange_nextafter (mode
, result
, inf
);
430 frange_nextafter (mode
, result
, inf
);
437 // Crop R to [-INF, MAX] where MAX is the maximum representable number
441 frange_drop_inf (frange
&r
, tree type
)
443 REAL_VALUE_TYPE max
= real_max_representable (type
);
444 frange
tmp (type
, r
.lower_bound (), max
);
448 // Crop R to [MIN, +INF] where MIN is the minimum representable number
452 frange_drop_ninf (frange
&r
, tree type
)
454 REAL_VALUE_TYPE min
= real_min_representable (type
);
455 frange
tmp (type
, min
, r
.upper_bound ());
459 // Crop R to [MIN, MAX] where MAX is the maximum representable number
460 // for TYPE and MIN the minimum representable number for TYPE.
463 frange_drop_infs (frange
&r
, tree type
)
465 REAL_VALUE_TYPE max
= real_max_representable (type
);
466 REAL_VALUE_TYPE min
= real_min_representable (type
);
467 frange
tmp (type
, min
, max
);
471 // If zero is in R, make sure both -0.0 and +0.0 are in the range.
474 frange_add_zeros (frange
&r
, tree type
)
476 if (r
.undefined_p () || r
.known_isnan ())
479 if (HONOR_SIGNED_ZEROS (type
)
480 && (real_iszero (&r
.lower_bound ()) || real_iszero (&r
.upper_bound ())))
483 zero
.set_zero (type
);
488 // Build a range that is <= VAL and store it in R. Return TRUE if
489 // further changes may be needed for R, or FALSE if R is in its final
493 build_le (frange
&r
, tree type
, const frange
&val
)
495 gcc_checking_assert (!val
.known_isnan ());
497 REAL_VALUE_TYPE ninf
= frange_val_min (type
);
498 r
.set (type
, ninf
, val
.upper_bound ());
500 // Add both zeros if there's the possibility of zero equality.
501 frange_add_zeros (r
, type
);
506 // Build a range that is < VAL and store it in R. Return TRUE if
507 // further changes may be needed for R, or FALSE if R is in its final
511 build_lt (frange
&r
, tree type
, const frange
&val
)
513 gcc_checking_assert (!val
.known_isnan ());
515 // < -INF is outside the range.
516 if (real_isinf (&val
.upper_bound (), 1))
518 if (HONOR_NANS (type
))
525 REAL_VALUE_TYPE ninf
= frange_val_min (type
);
526 REAL_VALUE_TYPE prev
= val
.upper_bound ();
527 machine_mode mode
= TYPE_MODE (type
);
528 // Default to the conservatively correct closed ranges for
529 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
530 // !HONOR_INFINITIES, nextafter will yield -INF, but frange::set()
531 // will crop the range appropriately.
532 if (!MODE_COMPOSITE_P (mode
))
533 frange_nextafter (mode
, prev
, ninf
);
534 r
.set (type
, ninf
, prev
);
538 // Build a range that is >= VAL and store it in R. Return TRUE if
539 // further changes may be needed for R, or FALSE if R is in its final
543 build_ge (frange
&r
, tree type
, const frange
&val
)
545 gcc_checking_assert (!val
.known_isnan ());
547 REAL_VALUE_TYPE inf
= frange_val_max (type
);
548 r
.set (type
, val
.lower_bound (), inf
);
550 // Add both zeros if there's the possibility of zero equality.
551 frange_add_zeros (r
, type
);
556 // Build a range that is > VAL and store it in R. Return TRUE if
557 // further changes may be needed for R, or FALSE if R is in its final
561 build_gt (frange
&r
, tree type
, const frange
&val
)
563 gcc_checking_assert (!val
.known_isnan ());
565 // > +INF is outside the range.
566 if (real_isinf (&val
.lower_bound (), 0))
568 if (HONOR_NANS (type
))
575 REAL_VALUE_TYPE inf
= frange_val_max (type
);
576 REAL_VALUE_TYPE next
= val
.lower_bound ();
577 machine_mode mode
= TYPE_MODE (type
);
578 // Default to the conservatively correct closed ranges for
579 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
580 // !HONOR_INFINITIES, nextafter will yield +INF, but frange::set()
581 // will crop the range appropriately.
582 if (!MODE_COMPOSITE_P (mode
))
583 frange_nextafter (mode
, next
, inf
);
584 r
.set (type
, next
, inf
);
590 operator_identity::fold_range (frange
&r
, tree
, const frange
&op1
,
591 const frange
&, relation_trio
) const
598 operator_identity::op1_range (frange
&r
, tree
, const frange
&lhs
,
599 const frange
&, relation_trio
) const
606 operator_cst::fold_range (frange
&r
, tree
, const frange
&op1
,
607 const frange
&, relation_trio
) const
614 operator_equal::op2_range (frange
&r
, tree type
,
615 const irange
&lhs
, const frange
&op1
,
616 relation_trio rel
) const
618 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
622 operator_equal::fold_range (irange
&r
, tree type
,
623 const frange
&op1
, const frange
&op2
,
624 relation_trio rel
) const
626 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_EQ
))
629 if (op1
.known_isnan () || op2
.known_isnan ())
630 r
= range_false (type
);
631 // We can be sure the values are always equal or not if both ranges
632 // consist of a single value, and then compare them.
633 else if (op1
.singleton_p () && op2
.singleton_p ())
636 r
= range_true (type
);
637 // If one operand is -0.0 and other 0.0, they are still equal.
638 else if (real_iszero (&op1
.lower_bound ())
639 && real_iszero (&op2
.lower_bound ()))
640 r
= range_true (type
);
642 r
= range_false (type
);
644 else if (real_iszero (&op1
.lower_bound ())
645 && real_iszero (&op1
.upper_bound ())
646 && real_iszero (&op2
.lower_bound ())
647 && real_iszero (&op2
.upper_bound ())
648 && !maybe_isnan (op1
, op2
))
649 // [-0.0, 0.0] == [-0.0, 0.0] or similar.
650 r
= range_true (type
);
653 // If ranges do not intersect, we know the range is not equal,
654 // otherwise we don't know anything for sure.
657 if (tmp
.undefined_p ())
659 // If one range is [whatever, -0.0] and another
660 // [0.0, whatever2], we don't know anything either,
661 // because -0.0 == 0.0.
662 if ((real_iszero (&op1
.upper_bound ())
663 && real_iszero (&op2
.lower_bound ()))
664 || (real_iszero (&op1
.lower_bound ())
665 && real_iszero (&op2
.upper_bound ())))
666 r
= range_true_and_false (type
);
668 r
= range_false (type
);
671 r
= range_true_and_false (type
);
677 operator_equal::op1_range (frange
&r
, tree type
,
680 relation_trio trio
) const
682 relation_kind rel
= trio
.op1_op2 ();
683 switch (get_bool_state (r
, lhs
, type
))
686 // The TRUE side of x == NAN is unreachable.
687 if (op2
.known_isnan ())
691 // If it's true, the result is the same as OP2.
693 // Add both zeros if there's the possibility of zero equality.
694 frange_add_zeros (r
, type
);
695 // The TRUE side of op1 == op2 implies op1 is !NAN.
701 // The FALSE side of op1 == op1 implies op1 is a NAN.
704 // On the FALSE side of x == NAN, we know nothing about x.
705 else if (op2
.known_isnan ())
706 r
.set_varying (type
);
707 // If the result is false, the only time we know anything is
708 // if OP2 is a constant.
709 else if (op2
.singleton_p ()
710 || (!op2
.maybe_isnan () && op2
.zero_p ()))
712 REAL_VALUE_TYPE tmp
= op2
.lower_bound ();
713 r
.set (type
, tmp
, tmp
, VR_ANTI_RANGE
);
716 r
.set_varying (type
);
725 // Check if the LHS range indicates a relation between OP1 and OP2.
728 operator_equal::op1_op2_relation (const irange
&lhs
, const frange
&,
729 const frange
&) const
731 if (lhs
.undefined_p ())
732 return VREL_UNDEFINED
;
734 // FALSE = op1 == op2 indicates NE_EXPR.
738 // TRUE = op1 == op2 indicates EQ_EXPR.
739 if (!contains_zero_p (lhs
))
745 operator_not_equal::fold_range (irange
&r
, tree type
,
746 const frange
&op1
, const frange
&op2
,
747 relation_trio trio
) const
749 relation_kind rel
= trio
.op1_op2 ();
751 // VREL_NE & NE_EXPR is always true, even with NANs.
754 r
= range_true (type
);
757 if (rel
== VREL_EQ
&& maybe_isnan (op1
, op2
))
759 // Avoid frelop_early_resolve() below as it could fold to FALSE
760 // without regards to NANs. This would be incorrect if trying
761 // to fold x_5 != x_5 without prior knowledge of NANs.
763 else if (frelop_early_resolve (r
, type
, op1
, op2
, trio
, VREL_NE
))
766 // x != NAN is always TRUE.
767 if (op1
.known_isnan () || op2
.known_isnan ())
768 r
= range_true (type
);
769 // We can be sure the values are always equal or not if both ranges
770 // consist of a single value, and then compare them.
771 else if (op1
.singleton_p () && op2
.singleton_p ())
774 r
= range_false (type
);
775 // If one operand is -0.0 and other 0.0, they are still equal.
776 else if (real_iszero (&op1
.lower_bound ())
777 && real_iszero (&op2
.lower_bound ()))
778 r
= range_false (type
);
780 r
= range_true (type
);
782 else if (real_iszero (&op1
.lower_bound ())
783 && real_iszero (&op1
.upper_bound ())
784 && real_iszero (&op2
.lower_bound ())
785 && real_iszero (&op2
.upper_bound ())
786 && !maybe_isnan (op1
, op2
))
787 // [-0.0, 0.0] != [-0.0, 0.0] or similar.
788 r
= range_false (type
);
791 // If ranges do not intersect, we know the range is not equal,
792 // otherwise we don't know anything for sure.
795 if (tmp
.undefined_p ())
797 // If one range is [whatever, -0.0] and another
798 // [0.0, whatever2], we don't know anything either,
799 // because -0.0 == 0.0.
800 if ((real_iszero (&op1
.upper_bound ())
801 && real_iszero (&op2
.lower_bound ()))
802 || (real_iszero (&op1
.lower_bound ())
803 && real_iszero (&op2
.upper_bound ())))
804 r
= range_true_and_false (type
);
806 r
= range_true (type
);
809 r
= range_true_and_false (type
);
815 operator_not_equal::op1_range (frange
&r
, tree type
,
818 relation_trio trio
) const
820 relation_kind rel
= trio
.op1_op2 ();
821 switch (get_bool_state (r
, lhs
, type
))
824 // If the result is true, the only time we know anything is if
825 // OP2 is a constant.
826 if (op2
.singleton_p ())
828 // This is correct even if op1 is NAN, because the following
829 // range would be ~[tmp, tmp] with the NAN property set to
831 REAL_VALUE_TYPE tmp
= op2
.lower_bound ();
832 r
.set (type
, tmp
, tmp
, VR_ANTI_RANGE
);
834 // The TRUE side of op1 != op1 implies op1 is NAN.
835 else if (rel
== VREL_EQ
)
838 r
.set_varying (type
);
842 // The FALSE side of x != NAN is impossible.
843 if (op2
.known_isnan ())
847 // If it's false, the result is the same as OP2.
849 // Add both zeros if there's the possibility of zero equality.
850 frange_add_zeros (r
, type
);
851 // The FALSE side of op1 != op2 implies op1 is !NAN.
863 operator_not_equal::op2_range (frange
&r
, tree type
,
866 relation_trio trio
) const
868 return op1_range (r
, type
, lhs
, op1
, trio
);
871 // Check if the LHS range indicates a relation between OP1 and OP2.
874 operator_not_equal::op1_op2_relation (const irange
&lhs
, const frange
&,
875 const frange
&) const
877 if (lhs
.undefined_p ())
878 return VREL_UNDEFINED
;
880 // FALSE = op1 != op2 indicates EQ_EXPR.
884 // TRUE = op1 != op2 indicates NE_EXPR.
885 if (!contains_zero_p (lhs
))
891 operator_lt::fold_range (irange
&r
, tree type
,
892 const frange
&op1
, const frange
&op2
,
893 relation_trio trio
) const
895 if (frelop_early_resolve (r
, type
, op1
, op2
, trio
, VREL_LT
))
898 if (op1
.known_isnan ()
899 || op2
.known_isnan ()
900 || !real_less (&op1
.lower_bound (), &op2
.upper_bound ()))
901 r
= range_false (type
);
902 else if (!maybe_isnan (op1
, op2
)
903 && real_less (&op1
.upper_bound (), &op2
.lower_bound ()))
904 r
= range_true (type
);
906 r
= range_true_and_false (type
);
911 operator_lt::op1_range (frange
&r
,
917 switch (get_bool_state (r
, lhs
, type
))
920 // The TRUE side of x < NAN is unreachable.
921 if (op2
.known_isnan ())
923 else if (op2
.undefined_p ())
925 else if (build_lt (r
, type
, op2
))
928 // x < y implies x is not +INF.
929 frange_drop_inf (r
, type
);
934 // On the FALSE side of x < NAN, we know nothing about x.
935 if (op2
.maybe_isnan ())
936 r
.set_varying (type
);
938 build_ge (r
, type
, op2
);
948 operator_lt::op2_range (frange
&r
,
954 switch (get_bool_state (r
, lhs
, type
))
957 // The TRUE side of NAN < x is unreachable.
958 if (op1
.known_isnan ())
960 else if (op1
.undefined_p ())
962 else if (build_gt (r
, type
, op1
))
965 // x < y implies y is not -INF.
966 frange_drop_ninf (r
, type
);
971 // On the FALSE side of NAN < x, we know nothing about x.
972 if (op1
.maybe_isnan ())
973 r
.set_varying (type
);
975 build_le (r
, type
, op1
);
985 // Check if the LHS range indicates a relation between OP1 and OP2.
988 operator_lt::op1_op2_relation (const irange
&lhs
, const frange
&,
989 const frange
&) const
991 if (lhs
.undefined_p ())
992 return VREL_UNDEFINED
;
994 // FALSE = op1 < op2 indicates GE_EXPR.
998 // TRUE = op1 < op2 indicates LT_EXPR.
999 if (!contains_zero_p (lhs
))
1001 return VREL_VARYING
;
1005 operator_le::fold_range (irange
&r
, tree type
,
1006 const frange
&op1
, const frange
&op2
,
1007 relation_trio rel
) const
1009 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_LE
))
1012 if (op1
.known_isnan ()
1013 || op2
.known_isnan ()
1014 || !real_compare (LE_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
1015 r
= range_false (type
);
1016 else if (!maybe_isnan (op1
, op2
)
1017 && real_compare (LE_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
1018 r
= range_true (type
);
1020 r
= range_true_and_false (type
);
1025 operator_le::op1_range (frange
&r
,
1029 relation_trio
) const
1031 switch (get_bool_state (r
, lhs
, type
))
1034 // The TRUE side of x <= NAN is unreachable.
1035 if (op2
.known_isnan ())
1037 else if (op2
.undefined_p ())
1039 else if (build_le (r
, type
, op2
))
1044 // On the FALSE side of x <= NAN, we know nothing about x.
1045 if (op2
.maybe_isnan ())
1046 r
.set_varying (type
);
1048 build_gt (r
, type
, op2
);
1058 operator_le::op2_range (frange
&r
,
1062 relation_trio
) const
1064 switch (get_bool_state (r
, lhs
, type
))
1067 // The TRUE side of NAN <= x is unreachable.
1068 if (op1
.known_isnan ())
1070 else if (op1
.undefined_p ())
1072 else if (build_ge (r
, type
, op1
))
1077 // On the FALSE side of NAN <= x, we know nothing about x.
1078 if (op1
.maybe_isnan ())
1079 r
.set_varying (type
);
1080 else if (op1
.undefined_p ())
1083 build_lt (r
, type
, op1
);
1092 // Check if the LHS range indicates a relation between OP1 and OP2.
1095 operator_le::op1_op2_relation (const irange
&lhs
, const frange
&,
1096 const frange
&) const
1098 if (lhs
.undefined_p ())
1099 return VREL_UNDEFINED
;
1101 // FALSE = op1 <= op2 indicates GT_EXPR.
1105 // TRUE = op1 <= op2 indicates LE_EXPR.
1106 if (!contains_zero_p (lhs
))
1108 return VREL_VARYING
;
1112 operator_gt::fold_range (irange
&r
, tree type
,
1113 const frange
&op1
, const frange
&op2
,
1114 relation_trio trio
) const
1116 if (frelop_early_resolve (r
, type
, op1
, op2
, trio
, VREL_GT
))
1119 if (op1
.known_isnan ()
1120 || op2
.known_isnan ()
1121 || !real_compare (GT_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
1122 r
= range_false (type
);
1123 else if (!maybe_isnan (op1
, op2
)
1124 && real_compare (GT_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
1125 r
= range_true (type
);
1127 r
= range_true_and_false (type
);
1132 operator_gt::op1_range (frange
&r
,
1136 relation_trio
) const
1138 switch (get_bool_state (r
, lhs
, type
))
1141 // The TRUE side of x > NAN is unreachable.
1142 if (op2
.known_isnan ())
1144 else if (op2
.undefined_p ())
1146 else if (build_gt (r
, type
, op2
))
1149 // x > y implies x is not -INF.
1150 frange_drop_ninf (r
, type
);
1155 // On the FALSE side of x > NAN, we know nothing about x.
1156 if (op2
.maybe_isnan ())
1157 r
.set_varying (type
);
1158 else if (op2
.undefined_p ())
1161 build_le (r
, type
, op2
);
1171 operator_gt::op2_range (frange
&r
,
1175 relation_trio
) const
1177 switch (get_bool_state (r
, lhs
, type
))
1180 // The TRUE side of NAN > x is unreachable.
1181 if (op1
.known_isnan ())
1183 else if (op1
.undefined_p ())
1185 else if (build_lt (r
, type
, op1
))
1188 // x > y implies y is not +INF.
1189 frange_drop_inf (r
, type
);
1194 // On The FALSE side of NAN > x, we know nothing about x.
1195 if (op1
.maybe_isnan ())
1196 r
.set_varying (type
);
1197 else if (op1
.undefined_p ())
1200 build_ge (r
, type
, op1
);
1209 // Check if the LHS range indicates a relation between OP1 and OP2.
1212 operator_gt::op1_op2_relation (const irange
&lhs
, const frange
&,
1213 const frange
&) const
1215 if (lhs
.undefined_p ())
1216 return VREL_UNDEFINED
;
1218 // FALSE = op1 > op2 indicates LE_EXPR.
1222 // TRUE = op1 > op2 indicates GT_EXPR.
1223 if (!contains_zero_p (lhs
))
1225 return VREL_VARYING
;
1229 operator_ge::fold_range (irange
&r
, tree type
,
1230 const frange
&op1
, const frange
&op2
,
1231 relation_trio rel
) const
1233 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_GE
))
1236 if (op1
.known_isnan ()
1237 || op2
.known_isnan ()
1238 || !real_compare (GE_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
1239 r
= range_false (type
);
1240 else if (!maybe_isnan (op1
, op2
)
1241 && real_compare (GE_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
1242 r
= range_true (type
);
1244 r
= range_true_and_false (type
);
1249 operator_ge::op1_range (frange
&r
,
1253 relation_trio
) const
1255 switch (get_bool_state (r
, lhs
, type
))
1258 // The TRUE side of x >= NAN is unreachable.
1259 if (op2
.known_isnan ())
1261 else if (op2
.undefined_p ())
1263 else if (build_ge (r
, type
, op2
))
1268 // On the FALSE side of x >= NAN, we know nothing about x.
1269 if (op2
.maybe_isnan ())
1270 r
.set_varying (type
);
1271 else if (op2
.undefined_p ())
1274 build_lt (r
, type
, op2
);
1284 operator_ge::op2_range (frange
&r
, tree type
,
1287 relation_trio
) const
1289 switch (get_bool_state (r
, lhs
, type
))
1292 // The TRUE side of NAN >= x is unreachable.
1293 if (op1
.known_isnan ())
1295 else if (op1
.undefined_p ())
1297 else if (build_le (r
, type
, op1
))
1302 // On the FALSE side of NAN >= x, we know nothing about x.
1303 if (op1
.maybe_isnan ())
1304 r
.set_varying (type
);
1305 else if (op1
.undefined_p ())
1308 build_gt (r
, type
, op1
);
1317 // Check if the LHS range indicates a relation between OP1 and OP2.
1320 operator_ge::op1_op2_relation (const irange
&lhs
, const frange
&,
1321 const frange
&) const
1323 if (lhs
.undefined_p ())
1324 return VREL_UNDEFINED
;
1326 // FALSE = op1 >= op2 indicates LT_EXPR.
1330 // TRUE = op1 >= op2 indicates GE_EXPR.
1331 if (!contains_zero_p (lhs
))
1333 return VREL_VARYING
;
1336 // UNORDERED_EXPR comparison.
1338 class foperator_unordered
: public range_operator
1340 using range_operator::fold_range
;
1341 using range_operator::op1_range
;
1342 using range_operator::op2_range
;
1344 bool fold_range (irange
&r
, tree type
,
1345 const frange
&op1
, const frange
&op2
,
1346 relation_trio
= TRIO_VARYING
) const final override
;
1347 bool op1_range (frange
&r
, tree type
,
1348 const irange
&lhs
, const frange
&op2
,
1349 relation_trio
= TRIO_VARYING
) const final override
;
1350 bool op2_range (frange
&r
, tree type
,
1351 const irange
&lhs
, const frange
&op1
,
1352 relation_trio rel
= TRIO_VARYING
) const final override
1354 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
1359 foperator_unordered::fold_range (irange
&r
, tree type
,
1360 const frange
&op1
, const frange
&op2
,
1361 relation_trio
) const
1363 // UNORDERED is TRUE if either operand is a NAN.
1364 if (op1
.known_isnan () || op2
.known_isnan ())
1365 r
= range_true (type
);
1366 // UNORDERED is FALSE if neither operand is a NAN.
1367 else if (!op1
.maybe_isnan () && !op2
.maybe_isnan ())
1368 r
= range_false (type
);
1370 r
= range_true_and_false (type
);
1375 foperator_unordered::op1_range (frange
&r
, tree type
,
1378 relation_trio trio
) const
1380 relation_kind rel
= trio
.op1_op2 ();
1381 switch (get_bool_state (r
, lhs
, type
))
1384 // Since at least one operand must be NAN, if one of them is
1385 // not, the other must be.
1386 if (rel
== VREL_EQ
|| !op2
.maybe_isnan ())
1389 r
.set_varying (type
);
1393 // A false UNORDERED means both operands are !NAN, so it's
1394 // impossible for op2 to be a NAN.
1395 if (op2
.known_isnan ())
1399 r
.set_varying (type
);
1410 // ORDERED_EXPR comparison.
1412 class foperator_ordered
: public range_operator
1414 using range_operator::fold_range
;
1415 using range_operator::op1_range
;
1416 using range_operator::op2_range
;
1418 bool fold_range (irange
&r
, tree type
,
1419 const frange
&op1
, const frange
&op2
,
1420 relation_trio
= TRIO_VARYING
) const final override
;
1421 bool op1_range (frange
&r
, tree type
,
1422 const irange
&lhs
, const frange
&op2
,
1423 relation_trio
= TRIO_VARYING
) const final override
;
1424 bool op2_range (frange
&r
, tree type
,
1425 const irange
&lhs
, const frange
&op1
,
1426 relation_trio rel
= TRIO_VARYING
) const final override
1428 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
1433 foperator_ordered::fold_range (irange
&r
, tree type
,
1434 const frange
&op1
, const frange
&op2
,
1435 relation_trio
) const
1437 if (op1
.known_isnan () || op2
.known_isnan ())
1438 r
= range_false (type
);
1439 else if (!op1
.maybe_isnan () && !op2
.maybe_isnan ())
1440 r
= range_true (type
);
1442 r
= range_true_and_false (type
);
1447 foperator_ordered::op1_range (frange
&r
, tree type
,
1450 relation_trio trio
) const
1452 relation_kind rel
= trio
.op1_op2 ();
1453 switch (get_bool_state (r
, lhs
, type
))
1456 // The TRUE side of ORDERED means both operands are !NAN, so
1457 // it's impossible for op2 to be a NAN.
1458 if (op2
.known_isnan ())
1462 r
.set_varying (type
);
1468 // The FALSE side of op1 ORDERED op1 implies op1 is NAN.
1472 r
.set_varying (type
);
1482 operator_negate::fold_range (frange
&r
, tree type
,
1483 const frange
&op1
, const frange
&op2
,
1484 relation_trio
) const
1486 if (empty_range_varying (r
, type
, op1
, op2
))
1488 if (op1
.known_isnan ())
1491 if (op1
.nan_signbit_p (sign
))
1492 r
.set_nan (type
, !sign
);
1498 REAL_VALUE_TYPE lh_lb
= op1
.lower_bound ();
1499 REAL_VALUE_TYPE lh_ub
= op1
.upper_bound ();
1500 lh_lb
= real_value_negate (&lh_lb
);
1501 lh_ub
= real_value_negate (&lh_ub
);
1502 r
.set (type
, lh_ub
, lh_lb
);
1503 if (op1
.maybe_isnan ())
1506 if (op1
.nan_signbit_p (sign
))
1507 r
.update_nan (!sign
);
1517 operator_negate::op1_range (frange
&r
, tree type
,
1518 const frange
&lhs
, const frange
&op2
,
1519 relation_trio rel
) const
1521 return fold_range (r
, type
, lhs
, op2
, rel
);
1525 operator_abs::fold_range (frange
&r
, tree type
,
1526 const frange
&op1
, const frange
&op2
,
1527 relation_trio
) const
1529 if (empty_range_varying (r
, type
, op1
, op2
))
1531 if (op1
.known_isnan ())
1533 r
.set_nan (type
, /*sign=*/false);
1537 const REAL_VALUE_TYPE lh_lb
= op1
.lower_bound ();
1538 const REAL_VALUE_TYPE lh_ub
= op1
.upper_bound ();
1539 // Handle the easy case where everything is positive.
1540 if (real_compare (GE_EXPR
, &lh_lb
, &dconst0
)
1541 && !real_iszero (&lh_lb
, /*sign=*/true)
1542 && !op1
.maybe_isnan (/*sign=*/true))
1548 REAL_VALUE_TYPE min
= real_value_abs (&lh_lb
);
1549 REAL_VALUE_TYPE max
= real_value_abs (&lh_ub
);
1550 // If the range contains zero then we know that the minimum value in the
1551 // range will be zero.
1552 if (real_compare (LE_EXPR
, &lh_lb
, &dconst0
)
1553 && real_compare (GE_EXPR
, &lh_ub
, &dconst0
))
1555 if (real_compare (GT_EXPR
, &min
, &max
))
1561 // If the range was reversed, swap MIN and MAX.
1562 if (real_compare (GT_EXPR
, &min
, &max
))
1563 std::swap (min
, max
);
1566 r
.set (type
, min
, max
);
1567 if (op1
.maybe_isnan ())
1568 r
.update_nan (/*sign=*/false);
1575 operator_abs::op1_range (frange
&r
, tree type
,
1576 const frange
&lhs
, const frange
&op2
,
1577 relation_trio
) const
1579 if (empty_range_varying (r
, type
, lhs
, op2
))
1581 if (lhs
.known_isnan ())
1587 // Start with the positives because negatives are an impossible result.
1588 frange
positives (type
, dconst0
, frange_val_max (type
));
1589 positives
.update_nan (/*sign=*/false);
1590 positives
.intersect (lhs
);
1592 // Add -NAN if relevant.
1593 if (r
.maybe_isnan ())
1596 neg_nan
.set_nan (type
, true);
1599 if (r
.known_isnan () || r
.undefined_p ())
1601 // Then add the negative of each pair:
1602 // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
1603 frange
negatives (type
, real_value_negate (&positives
.upper_bound ()),
1604 real_value_negate (&positives
.lower_bound ()));
1605 negatives
.clear_nan ();
1606 r
.union_ (negatives
);
1610 class foperator_unordered_lt
: public range_operator
1612 using range_operator::fold_range
;
1613 using range_operator::op1_range
;
1614 using range_operator::op2_range
;
1616 bool fold_range (irange
&r
, tree type
,
1617 const frange
&op1
, const frange
&op2
,
1618 relation_trio trio
= TRIO_VARYING
) const final override
1620 if (op1
.known_isnan () || op2
.known_isnan ())
1622 r
= range_true (type
);
1625 frange op1_no_nan
= op1
;
1626 frange op2_no_nan
= op2
;
1627 if (op1
.maybe_isnan ())
1628 op1_no_nan
.clear_nan ();
1629 if (op2
.maybe_isnan ())
1630 op2_no_nan
.clear_nan ();
1631 if (!range_op_handler (LT_EXPR
).fold_range (r
, type
, op1_no_nan
,
1634 // The result is the same as the ordered version when the
1635 // comparison is true or when the operands cannot be NANs.
1636 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1640 r
= range_true_and_false (type
);
1644 bool op1_range (frange
&r
, tree type
,
1647 relation_trio trio
) const final override
;
1648 bool op2_range (frange
&r
, tree type
,
1651 relation_trio trio
) const final override
;
1655 foperator_unordered_lt::op1_range (frange
&r
, tree type
,
1658 relation_trio
) const
1660 switch (get_bool_state (r
, lhs
, type
))
1663 if (op2
.maybe_isnan ())
1664 r
.set_varying (type
);
1665 else if (op2
.undefined_p ())
1668 build_lt (r
, type
, op2
);
1672 // A false UNORDERED_LT means both operands are !NAN, so it's
1673 // impossible for op2 to be a NAN.
1674 if (op2
.known_isnan ())
1676 else if (op2
.undefined_p ())
1678 else if (build_ge (r
, type
, op2
))
1689 foperator_unordered_lt::op2_range (frange
&r
, tree type
,
1692 relation_trio
) const
1694 switch (get_bool_state (r
, lhs
, type
))
1697 if (op1
.maybe_isnan ())
1698 r
.set_varying (type
);
1699 else if (op1
.undefined_p ())
1702 build_gt (r
, type
, op1
);
1706 // A false UNORDERED_LT means both operands are !NAN, so it's
1707 // impossible for op1 to be a NAN.
1708 if (op1
.known_isnan ())
1710 else if (op1
.undefined_p ())
1712 else if (build_le (r
, type
, op1
))
1722 class foperator_unordered_le
: public range_operator
1724 using range_operator::fold_range
;
1725 using range_operator::op1_range
;
1726 using range_operator::op2_range
;
1728 bool fold_range (irange
&r
, tree type
,
1729 const frange
&op1
, const frange
&op2
,
1730 relation_trio trio
= TRIO_VARYING
) const final override
1732 if (op1
.known_isnan () || op2
.known_isnan ())
1734 r
= range_true (type
);
1737 frange op1_no_nan
= op1
;
1738 frange op2_no_nan
= op2
;
1739 if (op1
.maybe_isnan ())
1740 op1_no_nan
.clear_nan ();
1741 if (op2
.maybe_isnan ())
1742 op2_no_nan
.clear_nan ();
1743 if (!range_op_handler (LE_EXPR
).fold_range (r
, type
, op1_no_nan
,
1746 // The result is the same as the ordered version when the
1747 // comparison is true or when the operands cannot be NANs.
1748 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1752 r
= range_true_and_false (type
);
1756 bool op1_range (frange
&r
, tree type
,
1757 const irange
&lhs
, const frange
&op2
,
1758 relation_trio
= TRIO_VARYING
) const final override
;
1759 bool op2_range (frange
&r
, tree type
,
1760 const irange
&lhs
, const frange
&op1
,
1761 relation_trio
= TRIO_VARYING
) const final override
;
1765 foperator_unordered_le::op1_range (frange
&r
, tree type
,
1766 const irange
&lhs
, const frange
&op2
,
1767 relation_trio
) const
1769 switch (get_bool_state (r
, lhs
, type
))
1772 if (op2
.maybe_isnan ())
1773 r
.set_varying (type
);
1774 else if (op2
.undefined_p ())
1777 build_le (r
, type
, op2
);
1781 // A false UNORDERED_LE means both operands are !NAN, so it's
1782 // impossible for op2 to be a NAN.
1783 if (op2
.known_isnan ())
1785 else if (build_gt (r
, type
, op2
))
1796 foperator_unordered_le::op2_range (frange
&r
,
1800 relation_trio
) const
1802 switch (get_bool_state (r
, lhs
, type
))
1805 if (op1
.maybe_isnan ())
1806 r
.set_varying (type
);
1807 else if (op1
.undefined_p ())
1810 build_ge (r
, type
, op1
);
1814 // A false UNORDERED_LE means both operands are !NAN, so it's
1815 // impossible for op1 to be a NAN.
1816 if (op1
.known_isnan ())
1818 else if (op1
.undefined_p ())
1820 else if (build_lt (r
, type
, op1
))
1830 class foperator_unordered_gt
: public range_operator
1832 using range_operator::fold_range
;
1833 using range_operator::op1_range
;
1834 using range_operator::op2_range
;
1836 bool fold_range (irange
&r
, tree type
,
1837 const frange
&op1
, const frange
&op2
,
1838 relation_trio trio
= TRIO_VARYING
) const final override
1840 if (op1
.known_isnan () || op2
.known_isnan ())
1842 r
= range_true (type
);
1845 frange op1_no_nan
= op1
;
1846 frange op2_no_nan
= op2
;
1847 if (op1
.maybe_isnan ())
1848 op1_no_nan
.clear_nan ();
1849 if (op2
.maybe_isnan ())
1850 op2_no_nan
.clear_nan ();
1851 if (!range_op_handler (GT_EXPR
).fold_range (r
, type
, op1_no_nan
,
1854 // The result is the same as the ordered version when the
1855 // comparison is true or when the operands cannot be NANs.
1856 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1860 r
= range_true_and_false (type
);
1864 bool op1_range (frange
&r
, tree type
,
1865 const irange
&lhs
, const frange
&op2
,
1866 relation_trio
= TRIO_VARYING
) const final override
;
1867 bool op2_range (frange
&r
, tree type
,
1868 const irange
&lhs
, const frange
&op1
,
1869 relation_trio
= TRIO_VARYING
) const final override
;
1873 foperator_unordered_gt::op1_range (frange
&r
,
1877 relation_trio
) const
1879 switch (get_bool_state (r
, lhs
, type
))
1882 if (op2
.maybe_isnan ())
1883 r
.set_varying (type
);
1884 else if (op2
.undefined_p ())
1887 build_gt (r
, type
, op2
);
1891 // A false UNORDERED_GT means both operands are !NAN, so it's
1892 // impossible for op2 to be a NAN.
1893 if (op2
.known_isnan ())
1895 else if (op2
.undefined_p ())
1897 else if (build_le (r
, type
, op2
))
1908 foperator_unordered_gt::op2_range (frange
&r
,
1912 relation_trio
) const
1914 switch (get_bool_state (r
, lhs
, type
))
1917 if (op1
.maybe_isnan ())
1918 r
.set_varying (type
);
1919 else if (op1
.undefined_p ())
1922 build_lt (r
, type
, op1
);
1926 // A false UNORDERED_GT means both operands are !NAN, so it's
1927 // impossible for op1 to be a NAN.
1928 if (op1
.known_isnan ())
1930 else if (op1
.undefined_p ())
1932 else if (build_ge (r
, type
, op1
))
1942 class foperator_unordered_ge
: public range_operator
1944 using range_operator::fold_range
;
1945 using range_operator::op1_range
;
1946 using range_operator::op2_range
;
1948 bool fold_range (irange
&r
, tree type
,
1949 const frange
&op1
, const frange
&op2
,
1950 relation_trio trio
= TRIO_VARYING
) const final override
1952 if (op1
.known_isnan () || op2
.known_isnan ())
1954 r
= range_true (type
);
1957 frange op1_no_nan
= op1
;
1958 frange op2_no_nan
= op2
;
1959 if (op1
.maybe_isnan ())
1960 op1_no_nan
.clear_nan ();
1961 if (op2
.maybe_isnan ())
1962 op2_no_nan
.clear_nan ();
1963 if (!range_op_handler (GE_EXPR
).fold_range (r
, type
, op1_no_nan
,
1966 // The result is the same as the ordered version when the
1967 // comparison is true or when the operands cannot be NANs.
1968 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1972 r
= range_true_and_false (type
);
1976 bool op1_range (frange
&r
, tree type
,
1977 const irange
&lhs
, const frange
&op2
,
1978 relation_trio
= TRIO_VARYING
) const final override
;
1979 bool op2_range (frange
&r
, tree type
,
1980 const irange
&lhs
, const frange
&op1
,
1981 relation_trio
= TRIO_VARYING
) const final override
;
1985 foperator_unordered_ge::op1_range (frange
&r
,
1989 relation_trio
) const
1991 switch (get_bool_state (r
, lhs
, type
))
1994 if (op2
.maybe_isnan ())
1995 r
.set_varying (type
);
1996 else if (op2
.undefined_p ())
1999 build_ge (r
, type
, op2
);
2003 // A false UNORDERED_GE means both operands are !NAN, so it's
2004 // impossible for op2 to be a NAN.
2005 if (op2
.known_isnan ())
2007 else if (op2
.undefined_p ())
2009 else if (build_lt (r
, type
, op2
))
2020 foperator_unordered_ge::op2_range (frange
&r
, tree type
,
2023 relation_trio
) const
2025 switch (get_bool_state (r
, lhs
, type
))
2028 if (op1
.maybe_isnan ())
2029 r
.set_varying (type
);
2030 else if (op1
.undefined_p ())
2033 build_le (r
, type
, op1
);
2037 // A false UNORDERED_GE means both operands are !NAN, so it's
2038 // impossible for op1 to be a NAN.
2039 if (op1
.known_isnan ())
2041 else if (op1
.undefined_p ())
2043 else if (build_gt (r
, type
, op1
))
2053 class foperator_unordered_equal
: public range_operator
2055 using range_operator::fold_range
;
2056 using range_operator::op1_range
;
2057 using range_operator::op2_range
;
2059 bool fold_range (irange
&r
, tree type
,
2060 const frange
&op1
, const frange
&op2
,
2061 relation_trio trio
= TRIO_VARYING
) const final override
2063 if (op1
.known_isnan () || op2
.known_isnan ())
2065 r
= range_true (type
);
2068 frange op1_no_nan
= op1
;
2069 frange op2_no_nan
= op2
;
2070 if (op1
.maybe_isnan ())
2071 op1_no_nan
.clear_nan ();
2072 if (op2
.maybe_isnan ())
2073 op2_no_nan
.clear_nan ();
2074 if (!range_op_handler (EQ_EXPR
).fold_range (r
, type
, op1_no_nan
,
2077 // The result is the same as the ordered version when the
2078 // comparison is true or when the operands cannot be NANs.
2079 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
2083 r
= range_true_and_false (type
);
2087 bool op1_range (frange
&r
, tree type
,
2088 const irange
&lhs
, const frange
&op2
,
2089 relation_trio
= TRIO_VARYING
) const final override
;
2090 bool op2_range (frange
&r
, tree type
,
2091 const irange
&lhs
, const frange
&op1
,
2092 relation_trio rel
= TRIO_VARYING
) const final override
2094 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
2096 } fop_unordered_equal
;
2099 foperator_unordered_equal::op1_range (frange
&r
, tree type
,
2102 relation_trio
) const
2104 switch (get_bool_state (r
, lhs
, type
))
2107 // If it's true, the result is the same as OP2 plus a NAN.
2109 // Add both zeros if there's the possibility of zero equality.
2110 frange_add_zeros (r
, type
);
2111 // Add the possibility of a NAN.
2116 // A false UNORDERED_EQ means both operands are !NAN, so it's
2117 // impossible for op2 to be a NAN.
2118 if (op2
.known_isnan ())
2122 // The false side indicates !NAN and not equal. We can at least
2124 r
.set_varying (type
);
2135 class foperator_ltgt
: public range_operator
2137 using range_operator::fold_range
;
2138 using range_operator::op1_range
;
2139 using range_operator::op2_range
;
2141 bool fold_range (irange
&r
, tree type
,
2142 const frange
&op1
, const frange
&op2
,
2143 relation_trio trio
= TRIO_VARYING
) const final override
2145 if (op1
.known_isnan () || op2
.known_isnan ())
2147 r
= range_false (type
);
2150 frange op1_no_nan
= op1
;
2151 frange op2_no_nan
= op2
;
2152 if (op1
.maybe_isnan ())
2153 op1_no_nan
.clear_nan ();
2154 if (op2
.maybe_isnan ())
2155 op2_no_nan
.clear_nan ();
2156 if (!range_op_handler (NE_EXPR
).fold_range (r
, type
, op1_no_nan
,
2159 // The result is the same as the ordered version when the
2160 // comparison is true or when the operands cannot be NANs.
2161 if (!maybe_isnan (op1
, op2
) || r
== range_false (type
))
2165 r
= range_true_and_false (type
);
2169 bool op1_range (frange
&r
, tree type
,
2170 const irange
&lhs
, const frange
&op2
,
2171 relation_trio
= TRIO_VARYING
) const final override
;
2172 bool op2_range (frange
&r
, tree type
,
2173 const irange
&lhs
, const frange
&op1
,
2174 relation_trio rel
= TRIO_VARYING
) const final override
2176 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
2181 foperator_ltgt::op1_range (frange
&r
, tree type
,
2184 relation_trio
) const
2186 switch (get_bool_state (r
, lhs
, type
))
2189 // A true LTGT means both operands are !NAN, so it's
2190 // impossible for op2 to be a NAN.
2191 if (op2
.known_isnan ())
2195 // The true side indicates !NAN and not equal. We can at least
2197 r
.set_varying (type
);
2203 // If it's false, the result is the same as OP2 plus a NAN.
2205 // Add both zeros if there's the possibility of zero equality.
2206 frange_add_zeros (r
, type
);
2207 // Add the possibility of a NAN.
2217 // Final tweaks for float binary op op1_range/op2_range.
2218 // Return TRUE if the operation is performed and a valid range is available.
2221 float_binary_op_range_finish (bool ret
, frange
&r
, tree type
,
2222 const frange
&lhs
, bool div_op2
= false)
2227 // If we get a known NAN from reverse op, it means either that
2228 // the other operand was known NAN (in that case we know nothing),
2229 // or the reverse operation introduced a known NAN.
2230 // Say for lhs = op1 * op2 if lhs is [-0, +0] and op2 is too,
2231 // 0 / 0 is known NAN. Just punt in that case.
2232 // If NANs aren't honored, we get for 0 / 0 UNDEFINED, so punt as well.
2233 // Or if lhs is a known NAN, we also don't know anything.
2234 if (r
.known_isnan () || lhs
.known_isnan () || r
.undefined_p ())
2236 r
.set_varying (type
);
2240 // If lhs isn't NAN, then neither operand could be NAN,
2241 // even if the reverse operation does introduce a maybe_nan.
2242 if (!lhs
.maybe_isnan ())
2246 ? !(real_compare (LE_EXPR
, &lhs
.lower_bound (), &dconst0
)
2247 && real_compare (GE_EXPR
, &lhs
.upper_bound (), &dconst0
))
2248 : !(real_isinf (&lhs
.lower_bound ())
2249 || real_isinf (&lhs
.upper_bound ())))
2250 // For reverse + or - or * or op1 of /, if result is finite, then
2251 // r must be finite too, as X + INF or X - INF or X * INF or
2252 // INF / X is always +-INF or NAN. For op2 of /, if result is
2253 // non-zero and not NAN, r must be finite, as X / INF is always
2255 frange_drop_infs (r
, type
);
2257 // If lhs is a maybe or known NAN, the operand could be
2264 // True if [lb, ub] is [+-0, +-0].
2266 zero_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
2268 return real_iszero (&lb
) && real_iszero (&ub
);
2271 // True if +0 or -0 is in [lb, ub] range.
2273 contains_zero_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
2275 return (real_compare (LE_EXPR
, &lb
, &dconst0
)
2276 && real_compare (GE_EXPR
, &ub
, &dconst0
));
2279 // True if [lb, ub] is [-INF, -INF] or [+INF, +INF].
2281 singleton_inf_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
2283 return real_isinf (&lb
) && real_isinf (&ub
, real_isneg (&lb
));
2286 // Return -1 if binary op result must have sign bit set,
2287 // 1 if binary op result must have sign bit clear,
2289 // Sign bit of binary op result is exclusive or of the
2290 // operand's sign bits.
2292 signbit_known_p (const REAL_VALUE_TYPE
&lh_lb
, const REAL_VALUE_TYPE
&lh_ub
,
2293 const REAL_VALUE_TYPE
&rh_lb
, const REAL_VALUE_TYPE
&rh_ub
)
2295 if (real_isneg (&lh_lb
) == real_isneg (&lh_ub
)
2296 && real_isneg (&rh_lb
) == real_isneg (&rh_ub
))
2298 if (real_isneg (&lh_lb
) == real_isneg (&rh_ub
))
2306 // Set [lb, ub] to [-0, -0], [-0, +0] or [+0, +0] depending on
2309 zero_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
2312 if (signbit_known
<= 0)
2314 if (signbit_known
< 0)
2318 // Set [lb, ub] to [-INF, -INF], [-INF, +INF] or [+INF, +INF] depending on
2321 inf_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
2323 if (signbit_known
> 0)
2324 ub
= lb
= dconstinf
;
2325 else if (signbit_known
< 0)
2326 ub
= lb
= dconstninf
;
2334 // Set [lb, ub] to [-INF, -0], [-INF, +INF] or [+0, +INF] depending on
2337 zero_to_inf_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
2339 if (signbit_known
> 0)
2344 else if (signbit_known
< 0)
2356 /* Extend the LHS range by 1ulp in each direction. For op1_range
2357 or op2_range of binary operations just computing the inverse
2358 operation on ranges isn't sufficient. Consider e.g.
2359 [1., 1.] = op1 + [1., 1.]. op1's range is not [0., 0.], but
2360 [-0x1.0p-54, 0x1.0p-53] (when not -frounding-math), any value for
2361 which adding 1. to it results in 1. after rounding to nearest.
2362 So, for op1_range/op2_range extend the lhs range by 1ulp (or 0.5ulp)
2363 in each direction. See PR109008 for more details. */
2366 float_widen_lhs_range (tree type
, const frange
&lhs
)
2369 if (lhs
.known_isnan ())
2371 REAL_VALUE_TYPE lb
= lhs
.lower_bound ();
2372 REAL_VALUE_TYPE ub
= lhs
.upper_bound ();
2373 if (real_isfinite (&lb
))
2375 frange_nextafter (TYPE_MODE (type
), lb
, dconstninf
);
2376 if (real_isinf (&lb
))
2378 /* For -DBL_MAX, instead of -Inf use
2379 nexttoward (-DBL_MAX, -LDBL_MAX) in a hypothetical
2380 wider type with the same mantissa precision but larger
2381 exponent range; it is outside of range of double values,
2382 but makes it clear it is just one ulp larger rather than
2383 infinite amount larger. */
2385 SET_REAL_EXP (&lb
, FLOAT_MODE_FORMAT (TYPE_MODE (type
))->emax
+ 1);
2387 if (!flag_rounding_math
&& !MODE_COMPOSITE_P (TYPE_MODE (type
)))
2389 /* If not -frounding-math nor IBM double double, actually widen
2390 just by 0.5ulp rather than 1ulp. */
2391 REAL_VALUE_TYPE tem
;
2392 real_arithmetic (&tem
, PLUS_EXPR
, &lhs
.lower_bound (), &lb
);
2393 real_arithmetic (&lb
, RDIV_EXPR
, &tem
, &dconst2
);
2396 if (real_isfinite (&ub
))
2398 frange_nextafter (TYPE_MODE (type
), ub
, dconstinf
);
2399 if (real_isinf (&ub
))
2401 /* For DBL_MAX similarly. */
2403 SET_REAL_EXP (&ub
, FLOAT_MODE_FORMAT (TYPE_MODE (type
))->emax
+ 1);
2405 if (!flag_rounding_math
&& !MODE_COMPOSITE_P (TYPE_MODE (type
)))
2407 /* If not -frounding-math nor IBM double double, actually widen
2408 just by 0.5ulp rather than 1ulp. */
2409 REAL_VALUE_TYPE tem
;
2410 real_arithmetic (&tem
, PLUS_EXPR
, &lhs
.upper_bound (), &ub
);
2411 real_arithmetic (&ub
, RDIV_EXPR
, &tem
, &dconst2
);
2414 /* Temporarily disable -ffinite-math-only, so that frange::set doesn't
2415 reduce the range back to real_min_representable (type) as lower bound
2416 or real_max_representable (type) as upper bound. */
2417 bool save_flag_finite_math_only
= flag_finite_math_only
;
2418 flag_finite_math_only
= false;
2419 ret
.set (type
, lb
, ub
, lhs
.get_nan_state ());
2420 flag_finite_math_only
= save_flag_finite_math_only
;
2425 operator_plus::op1_range (frange
&r
, tree type
, const frange
&lhs
,
2426 const frange
&op2
, relation_trio
) const
2428 if (lhs
.undefined_p ())
2430 range_op_handler
minus (MINUS_EXPR
);
2433 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2434 return float_binary_op_range_finish (minus
.fold_range (r
, type
, wlhs
, op2
),
2439 operator_plus::op2_range (frange
&r
, tree type
,
2440 const frange
&lhs
, const frange
&op1
,
2441 relation_trio
) const
2443 return op1_range (r
, type
, lhs
, op1
);
2447 operator_plus::rv_fold (frange
&r
, tree type
,
2448 const REAL_VALUE_TYPE
&lh_lb
,
2449 const REAL_VALUE_TYPE
&lh_ub
,
2450 const REAL_VALUE_TYPE
&rh_lb
,
2451 const REAL_VALUE_TYPE
&rh_ub
,
2452 relation_kind
) const
2454 REAL_VALUE_TYPE lb
, ub
;
2455 bool maybe_nan
= false;
2457 frange_arithmetic (PLUS_EXPR
, type
, lb
, lh_lb
, rh_lb
, dconstninf
);
2458 frange_arithmetic (PLUS_EXPR
, type
, ub
, lh_ub
, rh_ub
, dconstinf
);
2460 // [-INF] + [+INF] = NAN
2461 if (real_isinf (&lh_lb
, true) && real_isinf (&rh_ub
, false))
2463 // [+INF] + [-INF] = NAN
2464 else if (real_isinf (&lh_ub
, false) && real_isinf (&rh_lb
, true))
2467 // Handle possible NANs by saturating to the appropriate INF if only
2468 // one end is a NAN. If both ends are a NAN, just return a NAN.
2469 bool lb_nan
= real_isnan (&lb
);
2470 bool ub_nan
= real_isnan (&ub
);
2471 if (lb_nan
&& ub_nan
)
2480 r
.set (type
, lb
, ub
, nan_state (maybe_nan
));
2485 operator_minus::op1_range (frange
&r
, tree type
,
2486 const frange
&lhs
, const frange
&op2
,
2487 relation_trio
) const
2489 if (lhs
.undefined_p ())
2491 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2492 return float_binary_op_range_finish (
2493 range_op_handler (PLUS_EXPR
).fold_range (r
, type
, wlhs
, op2
),
2498 operator_minus::op2_range (frange
&r
, tree type
,
2499 const frange
&lhs
, const frange
&op1
,
2500 relation_trio
) const
2502 if (lhs
.undefined_p ())
2504 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2505 return float_binary_op_range_finish (fold_range (r
, type
, op1
, wlhs
),
2510 operator_minus::rv_fold (frange
&r
, tree type
,
2511 const REAL_VALUE_TYPE
&lh_lb
,
2512 const REAL_VALUE_TYPE
&lh_ub
,
2513 const REAL_VALUE_TYPE
&rh_lb
,
2514 const REAL_VALUE_TYPE
&rh_ub
,
2515 relation_kind
) const
2517 REAL_VALUE_TYPE lb
, ub
;
2518 bool maybe_nan
= false;
2520 frange_arithmetic (MINUS_EXPR
, type
, lb
, lh_lb
, rh_ub
, dconstninf
);
2521 frange_arithmetic (MINUS_EXPR
, type
, ub
, lh_ub
, rh_lb
, dconstinf
);
2523 // [+INF] - [+INF] = NAN
2524 if (real_isinf (&lh_ub
, false) && real_isinf (&rh_ub
, false))
2526 // [-INF] - [-INF] = NAN
2527 else if (real_isinf (&lh_lb
, true) && real_isinf (&rh_lb
, true))
2530 // Handle possible NANs by saturating to the appropriate INF if only
2531 // one end is a NAN. If both ends are a NAN, just return a NAN.
2532 bool lb_nan
= real_isnan (&lb
);
2533 bool ub_nan
= real_isnan (&ub
);
2534 if (lb_nan
&& ub_nan
)
2543 r
.set (type
, lb
, ub
, nan_state (maybe_nan
));
2547 // Given CP[0] to CP[3] floating point values rounded to -INF,
2548 // set LB to the smallest of them (treating -0 as smaller to +0).
2549 // Given CP[4] to CP[7] floating point values rounded to +INF,
2550 // set UB to the largest of them (treating -0 as smaller to +0).
2553 find_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
,
2554 const REAL_VALUE_TYPE (&cp
)[8])
2558 for (int i
= 1; i
< 4; ++i
)
2560 if (real_less (&cp
[i
], &lb
)
2561 || (real_iszero (&lb
) && real_isnegzero (&cp
[i
])))
2563 if (real_less (&ub
, &cp
[i
+ 4])
2564 || (real_isnegzero (&ub
) && real_iszero (&cp
[i
+ 4])))
2571 operator_mult::op1_range (frange
&r
, tree type
,
2572 const frange
&lhs
, const frange
&op2
,
2573 relation_trio
) const
2575 if (lhs
.undefined_p ())
2577 range_op_handler
rdiv (RDIV_EXPR
);
2580 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2581 bool ret
= rdiv
.fold_range (r
, type
, wlhs
, op2
);
2584 if (wlhs
.known_isnan () || op2
.known_isnan () || op2
.undefined_p ())
2585 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2586 const REAL_VALUE_TYPE
&lhs_lb
= wlhs
.lower_bound ();
2587 const REAL_VALUE_TYPE
&lhs_ub
= wlhs
.upper_bound ();
2588 const REAL_VALUE_TYPE
&op2_lb
= op2
.lower_bound ();
2589 const REAL_VALUE_TYPE
&op2_ub
= op2
.upper_bound ();
2590 if ((contains_zero_p (lhs_lb
, lhs_ub
) && contains_zero_p (op2_lb
, op2_ub
))
2591 || ((real_isinf (&lhs_lb
) || real_isinf (&lhs_ub
))
2592 && (real_isinf (&op2_lb
) || real_isinf (&op2_ub
))))
2594 // If both lhs and op2 could be zeros or both could be infinities,
2595 // we don't know anything about op1 except maybe for the sign
2596 // and perhaps if it can be NAN or not.
2597 REAL_VALUE_TYPE lb
, ub
;
2598 int signbit_known
= signbit_known_p (lhs_lb
, lhs_ub
, op2_lb
, op2_ub
);
2599 zero_to_inf_range (lb
, ub
, signbit_known
);
2600 r
.set (type
, lb
, ub
);
2602 // Otherwise, if op2 is a singleton INF and lhs doesn't include INF,
2603 // or if lhs must be zero and op2 doesn't include zero, it would be
2604 // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF
2605 // range. Those are supersets of UNDEFINED, so let's keep that way.
2606 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2610 operator_mult::op2_range (frange
&r
, tree type
,
2611 const frange
&lhs
, const frange
&op1
,
2612 relation_trio
) const
2614 return op1_range (r
, type
, lhs
, op1
);
2618 operator_mult::rv_fold (frange
&r
, tree type
,
2619 const REAL_VALUE_TYPE
&lh_lb
,
2620 const REAL_VALUE_TYPE
&lh_ub
,
2621 const REAL_VALUE_TYPE
&rh_lb
,
2622 const REAL_VALUE_TYPE
&rh_ub
,
2623 relation_kind kind
) const
2627 && real_equal (&lh_lb
, &rh_lb
)
2628 && real_equal (&lh_ub
, &rh_ub
)
2629 && real_isneg (&lh_lb
) == real_isneg (&rh_lb
)
2630 && real_isneg (&lh_ub
) == real_isneg (&rh_ub
));
2631 REAL_VALUE_TYPE lb
, ub
;
2632 bool maybe_nan
= false;
2633 // x * x never produces a new NAN and we only multiply the same
2634 // values, so the 0 * INF problematic cases never appear there.
2637 // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN.
2638 if ((zero_p (lh_lb
, lh_ub
) && singleton_inf_p (rh_lb
, rh_ub
))
2639 || (zero_p (rh_lb
, rh_ub
) && singleton_inf_p (lh_lb
, lh_ub
)))
2645 // Otherwise, if one range includes zero and the other ends with +-INF,
2646 // it is a maybe NAN.
2647 if ((contains_zero_p (lh_lb
, lh_ub
)
2648 && (real_isinf (&rh_lb
) || real_isinf (&rh_ub
)))
2649 || (contains_zero_p (rh_lb
, rh_ub
)
2650 && (real_isinf (&lh_lb
) || real_isinf (&lh_ub
))))
2654 int signbit_known
= signbit_known_p (lh_lb
, lh_ub
, rh_lb
, rh_ub
);
2656 // If one of the ranges that includes INF is singleton
2657 // and the other range includes zero, the resulting
2658 // range is INF and NAN, because the 0 * INF boundary
2659 // case will be NAN, but already nextafter (0, 1) * INF
2661 if (singleton_inf_p (lh_lb
, lh_ub
)
2662 || singleton_inf_p (rh_lb
, rh_ub
))
2664 inf_range (lb
, ub
, signbit_known
);
2665 r
.set (type
, lb
, ub
, nan_state (true));
2669 // If one of the multiplicands must be zero, the resulting
2670 // range is +-0 and NAN.
2671 if (zero_p (lh_lb
, lh_ub
) || zero_p (rh_lb
, rh_ub
))
2673 zero_range (lb
, ub
, signbit_known
);
2674 r
.set (type
, lb
, ub
, nan_state (true));
2678 // Otherwise one of the multiplicands could be
2679 // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF]
2680 // or similarly with different signs. 0.0 * DBL_MAX
2681 // is still 0.0, nextafter (0.0, 1.0) * INF is still INF,
2682 // so if the signs are always the same or always different,
2683 // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING.
2684 zero_to_inf_range (lb
, ub
, signbit_known
);
2685 r
.set (type
, lb
, ub
, nan_state (true));
2690 REAL_VALUE_TYPE cp
[8];
2691 // Do a cross-product. At this point none of the multiplications
2692 // should produce a NAN.
2693 frange_arithmetic (MULT_EXPR
, type
, cp
[0], lh_lb
, rh_lb
, dconstninf
);
2694 frange_arithmetic (MULT_EXPR
, type
, cp
[4], lh_lb
, rh_lb
, dconstinf
);
2697 // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub)
2698 // as maximum and -0.0 as minimum if 0.0 is in the range,
2699 // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub).
2700 // -0.0 rather than 0.0 because VREL_EQ doesn't prove that
2701 // x and y are bitwise equal, just that they compare equal.
2702 if (contains_zero_p (lh_lb
, lh_ub
))
2704 if (real_isneg (&lh_lb
) == real_isneg (&lh_ub
))
2717 frange_arithmetic (MULT_EXPR
, type
, cp
[1], lh_lb
, rh_ub
, dconstninf
);
2718 frange_arithmetic (MULT_EXPR
, type
, cp
[5], lh_lb
, rh_ub
, dconstinf
);
2719 frange_arithmetic (MULT_EXPR
, type
, cp
[2], lh_ub
, rh_lb
, dconstninf
);
2720 frange_arithmetic (MULT_EXPR
, type
, cp
[6], lh_ub
, rh_lb
, dconstinf
);
2722 frange_arithmetic (MULT_EXPR
, type
, cp
[3], lh_ub
, rh_ub
, dconstninf
);
2723 frange_arithmetic (MULT_EXPR
, type
, cp
[7], lh_ub
, rh_ub
, dconstinf
);
2725 find_range (lb
, ub
, cp
);
2727 gcc_checking_assert (!real_isnan (&lb
));
2728 gcc_checking_assert (!real_isnan (&ub
));
2729 r
.set (type
, lb
, ub
, nan_state (maybe_nan
));
2733 class foperator_div
: public range_operator
2735 using range_operator::op1_range
;
2736 using range_operator::op2_range
;
2738 virtual bool op1_range (frange
&r
, tree type
,
2741 relation_trio
= TRIO_VARYING
) const final override
2743 if (lhs
.undefined_p ())
2745 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2746 bool ret
= range_op_handler (MULT_EXPR
).fold_range (r
, type
, wlhs
, op2
);
2749 if (wlhs
.known_isnan () || op2
.known_isnan () || op2
.undefined_p ())
2750 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2751 const REAL_VALUE_TYPE
&lhs_lb
= wlhs
.lower_bound ();
2752 const REAL_VALUE_TYPE
&lhs_ub
= wlhs
.upper_bound ();
2753 const REAL_VALUE_TYPE
&op2_lb
= op2
.lower_bound ();
2754 const REAL_VALUE_TYPE
&op2_ub
= op2
.upper_bound ();
2755 if ((contains_zero_p (lhs_lb
, lhs_ub
)
2756 && (real_isinf (&op2_lb
) || real_isinf (&op2_ub
)))
2757 || ((contains_zero_p (op2_lb
, op2_ub
))
2758 && (real_isinf (&lhs_lb
) || real_isinf (&lhs_ub
))))
2760 // If both lhs could be zero and op2 infinity or vice versa,
2761 // we don't know anything about op1 except maybe for the sign
2762 // and perhaps if it can be NAN or not.
2763 REAL_VALUE_TYPE lb
, ub
;
2764 int signbit_known
= signbit_known_p (lhs_lb
, lhs_ub
, op2_lb
, op2_ub
);
2765 zero_to_inf_range (lb
, ub
, signbit_known
);
2766 r
.set (type
, lb
, ub
);
2768 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2770 virtual bool op2_range (frange
&r
, tree type
,
2773 relation_trio
= TRIO_VARYING
) const final override
2775 if (lhs
.undefined_p ())
2777 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2778 bool ret
= fold_range (r
, type
, op1
, wlhs
);
2781 if (wlhs
.known_isnan () || op1
.known_isnan () || op1
.undefined_p ())
2782 return float_binary_op_range_finish (ret
, r
, type
, wlhs
, true);
2783 const REAL_VALUE_TYPE
&lhs_lb
= wlhs
.lower_bound ();
2784 const REAL_VALUE_TYPE
&lhs_ub
= wlhs
.upper_bound ();
2785 const REAL_VALUE_TYPE
&op1_lb
= op1
.lower_bound ();
2786 const REAL_VALUE_TYPE
&op1_ub
= op1
.upper_bound ();
2787 if ((contains_zero_p (lhs_lb
, lhs_ub
) && contains_zero_p (op1_lb
, op1_ub
))
2788 || ((real_isinf (&lhs_lb
) || real_isinf (&lhs_ub
))
2789 && (real_isinf (&op1_lb
) || real_isinf (&op1_ub
))))
2791 // If both lhs and op1 could be zeros or both could be infinities,
2792 // we don't know anything about op2 except maybe for the sign
2793 // and perhaps if it can be NAN or not.
2794 REAL_VALUE_TYPE lb
, ub
;
2795 int signbit_known
= signbit_known_p (lhs_lb
, lhs_ub
, op1_lb
, op1_ub
);
2796 zero_to_inf_range (lb
, ub
, signbit_known
);
2797 r
.set (type
, lb
, ub
);
2799 return float_binary_op_range_finish (ret
, r
, type
, wlhs
, true);
2802 void rv_fold (frange
&r
, tree type
,
2803 const REAL_VALUE_TYPE
&lh_lb
,
2804 const REAL_VALUE_TYPE
&lh_ub
,
2805 const REAL_VALUE_TYPE
&rh_lb
,
2806 const REAL_VALUE_TYPE
&rh_ub
,
2807 relation_kind
) const final override
2809 // +-0.0 / +-0.0 or +-INF / +-INF is a known NAN.
2810 if ((zero_p (lh_lb
, lh_ub
) && zero_p (rh_lb
, rh_ub
))
2811 || (singleton_inf_p (lh_lb
, lh_ub
) && singleton_inf_p (rh_lb
, rh_ub
)))
2817 REAL_VALUE_TYPE lb
, ub
;
2818 bool maybe_nan
= false;
2819 // If +-0.0 is in both ranges, it is a maybe NAN.
2820 if (contains_zero_p (lh_lb
, lh_ub
) && contains_zero_p (rh_lb
, rh_ub
))
2822 // If +-INF is in both ranges, it is a maybe NAN.
2823 else if ((real_isinf (&lh_lb
) || real_isinf (&lh_ub
))
2824 && (real_isinf (&rh_lb
) || real_isinf (&rh_ub
)))
2827 int signbit_known
= signbit_known_p (lh_lb
, lh_ub
, rh_lb
, rh_ub
);
2829 // If dividend must be zero, the range is just +-0
2830 // (including if the divisor is +-INF).
2831 // If divisor must be +-INF, the range is just +-0
2832 // (including if the dividend is zero).
2833 if (zero_p (lh_lb
, lh_ub
) || singleton_inf_p (rh_lb
, rh_ub
))
2835 zero_range (lb
, ub
, signbit_known
);
2836 r
.set (type
, lb
, ub
, nan_state (maybe_nan
));
2840 // If divisor must be zero, the range is just +-INF
2841 // (including if the dividend is +-INF).
2842 // If dividend must be +-INF, the range is just +-INF
2843 // (including if the dividend is zero).
2844 if (zero_p (rh_lb
, rh_ub
) || singleton_inf_p (lh_lb
, lh_ub
))
2846 inf_range (lb
, ub
, signbit_known
);
2847 r
.set (type
, lb
, ub
, nan_state (maybe_nan
));
2851 // Otherwise if both operands may be zero, divisor could be
2852 // nextafter(0.0, +-1.0) and dividend +-0.0
2853 // in which case result is going to INF or vice versa and
2854 // result +0.0. So, all we can say for that case is if the
2855 // signs of divisor and dividend are always the same we have
2856 // [+0.0, +INF], if they are always different we have
2857 // [-INF, -0.0]. If they vary, VARYING.
2858 // If both may be +-INF, divisor could be INF and dividend FLT_MAX,
2859 // in which case result is going to INF or vice versa and
2860 // result +0.0. So, all we can say for that case is if the
2861 // signs of divisor and dividend are always the same we have
2862 // [+0.0, +INF], if they are always different we have
2863 // [-INF, -0.0]. If they vary, VARYING.
2866 zero_to_inf_range (lb
, ub
, signbit_known
);
2867 r
.set (type
, lb
, ub
, nan_state (maybe_nan
));
2871 REAL_VALUE_TYPE cp
[8];
2872 // Do a cross-division. At this point none of the divisions should
2874 frange_arithmetic (RDIV_EXPR
, type
, cp
[0], lh_lb
, rh_lb
, dconstninf
);
2875 frange_arithmetic (RDIV_EXPR
, type
, cp
[1], lh_lb
, rh_ub
, dconstninf
);
2876 frange_arithmetic (RDIV_EXPR
, type
, cp
[2], lh_ub
, rh_lb
, dconstninf
);
2877 frange_arithmetic (RDIV_EXPR
, type
, cp
[3], lh_ub
, rh_ub
, dconstninf
);
2878 frange_arithmetic (RDIV_EXPR
, type
, cp
[4], lh_lb
, rh_lb
, dconstinf
);
2879 frange_arithmetic (RDIV_EXPR
, type
, cp
[5], lh_lb
, rh_ub
, dconstinf
);
2880 frange_arithmetic (RDIV_EXPR
, type
, cp
[6], lh_ub
, rh_lb
, dconstinf
);
2881 frange_arithmetic (RDIV_EXPR
, type
, cp
[7], lh_ub
, rh_ub
, dconstinf
);
2883 find_range (lb
, ub
, cp
);
2885 // If divisor may be zero (but is not known to be only zero),
2886 // and dividend can't be zero, the range can go up to -INF or +INF
2887 // depending on the signs.
2888 if (contains_zero_p (rh_lb
, rh_ub
))
2890 if (signbit_known
<= 0)
2891 real_inf (&lb
, true);
2892 if (signbit_known
>= 0)
2893 real_inf (&ub
, false);
2896 gcc_checking_assert (!real_isnan (&lb
));
2897 gcc_checking_assert (!real_isnan (&ub
));
2898 r
.set (type
, lb
, ub
, nan_state (maybe_nan
));
2903 // Initialize any float operators to the primary table
2906 range_op_table::initialize_float_ops ()
2908 set (UNLE_EXPR
, fop_unordered_le
);
2909 set (UNLT_EXPR
, fop_unordered_lt
);
2910 set (UNGE_EXPR
, fop_unordered_ge
);
2911 set (UNGT_EXPR
, fop_unordered_gt
);
2912 set (UNEQ_EXPR
, fop_unordered_equal
);
2913 set (ORDERED_EXPR
, fop_ordered
);
2914 set (UNORDERED_EXPR
, fop_unordered
);
2915 set (LTGT_EXPR
, fop_ltgt
);
2916 set (RDIV_EXPR
, fop_div
);
2920 #include "selftest.h"
2925 // Build an frange from string endpoints.
2927 static inline frange
2928 frange_float (const char *lb
, const char *ub
, tree type
= float_type_node
)
2930 REAL_VALUE_TYPE min
, max
;
2931 gcc_assert (real_from_string (&min
, lb
) == 0);
2932 gcc_assert (real_from_string (&max
, ub
) == 0);
2933 return frange (type
, min
, max
);
2937 range_op_float_tests ()
2940 frange
trange (float_type_node
);
2942 // negate([-5, +10]) => [-10, 5]
2943 r0
= frange_float ("-5", "10");
2944 range_op_handler (NEGATE_EXPR
).fold_range (r
, float_type_node
, r0
, trange
);
2945 ASSERT_EQ (r
, frange_float ("-10", "5"));
2947 // negate([0, 1] -NAN) => [-1, -0] +NAN
2948 r0
= frange_float ("0", "1");
2949 r0
.update_nan (true);
2950 range_op_handler (NEGATE_EXPR
).fold_range (r
, float_type_node
, r0
, trange
);
2951 r1
= frange_float ("-1", "-0");
2952 r1
.update_nan (false);
2955 // [-INF,+INF] + [-INF,+INF] could be a NAN.
2956 range_op_handler
plus (PLUS_EXPR
);
2957 r0
.set_varying (float_type_node
);
2958 r1
.set_varying (float_type_node
);
2961 plus
.fold_range (r
, float_type_node
, r0
, r1
);
2962 if (HONOR_NANS (float_type_node
))
2963 ASSERT_TRUE (r
.maybe_isnan ());
2966 } // namespace selftest
2968 #endif // CHECKING_P