1 /* Floating point range operators.
2 Copyright (C) 2022 Free Software Foundation, Inc.
3 Contributed by Aldy Hernandez <aldyh@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
25 #include "insn-codes.h"
30 #include "tree-pass.h"
32 #include "optabs-tree.h"
33 #include "gimple-pretty-print.h"
34 #include "diagnostic-core.h"
36 #include "fold-const.h"
37 #include "stor-layout.h"
40 #include "gimple-iterator.h"
41 #include "gimple-fold.h"
43 #include "gimple-walk.h"
46 #include "value-relation.h"
49 // Default definitions for floating point operators.
52 range_operator_float::fold_range (frange
&r
, tree type
,
53 const frange
&op1
, const frange
&op2
,
54 relation_trio trio
) const
56 if (empty_range_varying (r
, type
, op1
, op2
))
58 if (op1
.known_isnan () || op2
.known_isnan ())
60 r
.set_nan (op1
.type ());
64 REAL_VALUE_TYPE lb
, ub
;
66 rv_fold (lb
, ub
, maybe_nan
, type
,
67 op1
.lower_bound (), op1
.upper_bound (),
68 op2
.lower_bound (), op2
.upper_bound (), trio
.op1_op2 ());
70 // Handle possible NANs by saturating to the appropriate INF if only
71 // one end is a NAN. If both ends are a NAN, just return a NAN.
72 bool lb_nan
= real_isnan (&lb
);
73 bool ub_nan
= real_isnan (&ub
);
86 if (lb_nan
|| ub_nan
|| maybe_nan
88 || op2
.maybe_isnan ())
89 // Keep the default NAN (with a varying sign) set by the setter.
97 // For a given operation, fold two sets of ranges into [lb, ub].
98 // MAYBE_NAN is set to TRUE if, in addition to any result in LB or
99 // UB, the final range has the possiblity of a NAN.
101 range_operator_float::rv_fold (REAL_VALUE_TYPE
&lb
,
104 tree type ATTRIBUTE_UNUSED
,
105 const REAL_VALUE_TYPE
&lh_lb ATTRIBUTE_UNUSED
,
106 const REAL_VALUE_TYPE
&lh_ub ATTRIBUTE_UNUSED
,
107 const REAL_VALUE_TYPE
&rh_lb ATTRIBUTE_UNUSED
,
108 const REAL_VALUE_TYPE
&rh_ub ATTRIBUTE_UNUSED
,
117 range_operator_float::fold_range (irange
&r ATTRIBUTE_UNUSED
,
118 tree type ATTRIBUTE_UNUSED
,
119 const frange
&lh ATTRIBUTE_UNUSED
,
120 const irange
&rh ATTRIBUTE_UNUSED
,
127 range_operator_float::fold_range (irange
&r ATTRIBUTE_UNUSED
,
128 tree type ATTRIBUTE_UNUSED
,
129 const frange
&lh ATTRIBUTE_UNUSED
,
130 const frange
&rh ATTRIBUTE_UNUSED
,
137 range_operator_float::op1_range (frange
&r ATTRIBUTE_UNUSED
,
138 tree type ATTRIBUTE_UNUSED
,
139 const frange
&lhs ATTRIBUTE_UNUSED
,
140 const frange
&op2 ATTRIBUTE_UNUSED
,
147 range_operator_float::op1_range (frange
&r ATTRIBUTE_UNUSED
,
148 tree type ATTRIBUTE_UNUSED
,
149 const irange
&lhs ATTRIBUTE_UNUSED
,
150 const frange
&op2 ATTRIBUTE_UNUSED
,
157 range_operator_float::op2_range (frange
&r ATTRIBUTE_UNUSED
,
158 tree type ATTRIBUTE_UNUSED
,
159 const frange
&lhs ATTRIBUTE_UNUSED
,
160 const frange
&op1 ATTRIBUTE_UNUSED
,
167 range_operator_float::op2_range (frange
&r ATTRIBUTE_UNUSED
,
168 tree type ATTRIBUTE_UNUSED
,
169 const irange
&lhs ATTRIBUTE_UNUSED
,
170 const frange
&op1 ATTRIBUTE_UNUSED
,
177 range_operator_float::lhs_op1_relation (const frange
&lhs ATTRIBUTE_UNUSED
,
178 const frange
&op1 ATTRIBUTE_UNUSED
,
179 const frange
&op2 ATTRIBUTE_UNUSED
,
186 range_operator_float::lhs_op1_relation (const irange
&lhs ATTRIBUTE_UNUSED
,
187 const frange
&op1 ATTRIBUTE_UNUSED
,
188 const frange
&op2 ATTRIBUTE_UNUSED
,
195 range_operator_float::lhs_op2_relation (const irange
&lhs ATTRIBUTE_UNUSED
,
196 const frange
&op1 ATTRIBUTE_UNUSED
,
197 const frange
&op2 ATTRIBUTE_UNUSED
,
204 range_operator_float::lhs_op2_relation (const frange
&lhs ATTRIBUTE_UNUSED
,
205 const frange
&op1 ATTRIBUTE_UNUSED
,
206 const frange
&op2 ATTRIBUTE_UNUSED
,
213 range_operator_float::op1_op2_relation (const irange
&lhs ATTRIBUTE_UNUSED
) const
219 range_operator_float::op1_op2_relation (const frange
&lhs ATTRIBUTE_UNUSED
) const
224 // Return TRUE if OP1 and OP2 may be a NAN.
227 maybe_isnan (const frange
&op1
, const frange
&op2
)
229 return op1
.maybe_isnan () || op2
.maybe_isnan ();
232 // Floating version of relop_early_resolve that takes into account NAN
233 // and -ffinite-math-only.
236 frelop_early_resolve (irange
&r
, tree type
,
237 const frange
&op1
, const frange
&op2
,
238 relation_trio rel
, relation_kind my_rel
)
240 // If either operand is undefined, return VARYING.
241 if (empty_range_varying (r
, type
, op1
, op2
))
244 // We can fold relations from the oracle when we know both operands
245 // are free of NANs, or when -ffinite-math-only.
246 return (!maybe_isnan (op1
, op2
)
247 && relop_early_resolve (r
, type
, op1
, op2
, rel
, my_rel
));
250 // Set VALUE to its next real value, or INF if the operation overflows.
253 frange_nextafter (enum machine_mode mode
,
254 REAL_VALUE_TYPE
&value
,
255 const REAL_VALUE_TYPE
&inf
)
257 const real_format
*fmt
= REAL_MODE_FORMAT (mode
);
259 real_nextafter (&tmp
, fmt
, &value
, &inf
);
263 // Like real_arithmetic, but round the result to INF if the operation
264 // produced inexact results.
266 // ?? There is still one problematic case, i387. With
267 // -fexcess-precision=standard we perform most SF/DFmode arithmetic in
268 // XFmode (long_double_type_node), so that case is OK. But without
269 // -mfpmath=sse, all the SF/DFmode computations are in XFmode
270 // precision (64-bit mantissa) and only occassionally rounded to
271 // SF/DFmode (when storing into memory from the 387 stack). Maybe
272 // this is ok as well though it is just occassionally more precise. ??
275 frange_arithmetic (enum tree_code code
, tree type
,
276 REAL_VALUE_TYPE
&result
,
277 const REAL_VALUE_TYPE
&op1
,
278 const REAL_VALUE_TYPE
&op2
,
279 const REAL_VALUE_TYPE
&inf
)
281 REAL_VALUE_TYPE value
;
282 enum machine_mode mode
= TYPE_MODE (type
);
283 bool mode_composite
= MODE_COMPOSITE_P (mode
);
285 bool inexact
= real_arithmetic (&value
, code
, &op1
, &op2
);
286 real_convert (&result
, mode
, &value
);
288 // Be extra careful if there may be discrepancies between the
289 // compile and runtime results.
290 if ((mode_composite
|| (real_isneg (&inf
) ? real_less (&result
, &value
)
291 : !real_less (&value
, &result
)))
292 && (inexact
|| !real_identical (&result
, &value
)))
296 if (real_isdenormal (&result
, mode
)
297 || real_iszero (&result
))
299 // IBM extended denormals only have DFmode precision.
301 real_convert (&tmp
, DFmode
, &value
);
302 frange_nextafter (DFmode
, tmp
, inf
);
303 real_convert (&result
, mode
, &tmp
);
307 frange_nextafter (mode
, result
, inf
);
311 // Crop R to [-INF, MAX] where MAX is the maximum representable number
315 frange_drop_inf (frange
&r
, tree type
)
317 REAL_VALUE_TYPE max
= real_max_representable (type
);
318 frange
tmp (type
, r
.lower_bound (), max
);
322 // Crop R to [MIN, +INF] where MIN is the minimum representable number
326 frange_drop_ninf (frange
&r
, tree type
)
328 REAL_VALUE_TYPE min
= real_min_representable (type
);
329 frange
tmp (type
, min
, r
.upper_bound ());
333 // If zero is in R, make sure both -0.0 and +0.0 are in the range.
336 frange_add_zeros (frange
&r
, tree type
)
338 if (r
.undefined_p () || r
.known_isnan ())
341 if (HONOR_SIGNED_ZEROS (type
)
342 && (real_iszero (&r
.lower_bound ()) || real_iszero (&r
.upper_bound ())))
345 zero
.set_zero (type
);
350 // Build a range that is <= VAL and store it in R. Return TRUE if
351 // further changes may be needed for R, or FALSE if R is in its final
355 build_le (frange
&r
, tree type
, const frange
&val
)
357 gcc_checking_assert (!val
.known_isnan ());
359 REAL_VALUE_TYPE ninf
= frange_val_min (type
);
360 r
.set (type
, ninf
, val
.upper_bound ());
362 // Add both zeros if there's the possibility of zero equality.
363 frange_add_zeros (r
, type
);
368 // Build a range that is < VAL and store it in R. Return TRUE if
369 // further changes may be needed for R, or FALSE if R is in its final
373 build_lt (frange
&r
, tree type
, const frange
&val
)
375 gcc_checking_assert (!val
.known_isnan ());
377 // < -INF is outside the range.
378 if (real_isinf (&val
.upper_bound (), 1))
380 if (HONOR_NANS (type
))
387 REAL_VALUE_TYPE ninf
= frange_val_min (type
);
388 REAL_VALUE_TYPE prev
= val
.upper_bound ();
389 machine_mode mode
= TYPE_MODE (type
);
390 // Default to the conservatively correct closed ranges for
391 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
392 // !HONOR_INFINITIES, nextafter will yield -INF, but frange::set()
393 // will crop the range appropriately.
394 if (!MODE_COMPOSITE_P (mode
))
395 frange_nextafter (mode
, prev
, ninf
);
396 r
.set (type
, ninf
, prev
);
400 // Build a range that is >= VAL and store it in R. Return TRUE if
401 // further changes may be needed for R, or FALSE if R is in its final
405 build_ge (frange
&r
, tree type
, const frange
&val
)
407 gcc_checking_assert (!val
.known_isnan ());
409 REAL_VALUE_TYPE inf
= frange_val_max (type
);
410 r
.set (type
, val
.lower_bound (), inf
);
412 // Add both zeros if there's the possibility of zero equality.
413 frange_add_zeros (r
, type
);
418 // Build a range that is > VAL and store it in R. Return TRUE if
419 // further changes may be needed for R, or FALSE if R is in its final
423 build_gt (frange
&r
, tree type
, const frange
&val
)
425 gcc_checking_assert (!val
.known_isnan ());
427 // > +INF is outside the range.
428 if (real_isinf (&val
.lower_bound (), 0))
430 if (HONOR_NANS (type
))
437 REAL_VALUE_TYPE inf
= frange_val_max (type
);
438 REAL_VALUE_TYPE next
= val
.lower_bound ();
439 machine_mode mode
= TYPE_MODE (type
);
440 // Default to the conservatively correct closed ranges for
441 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
442 // !HONOR_INFINITIES, nextafter will yield +INF, but frange::set()
443 // will crop the range appropriately.
444 if (!MODE_COMPOSITE_P (mode
))
445 frange_nextafter (mode
, next
, inf
);
446 r
.set (type
, next
, inf
);
451 class foperator_identity
: public range_operator_float
453 using range_operator_float::fold_range
;
454 using range_operator_float::op1_range
;
456 bool fold_range (frange
&r
, tree type ATTRIBUTE_UNUSED
,
457 const frange
&op1
, const frange
&op2 ATTRIBUTE_UNUSED
,
458 relation_trio
= TRIO_VARYING
) const final override
463 bool op1_range (frange
&r
, tree type ATTRIBUTE_UNUSED
,
464 const frange
&lhs
, const frange
&op2 ATTRIBUTE_UNUSED
,
465 relation_trio
= TRIO_VARYING
) const final override
473 class foperator_equal
: public range_operator_float
475 using range_operator_float::fold_range
;
476 using range_operator_float::op1_range
;
477 using range_operator_float::op2_range
;
478 using range_operator_float::op1_op2_relation
;
480 bool fold_range (irange
&r
, tree type
,
481 const frange
&op1
, const frange
&op2
,
482 relation_trio
= TRIO_VARYING
) const final override
;
483 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
485 return equal_op1_op2_relation (lhs
);
487 bool op1_range (frange
&r
, tree type
,
488 const irange
&lhs
, const frange
&op2
,
489 relation_trio
= TRIO_VARYING
) const final override
;
490 bool op2_range (frange
&r
, tree type
,
491 const irange
&lhs
, const frange
&op1
,
492 relation_trio rel
= TRIO_VARYING
) const final override
494 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
499 foperator_equal::fold_range (irange
&r
, tree type
,
500 const frange
&op1
, const frange
&op2
,
501 relation_trio rel
) const
503 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_EQ
))
506 if (op1
.known_isnan () || op2
.known_isnan ())
507 r
= range_false (type
);
508 // We can be sure the values are always equal or not if both ranges
509 // consist of a single value, and then compare them.
510 else if (op1
.singleton_p () && op2
.singleton_p ())
513 r
= range_true (type
);
515 r
= range_false (type
);
517 else if (!maybe_isnan (op1
, op2
))
519 // If ranges do not intersect, we know the range is not equal,
520 // otherwise we don't know anything for sure.
523 if (tmp
.undefined_p ())
524 r
= range_false (type
);
526 r
= range_true_and_false (type
);
529 r
= range_true_and_false (type
);
534 foperator_equal::op1_range (frange
&r
, tree type
,
537 relation_trio trio
) const
539 relation_kind rel
= trio
.op1_op2 ();
540 switch (get_bool_state (r
, lhs
, type
))
543 // The TRUE side of x == NAN is unreachable.
544 if (op2
.known_isnan ())
548 // If it's true, the result is the same as OP2.
550 // Add both zeros if there's the possibility of zero equality.
551 frange_add_zeros (r
, type
);
552 // The TRUE side of op1 == op2 implies op1 is !NAN.
558 // The FALSE side of op1 == op1 implies op1 is a NAN.
561 // On the FALSE side of x == NAN, we know nothing about x.
562 else if (op2
.known_isnan ())
563 r
.set_varying (type
);
564 // If the result is false, the only time we know anything is
565 // if OP2 is a constant.
566 else if (op2
.singleton_p ()
567 || (!op2
.maybe_isnan () && op2
.zero_p ()))
569 REAL_VALUE_TYPE tmp
= op2
.lower_bound ();
570 r
.set (type
, tmp
, tmp
, VR_ANTI_RANGE
);
573 r
.set_varying (type
);
582 class foperator_not_equal
: public range_operator_float
584 using range_operator_float::fold_range
;
585 using range_operator_float::op1_range
;
586 using range_operator_float::op1_op2_relation
;
588 bool fold_range (irange
&r
, tree type
,
589 const frange
&op1
, const frange
&op2
,
590 relation_trio rel
= TRIO_VARYING
) const final override
;
591 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
593 return not_equal_op1_op2_relation (lhs
);
595 bool op1_range (frange
&r
, tree type
,
596 const irange
&lhs
, const frange
&op2
,
597 relation_trio
= TRIO_VARYING
) const final override
;
601 foperator_not_equal::fold_range (irange
&r
, tree type
,
602 const frange
&op1
, const frange
&op2
,
603 relation_trio rel
) const
605 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_NE
))
608 // x != NAN is always TRUE.
609 if (op1
.known_isnan () || op2
.known_isnan ())
610 r
= range_true (type
);
611 // We can be sure the values are always equal or not if both ranges
612 // consist of a single value, and then compare them.
613 else if (op1
.singleton_p () && op2
.singleton_p ())
616 r
= range_true (type
);
618 r
= range_false (type
);
620 else if (!maybe_isnan (op1
, op2
))
622 // If ranges do not intersect, we know the range is not equal,
623 // otherwise we don't know anything for sure.
626 if (tmp
.undefined_p ())
627 r
= range_true (type
);
629 r
= range_true_and_false (type
);
632 r
= range_true_and_false (type
);
637 foperator_not_equal::op1_range (frange
&r
, tree type
,
640 relation_trio trio
) const
642 relation_kind rel
= trio
.op1_op2 ();
643 switch (get_bool_state (r
, lhs
, type
))
646 // If the result is true, the only time we know anything is if
647 // OP2 is a constant.
648 if (op2
.singleton_p ())
650 // This is correct even if op1 is NAN, because the following
651 // range would be ~[tmp, tmp] with the NAN property set to
653 REAL_VALUE_TYPE tmp
= op2
.lower_bound ();
654 r
.set (type
, tmp
, tmp
, VR_ANTI_RANGE
);
656 // The TRUE side of op1 != op1 implies op1 is NAN.
657 else if (rel
== VREL_EQ
)
660 r
.set_varying (type
);
664 // The FALSE side of x != NAN is impossible.
665 if (op2
.known_isnan ())
669 // If it's false, the result is the same as OP2.
671 // Add both zeros if there's the possibility of zero equality.
672 frange_add_zeros (r
, type
);
673 // The FALSE side of op1 != op2 implies op1 is !NAN.
684 class foperator_lt
: public range_operator_float
686 using range_operator_float::fold_range
;
687 using range_operator_float::op1_range
;
688 using range_operator_float::op2_range
;
689 using range_operator_float::op1_op2_relation
;
691 bool fold_range (irange
&r
, tree type
,
692 const frange
&op1
, const frange
&op2
,
693 relation_trio
= TRIO_VARYING
) const final override
;
694 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
696 return lt_op1_op2_relation (lhs
);
698 bool op1_range (frange
&r
, tree type
,
699 const irange
&lhs
, const frange
&op2
,
700 relation_trio
= TRIO_VARYING
) const final override
;
701 bool op2_range (frange
&r
, tree type
,
702 const irange
&lhs
, const frange
&op1
,
703 relation_trio
= TRIO_VARYING
) const final override
;
707 foperator_lt::fold_range (irange
&r
, tree type
,
708 const frange
&op1
, const frange
&op2
,
709 relation_trio rel
) const
711 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_LT
))
714 if (op1
.known_isnan () || op2
.known_isnan ())
715 r
= range_false (type
);
716 else if (!maybe_isnan (op1
, op2
))
718 if (real_less (&op1
.upper_bound (), &op2
.lower_bound ()))
719 r
= range_true (type
);
720 else if (!real_less (&op1
.lower_bound (), &op2
.upper_bound ()))
721 r
= range_false (type
);
723 r
= range_true_and_false (type
);
726 r
= range_true_and_false (type
);
731 foperator_lt::op1_range (frange
&r
,
737 switch (get_bool_state (r
, lhs
, type
))
740 // The TRUE side of x < NAN is unreachable.
741 if (op2
.known_isnan ())
743 else if (build_lt (r
, type
, op2
))
746 // x < y implies x is not +INF.
747 frange_drop_inf (r
, type
);
752 // On the FALSE side of x < NAN, we know nothing about x.
753 if (op2
.known_isnan ())
754 r
.set_varying (type
);
756 build_ge (r
, type
, op2
);
766 foperator_lt::op2_range (frange
&r
,
772 switch (get_bool_state (r
, lhs
, type
))
775 // The TRUE side of NAN < x is unreachable.
776 if (op1
.known_isnan ())
778 else if (build_gt (r
, type
, op1
))
781 // x < y implies y is not -INF.
782 frange_drop_ninf (r
, type
);
787 // On the FALSE side of NAN < x, we know nothing about x.
788 if (op1
.known_isnan ())
789 r
.set_varying (type
);
791 build_le (r
, type
, op1
);
800 class foperator_le
: public range_operator_float
802 using range_operator_float::fold_range
;
803 using range_operator_float::op1_range
;
804 using range_operator_float::op2_range
;
805 using range_operator_float::op1_op2_relation
;
807 bool fold_range (irange
&r
, tree type
,
808 const frange
&op1
, const frange
&op2
,
809 relation_trio rel
= TRIO_VARYING
) const final override
;
810 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
812 return le_op1_op2_relation (lhs
);
814 bool op1_range (frange
&r
, tree type
,
815 const irange
&lhs
, const frange
&op2
,
816 relation_trio rel
= TRIO_VARYING
) const final override
;
817 bool op2_range (frange
&r
, tree type
,
818 const irange
&lhs
, const frange
&op1
,
819 relation_trio rel
= TRIO_VARYING
) const final override
;
823 foperator_le::fold_range (irange
&r
, tree type
,
824 const frange
&op1
, const frange
&op2
,
825 relation_trio rel
) const
827 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_LE
))
830 if (op1
.known_isnan () || op2
.known_isnan ())
831 r
= range_false (type
);
832 else if (!maybe_isnan (op1
, op2
))
834 if (real_compare (LE_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
835 r
= range_true (type
);
836 else if (!real_compare (LE_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
837 r
= range_false (type
);
839 r
= range_true_and_false (type
);
842 r
= range_true_and_false (type
);
847 foperator_le::op1_range (frange
&r
,
853 switch (get_bool_state (r
, lhs
, type
))
856 // The TRUE side of x <= NAN is unreachable.
857 if (op2
.known_isnan ())
859 else if (build_le (r
, type
, op2
))
864 // On the FALSE side of x <= NAN, we know nothing about x.
865 if (op2
.known_isnan ())
866 r
.set_varying (type
);
868 build_gt (r
, type
, op2
);
878 foperator_le::op2_range (frange
&r
,
884 switch (get_bool_state (r
, lhs
, type
))
887 // The TRUE side of NAN <= x is unreachable.
888 if (op1
.known_isnan ())
890 else if (build_ge (r
, type
, op1
))
895 // On the FALSE side of NAN <= x, we know nothing about x.
896 if (op1
.known_isnan ())
897 r
.set_varying (type
);
899 build_lt (r
, type
, op1
);
908 class foperator_gt
: public range_operator_float
910 using range_operator_float::fold_range
;
911 using range_operator_float::op1_range
;
912 using range_operator_float::op2_range
;
913 using range_operator_float::op1_op2_relation
;
915 bool fold_range (irange
&r
, tree type
,
916 const frange
&op1
, const frange
&op2
,
917 relation_trio
= TRIO_VARYING
) const final override
;
918 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
920 return gt_op1_op2_relation (lhs
);
922 bool op1_range (frange
&r
, tree type
,
923 const irange
&lhs
, const frange
&op2
,
924 relation_trio
= TRIO_VARYING
) const final override
;
925 bool op2_range (frange
&r
, tree type
,
926 const irange
&lhs
, const frange
&op1
,
927 relation_trio
= TRIO_VARYING
) const final override
;
931 foperator_gt::fold_range (irange
&r
, tree type
,
932 const frange
&op1
, const frange
&op2
,
933 relation_trio rel
) const
935 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_GT
))
938 if (op1
.known_isnan () || op2
.known_isnan ())
939 r
= range_false (type
);
940 else if (!maybe_isnan (op1
, op2
))
942 if (real_compare (GT_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
943 r
= range_true (type
);
944 else if (!real_compare (GT_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
945 r
= range_false (type
);
947 r
= range_true_and_false (type
);
950 r
= range_true_and_false (type
);
955 foperator_gt::op1_range (frange
&r
,
961 switch (get_bool_state (r
, lhs
, type
))
964 // The TRUE side of x > NAN is unreachable.
965 if (op2
.known_isnan ())
967 else if (build_gt (r
, type
, op2
))
970 // x > y implies x is not -INF.
971 frange_drop_ninf (r
, type
);
976 // On the FALSE side of x > NAN, we know nothing about x.
977 if (op2
.known_isnan ())
978 r
.set_varying (type
);
980 build_le (r
, type
, op2
);
990 foperator_gt::op2_range (frange
&r
,
996 switch (get_bool_state (r
, lhs
, type
))
999 // The TRUE side of NAN > x is unreachable.
1000 if (op1
.known_isnan ())
1002 else if (build_lt (r
, type
, op1
))
1005 // x > y implies y is not +INF.
1006 frange_drop_inf (r
, type
);
1011 // On The FALSE side of NAN > x, we know nothing about x.
1012 if (op1
.known_isnan ())
1013 r
.set_varying (type
);
1015 build_ge (r
, type
, op1
);
1024 class foperator_ge
: public range_operator_float
1026 using range_operator_float::fold_range
;
1027 using range_operator_float::op1_range
;
1028 using range_operator_float::op2_range
;
1029 using range_operator_float::op1_op2_relation
;
1031 bool fold_range (irange
&r
, tree type
,
1032 const frange
&op1
, const frange
&op2
,
1033 relation_trio
= TRIO_VARYING
) const final override
;
1034 relation_kind
op1_op2_relation (const irange
&lhs
) const final override
1036 return ge_op1_op2_relation (lhs
);
1038 bool op1_range (frange
&r
, tree type
,
1039 const irange
&lhs
, const frange
&op2
,
1040 relation_trio
= TRIO_VARYING
) const final override
;
1041 bool op2_range (frange
&r
, tree type
,
1042 const irange
&lhs
, const frange
&op1
,
1043 relation_trio
= TRIO_VARYING
) const final override
;
1047 foperator_ge::fold_range (irange
&r
, tree type
,
1048 const frange
&op1
, const frange
&op2
,
1049 relation_trio rel
) const
1051 if (frelop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_GE
))
1054 if (op1
.known_isnan () || op2
.known_isnan ())
1055 r
= range_false (type
);
1056 else if (!maybe_isnan (op1
, op2
))
1058 if (real_compare (GE_EXPR
, &op1
.lower_bound (), &op2
.upper_bound ()))
1059 r
= range_true (type
);
1060 else if (!real_compare (GE_EXPR
, &op1
.upper_bound (), &op2
.lower_bound ()))
1061 r
= range_false (type
);
1063 r
= range_true_and_false (type
);
1066 r
= range_true_and_false (type
);
1071 foperator_ge::op1_range (frange
&r
,
1075 relation_trio
) const
1077 switch (get_bool_state (r
, lhs
, type
))
1080 // The TRUE side of x >= NAN is unreachable.
1081 if (op2
.known_isnan ())
1083 else if (build_ge (r
, type
, op2
))
1088 // On the FALSE side of x >= NAN, we know nothing about x.
1089 if (op2
.known_isnan ())
1090 r
.set_varying (type
);
1092 build_lt (r
, type
, op2
);
1102 foperator_ge::op2_range (frange
&r
, tree type
,
1105 relation_trio
) const
1107 switch (get_bool_state (r
, lhs
, type
))
1110 // The TRUE side of NAN >= x is unreachable.
1111 if (op1
.known_isnan ())
1113 else if (build_le (r
, type
, op1
))
1118 // On the FALSE side of NAN >= x, we know nothing about x.
1119 if (op1
.known_isnan ())
1120 r
.set_varying (type
);
1122 build_gt (r
, type
, op1
);
1131 // UNORDERED_EXPR comparison.
1133 class foperator_unordered
: public range_operator_float
1135 using range_operator_float::fold_range
;
1136 using range_operator_float::op1_range
;
1137 using range_operator_float::op2_range
;
1139 bool fold_range (irange
&r
, tree type
,
1140 const frange
&op1
, const frange
&op2
,
1141 relation_trio
= TRIO_VARYING
) const final override
;
1142 bool op1_range (frange
&r
, tree type
,
1143 const irange
&lhs
, const frange
&op2
,
1144 relation_trio
= TRIO_VARYING
) const final override
;
1145 bool op2_range (frange
&r
, tree type
,
1146 const irange
&lhs
, const frange
&op1
,
1147 relation_trio rel
= TRIO_VARYING
) const final override
1149 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
1154 foperator_unordered::fold_range (irange
&r
, tree type
,
1155 const frange
&op1
, const frange
&op2
,
1156 relation_trio
) const
1158 // UNORDERED is TRUE if either operand is a NAN.
1159 if (op1
.known_isnan () || op2
.known_isnan ())
1160 r
= range_true (type
);
1161 // UNORDERED is FALSE if neither operand is a NAN.
1162 else if (!op1
.maybe_isnan () && !op2
.maybe_isnan ())
1163 r
= range_false (type
);
1165 r
= range_true_and_false (type
);
1170 foperator_unordered::op1_range (frange
&r
, tree type
,
1173 relation_trio trio
) const
1175 relation_kind rel
= trio
.op1_op2 ();
1176 switch (get_bool_state (r
, lhs
, type
))
1179 // Since at least one operand must be NAN, if one of them is
1180 // not, the other must be.
1181 if (rel
== VREL_EQ
|| !op2
.maybe_isnan ())
1184 r
.set_varying (type
);
1188 // A false UNORDERED means both operands are !NAN, so it's
1189 // impossible for op2 to be a NAN.
1190 if (op2
.known_isnan ())
1194 r
.set_varying (type
);
1205 // ORDERED_EXPR comparison.
1207 class foperator_ordered
: public range_operator_float
1209 using range_operator_float::fold_range
;
1210 using range_operator_float::op1_range
;
1211 using range_operator_float::op2_range
;
1213 bool fold_range (irange
&r
, tree type
,
1214 const frange
&op1
, const frange
&op2
,
1215 relation_trio
= TRIO_VARYING
) const final override
;
1216 bool op1_range (frange
&r
, tree type
,
1217 const irange
&lhs
, const frange
&op2
,
1218 relation_trio
= TRIO_VARYING
) const final override
;
1219 bool op2_range (frange
&r
, tree type
,
1220 const irange
&lhs
, const frange
&op1
,
1221 relation_trio rel
= TRIO_VARYING
) const final override
1223 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
1228 foperator_ordered::fold_range (irange
&r
, tree type
,
1229 const frange
&op1
, const frange
&op2
,
1230 relation_trio
) const
1232 if (op1
.known_isnan () || op2
.known_isnan ())
1233 r
= range_false (type
);
1234 else if (!op1
.maybe_isnan () && !op2
.maybe_isnan ())
1235 r
= range_true (type
);
1237 r
= range_true_and_false (type
);
1242 foperator_ordered::op1_range (frange
&r
, tree type
,
1245 relation_trio trio
) const
1247 relation_kind rel
= trio
.op1_op2 ();
1248 switch (get_bool_state (r
, lhs
, type
))
1251 // The TRUE side of ORDERED means both operands are !NAN, so
1252 // it's impossible for op2 to be a NAN.
1253 if (op2
.known_isnan ())
1257 r
.set_varying (type
);
1263 // The FALSE side of op1 ORDERED op1 implies op1 is NAN.
1267 r
.set_varying (type
);
1276 class foperator_negate
: public range_operator_float
1278 using range_operator_float::fold_range
;
1279 using range_operator_float::op1_range
;
1281 bool fold_range (frange
&r
, tree type
,
1282 const frange
&op1
, const frange
&op2
,
1283 relation_trio
= TRIO_VARYING
) const final override
1285 if (empty_range_varying (r
, type
, op1
, op2
))
1287 if (op1
.known_isnan ())
1290 if (op1
.nan_signbit_p (sign
))
1291 r
.set_nan (type
, !sign
);
1297 REAL_VALUE_TYPE lh_lb
= op1
.lower_bound ();
1298 REAL_VALUE_TYPE lh_ub
= op1
.upper_bound ();
1299 lh_lb
= real_value_negate (&lh_lb
);
1300 lh_ub
= real_value_negate (&lh_ub
);
1301 r
.set (type
, lh_ub
, lh_lb
);
1302 if (op1
.maybe_isnan ())
1305 if (op1
.nan_signbit_p (sign
))
1306 r
.update_nan (!sign
);
1314 bool op1_range (frange
&r
, tree type
,
1315 const frange
&lhs
, const frange
&op2
,
1316 relation_trio rel
= TRIO_VARYING
) const final override
1318 return fold_range (r
, type
, lhs
, op2
, rel
);
1322 class foperator_abs
: public range_operator_float
1324 using range_operator_float::fold_range
;
1325 using range_operator_float::op1_range
;
1327 bool fold_range (frange
&r
, tree type
,
1328 const frange
&op1
, const frange
&,
1329 relation_trio
= TRIO_VARYING
) const final override
;
1330 bool op1_range (frange
&r
, tree type
,
1331 const frange
&lhs
, const frange
&op2
,
1332 relation_trio rel
= TRIO_VARYING
) const final override
;
1336 foperator_abs::fold_range (frange
&r
, tree type
,
1337 const frange
&op1
, const frange
&op2
,
1338 relation_trio
) const
1340 if (empty_range_varying (r
, type
, op1
, op2
))
1342 if (op1
.known_isnan ())
1344 r
.set_nan (type
, /*sign=*/false);
1348 const REAL_VALUE_TYPE lh_lb
= op1
.lower_bound ();
1349 const REAL_VALUE_TYPE lh_ub
= op1
.upper_bound ();
1350 // Handle the easy case where everything is positive.
1351 if (real_compare (GE_EXPR
, &lh_lb
, &dconst0
)
1352 && !real_iszero (&lh_lb
, /*sign=*/true)
1353 && !op1
.maybe_isnan (/*sign=*/true))
1359 REAL_VALUE_TYPE min
= real_value_abs (&lh_lb
);
1360 REAL_VALUE_TYPE max
= real_value_abs (&lh_ub
);
1361 // If the range contains zero then we know that the minimum value in the
1362 // range will be zero.
1363 if (real_compare (LE_EXPR
, &lh_lb
, &dconst0
)
1364 && real_compare (GE_EXPR
, &lh_ub
, &dconst0
))
1366 if (real_compare (GT_EXPR
, &min
, &max
))
1372 // If the range was reversed, swap MIN and MAX.
1373 if (real_compare (GT_EXPR
, &min
, &max
))
1374 std::swap (min
, max
);
1377 r
.set (type
, min
, max
);
1378 if (op1
.maybe_isnan ())
1379 r
.update_nan (/*sign=*/false);
1386 foperator_abs::op1_range (frange
&r
, tree type
,
1387 const frange
&lhs
, const frange
&op2
,
1388 relation_trio
) const
1390 if (empty_range_varying (r
, type
, lhs
, op2
))
1392 if (lhs
.known_isnan ())
1398 // Start with the positives because negatives are an impossible result.
1399 frange
positives (type
, dconst0
, frange_val_max (type
));
1400 positives
.update_nan (/*sign=*/false);
1401 positives
.intersect (lhs
);
1403 // Add -NAN if relevant.
1404 if (r
.maybe_isnan ())
1407 neg_nan
.set_nan (type
, true);
1410 if (r
.known_isnan () || r
.undefined_p ())
1412 // Then add the negative of each pair:
1413 // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
1414 frange
negatives (type
, real_value_negate (&positives
.upper_bound ()),
1415 real_value_negate (&positives
.lower_bound ()));
1416 negatives
.clear_nan ();
1417 r
.union_ (negatives
);
1421 class foperator_unordered_lt
: public range_operator_float
1423 using range_operator_float::fold_range
;
1424 using range_operator_float::op1_range
;
1425 using range_operator_float::op2_range
;
1427 bool fold_range (irange
&r
, tree type
,
1428 const frange
&op1
, const frange
&op2
,
1429 relation_trio rel
= TRIO_VARYING
) const final override
1431 if (op1
.known_isnan () || op2
.known_isnan ())
1433 r
= range_true (type
);
1436 if (!fop_lt
.fold_range (r
, type
, op1
, op2
, rel
))
1438 // The result is the same as the ordered version when the
1439 // comparison is true or when the operands cannot be NANs.
1440 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1444 r
= range_true_and_false (type
);
1448 bool op1_range (frange
&r
, tree type
,
1451 relation_trio trio
) const final override
;
1452 bool op2_range (frange
&r
, tree type
,
1455 relation_trio trio
) const final override
;
1459 foperator_unordered_lt::op1_range (frange
&r
, tree type
,
1462 relation_trio
) const
1464 switch (get_bool_state (r
, lhs
, type
))
1467 if (op2
.known_isnan ())
1468 r
.set_varying (type
);
1470 build_lt (r
, type
, op2
);
1474 // A false UNORDERED_LT means both operands are !NAN, so it's
1475 // impossible for op2 to be a NAN.
1476 if (op2
.known_isnan ())
1478 else if (build_ge (r
, type
, op2
))
1489 foperator_unordered_lt::op2_range (frange
&r
, tree type
,
1492 relation_trio
) const
1494 switch (get_bool_state (r
, lhs
, type
))
1497 if (op1
.known_isnan ())
1498 r
.set_varying (type
);
1500 build_gt (r
, type
, op1
);
1504 // A false UNORDERED_LT means both operands are !NAN, so it's
1505 // impossible for op1 to be a NAN.
1506 if (op1
.known_isnan ())
1508 else if (build_le (r
, type
, op1
))
1518 class foperator_unordered_le
: public range_operator_float
1520 using range_operator_float::fold_range
;
1521 using range_operator_float::op1_range
;
1522 using range_operator_float::op2_range
;
1524 bool fold_range (irange
&r
, tree type
,
1525 const frange
&op1
, const frange
&op2
,
1526 relation_trio rel
= TRIO_VARYING
) const final override
1528 if (op1
.known_isnan () || op2
.known_isnan ())
1530 r
= range_true (type
);
1533 if (!fop_le
.fold_range (r
, type
, op1
, op2
, rel
))
1535 // The result is the same as the ordered version when the
1536 // comparison is true or when the operands cannot be NANs.
1537 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1541 r
= range_true_and_false (type
);
1545 bool op1_range (frange
&r
, tree type
,
1546 const irange
&lhs
, const frange
&op2
,
1547 relation_trio
= TRIO_VARYING
) const final override
;
1548 bool op2_range (frange
&r
, tree type
,
1549 const irange
&lhs
, const frange
&op1
,
1550 relation_trio
= TRIO_VARYING
) const final override
;
1554 foperator_unordered_le::op1_range (frange
&r
, tree type
,
1555 const irange
&lhs
, const frange
&op2
,
1556 relation_trio
) const
1558 switch (get_bool_state (r
, lhs
, type
))
1561 if (op2
.known_isnan ())
1562 r
.set_varying (type
);
1564 build_le (r
, type
, op2
);
1568 // A false UNORDERED_LE means both operands are !NAN, so it's
1569 // impossible for op2 to be a NAN.
1570 if (op2
.known_isnan ())
1572 else if (build_gt (r
, type
, op2
))
1583 foperator_unordered_le::op2_range (frange
&r
,
1587 relation_trio
) const
1589 switch (get_bool_state (r
, lhs
, type
))
1592 if (op1
.known_isnan ())
1593 r
.set_varying (type
);
1595 build_ge (r
, type
, op1
);
1599 // A false UNORDERED_LE means both operands are !NAN, so it's
1600 // impossible for op1 to be a NAN.
1601 if (op1
.known_isnan ())
1603 else if (build_lt (r
, type
, op1
))
1613 class foperator_unordered_gt
: public range_operator_float
1615 using range_operator_float::fold_range
;
1616 using range_operator_float::op1_range
;
1617 using range_operator_float::op2_range
;
1619 bool fold_range (irange
&r
, tree type
,
1620 const frange
&op1
, const frange
&op2
,
1621 relation_trio rel
= TRIO_VARYING
) const final override
1623 if (op1
.known_isnan () || op2
.known_isnan ())
1625 r
= range_true (type
);
1628 if (!fop_gt
.fold_range (r
, type
, op1
, op2
, rel
))
1630 // The result is the same as the ordered version when the
1631 // comparison is true or when the operands cannot be NANs.
1632 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1636 r
= range_true_and_false (type
);
1640 bool op1_range (frange
&r
, tree type
,
1641 const irange
&lhs
, const frange
&op2
,
1642 relation_trio
= TRIO_VARYING
) const final override
;
1643 bool op2_range (frange
&r
, tree type
,
1644 const irange
&lhs
, const frange
&op1
,
1645 relation_trio
= TRIO_VARYING
) const final override
;
1649 foperator_unordered_gt::op1_range (frange
&r
,
1653 relation_trio
) const
1655 switch (get_bool_state (r
, lhs
, type
))
1658 if (op2
.known_isnan ())
1659 r
.set_varying (type
);
1661 build_gt (r
, type
, op2
);
1665 // A false UNORDERED_GT means both operands are !NAN, so it's
1666 // impossible for op2 to be a NAN.
1667 if (op2
.known_isnan ())
1669 else if (build_le (r
, type
, op2
))
1680 foperator_unordered_gt::op2_range (frange
&r
,
1684 relation_trio
) const
1686 switch (get_bool_state (r
, lhs
, type
))
1689 if (op1
.known_isnan ())
1690 r
.set_varying (type
);
1692 build_lt (r
, type
, op1
);
1696 // A false UNORDERED_GT means both operands are !NAN, so it's
1697 // impossible for op1 to be a NAN.
1698 if (op1
.known_isnan ())
1700 else if (build_ge (r
, type
, op1
))
1710 class foperator_unordered_ge
: public range_operator_float
1712 using range_operator_float::fold_range
;
1713 using range_operator_float::op1_range
;
1714 using range_operator_float::op2_range
;
1716 bool fold_range (irange
&r
, tree type
,
1717 const frange
&op1
, const frange
&op2
,
1718 relation_trio rel
= TRIO_VARYING
) const final override
1720 if (op1
.known_isnan () || op2
.known_isnan ())
1722 r
= range_true (type
);
1725 if (!fop_ge
.fold_range (r
, type
, op1
, op2
, rel
))
1727 // The result is the same as the ordered version when the
1728 // comparison is true or when the operands cannot be NANs.
1729 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1733 r
= range_true_and_false (type
);
1737 bool op1_range (frange
&r
, tree type
,
1738 const irange
&lhs
, const frange
&op2
,
1739 relation_trio
= TRIO_VARYING
) const final override
;
1740 bool op2_range (frange
&r
, tree type
,
1741 const irange
&lhs
, const frange
&op1
,
1742 relation_trio
= TRIO_VARYING
) const final override
;
1746 foperator_unordered_ge::op1_range (frange
&r
,
1750 relation_trio
) const
1752 switch (get_bool_state (r
, lhs
, type
))
1755 if (op2
.known_isnan ())
1756 r
.set_varying (type
);
1758 build_ge (r
, type
, op2
);
1762 // A false UNORDERED_GE means both operands are !NAN, so it's
1763 // impossible for op2 to be a NAN.
1764 if (op2
.known_isnan ())
1766 else if (build_lt (r
, type
, op2
))
1777 foperator_unordered_ge::op2_range (frange
&r
, tree type
,
1780 relation_trio
) const
1782 switch (get_bool_state (r
, lhs
, type
))
1785 if (op1
.known_isnan ())
1786 r
.set_varying (type
);
1788 build_le (r
, type
, op1
);
1792 // A false UNORDERED_GE means both operands are !NAN, so it's
1793 // impossible for op1 to be a NAN.
1794 if (op1
.known_isnan ())
1796 else if (build_gt (r
, type
, op1
))
1806 class foperator_unordered_equal
: public range_operator_float
1808 using range_operator_float::fold_range
;
1809 using range_operator_float::op1_range
;
1810 using range_operator_float::op2_range
;
1812 bool fold_range (irange
&r
, tree type
,
1813 const frange
&op1
, const frange
&op2
,
1814 relation_trio rel
= TRIO_VARYING
) const final override
1816 if (op1
.known_isnan () || op2
.known_isnan ())
1818 r
= range_true (type
);
1821 if (!fop_equal
.fold_range (r
, type
, op1
, op2
, rel
))
1823 // The result is the same as the ordered version when the
1824 // comparison is true or when the operands cannot be NANs.
1825 if (!maybe_isnan (op1
, op2
) || r
== range_true (type
))
1829 r
= range_true_and_false (type
);
1833 bool op1_range (frange
&r
, tree type
,
1834 const irange
&lhs
, const frange
&op2
,
1835 relation_trio
= TRIO_VARYING
) const final override
;
1836 bool op2_range (frange
&r
, tree type
,
1837 const irange
&lhs
, const frange
&op1
,
1838 relation_trio rel
= TRIO_VARYING
) const final override
1840 return op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
1842 } fop_unordered_equal
;
1845 foperator_unordered_equal::op1_range (frange
&r
, tree type
,
1848 relation_trio
) const
1850 switch (get_bool_state (r
, lhs
, type
))
1853 // If it's true, the result is the same as OP2 plus a NAN.
1855 // Add both zeros if there's the possibility of zero equality.
1856 frange_add_zeros (r
, type
);
1857 // Add the posibility of a NAN.
1862 // A false UNORDERED_EQ means both operands are !NAN, so it's
1863 // impossible for op2 to be a NAN.
1864 if (op2
.known_isnan ())
1868 // The false side indictates !NAN and not equal. We can at least
1870 r
.set_varying (type
);
1881 // Final tweaks for float binary op op1_range/op2_range.
1882 // Return TRUE if the operation is performed and a valid range is available.
1885 float_binary_op_range_finish (bool ret
, frange
&r
, tree type
,
1891 // If we get a known NAN from reverse op, it means either that
1892 // the other operand was known NAN (in that case we know nothing),
1893 // or the reverse operation introduced a known NAN.
1894 // Say for lhs = op1 * op2 if lhs is [-0, +0] and op2 is too,
1895 // 0 / 0 is known NAN. Just punt in that case.
1896 // If NANs aren't honored, we get for 0 / 0 UNDEFINED, so punt as well.
1897 // Or if lhs is a known NAN, we also don't know anything.
1898 if (r
.known_isnan () || lhs
.known_isnan () || r
.undefined_p ())
1900 r
.set_varying (type
);
1904 // If lhs isn't NAN, then neither operand could be NAN,
1905 // even if the reverse operation does introduce a maybe_nan.
1906 if (!lhs
.maybe_isnan ())
1908 // If lhs is a maybe or known NAN, the operand could be
1915 // True if [lb, ub] is [+-0, +-0].
1917 zero_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
1919 return real_iszero (&lb
) && real_iszero (&ub
);
1922 // True if +0 or -0 is in [lb, ub] range.
1924 contains_zero_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
1926 return (real_compare (LE_EXPR
, &lb
, &dconst0
)
1927 && real_compare (GE_EXPR
, &ub
, &dconst0
));
1930 // True if [lb, ub] is [-INF, -INF] or [+INF, +INF].
1932 singleton_inf_p (const REAL_VALUE_TYPE
&lb
, const REAL_VALUE_TYPE
&ub
)
1934 return real_isinf (&lb
) && real_isinf (&ub
, real_isneg (&lb
));
1937 // Return -1 if binary op result must have sign bit set,
1938 // 1 if binary op result must have sign bit clear,
1940 // Sign bit of binary op result is exclusive or of the
1941 // operand's sign bits.
1943 signbit_known_p (const REAL_VALUE_TYPE
&lh_lb
, const REAL_VALUE_TYPE
&lh_ub
,
1944 const REAL_VALUE_TYPE
&rh_lb
, const REAL_VALUE_TYPE
&rh_ub
)
1946 if (real_isneg (&lh_lb
) == real_isneg (&lh_ub
)
1947 && real_isneg (&rh_lb
) == real_isneg (&rh_ub
))
1949 if (real_isneg (&lh_lb
) == real_isneg (&rh_ub
))
1957 // Set [lb, ub] to [-0, -0], [-0, +0] or [+0, +0] depending on
1960 zero_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
1963 if (signbit_known
<= 0)
1964 lb
= real_value_negate (&dconst0
);
1965 if (signbit_known
< 0)
1969 // Set [lb, ub] to [-INF, -INF], [-INF, +INF] or [+INF, +INF] depending on
1972 inf_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
1974 if (signbit_known
> 0)
1975 ub
= lb
= dconstinf
;
1976 else if (signbit_known
< 0)
1977 ub
= lb
= dconstninf
;
1985 // Set [lb, ub] to [-INF, -0], [-INF, +INF] or [+0, +INF] depending on
1988 zero_to_inf_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, int signbit_known
)
1990 if (signbit_known
> 0)
1995 else if (signbit_known
< 0)
1998 ub
= real_value_negate (&dconst0
);
2007 class foperator_plus
: public range_operator_float
2009 using range_operator_float::op1_range
;
2010 using range_operator_float::op2_range
;
2012 virtual bool op1_range (frange
&r
, tree type
,
2015 relation_trio
= TRIO_VARYING
) const final override
2017 if (lhs
.undefined_p ())
2019 range_op_handler
minus (MINUS_EXPR
, type
);
2022 return float_binary_op_range_finish (minus
.fold_range (r
, type
, lhs
, op2
),
2025 virtual bool op2_range (frange
&r
, tree type
,
2028 relation_trio
= TRIO_VARYING
) const final override
2030 return op1_range (r
, type
, lhs
, op1
);
2033 void rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, bool &maybe_nan
,
2035 const REAL_VALUE_TYPE
&lh_lb
,
2036 const REAL_VALUE_TYPE
&lh_ub
,
2037 const REAL_VALUE_TYPE
&rh_lb
,
2038 const REAL_VALUE_TYPE
&rh_ub
,
2039 relation_kind
) const final override
2041 frange_arithmetic (PLUS_EXPR
, type
, lb
, lh_lb
, rh_lb
, dconstninf
);
2042 frange_arithmetic (PLUS_EXPR
, type
, ub
, lh_ub
, rh_ub
, dconstinf
);
2044 // [-INF] + [+INF] = NAN
2045 if (real_isinf (&lh_lb
, true) && real_isinf (&rh_ub
, false))
2047 // [+INF] + [-INF] = NAN
2048 else if (real_isinf (&lh_ub
, false) && real_isinf (&rh_lb
, true))
2056 class foperator_minus
: public range_operator_float
2058 using range_operator_float::op1_range
;
2059 using range_operator_float::op2_range
;
2061 virtual bool op1_range (frange
&r
, tree type
,
2064 relation_trio
= TRIO_VARYING
) const final override
2066 if (lhs
.undefined_p ())
2068 return float_binary_op_range_finish (fop_plus
.fold_range (r
, type
, lhs
,
2072 virtual bool op2_range (frange
&r
, tree type
,
2075 relation_trio
= TRIO_VARYING
) const final override
2077 if (lhs
.undefined_p ())
2079 return float_binary_op_range_finish (fold_range (r
, type
, op1
, lhs
),
2083 void rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, bool &maybe_nan
,
2085 const REAL_VALUE_TYPE
&lh_lb
,
2086 const REAL_VALUE_TYPE
&lh_ub
,
2087 const REAL_VALUE_TYPE
&rh_lb
,
2088 const REAL_VALUE_TYPE
&rh_ub
,
2089 relation_kind
) const final override
2091 frange_arithmetic (MINUS_EXPR
, type
, lb
, lh_lb
, rh_ub
, dconstninf
);
2092 frange_arithmetic (MINUS_EXPR
, type
, ub
, lh_ub
, rh_lb
, dconstinf
);
2094 // [+INF] - [+INF] = NAN
2095 if (real_isinf (&lh_ub
, false) && real_isinf (&rh_ub
, false))
2097 // [-INF] - [-INF] = NAN
2098 else if (real_isinf (&lh_lb
, true) && real_isinf (&rh_lb
, true))
2106 class foperator_mult_div_base
: public range_operator_float
2109 // Given CP[0] to CP[3] floating point values rounded to -INF,
2110 // set LB to the smallest of them (treating -0 as smaller to +0).
2111 // Given CP[4] to CP[7] floating point values rounded to +INF,
2112 // set UB to the largest of them (treating -0 as smaller to +0).
2113 static void find_range (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
,
2114 const REAL_VALUE_TYPE (&cp
)[8])
2118 for (int i
= 1; i
< 4; ++i
)
2120 if (real_less (&cp
[i
], &lb
)
2121 || (real_iszero (&lb
) && real_isnegzero (&cp
[i
])))
2123 if (real_less (&ub
, &cp
[i
+ 4])
2124 || (real_isnegzero (&ub
) && real_iszero (&cp
[i
+ 4])))
2131 class foperator_mult
: public foperator_mult_div_base
2133 using range_operator_float::op1_range
;
2134 using range_operator_float::op2_range
;
2136 virtual bool op1_range (frange
&r
, tree type
,
2139 relation_trio
= TRIO_VARYING
) const final override
2141 if (lhs
.undefined_p ())
2143 range_op_handler
rdiv (RDIV_EXPR
, type
);
2146 return float_binary_op_range_finish (rdiv
.fold_range (r
, type
, lhs
, op2
),
2149 virtual bool op2_range (frange
&r
, tree type
,
2152 relation_trio
= TRIO_VARYING
) const final override
2154 return op1_range (r
, type
, lhs
, op1
);
2157 void rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, bool &maybe_nan
,
2159 const REAL_VALUE_TYPE
&lh_lb
,
2160 const REAL_VALUE_TYPE
&lh_ub
,
2161 const REAL_VALUE_TYPE
&rh_lb
,
2162 const REAL_VALUE_TYPE
&rh_ub
,
2163 relation_kind kind
) const final override
2167 && real_equal (&lh_lb
, &rh_lb
)
2168 && real_equal (&lh_ub
, &rh_ub
)
2169 && real_isneg (&lh_lb
) == real_isneg (&rh_lb
)
2170 && real_isneg (&lh_ub
) == real_isneg (&rh_ub
));
2173 // x * x never produces a new NAN and we only multiply the same
2174 // values, so the 0 * INF problematic cases never appear there.
2177 // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN.
2178 if ((zero_p (lh_lb
, lh_ub
) && singleton_inf_p (rh_lb
, rh_ub
))
2179 || (zero_p (rh_lb
, rh_ub
) && singleton_inf_p (lh_lb
, lh_ub
)))
2181 real_nan (&lb
, "", 0, TYPE_MODE (type
));
2187 // Otherwise, if one range includes zero and the other ends with +-INF,
2188 // it is a maybe NAN.
2189 if ((contains_zero_p (lh_lb
, lh_ub
)
2190 && (real_isinf (&rh_lb
) || real_isinf (&rh_ub
)))
2191 || (contains_zero_p (rh_lb
, rh_ub
)
2192 && (real_isinf (&lh_lb
) || real_isinf (&lh_ub
))))
2196 int signbit_known
= signbit_known_p (lh_lb
, lh_ub
, rh_lb
, rh_ub
);
2198 // If one of the ranges that includes INF is singleton
2199 // and the other range includes zero, the resulting
2200 // range is INF and NAN, because the 0 * INF boundary
2201 // case will be NAN, but already nextafter (0, 1) * INF
2203 if (singleton_inf_p (lh_lb
, lh_ub
)
2204 || singleton_inf_p (rh_lb
, rh_ub
))
2205 return inf_range (lb
, ub
, signbit_known
);
2207 // If one of the multiplicands must be zero, the resulting
2208 // range is +-0 and NAN.
2209 if (zero_p (lh_lb
, lh_ub
) || zero_p (rh_lb
, rh_ub
))
2210 return zero_range (lb
, ub
, signbit_known
);
2212 // Otherwise one of the multiplicands could be
2213 // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF]
2214 // or similarly with different signs. 0.0 * DBL_MAX
2215 // is still 0.0, nextafter (0.0, 1.0) * INF is still INF,
2216 // so if the signs are always the same or always different,
2217 // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING.
2218 return zero_to_inf_range (lb
, ub
, signbit_known
);
2222 REAL_VALUE_TYPE cp
[8];
2223 // Do a cross-product. At this point none of the multiplications
2224 // should produce a NAN.
2225 frange_arithmetic (MULT_EXPR
, type
, cp
[0], lh_lb
, rh_lb
, dconstninf
);
2226 frange_arithmetic (MULT_EXPR
, type
, cp
[4], lh_lb
, rh_lb
, dconstinf
);
2229 // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub)
2230 // as maximum and -0.0 as minimum if 0.0 is in the range,
2231 // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub).
2232 // -0.0 rather than 0.0 because VREL_EQ doesn't prove that
2233 // x and y are bitwise equal, just that they compare equal.
2234 if (contains_zero_p (lh_lb
, lh_ub
))
2236 if (real_isneg (&lh_lb
) == real_isneg (&lh_ub
))
2239 cp
[1] = real_value_negate (&dconst0
);
2249 frange_arithmetic (MULT_EXPR
, type
, cp
[1], lh_lb
, rh_ub
, dconstninf
);
2250 frange_arithmetic (MULT_EXPR
, type
, cp
[5], lh_lb
, rh_ub
, dconstinf
);
2251 frange_arithmetic (MULT_EXPR
, type
, cp
[2], lh_ub
, rh_lb
, dconstninf
);
2252 frange_arithmetic (MULT_EXPR
, type
, cp
[6], lh_ub
, rh_lb
, dconstinf
);
2254 frange_arithmetic (MULT_EXPR
, type
, cp
[3], lh_ub
, rh_ub
, dconstninf
);
2255 frange_arithmetic (MULT_EXPR
, type
, cp
[7], lh_ub
, rh_ub
, dconstinf
);
2257 find_range (lb
, ub
, cp
);
2262 class foperator_div
: public foperator_mult_div_base
2264 using range_operator_float::op1_range
;
2265 using range_operator_float::op2_range
;
2267 virtual bool op1_range (frange
&r
, tree type
,
2270 relation_trio
= TRIO_VARYING
) const final override
2272 if (lhs
.undefined_p ())
2274 return float_binary_op_range_finish (fop_mult
.fold_range (r
, type
, lhs
,
2278 virtual bool op2_range (frange
&r
, tree type
,
2281 relation_trio
= TRIO_VARYING
) const final override
2283 if (lhs
.undefined_p ())
2285 return float_binary_op_range_finish (fold_range (r
, type
, op1
, lhs
),
2289 void rv_fold (REAL_VALUE_TYPE
&lb
, REAL_VALUE_TYPE
&ub
, bool &maybe_nan
,
2291 const REAL_VALUE_TYPE
&lh_lb
,
2292 const REAL_VALUE_TYPE
&lh_ub
,
2293 const REAL_VALUE_TYPE
&rh_lb
,
2294 const REAL_VALUE_TYPE
&rh_ub
,
2295 relation_kind
) const final override
2297 // +-0.0 / +-0.0 or +-INF / +-INF is a known NAN.
2298 if ((zero_p (lh_lb
, lh_ub
) && zero_p (rh_lb
, rh_ub
))
2299 || (singleton_inf_p (lh_lb
, lh_ub
) || singleton_inf_p (rh_lb
, rh_ub
)))
2301 real_nan (&lb
, "", 0, TYPE_MODE (type
));
2307 // If +-0.0 is in both ranges, it is a maybe NAN.
2308 if (contains_zero_p (lh_lb
, lh_ub
) && contains_zero_p (rh_lb
, rh_ub
))
2310 // If +-INF is in both ranges, it is a maybe NAN.
2311 else if ((real_isinf (&lh_lb
) || real_isinf (&lh_ub
))
2312 && (real_isinf (&rh_lb
) || real_isinf (&rh_ub
)))
2317 int signbit_known
= signbit_known_p (lh_lb
, lh_ub
, rh_lb
, rh_ub
);
2319 // If dividend must be zero, the range is just +-0
2320 // (including if the divisor is +-INF).
2321 // If divisor must be +-INF, the range is just +-0
2322 // (including if the dividend is zero).
2323 if (zero_p (lh_lb
, lh_ub
) || singleton_inf_p (rh_lb
, rh_ub
))
2324 return zero_range (lb
, ub
, signbit_known
);
2326 // If divisor must be zero, the range is just +-INF
2327 // (including if the dividend is +-INF).
2328 // If dividend must be +-INF, the range is just +-INF
2329 // (including if the dividend is zero).
2330 if (zero_p (rh_lb
, rh_ub
) || singleton_inf_p (lh_lb
, lh_ub
))
2331 return inf_range (lb
, ub
, signbit_known
);
2333 // Otherwise if both operands may be zero, divisor could be
2334 // nextafter(0.0, +-1.0) and dividend +-0.0
2335 // in which case result is going to INF or vice versa and
2336 // result +0.0. So, all we can say for that case is if the
2337 // signs of divisor and dividend are always the same we have
2338 // [+0.0, +INF], if they are always different we have
2339 // [-INF, -0.0]. If they vary, VARING.
2340 // If both may be +-INF, divisor could be INF and dividend FLT_MAX,
2341 // in which case result is going to INF or vice versa and
2342 // result +0.0. So, all we can say for that case is if the
2343 // signs of divisor and dividend are always the same we have
2344 // [+0.0, +INF], if they are always different we have
2345 // [-INF, -0.0]. If they vary, VARYING.
2347 return zero_to_inf_range (lb
, ub
, signbit_known
);
2349 REAL_VALUE_TYPE cp
[8];
2350 // Do a cross-division. At this point none of the divisions should
2352 frange_arithmetic (RDIV_EXPR
, type
, cp
[0], lh_lb
, rh_lb
, dconstninf
);
2353 frange_arithmetic (RDIV_EXPR
, type
, cp
[1], lh_lb
, rh_ub
, dconstninf
);
2354 frange_arithmetic (RDIV_EXPR
, type
, cp
[2], lh_ub
, rh_lb
, dconstninf
);
2355 frange_arithmetic (RDIV_EXPR
, type
, cp
[3], lh_ub
, rh_ub
, dconstninf
);
2356 frange_arithmetic (RDIV_EXPR
, type
, cp
[4], lh_lb
, rh_lb
, dconstinf
);
2357 frange_arithmetic (RDIV_EXPR
, type
, cp
[5], lh_lb
, rh_ub
, dconstinf
);
2358 frange_arithmetic (RDIV_EXPR
, type
, cp
[6], lh_ub
, rh_lb
, dconstinf
);
2359 frange_arithmetic (RDIV_EXPR
, type
, cp
[7], lh_ub
, rh_ub
, dconstinf
);
2361 find_range (lb
, ub
, cp
);
2363 // If divisor may be zero (but is not known to be only zero),
2364 // and dividend can't be zero, the range can go up to -INF or +INF
2365 // depending on the signs.
2366 if (contains_zero_p (rh_lb
, rh_ub
))
2368 if (signbit_known
<= 0)
2369 real_inf (&lb
, true);
2370 if (signbit_known
>= 0)
2371 real_inf (&ub
, false);
2376 // Instantiate a range_op_table for floating point operations.
2377 static floating_op_table global_floating_table
;
2379 // Pointer to the float table so the dispatch code can access it.
2380 floating_op_table
*floating_tree_table
= &global_floating_table
;
2382 floating_op_table::floating_op_table ()
2384 set (SSA_NAME
, fop_identity
);
2385 set (PAREN_EXPR
, fop_identity
);
2386 set (OBJ_TYPE_REF
, fop_identity
);
2387 set (REAL_CST
, fop_identity
);
2389 // All the relational operators are expected to work, because the
2390 // calculation of ranges on outgoing edges expect the handlers to be
2392 set (EQ_EXPR
, fop_equal
);
2393 set (NE_EXPR
, fop_not_equal
);
2394 set (LT_EXPR
, fop_lt
);
2395 set (LE_EXPR
, fop_le
);
2396 set (GT_EXPR
, fop_gt
);
2397 set (GE_EXPR
, fop_ge
);
2398 set (UNLE_EXPR
, fop_unordered_le
);
2399 set (UNLT_EXPR
, fop_unordered_lt
);
2400 set (UNGE_EXPR
, fop_unordered_ge
);
2401 set (UNGT_EXPR
, fop_unordered_gt
);
2402 set (UNEQ_EXPR
, fop_unordered_equal
);
2403 set (ORDERED_EXPR
, fop_ordered
);
2404 set (UNORDERED_EXPR
, fop_unordered
);
2406 set (ABS_EXPR
, fop_abs
);
2407 set (NEGATE_EXPR
, fop_negate
);
2408 set (PLUS_EXPR
, fop_plus
);
2409 set (MINUS_EXPR
, fop_minus
);
2410 set (MULT_EXPR
, fop_mult
);
2411 set (RDIV_EXPR
, fop_div
);
2414 // Return a pointer to the range_operator_float instance, if there is
2415 // one associated with tree_code CODE.
2417 range_operator_float
*
2418 floating_op_table::operator[] (enum tree_code code
)
2420 return m_range_tree
[code
];
2423 // Add OP to the handler table for CODE.
2426 floating_op_table::set (enum tree_code code
, range_operator_float
&op
)
2428 gcc_checking_assert (m_range_tree
[code
] == NULL
);
2429 m_range_tree
[code
] = &op
;
2433 #include "selftest.h"
2438 // Build an frange from string endpoints.
2441 frange_float (const char *lb
, const char *ub
, tree type
= float_type_node
)
2443 REAL_VALUE_TYPE min
, max
;
2444 gcc_assert (real_from_string (&min
, lb
) == 0);
2445 gcc_assert (real_from_string (&max
, ub
) == 0);
2446 return frange (type
, min
, max
);
2450 range_op_float_tests ()
2453 frange
trange (float_type_node
);
2455 // negate([-5, +10]) => [-10, 5]
2456 r0
= frange_float ("-5", "10");
2457 fop_negate
.fold_range (r
, float_type_node
, r0
, trange
);
2458 ASSERT_EQ (r
, frange_float ("-10", "5"));
2460 // negate([0, 1] -NAN) => [-1, -0] +NAN
2461 r0
= frange_float ("0", "1");
2462 r0
.update_nan (true);
2463 fop_negate
.fold_range (r
, float_type_node
, r0
, trange
);
2464 r1
= frange_float ("-1", "-0");
2465 r1
.update_nan (false);
2468 // [-INF,+INF] + [-INF,+INF] could be a NAN.
2469 range_op_handler
plus (PLUS_EXPR
, float_type_node
);
2470 r0
.set_varying (float_type_node
);
2471 r1
.set_varying (float_type_node
);
2474 plus
.fold_range (r
, float_type_node
, r0
, r1
);
2475 if (HONOR_NANS (float_type_node
))
2476 ASSERT_TRUE (r
.maybe_isnan ());
2479 } // namespace selftest
2481 #endif // CHECKING_P