ada: Fix minor glitch in finish_record_type
[official-gcc.git] / gcc / range-op-float.cc
blobcc729e12a9ec0b2c24cebfd59e3563f64a3c78cd
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)
10 any later version.
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/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "insn-codes.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "gimple.h"
29 #include "cfghooks.h"
30 #include "tree-pass.h"
31 #include "ssa.h"
32 #include "optabs-tree.h"
33 #include "gimple-pretty-print.h"
34 #include "diagnostic-core.h"
35 #include "flags.h"
36 #include "fold-const.h"
37 #include "stor-layout.h"
38 #include "calls.h"
39 #include "cfganal.h"
40 #include "gimple-iterator.h"
41 #include "gimple-fold.h"
42 #include "tree-eh.h"
43 #include "gimple-walk.h"
44 #include "tree-cfg.h"
45 #include "wide-int.h"
46 #include "value-relation.h"
47 #include "range-op.h"
48 #include "range-op-mixed.h"
50 // Default definitions for floating point operators.
52 bool
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))
58 return true;
59 if (op1.known_isnan () || op2.known_isnan ())
61 r.set_nan (type);
62 return true;
65 REAL_VALUE_TYPE lb, ub;
66 bool maybe_nan;
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);
75 if (lb_nan && ub_nan)
77 r.set_nan (type);
78 return true;
80 if (lb_nan)
81 lb = dconstninf;
82 else if (ub_nan)
83 ub = dconstinf;
85 r.set (type, lb, ub);
87 if (lb_nan || ub_nan || maybe_nan
88 || op1.maybe_isnan ()
89 || op2.maybe_isnan ())
90 // Keep the default NAN (with a varying sign) set by the setter.
92 else
93 r.clear_nan ();
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);
109 else
111 REAL_VALUE_TYPE max = real_max_representable (type);
112 r.set (type, max, inf);
116 r.flush_denormals_to_zero ();
118 return true;
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.
124 void
125 range_operator::rv_fold (REAL_VALUE_TYPE &lb,
126 REAL_VALUE_TYPE &ub,
127 bool &maybe_nan,
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,
133 relation_kind) const
135 lb = dconstninf;
136 ub = dconstinf;
137 maybe_nan = true;
140 bool
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,
145 relation_trio) const
147 return false;
150 bool
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,
155 relation_trio) const
157 return false;
160 bool
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,
165 relation_trio) const
167 return false;
170 bool
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,
175 relation_trio) const
177 return false;
180 bool
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,
185 relation_trio) const
187 return false;
190 bool
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,
195 relation_trio) const
197 return false;
200 bool
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,
205 relation_trio) const
207 return false;
210 relation_kind
211 range_operator::lhs_op1_relation (const frange &lhs ATTRIBUTE_UNUSED,
212 const frange &op1 ATTRIBUTE_UNUSED,
213 const frange &op2 ATTRIBUTE_UNUSED,
214 relation_kind) const
216 return VREL_VARYING;
219 relation_kind
220 range_operator::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED,
221 const frange &op1 ATTRIBUTE_UNUSED,
222 const frange &op2 ATTRIBUTE_UNUSED,
223 relation_kind) const
225 return VREL_VARYING;
228 relation_kind
229 range_operator::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
230 const frange &op1 ATTRIBUTE_UNUSED,
231 const frange &op2 ATTRIBUTE_UNUSED,
232 relation_kind) const
234 return VREL_VARYING;
237 relation_kind
238 range_operator::lhs_op2_relation (const frange &lhs ATTRIBUTE_UNUSED,
239 const frange &op1 ATTRIBUTE_UNUSED,
240 const frange &op2 ATTRIBUTE_UNUSED,
241 relation_kind) const
243 return VREL_VARYING;
246 relation_kind
247 range_operator::op1_op2_relation (const irange &,
248 const frange &,
249 const frange &) const
251 return VREL_VARYING;
255 relation_kind
256 range_operator::op1_op2_relation (const frange &,
257 const frange &,
258 const frange &) const
260 return VREL_VARYING;
263 // Return TRUE if OP1 and OP2 may be a NAN.
265 static inline bool
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
272 // account.
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,
277 // return false.
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.
297 static inline bool
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
308 // special cases.
309 if (rel == VREL_EQ)
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:
316 // if (x_3 >= y_5)
317 // ;
318 // else
319 // ;; With NANs the relation here is basically VREL_UNLT, so we
320 // ;; can't fold the following:
321 // if (x_3 < y_5)
322 else if (relation_union (rel, my_rel) == my_rel)
324 r = range_true (type);
325 return true;
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);
332 return true;
335 // If either operand is undefined, return VARYING.
336 if (empty_range_varying (r, type, op1, op2))
337 return true;
339 return false;
342 // Set VALUE to its next real value, or INF if the operation overflows.
344 void
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);
358 else
360 REAL_VALUE_TYPE tmp;
361 real_nextafter (&tmp, REAL_MODE_FORMAT (mode), &value, &inf);
362 value = tmp;
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. ??
377 void
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)
397 && !inexact
398 && real_iszero (&result)
399 && !real_isneg (&result)
400 && real_isneg (&inf))
402 REAL_VALUE_TYPE op2a = op2;
403 if (code == PLUS_EXPR)
404 op2a.sign ^= 1;
405 if (real_isneg (&op1) == real_isneg (&op2a) && real_equal (&op1, &op2a))
406 result.sign = 1;
409 // Be extra careful if there may be discrepancies between the
410 // compile and runtime results.
411 bool round = false;
412 if (mode_composite)
413 round = true;
414 else
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
429 // extra buffer.
430 if (!inexact)
431 round = false;
432 else
434 REAL_VALUE_TYPE tmp = result, tmp2;
435 frange_nextafter (mode, tmp, inf);
436 // TMP is at this point the maximum representable
437 // number.
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))
442 round = false;
446 if (round && (inexact || !real_identical (&result, &value)))
448 if (mode_composite
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);
457 else
458 frange_nextafter (mode, result, inf);
460 if (mode_composite)
461 switch (code)
463 case PLUS_EXPR:
464 case MINUS_EXPR:
465 // ibm-ldouble-format documents 1ulp for + and -.
466 frange_nextafter (mode, result, inf);
467 break;
468 case MULT_EXPR:
469 // ibm-ldouble-format documents 2ulps for *.
470 frange_nextafter (mode, result, inf);
471 frange_nextafter (mode, result, inf);
472 break;
473 case RDIV_EXPR:
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);
478 break;
479 default:
480 break;
484 // Crop R to [-INF, MAX] where MAX is the maximum representable number
485 // for TYPE.
487 static inline void
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);
492 r.intersect (tmp);
495 // Crop R to [MIN, +INF] where MIN is the minimum representable number
496 // for TYPE.
498 static inline void
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 ());
503 r.intersect (tmp);
506 // Crop R to [MIN, MAX] where MAX is the maximum representable number
507 // for TYPE and MIN the minimum representable number for TYPE.
509 static inline void
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);
515 r.intersect (tmp);
518 // If zero is in R, make sure both -0.0 and +0.0 are in the range.
520 static inline void
521 frange_add_zeros (frange &r, tree type)
523 if (r.undefined_p () || r.known_isnan ())
524 return;
526 if (HONOR_SIGNED_ZEROS (type)
527 && (real_iszero (&r.lower_bound ()) || real_iszero (&r.upper_bound ())))
529 frange zero;
530 zero.set_zero (type);
531 r.union_ (zero);
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
537 // form.
539 static bool
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);
550 return true;
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
555 // form.
557 static bool
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))
566 r.set_nan (type);
567 else
568 r.set_undefined ();
569 return false;
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);
582 return true;
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
587 // form.
589 static bool
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);
600 return true;
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
605 // form.
607 static bool
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))
616 r.set_nan (type);
617 else
618 r.set_undefined ();
619 return false;
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);
632 return true;
636 bool
637 operator_identity::fold_range (frange &r, tree, const frange &op1,
638 const frange &, relation_trio) const
640 r = op1;
641 return true;
644 bool
645 operator_identity::op1_range (frange &r, tree, const frange &lhs,
646 const frange &, relation_trio) const
648 r = lhs;
649 return true;
652 bool
653 operator_cst::fold_range (frange &r, tree, const frange &op1,
654 const frange &, relation_trio) const
656 r = op1;
657 return true;
660 bool
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 ());
668 bool
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))
674 return true;
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 ())
682 if (op1 == op2)
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);
688 else
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);
698 else
700 // If ranges do not intersect, we know the range is not equal,
701 // otherwise we don't know anything for sure.
702 frange tmp = op1;
703 tmp.intersect (op2);
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);
714 else
715 r = range_false (type);
717 else
718 r = range_true_and_false (type);
720 return true;
723 bool
724 operator_equal::op1_range (frange &r, tree type,
725 const irange &lhs,
726 const frange &op2,
727 relation_trio trio) const
729 relation_kind rel = trio.op1_op2 ();
730 switch (get_bool_state (r, lhs, type))
732 case BRS_TRUE:
733 // The TRUE side of x == NAN is unreachable.
734 if (op2.known_isnan ())
735 r.set_undefined ();
736 else
738 // If it's true, the result is the same as OP2.
739 r = 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.
743 r.clear_nan ();
745 break;
747 case BRS_FALSE:
748 // The FALSE side of op1 == op1 implies op1 is a NAN.
749 if (rel == VREL_EQ)
750 r.set_nan (type);
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);
762 else
763 r.set_varying (type);
764 break;
766 default:
767 break;
769 return true;
772 // Check if the LHS range indicates a relation between OP1 and OP2.
774 relation_kind
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.
782 if (lhs.zero_p ())
783 return VREL_NE;
785 // TRUE = op1 == op2 indicates EQ_EXPR.
786 if (!contains_zero_p (lhs))
787 return VREL_EQ;
788 return VREL_VARYING;
791 bool
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.
799 if (rel == VREL_NE)
801 r = range_true (type);
802 return true;
804 if (frelop_early_resolve (r, type, op1, op2, trio, VREL_NE))
805 return true;
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 ())
814 if (op1 == op2)
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);
820 else
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);
830 else
832 // If ranges do not intersect, we know the range is not equal,
833 // otherwise we don't know anything for sure.
834 frange tmp = op1;
835 tmp.intersect (op2);
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);
846 else
847 r = range_true (type);
849 else
850 r = range_true_and_false (type);
852 return true;
855 bool
856 operator_not_equal::op1_range (frange &r, tree type,
857 const irange &lhs,
858 const frange &op2,
859 relation_trio trio) const
861 relation_kind rel = trio.op1_op2 ();
862 switch (get_bool_state (r, lhs, type))
864 case BRS_TRUE:
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
871 // maybe (VARYING).
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)
877 r.set_nan (type);
878 else
879 r.set_varying (type);
880 break;
882 case BRS_FALSE:
883 // The FALSE side of x != NAN is impossible.
884 if (op2.known_isnan ())
885 r.set_undefined ();
886 else
888 // If it's false, the result is the same as OP2.
889 r = 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.
893 r.clear_nan ();
895 break;
897 default:
898 break;
900 return true;
904 // Check if the LHS range indicates a relation between OP1 and OP2.
906 relation_kind
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.
914 if (lhs.zero_p ())
915 return VREL_EQ;
917 // TRUE = op1 != op2 indicates NE_EXPR.
918 if (!contains_zero_p (lhs))
919 return VREL_NE;
920 return VREL_VARYING;
923 bool
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.
931 if (rel == VREL_EQ)
933 r = range_false (type);
934 return true;
936 if (frelop_early_resolve (r, type, op1, op2, trio, VREL_LT))
937 return true;
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);
946 else
947 r = range_true_and_false (type);
948 return true;
951 bool
952 operator_lt::op1_range (frange &r,
953 tree type,
954 const irange &lhs,
955 const frange &op2,
956 relation_trio) const
958 switch (get_bool_state (r, lhs, type))
960 case BRS_TRUE:
961 // The TRUE side of x < NAN is unreachable.
962 if (op2.known_isnan ())
963 r.set_undefined ();
964 else if (op2.undefined_p ())
965 return false;
966 else if (build_lt (r, type, op2))
968 r.clear_nan ();
969 // x < y implies x is not +INF.
970 frange_drop_inf (r, type);
972 break;
974 case BRS_FALSE:
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);
978 else
979 build_ge (r, type, op2);
980 break;
982 default:
983 break;
985 return true;
988 bool
989 operator_lt::op2_range (frange &r,
990 tree type,
991 const irange &lhs,
992 const frange &op1,
993 relation_trio) const
995 switch (get_bool_state (r, lhs, type))
997 case BRS_TRUE:
998 // The TRUE side of NAN < x is unreachable.
999 if (op1.known_isnan ())
1000 r.set_undefined ();
1001 else if (op1.undefined_p ())
1002 return false;
1003 else if (build_gt (r, type, op1))
1005 r.clear_nan ();
1006 // x < y implies y is not -INF.
1007 frange_drop_ninf (r, type);
1009 break;
1011 case BRS_FALSE:
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);
1015 else
1016 build_le (r, type, op1);
1017 break;
1019 default:
1020 break;
1022 return true;
1026 // Check if the LHS range indicates a relation between OP1 and OP2.
1028 relation_kind
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.
1036 if (lhs.zero_p ())
1037 return VREL_GE;
1039 // TRUE = op1 < op2 indicates LT_EXPR.
1040 if (!contains_zero_p (lhs))
1041 return VREL_LT;
1042 return VREL_VARYING;
1045 bool
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))
1051 return true;
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);
1060 else
1061 r = range_true_and_false (type);
1062 return true;
1065 bool
1066 operator_le::op1_range (frange &r,
1067 tree type,
1068 const irange &lhs,
1069 const frange &op2,
1070 relation_trio) const
1072 switch (get_bool_state (r, lhs, type))
1074 case BRS_TRUE:
1075 // The TRUE side of x <= NAN is unreachable.
1076 if (op2.known_isnan ())
1077 r.set_undefined ();
1078 else if (op2.undefined_p ())
1079 return false;
1080 else if (build_le (r, type, op2))
1081 r.clear_nan ();
1082 break;
1084 case BRS_FALSE:
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);
1088 else
1089 build_gt (r, type, op2);
1090 break;
1092 default:
1093 break;
1095 return true;
1098 bool
1099 operator_le::op2_range (frange &r,
1100 tree type,
1101 const irange &lhs,
1102 const frange &op1,
1103 relation_trio) const
1105 switch (get_bool_state (r, lhs, type))
1107 case BRS_TRUE:
1108 // The TRUE side of NAN <= x is unreachable.
1109 if (op1.known_isnan ())
1110 r.set_undefined ();
1111 else if (op1.undefined_p ())
1112 return false;
1113 else if (build_ge (r, type, op1))
1114 r.clear_nan ();
1115 break;
1117 case BRS_FALSE:
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 ())
1122 return false;
1123 else
1124 build_lt (r, type, op1);
1125 break;
1127 default:
1128 break;
1130 return true;
1133 // Check if the LHS range indicates a relation between OP1 and OP2.
1135 relation_kind
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.
1143 if (lhs.zero_p ())
1144 return VREL_GT;
1146 // TRUE = op1 <= op2 indicates LE_EXPR.
1147 if (!contains_zero_p (lhs))
1148 return VREL_LE;
1149 return VREL_VARYING;
1152 bool
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.
1160 if (rel == VREL_EQ)
1162 r = range_false (type);
1163 return true;
1165 if (frelop_early_resolve (r, type, op1, op2, trio, VREL_GT))
1166 return true;
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);
1175 else
1176 r = range_true_and_false (type);
1177 return true;
1180 bool
1181 operator_gt::op1_range (frange &r,
1182 tree type,
1183 const irange &lhs,
1184 const frange &op2,
1185 relation_trio) const
1187 switch (get_bool_state (r, lhs, type))
1189 case BRS_TRUE:
1190 // The TRUE side of x > NAN is unreachable.
1191 if (op2.known_isnan ())
1192 r.set_undefined ();
1193 else if (op2.undefined_p ())
1194 return false;
1195 else if (build_gt (r, type, op2))
1197 r.clear_nan ();
1198 // x > y implies x is not -INF.
1199 frange_drop_ninf (r, type);
1201 break;
1203 case BRS_FALSE:
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 ())
1208 return false;
1209 else
1210 build_le (r, type, op2);
1211 break;
1213 default:
1214 break;
1216 return true;
1219 bool
1220 operator_gt::op2_range (frange &r,
1221 tree type,
1222 const irange &lhs,
1223 const frange &op1,
1224 relation_trio) const
1226 switch (get_bool_state (r, lhs, type))
1228 case BRS_TRUE:
1229 // The TRUE side of NAN > x is unreachable.
1230 if (op1.known_isnan ())
1231 r.set_undefined ();
1232 else if (op1.undefined_p ())
1233 return false;
1234 else if (build_lt (r, type, op1))
1236 r.clear_nan ();
1237 // x > y implies y is not +INF.
1238 frange_drop_inf (r, type);
1240 break;
1242 case BRS_FALSE:
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 ())
1247 return false;
1248 else
1249 build_ge (r, type, op1);
1250 break;
1252 default:
1253 break;
1255 return true;
1258 // Check if the LHS range indicates a relation between OP1 and OP2.
1260 relation_kind
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.
1268 if (lhs.zero_p ())
1269 return VREL_LE;
1271 // TRUE = op1 > op2 indicates GT_EXPR.
1272 if (!contains_zero_p (lhs))
1273 return VREL_GT;
1274 return VREL_VARYING;
1277 bool
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))
1283 return true;
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);
1292 else
1293 r = range_true_and_false (type);
1294 return true;
1297 bool
1298 operator_ge::op1_range (frange &r,
1299 tree type,
1300 const irange &lhs,
1301 const frange &op2,
1302 relation_trio) const
1304 switch (get_bool_state (r, lhs, type))
1306 case BRS_TRUE:
1307 // The TRUE side of x >= NAN is unreachable.
1308 if (op2.known_isnan ())
1309 r.set_undefined ();
1310 else if (op2.undefined_p ())
1311 return false;
1312 else if (build_ge (r, type, op2))
1313 r.clear_nan ();
1314 break;
1316 case BRS_FALSE:
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 ())
1321 return false;
1322 else
1323 build_lt (r, type, op2);
1324 break;
1326 default:
1327 break;
1329 return true;
1332 bool
1333 operator_ge::op2_range (frange &r, tree type,
1334 const irange &lhs,
1335 const frange &op1,
1336 relation_trio) const
1338 switch (get_bool_state (r, lhs, type))
1340 case BRS_TRUE:
1341 // The TRUE side of NAN >= x is unreachable.
1342 if (op1.known_isnan ())
1343 r.set_undefined ();
1344 else if (op1.undefined_p ())
1345 return false;
1346 else if (build_le (r, type, op1))
1347 r.clear_nan ();
1348 break;
1350 case BRS_FALSE:
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 ())
1355 return false;
1356 else
1357 build_gt (r, type, op1);
1358 break;
1360 default:
1361 break;
1363 return true;
1366 // Check if the LHS range indicates a relation between OP1 and OP2.
1368 relation_kind
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.
1376 if (lhs.zero_p ())
1377 return VREL_LT;
1379 // TRUE = op1 >= op2 indicates GE_EXPR.
1380 if (!contains_zero_p (lhs))
1381 return VREL_GE;
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;
1392 public:
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 ());
1405 } fop_unordered;
1407 bool
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);
1418 else
1419 r = range_true_and_false (type);
1420 return true;
1423 bool
1424 foperator_unordered::op1_range (frange &r, tree type,
1425 const irange &lhs,
1426 const frange &op2,
1427 relation_trio trio) const
1429 relation_kind rel = trio.op1_op2 ();
1430 switch (get_bool_state (r, lhs, type))
1432 case BRS_TRUE:
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 ())
1436 r.set_nan (type);
1437 else
1438 r.set_varying (type);
1439 break;
1441 case BRS_FALSE:
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 ())
1445 r.set_undefined ();
1446 else
1448 r.set_varying (type);
1449 r.clear_nan ();
1451 break;
1453 default:
1454 break;
1456 return true;
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;
1466 public:
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 ());
1479 } fop_ordered;
1481 bool
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);
1490 else
1491 r = range_true_and_false (type);
1492 return true;
1495 bool
1496 foperator_ordered::op1_range (frange &r, tree type,
1497 const irange &lhs,
1498 const frange &op2,
1499 relation_trio trio) const
1501 relation_kind rel = trio.op1_op2 ();
1502 switch (get_bool_state (r, lhs, type))
1504 case BRS_TRUE:
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 ())
1508 r.set_undefined ();
1509 else
1511 r.set_varying (type);
1512 r.clear_nan ();
1514 break;
1516 case BRS_FALSE:
1517 // The FALSE side of op1 ORDERED op1 implies op1 is NAN.
1518 if (rel == VREL_EQ)
1519 r.set_nan (type);
1520 else
1521 r.set_varying (type);
1522 break;
1524 default:
1525 break;
1527 return true;
1530 bool
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))
1536 return true;
1537 if (op1.known_isnan ())
1539 bool sign;
1540 if (op1.nan_signbit_p (sign))
1541 r.set_nan (type, !sign);
1542 else
1543 r.set_nan (type);
1544 return true;
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 ())
1554 bool sign;
1555 if (op1.nan_signbit_p (sign))
1556 r.update_nan (!sign);
1557 else
1558 r.update_nan ();
1560 else
1561 r.clear_nan ();
1562 return true;
1565 bool
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);
1573 bool
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))
1579 return true;
1580 if (op1.known_isnan ())
1582 r.set_nan (type, /*sign=*/false);
1583 return true;
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))
1593 r = op1;
1594 return 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))
1605 max = min;
1606 min = dconst0;
1608 else
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);
1618 else
1619 r.clear_nan ();
1620 return true;
1623 bool
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))
1629 return true;
1630 if (lhs.known_isnan ())
1632 r.set_nan (type);
1633 return true;
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);
1640 r = positives;
1641 // Add -NAN if relevant.
1642 if (r.maybe_isnan ())
1644 frange neg_nan;
1645 neg_nan.set_nan (type, true);
1646 r.union_ (neg_nan);
1648 if (r.known_isnan () || r.undefined_p ())
1649 return true;
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);
1656 return true;
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;
1664 public:
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 ()
1672 || rel == VREL_LT)
1674 r = range_true (type);
1675 return true;
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,
1684 op2_no_nan, trio))
1685 return false;
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))
1689 return true;
1690 else
1692 r = range_true_and_false (type);
1693 return true;
1696 bool op1_range (frange &r, tree type,
1697 const irange &lhs,
1698 const frange &op2,
1699 relation_trio trio) const final override;
1700 bool op2_range (frange &r, tree type,
1701 const irange &lhs,
1702 const frange &op1,
1703 relation_trio trio) const final override;
1704 } fop_unordered_lt;
1706 bool
1707 foperator_unordered_lt::op1_range (frange &r, tree type,
1708 const irange &lhs,
1709 const frange &op2,
1710 relation_trio) const
1712 switch (get_bool_state (r, lhs, type))
1714 case BRS_TRUE:
1715 if (op2.known_isnan () || op2.maybe_isnan ())
1716 r.set_varying (type);
1717 else if (op2.undefined_p ())
1718 return false;
1719 else
1720 build_lt (r, type, op2);
1721 break;
1723 case BRS_FALSE:
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 ())
1727 r.set_undefined ();
1728 else if (op2.undefined_p ())
1729 return false;
1730 else if (build_ge (r, type, op2))
1731 r.clear_nan ();
1732 break;
1734 default:
1735 break;
1737 return true;
1740 bool
1741 foperator_unordered_lt::op2_range (frange &r, tree type,
1742 const irange &lhs,
1743 const frange &op1,
1744 relation_trio) const
1746 switch (get_bool_state (r, lhs, type))
1748 case BRS_TRUE:
1749 if (op1.known_isnan () || op1.maybe_isnan ())
1750 r.set_varying (type);
1751 else if (op1.undefined_p ())
1752 return false;
1753 else
1754 build_gt (r, type, op1);
1755 break;
1757 case BRS_FALSE:
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 ())
1761 r.set_undefined ();
1762 else if (op1.undefined_p ())
1763 return false;
1764 else if (build_le (r, type, op1))
1765 r.clear_nan ();
1766 break;
1768 default:
1769 break;
1771 return true;
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;
1779 public:
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 ()
1787 || rel == VREL_LE)
1789 r = range_true (type);
1790 return true;
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,
1799 op2_no_nan, trio))
1800 return false;
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))
1804 return true;
1805 else
1807 r = range_true_and_false (type);
1808 return true;
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;
1817 } fop_unordered_le;
1819 bool
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))
1826 case BRS_TRUE:
1827 if (op2.known_isnan () || op2.maybe_isnan ())
1828 r.set_varying (type);
1829 else if (op2.undefined_p ())
1830 return false;
1831 else
1832 build_le (r, type, op2);
1833 break;
1835 case BRS_FALSE:
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 ())
1839 r.set_undefined ();
1840 else if (build_gt (r, type, op2))
1841 r.clear_nan ();
1842 break;
1844 default:
1845 break;
1847 return true;
1850 bool
1851 foperator_unordered_le::op2_range (frange &r,
1852 tree type,
1853 const irange &lhs,
1854 const frange &op1,
1855 relation_trio) const
1857 switch (get_bool_state (r, lhs, type))
1859 case BRS_TRUE:
1860 if (op1.known_isnan () || op1.maybe_isnan ())
1861 r.set_varying (type);
1862 else if (op1.undefined_p ())
1863 return false;
1864 else
1865 build_ge (r, type, op1);
1866 break;
1868 case BRS_FALSE:
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 ())
1872 r.set_undefined ();
1873 else if (op1.undefined_p ())
1874 return false;
1875 else if (build_lt (r, type, op1))
1876 r.clear_nan ();
1877 break;
1879 default:
1880 break;
1882 return true;
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;
1890 public:
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 ()
1898 || rel == VREL_GT)
1900 r = range_true (type);
1901 return true;
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,
1910 op2_no_nan, trio))
1911 return false;
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))
1915 return true;
1916 else
1918 r = range_true_and_false (type);
1919 return true;
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;
1928 } fop_unordered_gt;
1930 bool
1931 foperator_unordered_gt::op1_range (frange &r,
1932 tree type,
1933 const irange &lhs,
1934 const frange &op2,
1935 relation_trio) const
1937 switch (get_bool_state (r, lhs, type))
1939 case BRS_TRUE:
1940 if (op2.known_isnan () || op2.maybe_isnan ())
1941 r.set_varying (type);
1942 else if (op2.undefined_p ())
1943 return false;
1944 else
1945 build_gt (r, type, op2);
1946 break;
1948 case BRS_FALSE:
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 ())
1952 r.set_undefined ();
1953 else if (op2.undefined_p ())
1954 return false;
1955 else if (build_le (r, type, op2))
1956 r.clear_nan ();
1957 break;
1959 default:
1960 break;
1962 return true;
1965 bool
1966 foperator_unordered_gt::op2_range (frange &r,
1967 tree type,
1968 const irange &lhs,
1969 const frange &op1,
1970 relation_trio) const
1972 switch (get_bool_state (r, lhs, type))
1974 case BRS_TRUE:
1975 if (op1.known_isnan () || op1.maybe_isnan ())
1976 r.set_varying (type);
1977 else if (op1.undefined_p ())
1978 return false;
1979 else
1980 build_lt (r, type, op1);
1981 break;
1983 case BRS_FALSE:
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 ())
1987 r.set_undefined ();
1988 else if (op1.undefined_p ())
1989 return false;
1990 else if (build_ge (r, type, op1))
1991 r.clear_nan ();
1992 break;
1994 default:
1995 break;
1997 return true;
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;
2005 public:
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 ()
2013 || rel == VREL_GE)
2015 r = range_true (type);
2016 return true;
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,
2025 op2_no_nan, trio))
2026 return false;
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))
2030 return true;
2031 else
2033 r = range_true_and_false (type);
2034 return true;
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;
2043 } fop_unordered_ge;
2045 bool
2046 foperator_unordered_ge::op1_range (frange &r,
2047 tree type,
2048 const irange &lhs,
2049 const frange &op2,
2050 relation_trio) const
2052 switch (get_bool_state (r, lhs, type))
2054 case BRS_TRUE:
2055 if (op2.known_isnan () || op2.maybe_isnan ())
2056 r.set_varying (type);
2057 else if (op2.undefined_p ())
2058 return false;
2059 else
2060 build_ge (r, type, op2);
2061 break;
2063 case BRS_FALSE:
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 ())
2067 r.set_undefined ();
2068 else if (op2.undefined_p ())
2069 return false;
2070 else if (build_lt (r, type, op2))
2071 r.clear_nan ();
2072 break;
2074 default:
2075 break;
2077 return true;
2080 bool
2081 foperator_unordered_ge::op2_range (frange &r, tree type,
2082 const irange &lhs,
2083 const frange &op1,
2084 relation_trio) const
2086 switch (get_bool_state (r, lhs, type))
2088 case BRS_TRUE:
2089 if (op1.known_isnan () || op1.maybe_isnan ())
2090 r.set_varying (type);
2091 else if (op1.undefined_p ())
2092 return false;
2093 else
2094 build_le (r, type, op1);
2095 break;
2097 case BRS_FALSE:
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 ())
2101 r.set_undefined ();
2102 else if (op1.undefined_p ())
2103 return false;
2104 else if (build_gt (r, type, op1))
2105 r.clear_nan ();
2106 break;
2108 default:
2109 break;
2111 return true;
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;
2119 public:
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 ()
2127 || rel == VREL_EQ)
2129 r = range_true (type);
2130 return true;
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,
2139 op2_no_nan, trio))
2140 return false;
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))
2144 return true;
2145 else
2147 r = range_true_and_false (type);
2148 return true;
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;
2162 bool
2163 foperator_unordered_equal::op1_range (frange &r, tree type,
2164 const irange &lhs,
2165 const frange &op2,
2166 relation_trio) const
2168 switch (get_bool_state (r, lhs, type))
2170 case BRS_TRUE:
2171 // If it's true, the result is the same as OP2 plus a NAN.
2172 r = op2;
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.
2176 r.update_nan ();
2177 break;
2179 case BRS_FALSE:
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 ())
2183 r.set_undefined ();
2184 else
2186 // The false side indicates !NAN and not equal. We can at least
2187 // represent !NAN.
2188 r.set_varying (type);
2189 r.clear_nan ();
2191 break;
2193 default:
2194 break;
2196 return true;
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;
2204 public:
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 if (op1.known_isnan () || op2.known_isnan ())
2211 r = range_false (type);
2212 return true;
2214 frange op1_no_nan = op1;
2215 frange op2_no_nan = op2;
2216 if (op1.maybe_isnan ())
2217 op1_no_nan.clear_nan ();
2218 if (op2.maybe_isnan ())
2219 op2_no_nan.clear_nan ();
2220 if (!range_op_handler (NE_EXPR).fold_range (r, type, op1_no_nan,
2221 op2_no_nan, trio))
2222 return false;
2223 // The result is the same as the ordered version when the
2224 // comparison is true or when the operands cannot be NANs.
2225 if (!maybe_isnan (op1, op2) || r == range_false (type))
2226 return true;
2227 else
2229 r = range_true_and_false (type);
2230 return true;
2233 bool op1_range (frange &r, tree type,
2234 const irange &lhs, const frange &op2,
2235 relation_trio = TRIO_VARYING) const final override;
2236 bool op2_range (frange &r, tree type,
2237 const irange &lhs, const frange &op1,
2238 relation_trio rel = TRIO_VARYING) const final override
2240 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
2242 } fop_ltgt;
2244 bool
2245 foperator_ltgt::op1_range (frange &r, tree type,
2246 const irange &lhs,
2247 const frange &op2,
2248 relation_trio) const
2250 switch (get_bool_state (r, lhs, type))
2252 case BRS_TRUE:
2253 // A true LTGT means both operands are !NAN, so it's
2254 // impossible for op2 to be a NAN.
2255 if (op2.known_isnan ())
2256 r.set_undefined ();
2257 else
2259 // The true side indicates !NAN and not equal. We can at least
2260 // represent !NAN.
2261 r.set_varying (type);
2262 r.clear_nan ();
2264 break;
2266 case BRS_FALSE:
2267 // If it's false, the result is the same as OP2 plus a NAN.
2268 r = op2;
2269 // Add both zeros if there's the possibility of zero equality.
2270 frange_add_zeros (r, type);
2271 // Add the possibility of a NAN.
2272 r.update_nan ();
2273 break;
2275 default:
2276 break;
2278 return true;
2281 // Final tweaks for float binary op op1_range/op2_range.
2282 // Return TRUE if the operation is performed and a valid range is available.
2284 static bool
2285 float_binary_op_range_finish (bool ret, frange &r, tree type,
2286 const frange &lhs, bool div_op2 = false)
2288 if (!ret)
2289 return false;
2291 // If we get a known NAN from reverse op, it means either that
2292 // the other operand was known NAN (in that case we know nothing),
2293 // or the reverse operation introduced a known NAN.
2294 // Say for lhs = op1 * op2 if lhs is [-0, +0] and op2 is too,
2295 // 0 / 0 is known NAN. Just punt in that case.
2296 // If NANs aren't honored, we get for 0 / 0 UNDEFINED, so punt as well.
2297 // Or if lhs is a known NAN, we also don't know anything.
2298 if (r.known_isnan () || lhs.known_isnan () || r.undefined_p ())
2300 r.set_varying (type);
2301 return true;
2304 // If lhs isn't NAN, then neither operand could be NAN,
2305 // even if the reverse operation does introduce a maybe_nan.
2306 if (!lhs.maybe_isnan ())
2308 r.clear_nan ();
2309 if (div_op2
2310 ? !(real_compare (LE_EXPR, &lhs.lower_bound (), &dconst0)
2311 && real_compare (GE_EXPR, &lhs.upper_bound (), &dconst0))
2312 : !(real_isinf (&lhs.lower_bound ())
2313 || real_isinf (&lhs.upper_bound ())))
2314 // For reverse + or - or * or op1 of /, if result is finite, then
2315 // r must be finite too, as X + INF or X - INF or X * INF or
2316 // INF / X is always +-INF or NAN. For op2 of /, if result is
2317 // non-zero and not NAN, r must be finite, as X / INF is always
2318 // 0 or NAN.
2319 frange_drop_infs (r, type);
2321 // If lhs is a maybe or known NAN, the operand could be
2322 // NAN.
2323 else
2324 r.update_nan ();
2325 return true;
2328 // True if [lb, ub] is [+-0, +-0].
2329 static bool
2330 zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2332 return real_iszero (&lb) && real_iszero (&ub);
2335 // True if +0 or -0 is in [lb, ub] range.
2336 static bool
2337 contains_zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2339 return (real_compare (LE_EXPR, &lb, &dconst0)
2340 && real_compare (GE_EXPR, &ub, &dconst0));
2343 // True if [lb, ub] is [-INF, -INF] or [+INF, +INF].
2344 static bool
2345 singleton_inf_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2347 return real_isinf (&lb) && real_isinf (&ub, real_isneg (&lb));
2350 // Return -1 if binary op result must have sign bit set,
2351 // 1 if binary op result must have sign bit clear,
2352 // 0 otherwise.
2353 // Sign bit of binary op result is exclusive or of the
2354 // operand's sign bits.
2355 static int
2356 signbit_known_p (const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
2357 const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub)
2359 if (real_isneg (&lh_lb) == real_isneg (&lh_ub)
2360 && real_isneg (&rh_lb) == real_isneg (&rh_ub))
2362 if (real_isneg (&lh_lb) == real_isneg (&rh_ub))
2363 return 1;
2364 else
2365 return -1;
2367 return 0;
2370 // Set [lb, ub] to [-0, -0], [-0, +0] or [+0, +0] depending on
2371 // signbit_known.
2372 static void
2373 zero_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2375 ub = lb = dconst0;
2376 if (signbit_known <= 0)
2377 lb = dconstm0;
2378 if (signbit_known < 0)
2379 ub = lb;
2382 // Set [lb, ub] to [-INF, -INF], [-INF, +INF] or [+INF, +INF] depending on
2383 // signbit_known.
2384 static void
2385 inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2387 if (signbit_known > 0)
2388 ub = lb = dconstinf;
2389 else if (signbit_known < 0)
2390 ub = lb = dconstninf;
2391 else
2393 lb = dconstninf;
2394 ub = dconstinf;
2398 // Set [lb, ub] to [-INF, -0], [-INF, +INF] or [+0, +INF] depending on
2399 // signbit_known.
2400 static void
2401 zero_to_inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2403 if (signbit_known > 0)
2405 lb = dconst0;
2406 ub = dconstinf;
2408 else if (signbit_known < 0)
2410 lb = dconstninf;
2411 ub = dconstm0;
2413 else
2415 lb = dconstninf;
2416 ub = dconstinf;
2420 /* Extend the LHS range by 1ulp in each direction. For op1_range
2421 or op2_range of binary operations just computing the inverse
2422 operation on ranges isn't sufficient. Consider e.g.
2423 [1., 1.] = op1 + [1., 1.]. op1's range is not [0., 0.], but
2424 [-0x1.0p-54, 0x1.0p-53] (when not -frounding-math), any value for
2425 which adding 1. to it results in 1. after rounding to nearest.
2426 So, for op1_range/op2_range extend the lhs range by 1ulp (or 0.5ulp)
2427 in each direction. See PR109008 for more details. */
2429 static frange
2430 float_widen_lhs_range (tree type, const frange &lhs)
2432 frange ret = lhs;
2433 if (lhs.known_isnan ())
2434 return ret;
2435 REAL_VALUE_TYPE lb = lhs.lower_bound ();
2436 REAL_VALUE_TYPE ub = lhs.upper_bound ();
2437 if (real_isfinite (&lb))
2439 frange_nextafter (TYPE_MODE (type), lb, dconstninf);
2440 if (real_isinf (&lb))
2442 /* For -DBL_MAX, instead of -Inf use
2443 nexttoward (-DBL_MAX, -LDBL_MAX) in a hypothetical
2444 wider type with the same mantissa precision but larger
2445 exponent range; it is outside of range of double values,
2446 but makes it clear it is just one ulp larger rather than
2447 infinite amount larger. */
2448 lb = dconstm1;
2449 SET_REAL_EXP (&lb, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
2451 if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)))
2453 /* If not -frounding-math nor IBM double double, actually widen
2454 just by 0.5ulp rather than 1ulp. */
2455 REAL_VALUE_TYPE tem;
2456 real_arithmetic (&tem, PLUS_EXPR, &lhs.lower_bound (), &lb);
2457 real_arithmetic (&lb, RDIV_EXPR, &tem, &dconst2);
2460 if (real_isfinite (&ub))
2462 frange_nextafter (TYPE_MODE (type), ub, dconstinf);
2463 if (real_isinf (&ub))
2465 /* For DBL_MAX similarly. */
2466 ub = dconst1;
2467 SET_REAL_EXP (&ub, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
2469 if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)))
2471 /* If not -frounding-math nor IBM double double, actually widen
2472 just by 0.5ulp rather than 1ulp. */
2473 REAL_VALUE_TYPE tem;
2474 real_arithmetic (&tem, PLUS_EXPR, &lhs.upper_bound (), &ub);
2475 real_arithmetic (&ub, RDIV_EXPR, &tem, &dconst2);
2478 /* Temporarily disable -ffinite-math-only, so that frange::set doesn't
2479 reduce the range back to real_min_representable (type) as lower bound
2480 or real_max_representable (type) as upper bound. */
2481 bool save_flag_finite_math_only = flag_finite_math_only;
2482 flag_finite_math_only = false;
2483 ret.set (type, lb, ub, lhs.get_nan_state ());
2484 flag_finite_math_only = save_flag_finite_math_only;
2485 return ret;
2488 bool
2489 operator_plus::op1_range (frange &r, tree type, const frange &lhs,
2490 const frange &op2, relation_trio) const
2492 if (lhs.undefined_p ())
2493 return false;
2494 range_op_handler minus (MINUS_EXPR);
2495 if (!minus)
2496 return false;
2497 frange wlhs = float_widen_lhs_range (type, lhs);
2498 return float_binary_op_range_finish (minus.fold_range (r, type, wlhs, op2),
2499 r, type, wlhs);
2502 bool
2503 operator_plus::op2_range (frange &r, tree type,
2504 const frange &lhs, const frange &op1,
2505 relation_trio) const
2507 return op1_range (r, type, lhs, op1);
2510 void
2511 operator_plus::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
2512 bool &maybe_nan, tree type,
2513 const REAL_VALUE_TYPE &lh_lb,
2514 const REAL_VALUE_TYPE &lh_ub,
2515 const REAL_VALUE_TYPE &rh_lb,
2516 const REAL_VALUE_TYPE &rh_ub,
2517 relation_kind) const
2519 frange_arithmetic (PLUS_EXPR, type, lb, lh_lb, rh_lb, dconstninf);
2520 frange_arithmetic (PLUS_EXPR, type, ub, lh_ub, rh_ub, dconstinf);
2522 // [-INF] + [+INF] = NAN
2523 if (real_isinf (&lh_lb, true) && real_isinf (&rh_ub, false))
2524 maybe_nan = true;
2525 // [+INF] + [-INF] = NAN
2526 else if (real_isinf (&lh_ub, false) && real_isinf (&rh_lb, true))
2527 maybe_nan = true;
2528 else
2529 maybe_nan = false;
2533 bool
2534 operator_minus::op1_range (frange &r, tree type,
2535 const frange &lhs, const frange &op2,
2536 relation_trio) const
2538 if (lhs.undefined_p ())
2539 return false;
2540 frange wlhs = float_widen_lhs_range (type, lhs);
2541 return float_binary_op_range_finish (
2542 range_op_handler (PLUS_EXPR).fold_range (r, type, wlhs, op2),
2543 r, type, wlhs);
2546 bool
2547 operator_minus::op2_range (frange &r, tree type,
2548 const frange &lhs, const frange &op1,
2549 relation_trio) const
2551 if (lhs.undefined_p ())
2552 return false;
2553 frange wlhs = float_widen_lhs_range (type, lhs);
2554 return float_binary_op_range_finish (fold_range (r, type, op1, wlhs),
2555 r, type, wlhs);
2558 void
2559 operator_minus::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
2560 bool &maybe_nan, tree type,
2561 const REAL_VALUE_TYPE &lh_lb,
2562 const REAL_VALUE_TYPE &lh_ub,
2563 const REAL_VALUE_TYPE &rh_lb,
2564 const REAL_VALUE_TYPE &rh_ub,
2565 relation_kind) const
2567 frange_arithmetic (MINUS_EXPR, type, lb, lh_lb, rh_ub, dconstninf);
2568 frange_arithmetic (MINUS_EXPR, type, ub, lh_ub, rh_lb, dconstinf);
2570 // [+INF] - [+INF] = NAN
2571 if (real_isinf (&lh_ub, false) && real_isinf (&rh_ub, false))
2572 maybe_nan = true;
2573 // [-INF] - [-INF] = NAN
2574 else if (real_isinf (&lh_lb, true) && real_isinf (&rh_lb, true))
2575 maybe_nan = true;
2576 else
2577 maybe_nan = false;
2581 // Given CP[0] to CP[3] floating point values rounded to -INF,
2582 // set LB to the smallest of them (treating -0 as smaller to +0).
2583 // Given CP[4] to CP[7] floating point values rounded to +INF,
2584 // set UB to the largest of them (treating -0 as smaller to +0).
2586 static void
2587 find_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
2588 const REAL_VALUE_TYPE (&cp)[8])
2590 lb = cp[0];
2591 ub = cp[4];
2592 for (int i = 1; i < 4; ++i)
2594 if (real_less (&cp[i], &lb)
2595 || (real_iszero (&lb) && real_isnegzero (&cp[i])))
2596 lb = cp[i];
2597 if (real_less (&ub, &cp[i + 4])
2598 || (real_isnegzero (&ub) && real_iszero (&cp[i + 4])))
2599 ub = cp[i + 4];
2604 bool
2605 operator_mult::op1_range (frange &r, tree type,
2606 const frange &lhs, const frange &op2,
2607 relation_trio) const
2609 if (lhs.undefined_p ())
2610 return false;
2611 range_op_handler rdiv (RDIV_EXPR);
2612 if (!rdiv)
2613 return false;
2614 frange wlhs = float_widen_lhs_range (type, lhs);
2615 bool ret = rdiv.fold_range (r, type, wlhs, op2);
2616 if (ret == false)
2617 return false;
2618 if (wlhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
2619 return float_binary_op_range_finish (ret, r, type, wlhs);
2620 const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
2621 const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
2622 const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
2623 const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
2624 if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op2_lb, op2_ub))
2625 || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
2626 && (real_isinf (&op2_lb) || real_isinf (&op2_ub))))
2628 // If both lhs and op2 could be zeros or both could be infinities,
2629 // we don't know anything about op1 except maybe for the sign
2630 // and perhaps if it can be NAN or not.
2631 REAL_VALUE_TYPE lb, ub;
2632 int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
2633 zero_to_inf_range (lb, ub, signbit_known);
2634 r.set (type, lb, ub);
2636 // Otherwise, if op2 is a singleton INF and lhs doesn't include INF,
2637 // or if lhs must be zero and op2 doesn't include zero, it would be
2638 // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF
2639 // range. Those are supersets of UNDEFINED, so let's keep that way.
2640 return float_binary_op_range_finish (ret, r, type, wlhs);
2643 bool
2644 operator_mult::op2_range (frange &r, tree type,
2645 const frange &lhs, const frange &op1,
2646 relation_trio) const
2648 return op1_range (r, type, lhs, op1);
2651 void
2652 operator_mult::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
2653 bool &maybe_nan, tree type,
2654 const REAL_VALUE_TYPE &lh_lb,
2655 const REAL_VALUE_TYPE &lh_ub,
2656 const REAL_VALUE_TYPE &rh_lb,
2657 const REAL_VALUE_TYPE &rh_ub,
2658 relation_kind kind) const
2660 bool is_square
2661 = (kind == VREL_EQ
2662 && real_equal (&lh_lb, &rh_lb)
2663 && real_equal (&lh_ub, &rh_ub)
2664 && real_isneg (&lh_lb) == real_isneg (&rh_lb)
2665 && real_isneg (&lh_ub) == real_isneg (&rh_ub));
2667 maybe_nan = false;
2668 // x * x never produces a new NAN and we only multiply the same
2669 // values, so the 0 * INF problematic cases never appear there.
2670 if (!is_square)
2672 // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN.
2673 if ((zero_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub))
2674 || (zero_p (rh_lb, rh_ub) && singleton_inf_p (lh_lb, lh_ub)))
2676 real_nan (&lb, "", 0, TYPE_MODE (type));
2677 ub = lb;
2678 maybe_nan = true;
2679 return;
2682 // Otherwise, if one range includes zero and the other ends with +-INF,
2683 // it is a maybe NAN.
2684 if ((contains_zero_p (lh_lb, lh_ub)
2685 && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
2686 || (contains_zero_p (rh_lb, rh_ub)
2687 && (real_isinf (&lh_lb) || real_isinf (&lh_ub))))
2689 maybe_nan = true;
2691 int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
2693 // If one of the ranges that includes INF is singleton
2694 // and the other range includes zero, the resulting
2695 // range is INF and NAN, because the 0 * INF boundary
2696 // case will be NAN, but already nextafter (0, 1) * INF
2697 // is INF.
2698 if (singleton_inf_p (lh_lb, lh_ub)
2699 || singleton_inf_p (rh_lb, rh_ub))
2700 return inf_range (lb, ub, signbit_known);
2702 // If one of the multiplicands must be zero, the resulting
2703 // range is +-0 and NAN.
2704 if (zero_p (lh_lb, lh_ub) || zero_p (rh_lb, rh_ub))
2705 return zero_range (lb, ub, signbit_known);
2707 // Otherwise one of the multiplicands could be
2708 // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF]
2709 // or similarly with different signs. 0.0 * DBL_MAX
2710 // is still 0.0, nextafter (0.0, 1.0) * INF is still INF,
2711 // so if the signs are always the same or always different,
2712 // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING.
2713 return zero_to_inf_range (lb, ub, signbit_known);
2717 REAL_VALUE_TYPE cp[8];
2718 // Do a cross-product. At this point none of the multiplications
2719 // should produce a NAN.
2720 frange_arithmetic (MULT_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
2721 frange_arithmetic (MULT_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
2722 if (is_square)
2724 // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub)
2725 // as maximum and -0.0 as minimum if 0.0 is in the range,
2726 // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub).
2727 // -0.0 rather than 0.0 because VREL_EQ doesn't prove that
2728 // x and y are bitwise equal, just that they compare equal.
2729 if (contains_zero_p (lh_lb, lh_ub))
2731 if (real_isneg (&lh_lb) == real_isneg (&lh_ub))
2732 cp[1] = dconst0;
2733 else
2734 cp[1] = dconstm0;
2736 else
2737 cp[1] = cp[0];
2738 cp[2] = cp[0];
2739 cp[5] = cp[4];
2740 cp[6] = cp[4];
2742 else
2744 frange_arithmetic (MULT_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
2745 frange_arithmetic (MULT_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
2746 frange_arithmetic (MULT_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
2747 frange_arithmetic (MULT_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
2749 frange_arithmetic (MULT_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
2750 frange_arithmetic (MULT_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);
2752 find_range (lb, ub, cp);
2756 class foperator_div : public range_operator
2758 using range_operator::op1_range;
2759 using range_operator::op2_range;
2760 public:
2761 virtual bool op1_range (frange &r, tree type,
2762 const frange &lhs,
2763 const frange &op2,
2764 relation_trio = TRIO_VARYING) const final override
2766 if (lhs.undefined_p ())
2767 return false;
2768 frange wlhs = float_widen_lhs_range (type, lhs);
2769 bool ret = range_op_handler (MULT_EXPR).fold_range (r, type, wlhs, op2);
2770 if (!ret)
2771 return ret;
2772 if (wlhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
2773 return float_binary_op_range_finish (ret, r, type, wlhs);
2774 const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
2775 const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
2776 const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
2777 const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
2778 if ((contains_zero_p (lhs_lb, lhs_ub)
2779 && (real_isinf (&op2_lb) || real_isinf (&op2_ub)))
2780 || ((contains_zero_p (op2_lb, op2_ub))
2781 && (real_isinf (&lhs_lb) || real_isinf (&lhs_ub))))
2783 // If both lhs could be zero and op2 infinity or vice versa,
2784 // we don't know anything about op1 except maybe for the sign
2785 // and perhaps if it can be NAN or not.
2786 REAL_VALUE_TYPE lb, ub;
2787 int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
2788 zero_to_inf_range (lb, ub, signbit_known);
2789 r.set (type, lb, ub);
2791 return float_binary_op_range_finish (ret, r, type, wlhs);
2793 virtual bool op2_range (frange &r, tree type,
2794 const frange &lhs,
2795 const frange &op1,
2796 relation_trio = TRIO_VARYING) const final override
2798 if (lhs.undefined_p ())
2799 return false;
2800 frange wlhs = float_widen_lhs_range (type, lhs);
2801 bool ret = fold_range (r, type, op1, wlhs);
2802 if (!ret)
2803 return ret;
2804 if (wlhs.known_isnan () || op1.known_isnan () || op1.undefined_p ())
2805 return float_binary_op_range_finish (ret, r, type, wlhs, true);
2806 const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
2807 const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
2808 const REAL_VALUE_TYPE &op1_lb = op1.lower_bound ();
2809 const REAL_VALUE_TYPE &op1_ub = op1.upper_bound ();
2810 if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op1_lb, op1_ub))
2811 || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
2812 && (real_isinf (&op1_lb) || real_isinf (&op1_ub))))
2814 // If both lhs and op1 could be zeros or both could be infinities,
2815 // we don't know anything about op2 except maybe for the sign
2816 // and perhaps if it can be NAN or not.
2817 REAL_VALUE_TYPE lb, ub;
2818 int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op1_lb, op1_ub);
2819 zero_to_inf_range (lb, ub, signbit_known);
2820 r.set (type, lb, ub);
2822 return float_binary_op_range_finish (ret, r, type, wlhs, true);
2824 private:
2825 void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan,
2826 tree type,
2827 const REAL_VALUE_TYPE &lh_lb,
2828 const REAL_VALUE_TYPE &lh_ub,
2829 const REAL_VALUE_TYPE &rh_lb,
2830 const REAL_VALUE_TYPE &rh_ub,
2831 relation_kind) const final override
2833 // +-0.0 / +-0.0 or +-INF / +-INF is a known NAN.
2834 if ((zero_p (lh_lb, lh_ub) && zero_p (rh_lb, rh_ub))
2835 || (singleton_inf_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub)))
2837 real_nan (&lb, "", 0, TYPE_MODE (type));
2838 ub = lb;
2839 maybe_nan = true;
2840 return;
2843 // If +-0.0 is in both ranges, it is a maybe NAN.
2844 if (contains_zero_p (lh_lb, lh_ub) && contains_zero_p (rh_lb, rh_ub))
2845 maybe_nan = true;
2846 // If +-INF is in both ranges, it is a maybe NAN.
2847 else if ((real_isinf (&lh_lb) || real_isinf (&lh_ub))
2848 && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
2849 maybe_nan = true;
2850 else
2851 maybe_nan = false;
2853 int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
2855 // If dividend must be zero, the range is just +-0
2856 // (including if the divisor is +-INF).
2857 // If divisor must be +-INF, the range is just +-0
2858 // (including if the dividend is zero).
2859 if (zero_p (lh_lb, lh_ub) || singleton_inf_p (rh_lb, rh_ub))
2860 return zero_range (lb, ub, signbit_known);
2862 // If divisor must be zero, the range is just +-INF
2863 // (including if the dividend is +-INF).
2864 // If dividend must be +-INF, the range is just +-INF
2865 // (including if the dividend is zero).
2866 if (zero_p (rh_lb, rh_ub) || singleton_inf_p (lh_lb, lh_ub))
2867 return inf_range (lb, ub, signbit_known);
2869 // Otherwise if both operands may be zero, divisor could be
2870 // nextafter(0.0, +-1.0) and dividend +-0.0
2871 // in which case result is going to INF or vice versa and
2872 // result +0.0. So, all we can say for that case is if the
2873 // signs of divisor and dividend are always the same we have
2874 // [+0.0, +INF], if they are always different we have
2875 // [-INF, -0.0]. If they vary, VARYING.
2876 // If both may be +-INF, divisor could be INF and dividend FLT_MAX,
2877 // in which case result is going to INF or vice versa and
2878 // result +0.0. So, all we can say for that case is if the
2879 // signs of divisor and dividend are always the same we have
2880 // [+0.0, +INF], if they are always different we have
2881 // [-INF, -0.0]. If they vary, VARYING.
2882 if (maybe_nan)
2883 return zero_to_inf_range (lb, ub, signbit_known);
2885 REAL_VALUE_TYPE cp[8];
2886 // Do a cross-division. At this point none of the divisions should
2887 // produce a NAN.
2888 frange_arithmetic (RDIV_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
2889 frange_arithmetic (RDIV_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
2890 frange_arithmetic (RDIV_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
2891 frange_arithmetic (RDIV_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
2892 frange_arithmetic (RDIV_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
2893 frange_arithmetic (RDIV_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
2894 frange_arithmetic (RDIV_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
2895 frange_arithmetic (RDIV_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);
2897 find_range (lb, ub, cp);
2899 // If divisor may be zero (but is not known to be only zero),
2900 // and dividend can't be zero, the range can go up to -INF or +INF
2901 // depending on the signs.
2902 if (contains_zero_p (rh_lb, rh_ub))
2904 if (signbit_known <= 0)
2905 real_inf (&lb, true);
2906 if (signbit_known >= 0)
2907 real_inf (&ub, false);
2910 } fop_div;
2913 // Initialize any float operators to the primary table
2915 void
2916 range_op_table::initialize_float_ops ()
2918 set (UNLE_EXPR, fop_unordered_le);
2919 set (UNLT_EXPR, fop_unordered_lt);
2920 set (UNGE_EXPR, fop_unordered_ge);
2921 set (UNGT_EXPR, fop_unordered_gt);
2922 set (UNEQ_EXPR, fop_unordered_equal);
2923 set (ORDERED_EXPR, fop_ordered);
2924 set (UNORDERED_EXPR, fop_unordered);
2925 set (LTGT_EXPR, fop_ltgt);
2926 set (RDIV_EXPR, fop_div);
2929 #if CHECKING_P
2930 #include "selftest.h"
2932 namespace selftest
2935 // Build an frange from string endpoints.
2937 static inline frange
2938 frange_float (const char *lb, const char *ub, tree type = float_type_node)
2940 REAL_VALUE_TYPE min, max;
2941 gcc_assert (real_from_string (&min, lb) == 0);
2942 gcc_assert (real_from_string (&max, ub) == 0);
2943 return frange (type, min, max);
2946 void
2947 range_op_float_tests ()
2949 frange r, r0, r1;
2950 frange trange (float_type_node);
2952 // negate([-5, +10]) => [-10, 5]
2953 r0 = frange_float ("-5", "10");
2954 range_op_handler (NEGATE_EXPR).fold_range (r, float_type_node, r0, trange);
2955 ASSERT_EQ (r, frange_float ("-10", "5"));
2957 // negate([0, 1] -NAN) => [-1, -0] +NAN
2958 r0 = frange_float ("0", "1");
2959 r0.update_nan (true);
2960 range_op_handler (NEGATE_EXPR).fold_range (r, float_type_node, r0, trange);
2961 r1 = frange_float ("-1", "-0");
2962 r1.update_nan (false);
2963 ASSERT_EQ (r, r1);
2965 // [-INF,+INF] + [-INF,+INF] could be a NAN.
2966 range_op_handler plus (PLUS_EXPR);
2967 r0.set_varying (float_type_node);
2968 r1.set_varying (float_type_node);
2969 r0.clear_nan ();
2970 r1.clear_nan ();
2971 plus.fold_range (r, float_type_node, r0, r1);
2972 if (HONOR_NANS (float_type_node))
2973 ASSERT_TRUE (r.maybe_isnan ());
2976 } // namespace selftest
2978 #endif // CHECKING_P