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 ())
65 REAL_VALUE_TYPE lb
, ub
;
67 rv_fold (lb
, ub
, maybe_nan
, type
,
68 op1
.lower_bound (), op1
.upper_bound (),
69 op2
.lower_bound (), op2
.upper_bound (), trio
.op1_op2 ());
71 // Handle possible NANs by saturating to the appropriate INF if only
72 // one end is a NAN. If both ends are a NAN, just return a NAN.
73 bool lb_nan
= real_isnan (&lb
);
74 bool ub_nan
= real_isnan (&ub
);
87 if (lb_nan
|| ub_nan
|| maybe_nan
89 || op2
.maybe_isnan ())
90 // Keep the default NAN (with a varying sign) set by the setter.
95 // If the result has overflowed and flag_trapping_math, folding this
96 // operation could elide an overflow or division by zero exception.
97 // Avoid returning a singleton +-INF, to keep the propagators (DOM
98 // and substitute_and_fold_engine) from folding. See PR107608.
99 if (flag_trapping_math
100 && MODE_HAS_INFINITIES (TYPE_MODE (type
))
101 && r
.known_isinf () && !op1
.known_isinf () && !op2
.known_isinf ())
103 REAL_VALUE_TYPE inf
= r
.lower_bound ();
104 if (real_isneg (&inf
))
106 REAL_VALUE_TYPE min
= real_min_representable (type
);
107 r
.set (type
, inf
, min
);
111 REAL_VALUE_TYPE max
= real_max_representable (type
);
112 r
.set (type
, max
, inf
);
116 r
.flush_denormals_to_zero ();
121 // For a given operation, fold two sets of ranges into [lb, ub].
122 // MAYBE_NAN is set to TRUE if, in addition to any result in LB or
123 // UB, the final range has the possibility of a NAN.
125 range_operator::rv_fold (REAL_VALUE_TYPE
&lb
,
128 tree type ATTRIBUTE_UNUSED
,
129 const REAL_VALUE_TYPE
&lh_lb ATTRIBUTE_UNUSED
,
130 const REAL_VALUE_TYPE
&lh_ub ATTRIBUTE_UNUSED
,
131 const REAL_VALUE_TYPE
&rh_lb ATTRIBUTE_UNUSED
,
132 const REAL_VALUE_TYPE
&rh_ub ATTRIBUTE_UNUSED
,
141 range_operator::fold_range (irange
&r ATTRIBUTE_UNUSED
,
142 tree type ATTRIBUTE_UNUSED
,
143 const frange
&lh ATTRIBUTE_UNUSED
,
144 const irange
&rh ATTRIBUTE_UNUSED
,
151 range_operator::fold_range (irange
&r ATTRIBUTE_UNUSED
,
152 tree type ATTRIBUTE_UNUSED
,
153 const frange
&lh ATTRIBUTE_UNUSED
,
154 const frange
&rh ATTRIBUTE_UNUSED
,
161 range_operator::fold_range (frange
&r ATTRIBUTE_UNUSED
,
162 tree type ATTRIBUTE_UNUSED
,
163 const irange
&lh ATTRIBUTE_UNUSED
,
164 const irange
&rh ATTRIBUTE_UNUSED
,
171 range_operator::op1_range (frange
&r ATTRIBUTE_UNUSED
,
172 tree type ATTRIBUTE_UNUSED
,
173 const frange
&lhs ATTRIBUTE_UNUSED
,
174 const frange
&op2 ATTRIBUTE_UNUSED
,
181 range_operator::op1_range (frange
&r ATTRIBUTE_UNUSED
,
182 tree type ATTRIBUTE_UNUSED
,
183 const irange
&lhs ATTRIBUTE_UNUSED
,
184 const frange
&op2 ATTRIBUTE_UNUSED
,
191 range_operator::op2_range (frange
&r ATTRIBUTE_UNUSED
,
192 tree type ATTRIBUTE_UNUSED
,
193 const frange
&lhs ATTRIBUTE_UNUSED
,
194 const frange
&op1 ATTRIBUTE_UNUSED
,
201 range_operator::op2_range (frange
&r ATTRIBUTE_UNUSED
,
202 tree type ATTRIBUTE_UNUSED
,
203 const irange
&lhs ATTRIBUTE_UNUSED
,
204 const frange
&op1 ATTRIBUTE_UNUSED
,
211 range_operator::lhs_op1_relation (const frange
&lhs ATTRIBUTE_UNUSED
,
212 const frange
&op1 ATTRIBUTE_UNUSED
,
213 const frange
&op2 ATTRIBUTE_UNUSED
,
220 range_operator::lhs_op1_relation (const irange
&lhs ATTRIBUTE_UNUSED
,
221 const frange
&op1 ATTRIBUTE_UNUSED
,
222 const frange
&op2 ATTRIBUTE_UNUSED
,
229 range_operator::lhs_op2_relation (const irange
&lhs ATTRIBUTE_UNUSED
,
230 const frange
&op1 ATTRIBUTE_UNUSED
,
231 const frange
&op2 ATTRIBUTE_UNUSED
,
238 range_operator::lhs_op2_relation (const frange
&lhs ATTRIBUTE_UNUSED
,
239 const frange
&op1 ATTRIBUTE_UNUSED
,
240 const frange
&op2 ATTRIBUTE_UNUSED
,
247 range_operator::op1_op2_relation (const irange
&,
249 const frange
&) const
256 range_operator::op1_op2_relation (const frange
&,
258 const frange
&) const
263 // Return TRUE if OP1 and OP2 may be a NAN.
266 maybe_isnan (const frange
&op1
, const frange
&op2
)
268 return op1
.maybe_isnan () || op2
.maybe_isnan ();
271 // Floating point version of relop_early_resolve that takes NANs into
274 // For relation opcodes, first try to see if the supplied relation
275 // forces a true or false result, and return that.
276 // Then check for undefined operands. If none of this applies,
279 // TRIO are the relations between operands as they appear in the IL.
280 // MY_REL is the relation that corresponds to the operator being
281 // folded. For example, when attempting to fold x_3 == y_5, MY_REL is
282 // VREL_EQ, and if the statement is dominated by x_3 > y_5, then
283 // TRIO.op1_op2() is VREL_GT.
286 frelop_early_resolve (irange
&r
, tree type
,
287 const frange
&op1
, const frange
&op2
,
288 relation_trio trio
, relation_kind my_rel
)
290 relation_kind rel
= trio
.op1_op2 ();
292 // If known relation is a complete subset of this relation, always
293 // return true. However, avoid doing this when NAN is a possibility
294 // as we'll incorrectly fold conditions:
299 // ;; With NANs the relation here is basically VREL_UNLT, so we
300 // ;; can't fold the following:
302 if (!maybe_isnan (op1
, op2
) && relation_union (rel
, my_rel
) == my_rel
)
304 r
= range_true (type
);
308 // If known relation has no subset of this relation, always false.
309 if (relation_intersect (rel
, my_rel
) == VREL_UNDEFINED
)
311 r
= range_false (type
);
315 // If either operand is undefined, return VARYING.
316 if (empty_range_varying (r
, type
, op1
, op2
))
322 // Set VALUE to its next real value, or INF if the operation overflows.
325 frange_nextafter (enum machine_mode mode
,
326 REAL_VALUE_TYPE
&value
,
327 const REAL_VALUE_TYPE
&inf
)
329 if (MODE_COMPOSITE_P (mode
)
330 && (real_isdenormal (&value
, mode
) || real_iszero (&value
)))
332 // IBM extended denormals only have DFmode precision.
333 REAL_VALUE_TYPE tmp
, tmp2
;
334 real_convert (&tmp2
, DFmode
, &value
);
335 real_nextafter (&tmp
, REAL_MODE_FORMAT (DFmode
), &tmp2
, &inf
);
336 real_convert (&value
, mode
, &tmp
);
341 real_nextafter (&tmp
, REAL_MODE_FORMAT (mode
), &value
, &inf
);
346 // Like real_arithmetic, but round the result to INF if the operation
347 // produced inexact results.
349 // ?? There is still one problematic case, i387. With
350 // -fexcess-precision=standard we perform most SF/DFmode arithmetic in
351 // XFmode (long_double_type_node), so that case is OK. But without
352 // -mfpmath=sse, all the SF/DFmode computations are in XFmode
353 // precision (64-bit mantissa) and only occasionally rounded to
354 // SF/DFmode (when storing into memory from the 387 stack). Maybe
355 // this is ok as well though it is just occasionally more precise. ??
358 frange_arithmetic (enum tree_code code
, tree type
,
359 REAL_VALUE_TYPE
&result
,
360 const REAL_VALUE_TYPE
&op1
,
361 const REAL_VALUE_TYPE
&op2
,
362 const REAL_VALUE_TYPE
&inf
)
364 REAL_VALUE_TYPE value
;
365 enum machine_mode mode
= TYPE_MODE (type
);
366 bool mode_composite
= MODE_COMPOSITE_P (mode
);
368 bool inexact
= real_arithmetic (&value
, code
, &op1
, &op2
);
369 real_convert (&result
, mode
, &value
);
371 /* When rounding towards negative infinity, x + (-x) and
372 x - x is -0 rather than +0 real_arithmetic computes.
373 So, when we are looking for lower bound (inf is negative),
374 use -0 rather than +0. */
375 if (flag_rounding_math
376 && (code
== PLUS_EXPR
|| code
== MINUS_EXPR
)
378 && real_iszero (&result
)
379 && !real_isneg (&result
)
380 && real_isneg (&inf
))
382 REAL_VALUE_TYPE op2a
= op2
;
383 if (code
== PLUS_EXPR
)
385 if (real_isneg (&op1
) == real_isneg (&op2a
) && real_equal (&op1
, &op2a
))
389 // Be extra careful if there may be discrepancies between the
390 // compile and runtime results.
396 bool low
= real_isneg (&inf
);
397 round
= (low
? !real_less (&result
, &value
)
398 : !real_less (&value
, &result
));
399 if (real_isinf (&result
, !low
)
400 && !real_isinf (&value
)
401 && !flag_rounding_math
)
403 // Use just [+INF, +INF] rather than [MAX, +INF]
404 // even if value is larger than MAX and rounds to
405 // nearest to +INF. Similarly just [-INF, -INF]
406 // rather than [-INF, +MAX] even if value is smaller
407 // than -MAX and rounds to nearest to -INF.
408 // Unless INEXACT is true, in that case we need some
414 REAL_VALUE_TYPE tmp
= result
, tmp2
;
415 frange_nextafter (mode
, tmp
, inf
);
416 // TMP is at this point the maximum representable
418 real_arithmetic (&tmp2
, MINUS_EXPR
, &value
, &tmp
);
419 if (real_isneg (&tmp2
) != low
420 && (REAL_EXP (&tmp2
) - REAL_EXP (&tmp
)
421 >= 2 - REAL_MODE_FORMAT (mode
)->p
))
426 if (round
&& (inexact
|| !real_identical (&result
, &value
)))
429 && (real_isdenormal (&result
, mode
) || real_iszero (&result
)))
431 // IBM extended denormals only have DFmode precision.
432 REAL_VALUE_TYPE tmp
, tmp2
;
433 real_convert (&tmp2
, DFmode
, &value
);
434 real_nextafter (&tmp
, REAL_MODE_FORMAT (DFmode
), &tmp2
, &inf
);
435 real_convert (&result
, mode
, &tmp
);
438 frange_nextafter (mode
, result
, inf
);
445 // ibm-ldouble-format documents 1ulp for + and -.
446 frange_nextafter (mode
, result
, inf
);
449 // ibm-ldouble-format documents 2ulps for *.
450 frange_nextafter (mode
, result
, inf
);
451 frange_nextafter (mode
, result
, inf
);
454 // ibm-ldouble-format documents 3ulps for /.
455 frange_nextafter (mode
, result
, inf
);
456 frange_nextafter (mode
, result
, inf
);
457 frange_nextafter (mode
, result
, inf
);
464 // Crop R to [-INF, MAX] where MAX is the maximum representable number
468 frange_drop_inf (frange
&r
, tree type
)
470 REAL_VALUE_TYPE max
= real_max_representable (type
);
471 frange
tmp (type
, r
.lower_bound (), max
);
475 // Crop R to [MIN, +INF] where MIN is the minimum representable number
479 frange_drop_ninf (frange
&r
, tree type
)
481 REAL_VALUE_TYPE min
= real_min_representable (type
);
482 frange
tmp (type
, min
, r
.upper_bound ());
486 // Crop R to [MIN, MAX] where MAX is the maximum representable number
487 // for TYPE and MIN the minimum representable number for TYPE.
490 frange_drop_infs (frange
&r
, tree type
)
492 REAL_VALUE_TYPE max
= real_max_representable (type
);
493 REAL_VALUE_TYPE min
= real_min_representable (type
);
494 frange
tmp (type
, min
, max
);
498 // If zero is in R, make sure both -0.0 and +0.0 are in the range.
501 frange_add_zeros (frange
&r
, tree type
)
503 if (r
.undefined_p () || r
.known_isnan ())
506 if (HONOR_SIGNED_ZEROS (type
)
507 && (real_iszero (&r
.lower_bound ()) || real_iszero (&r
.upper_bound ())))
510 zero
.set_zero (type
);
515 // Build a range that is <= VAL and store it in R. Return TRUE if
516 // further changes may be needed for R, or FALSE if R is in its final
520 build_le (frange
&r
, tree type
, const frange
&val
)
522 gcc_checking_assert (!val
.known_isnan ());
524 REAL_VALUE_TYPE ninf
= frange_val_min (type
);
525 r
.set (type
, ninf
, val
.upper_bound ());
527 // Add both zeros if there's the possibility of zero equality.
528 frange_add_zeros (r
, type
);
533 // Build a range that is < VAL and store it in R. Return TRUE if
534 // further changes may be needed for R, or FALSE if R is in its final
538 build_lt (frange
&r
, tree type
, const frange
&val
)
540 gcc_checking_assert (!val
.known_isnan ());
542 // < -INF is outside the range.
543 if (real_isinf (&val
.upper_bound (), 1))
545 if (HONOR_NANS (type
))
552 REAL_VALUE_TYPE ninf
= frange_val_min (type
);
553 REAL_VALUE_TYPE prev
= val
.upper_bound ();
554 machine_mode mode
= TYPE_MODE (type
);
555 // Default to the conservatively correct closed ranges for
556 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
557 // !HONOR_INFINITIES, nextafter will yield -INF, but frange::set()
558 // will crop the range appropriately.
559 if (!MODE_COMPOSITE_P (mode
))
560 frange_nextafter (mode
, prev
, ninf
);
561 r
.set (type
, ninf
, prev
);
565 // Build a range that is >= VAL and store it in R. Return TRUE if
566 // further changes may be needed for R, or FALSE if R is in its final
570 build_ge (frange
&r
, tree type
, const frange
&val
)
572 gcc_checking_assert (!val
.known_isnan ());
574 REAL_VALUE_TYPE inf
= frange_val_max (type
);
575 r
.set (type
, val
.lower_bound (), inf
);
577 // Add both zeros if there's the possibility of zero equality.
578 frange_add_zeros (r
, type
);
583 // Build a range that is > VAL and store it in R. Return TRUE if
584 // further changes may be needed for R, or FALSE if R is in its final
588 build_gt (frange
&r
, tree type
, const frange
&val
)
590 gcc_checking_assert (!val
.known_isnan ());
592 // > +INF is outside the range.
593 if (real_isinf (&val
.lower_bound (), 0))
595 if (HONOR_NANS (type
))
602 REAL_VALUE_TYPE inf
= frange_val_max (type
);
603 REAL_VALUE_TYPE next
= val
.lower_bound ();
604 machine_mode mode
= TYPE_MODE (type
);
605 // Default to the conservatively correct closed ranges for
606 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
607 // !HONOR_INFINITIES, nextafter will yield +INF, but frange::set()
608 // will crop the range appropriately.
609 if (!MODE_COMPOSITE_P (mode
))
610 frange_nextafter (mode
, next
, inf
);
611 r
.set (type
, next
, inf
);
617 operator_identity::fold_range (frange
&r
, tree
, const frange
&op1
,
618 const frange
&, relation_trio
) const
625 operator_identity::op1_range (frange
&r
, tree
, const frange
&lhs
,
626 const frange
&, relation_trio
) const
633 operator_cst::fold_range (frange
&r
, tree
, const frange
&op1
,
634 const frange
&, relation_trio
) const
641 operator_equal::op2_range (frange
&r
, tree type
,
642 const irange
&lhs
, const frange
&op1
,
643 relation_trio rel
) const
645 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
649 operator_equal::fold_range (irange
&r
, tree type
,
650 const frange
&op1
, const frange
&op2
,
651 relation_trio rel
) const
653 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_EQ
))
656 if (op1
.known_isnan () || op2
.known_isnan ())
657 r
= range_false (type
);
658 // We can be sure the values are always equal or not if both ranges
659 // consist of a single value, and then compare them.
660 else if (op1
.singleton_p () && op2
.singleton_p ())
663 r
= range_true (type
);
664 // If one operand is -0.0 and other 0.0, they are still equal.
665 else if (real_iszero (&op1
.lower_bound ())
666 && real_iszero (&op2
.lower_bound ()))
667 r
= range_true (type
);
669 r
= range_false (type
);
671 else if (real_iszero (&op1
.lower_bound ())
672 && real_iszero (&op1
.upper_bound ())
673 && real_iszero (&op2
.lower_bound ())
674 && real_iszero (&op2
.upper_bound ())
675 && !maybe_isnan (op1
, op2
))
676 // [-0.0, 0.0] == [-0.0, 0.0] or similar.
677 r
= range_true (type
);
680 // If ranges do not intersect, we know the range is not equal,
681 // otherwise we don't know anything for sure.
684 if (tmp
.undefined_p ())
686 // If one range is [whatever, -0.0] and another
687 // [0.0, whatever2], we don't know anything either,
688 // because -0.0 == 0.0.
689 if ((real_iszero (&op1
.upper_bound ())
690 && real_iszero (&op2
.lower_bound ()))
691 || (real_iszero (&op1
.lower_bound ())
692 && real_iszero (&op2
.upper_bound ())))
693 r
= range_true_and_false (type
);
695 r
= range_false (type
);
698 r
= range_true_and_false (type
);
704 operator_equal::op1_range (frange
&r
, tree type
,
707 relation_trio trio
) const
709 relation_kind rel
= trio
.op1_op2 ();
710 switch (get_bool_state (r
, lhs
, type
))
713 // The TRUE side of x == NAN is unreachable.
714 if (op2
.known_isnan ())
718 // If it's true, the result is the same as OP2.
720 // Add both zeros if there's the possibility of zero equality.
721 frange_add_zeros (r
, type
);
722 // The TRUE side of op1 == op2 implies op1 is !NAN.
728 // The FALSE side of op1 == op1 implies op1 is a NAN.
731 // On the FALSE side of x == NAN, we know nothing about x.
732 else if (op2
.known_isnan ())
733 r
.set_varying (type
);
734 // If the result is false, the only time we know anything is
735 // if OP2 is a constant.
736 else if (op2
.singleton_p ()
737 || (!op2
.maybe_isnan () && op2
.zero_p ()))
739 REAL_VALUE_TYPE tmp
= op2
.lower_bound ();
740 r
.set (type
, tmp
, tmp
, VR_ANTI_RANGE
);
743 r
.set_varying (type
);
752 // Check if the LHS range indicates a relation between OP1 and OP2.
755 operator_equal::op1_op2_relation (const irange
&lhs
, const frange
&,
756 const frange
&) const
758 if (lhs
.undefined_p ())
759 return VREL_UNDEFINED
;
761 // FALSE = op1 == op2 indicates NE_EXPR.
765 // TRUE = op1 == op2 indicates EQ_EXPR.
766 if (!contains_zero_p (lhs
))
772 operator_not_equal::fold_range (irange
&r
, tree type
,
773 const frange
&op1
, const frange
&op2
,
774 relation_trio trio
) const
776 relation_kind rel
= trio
.op1_op2 ();
778 // VREL_NE & NE_EXPR is always true, even with NANs.
781 r
= range_true (type
);
784 if (rel
== VREL_EQ
&& maybe_isnan (op1
, op2
))
786 // Avoid frelop_early_resolve() below as it could fold to FALSE
787 // without regards to NANs. This would be incorrect if trying
788 // to fold x_5 != x_5 without prior knowledge of NANs.
790 else if (frelop_early_resolve (r
, type
, op1
, op2
, trio
, VREL_NE
))
793 // x != NAN is always TRUE.
794 if (op1
.known_isnan () || op2
.known_isnan ())
795 r
= range_true (type
);
796 // We can be sure the values are always equal or not if both ranges
797 // consist of a single value, and then compare them.
798 else if (op1
.singleton_p () && op2
.singleton_p ())
801 r
= range_false (type
);
802 // If one operand is -0.0 and other 0.0, they are still equal.
803 else if (real_iszero (&op1
.lower_bound ())
804 && real_iszero (&op2
.lower_bound ()))
805 r
= range_false (type
);
807 r
= range_true (type
);
809 else if (real_iszero (&op1
.lower_bound ())
810 && real_iszero (&op1
.upper_bound ())
811 && real_iszero (&op2
.lower_bound ())
812 && real_iszero (&op2
.upper_bound ())
813 && !maybe_isnan (op1
, op2
))
814 // [-0.0, 0.0] != [-0.0, 0.0] or similar.
815 r
= range_false (type
);
818 // If ranges do not intersect, we know the range is not equal,
819 // otherwise we don't know anything for sure.
822 if (tmp
.undefined_p ())
824 // If one range is [whatever, -0.0] and another
825 // [0.0, whatever2], we don't know anything either,
826 // because -0.0 == 0.0.
827 if ((real_iszero (&op1
.upper_bound ())
828 && real_iszero (&op2
.lower_bound ()))
829 || (real_iszero (&op1
.lower_bound ())
830 && real_iszero (&op2
.upper_bound ())))
831 r
= range_true_and_false (type
);
833 r
= range_true (type
);
836 r
= range_true_and_false (type
);
842 operator_not_equal::op1_range (frange
&r
, tree type
,
845 relation_trio trio
) const
847 relation_kind rel
= trio
.op1_op2 ();
848 switch (get_bool_state (r
, lhs
, type
))
851 // If the result is true, the only time we know anything is if
852 // OP2 is a constant.
853 if (op2
.singleton_p ())
855 // This is correct even if op1 is NAN, because the following
856 // range would be ~[tmp, tmp] with the NAN property set to
858 REAL_VALUE_TYPE tmp
= op2
.lower_bound ();
859 r
.set (type
, tmp
, tmp
, VR_ANTI_RANGE
);
861 // The TRUE side of op1 != op1 implies op1 is NAN.
862 else if (rel
== VREL_EQ
)
865 r
.set_varying (type
);
869 // The FALSE side of x != NAN is impossible.
870 if (op2
.known_isnan ())
874 // If it's false, the result is the same as OP2.
876 // Add both zeros if there's the possibility of zero equality.
877 frange_add_zeros (r
, type
);
878 // The FALSE side of op1 != op2 implies op1 is !NAN.
890 operator_not_equal::op2_range (frange
&r
, tree type
,
893 relation_trio trio
) const
895 return op1_range (r
, type
, lhs
, op1
, trio
);
898 // Check if the LHS range indicates a relation between OP1 and OP2.
901 operator_not_equal::op1_op2_relation (const irange
&lhs
, const frange
&,
902 const frange
&) const
904 if (lhs
.undefined_p ())
905 return VREL_UNDEFINED
;
907 // FALSE = op1 != op2 indicates EQ_EXPR.
911 // TRUE = op1 != op2 indicates NE_EXPR.
912 if (!contains_zero_p (lhs
))
918 operator_lt::fold_range (irange
&r
, tree type
,
919 const frange
&op1
, const frange
&op2
,
920 relation_trio trio
) const
922 if (frelop_early_resolve (r
, type
, op1
, op2
, trio
, VREL_LT
))
925 if (op1
.known_isnan ()
926 || op2
.known_isnan ()
927 || !real_less (&op1
.lower_bound (), &op2
.upper_bound ()))
928 r
= range_false (type
);
929 else if (!maybe_isnan (op1
, op2
)
930 && real_less (&op1
.upper_bound (), &op2
.lower_bound ()))
931 r
= range_true (type
);
933 r
= range_true_and_false (type
);
938 operator_lt::op1_range (frange
&r
,
944 switch (get_bool_state (r
, lhs
, type
))
947 // The TRUE side of x < NAN is unreachable.
948 if (op2
.known_isnan ())
950 else if (op2
.undefined_p ())
952 else if (build_lt (r
, type
, op2
))
955 // x < y implies x is not +INF.
956 frange_drop_inf (r
, type
);
961 // On the FALSE side of x < NAN, we know nothing about x.
962 if (op2
.maybe_isnan ())
963 r
.set_varying (type
);
965 build_ge (r
, type
, op2
);
975 operator_lt::op2_range (frange
&r
,
981 switch (get_bool_state (r
, lhs
, type
))
984 // The TRUE side of NAN < x is unreachable.
985 if (op1
.known_isnan ())
987 else if (op1
.undefined_p ())
989 else if (build_gt (r
, type
, op1
))
992 // x < y implies y is not -INF.
993 frange_drop_ninf (r
, type
);
998 // On the FALSE side of NAN < x, we know nothing about x.
999 if (op1
.maybe_isnan ())
1000 r
.set_varying (type
);
1002 build_le (r
, type
, op1
);
1012 // Check if the LHS range indicates a relation between OP1 and OP2.
1015 operator_lt::op1_op2_relation (const irange
&lhs
, const frange
&,
1016 const frange
&) const
1018 if (lhs
.undefined_p ())
1019 return VREL_UNDEFINED
;
1021 // FALSE = op1 < op2 indicates GE_EXPR.
1025 // TRUE = op1 < op2 indicates LT_EXPR.
1026 if (!contains_zero_p (lhs
))
1028 return VREL_VARYING
;
1032 operator_le::fold_range (irange
&r
, tree type
,
1033 const frange
&op1
, const frange
&op2
,
1034 relation_trio rel
) const
1036 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_LE
))
1039 if (op1
.known_isnan ()
1040 || op2
.known_isnan ()
1041 || !real_compare (LE_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
1042 r
= range_false (type
);
1043 else if (!maybe_isnan (op1
, op2
)
1044 && real_compare (LE_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
1045 r
= range_true (type
);
1047 r
= range_true_and_false (type
);
1052 operator_le::op1_range (frange
&r
,
1056 relation_trio
) const
1058 switch (get_bool_state (r
, lhs
, type
))
1061 // The TRUE side of x <= NAN is unreachable.
1062 if (op2
.known_isnan ())
1064 else if (op2
.undefined_p ())
1066 else if (build_le (r
, type
, op2
))
1071 // On the FALSE side of x <= NAN, we know nothing about x.
1072 if (op2
.maybe_isnan ())
1073 r
.set_varying (type
);
1075 build_gt (r
, type
, op2
);
1085 operator_le::op2_range (frange
&r
,
1089 relation_trio
) const
1091 switch (get_bool_state (r
, lhs
, type
))
1094 // The TRUE side of NAN <= x is unreachable.
1095 if (op1
.known_isnan ())
1097 else if (op1
.undefined_p ())
1099 else if (build_ge (r
, type
, op1
))
1104 // On the FALSE side of NAN <= x, we know nothing about x.
1105 if (op1
.maybe_isnan ())
1106 r
.set_varying (type
);
1107 else if (op1
.undefined_p ())
1110 build_lt (r
, type
, op1
);
1119 // Check if the LHS range indicates a relation between OP1 and OP2.
1122 operator_le::op1_op2_relation (const irange
&lhs
, const frange
&,
1123 const frange
&) const
1125 if (lhs
.undefined_p ())
1126 return VREL_UNDEFINED
;
1128 // FALSE = op1 <= op2 indicates GT_EXPR.
1132 // TRUE = op1 <= op2 indicates LE_EXPR.
1133 if (!contains_zero_p (lhs
))
1135 return VREL_VARYING
;
1139 operator_gt::fold_range (irange
&r
, tree type
,
1140 const frange
&op1
, const frange
&op2
,
1141 relation_trio trio
) const
1143 if (frelop_early_resolve (r
, type
, op1
, op2
, trio
, VREL_GT
))
1146 if (op1
.known_isnan ()
1147 || op2
.known_isnan ()
1148 || !real_compare (GT_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
1149 r
= range_false (type
);
1150 else if (!maybe_isnan (op1
, op2
)
1151 && real_compare (GT_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
1152 r
= range_true (type
);
1154 r
= range_true_and_false (type
);
1159 operator_gt::op1_range (frange
&r
,
1163 relation_trio
) const
1165 switch (get_bool_state (r
, lhs
, type
))
1168 // The TRUE side of x > NAN is unreachable.
1169 if (op2
.known_isnan ())
1171 else if (op2
.undefined_p ())
1173 else if (build_gt (r
, type
, op2
))
1176 // x > y implies x is not -INF.
1177 frange_drop_ninf (r
, type
);
1182 // On the FALSE side of x > NAN, we know nothing about x.
1183 if (op2
.maybe_isnan ())
1184 r
.set_varying (type
);
1185 else if (op2
.undefined_p ())
1188 build_le (r
, type
, op2
);
1198 operator_gt::op2_range (frange
&r
,
1202 relation_trio
) const
1204 switch (get_bool_state (r
, lhs
, type
))
1207 // The TRUE side of NAN > x is unreachable.
1208 if (op1
.known_isnan ())
1210 else if (op1
.undefined_p ())
1212 else if (build_lt (r
, type
, op1
))
1215 // x > y implies y is not +INF.
1216 frange_drop_inf (r
, type
);
1221 // On The FALSE side of NAN > x, we know nothing about x.
1222 if (op1
.maybe_isnan ())
1223 r
.set_varying (type
);
1224 else if (op1
.undefined_p ())
1227 build_ge (r
, type
, op1
);
1236 // Check if the LHS range indicates a relation between OP1 and OP2.
1239 operator_gt::op1_op2_relation (const irange
&lhs
, const frange
&,
1240 const frange
&) const
1242 if (lhs
.undefined_p ())
1243 return VREL_UNDEFINED
;
1245 // FALSE = op1 > op2 indicates LE_EXPR.
1249 // TRUE = op1 > op2 indicates GT_EXPR.
1250 if (!contains_zero_p (lhs
))
1252 return VREL_VARYING
;
1256 operator_ge::fold_range (irange
&r
, tree type
,
1257 const frange
&op1
, const frange
&op2
,
1258 relation_trio rel
) const
1260 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_GE
))
1263 if (op1
.known_isnan ()
1264 || op2
.known_isnan ()
1265 || !real_compare (GE_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
1266 r
= range_false (type
);
1267 else if (!maybe_isnan (op1
, op2
)
1268 && real_compare (GE_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
1269 r
= range_true (type
);
1271 r
= range_true_and_false (type
);
1276 operator_ge::op1_range (frange
&r
,
1280 relation_trio
) const
1282 switch (get_bool_state (r
, lhs
, type
))
1285 // The TRUE side of x >= NAN is unreachable.
1286 if (op2
.known_isnan ())
1288 else if (op2
.undefined_p ())
1290 else if (build_ge (r
, type
, op2
))
1295 // On the FALSE side of x >= NAN, we know nothing about x.
1296 if (op2
.maybe_isnan ())
1297 r
.set_varying (type
);
1298 else if (op2
.undefined_p ())
1301 build_lt (r
, type
, op2
);
1311 operator_ge::op2_range (frange
&r
, tree type
,
1314 relation_trio
) const
1316 switch (get_bool_state (r
, lhs
, type
))
1319 // The TRUE side of NAN >= x is unreachable.
1320 if (op1
.known_isnan ())
1322 else if (op1
.undefined_p ())
1324 else if (build_le (r
, type
, op1
))
1329 // On the FALSE side of NAN >= x, we know nothing about x.
1330 if (op1
.maybe_isnan ())
1331 r
.set_varying (type
);
1332 else if (op1
.undefined_p ())
1335 build_gt (r
, type
, op1
);
1344 // Check if the LHS range indicates a relation between OP1 and OP2.
1347 operator_ge::op1_op2_relation (const irange
&lhs
, const frange
&,
1348 const frange
&) const
1350 if (lhs
.undefined_p ())
1351 return VREL_UNDEFINED
;
1353 // FALSE = op1 >= op2 indicates LT_EXPR.
1357 // TRUE = op1 >= op2 indicates GE_EXPR.
1358 if (!contains_zero_p (lhs
))
1360 return VREL_VARYING
;
1363 // UNORDERED_EXPR comparison.
1365 class foperator_unordered
: public range_operator
1367 using range_operator::fold_range
;
1368 using range_operator::op1_range
;
1369 using range_operator::op2_range
;
1371 bool fold_range (irange
&r
, tree type
,
1372 const frange
&op1
, const frange
&op2
,
1373 relation_trio
= TRIO_VARYING
) const final override
;
1374 bool op1_range (frange
&r
, tree type
,
1375 const irange
&lhs
, const frange
&op2
,
1376 relation_trio
= TRIO_VARYING
) const final override
;
1377 bool op2_range (frange
&r
, tree type
,
1378 const irange
&lhs
, const frange
&op1
,
1379 relation_trio rel
= TRIO_VARYING
) const final override
1381 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
1386 foperator_unordered::fold_range (irange
&r
, tree type
,
1387 const frange
&op1
, const frange
&op2
,
1388 relation_trio
) const
1390 // UNORDERED is TRUE if either operand is a NAN.
1391 if (op1
.known_isnan () || op2
.known_isnan ())
1392 r
= range_true (type
);
1393 // UNORDERED is FALSE if neither operand is a NAN.
1394 else if (!op1
.maybe_isnan () && !op2
.maybe_isnan ())
1395 r
= range_false (type
);
1397 r
= range_true_and_false (type
);
1402 foperator_unordered::op1_range (frange
&r
, tree type
,
1405 relation_trio trio
) const
1407 relation_kind rel
= trio
.op1_op2 ();
1408 switch (get_bool_state (r
, lhs
, type
))
1411 // Since at least one operand must be NAN, if one of them is
1412 // not, the other must be.
1413 if (rel
== VREL_EQ
|| !op2
.maybe_isnan ())
1416 r
.set_varying (type
);
1420 // A false UNORDERED means both operands are !NAN, so it's
1421 // impossible for op2 to be a NAN.
1422 if (op2
.known_isnan ())
1426 r
.set_varying (type
);
1437 // ORDERED_EXPR comparison.
1439 class foperator_ordered
: public range_operator
1441 using range_operator::fold_range
;
1442 using range_operator::op1_range
;
1443 using range_operator::op2_range
;
1445 bool fold_range (irange
&r
, tree type
,
1446 const frange
&op1
, const frange
&op2
,
1447 relation_trio
= TRIO_VARYING
) const final override
;
1448 bool op1_range (frange
&r
, tree type
,
1449 const irange
&lhs
, const frange
&op2
,
1450 relation_trio
= TRIO_VARYING
) const final override
;
1451 bool op2_range (frange
&r
, tree type
,
1452 const irange
&lhs
, const frange
&op1
,
1453 relation_trio rel
= TRIO_VARYING
) const final override
1455 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
1460 foperator_ordered::fold_range (irange
&r
, tree type
,
1461 const frange
&op1
, const frange
&op2
,
1462 relation_trio
) const
1464 if (op1
.known_isnan () || op2
.known_isnan ())
1465 r
= range_false (type
);
1466 else if (!op1
.maybe_isnan () && !op2
.maybe_isnan ())
1467 r
= range_true (type
);
1469 r
= range_true_and_false (type
);
1474 foperator_ordered::op1_range (frange
&r
, tree type
,
1477 relation_trio trio
) const
1479 relation_kind rel
= trio
.op1_op2 ();
1480 switch (get_bool_state (r
, lhs
, type
))
1483 // The TRUE side of ORDERED means both operands are !NAN, so
1484 // it's impossible for op2 to be a NAN.
1485 if (op2
.known_isnan ())
1489 r
.set_varying (type
);
1495 // The FALSE side of op1 ORDERED op1 implies op1 is NAN.
1499 r
.set_varying (type
);
1509 operator_negate::fold_range (frange
&r
, tree type
,
1510 const frange
&op1
, const frange
&op2
,
1511 relation_trio
) const
1513 if (empty_range_varying (r
, type
, op1
, op2
))
1515 if (op1
.known_isnan ())
1518 if (op1
.nan_signbit_p (sign
))
1519 r
.set_nan (type
, !sign
);
1525 REAL_VALUE_TYPE lh_lb
= op1
.lower_bound ();
1526 REAL_VALUE_TYPE lh_ub
= op1
.upper_bound ();
1527 lh_lb
= real_value_negate (&lh_lb
);
1528 lh_ub
= real_value_negate (&lh_ub
);
1529 r
.set (type
, lh_ub
, lh_lb
);
1530 if (op1
.maybe_isnan ())
1533 if (op1
.nan_signbit_p (sign
))
1534 r
.update_nan (!sign
);
1544 operator_negate::op1_range (frange
&r
, tree type
,
1545 const frange
&lhs
, const frange
&op2
,
1546 relation_trio rel
) const
1548 return fold_range (r
, type
, lhs
, op2
, rel
);
1552 operator_abs::fold_range (frange
&r
, tree type
,
1553 const frange
&op1
, const frange
&op2
,
1554 relation_trio
) const
1556 if (empty_range_varying (r
, type
, op1
, op2
))
1558 if (op1
.known_isnan ())
1560 r
.set_nan (type
, /*sign=*/false);
1564 const REAL_VALUE_TYPE lh_lb
= op1
.lower_bound ();
1565 const REAL_VALUE_TYPE lh_ub
= op1
.upper_bound ();
1566 // Handle the easy case where everything is positive.
1567 if (real_compare (GE_EXPR
, &lh_lb
, &dconst0
)
1568 && !real_iszero (&lh_lb
, /*sign=*/true)
1569 && !op1
.maybe_isnan (/*sign=*/true))
1575 REAL_VALUE_TYPE min
= real_value_abs (&lh_lb
);
1576 REAL_VALUE_TYPE max
= real_value_abs (&lh_ub
);
1577 // If the range contains zero then we know that the minimum value in the
1578 // range will be zero.
1579 if (real_compare (LE_EXPR
, &lh_lb
, &dconst0
)
1580 && real_compare (GE_EXPR
, &lh_ub
, &dconst0
))
1582 if (real_compare (GT_EXPR
, &min
, &max
))
1588 // If the range was reversed, swap MIN and MAX.
1589 if (real_compare (GT_EXPR
, &min
, &max
))
1590 std::swap (min
, max
);
1593 r
.set (type
, min
, max
);
1594 if (op1
.maybe_isnan ())
1595 r
.update_nan (/*sign=*/false);
1602 operator_abs::op1_range (frange
&r
, tree type
,
1603 const frange
&lhs
, const frange
&op2
,
1604 relation_trio
) const
1606 if (empty_range_varying (r
, type
, lhs
, op2
))
1608 if (lhs
.known_isnan ())
1614 // Start with the positives because negatives are an impossible result.
1615 frange
positives (type
, dconst0
, frange_val_max (type
));
1616 positives
.update_nan (/*sign=*/false);
1617 positives
.intersect (lhs
);
1619 // Add -NAN if relevant.
1620 if (r
.maybe_isnan ())
1623 neg_nan
.set_nan (type
, true);
1626 if (r
.known_isnan () || r
.undefined_p ())
1628 // Then add the negative of each pair:
1629 // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
1630 frange
negatives (type
, real_value_negate (&positives
.upper_bound ()),
1631 real_value_negate (&positives
.lower_bound ()));
1632 negatives
.clear_nan ();
1633 r
.union_ (negatives
);
1637 class foperator_unordered_lt
: public range_operator
1639 using range_operator::fold_range
;
1640 using range_operator::op1_range
;
1641 using range_operator::op2_range
;
1643 bool fold_range (irange
&r
, tree type
,
1644 const frange
&op1
, const frange
&op2
,
1645 relation_trio trio
= TRIO_VARYING
) const final override
1647 if (op1
.known_isnan () || op2
.known_isnan ())
1649 r
= range_true (type
);
1652 frange op1_no_nan
= op1
;
1653 frange op2_no_nan
= op2
;
1654 if (op1
.maybe_isnan ())
1655 op1_no_nan
.clear_nan ();
1656 if (op2
.maybe_isnan ())
1657 op2_no_nan
.clear_nan ();
1658 if (!range_op_handler (LT_EXPR
).fold_range (r
, type
, op1_no_nan
,
1661 // The result is the same as the ordered version when the
1662 // comparison is true or when the operands cannot be NANs.
1663 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1667 r
= range_true_and_false (type
);
1671 bool op1_range (frange
&r
, tree type
,
1674 relation_trio trio
) const final override
;
1675 bool op2_range (frange
&r
, tree type
,
1678 relation_trio trio
) const final override
;
1682 foperator_unordered_lt::op1_range (frange
&r
, tree type
,
1685 relation_trio
) const
1687 switch (get_bool_state (r
, lhs
, type
))
1690 if (op2
.maybe_isnan ())
1691 r
.set_varying (type
);
1692 else if (op2
.undefined_p ())
1695 build_lt (r
, type
, op2
);
1699 // A false UNORDERED_LT means both operands are !NAN, so it's
1700 // impossible for op2 to be a NAN.
1701 if (op2
.known_isnan ())
1703 else if (op2
.undefined_p ())
1705 else if (build_ge (r
, type
, op2
))
1716 foperator_unordered_lt::op2_range (frange
&r
, tree type
,
1719 relation_trio
) const
1721 switch (get_bool_state (r
, lhs
, type
))
1724 if (op1
.maybe_isnan ())
1725 r
.set_varying (type
);
1726 else if (op1
.undefined_p ())
1729 build_gt (r
, type
, op1
);
1733 // A false UNORDERED_LT means both operands are !NAN, so it's
1734 // impossible for op1 to be a NAN.
1735 if (op1
.known_isnan ())
1737 else if (op1
.undefined_p ())
1739 else if (build_le (r
, type
, op1
))
1749 class foperator_unordered_le
: public range_operator
1751 using range_operator::fold_range
;
1752 using range_operator::op1_range
;
1753 using range_operator::op2_range
;
1755 bool fold_range (irange
&r
, tree type
,
1756 const frange
&op1
, const frange
&op2
,
1757 relation_trio trio
= TRIO_VARYING
) const final override
1759 if (op1
.known_isnan () || op2
.known_isnan ())
1761 r
= range_true (type
);
1764 frange op1_no_nan
= op1
;
1765 frange op2_no_nan
= op2
;
1766 if (op1
.maybe_isnan ())
1767 op1_no_nan
.clear_nan ();
1768 if (op2
.maybe_isnan ())
1769 op2_no_nan
.clear_nan ();
1770 if (!range_op_handler (LE_EXPR
).fold_range (r
, type
, op1_no_nan
,
1773 // The result is the same as the ordered version when the
1774 // comparison is true or when the operands cannot be NANs.
1775 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1779 r
= range_true_and_false (type
);
1783 bool op1_range (frange
&r
, tree type
,
1784 const irange
&lhs
, const frange
&op2
,
1785 relation_trio
= TRIO_VARYING
) const final override
;
1786 bool op2_range (frange
&r
, tree type
,
1787 const irange
&lhs
, const frange
&op1
,
1788 relation_trio
= TRIO_VARYING
) const final override
;
1792 foperator_unordered_le::op1_range (frange
&r
, tree type
,
1793 const irange
&lhs
, const frange
&op2
,
1794 relation_trio
) const
1796 switch (get_bool_state (r
, lhs
, type
))
1799 if (op2
.maybe_isnan ())
1800 r
.set_varying (type
);
1801 else if (op2
.undefined_p ())
1804 build_le (r
, type
, op2
);
1808 // A false UNORDERED_LE means both operands are !NAN, so it's
1809 // impossible for op2 to be a NAN.
1810 if (op2
.known_isnan ())
1812 else if (build_gt (r
, type
, op2
))
1823 foperator_unordered_le::op2_range (frange
&r
,
1827 relation_trio
) const
1829 switch (get_bool_state (r
, lhs
, type
))
1832 if (op1
.maybe_isnan ())
1833 r
.set_varying (type
);
1834 else if (op1
.undefined_p ())
1837 build_ge (r
, type
, op1
);
1841 // A false UNORDERED_LE means both operands are !NAN, so it's
1842 // impossible for op1 to be a NAN.
1843 if (op1
.known_isnan ())
1845 else if (op1
.undefined_p ())
1847 else if (build_lt (r
, type
, op1
))
1857 class foperator_unordered_gt
: public range_operator
1859 using range_operator::fold_range
;
1860 using range_operator::op1_range
;
1861 using range_operator::op2_range
;
1863 bool fold_range (irange
&r
, tree type
,
1864 const frange
&op1
, const frange
&op2
,
1865 relation_trio trio
= TRIO_VARYING
) const final override
1867 if (op1
.known_isnan () || op2
.known_isnan ())
1869 r
= range_true (type
);
1872 frange op1_no_nan
= op1
;
1873 frange op2_no_nan
= op2
;
1874 if (op1
.maybe_isnan ())
1875 op1_no_nan
.clear_nan ();
1876 if (op2
.maybe_isnan ())
1877 op2_no_nan
.clear_nan ();
1878 if (!range_op_handler (GT_EXPR
).fold_range (r
, type
, op1_no_nan
,
1881 // The result is the same as the ordered version when the
1882 // comparison is true or when the operands cannot be NANs.
1883 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1887 r
= range_true_and_false (type
);
1891 bool op1_range (frange
&r
, tree type
,
1892 const irange
&lhs
, const frange
&op2
,
1893 relation_trio
= TRIO_VARYING
) const final override
;
1894 bool op2_range (frange
&r
, tree type
,
1895 const irange
&lhs
, const frange
&op1
,
1896 relation_trio
= TRIO_VARYING
) const final override
;
1900 foperator_unordered_gt::op1_range (frange
&r
,
1904 relation_trio
) const
1906 switch (get_bool_state (r
, lhs
, type
))
1909 if (op2
.maybe_isnan ())
1910 r
.set_varying (type
);
1911 else if (op2
.undefined_p ())
1914 build_gt (r
, type
, op2
);
1918 // A false UNORDERED_GT means both operands are !NAN, so it's
1919 // impossible for op2 to be a NAN.
1920 if (op2
.known_isnan ())
1922 else if (op2
.undefined_p ())
1924 else if (build_le (r
, type
, op2
))
1935 foperator_unordered_gt::op2_range (frange
&r
,
1939 relation_trio
) const
1941 switch (get_bool_state (r
, lhs
, type
))
1944 if (op1
.maybe_isnan ())
1945 r
.set_varying (type
);
1946 else if (op1
.undefined_p ())
1949 build_lt (r
, type
, op1
);
1953 // A false UNORDERED_GT means both operands are !NAN, so it's
1954 // impossible for op1 to be a NAN.
1955 if (op1
.known_isnan ())
1957 else if (op1
.undefined_p ())
1959 else if (build_ge (r
, type
, op1
))
1969 class foperator_unordered_ge
: public range_operator
1971 using range_operator::fold_range
;
1972 using range_operator::op1_range
;
1973 using range_operator::op2_range
;
1975 bool fold_range (irange
&r
, tree type
,
1976 const frange
&op1
, const frange
&op2
,
1977 relation_trio trio
= TRIO_VARYING
) const final override
1979 if (op1
.known_isnan () || op2
.known_isnan ())
1981 r
= range_true (type
);
1984 frange op1_no_nan
= op1
;
1985 frange op2_no_nan
= op2
;
1986 if (op1
.maybe_isnan ())
1987 op1_no_nan
.clear_nan ();
1988 if (op2
.maybe_isnan ())
1989 op2_no_nan
.clear_nan ();
1990 if (!range_op_handler (GE_EXPR
).fold_range (r
, type
, op1_no_nan
,
1993 // The result is the same as the ordered version when the
1994 // comparison is true or when the operands cannot be NANs.
1995 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1999 r
= range_true_and_false (type
);
2003 bool op1_range (frange
&r
, tree type
,
2004 const irange
&lhs
, const frange
&op2
,
2005 relation_trio
= TRIO_VARYING
) const final override
;
2006 bool op2_range (frange
&r
, tree type
,
2007 const irange
&lhs
, const frange
&op1
,
2008 relation_trio
= TRIO_VARYING
) const final override
;
2012 foperator_unordered_ge::op1_range (frange
&r
,
2016 relation_trio
) const
2018 switch (get_bool_state (r
, lhs
, type
))
2021 if (op2
.maybe_isnan ())
2022 r
.set_varying (type
);
2023 else if (op2
.undefined_p ())
2026 build_ge (r
, type
, op2
);
2030 // A false UNORDERED_GE means both operands are !NAN, so it's
2031 // impossible for op2 to be a NAN.
2032 if (op2
.known_isnan ())
2034 else if (op2
.undefined_p ())
2036 else if (build_lt (r
, type
, op2
))
2047 foperator_unordered_ge::op2_range (frange
&r
, tree type
,
2050 relation_trio
) const
2052 switch (get_bool_state (r
, lhs
, type
))
2055 if (op1
.maybe_isnan ())
2056 r
.set_varying (type
);
2057 else if (op1
.undefined_p ())
2060 build_le (r
, type
, op1
);
2064 // A false UNORDERED_GE means both operands are !NAN, so it's
2065 // impossible for op1 to be a NAN.
2066 if (op1
.known_isnan ())
2068 else if (op1
.undefined_p ())
2070 else if (build_gt (r
, type
, op1
))
2080 class foperator_unordered_equal
: public range_operator
2082 using range_operator::fold_range
;
2083 using range_operator::op1_range
;
2084 using range_operator::op2_range
;
2086 bool fold_range (irange
&r
, tree type
,
2087 const frange
&op1
, const frange
&op2
,
2088 relation_trio trio
= TRIO_VARYING
) const final override
2090 if (op1
.known_isnan () || op2
.known_isnan ())
2092 r
= range_true (type
);
2095 frange op1_no_nan
= op1
;
2096 frange op2_no_nan
= op2
;
2097 if (op1
.maybe_isnan ())
2098 op1_no_nan
.clear_nan ();
2099 if (op2
.maybe_isnan ())
2100 op2_no_nan
.clear_nan ();
2101 if (!range_op_handler (EQ_EXPR
).fold_range (r
, type
, op1_no_nan
,
2104 // The result is the same as the ordered version when the
2105 // comparison is true or when the operands cannot be NANs.
2106 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
2110 r
= range_true_and_false (type
);
2114 bool op1_range (frange
&r
, tree type
,
2115 const irange
&lhs
, const frange
&op2
,
2116 relation_trio
= TRIO_VARYING
) const final override
;
2117 bool op2_range (frange
&r
, tree type
,
2118 const irange
&lhs
, const frange
&op1
,
2119 relation_trio rel
= TRIO_VARYING
) const final override
2121 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
2123 } fop_unordered_equal
;
2126 foperator_unordered_equal::op1_range (frange
&r
, tree type
,
2129 relation_trio
) const
2131 switch (get_bool_state (r
, lhs
, type
))
2134 // If it's true, the result is the same as OP2 plus a NAN.
2136 // Add both zeros if there's the possibility of zero equality.
2137 frange_add_zeros (r
, type
);
2138 // Add the possibility of a NAN.
2143 // A false UNORDERED_EQ means both operands are !NAN, so it's
2144 // impossible for op2 to be a NAN.
2145 if (op2
.known_isnan ())
2149 // The false side indicates !NAN and not equal. We can at least
2151 r
.set_varying (type
);
2162 class foperator_ltgt
: public range_operator
2164 using range_operator::fold_range
;
2165 using range_operator::op1_range
;
2166 using range_operator::op2_range
;
2168 bool fold_range (irange
&r
, tree type
,
2169 const frange
&op1
, const frange
&op2
,
2170 relation_trio trio
= TRIO_VARYING
) const final override
2172 if (op1
.known_isnan () || op2
.known_isnan ())
2174 r
= range_false (type
);
2177 frange op1_no_nan
= op1
;
2178 frange op2_no_nan
= op2
;
2179 if (op1
.maybe_isnan ())
2180 op1_no_nan
.clear_nan ();
2181 if (op2
.maybe_isnan ())
2182 op2_no_nan
.clear_nan ();
2183 if (!range_op_handler (NE_EXPR
).fold_range (r
, type
, op1_no_nan
,
2186 // The result is the same as the ordered version when the
2187 // comparison is true or when the operands cannot be NANs.
2188 if (!maybe_isnan (op1
, op2
) || r
== range_false (type
))
2192 r
= range_true_and_false (type
);
2196 bool op1_range (frange
&r
, tree type
,
2197 const irange
&lhs
, const frange
&op2
,
2198 relation_trio
= TRIO_VARYING
) const final override
;
2199 bool op2_range (frange
&r
, tree type
,
2200 const irange
&lhs
, const frange
&op1
,
2201 relation_trio rel
= TRIO_VARYING
) const final override
2203 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
2208 foperator_ltgt::op1_range (frange
&r
, tree type
,
2211 relation_trio
) const
2213 switch (get_bool_state (r
, lhs
, type
))
2216 // A true LTGT means both operands are !NAN, so it's
2217 // impossible for op2 to be a NAN.
2218 if (op2
.known_isnan ())
2222 // The true side indicates !NAN and not equal. We can at least
2224 r
.set_varying (type
);
2230 // If it's false, the result is the same as OP2 plus a NAN.
2232 // Add both zeros if there's the possibility of zero equality.
2233 frange_add_zeros (r
, type
);
2234 // Add the possibility of a NAN.
2244 // Final tweaks for float binary op op1_range/op2_range.
2245 // Return TRUE if the operation is performed and a valid range is available.
2248 float_binary_op_range_finish (bool ret
, frange
&r
, tree type
,
2249 const frange
&lhs
, bool div_op2
= false)
2254 // If we get a known NAN from reverse op, it means either that
2255 // the other operand was known NAN (in that case we know nothing),
2256 // or the reverse operation introduced a known NAN.
2257 // Say for lhs = op1 * op2 if lhs is [-0, +0] and op2 is too,
2258 // 0 / 0 is known NAN. Just punt in that case.
2259 // If NANs aren't honored, we get for 0 / 0 UNDEFINED, so punt as well.
2260 // Or if lhs is a known NAN, we also don't know anything.
2261 if (r
.known_isnan () || lhs
.known_isnan () || r
.undefined_p ())
2263 r
.set_varying (type
);
2267 // If lhs isn't NAN, then neither operand could be NAN,
2268 // even if the reverse operation does introduce a maybe_nan.
2269 if (!lhs
.maybe_isnan ())
2273 ? !(real_compare (LE_EXPR
, &lhs
.lower_bound (), &dconst0
)
2274 && real_compare (GE_EXPR
, &lhs
.upper_bound (), &dconst0
))
2275 : !(real_isinf (&lhs
.lower_bound ())
2276 || real_isinf (&lhs
.upper_bound ())))
2277 // For reverse + or - or * or op1 of /, if result is finite, then
2278 // r must be finite too, as X + INF or X - INF or X * INF or
2279 // INF / X is always +-INF or NAN. For op2 of /, if result is
2280 // non-zero and not NAN, r must be finite, as X / INF is always
2282 frange_drop_infs (r
, type
);
2284 // If lhs is a maybe or known NAN, the operand could be
2291 // True if [lb, ub] is [+-0, +-0].
2293 zero_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
2295 return real_iszero (&lb
) && real_iszero (&ub
);
2298 // True if +0 or -0 is in [lb, ub] range.
2300 contains_zero_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
2302 return (real_compare (LE_EXPR
, &lb
, &dconst0
)
2303 && real_compare (GE_EXPR
, &ub
, &dconst0
));
2306 // True if [lb, ub] is [-INF, -INF] or [+INF, +INF].
2308 singleton_inf_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
2310 return real_isinf (&lb
) && real_isinf (&ub
, real_isneg (&lb
));
2313 // Return -1 if binary op result must have sign bit set,
2314 // 1 if binary op result must have sign bit clear,
2316 // Sign bit of binary op result is exclusive or of the
2317 // operand's sign bits.
2319 signbit_known_p (const REAL_VALUE_TYPE
&lh_lb
, const REAL_VALUE_TYPE
&lh_ub
,
2320 const REAL_VALUE_TYPE
&rh_lb
, const REAL_VALUE_TYPE
&rh_ub
)
2322 if (real_isneg (&lh_lb
) == real_isneg (&lh_ub
)
2323 && real_isneg (&rh_lb
) == real_isneg (&rh_ub
))
2325 if (real_isneg (&lh_lb
) == real_isneg (&rh_ub
))
2333 // Set [lb, ub] to [-0, -0], [-0, +0] or [+0, +0] depending on
2336 zero_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
2339 if (signbit_known
<= 0)
2341 if (signbit_known
< 0)
2345 // Set [lb, ub] to [-INF, -INF], [-INF, +INF] or [+INF, +INF] depending on
2348 inf_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
2350 if (signbit_known
> 0)
2351 ub
= lb
= dconstinf
;
2352 else if (signbit_known
< 0)
2353 ub
= lb
= dconstninf
;
2361 // Set [lb, ub] to [-INF, -0], [-INF, +INF] or [+0, +INF] depending on
2364 zero_to_inf_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
2366 if (signbit_known
> 0)
2371 else if (signbit_known
< 0)
2383 /* Extend the LHS range by 1ulp in each direction. For op1_range
2384 or op2_range of binary operations just computing the inverse
2385 operation on ranges isn't sufficient. Consider e.g.
2386 [1., 1.] = op1 + [1., 1.]. op1's range is not [0., 0.], but
2387 [-0x1.0p-54, 0x1.0p-53] (when not -frounding-math), any value for
2388 which adding 1. to it results in 1. after rounding to nearest.
2389 So, for op1_range/op2_range extend the lhs range by 1ulp (or 0.5ulp)
2390 in each direction. See PR109008 for more details. */
2393 float_widen_lhs_range (tree type
, const frange
&lhs
)
2396 if (lhs
.known_isnan ())
2398 REAL_VALUE_TYPE lb
= lhs
.lower_bound ();
2399 REAL_VALUE_TYPE ub
= lhs
.upper_bound ();
2400 if (real_isfinite (&lb
))
2402 frange_nextafter (TYPE_MODE (type
), lb
, dconstninf
);
2403 if (real_isinf (&lb
))
2405 /* For -DBL_MAX, instead of -Inf use
2406 nexttoward (-DBL_MAX, -LDBL_MAX) in a hypothetical
2407 wider type with the same mantissa precision but larger
2408 exponent range; it is outside of range of double values,
2409 but makes it clear it is just one ulp larger rather than
2410 infinite amount larger. */
2412 SET_REAL_EXP (&lb
, FLOAT_MODE_FORMAT (TYPE_MODE (type
))->emax
+ 1);
2414 if (!flag_rounding_math
&& !MODE_COMPOSITE_P (TYPE_MODE (type
)))
2416 /* If not -frounding-math nor IBM double double, actually widen
2417 just by 0.5ulp rather than 1ulp. */
2418 REAL_VALUE_TYPE tem
;
2419 real_arithmetic (&tem
, PLUS_EXPR
, &lhs
.lower_bound (), &lb
);
2420 real_arithmetic (&lb
, RDIV_EXPR
, &tem
, &dconst2
);
2423 if (real_isfinite (&ub
))
2425 frange_nextafter (TYPE_MODE (type
), ub
, dconstinf
);
2426 if (real_isinf (&ub
))
2428 /* For DBL_MAX similarly. */
2430 SET_REAL_EXP (&ub
, FLOAT_MODE_FORMAT (TYPE_MODE (type
))->emax
+ 1);
2432 if (!flag_rounding_math
&& !MODE_COMPOSITE_P (TYPE_MODE (type
)))
2434 /* If not -frounding-math nor IBM double double, actually widen
2435 just by 0.5ulp rather than 1ulp. */
2436 REAL_VALUE_TYPE tem
;
2437 real_arithmetic (&tem
, PLUS_EXPR
, &lhs
.upper_bound (), &ub
);
2438 real_arithmetic (&ub
, RDIV_EXPR
, &tem
, &dconst2
);
2441 /* Temporarily disable -ffinite-math-only, so that frange::set doesn't
2442 reduce the range back to real_min_representable (type) as lower bound
2443 or real_max_representable (type) as upper bound. */
2444 bool save_flag_finite_math_only
= flag_finite_math_only
;
2445 flag_finite_math_only
= false;
2446 ret
.set (type
, lb
, ub
, lhs
.get_nan_state ());
2447 flag_finite_math_only
= save_flag_finite_math_only
;
2452 operator_plus::op1_range (frange
&r
, tree type
, const frange
&lhs
,
2453 const frange
&op2
, relation_trio
) const
2455 if (lhs
.undefined_p ())
2457 range_op_handler
minus (MINUS_EXPR
);
2460 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2461 return float_binary_op_range_finish (minus
.fold_range (r
, type
, wlhs
, op2
),
2466 operator_plus::op2_range (frange
&r
, tree type
,
2467 const frange
&lhs
, const frange
&op1
,
2468 relation_trio
) const
2470 return op1_range (r
, type
, lhs
, op1
);
2474 operator_plus::rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
,
2475 bool &maybe_nan
, tree type
,
2476 const REAL_VALUE_TYPE
&lh_lb
,
2477 const REAL_VALUE_TYPE
&lh_ub
,
2478 const REAL_VALUE_TYPE
&rh_lb
,
2479 const REAL_VALUE_TYPE
&rh_ub
,
2480 relation_kind
) const
2482 frange_arithmetic (PLUS_EXPR
, type
, lb
, lh_lb
, rh_lb
, dconstninf
);
2483 frange_arithmetic (PLUS_EXPR
, type
, ub
, lh_ub
, rh_ub
, dconstinf
);
2485 // [-INF] + [+INF] = NAN
2486 if (real_isinf (&lh_lb
, true) && real_isinf (&rh_ub
, false))
2488 // [+INF] + [-INF] = NAN
2489 else if (real_isinf (&lh_ub
, false) && real_isinf (&rh_lb
, true))
2497 operator_minus::op1_range (frange
&r
, tree type
,
2498 const frange
&lhs
, const frange
&op2
,
2499 relation_trio
) const
2501 if (lhs
.undefined_p ())
2503 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2504 return float_binary_op_range_finish (
2505 range_op_handler (PLUS_EXPR
).fold_range (r
, type
, wlhs
, op2
),
2510 operator_minus::op2_range (frange
&r
, tree type
,
2511 const frange
&lhs
, const frange
&op1
,
2512 relation_trio
) const
2514 if (lhs
.undefined_p ())
2516 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2517 return float_binary_op_range_finish (fold_range (r
, type
, op1
, wlhs
),
2522 operator_minus::rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
,
2523 bool &maybe_nan
, tree type
,
2524 const REAL_VALUE_TYPE
&lh_lb
,
2525 const REAL_VALUE_TYPE
&lh_ub
,
2526 const REAL_VALUE_TYPE
&rh_lb
,
2527 const REAL_VALUE_TYPE
&rh_ub
,
2528 relation_kind
) const
2530 frange_arithmetic (MINUS_EXPR
, type
, lb
, lh_lb
, rh_ub
, dconstninf
);
2531 frange_arithmetic (MINUS_EXPR
, type
, ub
, lh_ub
, rh_lb
, dconstinf
);
2533 // [+INF] - [+INF] = NAN
2534 if (real_isinf (&lh_ub
, false) && real_isinf (&rh_ub
, false))
2536 // [-INF] - [-INF] = NAN
2537 else if (real_isinf (&lh_lb
, true) && real_isinf (&rh_lb
, true))
2544 // Given CP[0] to CP[3] floating point values rounded to -INF,
2545 // set LB to the smallest of them (treating -0 as smaller to +0).
2546 // Given CP[4] to CP[7] floating point values rounded to +INF,
2547 // set UB to the largest of them (treating -0 as smaller to +0).
2550 find_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
,
2551 const REAL_VALUE_TYPE (&cp
)[8])
2555 for (int i
= 1; i
< 4; ++i
)
2557 if (real_less (&cp
[i
], &lb
)
2558 || (real_iszero (&lb
) && real_isnegzero (&cp
[i
])))
2560 if (real_less (&ub
, &cp
[i
+ 4])
2561 || (real_isnegzero (&ub
) && real_iszero (&cp
[i
+ 4])))
2568 operator_mult::op1_range (frange
&r
, tree type
,
2569 const frange
&lhs
, const frange
&op2
,
2570 relation_trio
) const
2572 if (lhs
.undefined_p ())
2574 range_op_handler
rdiv (RDIV_EXPR
);
2577 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2578 bool ret
= rdiv
.fold_range (r
, type
, wlhs
, op2
);
2581 if (wlhs
.known_isnan () || op2
.known_isnan () || op2
.undefined_p ())
2582 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2583 const REAL_VALUE_TYPE
&lhs_lb
= wlhs
.lower_bound ();
2584 const REAL_VALUE_TYPE
&lhs_ub
= wlhs
.upper_bound ();
2585 const REAL_VALUE_TYPE
&op2_lb
= op2
.lower_bound ();
2586 const REAL_VALUE_TYPE
&op2_ub
= op2
.upper_bound ();
2587 if ((contains_zero_p (lhs_lb
, lhs_ub
) && contains_zero_p (op2_lb
, op2_ub
))
2588 || ((real_isinf (&lhs_lb
) || real_isinf (&lhs_ub
))
2589 && (real_isinf (&op2_lb
) || real_isinf (&op2_ub
))))
2591 // If both lhs and op2 could be zeros or both could be infinities,
2592 // we don't know anything about op1 except maybe for the sign
2593 // and perhaps if it can be NAN or not.
2594 REAL_VALUE_TYPE lb
, ub
;
2595 int signbit_known
= signbit_known_p (lhs_lb
, lhs_ub
, op2_lb
, op2_ub
);
2596 zero_to_inf_range (lb
, ub
, signbit_known
);
2597 r
.set (type
, lb
, ub
);
2599 // Otherwise, if op2 is a singleton INF and lhs doesn't include INF,
2600 // or if lhs must be zero and op2 doesn't include zero, it would be
2601 // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF
2602 // range. Those are supersets of UNDEFINED, so let's keep that way.
2603 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2607 operator_mult::op2_range (frange
&r
, tree type
,
2608 const frange
&lhs
, const frange
&op1
,
2609 relation_trio
) const
2611 return op1_range (r
, type
, lhs
, op1
);
2615 operator_mult::rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
,
2616 bool &maybe_nan
, tree type
,
2617 const REAL_VALUE_TYPE
&lh_lb
,
2618 const REAL_VALUE_TYPE
&lh_ub
,
2619 const REAL_VALUE_TYPE
&rh_lb
,
2620 const REAL_VALUE_TYPE
&rh_ub
,
2621 relation_kind kind
) const
2625 && real_equal (&lh_lb
, &rh_lb
)
2626 && real_equal (&lh_ub
, &rh_ub
)
2627 && real_isneg (&lh_lb
) == real_isneg (&rh_lb
)
2628 && real_isneg (&lh_ub
) == real_isneg (&rh_ub
));
2631 // x * x never produces a new NAN and we only multiply the same
2632 // values, so the 0 * INF problematic cases never appear there.
2635 // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN.
2636 if ((zero_p (lh_lb
, lh_ub
) && singleton_inf_p (rh_lb
, rh_ub
))
2637 || (zero_p (rh_lb
, rh_ub
) && singleton_inf_p (lh_lb
, lh_ub
)))
2639 real_nan (&lb
, "", 0, TYPE_MODE (type
));
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
))
2663 return inf_range (lb
, ub
, signbit_known
);
2665 // If one of the multiplicands must be zero, the resulting
2666 // range is +-0 and NAN.
2667 if (zero_p (lh_lb
, lh_ub
) || zero_p (rh_lb
, rh_ub
))
2668 return zero_range (lb
, ub
, signbit_known
);
2670 // Otherwise one of the multiplicands could be
2671 // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF]
2672 // or similarly with different signs. 0.0 * DBL_MAX
2673 // is still 0.0, nextafter (0.0, 1.0) * INF is still INF,
2674 // so if the signs are always the same or always different,
2675 // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING.
2676 return zero_to_inf_range (lb
, ub
, signbit_known
);
2680 REAL_VALUE_TYPE cp
[8];
2681 // Do a cross-product. At this point none of the multiplications
2682 // should produce a NAN.
2683 frange_arithmetic (MULT_EXPR
, type
, cp
[0], lh_lb
, rh_lb
, dconstninf
);
2684 frange_arithmetic (MULT_EXPR
, type
, cp
[4], lh_lb
, rh_lb
, dconstinf
);
2687 // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub)
2688 // as maximum and -0.0 as minimum if 0.0 is in the range,
2689 // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub).
2690 // -0.0 rather than 0.0 because VREL_EQ doesn't prove that
2691 // x and y are bitwise equal, just that they compare equal.
2692 if (contains_zero_p (lh_lb
, lh_ub
))
2694 if (real_isneg (&lh_lb
) == real_isneg (&lh_ub
))
2707 frange_arithmetic (MULT_EXPR
, type
, cp
[1], lh_lb
, rh_ub
, dconstninf
);
2708 frange_arithmetic (MULT_EXPR
, type
, cp
[5], lh_lb
, rh_ub
, dconstinf
);
2709 frange_arithmetic (MULT_EXPR
, type
, cp
[2], lh_ub
, rh_lb
, dconstninf
);
2710 frange_arithmetic (MULT_EXPR
, type
, cp
[6], lh_ub
, rh_lb
, dconstinf
);
2712 frange_arithmetic (MULT_EXPR
, type
, cp
[3], lh_ub
, rh_ub
, dconstninf
);
2713 frange_arithmetic (MULT_EXPR
, type
, cp
[7], lh_ub
, rh_ub
, dconstinf
);
2715 find_range (lb
, ub
, cp
);
2719 class foperator_div
: public range_operator
2721 using range_operator::op1_range
;
2722 using range_operator::op2_range
;
2724 virtual bool op1_range (frange
&r
, tree type
,
2727 relation_trio
= TRIO_VARYING
) const final override
2729 if (lhs
.undefined_p ())
2731 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2732 bool ret
= range_op_handler (MULT_EXPR
).fold_range (r
, type
, wlhs
, op2
);
2735 if (wlhs
.known_isnan () || op2
.known_isnan () || op2
.undefined_p ())
2736 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2737 const REAL_VALUE_TYPE
&lhs_lb
= wlhs
.lower_bound ();
2738 const REAL_VALUE_TYPE
&lhs_ub
= wlhs
.upper_bound ();
2739 const REAL_VALUE_TYPE
&op2_lb
= op2
.lower_bound ();
2740 const REAL_VALUE_TYPE
&op2_ub
= op2
.upper_bound ();
2741 if ((contains_zero_p (lhs_lb
, lhs_ub
)
2742 && (real_isinf (&op2_lb
) || real_isinf (&op2_ub
)))
2743 || ((contains_zero_p (op2_lb
, op2_ub
))
2744 && (real_isinf (&lhs_lb
) || real_isinf (&lhs_ub
))))
2746 // If both lhs could be zero and op2 infinity or vice versa,
2747 // we don't know anything about op1 except maybe for the sign
2748 // and perhaps if it can be NAN or not.
2749 REAL_VALUE_TYPE lb
, ub
;
2750 int signbit_known
= signbit_known_p (lhs_lb
, lhs_ub
, op2_lb
, op2_ub
);
2751 zero_to_inf_range (lb
, ub
, signbit_known
);
2752 r
.set (type
, lb
, ub
);
2754 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2756 virtual bool op2_range (frange
&r
, tree type
,
2759 relation_trio
= TRIO_VARYING
) const final override
2761 if (lhs
.undefined_p ())
2763 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2764 bool ret
= fold_range (r
, type
, op1
, wlhs
);
2767 if (wlhs
.known_isnan () || op1
.known_isnan () || op1
.undefined_p ())
2768 return float_binary_op_range_finish (ret
, r
, type
, wlhs
, true);
2769 const REAL_VALUE_TYPE
&lhs_lb
= wlhs
.lower_bound ();
2770 const REAL_VALUE_TYPE
&lhs_ub
= wlhs
.upper_bound ();
2771 const REAL_VALUE_TYPE
&op1_lb
= op1
.lower_bound ();
2772 const REAL_VALUE_TYPE
&op1_ub
= op1
.upper_bound ();
2773 if ((contains_zero_p (lhs_lb
, lhs_ub
) && contains_zero_p (op1_lb
, op1_ub
))
2774 || ((real_isinf (&lhs_lb
) || real_isinf (&lhs_ub
))
2775 && (real_isinf (&op1_lb
) || real_isinf (&op1_ub
))))
2777 // If both lhs and op1 could be zeros or both could be infinities,
2778 // we don't know anything about op2 except maybe for the sign
2779 // and perhaps if it can be NAN or not.
2780 REAL_VALUE_TYPE lb
, ub
;
2781 int signbit_known
= signbit_known_p (lhs_lb
, lhs_ub
, op1_lb
, op1_ub
);
2782 zero_to_inf_range (lb
, ub
, signbit_known
);
2783 r
.set (type
, lb
, ub
);
2785 return float_binary_op_range_finish (ret
, r
, type
, wlhs
, true);
2788 void rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, bool &maybe_nan
,
2790 const REAL_VALUE_TYPE
&lh_lb
,
2791 const REAL_VALUE_TYPE
&lh_ub
,
2792 const REAL_VALUE_TYPE
&rh_lb
,
2793 const REAL_VALUE_TYPE
&rh_ub
,
2794 relation_kind
) const final override
2796 // +-0.0 / +-0.0 or +-INF / +-INF is a known NAN.
2797 if ((zero_p (lh_lb
, lh_ub
) && zero_p (rh_lb
, rh_ub
))
2798 || (singleton_inf_p (lh_lb
, lh_ub
) && singleton_inf_p (rh_lb
, rh_ub
)))
2800 real_nan (&lb
, "", 0, TYPE_MODE (type
));
2806 // If +-0.0 is in both ranges, it is a maybe NAN.
2807 if (contains_zero_p (lh_lb
, lh_ub
) && contains_zero_p (rh_lb
, rh_ub
))
2809 // If +-INF is in both ranges, it is a maybe NAN.
2810 else if ((real_isinf (&lh_lb
) || real_isinf (&lh_ub
))
2811 && (real_isinf (&rh_lb
) || real_isinf (&rh_ub
)))
2816 int signbit_known
= signbit_known_p (lh_lb
, lh_ub
, rh_lb
, rh_ub
);
2818 // If dividend must be zero, the range is just +-0
2819 // (including if the divisor is +-INF).
2820 // If divisor must be +-INF, the range is just +-0
2821 // (including if the dividend is zero).
2822 if (zero_p (lh_lb
, lh_ub
) || singleton_inf_p (rh_lb
, rh_ub
))
2823 return zero_range (lb
, ub
, signbit_known
);
2825 // If divisor must be zero, the range is just +-INF
2826 // (including if the dividend is +-INF).
2827 // If dividend must be +-INF, the range is just +-INF
2828 // (including if the dividend is zero).
2829 if (zero_p (rh_lb
, rh_ub
) || singleton_inf_p (lh_lb
, lh_ub
))
2830 return inf_range (lb
, ub
, signbit_known
);
2832 // Otherwise if both operands may be zero, divisor could be
2833 // nextafter(0.0, +-1.0) and dividend +-0.0
2834 // in which case result is going to INF or vice versa and
2835 // result +0.0. So, all we can say for that case is if the
2836 // signs of divisor and dividend are always the same we have
2837 // [+0.0, +INF], if they are always different we have
2838 // [-INF, -0.0]. If they vary, VARYING.
2839 // If both may be +-INF, divisor could be INF and dividend FLT_MAX,
2840 // in which case result is going to INF or vice versa and
2841 // result +0.0. So, all we can say for that case is if the
2842 // signs of divisor and dividend are always the same we have
2843 // [+0.0, +INF], if they are always different we have
2844 // [-INF, -0.0]. If they vary, VARYING.
2846 return zero_to_inf_range (lb
, ub
, signbit_known
);
2848 REAL_VALUE_TYPE cp
[8];
2849 // Do a cross-division. At this point none of the divisions should
2851 frange_arithmetic (RDIV_EXPR
, type
, cp
[0], lh_lb
, rh_lb
, dconstninf
);
2852 frange_arithmetic (RDIV_EXPR
, type
, cp
[1], lh_lb
, rh_ub
, dconstninf
);
2853 frange_arithmetic (RDIV_EXPR
, type
, cp
[2], lh_ub
, rh_lb
, dconstninf
);
2854 frange_arithmetic (RDIV_EXPR
, type
, cp
[3], lh_ub
, rh_ub
, dconstninf
);
2855 frange_arithmetic (RDIV_EXPR
, type
, cp
[4], lh_lb
, rh_lb
, dconstinf
);
2856 frange_arithmetic (RDIV_EXPR
, type
, cp
[5], lh_lb
, rh_ub
, dconstinf
);
2857 frange_arithmetic (RDIV_EXPR
, type
, cp
[6], lh_ub
, rh_lb
, dconstinf
);
2858 frange_arithmetic (RDIV_EXPR
, type
, cp
[7], lh_ub
, rh_ub
, dconstinf
);
2860 find_range (lb
, ub
, cp
);
2862 // If divisor may be zero (but is not known to be only zero),
2863 // and dividend can't be zero, the range can go up to -INF or +INF
2864 // depending on the signs.
2865 if (contains_zero_p (rh_lb
, rh_ub
))
2867 if (signbit_known
<= 0)
2868 real_inf (&lb
, true);
2869 if (signbit_known
>= 0)
2870 real_inf (&ub
, false);
2876 // Initialize any float operators to the primary table
2879 range_op_table::initialize_float_ops ()
2881 set (UNLE_EXPR
, fop_unordered_le
);
2882 set (UNLT_EXPR
, fop_unordered_lt
);
2883 set (UNGE_EXPR
, fop_unordered_ge
);
2884 set (UNGT_EXPR
, fop_unordered_gt
);
2885 set (UNEQ_EXPR
, fop_unordered_equal
);
2886 set (ORDERED_EXPR
, fop_ordered
);
2887 set (UNORDERED_EXPR
, fop_unordered
);
2888 set (LTGT_EXPR
, fop_ltgt
);
2889 set (RDIV_EXPR
, fop_div
);
2893 #include "selftest.h"
2898 // Build an frange from string endpoints.
2900 static inline frange
2901 frange_float (const char *lb
, const char *ub
, tree type
= float_type_node
)
2903 REAL_VALUE_TYPE min
, max
;
2904 gcc_assert (real_from_string (&min
, lb
) == 0);
2905 gcc_assert (real_from_string (&max
, ub
) == 0);
2906 return frange (type
, min
, max
);
2910 range_op_float_tests ()
2913 frange
trange (float_type_node
);
2915 // negate([-5, +10]) => [-10, 5]
2916 r0
= frange_float ("-5", "10");
2917 range_op_handler (NEGATE_EXPR
).fold_range (r
, float_type_node
, r0
, trange
);
2918 ASSERT_EQ (r
, frange_float ("-10", "5"));
2920 // negate([0, 1] -NAN) => [-1, -0] +NAN
2921 r0
= frange_float ("0", "1");
2922 r0
.update_nan (true);
2923 range_op_handler (NEGATE_EXPR
).fold_range (r
, float_type_node
, r0
, trange
);
2924 r1
= frange_float ("-1", "-0");
2925 r1
.update_nan (false);
2928 // [-INF,+INF] + [-INF,+INF] could be a NAN.
2929 range_op_handler
plus (PLUS_EXPR
);
2930 r0
.set_varying (float_type_node
);
2931 r1
.set_varying (float_type_node
);
2934 plus
.fold_range (r
, float_type_node
, r0
, r1
);
2935 if (HONOR_NANS (float_type_node
))
2936 ASSERT_TRUE (r
.maybe_isnan ());
2939 } // namespace selftest
2941 #endif // CHECKING_P