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.
285 // Relations in a floating point world are a bit tricky, as TRIO
286 // behaves as the corresponding unordered variant if either operand
287 // could be a NAN. For example, when resolving "if (x_5 == x_5)", the
288 // relation is VREL_EQ, but it behaves like VREL_UNEQ if NANs are a
289 // possibility. Similarly, the false edge of "if (x >= y)" has a
290 // relation of VREL_LT, but behaves as VREL_UNLT unless we can prove
291 // neither operand can be NAN.
293 // ?? It is unclear whether providing unordered VREL relations would
294 // simplify things, as we'd have to add more entries to various
295 // tables, tweak all the op1_op2_relation() entries, etc.
298 frelop_early_resolve (irange
&r
, tree type
,
299 const frange
&op1
, const frange
&op2
,
300 relation_trio trio
, relation_kind my_rel
)
302 relation_kind rel
= trio
.op1_op2 ();
304 if (maybe_isnan (op1
, op2
))
306 // There's not much we can do for VREL_EQ if NAN is a
307 // possibility. It is up to the caller to deal with these
310 return empty_range_varying (r
, type
, op1
, op2
);
312 // If known relation is a complete subset of this relation, always
313 // return true. However, avoid doing this when NAN is a possibility
314 // as we'll incorrectly fold conditions:
319 // ;; With NANs the relation here is basically VREL_UNLT, so we
320 // ;; can't fold the following:
322 else if (relation_union (rel
, my_rel
) == my_rel
)
324 r
= range_true (type
);
328 // If known relation has no subset of this relation, always false.
329 if (relation_intersect (rel
, my_rel
) == VREL_UNDEFINED
)
331 r
= range_false (type
);
335 // If either operand is undefined, return VARYING.
336 if (empty_range_varying (r
, type
, op1
, op2
))
342 // Set VALUE to its next real value, or INF if the operation overflows.
345 frange_nextafter (enum machine_mode mode
,
346 REAL_VALUE_TYPE
&value
,
347 const REAL_VALUE_TYPE
&inf
)
349 if (MODE_COMPOSITE_P (mode
)
350 && (real_isdenormal (&value
, mode
) || real_iszero (&value
)))
352 // IBM extended denormals only have DFmode precision.
353 REAL_VALUE_TYPE tmp
, tmp2
;
354 real_convert (&tmp2
, DFmode
, &value
);
355 real_nextafter (&tmp
, REAL_MODE_FORMAT (DFmode
), &tmp2
, &inf
);
356 real_convert (&value
, mode
, &tmp
);
361 real_nextafter (&tmp
, REAL_MODE_FORMAT (mode
), &value
, &inf
);
366 // Like real_arithmetic, but round the result to INF if the operation
367 // produced inexact results.
369 // ?? There is still one problematic case, i387. With
370 // -fexcess-precision=standard we perform most SF/DFmode arithmetic in
371 // XFmode (long_double_type_node), so that case is OK. But without
372 // -mfpmath=sse, all the SF/DFmode computations are in XFmode
373 // precision (64-bit mantissa) and only occasionally rounded to
374 // SF/DFmode (when storing into memory from the 387 stack). Maybe
375 // this is ok as well though it is just occasionally more precise. ??
378 frange_arithmetic (enum tree_code code
, tree type
,
379 REAL_VALUE_TYPE
&result
,
380 const REAL_VALUE_TYPE
&op1
,
381 const REAL_VALUE_TYPE
&op2
,
382 const REAL_VALUE_TYPE
&inf
)
384 REAL_VALUE_TYPE value
;
385 enum machine_mode mode
= TYPE_MODE (type
);
386 bool mode_composite
= MODE_COMPOSITE_P (mode
);
388 bool inexact
= real_arithmetic (&value
, code
, &op1
, &op2
);
389 real_convert (&result
, mode
, &value
);
391 /* When rounding towards negative infinity, x + (-x) and
392 x - x is -0 rather than +0 real_arithmetic computes.
393 So, when we are looking for lower bound (inf is negative),
394 use -0 rather than +0. */
395 if (flag_rounding_math
396 && (code
== PLUS_EXPR
|| code
== MINUS_EXPR
)
398 && real_iszero (&result
)
399 && !real_isneg (&result
)
400 && real_isneg (&inf
))
402 REAL_VALUE_TYPE op2a
= op2
;
403 if (code
== PLUS_EXPR
)
405 if (real_isneg (&op1
) == real_isneg (&op2a
) && real_equal (&op1
, &op2a
))
409 // Be extra careful if there may be discrepancies between the
410 // compile and runtime results.
416 bool low
= real_isneg (&inf
);
417 round
= (low
? !real_less (&result
, &value
)
418 : !real_less (&value
, &result
));
419 if (real_isinf (&result
, !low
)
420 && !real_isinf (&value
)
421 && !flag_rounding_math
)
423 // Use just [+INF, +INF] rather than [MAX, +INF]
424 // even if value is larger than MAX and rounds to
425 // nearest to +INF. Similarly just [-INF, -INF]
426 // rather than [-INF, +MAX] even if value is smaller
427 // than -MAX and rounds to nearest to -INF.
428 // Unless INEXACT is true, in that case we need some
434 REAL_VALUE_TYPE tmp
= result
, tmp2
;
435 frange_nextafter (mode
, tmp
, inf
);
436 // TMP is at this point the maximum representable
438 real_arithmetic (&tmp2
, MINUS_EXPR
, &value
, &tmp
);
439 if (real_isneg (&tmp2
) != low
440 && (REAL_EXP (&tmp2
) - REAL_EXP (&tmp
)
441 >= 2 - REAL_MODE_FORMAT (mode
)->p
))
446 if (round
&& (inexact
|| !real_identical (&result
, &value
)))
449 && (real_isdenormal (&result
, mode
) || real_iszero (&result
)))
451 // IBM extended denormals only have DFmode precision.
452 REAL_VALUE_TYPE tmp
, tmp2
;
453 real_convert (&tmp2
, DFmode
, &value
);
454 real_nextafter (&tmp
, REAL_MODE_FORMAT (DFmode
), &tmp2
, &inf
);
455 real_convert (&result
, mode
, &tmp
);
458 frange_nextafter (mode
, result
, inf
);
465 // ibm-ldouble-format documents 1ulp for + and -.
466 frange_nextafter (mode
, result
, inf
);
469 // ibm-ldouble-format documents 2ulps for *.
470 frange_nextafter (mode
, result
, inf
);
471 frange_nextafter (mode
, result
, inf
);
474 // ibm-ldouble-format documents 3ulps for /.
475 frange_nextafter (mode
, result
, inf
);
476 frange_nextafter (mode
, result
, inf
);
477 frange_nextafter (mode
, result
, inf
);
484 // Crop R to [-INF, MAX] where MAX is the maximum representable number
488 frange_drop_inf (frange
&r
, tree type
)
490 REAL_VALUE_TYPE max
= real_max_representable (type
);
491 frange
tmp (type
, r
.lower_bound (), max
);
495 // Crop R to [MIN, +INF] where MIN is the minimum representable number
499 frange_drop_ninf (frange
&r
, tree type
)
501 REAL_VALUE_TYPE min
= real_min_representable (type
);
502 frange
tmp (type
, min
, r
.upper_bound ());
506 // Crop R to [MIN, MAX] where MAX is the maximum representable number
507 // for TYPE and MIN the minimum representable number for TYPE.
510 frange_drop_infs (frange
&r
, tree type
)
512 REAL_VALUE_TYPE max
= real_max_representable (type
);
513 REAL_VALUE_TYPE min
= real_min_representable (type
);
514 frange
tmp (type
, min
, max
);
518 // If zero is in R, make sure both -0.0 and +0.0 are in the range.
521 frange_add_zeros (frange
&r
, tree type
)
523 if (r
.undefined_p () || r
.known_isnan ())
526 if (HONOR_SIGNED_ZEROS (type
)
527 && (real_iszero (&r
.lower_bound ()) || real_iszero (&r
.upper_bound ())))
530 zero
.set_zero (type
);
535 // Build a range that is <= VAL and store it in R. Return TRUE if
536 // further changes may be needed for R, or FALSE if R is in its final
540 build_le (frange
&r
, tree type
, const frange
&val
)
542 gcc_checking_assert (!val
.known_isnan ());
544 REAL_VALUE_TYPE ninf
= frange_val_min (type
);
545 r
.set (type
, ninf
, val
.upper_bound ());
547 // Add both zeros if there's the possibility of zero equality.
548 frange_add_zeros (r
, type
);
553 // Build a range that is < VAL and store it in R. Return TRUE if
554 // further changes may be needed for R, or FALSE if R is in its final
558 build_lt (frange
&r
, tree type
, const frange
&val
)
560 gcc_checking_assert (!val
.known_isnan ());
562 // < -INF is outside the range.
563 if (real_isinf (&val
.upper_bound (), 1))
565 if (HONOR_NANS (type
))
572 REAL_VALUE_TYPE ninf
= frange_val_min (type
);
573 REAL_VALUE_TYPE prev
= val
.upper_bound ();
574 machine_mode mode
= TYPE_MODE (type
);
575 // Default to the conservatively correct closed ranges for
576 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
577 // !HONOR_INFINITIES, nextafter will yield -INF, but frange::set()
578 // will crop the range appropriately.
579 if (!MODE_COMPOSITE_P (mode
))
580 frange_nextafter (mode
, prev
, ninf
);
581 r
.set (type
, ninf
, prev
);
585 // Build a range that is >= VAL and store it in R. Return TRUE if
586 // further changes may be needed for R, or FALSE if R is in its final
590 build_ge (frange
&r
, tree type
, const frange
&val
)
592 gcc_checking_assert (!val
.known_isnan ());
594 REAL_VALUE_TYPE inf
= frange_val_max (type
);
595 r
.set (type
, val
.lower_bound (), inf
);
597 // Add both zeros if there's the possibility of zero equality.
598 frange_add_zeros (r
, type
);
603 // Build a range that is > VAL and store it in R. Return TRUE if
604 // further changes may be needed for R, or FALSE if R is in its final
608 build_gt (frange
&r
, tree type
, const frange
&val
)
610 gcc_checking_assert (!val
.known_isnan ());
612 // > +INF is outside the range.
613 if (real_isinf (&val
.lower_bound (), 0))
615 if (HONOR_NANS (type
))
622 REAL_VALUE_TYPE inf
= frange_val_max (type
);
623 REAL_VALUE_TYPE next
= val
.lower_bound ();
624 machine_mode mode
= TYPE_MODE (type
);
625 // Default to the conservatively correct closed ranges for
626 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
627 // !HONOR_INFINITIES, nextafter will yield +INF, but frange::set()
628 // will crop the range appropriately.
629 if (!MODE_COMPOSITE_P (mode
))
630 frange_nextafter (mode
, next
, inf
);
631 r
.set (type
, next
, inf
);
637 operator_identity::fold_range (frange
&r
, tree
, const frange
&op1
,
638 const frange
&, relation_trio
) const
645 operator_identity::op1_range (frange
&r
, tree
, const frange
&lhs
,
646 const frange
&, relation_trio
) const
653 operator_cst::fold_range (frange
&r
, tree
, const frange
&op1
,
654 const frange
&, relation_trio
) const
661 operator_equal::op2_range (frange
&r
, tree type
,
662 const irange
&lhs
, const frange
&op1
,
663 relation_trio rel
) const
665 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
669 operator_equal::fold_range (irange
&r
, tree type
,
670 const frange
&op1
, const frange
&op2
,
671 relation_trio rel
) const
673 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_EQ
))
676 if (op1
.known_isnan () || op2
.known_isnan ())
677 r
= range_false (type
);
678 // We can be sure the values are always equal or not if both ranges
679 // consist of a single value, and then compare them.
680 else if (op1
.singleton_p () && op2
.singleton_p ())
683 r
= range_true (type
);
684 // If one operand is -0.0 and other 0.0, they are still equal.
685 else if (real_iszero (&op1
.lower_bound ())
686 && real_iszero (&op2
.lower_bound ()))
687 r
= range_true (type
);
689 r
= range_false (type
);
691 else if (real_iszero (&op1
.lower_bound ())
692 && real_iszero (&op1
.upper_bound ())
693 && real_iszero (&op2
.lower_bound ())
694 && real_iszero (&op2
.upper_bound ())
695 && !maybe_isnan (op1
, op2
))
696 // [-0.0, 0.0] == [-0.0, 0.0] or similar.
697 r
= range_true (type
);
700 // If ranges do not intersect, we know the range is not equal,
701 // otherwise we don't know anything for sure.
704 if (tmp
.undefined_p ())
706 // If one range is [whatever, -0.0] and another
707 // [0.0, whatever2], we don't know anything either,
708 // because -0.0 == 0.0.
709 if ((real_iszero (&op1
.upper_bound ())
710 && real_iszero (&op2
.lower_bound ()))
711 || (real_iszero (&op1
.lower_bound ())
712 && real_iszero (&op2
.upper_bound ())))
713 r
= range_true_and_false (type
);
715 r
= range_false (type
);
718 r
= range_true_and_false (type
);
724 operator_equal::op1_range (frange
&r
, tree type
,
727 relation_trio trio
) const
729 relation_kind rel
= trio
.op1_op2 ();
730 switch (get_bool_state (r
, lhs
, type
))
733 // The TRUE side of x == NAN is unreachable.
734 if (op2
.known_isnan ())
738 // If it's true, the result is the same as OP2.
740 // Add both zeros if there's the possibility of zero equality.
741 frange_add_zeros (r
, type
);
742 // The TRUE side of op1 == op2 implies op1 is !NAN.
748 // The FALSE side of op1 == op1 implies op1 is a NAN.
751 // On the FALSE side of x == NAN, we know nothing about x.
752 else if (op2
.known_isnan ())
753 r
.set_varying (type
);
754 // If the result is false, the only time we know anything is
755 // if OP2 is a constant.
756 else if (op2
.singleton_p ()
757 || (!op2
.maybe_isnan () && op2
.zero_p ()))
759 REAL_VALUE_TYPE tmp
= op2
.lower_bound ();
760 r
.set (type
, tmp
, tmp
, VR_ANTI_RANGE
);
763 r
.set_varying (type
);
772 // Check if the LHS range indicates a relation between OP1 and OP2.
775 operator_equal::op1_op2_relation (const irange
&lhs
, const frange
&,
776 const frange
&) const
778 if (lhs
.undefined_p ())
779 return VREL_UNDEFINED
;
781 // FALSE = op1 == op2 indicates NE_EXPR.
785 // TRUE = op1 == op2 indicates EQ_EXPR.
786 if (lhs
.undefined_p () || !contains_zero_p (lhs
))
792 operator_not_equal::fold_range (irange
&r
, tree type
,
793 const frange
&op1
, const frange
&op2
,
794 relation_trio trio
) const
796 relation_kind rel
= trio
.op1_op2 ();
798 // VREL_NE & NE_EXPR is always true, even with NANs.
801 r
= range_true (type
);
804 if (frelop_early_resolve (r
, type
, op1
, op2
, trio
, VREL_NE
))
807 // x != NAN is always TRUE.
808 if (op1
.known_isnan () || op2
.known_isnan ())
809 r
= range_true (type
);
810 // We can be sure the values are always equal or not if both ranges
811 // consist of a single value, and then compare them.
812 else if (op1
.singleton_p () && op2
.singleton_p ())
815 r
= range_false (type
);
816 // If one operand is -0.0 and other 0.0, they are still equal.
817 else if (real_iszero (&op1
.lower_bound ())
818 && real_iszero (&op2
.lower_bound ()))
819 r
= range_false (type
);
821 r
= range_true (type
);
823 else if (real_iszero (&op1
.lower_bound ())
824 && real_iszero (&op1
.upper_bound ())
825 && real_iszero (&op2
.lower_bound ())
826 && real_iszero (&op2
.upper_bound ())
827 && !maybe_isnan (op1
, op2
))
828 // [-0.0, 0.0] != [-0.0, 0.0] or similar.
829 r
= range_false (type
);
832 // If ranges do not intersect, we know the range is not equal,
833 // otherwise we don't know anything for sure.
836 if (tmp
.undefined_p ())
838 // If one range is [whatever, -0.0] and another
839 // [0.0, whatever2], we don't know anything either,
840 // because -0.0 == 0.0.
841 if ((real_iszero (&op1
.upper_bound ())
842 && real_iszero (&op2
.lower_bound ()))
843 || (real_iszero (&op1
.lower_bound ())
844 && real_iszero (&op2
.upper_bound ())))
845 r
= range_true_and_false (type
);
847 r
= range_true (type
);
850 r
= range_true_and_false (type
);
856 operator_not_equal::op1_range (frange
&r
, tree type
,
859 relation_trio trio
) const
861 relation_kind rel
= trio
.op1_op2 ();
862 switch (get_bool_state (r
, lhs
, type
))
865 // If the result is true, the only time we know anything is if
866 // OP2 is a constant.
867 if (op2
.singleton_p ())
869 // This is correct even if op1 is NAN, because the following
870 // range would be ~[tmp, tmp] with the NAN property set to
872 REAL_VALUE_TYPE tmp
= op2
.lower_bound ();
873 r
.set (type
, tmp
, tmp
, VR_ANTI_RANGE
);
875 // The TRUE side of op1 != op1 implies op1 is NAN.
876 else if (rel
== VREL_EQ
)
879 r
.set_varying (type
);
883 // The FALSE side of x != NAN is impossible.
884 if (op2
.known_isnan ())
888 // If it's false, the result is the same as OP2.
890 // Add both zeros if there's the possibility of zero equality.
891 frange_add_zeros (r
, type
);
892 // The FALSE side of op1 != op2 implies op1 is !NAN.
904 // Check if the LHS range indicates a relation between OP1 and OP2.
907 operator_not_equal::op1_op2_relation (const irange
&lhs
, const frange
&,
908 const frange
&) const
910 if (lhs
.undefined_p ())
911 return VREL_UNDEFINED
;
913 // FALSE = op1 != op2 indicates EQ_EXPR.
917 // TRUE = op1 != op2 indicates NE_EXPR.
918 if (lhs
.undefined_p () || !contains_zero_p (lhs
))
924 operator_lt::fold_range (irange
&r
, tree type
,
925 const frange
&op1
, const frange
&op2
,
926 relation_trio trio
) const
928 relation_kind rel
= trio
.op1_op2 ();
930 // VREL_EQ & LT_EXPR is impossible, even with NANs.
933 r
= range_false (type
);
936 if (frelop_early_resolve (r
, type
, op1
, op2
, trio
, VREL_LT
))
939 if (op1
.known_isnan ()
940 || op2
.known_isnan ()
941 || !real_less (&op1
.lower_bound (), &op2
.upper_bound ()))
942 r
= range_false (type
);
943 else if (!maybe_isnan (op1
, op2
)
944 && real_less (&op1
.upper_bound (), &op2
.lower_bound ()))
945 r
= range_true (type
);
947 r
= range_true_and_false (type
);
952 operator_lt::op1_range (frange
&r
,
958 switch (get_bool_state (r
, lhs
, type
))
961 // The TRUE side of x < NAN is unreachable.
962 if (op2
.known_isnan ())
964 else if (op2
.undefined_p ())
966 else if (build_lt (r
, type
, op2
))
969 // x < y implies x is not +INF.
970 frange_drop_inf (r
, type
);
975 // On the FALSE side of x < NAN, we know nothing about x.
976 if (op2
.known_isnan () || op2
.maybe_isnan ())
977 r
.set_varying (type
);
979 build_ge (r
, type
, op2
);
989 operator_lt::op2_range (frange
&r
,
995 switch (get_bool_state (r
, lhs
, type
))
998 // The TRUE side of NAN < x is unreachable.
999 if (op1
.known_isnan ())
1001 else if (op1
.undefined_p ())
1003 else if (build_gt (r
, type
, op1
))
1006 // x < y implies y is not -INF.
1007 frange_drop_ninf (r
, type
);
1012 // On the FALSE side of NAN < x, we know nothing about x.
1013 if (op1
.known_isnan () || op1
.maybe_isnan ())
1014 r
.set_varying (type
);
1016 build_le (r
, type
, op1
);
1026 // Check if the LHS range indicates a relation between OP1 and OP2.
1029 operator_lt::op1_op2_relation (const irange
&lhs
, const frange
&,
1030 const frange
&) const
1032 if (lhs
.undefined_p ())
1033 return VREL_UNDEFINED
;
1035 // FALSE = op1 < op2 indicates GE_EXPR.
1039 // TRUE = op1 < op2 indicates LT_EXPR.
1040 if (lhs
.undefined_p () || !contains_zero_p (lhs
))
1042 return VREL_VARYING
;
1046 operator_le::fold_range (irange
&r
, tree type
,
1047 const frange
&op1
, const frange
&op2
,
1048 relation_trio rel
) const
1050 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_LE
))
1053 if (op1
.known_isnan ()
1054 || op2
.known_isnan ()
1055 || !real_compare (LE_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
1056 r
= range_false (type
);
1057 else if (!maybe_isnan (op1
, op2
)
1058 && real_compare (LE_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
1059 r
= range_true (type
);
1061 r
= range_true_and_false (type
);
1066 operator_le::op1_range (frange
&r
,
1070 relation_trio
) const
1072 switch (get_bool_state (r
, lhs
, type
))
1075 // The TRUE side of x <= NAN is unreachable.
1076 if (op2
.known_isnan ())
1078 else if (op2
.undefined_p ())
1080 else if (build_le (r
, type
, op2
))
1085 // On the FALSE side of x <= NAN, we know nothing about x.
1086 if (op2
.known_isnan () || op2
.maybe_isnan ())
1087 r
.set_varying (type
);
1089 build_gt (r
, type
, op2
);
1099 operator_le::op2_range (frange
&r
,
1103 relation_trio
) const
1105 switch (get_bool_state (r
, lhs
, type
))
1108 // The TRUE side of NAN <= x is unreachable.
1109 if (op1
.known_isnan ())
1111 else if (op1
.undefined_p ())
1113 else if (build_ge (r
, type
, op1
))
1118 // On the FALSE side of NAN <= x, we know nothing about x.
1119 if (op1
.known_isnan () || op1
.maybe_isnan ())
1120 r
.set_varying (type
);
1121 else if (op1
.undefined_p ())
1124 build_lt (r
, type
, op1
);
1133 // Check if the LHS range indicates a relation between OP1 and OP2.
1136 operator_le::op1_op2_relation (const irange
&lhs
, const frange
&,
1137 const frange
&) const
1139 if (lhs
.undefined_p ())
1140 return VREL_UNDEFINED
;
1142 // FALSE = op1 <= op2 indicates GT_EXPR.
1146 // TRUE = op1 <= op2 indicates LE_EXPR.
1147 if (lhs
.undefined_p () || !contains_zero_p (lhs
))
1149 return VREL_VARYING
;
1153 operator_gt::fold_range (irange
&r
, tree type
,
1154 const frange
&op1
, const frange
&op2
,
1155 relation_trio trio
) const
1157 relation_kind rel
= trio
.op1_op2 ();
1159 // VREL_EQ & GT_EXPR is impossible, even with NANs.
1162 r
= range_false (type
);
1165 if (frelop_early_resolve (r
, type
, op1
, op2
, trio
, VREL_GT
))
1168 if (op1
.known_isnan ()
1169 || op2
.known_isnan ()
1170 || !real_compare (GT_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
1171 r
= range_false (type
);
1172 else if (!maybe_isnan (op1
, op2
)
1173 && real_compare (GT_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
1174 r
= range_true (type
);
1176 r
= range_true_and_false (type
);
1181 operator_gt::op1_range (frange
&r
,
1185 relation_trio
) const
1187 switch (get_bool_state (r
, lhs
, type
))
1190 // The TRUE side of x > NAN is unreachable.
1191 if (op2
.known_isnan ())
1193 else if (op2
.undefined_p ())
1195 else if (build_gt (r
, type
, op2
))
1198 // x > y implies x is not -INF.
1199 frange_drop_ninf (r
, type
);
1204 // On the FALSE side of x > NAN, we know nothing about x.
1205 if (op2
.known_isnan () || op2
.maybe_isnan ())
1206 r
.set_varying (type
);
1207 else if (op2
.undefined_p ())
1210 build_le (r
, type
, op2
);
1220 operator_gt::op2_range (frange
&r
,
1224 relation_trio
) const
1226 switch (get_bool_state (r
, lhs
, type
))
1229 // The TRUE side of NAN > x is unreachable.
1230 if (op1
.known_isnan ())
1232 else if (op1
.undefined_p ())
1234 else if (build_lt (r
, type
, op1
))
1237 // x > y implies y is not +INF.
1238 frange_drop_inf (r
, type
);
1243 // On The FALSE side of NAN > x, we know nothing about x.
1244 if (op1
.known_isnan () || op1
.maybe_isnan ())
1245 r
.set_varying (type
);
1246 else if (op1
.undefined_p ())
1249 build_ge (r
, type
, op1
);
1258 // Check if the LHS range indicates a relation between OP1 and OP2.
1261 operator_gt::op1_op2_relation (const irange
&lhs
, const frange
&,
1262 const frange
&) const
1264 if (lhs
.undefined_p ())
1265 return VREL_UNDEFINED
;
1267 // FALSE = op1 > op2 indicates LE_EXPR.
1271 // TRUE = op1 > op2 indicates GT_EXPR.
1272 if (!contains_zero_p (lhs
))
1274 return VREL_VARYING
;
1278 operator_ge::fold_range (irange
&r
, tree type
,
1279 const frange
&op1
, const frange
&op2
,
1280 relation_trio rel
) const
1282 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_GE
))
1285 if (op1
.known_isnan ()
1286 || op2
.known_isnan ()
1287 || !real_compare (GE_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
1288 r
= range_false (type
);
1289 else if (!maybe_isnan (op1
, op2
)
1290 && real_compare (GE_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
1291 r
= range_true (type
);
1293 r
= range_true_and_false (type
);
1298 operator_ge::op1_range (frange
&r
,
1302 relation_trio
) const
1304 switch (get_bool_state (r
, lhs
, type
))
1307 // The TRUE side of x >= NAN is unreachable.
1308 if (op2
.known_isnan ())
1310 else if (op2
.undefined_p ())
1312 else if (build_ge (r
, type
, op2
))
1317 // On the FALSE side of x >= NAN, we know nothing about x.
1318 if (op2
.known_isnan () || op2
.maybe_isnan ())
1319 r
.set_varying (type
);
1320 else if (op2
.undefined_p ())
1323 build_lt (r
, type
, op2
);
1333 operator_ge::op2_range (frange
&r
, tree type
,
1336 relation_trio
) const
1338 switch (get_bool_state (r
, lhs
, type
))
1341 // The TRUE side of NAN >= x is unreachable.
1342 if (op1
.known_isnan ())
1344 else if (op1
.undefined_p ())
1346 else if (build_le (r
, type
, op1
))
1351 // On the FALSE side of NAN >= x, we know nothing about x.
1352 if (op1
.known_isnan () || op1
.maybe_isnan ())
1353 r
.set_varying (type
);
1354 else if (op1
.undefined_p ())
1357 build_gt (r
, type
, op1
);
1366 // Check if the LHS range indicates a relation between OP1 and OP2.
1369 operator_ge::op1_op2_relation (const irange
&lhs
, const frange
&,
1370 const frange
&) const
1372 if (lhs
.undefined_p ())
1373 return VREL_UNDEFINED
;
1375 // FALSE = op1 >= op2 indicates LT_EXPR.
1379 // TRUE = op1 >= op2 indicates GE_EXPR.
1380 if (!contains_zero_p (lhs
))
1382 return VREL_VARYING
;
1385 // UNORDERED_EXPR comparison.
1387 class foperator_unordered
: public range_operator
1389 using range_operator::fold_range
;
1390 using range_operator::op1_range
;
1391 using range_operator::op2_range
;
1393 bool fold_range (irange
&r
, tree type
,
1394 const frange
&op1
, const frange
&op2
,
1395 relation_trio
= TRIO_VARYING
) const final override
;
1396 bool op1_range (frange
&r
, tree type
,
1397 const irange
&lhs
, const frange
&op2
,
1398 relation_trio
= TRIO_VARYING
) const final override
;
1399 bool op2_range (frange
&r
, tree type
,
1400 const irange
&lhs
, const frange
&op1
,
1401 relation_trio rel
= TRIO_VARYING
) const final override
1403 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
1408 foperator_unordered::fold_range (irange
&r
, tree type
,
1409 const frange
&op1
, const frange
&op2
,
1410 relation_trio
) const
1412 // UNORDERED is TRUE if either operand is a NAN.
1413 if (op1
.known_isnan () || op2
.known_isnan ())
1414 r
= range_true (type
);
1415 // UNORDERED is FALSE if neither operand is a NAN.
1416 else if (!op1
.maybe_isnan () && !op2
.maybe_isnan ())
1417 r
= range_false (type
);
1419 r
= range_true_and_false (type
);
1424 foperator_unordered::op1_range (frange
&r
, tree type
,
1427 relation_trio trio
) const
1429 relation_kind rel
= trio
.op1_op2 ();
1430 switch (get_bool_state (r
, lhs
, type
))
1433 // Since at least one operand must be NAN, if one of them is
1434 // not, the other must be.
1435 if (rel
== VREL_EQ
|| !op2
.maybe_isnan ())
1438 r
.set_varying (type
);
1442 // A false UNORDERED means both operands are !NAN, so it's
1443 // impossible for op2 to be a NAN.
1444 if (op2
.known_isnan ())
1448 r
.set_varying (type
);
1459 // ORDERED_EXPR comparison.
1461 class foperator_ordered
: public range_operator
1463 using range_operator::fold_range
;
1464 using range_operator::op1_range
;
1465 using range_operator::op2_range
;
1467 bool fold_range (irange
&r
, tree type
,
1468 const frange
&op1
, const frange
&op2
,
1469 relation_trio
= TRIO_VARYING
) const final override
;
1470 bool op1_range (frange
&r
, tree type
,
1471 const irange
&lhs
, const frange
&op2
,
1472 relation_trio
= TRIO_VARYING
) const final override
;
1473 bool op2_range (frange
&r
, tree type
,
1474 const irange
&lhs
, const frange
&op1
,
1475 relation_trio rel
= TRIO_VARYING
) const final override
1477 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
1482 foperator_ordered::fold_range (irange
&r
, tree type
,
1483 const frange
&op1
, const frange
&op2
,
1484 relation_trio
) const
1486 if (op1
.known_isnan () || op2
.known_isnan ())
1487 r
= range_false (type
);
1488 else if (!op1
.maybe_isnan () && !op2
.maybe_isnan ())
1489 r
= range_true (type
);
1491 r
= range_true_and_false (type
);
1496 foperator_ordered::op1_range (frange
&r
, tree type
,
1499 relation_trio trio
) const
1501 relation_kind rel
= trio
.op1_op2 ();
1502 switch (get_bool_state (r
, lhs
, type
))
1505 // The TRUE side of ORDERED means both operands are !NAN, so
1506 // it's impossible for op2 to be a NAN.
1507 if (op2
.known_isnan ())
1511 r
.set_varying (type
);
1517 // The FALSE side of op1 ORDERED op1 implies op1 is NAN.
1521 r
.set_varying (type
);
1531 operator_negate::fold_range (frange
&r
, tree type
,
1532 const frange
&op1
, const frange
&op2
,
1533 relation_trio
) const
1535 if (empty_range_varying (r
, type
, op1
, op2
))
1537 if (op1
.known_isnan ())
1540 if (op1
.nan_signbit_p (sign
))
1541 r
.set_nan (type
, !sign
);
1547 REAL_VALUE_TYPE lh_lb
= op1
.lower_bound ();
1548 REAL_VALUE_TYPE lh_ub
= op1
.upper_bound ();
1549 lh_lb
= real_value_negate (&lh_lb
);
1550 lh_ub
= real_value_negate (&lh_ub
);
1551 r
.set (type
, lh_ub
, lh_lb
);
1552 if (op1
.maybe_isnan ())
1555 if (op1
.nan_signbit_p (sign
))
1556 r
.update_nan (!sign
);
1566 operator_negate::op1_range (frange
&r
, tree type
,
1567 const frange
&lhs
, const frange
&op2
,
1568 relation_trio rel
) const
1570 return fold_range (r
, type
, lhs
, op2
, rel
);
1574 operator_abs::fold_range (frange
&r
, tree type
,
1575 const frange
&op1
, const frange
&op2
,
1576 relation_trio
) const
1578 if (empty_range_varying (r
, type
, op1
, op2
))
1580 if (op1
.known_isnan ())
1582 r
.set_nan (type
, /*sign=*/false);
1586 const REAL_VALUE_TYPE lh_lb
= op1
.lower_bound ();
1587 const REAL_VALUE_TYPE lh_ub
= op1
.upper_bound ();
1588 // Handle the easy case where everything is positive.
1589 if (real_compare (GE_EXPR
, &lh_lb
, &dconst0
)
1590 && !real_iszero (&lh_lb
, /*sign=*/true)
1591 && !op1
.maybe_isnan (/*sign=*/true))
1597 REAL_VALUE_TYPE min
= real_value_abs (&lh_lb
);
1598 REAL_VALUE_TYPE max
= real_value_abs (&lh_ub
);
1599 // If the range contains zero then we know that the minimum value in the
1600 // range will be zero.
1601 if (real_compare (LE_EXPR
, &lh_lb
, &dconst0
)
1602 && real_compare (GE_EXPR
, &lh_ub
, &dconst0
))
1604 if (real_compare (GT_EXPR
, &min
, &max
))
1610 // If the range was reversed, swap MIN and MAX.
1611 if (real_compare (GT_EXPR
, &min
, &max
))
1612 std::swap (min
, max
);
1615 r
.set (type
, min
, max
);
1616 if (op1
.maybe_isnan ())
1617 r
.update_nan (/*sign=*/false);
1624 operator_abs::op1_range (frange
&r
, tree type
,
1625 const frange
&lhs
, const frange
&op2
,
1626 relation_trio
) const
1628 if (empty_range_varying (r
, type
, lhs
, op2
))
1630 if (lhs
.known_isnan ())
1636 // Start with the positives because negatives are an impossible result.
1637 frange
positives (type
, dconst0
, frange_val_max (type
));
1638 positives
.update_nan (/*sign=*/false);
1639 positives
.intersect (lhs
);
1641 // Add -NAN if relevant.
1642 if (r
.maybe_isnan ())
1645 neg_nan
.set_nan (type
, true);
1648 if (r
.known_isnan () || r
.undefined_p ())
1650 // Then add the negative of each pair:
1651 // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
1652 frange
negatives (type
, real_value_negate (&positives
.upper_bound ()),
1653 real_value_negate (&positives
.lower_bound ()));
1654 negatives
.clear_nan ();
1655 r
.union_ (negatives
);
1659 class foperator_unordered_lt
: public range_operator
1661 using range_operator::fold_range
;
1662 using range_operator::op1_range
;
1663 using range_operator::op2_range
;
1665 bool fold_range (irange
&r
, tree type
,
1666 const frange
&op1
, const frange
&op2
,
1667 relation_trio trio
= TRIO_VARYING
) const final override
1669 relation_kind rel
= trio
.op1_op2 ();
1671 if (op1
.known_isnan () || op2
.known_isnan ()
1674 r
= range_true (type
);
1677 frange op1_no_nan
= op1
;
1678 frange op2_no_nan
= op2
;
1679 if (op1
.maybe_isnan ())
1680 op1_no_nan
.clear_nan ();
1681 if (op2
.maybe_isnan ())
1682 op2_no_nan
.clear_nan ();
1683 if (!range_op_handler (LT_EXPR
).fold_range (r
, type
, op1_no_nan
,
1686 // The result is the same as the ordered version when the
1687 // comparison is true or when the operands cannot be NANs.
1688 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1692 r
= range_true_and_false (type
);
1696 bool op1_range (frange
&r
, tree type
,
1699 relation_trio trio
) const final override
;
1700 bool op2_range (frange
&r
, tree type
,
1703 relation_trio trio
) const final override
;
1707 foperator_unordered_lt::op1_range (frange
&r
, tree type
,
1710 relation_trio
) const
1712 switch (get_bool_state (r
, lhs
, type
))
1715 if (op2
.known_isnan () || op2
.maybe_isnan ())
1716 r
.set_varying (type
);
1717 else if (op2
.undefined_p ())
1720 build_lt (r
, type
, op2
);
1724 // A false UNORDERED_LT means both operands are !NAN, so it's
1725 // impossible for op2 to be a NAN.
1726 if (op2
.known_isnan ())
1728 else if (op2
.undefined_p ())
1730 else if (build_ge (r
, type
, op2
))
1741 foperator_unordered_lt::op2_range (frange
&r
, tree type
,
1744 relation_trio
) const
1746 switch (get_bool_state (r
, lhs
, type
))
1749 if (op1
.known_isnan () || op1
.maybe_isnan ())
1750 r
.set_varying (type
);
1751 else if (op1
.undefined_p ())
1754 build_gt (r
, type
, op1
);
1758 // A false UNORDERED_LT means both operands are !NAN, so it's
1759 // impossible for op1 to be a NAN.
1760 if (op1
.known_isnan ())
1762 else if (op1
.undefined_p ())
1764 else if (build_le (r
, type
, op1
))
1774 class foperator_unordered_le
: public range_operator
1776 using range_operator::fold_range
;
1777 using range_operator::op1_range
;
1778 using range_operator::op2_range
;
1780 bool fold_range (irange
&r
, tree type
,
1781 const frange
&op1
, const frange
&op2
,
1782 relation_trio trio
= TRIO_VARYING
) const final override
1784 relation_kind rel
= trio
.op1_op2 ();
1786 if (op1
.known_isnan () || op2
.known_isnan ()
1789 r
= range_true (type
);
1792 frange op1_no_nan
= op1
;
1793 frange op2_no_nan
= op2
;
1794 if (op1
.maybe_isnan ())
1795 op1_no_nan
.clear_nan ();
1796 if (op2
.maybe_isnan ())
1797 op2_no_nan
.clear_nan ();
1798 if (!range_op_handler (LE_EXPR
).fold_range (r
, type
, op1_no_nan
,
1801 // The result is the same as the ordered version when the
1802 // comparison is true or when the operands cannot be NANs.
1803 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1807 r
= range_true_and_false (type
);
1811 bool op1_range (frange
&r
, tree type
,
1812 const irange
&lhs
, const frange
&op2
,
1813 relation_trio
= TRIO_VARYING
) const final override
;
1814 bool op2_range (frange
&r
, tree type
,
1815 const irange
&lhs
, const frange
&op1
,
1816 relation_trio
= TRIO_VARYING
) const final override
;
1820 foperator_unordered_le::op1_range (frange
&r
, tree type
,
1821 const irange
&lhs
, const frange
&op2
,
1822 relation_trio
) const
1824 switch (get_bool_state (r
, lhs
, type
))
1827 if (op2
.known_isnan () || op2
.maybe_isnan ())
1828 r
.set_varying (type
);
1829 else if (op2
.undefined_p ())
1832 build_le (r
, type
, op2
);
1836 // A false UNORDERED_LE means both operands are !NAN, so it's
1837 // impossible for op2 to be a NAN.
1838 if (op2
.known_isnan ())
1840 else if (build_gt (r
, type
, op2
))
1851 foperator_unordered_le::op2_range (frange
&r
,
1855 relation_trio
) const
1857 switch (get_bool_state (r
, lhs
, type
))
1860 if (op1
.known_isnan () || op1
.maybe_isnan ())
1861 r
.set_varying (type
);
1862 else if (op1
.undefined_p ())
1865 build_ge (r
, type
, op1
);
1869 // A false UNORDERED_LE means both operands are !NAN, so it's
1870 // impossible for op1 to be a NAN.
1871 if (op1
.known_isnan ())
1873 else if (op1
.undefined_p ())
1875 else if (build_lt (r
, type
, op1
))
1885 class foperator_unordered_gt
: public range_operator
1887 using range_operator::fold_range
;
1888 using range_operator::op1_range
;
1889 using range_operator::op2_range
;
1891 bool fold_range (irange
&r
, tree type
,
1892 const frange
&op1
, const frange
&op2
,
1893 relation_trio trio
= TRIO_VARYING
) const final override
1895 relation_kind rel
= trio
.op1_op2 ();
1897 if (op1
.known_isnan () || op2
.known_isnan ()
1900 r
= range_true (type
);
1903 frange op1_no_nan
= op1
;
1904 frange op2_no_nan
= op2
;
1905 if (op1
.maybe_isnan ())
1906 op1_no_nan
.clear_nan ();
1907 if (op2
.maybe_isnan ())
1908 op2_no_nan
.clear_nan ();
1909 if (!range_op_handler (GT_EXPR
).fold_range (r
, type
, op1_no_nan
,
1912 // The result is the same as the ordered version when the
1913 // comparison is true or when the operands cannot be NANs.
1914 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1918 r
= range_true_and_false (type
);
1922 bool op1_range (frange
&r
, tree type
,
1923 const irange
&lhs
, const frange
&op2
,
1924 relation_trio
= TRIO_VARYING
) const final override
;
1925 bool op2_range (frange
&r
, tree type
,
1926 const irange
&lhs
, const frange
&op1
,
1927 relation_trio
= TRIO_VARYING
) const final override
;
1931 foperator_unordered_gt::op1_range (frange
&r
,
1935 relation_trio
) const
1937 switch (get_bool_state (r
, lhs
, type
))
1940 if (op2
.known_isnan () || op2
.maybe_isnan ())
1941 r
.set_varying (type
);
1942 else if (op2
.undefined_p ())
1945 build_gt (r
, type
, op2
);
1949 // A false UNORDERED_GT means both operands are !NAN, so it's
1950 // impossible for op2 to be a NAN.
1951 if (op2
.known_isnan ())
1953 else if (op2
.undefined_p ())
1955 else if (build_le (r
, type
, op2
))
1966 foperator_unordered_gt::op2_range (frange
&r
,
1970 relation_trio
) const
1972 switch (get_bool_state (r
, lhs
, type
))
1975 if (op1
.known_isnan () || op1
.maybe_isnan ())
1976 r
.set_varying (type
);
1977 else if (op1
.undefined_p ())
1980 build_lt (r
, type
, op1
);
1984 // A false UNORDERED_GT means both operands are !NAN, so it's
1985 // impossible for op1 to be a NAN.
1986 if (op1
.known_isnan ())
1988 else if (op1
.undefined_p ())
1990 else if (build_ge (r
, type
, op1
))
2000 class foperator_unordered_ge
: public range_operator
2002 using range_operator::fold_range
;
2003 using range_operator::op1_range
;
2004 using range_operator::op2_range
;
2006 bool fold_range (irange
&r
, tree type
,
2007 const frange
&op1
, const frange
&op2
,
2008 relation_trio trio
= TRIO_VARYING
) const final override
2010 relation_kind rel
= trio
.op1_op2 ();
2012 if (op1
.known_isnan () || op2
.known_isnan ()
2015 r
= range_true (type
);
2018 frange op1_no_nan
= op1
;
2019 frange op2_no_nan
= op2
;
2020 if (op1
.maybe_isnan ())
2021 op1_no_nan
.clear_nan ();
2022 if (op2
.maybe_isnan ())
2023 op2_no_nan
.clear_nan ();
2024 if (!range_op_handler (GE_EXPR
).fold_range (r
, type
, op1_no_nan
,
2027 // The result is the same as the ordered version when the
2028 // comparison is true or when the operands cannot be NANs.
2029 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
2033 r
= range_true_and_false (type
);
2037 bool op1_range (frange
&r
, tree type
,
2038 const irange
&lhs
, const frange
&op2
,
2039 relation_trio
= TRIO_VARYING
) const final override
;
2040 bool op2_range (frange
&r
, tree type
,
2041 const irange
&lhs
, const frange
&op1
,
2042 relation_trio
= TRIO_VARYING
) const final override
;
2046 foperator_unordered_ge::op1_range (frange
&r
,
2050 relation_trio
) const
2052 switch (get_bool_state (r
, lhs
, type
))
2055 if (op2
.known_isnan () || op2
.maybe_isnan ())
2056 r
.set_varying (type
);
2057 else if (op2
.undefined_p ())
2060 build_ge (r
, type
, op2
);
2064 // A false UNORDERED_GE means both operands are !NAN, so it's
2065 // impossible for op2 to be a NAN.
2066 if (op2
.known_isnan ())
2068 else if (op2
.undefined_p ())
2070 else if (build_lt (r
, type
, op2
))
2081 foperator_unordered_ge::op2_range (frange
&r
, tree type
,
2084 relation_trio
) const
2086 switch (get_bool_state (r
, lhs
, type
))
2089 if (op1
.known_isnan () || op1
.maybe_isnan ())
2090 r
.set_varying (type
);
2091 else if (op1
.undefined_p ())
2094 build_le (r
, type
, op1
);
2098 // A false UNORDERED_GE means both operands are !NAN, so it's
2099 // impossible for op1 to be a NAN.
2100 if (op1
.known_isnan ())
2102 else if (op1
.undefined_p ())
2104 else if (build_gt (r
, type
, op1
))
2114 class foperator_unordered_equal
: public range_operator
2116 using range_operator::fold_range
;
2117 using range_operator::op1_range
;
2118 using range_operator::op2_range
;
2120 bool fold_range (irange
&r
, tree type
,
2121 const frange
&op1
, const frange
&op2
,
2122 relation_trio trio
= TRIO_VARYING
) const final override
2124 relation_kind rel
= trio
.op1_op2 ();
2126 if (op1
.known_isnan () || op2
.known_isnan ()
2129 r
= range_true (type
);
2132 frange op1_no_nan
= op1
;
2133 frange op2_no_nan
= op2
;
2134 if (op1
.maybe_isnan ())
2135 op1_no_nan
.clear_nan ();
2136 if (op2
.maybe_isnan ())
2137 op2_no_nan
.clear_nan ();
2138 if (!range_op_handler (EQ_EXPR
).fold_range (r
, type
, op1_no_nan
,
2141 // The result is the same as the ordered version when the
2142 // comparison is true or when the operands cannot be NANs.
2143 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
2147 r
= range_true_and_false (type
);
2151 bool op1_range (frange
&r
, tree type
,
2152 const irange
&lhs
, const frange
&op2
,
2153 relation_trio
= TRIO_VARYING
) const final override
;
2154 bool op2_range (frange
&r
, tree type
,
2155 const irange
&lhs
, const frange
&op1
,
2156 relation_trio rel
= TRIO_VARYING
) const final override
2158 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
2160 } fop_unordered_equal
;
2163 foperator_unordered_equal::op1_range (frange
&r
, tree type
,
2166 relation_trio
) const
2168 switch (get_bool_state (r
, lhs
, type
))
2171 // If it's true, the result is the same as OP2 plus a NAN.
2173 // Add both zeros if there's the possibility of zero equality.
2174 frange_add_zeros (r
, type
);
2175 // Add the possibility of a NAN.
2180 // A false UNORDERED_EQ means both operands are !NAN, so it's
2181 // impossible for op2 to be a NAN.
2182 if (op2
.known_isnan ())
2186 // The false side indicates !NAN and not equal. We can at least
2188 r
.set_varying (type
);
2199 class foperator_ltgt
: public range_operator
2201 using range_operator::fold_range
;
2202 using range_operator::op1_range
;
2203 using range_operator::op2_range
;
2205 bool fold_range (irange
&r
, tree type
,
2206 const frange
&op1
, const frange
&op2
,
2207 relation_trio trio
= TRIO_VARYING
) const final override
2209 relation_kind rel
= trio
.op1_op2 ();
2211 // VREL_EQ is really VREL_(UN)EQ because we could have a NAN in
2212 // the operands, but since LTGT_EXPR is really a NE_EXPR without
2213 // the NAN, VREL_EQ & LTGT_EXPR is an impossibility.
2216 r
= range_false (type
);
2219 // ...otherwise pretend we're trying to resolve a NE_EXPR and
2220 // everything will "just work".
2221 if (frelop_early_resolve (r
, type
, op1
, op2
, trio
, VREL_NE
))
2224 if (op1
.known_isnan () || op2
.known_isnan ())
2226 r
= range_false (type
);
2229 frange op1_no_nan
= op1
;
2230 frange op2_no_nan
= op2
;
2231 if (op1
.maybe_isnan ())
2232 op1_no_nan
.clear_nan ();
2233 if (op2
.maybe_isnan ())
2234 op2_no_nan
.clear_nan ();
2235 if (!range_op_handler (NE_EXPR
).fold_range (r
, type
, op1_no_nan
,
2238 // The result is the same as the ordered version when the
2239 // comparison is true or when the operands cannot be NANs.
2240 if (!maybe_isnan (op1
, op2
) || r
== range_false (type
))
2244 r
= range_true_and_false (type
);
2248 bool op1_range (frange
&r
, tree type
,
2249 const irange
&lhs
, const frange
&op2
,
2250 relation_trio
= TRIO_VARYING
) const final override
;
2251 bool op2_range (frange
&r
, tree type
,
2252 const irange
&lhs
, const frange
&op1
,
2253 relation_trio rel
= TRIO_VARYING
) const final override
2255 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
2260 foperator_ltgt::op1_range (frange
&r
, tree type
,
2263 relation_trio
) const
2265 switch (get_bool_state (r
, lhs
, type
))
2268 // A true LTGT means both operands are !NAN, so it's
2269 // impossible for op2 to be a NAN.
2270 if (op2
.known_isnan ())
2274 // The true side indicates !NAN and not equal. We can at least
2276 r
.set_varying (type
);
2282 // If it's false, the result is the same as OP2 plus a NAN.
2284 // Add both zeros if there's the possibility of zero equality.
2285 frange_add_zeros (r
, type
);
2286 // Add the possibility of a NAN.
2296 // Final tweaks for float binary op op1_range/op2_range.
2297 // Return TRUE if the operation is performed and a valid range is available.
2300 float_binary_op_range_finish (bool ret
, frange
&r
, tree type
,
2301 const frange
&lhs
, bool div_op2
= false)
2306 // If we get a known NAN from reverse op, it means either that
2307 // the other operand was known NAN (in that case we know nothing),
2308 // or the reverse operation introduced a known NAN.
2309 // Say for lhs = op1 * op2 if lhs is [-0, +0] and op2 is too,
2310 // 0 / 0 is known NAN. Just punt in that case.
2311 // If NANs aren't honored, we get for 0 / 0 UNDEFINED, so punt as well.
2312 // Or if lhs is a known NAN, we also don't know anything.
2313 if (r
.known_isnan () || lhs
.known_isnan () || r
.undefined_p ())
2315 r
.set_varying (type
);
2319 // If lhs isn't NAN, then neither operand could be NAN,
2320 // even if the reverse operation does introduce a maybe_nan.
2321 if (!lhs
.maybe_isnan ())
2325 ? !(real_compare (LE_EXPR
, &lhs
.lower_bound (), &dconst0
)
2326 && real_compare (GE_EXPR
, &lhs
.upper_bound (), &dconst0
))
2327 : !(real_isinf (&lhs
.lower_bound ())
2328 || real_isinf (&lhs
.upper_bound ())))
2329 // For reverse + or - or * or op1 of /, if result is finite, then
2330 // r must be finite too, as X + INF or X - INF or X * INF or
2331 // INF / X is always +-INF or NAN. For op2 of /, if result is
2332 // non-zero and not NAN, r must be finite, as X / INF is always
2334 frange_drop_infs (r
, type
);
2336 // If lhs is a maybe or known NAN, the operand could be
2343 // True if [lb, ub] is [+-0, +-0].
2345 zero_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
2347 return real_iszero (&lb
) && real_iszero (&ub
);
2350 // True if +0 or -0 is in [lb, ub] range.
2352 contains_zero_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
2354 return (real_compare (LE_EXPR
, &lb
, &dconst0
)
2355 && real_compare (GE_EXPR
, &ub
, &dconst0
));
2358 // True if [lb, ub] is [-INF, -INF] or [+INF, +INF].
2360 singleton_inf_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
2362 return real_isinf (&lb
) && real_isinf (&ub
, real_isneg (&lb
));
2365 // Return -1 if binary op result must have sign bit set,
2366 // 1 if binary op result must have sign bit clear,
2368 // Sign bit of binary op result is exclusive or of the
2369 // operand's sign bits.
2371 signbit_known_p (const REAL_VALUE_TYPE
&lh_lb
, const REAL_VALUE_TYPE
&lh_ub
,
2372 const REAL_VALUE_TYPE
&rh_lb
, const REAL_VALUE_TYPE
&rh_ub
)
2374 if (real_isneg (&lh_lb
) == real_isneg (&lh_ub
)
2375 && real_isneg (&rh_lb
) == real_isneg (&rh_ub
))
2377 if (real_isneg (&lh_lb
) == real_isneg (&rh_ub
))
2385 // Set [lb, ub] to [-0, -0], [-0, +0] or [+0, +0] depending on
2388 zero_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
2391 if (signbit_known
<= 0)
2393 if (signbit_known
< 0)
2397 // Set [lb, ub] to [-INF, -INF], [-INF, +INF] or [+INF, +INF] depending on
2400 inf_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
2402 if (signbit_known
> 0)
2403 ub
= lb
= dconstinf
;
2404 else if (signbit_known
< 0)
2405 ub
= lb
= dconstninf
;
2413 // Set [lb, ub] to [-INF, -0], [-INF, +INF] or [+0, +INF] depending on
2416 zero_to_inf_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
2418 if (signbit_known
> 0)
2423 else if (signbit_known
< 0)
2435 /* Extend the LHS range by 1ulp in each direction. For op1_range
2436 or op2_range of binary operations just computing the inverse
2437 operation on ranges isn't sufficient. Consider e.g.
2438 [1., 1.] = op1 + [1., 1.]. op1's range is not [0., 0.], but
2439 [-0x1.0p-54, 0x1.0p-53] (when not -frounding-math), any value for
2440 which adding 1. to it results in 1. after rounding to nearest.
2441 So, for op1_range/op2_range extend the lhs range by 1ulp (or 0.5ulp)
2442 in each direction. See PR109008 for more details. */
2445 float_widen_lhs_range (tree type
, const frange
&lhs
)
2448 if (lhs
.known_isnan ())
2450 REAL_VALUE_TYPE lb
= lhs
.lower_bound ();
2451 REAL_VALUE_TYPE ub
= lhs
.upper_bound ();
2452 if (real_isfinite (&lb
))
2454 frange_nextafter (TYPE_MODE (type
), lb
, dconstninf
);
2455 if (real_isinf (&lb
))
2457 /* For -DBL_MAX, instead of -Inf use
2458 nexttoward (-DBL_MAX, -LDBL_MAX) in a hypothetical
2459 wider type with the same mantissa precision but larger
2460 exponent range; it is outside of range of double values,
2461 but makes it clear it is just one ulp larger rather than
2462 infinite amount larger. */
2464 SET_REAL_EXP (&lb
, FLOAT_MODE_FORMAT (TYPE_MODE (type
))->emax
+ 1);
2466 if (!flag_rounding_math
&& !MODE_COMPOSITE_P (TYPE_MODE (type
)))
2468 /* If not -frounding-math nor IBM double double, actually widen
2469 just by 0.5ulp rather than 1ulp. */
2470 REAL_VALUE_TYPE tem
;
2471 real_arithmetic (&tem
, PLUS_EXPR
, &lhs
.lower_bound (), &lb
);
2472 real_arithmetic (&lb
, RDIV_EXPR
, &tem
, &dconst2
);
2475 if (real_isfinite (&ub
))
2477 frange_nextafter (TYPE_MODE (type
), ub
, dconstinf
);
2478 if (real_isinf (&ub
))
2480 /* For DBL_MAX similarly. */
2482 SET_REAL_EXP (&ub
, FLOAT_MODE_FORMAT (TYPE_MODE (type
))->emax
+ 1);
2484 if (!flag_rounding_math
&& !MODE_COMPOSITE_P (TYPE_MODE (type
)))
2486 /* If not -frounding-math nor IBM double double, actually widen
2487 just by 0.5ulp rather than 1ulp. */
2488 REAL_VALUE_TYPE tem
;
2489 real_arithmetic (&tem
, PLUS_EXPR
, &lhs
.upper_bound (), &ub
);
2490 real_arithmetic (&ub
, RDIV_EXPR
, &tem
, &dconst2
);
2493 /* Temporarily disable -ffinite-math-only, so that frange::set doesn't
2494 reduce the range back to real_min_representable (type) as lower bound
2495 or real_max_representable (type) as upper bound. */
2496 bool save_flag_finite_math_only
= flag_finite_math_only
;
2497 flag_finite_math_only
= false;
2498 ret
.set (type
, lb
, ub
, lhs
.get_nan_state ());
2499 flag_finite_math_only
= save_flag_finite_math_only
;
2504 operator_plus::op1_range (frange
&r
, tree type
, const frange
&lhs
,
2505 const frange
&op2
, relation_trio
) const
2507 if (lhs
.undefined_p ())
2509 range_op_handler
minus (MINUS_EXPR
);
2512 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2513 return float_binary_op_range_finish (minus
.fold_range (r
, type
, wlhs
, op2
),
2518 operator_plus::op2_range (frange
&r
, tree type
,
2519 const frange
&lhs
, const frange
&op1
,
2520 relation_trio
) const
2522 return op1_range (r
, type
, lhs
, op1
);
2526 operator_plus::rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
,
2527 bool &maybe_nan
, tree type
,
2528 const REAL_VALUE_TYPE
&lh_lb
,
2529 const REAL_VALUE_TYPE
&lh_ub
,
2530 const REAL_VALUE_TYPE
&rh_lb
,
2531 const REAL_VALUE_TYPE
&rh_ub
,
2532 relation_kind
) const
2534 frange_arithmetic (PLUS_EXPR
, type
, lb
, lh_lb
, rh_lb
, dconstninf
);
2535 frange_arithmetic (PLUS_EXPR
, type
, ub
, lh_ub
, rh_ub
, dconstinf
);
2537 // [-INF] + [+INF] = NAN
2538 if (real_isinf (&lh_lb
, true) && real_isinf (&rh_ub
, false))
2540 // [+INF] + [-INF] = NAN
2541 else if (real_isinf (&lh_ub
, false) && real_isinf (&rh_lb
, true))
2549 operator_minus::op1_range (frange
&r
, tree type
,
2550 const frange
&lhs
, const frange
&op2
,
2551 relation_trio
) const
2553 if (lhs
.undefined_p ())
2555 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2556 return float_binary_op_range_finish (
2557 range_op_handler (PLUS_EXPR
).fold_range (r
, type
, wlhs
, op2
),
2562 operator_minus::op2_range (frange
&r
, tree type
,
2563 const frange
&lhs
, const frange
&op1
,
2564 relation_trio
) const
2566 if (lhs
.undefined_p ())
2568 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2569 return float_binary_op_range_finish (fold_range (r
, type
, op1
, wlhs
),
2574 operator_minus::rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
,
2575 bool &maybe_nan
, tree type
,
2576 const REAL_VALUE_TYPE
&lh_lb
,
2577 const REAL_VALUE_TYPE
&lh_ub
,
2578 const REAL_VALUE_TYPE
&rh_lb
,
2579 const REAL_VALUE_TYPE
&rh_ub
,
2580 relation_kind
) const
2582 frange_arithmetic (MINUS_EXPR
, type
, lb
, lh_lb
, rh_ub
, dconstninf
);
2583 frange_arithmetic (MINUS_EXPR
, type
, ub
, lh_ub
, rh_lb
, dconstinf
);
2585 // [+INF] - [+INF] = NAN
2586 if (real_isinf (&lh_ub
, false) && real_isinf (&rh_ub
, false))
2588 // [-INF] - [-INF] = NAN
2589 else if (real_isinf (&lh_lb
, true) && real_isinf (&rh_lb
, true))
2596 // Given CP[0] to CP[3] floating point values rounded to -INF,
2597 // set LB to the smallest of them (treating -0 as smaller to +0).
2598 // Given CP[4] to CP[7] floating point values rounded to +INF,
2599 // set UB to the largest of them (treating -0 as smaller to +0).
2602 find_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
,
2603 const REAL_VALUE_TYPE (&cp
)[8])
2607 for (int i
= 1; i
< 4; ++i
)
2609 if (real_less (&cp
[i
], &lb
)
2610 || (real_iszero (&lb
) && real_isnegzero (&cp
[i
])))
2612 if (real_less (&ub
, &cp
[i
+ 4])
2613 || (real_isnegzero (&ub
) && real_iszero (&cp
[i
+ 4])))
2620 operator_mult::op1_range (frange
&r
, tree type
,
2621 const frange
&lhs
, const frange
&op2
,
2622 relation_trio
) const
2624 if (lhs
.undefined_p ())
2626 range_op_handler
rdiv (RDIV_EXPR
);
2629 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2630 bool ret
= rdiv
.fold_range (r
, type
, wlhs
, op2
);
2633 if (wlhs
.known_isnan () || op2
.known_isnan () || op2
.undefined_p ())
2634 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2635 const REAL_VALUE_TYPE
&lhs_lb
= wlhs
.lower_bound ();
2636 const REAL_VALUE_TYPE
&lhs_ub
= wlhs
.upper_bound ();
2637 const REAL_VALUE_TYPE
&op2_lb
= op2
.lower_bound ();
2638 const REAL_VALUE_TYPE
&op2_ub
= op2
.upper_bound ();
2639 if ((contains_zero_p (lhs_lb
, lhs_ub
) && contains_zero_p (op2_lb
, op2_ub
))
2640 || ((real_isinf (&lhs_lb
) || real_isinf (&lhs_ub
))
2641 && (real_isinf (&op2_lb
) || real_isinf (&op2_ub
))))
2643 // If both lhs and op2 could be zeros or both could be infinities,
2644 // we don't know anything about op1 except maybe for the sign
2645 // and perhaps if it can be NAN or not.
2646 REAL_VALUE_TYPE lb
, ub
;
2647 int signbit_known
= signbit_known_p (lhs_lb
, lhs_ub
, op2_lb
, op2_ub
);
2648 zero_to_inf_range (lb
, ub
, signbit_known
);
2649 r
.set (type
, lb
, ub
);
2651 // Otherwise, if op2 is a singleton INF and lhs doesn't include INF,
2652 // or if lhs must be zero and op2 doesn't include zero, it would be
2653 // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF
2654 // range. Those are supersets of UNDEFINED, so let's keep that way.
2655 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2659 operator_mult::op2_range (frange
&r
, tree type
,
2660 const frange
&lhs
, const frange
&op1
,
2661 relation_trio
) const
2663 return op1_range (r
, type
, lhs
, op1
);
2667 operator_mult::rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
,
2668 bool &maybe_nan
, tree type
,
2669 const REAL_VALUE_TYPE
&lh_lb
,
2670 const REAL_VALUE_TYPE
&lh_ub
,
2671 const REAL_VALUE_TYPE
&rh_lb
,
2672 const REAL_VALUE_TYPE
&rh_ub
,
2673 relation_kind kind
) const
2677 && real_equal (&lh_lb
, &rh_lb
)
2678 && real_equal (&lh_ub
, &rh_ub
)
2679 && real_isneg (&lh_lb
) == real_isneg (&rh_lb
)
2680 && real_isneg (&lh_ub
) == real_isneg (&rh_ub
));
2683 // x * x never produces a new NAN and we only multiply the same
2684 // values, so the 0 * INF problematic cases never appear there.
2687 // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN.
2688 if ((zero_p (lh_lb
, lh_ub
) && singleton_inf_p (rh_lb
, rh_ub
))
2689 || (zero_p (rh_lb
, rh_ub
) && singleton_inf_p (lh_lb
, lh_ub
)))
2691 real_nan (&lb
, "", 0, TYPE_MODE (type
));
2697 // Otherwise, if one range includes zero and the other ends with +-INF,
2698 // it is a maybe NAN.
2699 if ((contains_zero_p (lh_lb
, lh_ub
)
2700 && (real_isinf (&rh_lb
) || real_isinf (&rh_ub
)))
2701 || (contains_zero_p (rh_lb
, rh_ub
)
2702 && (real_isinf (&lh_lb
) || real_isinf (&lh_ub
))))
2706 int signbit_known
= signbit_known_p (lh_lb
, lh_ub
, rh_lb
, rh_ub
);
2708 // If one of the ranges that includes INF is singleton
2709 // and the other range includes zero, the resulting
2710 // range is INF and NAN, because the 0 * INF boundary
2711 // case will be NAN, but already nextafter (0, 1) * INF
2713 if (singleton_inf_p (lh_lb
, lh_ub
)
2714 || singleton_inf_p (rh_lb
, rh_ub
))
2715 return inf_range (lb
, ub
, signbit_known
);
2717 // If one of the multiplicands must be zero, the resulting
2718 // range is +-0 and NAN.
2719 if (zero_p (lh_lb
, lh_ub
) || zero_p (rh_lb
, rh_ub
))
2720 return zero_range (lb
, ub
, signbit_known
);
2722 // Otherwise one of the multiplicands could be
2723 // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF]
2724 // or similarly with different signs. 0.0 * DBL_MAX
2725 // is still 0.0, nextafter (0.0, 1.0) * INF is still INF,
2726 // so if the signs are always the same or always different,
2727 // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING.
2728 return zero_to_inf_range (lb
, ub
, signbit_known
);
2732 REAL_VALUE_TYPE cp
[8];
2733 // Do a cross-product. At this point none of the multiplications
2734 // should produce a NAN.
2735 frange_arithmetic (MULT_EXPR
, type
, cp
[0], lh_lb
, rh_lb
, dconstninf
);
2736 frange_arithmetic (MULT_EXPR
, type
, cp
[4], lh_lb
, rh_lb
, dconstinf
);
2739 // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub)
2740 // as maximum and -0.0 as minimum if 0.0 is in the range,
2741 // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub).
2742 // -0.0 rather than 0.0 because VREL_EQ doesn't prove that
2743 // x and y are bitwise equal, just that they compare equal.
2744 if (contains_zero_p (lh_lb
, lh_ub
))
2746 if (real_isneg (&lh_lb
) == real_isneg (&lh_ub
))
2759 frange_arithmetic (MULT_EXPR
, type
, cp
[1], lh_lb
, rh_ub
, dconstninf
);
2760 frange_arithmetic (MULT_EXPR
, type
, cp
[5], lh_lb
, rh_ub
, dconstinf
);
2761 frange_arithmetic (MULT_EXPR
, type
, cp
[2], lh_ub
, rh_lb
, dconstninf
);
2762 frange_arithmetic (MULT_EXPR
, type
, cp
[6], lh_ub
, rh_lb
, dconstinf
);
2764 frange_arithmetic (MULT_EXPR
, type
, cp
[3], lh_ub
, rh_ub
, dconstninf
);
2765 frange_arithmetic (MULT_EXPR
, type
, cp
[7], lh_ub
, rh_ub
, dconstinf
);
2767 find_range (lb
, ub
, cp
);
2771 class foperator_div
: public range_operator
2773 using range_operator::op1_range
;
2774 using range_operator::op2_range
;
2776 virtual bool op1_range (frange
&r
, tree type
,
2779 relation_trio
= TRIO_VARYING
) const final override
2781 if (lhs
.undefined_p ())
2783 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2784 bool ret
= range_op_handler (MULT_EXPR
).fold_range (r
, type
, wlhs
, op2
);
2787 if (wlhs
.known_isnan () || op2
.known_isnan () || op2
.undefined_p ())
2788 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2789 const REAL_VALUE_TYPE
&lhs_lb
= wlhs
.lower_bound ();
2790 const REAL_VALUE_TYPE
&lhs_ub
= wlhs
.upper_bound ();
2791 const REAL_VALUE_TYPE
&op2_lb
= op2
.lower_bound ();
2792 const REAL_VALUE_TYPE
&op2_ub
= op2
.upper_bound ();
2793 if ((contains_zero_p (lhs_lb
, lhs_ub
)
2794 && (real_isinf (&op2_lb
) || real_isinf (&op2_ub
)))
2795 || ((contains_zero_p (op2_lb
, op2_ub
))
2796 && (real_isinf (&lhs_lb
) || real_isinf (&lhs_ub
))))
2798 // If both lhs could be zero and op2 infinity or vice versa,
2799 // we don't know anything about op1 except maybe for the sign
2800 // and perhaps if it can be NAN or not.
2801 REAL_VALUE_TYPE lb
, ub
;
2802 int signbit_known
= signbit_known_p (lhs_lb
, lhs_ub
, op2_lb
, op2_ub
);
2803 zero_to_inf_range (lb
, ub
, signbit_known
);
2804 r
.set (type
, lb
, ub
);
2806 return float_binary_op_range_finish (ret
, r
, type
, wlhs
);
2808 virtual bool op2_range (frange
&r
, tree type
,
2811 relation_trio
= TRIO_VARYING
) const final override
2813 if (lhs
.undefined_p ())
2815 frange wlhs
= float_widen_lhs_range (type
, lhs
);
2816 bool ret
= fold_range (r
, type
, op1
, wlhs
);
2819 if (wlhs
.known_isnan () || op1
.known_isnan () || op1
.undefined_p ())
2820 return float_binary_op_range_finish (ret
, r
, type
, wlhs
, true);
2821 const REAL_VALUE_TYPE
&lhs_lb
= wlhs
.lower_bound ();
2822 const REAL_VALUE_TYPE
&lhs_ub
= wlhs
.upper_bound ();
2823 const REAL_VALUE_TYPE
&op1_lb
= op1
.lower_bound ();
2824 const REAL_VALUE_TYPE
&op1_ub
= op1
.upper_bound ();
2825 if ((contains_zero_p (lhs_lb
, lhs_ub
) && contains_zero_p (op1_lb
, op1_ub
))
2826 || ((real_isinf (&lhs_lb
) || real_isinf (&lhs_ub
))
2827 && (real_isinf (&op1_lb
) || real_isinf (&op1_ub
))))
2829 // If both lhs and op1 could be zeros or both could be infinities,
2830 // we don't know anything about op2 except maybe for the sign
2831 // and perhaps if it can be NAN or not.
2832 REAL_VALUE_TYPE lb
, ub
;
2833 int signbit_known
= signbit_known_p (lhs_lb
, lhs_ub
, op1_lb
, op1_ub
);
2834 zero_to_inf_range (lb
, ub
, signbit_known
);
2835 r
.set (type
, lb
, ub
);
2837 return float_binary_op_range_finish (ret
, r
, type
, wlhs
, true);
2840 void rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, bool &maybe_nan
,
2842 const REAL_VALUE_TYPE
&lh_lb
,
2843 const REAL_VALUE_TYPE
&lh_ub
,
2844 const REAL_VALUE_TYPE
&rh_lb
,
2845 const REAL_VALUE_TYPE
&rh_ub
,
2846 relation_kind
) const final override
2848 // +-0.0 / +-0.0 or +-INF / +-INF is a known NAN.
2849 if ((zero_p (lh_lb
, lh_ub
) && zero_p (rh_lb
, rh_ub
))
2850 || (singleton_inf_p (lh_lb
, lh_ub
) && singleton_inf_p (rh_lb
, rh_ub
)))
2852 real_nan (&lb
, "", 0, TYPE_MODE (type
));
2858 // If +-0.0 is in both ranges, it is a maybe NAN.
2859 if (contains_zero_p (lh_lb
, lh_ub
) && contains_zero_p (rh_lb
, rh_ub
))
2861 // If +-INF is in both ranges, it is a maybe NAN.
2862 else if ((real_isinf (&lh_lb
) || real_isinf (&lh_ub
))
2863 && (real_isinf (&rh_lb
) || real_isinf (&rh_ub
)))
2868 int signbit_known
= signbit_known_p (lh_lb
, lh_ub
, rh_lb
, rh_ub
);
2870 // If dividend must be zero, the range is just +-0
2871 // (including if the divisor is +-INF).
2872 // If divisor must be +-INF, the range is just +-0
2873 // (including if the dividend is zero).
2874 if (zero_p (lh_lb
, lh_ub
) || singleton_inf_p (rh_lb
, rh_ub
))
2875 return zero_range (lb
, ub
, signbit_known
);
2877 // If divisor must be zero, the range is just +-INF
2878 // (including if the dividend is +-INF).
2879 // If dividend must be +-INF, the range is just +-INF
2880 // (including if the dividend is zero).
2881 if (zero_p (rh_lb
, rh_ub
) || singleton_inf_p (lh_lb
, lh_ub
))
2882 return inf_range (lb
, ub
, signbit_known
);
2884 // Otherwise if both operands may be zero, divisor could be
2885 // nextafter(0.0, +-1.0) and dividend +-0.0
2886 // in which case result is going to INF or vice versa and
2887 // result +0.0. So, all we can say for that case is if the
2888 // signs of divisor and dividend are always the same we have
2889 // [+0.0, +INF], if they are always different we have
2890 // [-INF, -0.0]. If they vary, VARYING.
2891 // If both may be +-INF, divisor could be INF and dividend FLT_MAX,
2892 // in which case result is going to INF or vice versa and
2893 // result +0.0. So, all we can say for that case is if the
2894 // signs of divisor and dividend are always the same we have
2895 // [+0.0, +INF], if they are always different we have
2896 // [-INF, -0.0]. If they vary, VARYING.
2898 return zero_to_inf_range (lb
, ub
, signbit_known
);
2900 REAL_VALUE_TYPE cp
[8];
2901 // Do a cross-division. At this point none of the divisions should
2903 frange_arithmetic (RDIV_EXPR
, type
, cp
[0], lh_lb
, rh_lb
, dconstninf
);
2904 frange_arithmetic (RDIV_EXPR
, type
, cp
[1], lh_lb
, rh_ub
, dconstninf
);
2905 frange_arithmetic (RDIV_EXPR
, type
, cp
[2], lh_ub
, rh_lb
, dconstninf
);
2906 frange_arithmetic (RDIV_EXPR
, type
, cp
[3], lh_ub
, rh_ub
, dconstninf
);
2907 frange_arithmetic (RDIV_EXPR
, type
, cp
[4], lh_lb
, rh_lb
, dconstinf
);
2908 frange_arithmetic (RDIV_EXPR
, type
, cp
[5], lh_lb
, rh_ub
, dconstinf
);
2909 frange_arithmetic (RDIV_EXPR
, type
, cp
[6], lh_ub
, rh_lb
, dconstinf
);
2910 frange_arithmetic (RDIV_EXPR
, type
, cp
[7], lh_ub
, rh_ub
, dconstinf
);
2912 find_range (lb
, ub
, cp
);
2914 // If divisor may be zero (but is not known to be only zero),
2915 // and dividend can't be zero, the range can go up to -INF or +INF
2916 // depending on the signs.
2917 if (contains_zero_p (rh_lb
, rh_ub
))
2919 if (signbit_known
<= 0)
2920 real_inf (&lb
, true);
2921 if (signbit_known
>= 0)
2922 real_inf (&ub
, false);
2928 // Initialize any float operators to the primary table
2931 range_op_table::initialize_float_ops ()
2933 set (UNLE_EXPR
, fop_unordered_le
);
2934 set (UNLT_EXPR
, fop_unordered_lt
);
2935 set (UNGE_EXPR
, fop_unordered_ge
);
2936 set (UNGT_EXPR
, fop_unordered_gt
);
2937 set (UNEQ_EXPR
, fop_unordered_equal
);
2938 set (ORDERED_EXPR
, fop_ordered
);
2939 set (UNORDERED_EXPR
, fop_unordered
);
2940 set (LTGT_EXPR
, fop_ltgt
);
2941 set (RDIV_EXPR
, fop_div
);
2945 #include "selftest.h"
2950 // Build an frange from string endpoints.
2952 static inline frange
2953 frange_float (const char *lb
, const char *ub
, tree type
= float_type_node
)
2955 REAL_VALUE_TYPE min
, max
;
2956 gcc_assert (real_from_string (&min
, lb
) == 0);
2957 gcc_assert (real_from_string (&max
, ub
) == 0);
2958 return frange (type
, min
, max
);
2962 range_op_float_tests ()
2965 frange
trange (float_type_node
);
2967 // negate([-5, +10]) => [-10, 5]
2968 r0
= frange_float ("-5", "10");
2969 range_op_handler (NEGATE_EXPR
).fold_range (r
, float_type_node
, r0
, trange
);
2970 ASSERT_EQ (r
, frange_float ("-10", "5"));
2972 // negate([0, 1] -NAN) => [-1, -0] +NAN
2973 r0
= frange_float ("0", "1");
2974 r0
.update_nan (true);
2975 range_op_handler (NEGATE_EXPR
).fold_range (r
, float_type_node
, r0
, trange
);
2976 r1
= frange_float ("-1", "-0");
2977 r1
.update_nan (false);
2980 // [-INF,+INF] + [-INF,+INF] could be a NAN.
2981 range_op_handler
plus (PLUS_EXPR
);
2982 r0
.set_varying (float_type_node
);
2983 r1
.set_varying (float_type_node
);
2986 plus
.fold_range (r
, float_type_node
, r0
, r1
);
2987 if (HONOR_NANS (float_type_node
))
2988 ASSERT_TRUE (r
.maybe_isnan ());
2991 } // namespace selftest
2993 #endif // CHECKING_P