Suppress -fstack-protector warning on hppa.
[official-gcc.git] / gcc / range-op-float.cc
blob929ff9c3f870647c5e06ecbbb648cda8b4c41c8e
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)
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"
49 // Default definitions for floating point operators.
51 bool
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))
57 return true;
58 if (op1.known_isnan () || op2.known_isnan ())
60 r.set_nan (op1.type ());
61 return true;
64 REAL_VALUE_TYPE lb, ub;
65 bool maybe_nan;
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);
74 if (lb_nan && ub_nan)
76 r.set_nan (type);
77 return true;
79 if (lb_nan)
80 lb = dconstninf;
81 else if (ub_nan)
82 ub = dconstinf;
84 r.set (type, lb, ub);
86 if (lb_nan || ub_nan || maybe_nan
87 || op1.maybe_isnan ()
88 || op2.maybe_isnan ())
89 // Keep the default NAN (with a varying sign) set by the setter.
91 else
92 r.clear_nan ();
94 return true;
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.
100 void
101 range_operator_float::rv_fold (REAL_VALUE_TYPE &lb,
102 REAL_VALUE_TYPE &ub,
103 bool &maybe_nan,
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,
109 relation_kind) const
111 lb = dconstninf;
112 ub = dconstinf;
113 maybe_nan = true;
116 bool
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,
121 relation_trio) const
123 return false;
126 bool
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,
131 relation_trio) const
133 return false;
136 bool
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,
141 relation_trio) const
143 return false;
146 bool
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,
151 relation_trio) const
153 return false;
156 bool
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,
161 relation_trio) const
163 return false;
166 bool
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,
171 relation_trio) const
173 return false;
176 relation_kind
177 range_operator_float::lhs_op1_relation (const frange &lhs ATTRIBUTE_UNUSED,
178 const frange &op1 ATTRIBUTE_UNUSED,
179 const frange &op2 ATTRIBUTE_UNUSED,
180 relation_kind) const
182 return VREL_VARYING;
185 relation_kind
186 range_operator_float::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED,
187 const frange &op1 ATTRIBUTE_UNUSED,
188 const frange &op2 ATTRIBUTE_UNUSED,
189 relation_kind) const
191 return VREL_VARYING;
194 relation_kind
195 range_operator_float::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
196 const frange &op1 ATTRIBUTE_UNUSED,
197 const frange &op2 ATTRIBUTE_UNUSED,
198 relation_kind) const
200 return VREL_VARYING;
203 relation_kind
204 range_operator_float::lhs_op2_relation (const frange &lhs ATTRIBUTE_UNUSED,
205 const frange &op1 ATTRIBUTE_UNUSED,
206 const frange &op2 ATTRIBUTE_UNUSED,
207 relation_kind) const
209 return VREL_VARYING;
212 relation_kind
213 range_operator_float::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED) const
215 return VREL_VARYING;
218 relation_kind
219 range_operator_float::op1_op2_relation (const frange &lhs ATTRIBUTE_UNUSED) const
221 return VREL_VARYING;
224 // Return TRUE if OP1 and OP2 may be a NAN.
226 static inline bool
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.
235 inline bool
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))
242 return true;
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.
252 inline void
253 frange_nextafter (enum machine_mode mode,
254 REAL_VALUE_TYPE &value,
255 const REAL_VALUE_TYPE &inf)
257 if (MODE_COMPOSITE_P (mode)
258 && (real_isdenormal (&value, mode) || real_iszero (&value)))
260 // IBM extended denormals only have DFmode precision.
261 REAL_VALUE_TYPE tmp, tmp2;
262 real_convert (&tmp2, DFmode, &value);
263 real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2, &inf);
264 real_convert (&value, mode, &tmp);
266 else
268 REAL_VALUE_TYPE tmp;
269 real_nextafter (&tmp, REAL_MODE_FORMAT (mode), &value, &inf);
270 value = tmp;
274 // Like real_arithmetic, but round the result to INF if the operation
275 // produced inexact results.
277 // ?? There is still one problematic case, i387. With
278 // -fexcess-precision=standard we perform most SF/DFmode arithmetic in
279 // XFmode (long_double_type_node), so that case is OK. But without
280 // -mfpmath=sse, all the SF/DFmode computations are in XFmode
281 // precision (64-bit mantissa) and only occassionally rounded to
282 // SF/DFmode (when storing into memory from the 387 stack). Maybe
283 // this is ok as well though it is just occassionally more precise. ??
285 static void
286 frange_arithmetic (enum tree_code code, tree type,
287 REAL_VALUE_TYPE &result,
288 const REAL_VALUE_TYPE &op1,
289 const REAL_VALUE_TYPE &op2,
290 const REAL_VALUE_TYPE &inf)
292 REAL_VALUE_TYPE value;
293 enum machine_mode mode = TYPE_MODE (type);
294 bool mode_composite = MODE_COMPOSITE_P (mode);
296 bool inexact = real_arithmetic (&value, code, &op1, &op2);
297 real_convert (&result, mode, &value);
299 // Be extra careful if there may be discrepancies between the
300 // compile and runtime results.
301 bool round = false;
302 if (mode_composite)
303 round = true;
304 else
306 bool low = real_isneg (&inf);
307 round = (low ? !real_less (&result, &value)
308 : !real_less (&value, &result));
309 if (real_isinf (&result, !low)
310 && !real_isinf (&value)
311 && !flag_rounding_math)
313 // Use just [+INF, +INF] rather than [MAX, +INF]
314 // even if value is larger than MAX and rounds to
315 // nearest to +INF. Similarly just [-INF, -INF]
316 // rather than [-INF, +MAX] even if value is smaller
317 // than -MAX and rounds to nearest to -INF.
318 // Unless INEXACT is true, in that case we need some
319 // extra buffer.
320 if (!inexact)
321 round = false;
322 else
324 REAL_VALUE_TYPE tmp = result, tmp2;
325 frange_nextafter (mode, tmp, inf);
326 // TMP is at this point the maximum representable
327 // number.
328 real_arithmetic (&tmp2, MINUS_EXPR, &value, &tmp);
329 if (real_isneg (&tmp2) != low
330 && (REAL_EXP (&tmp2) - REAL_EXP (&tmp)
331 >= 2 - REAL_MODE_FORMAT (mode)->p))
332 round = false;
336 if (round && (inexact || !real_identical (&result, &value)))
338 if (mode_composite
339 && (real_isdenormal (&result, mode) || real_iszero (&result)))
341 // IBM extended denormals only have DFmode precision.
342 REAL_VALUE_TYPE tmp, tmp2;
343 real_convert (&tmp2, DFmode, &value);
344 real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2, &inf);
345 real_convert (&result, mode, &tmp);
347 else
348 frange_nextafter (mode, result, inf);
350 if (mode_composite)
351 switch (code)
353 case PLUS_EXPR:
354 case MINUS_EXPR:
355 // ibm-ldouble-format documents 1ulp for + and -.
356 frange_nextafter (mode, result, inf);
357 break;
358 case MULT_EXPR:
359 // ibm-ldouble-format documents 2ulps for *.
360 frange_nextafter (mode, result, inf);
361 frange_nextafter (mode, result, inf);
362 break;
363 case RDIV_EXPR:
364 // ibm-ldouble-format documents 3ulps for /.
365 frange_nextafter (mode, result, inf);
366 frange_nextafter (mode, result, inf);
367 frange_nextafter (mode, result, inf);
368 break;
369 default:
370 break;
374 // Crop R to [-INF, MAX] where MAX is the maximum representable number
375 // for TYPE.
377 static inline void
378 frange_drop_inf (frange &r, tree type)
380 REAL_VALUE_TYPE max = real_max_representable (type);
381 frange tmp (type, r.lower_bound (), max);
382 r.intersect (tmp);
385 // Crop R to [MIN, +INF] where MIN is the minimum representable number
386 // for TYPE.
388 static inline void
389 frange_drop_ninf (frange &r, tree type)
391 REAL_VALUE_TYPE min = real_min_representable (type);
392 frange tmp (type, min, r.upper_bound ());
393 r.intersect (tmp);
396 // Crop R to [MIN, MAX] where MAX is the maximum representable number
397 // for TYPE and MIN the minimum representable number for TYPE.
399 static inline void
400 frange_drop_infs (frange &r, tree type)
402 REAL_VALUE_TYPE max = real_max_representable (type);
403 REAL_VALUE_TYPE min = real_min_representable (type);
404 frange tmp (type, min, max);
405 r.intersect (tmp);
408 // If zero is in R, make sure both -0.0 and +0.0 are in the range.
410 static inline void
411 frange_add_zeros (frange &r, tree type)
413 if (r.undefined_p () || r.known_isnan ())
414 return;
416 if (HONOR_SIGNED_ZEROS (type)
417 && (real_iszero (&r.lower_bound ()) || real_iszero (&r.upper_bound ())))
419 frange zero;
420 zero.set_zero (type);
421 r.union_ (zero);
425 // Build a range that is <= VAL and store it in R. Return TRUE if
426 // further changes may be needed for R, or FALSE if R is in its final
427 // form.
429 static bool
430 build_le (frange &r, tree type, const frange &val)
432 gcc_checking_assert (!val.known_isnan ());
434 REAL_VALUE_TYPE ninf = frange_val_min (type);
435 r.set (type, ninf, val.upper_bound ());
437 // Add both zeros if there's the possibility of zero equality.
438 frange_add_zeros (r, type);
440 return true;
443 // Build a range that is < VAL and store it in R. Return TRUE if
444 // further changes may be needed for R, or FALSE if R is in its final
445 // form.
447 static bool
448 build_lt (frange &r, tree type, const frange &val)
450 gcc_checking_assert (!val.known_isnan ());
452 // < -INF is outside the range.
453 if (real_isinf (&val.upper_bound (), 1))
455 if (HONOR_NANS (type))
456 r.set_nan (type);
457 else
458 r.set_undefined ();
459 return false;
462 REAL_VALUE_TYPE ninf = frange_val_min (type);
463 REAL_VALUE_TYPE prev = val.upper_bound ();
464 machine_mode mode = TYPE_MODE (type);
465 // Default to the conservatively correct closed ranges for
466 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
467 // !HONOR_INFINITIES, nextafter will yield -INF, but frange::set()
468 // will crop the range appropriately.
469 if (!MODE_COMPOSITE_P (mode))
470 frange_nextafter (mode, prev, ninf);
471 r.set (type, ninf, prev);
472 return true;
475 // Build a range that is >= VAL and store it in R. Return TRUE if
476 // further changes may be needed for R, or FALSE if R is in its final
477 // form.
479 static bool
480 build_ge (frange &r, tree type, const frange &val)
482 gcc_checking_assert (!val.known_isnan ());
484 REAL_VALUE_TYPE inf = frange_val_max (type);
485 r.set (type, val.lower_bound (), inf);
487 // Add both zeros if there's the possibility of zero equality.
488 frange_add_zeros (r, type);
490 return true;
493 // Build a range that is > VAL and store it in R. Return TRUE if
494 // further changes may be needed for R, or FALSE if R is in its final
495 // form.
497 static bool
498 build_gt (frange &r, tree type, const frange &val)
500 gcc_checking_assert (!val.known_isnan ());
502 // > +INF is outside the range.
503 if (real_isinf (&val.lower_bound (), 0))
505 if (HONOR_NANS (type))
506 r.set_nan (type);
507 else
508 r.set_undefined ();
509 return false;
512 REAL_VALUE_TYPE inf = frange_val_max (type);
513 REAL_VALUE_TYPE next = val.lower_bound ();
514 machine_mode mode = TYPE_MODE (type);
515 // Default to the conservatively correct closed ranges for
516 // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
517 // !HONOR_INFINITIES, nextafter will yield +INF, but frange::set()
518 // will crop the range appropriately.
519 if (!MODE_COMPOSITE_P (mode))
520 frange_nextafter (mode, next, inf);
521 r.set (type, next, inf);
522 return true;
526 class foperator_identity : public range_operator_float
528 using range_operator_float::fold_range;
529 using range_operator_float::op1_range;
530 public:
531 bool fold_range (frange &r, tree type ATTRIBUTE_UNUSED,
532 const frange &op1, const frange &op2 ATTRIBUTE_UNUSED,
533 relation_trio = TRIO_VARYING) const final override
535 r = op1;
536 return true;
538 bool op1_range (frange &r, tree type ATTRIBUTE_UNUSED,
539 const frange &lhs, const frange &op2 ATTRIBUTE_UNUSED,
540 relation_trio = TRIO_VARYING) const final override
542 r = lhs;
543 return true;
545 public:
546 } fop_identity;
548 class foperator_equal : public range_operator_float
550 using range_operator_float::fold_range;
551 using range_operator_float::op1_range;
552 using range_operator_float::op2_range;
553 using range_operator_float::op1_op2_relation;
554 public:
555 bool fold_range (irange &r, tree type,
556 const frange &op1, const frange &op2,
557 relation_trio = TRIO_VARYING) const final override;
558 relation_kind op1_op2_relation (const irange &lhs) const final override
560 return equal_op1_op2_relation (lhs);
562 bool op1_range (frange &r, tree type,
563 const irange &lhs, const frange &op2,
564 relation_trio = TRIO_VARYING) const final override;
565 bool op2_range (frange &r, tree type,
566 const irange &lhs, const frange &op1,
567 relation_trio rel = TRIO_VARYING) const final override
569 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
571 } fop_equal;
573 bool
574 foperator_equal::fold_range (irange &r, tree type,
575 const frange &op1, const frange &op2,
576 relation_trio rel) const
578 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_EQ))
579 return true;
581 if (op1.known_isnan () || op2.known_isnan ())
582 r = range_false (type);
583 // We can be sure the values are always equal or not if both ranges
584 // consist of a single value, and then compare them.
585 else if (op1.singleton_p () && op2.singleton_p ())
587 if (op1 == op2)
588 r = range_true (type);
589 else
590 r = range_false (type);
592 else if (!maybe_isnan (op1, op2))
594 // If ranges do not intersect, we know the range is not equal,
595 // otherwise we don't know anything for sure.
596 frange tmp = op1;
597 tmp.intersect (op2);
598 if (tmp.undefined_p ())
599 r = range_false (type);
600 else
601 r = range_true_and_false (type);
603 else
604 r = range_true_and_false (type);
605 return true;
608 bool
609 foperator_equal::op1_range (frange &r, tree type,
610 const irange &lhs,
611 const frange &op2,
612 relation_trio trio) const
614 relation_kind rel = trio.op1_op2 ();
615 switch (get_bool_state (r, lhs, type))
617 case BRS_TRUE:
618 // The TRUE side of x == NAN is unreachable.
619 if (op2.known_isnan ())
620 r.set_undefined ();
621 else
623 // If it's true, the result is the same as OP2.
624 r = op2;
625 // Add both zeros if there's the possibility of zero equality.
626 frange_add_zeros (r, type);
627 // The TRUE side of op1 == op2 implies op1 is !NAN.
628 r.clear_nan ();
630 break;
632 case BRS_FALSE:
633 // The FALSE side of op1 == op1 implies op1 is a NAN.
634 if (rel == VREL_EQ)
635 r.set_nan (type);
636 // On the FALSE side of x == NAN, we know nothing about x.
637 else if (op2.known_isnan ())
638 r.set_varying (type);
639 // If the result is false, the only time we know anything is
640 // if OP2 is a constant.
641 else if (op2.singleton_p ()
642 || (!op2.maybe_isnan () && op2.zero_p ()))
644 REAL_VALUE_TYPE tmp = op2.lower_bound ();
645 r.set (type, tmp, tmp, VR_ANTI_RANGE);
647 else
648 r.set_varying (type);
649 break;
651 default:
652 break;
654 return true;
657 class foperator_not_equal : public range_operator_float
659 using range_operator_float::fold_range;
660 using range_operator_float::op1_range;
661 using range_operator_float::op1_op2_relation;
662 public:
663 bool fold_range (irange &r, tree type,
664 const frange &op1, const frange &op2,
665 relation_trio rel = TRIO_VARYING) const final override;
666 relation_kind op1_op2_relation (const irange &lhs) const final override
668 return not_equal_op1_op2_relation (lhs);
670 bool op1_range (frange &r, tree type,
671 const irange &lhs, const frange &op2,
672 relation_trio = TRIO_VARYING) const final override;
673 } fop_not_equal;
675 bool
676 foperator_not_equal::fold_range (irange &r, tree type,
677 const frange &op1, const frange &op2,
678 relation_trio rel) const
680 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_NE))
681 return true;
683 // x != NAN is always TRUE.
684 if (op1.known_isnan () || op2.known_isnan ())
685 r = range_true (type);
686 // We can be sure the values are always equal or not if both ranges
687 // consist of a single value, and then compare them.
688 else if (op1.singleton_p () && op2.singleton_p ())
690 if (op1 != op2)
691 r = range_true (type);
692 else
693 r = range_false (type);
695 else if (!maybe_isnan (op1, op2))
697 // If ranges do not intersect, we know the range is not equal,
698 // otherwise we don't know anything for sure.
699 frange tmp = op1;
700 tmp.intersect (op2);
701 if (tmp.undefined_p ())
702 r = range_true (type);
703 else
704 r = range_true_and_false (type);
706 else
707 r = range_true_and_false (type);
708 return true;
711 bool
712 foperator_not_equal::op1_range (frange &r, tree type,
713 const irange &lhs,
714 const frange &op2,
715 relation_trio trio) const
717 relation_kind rel = trio.op1_op2 ();
718 switch (get_bool_state (r, lhs, type))
720 case BRS_TRUE:
721 // If the result is true, the only time we know anything is if
722 // OP2 is a constant.
723 if (op2.singleton_p ())
725 // This is correct even if op1 is NAN, because the following
726 // range would be ~[tmp, tmp] with the NAN property set to
727 // maybe (VARYING).
728 REAL_VALUE_TYPE tmp = op2.lower_bound ();
729 r.set (type, tmp, tmp, VR_ANTI_RANGE);
731 // The TRUE side of op1 != op1 implies op1 is NAN.
732 else if (rel == VREL_EQ)
733 r.set_nan (type);
734 else
735 r.set_varying (type);
736 break;
738 case BRS_FALSE:
739 // The FALSE side of x != NAN is impossible.
740 if (op2.known_isnan ())
741 r.set_undefined ();
742 else
744 // If it's false, the result is the same as OP2.
745 r = op2;
746 // Add both zeros if there's the possibility of zero equality.
747 frange_add_zeros (r, type);
748 // The FALSE side of op1 != op2 implies op1 is !NAN.
749 r.clear_nan ();
751 break;
753 default:
754 break;
756 return true;
759 class foperator_lt : public range_operator_float
761 using range_operator_float::fold_range;
762 using range_operator_float::op1_range;
763 using range_operator_float::op2_range;
764 using range_operator_float::op1_op2_relation;
765 public:
766 bool fold_range (irange &r, tree type,
767 const frange &op1, const frange &op2,
768 relation_trio = TRIO_VARYING) const final override;
769 relation_kind op1_op2_relation (const irange &lhs) const final override
771 return lt_op1_op2_relation (lhs);
773 bool op1_range (frange &r, tree type,
774 const irange &lhs, const frange &op2,
775 relation_trio = TRIO_VARYING) const final override;
776 bool op2_range (frange &r, tree type,
777 const irange &lhs, const frange &op1,
778 relation_trio = TRIO_VARYING) const final override;
779 } fop_lt;
781 bool
782 foperator_lt::fold_range (irange &r, tree type,
783 const frange &op1, const frange &op2,
784 relation_trio rel) const
786 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_LT))
787 return true;
789 if (op1.known_isnan () || op2.known_isnan ())
790 r = range_false (type);
791 else if (!maybe_isnan (op1, op2))
793 if (real_less (&op1.upper_bound (), &op2.lower_bound ()))
794 r = range_true (type);
795 else if (!real_less (&op1.lower_bound (), &op2.upper_bound ()))
796 r = range_false (type);
797 else
798 r = range_true_and_false (type);
800 else
801 r = range_true_and_false (type);
802 return true;
805 bool
806 foperator_lt::op1_range (frange &r,
807 tree type,
808 const irange &lhs,
809 const frange &op2,
810 relation_trio) const
812 switch (get_bool_state (r, lhs, type))
814 case BRS_TRUE:
815 // The TRUE side of x < NAN is unreachable.
816 if (op2.known_isnan ())
817 r.set_undefined ();
818 else if (build_lt (r, type, op2))
820 r.clear_nan ();
821 // x < y implies x is not +INF.
822 frange_drop_inf (r, type);
824 break;
826 case BRS_FALSE:
827 // On the FALSE side of x < NAN, we know nothing about x.
828 if (op2.known_isnan ())
829 r.set_varying (type);
830 else
831 build_ge (r, type, op2);
832 break;
834 default:
835 break;
837 return true;
840 bool
841 foperator_lt::op2_range (frange &r,
842 tree type,
843 const irange &lhs,
844 const frange &op1,
845 relation_trio) const
847 switch (get_bool_state (r, lhs, type))
849 case BRS_TRUE:
850 // The TRUE side of NAN < x is unreachable.
851 if (op1.known_isnan ())
852 r.set_undefined ();
853 else if (build_gt (r, type, op1))
855 r.clear_nan ();
856 // x < y implies y is not -INF.
857 frange_drop_ninf (r, type);
859 break;
861 case BRS_FALSE:
862 // On the FALSE side of NAN < x, we know nothing about x.
863 if (op1.known_isnan ())
864 r.set_varying (type);
865 else
866 build_le (r, type, op1);
867 break;
869 default:
870 break;
872 return true;
875 class foperator_le : public range_operator_float
877 using range_operator_float::fold_range;
878 using range_operator_float::op1_range;
879 using range_operator_float::op2_range;
880 using range_operator_float::op1_op2_relation;
881 public:
882 bool fold_range (irange &r, tree type,
883 const frange &op1, const frange &op2,
884 relation_trio rel = TRIO_VARYING) const final override;
885 relation_kind op1_op2_relation (const irange &lhs) const final override
887 return le_op1_op2_relation (lhs);
889 bool op1_range (frange &r, tree type,
890 const irange &lhs, const frange &op2,
891 relation_trio rel = TRIO_VARYING) const final override;
892 bool op2_range (frange &r, tree type,
893 const irange &lhs, const frange &op1,
894 relation_trio rel = TRIO_VARYING) const final override;
895 } fop_le;
897 bool
898 foperator_le::fold_range (irange &r, tree type,
899 const frange &op1, const frange &op2,
900 relation_trio rel) const
902 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_LE))
903 return true;
905 if (op1.known_isnan () || op2.known_isnan ())
906 r = range_false (type);
907 else if (!maybe_isnan (op1, op2))
909 if (real_compare (LE_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
910 r = range_true (type);
911 else if (!real_compare (LE_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
912 r = range_false (type);
913 else
914 r = range_true_and_false (type);
916 else
917 r = range_true_and_false (type);
918 return true;
921 bool
922 foperator_le::op1_range (frange &r,
923 tree type,
924 const irange &lhs,
925 const frange &op2,
926 relation_trio) const
928 switch (get_bool_state (r, lhs, type))
930 case BRS_TRUE:
931 // The TRUE side of x <= NAN is unreachable.
932 if (op2.known_isnan ())
933 r.set_undefined ();
934 else if (build_le (r, type, op2))
935 r.clear_nan ();
936 break;
938 case BRS_FALSE:
939 // On the FALSE side of x <= NAN, we know nothing about x.
940 if (op2.known_isnan ())
941 r.set_varying (type);
942 else
943 build_gt (r, type, op2);
944 break;
946 default:
947 break;
949 return true;
952 bool
953 foperator_le::op2_range (frange &r,
954 tree type,
955 const irange &lhs,
956 const frange &op1,
957 relation_trio) const
959 switch (get_bool_state (r, lhs, type))
961 case BRS_TRUE:
962 // The TRUE side of NAN <= x is unreachable.
963 if (op1.known_isnan ())
964 r.set_undefined ();
965 else if (build_ge (r, type, op1))
966 r.clear_nan ();
967 break;
969 case BRS_FALSE:
970 // On the FALSE side of NAN <= x, we know nothing about x.
971 if (op1.known_isnan ())
972 r.set_varying (type);
973 else
974 build_lt (r, type, op1);
975 break;
977 default:
978 break;
980 return true;
983 class foperator_gt : public range_operator_float
985 using range_operator_float::fold_range;
986 using range_operator_float::op1_range;
987 using range_operator_float::op2_range;
988 using range_operator_float::op1_op2_relation;
989 public:
990 bool fold_range (irange &r, tree type,
991 const frange &op1, const frange &op2,
992 relation_trio = TRIO_VARYING) const final override;
993 relation_kind op1_op2_relation (const irange &lhs) const final override
995 return gt_op1_op2_relation (lhs);
997 bool op1_range (frange &r, tree type,
998 const irange &lhs, const frange &op2,
999 relation_trio = TRIO_VARYING) const final override;
1000 bool op2_range (frange &r, tree type,
1001 const irange &lhs, const frange &op1,
1002 relation_trio = TRIO_VARYING) const final override;
1003 } fop_gt;
1005 bool
1006 foperator_gt::fold_range (irange &r, tree type,
1007 const frange &op1, const frange &op2,
1008 relation_trio rel) const
1010 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_GT))
1011 return true;
1013 if (op1.known_isnan () || op2.known_isnan ())
1014 r = range_false (type);
1015 else if (!maybe_isnan (op1, op2))
1017 if (real_compare (GT_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
1018 r = range_true (type);
1019 else if (!real_compare (GT_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
1020 r = range_false (type);
1021 else
1022 r = range_true_and_false (type);
1024 else
1025 r = range_true_and_false (type);
1026 return true;
1029 bool
1030 foperator_gt::op1_range (frange &r,
1031 tree type,
1032 const irange &lhs,
1033 const frange &op2,
1034 relation_trio) const
1036 switch (get_bool_state (r, lhs, type))
1038 case BRS_TRUE:
1039 // The TRUE side of x > NAN is unreachable.
1040 if (op2.known_isnan ())
1041 r.set_undefined ();
1042 else if (build_gt (r, type, op2))
1044 r.clear_nan ();
1045 // x > y implies x is not -INF.
1046 frange_drop_ninf (r, type);
1048 break;
1050 case BRS_FALSE:
1051 // On the FALSE side of x > NAN, we know nothing about x.
1052 if (op2.known_isnan ())
1053 r.set_varying (type);
1054 else
1055 build_le (r, type, op2);
1056 break;
1058 default:
1059 break;
1061 return true;
1064 bool
1065 foperator_gt::op2_range (frange &r,
1066 tree type,
1067 const irange &lhs,
1068 const frange &op1,
1069 relation_trio) const
1071 switch (get_bool_state (r, lhs, type))
1073 case BRS_TRUE:
1074 // The TRUE side of NAN > x is unreachable.
1075 if (op1.known_isnan ())
1076 r.set_undefined ();
1077 else if (build_lt (r, type, op1))
1079 r.clear_nan ();
1080 // x > y implies y is not +INF.
1081 frange_drop_inf (r, type);
1083 break;
1085 case BRS_FALSE:
1086 // On The FALSE side of NAN > x, we know nothing about x.
1087 if (op1.known_isnan ())
1088 r.set_varying (type);
1089 else
1090 build_ge (r, type, op1);
1091 break;
1093 default:
1094 break;
1096 return true;
1099 class foperator_ge : public range_operator_float
1101 using range_operator_float::fold_range;
1102 using range_operator_float::op1_range;
1103 using range_operator_float::op2_range;
1104 using range_operator_float::op1_op2_relation;
1105 public:
1106 bool fold_range (irange &r, tree type,
1107 const frange &op1, const frange &op2,
1108 relation_trio = TRIO_VARYING) const final override;
1109 relation_kind op1_op2_relation (const irange &lhs) const final override
1111 return ge_op1_op2_relation (lhs);
1113 bool op1_range (frange &r, tree type,
1114 const irange &lhs, const frange &op2,
1115 relation_trio = TRIO_VARYING) const final override;
1116 bool op2_range (frange &r, tree type,
1117 const irange &lhs, const frange &op1,
1118 relation_trio = TRIO_VARYING) const final override;
1119 } fop_ge;
1121 bool
1122 foperator_ge::fold_range (irange &r, tree type,
1123 const frange &op1, const frange &op2,
1124 relation_trio rel) const
1126 if (frelop_early_resolve (r, type, op1, op2, rel, VREL_GE))
1127 return true;
1129 if (op1.known_isnan () || op2.known_isnan ())
1130 r = range_false (type);
1131 else if (!maybe_isnan (op1, op2))
1133 if (real_compare (GE_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
1134 r = range_true (type);
1135 else if (!real_compare (GE_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
1136 r = range_false (type);
1137 else
1138 r = range_true_and_false (type);
1140 else
1141 r = range_true_and_false (type);
1142 return true;
1145 bool
1146 foperator_ge::op1_range (frange &r,
1147 tree type,
1148 const irange &lhs,
1149 const frange &op2,
1150 relation_trio) const
1152 switch (get_bool_state (r, lhs, type))
1154 case BRS_TRUE:
1155 // The TRUE side of x >= NAN is unreachable.
1156 if (op2.known_isnan ())
1157 r.set_undefined ();
1158 else if (build_ge (r, type, op2))
1159 r.clear_nan ();
1160 break;
1162 case BRS_FALSE:
1163 // On the FALSE side of x >= NAN, we know nothing about x.
1164 if (op2.known_isnan ())
1165 r.set_varying (type);
1166 else
1167 build_lt (r, type, op2);
1168 break;
1170 default:
1171 break;
1173 return true;
1176 bool
1177 foperator_ge::op2_range (frange &r, tree type,
1178 const irange &lhs,
1179 const frange &op1,
1180 relation_trio) const
1182 switch (get_bool_state (r, lhs, type))
1184 case BRS_TRUE:
1185 // The TRUE side of NAN >= x is unreachable.
1186 if (op1.known_isnan ())
1187 r.set_undefined ();
1188 else if (build_le (r, type, op1))
1189 r.clear_nan ();
1190 break;
1192 case BRS_FALSE:
1193 // On the FALSE side of NAN >= x, we know nothing about x.
1194 if (op1.known_isnan ())
1195 r.set_varying (type);
1196 else
1197 build_gt (r, type, op1);
1198 break;
1200 default:
1201 break;
1203 return true;
1206 // UNORDERED_EXPR comparison.
1208 class foperator_unordered : public range_operator_float
1210 using range_operator_float::fold_range;
1211 using range_operator_float::op1_range;
1212 using range_operator_float::op2_range;
1213 public:
1214 bool fold_range (irange &r, tree type,
1215 const frange &op1, const frange &op2,
1216 relation_trio = TRIO_VARYING) const final override;
1217 bool op1_range (frange &r, tree type,
1218 const irange &lhs, const frange &op2,
1219 relation_trio = TRIO_VARYING) const final override;
1220 bool op2_range (frange &r, tree type,
1221 const irange &lhs, const frange &op1,
1222 relation_trio rel = TRIO_VARYING) const final override
1224 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
1226 } fop_unordered;
1228 bool
1229 foperator_unordered::fold_range (irange &r, tree type,
1230 const frange &op1, const frange &op2,
1231 relation_trio) const
1233 // UNORDERED is TRUE if either operand is a NAN.
1234 if (op1.known_isnan () || op2.known_isnan ())
1235 r = range_true (type);
1236 // UNORDERED is FALSE if neither operand is a NAN.
1237 else if (!op1.maybe_isnan () && !op2.maybe_isnan ())
1238 r = range_false (type);
1239 else
1240 r = range_true_and_false (type);
1241 return true;
1244 bool
1245 foperator_unordered::op1_range (frange &r, tree type,
1246 const irange &lhs,
1247 const frange &op2,
1248 relation_trio trio) const
1250 relation_kind rel = trio.op1_op2 ();
1251 switch (get_bool_state (r, lhs, type))
1253 case BRS_TRUE:
1254 // Since at least one operand must be NAN, if one of them is
1255 // not, the other must be.
1256 if (rel == VREL_EQ || !op2.maybe_isnan ())
1257 r.set_nan (type);
1258 else
1259 r.set_varying (type);
1260 break;
1262 case BRS_FALSE:
1263 // A false UNORDERED means both operands are !NAN, so it's
1264 // impossible for op2 to be a NAN.
1265 if (op2.known_isnan ())
1266 r.set_undefined ();
1267 else
1269 r.set_varying (type);
1270 r.clear_nan ();
1272 break;
1274 default:
1275 break;
1277 return true;
1280 // ORDERED_EXPR comparison.
1282 class foperator_ordered : public range_operator_float
1284 using range_operator_float::fold_range;
1285 using range_operator_float::op1_range;
1286 using range_operator_float::op2_range;
1287 public:
1288 bool fold_range (irange &r, tree type,
1289 const frange &op1, const frange &op2,
1290 relation_trio = TRIO_VARYING) const final override;
1291 bool op1_range (frange &r, tree type,
1292 const irange &lhs, const frange &op2,
1293 relation_trio = TRIO_VARYING) const final override;
1294 bool op2_range (frange &r, tree type,
1295 const irange &lhs, const frange &op1,
1296 relation_trio rel = TRIO_VARYING) const final override
1298 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
1300 } fop_ordered;
1302 bool
1303 foperator_ordered::fold_range (irange &r, tree type,
1304 const frange &op1, const frange &op2,
1305 relation_trio) const
1307 if (op1.known_isnan () || op2.known_isnan ())
1308 r = range_false (type);
1309 else if (!op1.maybe_isnan () && !op2.maybe_isnan ())
1310 r = range_true (type);
1311 else
1312 r = range_true_and_false (type);
1313 return true;
1316 bool
1317 foperator_ordered::op1_range (frange &r, tree type,
1318 const irange &lhs,
1319 const frange &op2,
1320 relation_trio trio) const
1322 relation_kind rel = trio.op1_op2 ();
1323 switch (get_bool_state (r, lhs, type))
1325 case BRS_TRUE:
1326 // The TRUE side of ORDERED means both operands are !NAN, so
1327 // it's impossible for op2 to be a NAN.
1328 if (op2.known_isnan ())
1329 r.set_undefined ();
1330 else
1332 r.set_varying (type);
1333 r.clear_nan ();
1335 break;
1337 case BRS_FALSE:
1338 // The FALSE side of op1 ORDERED op1 implies op1 is NAN.
1339 if (rel == VREL_EQ)
1340 r.set_nan (type);
1341 else
1342 r.set_varying (type);
1343 break;
1345 default:
1346 break;
1348 return true;
1351 class foperator_negate : public range_operator_float
1353 using range_operator_float::fold_range;
1354 using range_operator_float::op1_range;
1355 public:
1356 bool fold_range (frange &r, tree type,
1357 const frange &op1, const frange &op2,
1358 relation_trio = TRIO_VARYING) const final override
1360 if (empty_range_varying (r, type, op1, op2))
1361 return true;
1362 if (op1.known_isnan ())
1364 bool sign;
1365 if (op1.nan_signbit_p (sign))
1366 r.set_nan (type, !sign);
1367 else
1368 r.set_nan (type);
1369 return true;
1372 REAL_VALUE_TYPE lh_lb = op1.lower_bound ();
1373 REAL_VALUE_TYPE lh_ub = op1.upper_bound ();
1374 lh_lb = real_value_negate (&lh_lb);
1375 lh_ub = real_value_negate (&lh_ub);
1376 r.set (type, lh_ub, lh_lb);
1377 if (op1.maybe_isnan ())
1379 bool sign;
1380 if (op1.nan_signbit_p (sign))
1381 r.update_nan (!sign);
1382 else
1383 r.update_nan ();
1385 else
1386 r.clear_nan ();
1387 return true;
1389 bool op1_range (frange &r, tree type,
1390 const frange &lhs, const frange &op2,
1391 relation_trio rel = TRIO_VARYING) const final override
1393 return fold_range (r, type, lhs, op2, rel);
1395 } fop_negate;
1397 class foperator_abs : public range_operator_float
1399 using range_operator_float::fold_range;
1400 using range_operator_float::op1_range;
1401 public:
1402 bool fold_range (frange &r, tree type,
1403 const frange &op1, const frange &,
1404 relation_trio = TRIO_VARYING) const final override;
1405 bool op1_range (frange &r, tree type,
1406 const frange &lhs, const frange &op2,
1407 relation_trio rel = TRIO_VARYING) const final override;
1408 } fop_abs;
1410 bool
1411 foperator_abs::fold_range (frange &r, tree type,
1412 const frange &op1, const frange &op2,
1413 relation_trio) const
1415 if (empty_range_varying (r, type, op1, op2))
1416 return true;
1417 if (op1.known_isnan ())
1419 r.set_nan (type, /*sign=*/false);
1420 return true;
1423 const REAL_VALUE_TYPE lh_lb = op1.lower_bound ();
1424 const REAL_VALUE_TYPE lh_ub = op1.upper_bound ();
1425 // Handle the easy case where everything is positive.
1426 if (real_compare (GE_EXPR, &lh_lb, &dconst0)
1427 && !real_iszero (&lh_lb, /*sign=*/true)
1428 && !op1.maybe_isnan (/*sign=*/true))
1430 r = op1;
1431 return true;
1434 REAL_VALUE_TYPE min = real_value_abs (&lh_lb);
1435 REAL_VALUE_TYPE max = real_value_abs (&lh_ub);
1436 // If the range contains zero then we know that the minimum value in the
1437 // range will be zero.
1438 if (real_compare (LE_EXPR, &lh_lb, &dconst0)
1439 && real_compare (GE_EXPR, &lh_ub, &dconst0))
1441 if (real_compare (GT_EXPR, &min, &max))
1442 max = min;
1443 min = dconst0;
1445 else
1447 // If the range was reversed, swap MIN and MAX.
1448 if (real_compare (GT_EXPR, &min, &max))
1449 std::swap (min, max);
1452 r.set (type, min, max);
1453 if (op1.maybe_isnan ())
1454 r.update_nan (/*sign=*/false);
1455 else
1456 r.clear_nan ();
1457 return true;
1460 bool
1461 foperator_abs::op1_range (frange &r, tree type,
1462 const frange &lhs, const frange &op2,
1463 relation_trio) const
1465 if (empty_range_varying (r, type, lhs, op2))
1466 return true;
1467 if (lhs.known_isnan ())
1469 r.set_nan (type);
1470 return true;
1473 // Start with the positives because negatives are an impossible result.
1474 frange positives (type, dconst0, frange_val_max (type));
1475 positives.update_nan (/*sign=*/false);
1476 positives.intersect (lhs);
1477 r = positives;
1478 // Add -NAN if relevant.
1479 if (r.maybe_isnan ())
1481 frange neg_nan;
1482 neg_nan.set_nan (type, true);
1483 r.union_ (neg_nan);
1485 if (r.known_isnan () || r.undefined_p ())
1486 return true;
1487 // Then add the negative of each pair:
1488 // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
1489 frange negatives (type, real_value_negate (&positives.upper_bound ()),
1490 real_value_negate (&positives.lower_bound ()));
1491 negatives.clear_nan ();
1492 r.union_ (negatives);
1493 return true;
1496 class foperator_unordered_lt : public range_operator_float
1498 using range_operator_float::fold_range;
1499 using range_operator_float::op1_range;
1500 using range_operator_float::op2_range;
1501 public:
1502 bool fold_range (irange &r, tree type,
1503 const frange &op1, const frange &op2,
1504 relation_trio rel = TRIO_VARYING) const final override
1506 if (op1.known_isnan () || op2.known_isnan ())
1508 r = range_true (type);
1509 return true;
1511 if (!fop_lt.fold_range (r, type, op1, op2, rel))
1512 return false;
1513 // The result is the same as the ordered version when the
1514 // comparison is true or when the operands cannot be NANs.
1515 if (!maybe_isnan (op1, op2) || r == range_true (type))
1516 return true;
1517 else
1519 r = range_true_and_false (type);
1520 return true;
1523 bool op1_range (frange &r, tree type,
1524 const irange &lhs,
1525 const frange &op2,
1526 relation_trio trio) const final override;
1527 bool op2_range (frange &r, tree type,
1528 const irange &lhs,
1529 const frange &op1,
1530 relation_trio trio) const final override;
1531 } fop_unordered_lt;
1533 bool
1534 foperator_unordered_lt::op1_range (frange &r, tree type,
1535 const irange &lhs,
1536 const frange &op2,
1537 relation_trio) const
1539 switch (get_bool_state (r, lhs, type))
1541 case BRS_TRUE:
1542 if (op2.known_isnan ())
1543 r.set_varying (type);
1544 else
1545 build_lt (r, type, op2);
1546 break;
1548 case BRS_FALSE:
1549 // A false UNORDERED_LT means both operands are !NAN, so it's
1550 // impossible for op2 to be a NAN.
1551 if (op2.known_isnan ())
1552 r.set_undefined ();
1553 else if (build_ge (r, type, op2))
1554 r.clear_nan ();
1555 break;
1557 default:
1558 break;
1560 return true;
1563 bool
1564 foperator_unordered_lt::op2_range (frange &r, tree type,
1565 const irange &lhs,
1566 const frange &op1,
1567 relation_trio) const
1569 switch (get_bool_state (r, lhs, type))
1571 case BRS_TRUE:
1572 if (op1.known_isnan ())
1573 r.set_varying (type);
1574 else
1575 build_gt (r, type, op1);
1576 break;
1578 case BRS_FALSE:
1579 // A false UNORDERED_LT means both operands are !NAN, so it's
1580 // impossible for op1 to be a NAN.
1581 if (op1.known_isnan ())
1582 r.set_undefined ();
1583 else if (build_le (r, type, op1))
1584 r.clear_nan ();
1585 break;
1587 default:
1588 break;
1590 return true;
1593 class foperator_unordered_le : public range_operator_float
1595 using range_operator_float::fold_range;
1596 using range_operator_float::op1_range;
1597 using range_operator_float::op2_range;
1598 public:
1599 bool fold_range (irange &r, tree type,
1600 const frange &op1, const frange &op2,
1601 relation_trio rel = TRIO_VARYING) const final override
1603 if (op1.known_isnan () || op2.known_isnan ())
1605 r = range_true (type);
1606 return true;
1608 if (!fop_le.fold_range (r, type, op1, op2, rel))
1609 return false;
1610 // The result is the same as the ordered version when the
1611 // comparison is true or when the operands cannot be NANs.
1612 if (!maybe_isnan (op1, op2) || r == range_true (type))
1613 return true;
1614 else
1616 r = range_true_and_false (type);
1617 return true;
1620 bool op1_range (frange &r, tree type,
1621 const irange &lhs, const frange &op2,
1622 relation_trio = TRIO_VARYING) const final override;
1623 bool op2_range (frange &r, tree type,
1624 const irange &lhs, const frange &op1,
1625 relation_trio = TRIO_VARYING) const final override;
1626 } fop_unordered_le;
1628 bool
1629 foperator_unordered_le::op1_range (frange &r, tree type,
1630 const irange &lhs, const frange &op2,
1631 relation_trio) const
1633 switch (get_bool_state (r, lhs, type))
1635 case BRS_TRUE:
1636 if (op2.known_isnan ())
1637 r.set_varying (type);
1638 else
1639 build_le (r, type, op2);
1640 break;
1642 case BRS_FALSE:
1643 // A false UNORDERED_LE means both operands are !NAN, so it's
1644 // impossible for op2 to be a NAN.
1645 if (op2.known_isnan ())
1646 r.set_undefined ();
1647 else if (build_gt (r, type, op2))
1648 r.clear_nan ();
1649 break;
1651 default:
1652 break;
1654 return true;
1657 bool
1658 foperator_unordered_le::op2_range (frange &r,
1659 tree type,
1660 const irange &lhs,
1661 const frange &op1,
1662 relation_trio) const
1664 switch (get_bool_state (r, lhs, type))
1666 case BRS_TRUE:
1667 if (op1.known_isnan ())
1668 r.set_varying (type);
1669 else
1670 build_ge (r, type, op1);
1671 break;
1673 case BRS_FALSE:
1674 // A false UNORDERED_LE means both operands are !NAN, so it's
1675 // impossible for op1 to be a NAN.
1676 if (op1.known_isnan ())
1677 r.set_undefined ();
1678 else if (build_lt (r, type, op1))
1679 r.clear_nan ();
1680 break;
1682 default:
1683 break;
1685 return true;
1688 class foperator_unordered_gt : public range_operator_float
1690 using range_operator_float::fold_range;
1691 using range_operator_float::op1_range;
1692 using range_operator_float::op2_range;
1693 public:
1694 bool fold_range (irange &r, tree type,
1695 const frange &op1, const frange &op2,
1696 relation_trio rel = TRIO_VARYING) const final override
1698 if (op1.known_isnan () || op2.known_isnan ())
1700 r = range_true (type);
1701 return true;
1703 if (!fop_gt.fold_range (r, type, op1, op2, rel))
1704 return false;
1705 // The result is the same as the ordered version when the
1706 // comparison is true or when the operands cannot be NANs.
1707 if (!maybe_isnan (op1, op2) || r == range_true (type))
1708 return true;
1709 else
1711 r = range_true_and_false (type);
1712 return true;
1715 bool op1_range (frange &r, tree type,
1716 const irange &lhs, const frange &op2,
1717 relation_trio = TRIO_VARYING) const final override;
1718 bool op2_range (frange &r, tree type,
1719 const irange &lhs, const frange &op1,
1720 relation_trio = TRIO_VARYING) const final override;
1721 } fop_unordered_gt;
1723 bool
1724 foperator_unordered_gt::op1_range (frange &r,
1725 tree type,
1726 const irange &lhs,
1727 const frange &op2,
1728 relation_trio) const
1730 switch (get_bool_state (r, lhs, type))
1732 case BRS_TRUE:
1733 if (op2.known_isnan ())
1734 r.set_varying (type);
1735 else
1736 build_gt (r, type, op2);
1737 break;
1739 case BRS_FALSE:
1740 // A false UNORDERED_GT means both operands are !NAN, so it's
1741 // impossible for op2 to be a NAN.
1742 if (op2.known_isnan ())
1743 r.set_undefined ();
1744 else if (build_le (r, type, op2))
1745 r.clear_nan ();
1746 break;
1748 default:
1749 break;
1751 return true;
1754 bool
1755 foperator_unordered_gt::op2_range (frange &r,
1756 tree type,
1757 const irange &lhs,
1758 const frange &op1,
1759 relation_trio) const
1761 switch (get_bool_state (r, lhs, type))
1763 case BRS_TRUE:
1764 if (op1.known_isnan ())
1765 r.set_varying (type);
1766 else
1767 build_lt (r, type, op1);
1768 break;
1770 case BRS_FALSE:
1771 // A false UNORDERED_GT means both operands are !NAN, so it's
1772 // impossible for op1 to be a NAN.
1773 if (op1.known_isnan ())
1774 r.set_undefined ();
1775 else if (build_ge (r, type, op1))
1776 r.clear_nan ();
1777 break;
1779 default:
1780 break;
1782 return true;
1785 class foperator_unordered_ge : public range_operator_float
1787 using range_operator_float::fold_range;
1788 using range_operator_float::op1_range;
1789 using range_operator_float::op2_range;
1790 public:
1791 bool fold_range (irange &r, tree type,
1792 const frange &op1, const frange &op2,
1793 relation_trio rel = TRIO_VARYING) const final override
1795 if (op1.known_isnan () || op2.known_isnan ())
1797 r = range_true (type);
1798 return true;
1800 if (!fop_ge.fold_range (r, type, op1, op2, rel))
1801 return false;
1802 // The result is the same as the ordered version when the
1803 // comparison is true or when the operands cannot be NANs.
1804 if (!maybe_isnan (op1, op2) || r == range_true (type))
1805 return true;
1806 else
1808 r = range_true_and_false (type);
1809 return true;
1812 bool op1_range (frange &r, tree type,
1813 const irange &lhs, const frange &op2,
1814 relation_trio = TRIO_VARYING) const final override;
1815 bool op2_range (frange &r, tree type,
1816 const irange &lhs, const frange &op1,
1817 relation_trio = TRIO_VARYING) const final override;
1818 } fop_unordered_ge;
1820 bool
1821 foperator_unordered_ge::op1_range (frange &r,
1822 tree type,
1823 const irange &lhs,
1824 const frange &op2,
1825 relation_trio) const
1827 switch (get_bool_state (r, lhs, type))
1829 case BRS_TRUE:
1830 if (op2.known_isnan ())
1831 r.set_varying (type);
1832 else
1833 build_ge (r, type, op2);
1834 break;
1836 case BRS_FALSE:
1837 // A false UNORDERED_GE means both operands are !NAN, so it's
1838 // impossible for op2 to be a NAN.
1839 if (op2.known_isnan ())
1840 r.set_undefined ();
1841 else if (build_lt (r, type, op2))
1842 r.clear_nan ();
1843 break;
1845 default:
1846 break;
1848 return true;
1851 bool
1852 foperator_unordered_ge::op2_range (frange &r, 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 ())
1861 r.set_varying (type);
1862 else
1863 build_le (r, type, op1);
1864 break;
1866 case BRS_FALSE:
1867 // A false UNORDERED_GE means both operands are !NAN, so it's
1868 // impossible for op1 to be a NAN.
1869 if (op1.known_isnan ())
1870 r.set_undefined ();
1871 else if (build_gt (r, type, op1))
1872 r.clear_nan ();
1873 break;
1875 default:
1876 break;
1878 return true;
1881 class foperator_unordered_equal : public range_operator_float
1883 using range_operator_float::fold_range;
1884 using range_operator_float::op1_range;
1885 using range_operator_float::op2_range;
1886 public:
1887 bool fold_range (irange &r, tree type,
1888 const frange &op1, const frange &op2,
1889 relation_trio rel = TRIO_VARYING) const final override
1891 if (op1.known_isnan () || op2.known_isnan ())
1893 r = range_true (type);
1894 return true;
1896 if (!fop_equal.fold_range (r, type, op1, op2, rel))
1897 return false;
1898 // The result is the same as the ordered version when the
1899 // comparison is true or when the operands cannot be NANs.
1900 if (!maybe_isnan (op1, op2) || r == range_true (type))
1901 return true;
1902 else
1904 r = range_true_and_false (type);
1905 return true;
1908 bool op1_range (frange &r, tree type,
1909 const irange &lhs, const frange &op2,
1910 relation_trio = TRIO_VARYING) const final override;
1911 bool op2_range (frange &r, tree type,
1912 const irange &lhs, const frange &op1,
1913 relation_trio rel = TRIO_VARYING) const final override
1915 return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
1917 } fop_unordered_equal;
1919 bool
1920 foperator_unordered_equal::op1_range (frange &r, tree type,
1921 const irange &lhs,
1922 const frange &op2,
1923 relation_trio) const
1925 switch (get_bool_state (r, lhs, type))
1927 case BRS_TRUE:
1928 // If it's true, the result is the same as OP2 plus a NAN.
1929 r = op2;
1930 // Add both zeros if there's the possibility of zero equality.
1931 frange_add_zeros (r, type);
1932 // Add the posibility of a NAN.
1933 r.update_nan ();
1934 break;
1936 case BRS_FALSE:
1937 // A false UNORDERED_EQ means both operands are !NAN, so it's
1938 // impossible for op2 to be a NAN.
1939 if (op2.known_isnan ())
1940 r.set_undefined ();
1941 else
1943 // The false side indictates !NAN and not equal. We can at least
1944 // represent !NAN.
1945 r.set_varying (type);
1946 r.clear_nan ();
1948 break;
1950 default:
1951 break;
1953 return true;
1956 // Final tweaks for float binary op op1_range/op2_range.
1957 // Return TRUE if the operation is performed and a valid range is available.
1959 static bool
1960 float_binary_op_range_finish (bool ret, frange &r, tree type,
1961 const frange &lhs, bool div_op2 = false)
1963 if (!ret)
1964 return false;
1966 // If we get a known NAN from reverse op, it means either that
1967 // the other operand was known NAN (in that case we know nothing),
1968 // or the reverse operation introduced a known NAN.
1969 // Say for lhs = op1 * op2 if lhs is [-0, +0] and op2 is too,
1970 // 0 / 0 is known NAN. Just punt in that case.
1971 // If NANs aren't honored, we get for 0 / 0 UNDEFINED, so punt as well.
1972 // Or if lhs is a known NAN, we also don't know anything.
1973 if (r.known_isnan () || lhs.known_isnan () || r.undefined_p ())
1975 r.set_varying (type);
1976 return true;
1979 // If lhs isn't NAN, then neither operand could be NAN,
1980 // even if the reverse operation does introduce a maybe_nan.
1981 if (!lhs.maybe_isnan ())
1983 r.clear_nan ();
1984 if (div_op2
1985 ? !(real_compare (LE_EXPR, &lhs.lower_bound (), &dconst0)
1986 && real_compare (GE_EXPR, &lhs.upper_bound (), &dconst0))
1987 : !(real_isinf (&lhs.lower_bound ())
1988 || real_isinf (&lhs.upper_bound ())))
1989 // For reverse + or - or * or op1 of /, if result is finite, then
1990 // r must be finite too, as X + INF or X - INF or X * INF or
1991 // INF / X is always +-INF or NAN. For op2 of /, if result is
1992 // non-zero and not NAN, r must be finite, as X / INF is always
1993 // 0 or NAN.
1994 frange_drop_infs (r, type);
1996 // If lhs is a maybe or known NAN, the operand could be
1997 // NAN.
1998 else
1999 r.update_nan ();
2000 return true;
2003 // True if [lb, ub] is [+-0, +-0].
2004 static bool
2005 zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2007 return real_iszero (&lb) && real_iszero (&ub);
2010 // True if +0 or -0 is in [lb, ub] range.
2011 static bool
2012 contains_zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2014 return (real_compare (LE_EXPR, &lb, &dconst0)
2015 && real_compare (GE_EXPR, &ub, &dconst0));
2018 // True if [lb, ub] is [-INF, -INF] or [+INF, +INF].
2019 static bool
2020 singleton_inf_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2022 return real_isinf (&lb) && real_isinf (&ub, real_isneg (&lb));
2025 // Return -1 if binary op result must have sign bit set,
2026 // 1 if binary op result must have sign bit clear,
2027 // 0 otherwise.
2028 // Sign bit of binary op result is exclusive or of the
2029 // operand's sign bits.
2030 static int
2031 signbit_known_p (const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
2032 const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub)
2034 if (real_isneg (&lh_lb) == real_isneg (&lh_ub)
2035 && real_isneg (&rh_lb) == real_isneg (&rh_ub))
2037 if (real_isneg (&lh_lb) == real_isneg (&rh_ub))
2038 return 1;
2039 else
2040 return -1;
2042 return 0;
2045 // Set [lb, ub] to [-0, -0], [-0, +0] or [+0, +0] depending on
2046 // signbit_known.
2047 static void
2048 zero_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2050 ub = lb = dconst0;
2051 if (signbit_known <= 0)
2052 lb = real_value_negate (&dconst0);
2053 if (signbit_known < 0)
2054 ub = lb;
2057 // Set [lb, ub] to [-INF, -INF], [-INF, +INF] or [+INF, +INF] depending on
2058 // signbit_known.
2059 static void
2060 inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2062 if (signbit_known > 0)
2063 ub = lb = dconstinf;
2064 else if (signbit_known < 0)
2065 ub = lb = dconstninf;
2066 else
2068 lb = dconstninf;
2069 ub = dconstinf;
2073 // Set [lb, ub] to [-INF, -0], [-INF, +INF] or [+0, +INF] depending on
2074 // signbit_known.
2075 static void
2076 zero_to_inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2078 if (signbit_known > 0)
2080 lb = dconst0;
2081 ub = dconstinf;
2083 else if (signbit_known < 0)
2085 lb = dconstninf;
2086 ub = real_value_negate (&dconst0);
2088 else
2090 lb = dconstninf;
2091 ub = dconstinf;
2095 class foperator_plus : public range_operator_float
2097 using range_operator_float::op1_range;
2098 using range_operator_float::op2_range;
2099 public:
2100 virtual bool op1_range (frange &r, tree type,
2101 const frange &lhs,
2102 const frange &op2,
2103 relation_trio = TRIO_VARYING) const final override
2105 if (lhs.undefined_p ())
2106 return false;
2107 range_op_handler minus (MINUS_EXPR, type);
2108 if (!minus)
2109 return false;
2110 return float_binary_op_range_finish (minus.fold_range (r, type, lhs, op2),
2111 r, type, lhs);
2113 virtual bool op2_range (frange &r, tree type,
2114 const frange &lhs,
2115 const frange &op1,
2116 relation_trio = TRIO_VARYING) const final override
2118 return op1_range (r, type, lhs, op1);
2120 private:
2121 void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan,
2122 tree type,
2123 const REAL_VALUE_TYPE &lh_lb,
2124 const REAL_VALUE_TYPE &lh_ub,
2125 const REAL_VALUE_TYPE &rh_lb,
2126 const REAL_VALUE_TYPE &rh_ub,
2127 relation_kind) const final override
2129 frange_arithmetic (PLUS_EXPR, type, lb, lh_lb, rh_lb, dconstninf);
2130 frange_arithmetic (PLUS_EXPR, type, ub, lh_ub, rh_ub, dconstinf);
2132 // [-INF] + [+INF] = NAN
2133 if (real_isinf (&lh_lb, true) && real_isinf (&rh_ub, false))
2134 maybe_nan = true;
2135 // [+INF] + [-INF] = NAN
2136 else if (real_isinf (&lh_ub, false) && real_isinf (&rh_lb, true))
2137 maybe_nan = true;
2138 else
2139 maybe_nan = false;
2141 } fop_plus;
2144 class foperator_minus : public range_operator_float
2146 using range_operator_float::op1_range;
2147 using range_operator_float::op2_range;
2148 public:
2149 virtual bool op1_range (frange &r, tree type,
2150 const frange &lhs,
2151 const frange &op2,
2152 relation_trio = TRIO_VARYING) const final override
2154 if (lhs.undefined_p ())
2155 return false;
2156 return float_binary_op_range_finish (fop_plus.fold_range (r, type, lhs,
2157 op2),
2158 r, type, lhs);
2160 virtual bool op2_range (frange &r, tree type,
2161 const frange &lhs,
2162 const frange &op1,
2163 relation_trio = TRIO_VARYING) const final override
2165 if (lhs.undefined_p ())
2166 return false;
2167 return float_binary_op_range_finish (fold_range (r, type, op1, lhs),
2168 r, type, lhs);
2170 private:
2171 void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan,
2172 tree type,
2173 const REAL_VALUE_TYPE &lh_lb,
2174 const REAL_VALUE_TYPE &lh_ub,
2175 const REAL_VALUE_TYPE &rh_lb,
2176 const REAL_VALUE_TYPE &rh_ub,
2177 relation_kind) const final override
2179 frange_arithmetic (MINUS_EXPR, type, lb, lh_lb, rh_ub, dconstninf);
2180 frange_arithmetic (MINUS_EXPR, type, ub, lh_ub, rh_lb, dconstinf);
2182 // [+INF] - [+INF] = NAN
2183 if (real_isinf (&lh_ub, false) && real_isinf (&rh_ub, false))
2184 maybe_nan = true;
2185 // [-INF] - [-INF] = NAN
2186 else if (real_isinf (&lh_lb, true) && real_isinf (&rh_lb, true))
2187 maybe_nan = true;
2188 else
2189 maybe_nan = false;
2191 } fop_minus;
2194 class foperator_mult_div_base : public range_operator_float
2196 protected:
2197 // Given CP[0] to CP[3] floating point values rounded to -INF,
2198 // set LB to the smallest of them (treating -0 as smaller to +0).
2199 // Given CP[4] to CP[7] floating point values rounded to +INF,
2200 // set UB to the largest of them (treating -0 as smaller to +0).
2201 static void find_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
2202 const REAL_VALUE_TYPE (&cp)[8])
2204 lb = cp[0];
2205 ub = cp[4];
2206 for (int i = 1; i < 4; ++i)
2208 if (real_less (&cp[i], &lb)
2209 || (real_iszero (&lb) && real_isnegzero (&cp[i])))
2210 lb = cp[i];
2211 if (real_less (&ub, &cp[i + 4])
2212 || (real_isnegzero (&ub) && real_iszero (&cp[i + 4])))
2213 ub = cp[i + 4];
2219 class foperator_mult : public foperator_mult_div_base
2221 using range_operator_float::op1_range;
2222 using range_operator_float::op2_range;
2223 public:
2224 virtual bool op1_range (frange &r, tree type,
2225 const frange &lhs,
2226 const frange &op2,
2227 relation_trio = TRIO_VARYING) const final override
2229 if (lhs.undefined_p ())
2230 return false;
2231 range_op_handler rdiv (RDIV_EXPR, type);
2232 if (!rdiv)
2233 return false;
2234 bool ret = rdiv.fold_range (r, type, lhs, op2);
2235 if (ret == false)
2236 return false;
2237 if (lhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
2238 return float_binary_op_range_finish (ret, r, type, lhs);
2239 const REAL_VALUE_TYPE &lhs_lb = lhs.lower_bound ();
2240 const REAL_VALUE_TYPE &lhs_ub = lhs.upper_bound ();
2241 const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
2242 const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
2243 if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op2_lb, op2_ub))
2244 || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
2245 && (real_isinf (&op2_lb) || real_isinf (&op2_ub))))
2247 // If both lhs and op2 could be zeros or both could be infinities,
2248 // we don't know anything about op1 except maybe for the sign
2249 // and perhaps if it can be NAN or not.
2250 REAL_VALUE_TYPE lb, ub;
2251 int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
2252 zero_to_inf_range (lb, ub, signbit_known);
2253 r.set (type, lb, ub);
2255 // Otherwise, if op2 is a singleton INF and lhs doesn't include INF,
2256 // or if lhs must be zero and op2 doesn't include zero, it would be
2257 // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF
2258 // range. Those are supersets of UNDEFINED, so let's keep that way.
2259 return float_binary_op_range_finish (ret, r, type, lhs);
2261 virtual bool op2_range (frange &r, tree type,
2262 const frange &lhs,
2263 const frange &op1,
2264 relation_trio = TRIO_VARYING) const final override
2266 return op1_range (r, type, lhs, op1);
2268 private:
2269 void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan,
2270 tree type,
2271 const REAL_VALUE_TYPE &lh_lb,
2272 const REAL_VALUE_TYPE &lh_ub,
2273 const REAL_VALUE_TYPE &rh_lb,
2274 const REAL_VALUE_TYPE &rh_ub,
2275 relation_kind kind) const final override
2277 bool is_square
2278 = (kind == VREL_EQ
2279 && real_equal (&lh_lb, &rh_lb)
2280 && real_equal (&lh_ub, &rh_ub)
2281 && real_isneg (&lh_lb) == real_isneg (&rh_lb)
2282 && real_isneg (&lh_ub) == real_isneg (&rh_ub));
2284 maybe_nan = false;
2285 // x * x never produces a new NAN and we only multiply the same
2286 // values, so the 0 * INF problematic cases never appear there.
2287 if (!is_square)
2289 // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN.
2290 if ((zero_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub))
2291 || (zero_p (rh_lb, rh_ub) && singleton_inf_p (lh_lb, lh_ub)))
2293 real_nan (&lb, "", 0, TYPE_MODE (type));
2294 ub = lb;
2295 maybe_nan = true;
2296 return;
2299 // Otherwise, if one range includes zero and the other ends with +-INF,
2300 // it is a maybe NAN.
2301 if ((contains_zero_p (lh_lb, lh_ub)
2302 && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
2303 || (contains_zero_p (rh_lb, rh_ub)
2304 && (real_isinf (&lh_lb) || real_isinf (&lh_ub))))
2306 maybe_nan = true;
2308 int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
2310 // If one of the ranges that includes INF is singleton
2311 // and the other range includes zero, the resulting
2312 // range is INF and NAN, because the 0 * INF boundary
2313 // case will be NAN, but already nextafter (0, 1) * INF
2314 // is INF.
2315 if (singleton_inf_p (lh_lb, lh_ub)
2316 || singleton_inf_p (rh_lb, rh_ub))
2317 return inf_range (lb, ub, signbit_known);
2319 // If one of the multiplicands must be zero, the resulting
2320 // range is +-0 and NAN.
2321 if (zero_p (lh_lb, lh_ub) || zero_p (rh_lb, rh_ub))
2322 return zero_range (lb, ub, signbit_known);
2324 // Otherwise one of the multiplicands could be
2325 // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF]
2326 // or similarly with different signs. 0.0 * DBL_MAX
2327 // is still 0.0, nextafter (0.0, 1.0) * INF is still INF,
2328 // so if the signs are always the same or always different,
2329 // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING.
2330 return zero_to_inf_range (lb, ub, signbit_known);
2334 REAL_VALUE_TYPE cp[8];
2335 // Do a cross-product. At this point none of the multiplications
2336 // should produce a NAN.
2337 frange_arithmetic (MULT_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
2338 frange_arithmetic (MULT_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
2339 if (is_square)
2341 // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub)
2342 // as maximum and -0.0 as minimum if 0.0 is in the range,
2343 // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub).
2344 // -0.0 rather than 0.0 because VREL_EQ doesn't prove that
2345 // x and y are bitwise equal, just that they compare equal.
2346 if (contains_zero_p (lh_lb, lh_ub))
2348 if (real_isneg (&lh_lb) == real_isneg (&lh_ub))
2349 cp[1] = dconst0;
2350 else
2351 cp[1] = real_value_negate (&dconst0);
2353 else
2354 cp[1] = cp[0];
2355 cp[2] = cp[0];
2356 cp[5] = cp[4];
2357 cp[6] = cp[4];
2359 else
2361 frange_arithmetic (MULT_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
2362 frange_arithmetic (MULT_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
2363 frange_arithmetic (MULT_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
2364 frange_arithmetic (MULT_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
2366 frange_arithmetic (MULT_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
2367 frange_arithmetic (MULT_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);
2369 find_range (lb, ub, cp);
2371 } fop_mult;
2374 class foperator_div : public foperator_mult_div_base
2376 using range_operator_float::op1_range;
2377 using range_operator_float::op2_range;
2378 public:
2379 virtual bool op1_range (frange &r, tree type,
2380 const frange &lhs,
2381 const frange &op2,
2382 relation_trio = TRIO_VARYING) const final override
2384 if (lhs.undefined_p ())
2385 return false;
2386 bool ret = fop_mult.fold_range (r, type, lhs, op2);
2387 if (!ret)
2388 return ret;
2389 if (lhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
2390 return float_binary_op_range_finish (ret, r, type, lhs);
2391 const REAL_VALUE_TYPE &lhs_lb = lhs.lower_bound ();
2392 const REAL_VALUE_TYPE &lhs_ub = lhs.upper_bound ();
2393 const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
2394 const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
2395 if ((contains_zero_p (lhs_lb, lhs_ub)
2396 && (real_isinf (&op2_lb) || real_isinf (&op2_ub)))
2397 || ((contains_zero_p (op2_lb, op2_ub))
2398 && (real_isinf (&lhs_lb) || real_isinf (&lhs_ub))))
2400 // If both lhs could be zero and op2 infinity or vice versa,
2401 // we don't know anything about op1 except maybe for the sign
2402 // and perhaps if it can be NAN or not.
2403 REAL_VALUE_TYPE lb, ub;
2404 int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
2405 zero_to_inf_range (lb, ub, signbit_known);
2406 r.set (type, lb, ub);
2408 return float_binary_op_range_finish (ret, r, type, lhs);
2410 virtual bool op2_range (frange &r, tree type,
2411 const frange &lhs,
2412 const frange &op1,
2413 relation_trio = TRIO_VARYING) const final override
2415 if (lhs.undefined_p ())
2416 return false;
2417 bool ret = fold_range (r, type, op1, lhs);
2418 if (!ret)
2419 return ret;
2420 if (lhs.known_isnan () || op1.known_isnan () || op1.undefined_p ())
2421 return float_binary_op_range_finish (ret, r, type, lhs, true);
2422 const REAL_VALUE_TYPE &lhs_lb = lhs.lower_bound ();
2423 const REAL_VALUE_TYPE &lhs_ub = lhs.upper_bound ();
2424 const REAL_VALUE_TYPE &op1_lb = op1.lower_bound ();
2425 const REAL_VALUE_TYPE &op1_ub = op1.upper_bound ();
2426 if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op1_lb, op1_ub))
2427 || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
2428 && (real_isinf (&op1_lb) || real_isinf (&op1_ub))))
2430 // If both lhs and op1 could be zeros or both could be infinities,
2431 // we don't know anything about op2 except maybe for the sign
2432 // and perhaps if it can be NAN or not.
2433 REAL_VALUE_TYPE lb, ub;
2434 int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op1_lb, op1_ub);
2435 zero_to_inf_range (lb, ub, signbit_known);
2436 r.set (type, lb, ub);
2438 return float_binary_op_range_finish (ret, r, type, lhs, true);
2440 private:
2441 void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan,
2442 tree type,
2443 const REAL_VALUE_TYPE &lh_lb,
2444 const REAL_VALUE_TYPE &lh_ub,
2445 const REAL_VALUE_TYPE &rh_lb,
2446 const REAL_VALUE_TYPE &rh_ub,
2447 relation_kind) const final override
2449 // +-0.0 / +-0.0 or +-INF / +-INF is a known NAN.
2450 if ((zero_p (lh_lb, lh_ub) && zero_p (rh_lb, rh_ub))
2451 || (singleton_inf_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub)))
2453 real_nan (&lb, "", 0, TYPE_MODE (type));
2454 ub = lb;
2455 maybe_nan = true;
2456 return;
2459 // If +-0.0 is in both ranges, it is a maybe NAN.
2460 if (contains_zero_p (lh_lb, lh_ub) && contains_zero_p (rh_lb, rh_ub))
2461 maybe_nan = true;
2462 // If +-INF is in both ranges, it is a maybe NAN.
2463 else if ((real_isinf (&lh_lb) || real_isinf (&lh_ub))
2464 && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
2465 maybe_nan = true;
2466 else
2467 maybe_nan = false;
2469 int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
2471 // If dividend must be zero, the range is just +-0
2472 // (including if the divisor is +-INF).
2473 // If divisor must be +-INF, the range is just +-0
2474 // (including if the dividend is zero).
2475 if (zero_p (lh_lb, lh_ub) || singleton_inf_p (rh_lb, rh_ub))
2476 return zero_range (lb, ub, signbit_known);
2478 // If divisor must be zero, the range is just +-INF
2479 // (including if the dividend is +-INF).
2480 // If dividend must be +-INF, the range is just +-INF
2481 // (including if the dividend is zero).
2482 if (zero_p (rh_lb, rh_ub) || singleton_inf_p (lh_lb, lh_ub))
2483 return inf_range (lb, ub, signbit_known);
2485 // Otherwise if both operands may be zero, divisor could be
2486 // nextafter(0.0, +-1.0) and dividend +-0.0
2487 // in which case result is going to INF or vice versa and
2488 // result +0.0. So, all we can say for that case is if the
2489 // signs of divisor and dividend are always the same we have
2490 // [+0.0, +INF], if they are always different we have
2491 // [-INF, -0.0]. If they vary, VARING.
2492 // If both may be +-INF, divisor could be INF and dividend FLT_MAX,
2493 // in which case result is going to INF or vice versa and
2494 // result +0.0. So, all we can say for that case is if the
2495 // signs of divisor and dividend are always the same we have
2496 // [+0.0, +INF], if they are always different we have
2497 // [-INF, -0.0]. If they vary, VARYING.
2498 if (maybe_nan)
2499 return zero_to_inf_range (lb, ub, signbit_known);
2501 REAL_VALUE_TYPE cp[8];
2502 // Do a cross-division. At this point none of the divisions should
2503 // produce a NAN.
2504 frange_arithmetic (RDIV_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
2505 frange_arithmetic (RDIV_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
2506 frange_arithmetic (RDIV_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
2507 frange_arithmetic (RDIV_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
2508 frange_arithmetic (RDIV_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
2509 frange_arithmetic (RDIV_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
2510 frange_arithmetic (RDIV_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
2511 frange_arithmetic (RDIV_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);
2513 find_range (lb, ub, cp);
2515 // If divisor may be zero (but is not known to be only zero),
2516 // and dividend can't be zero, the range can go up to -INF or +INF
2517 // depending on the signs.
2518 if (contains_zero_p (rh_lb, rh_ub))
2520 if (signbit_known <= 0)
2521 real_inf (&lb, true);
2522 if (signbit_known >= 0)
2523 real_inf (&ub, false);
2526 } fop_div;
2528 // Instantiate a range_op_table for floating point operations.
2529 static floating_op_table global_floating_table;
2531 // Pointer to the float table so the dispatch code can access it.
2532 floating_op_table *floating_tree_table = &global_floating_table;
2534 floating_op_table::floating_op_table ()
2536 set (SSA_NAME, fop_identity);
2537 set (PAREN_EXPR, fop_identity);
2538 set (OBJ_TYPE_REF, fop_identity);
2539 set (REAL_CST, fop_identity);
2541 // All the relational operators are expected to work, because the
2542 // calculation of ranges on outgoing edges expect the handlers to be
2543 // present.
2544 set (EQ_EXPR, fop_equal);
2545 set (NE_EXPR, fop_not_equal);
2546 set (LT_EXPR, fop_lt);
2547 set (LE_EXPR, fop_le);
2548 set (GT_EXPR, fop_gt);
2549 set (GE_EXPR, fop_ge);
2550 set (UNLE_EXPR, fop_unordered_le);
2551 set (UNLT_EXPR, fop_unordered_lt);
2552 set (UNGE_EXPR, fop_unordered_ge);
2553 set (UNGT_EXPR, fop_unordered_gt);
2554 set (UNEQ_EXPR, fop_unordered_equal);
2555 set (ORDERED_EXPR, fop_ordered);
2556 set (UNORDERED_EXPR, fop_unordered);
2558 set (ABS_EXPR, fop_abs);
2559 set (NEGATE_EXPR, fop_negate);
2560 set (PLUS_EXPR, fop_plus);
2561 set (MINUS_EXPR, fop_minus);
2562 set (MULT_EXPR, fop_mult);
2563 set (RDIV_EXPR, fop_div);
2566 // Return a pointer to the range_operator_float instance, if there is
2567 // one associated with tree_code CODE.
2569 range_operator_float *
2570 floating_op_table::operator[] (enum tree_code code)
2572 return m_range_tree[code];
2575 // Add OP to the handler table for CODE.
2577 void
2578 floating_op_table::set (enum tree_code code, range_operator_float &op)
2580 gcc_checking_assert (m_range_tree[code] == NULL);
2581 m_range_tree[code] = &op;
2584 #if CHECKING_P
2585 #include "selftest.h"
2587 namespace selftest
2590 // Build an frange from string endpoints.
2592 inline frange
2593 frange_float (const char *lb, const char *ub, tree type = float_type_node)
2595 REAL_VALUE_TYPE min, max;
2596 gcc_assert (real_from_string (&min, lb) == 0);
2597 gcc_assert (real_from_string (&max, ub) == 0);
2598 return frange (type, min, max);
2601 void
2602 range_op_float_tests ()
2604 frange r, r0, r1;
2605 frange trange (float_type_node);
2607 // negate([-5, +10]) => [-10, 5]
2608 r0 = frange_float ("-5", "10");
2609 fop_negate.fold_range (r, float_type_node, r0, trange);
2610 ASSERT_EQ (r, frange_float ("-10", "5"));
2612 // negate([0, 1] -NAN) => [-1, -0] +NAN
2613 r0 = frange_float ("0", "1");
2614 r0.update_nan (true);
2615 fop_negate.fold_range (r, float_type_node, r0, trange);
2616 r1 = frange_float ("-1", "-0");
2617 r1.update_nan (false);
2618 ASSERT_EQ (r, r1);
2620 // [-INF,+INF] + [-INF,+INF] could be a NAN.
2621 range_op_handler plus (PLUS_EXPR, float_type_node);
2622 r0.set_varying (float_type_node);
2623 r1.set_varying (float_type_node);
2624 r0.clear_nan ();
2625 r1.clear_nan ();
2626 plus.fold_range (r, float_type_node, r0, r1);
2627 if (HONOR_NANS (float_type_node))
2628 ASSERT_TRUE (r.maybe_isnan ());
2631 } // namespace selftest
2633 #endif // CHECKING_P