Branch data Line data Source code
1 : : /* Floating point range operators.
2 : : Copyright (C) 2022-2025 Free Software Foundation, Inc.
3 : : Contributed by Aldy Hernandez <aldyh@redhat.com>.
4 : :
5 : : This file is part of GCC.
6 : :
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.
11 : :
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.
16 : :
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/>. */
20 : :
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"
49 : :
50 : : // Default definitions for floating point operators.
51 : :
52 : : bool
53 : 5552782 : range_operator::fold_range (frange &r, tree type,
54 : : const frange &op1, const frange &op2,
55 : : relation_trio trio) const
56 : : {
57 : 5552782 : if (empty_range_varying (r, type, op1, op2))
58 : 7425 : return true;
59 : 5545357 : if (op1.known_isnan () || op2.known_isnan ())
60 : : {
61 : 7255 : r.set_nan (type);
62 : 7255 : return true;
63 : : }
64 : :
65 : 5538102 : rv_fold (r, type,
66 : : op1.lower_bound (), op1.upper_bound (),
67 : : op2.lower_bound (), op2.upper_bound (), trio.op1_op2 ());
68 : :
69 : 5538102 : if (r.known_isnan ())
70 : : return true;
71 : 6629442 : if (op1.maybe_isnan () || op2.maybe_isnan ())
72 : 5135664 : r.update_nan ();
73 : :
74 : : // If the result has overflowed and flag_trapping_math, folding this
75 : : // operation could elide an overflow or division by zero exception.
76 : : // Avoid returning a singleton +-INF, to keep the propagators (DOM
77 : : // and substitute_and_fold_engine) from folding. See PR107608.
78 : 5537486 : if (flag_trapping_math
79 : 25996678 : && MODE_HAS_INFINITIES (TYPE_MODE (type))
80 : 10652673 : && r.known_isinf () && !op1.known_isinf () && !op2.known_isinf ())
81 : : {
82 : 1556 : REAL_VALUE_TYPE inf = r.lower_bound ();
83 : 1556 : if (real_isneg (&inf))
84 : : {
85 : 96 : REAL_VALUE_TYPE min = real_min_representable (type);
86 : 96 : r.set (type, inf, min);
87 : : }
88 : : else
89 : : {
90 : 1460 : REAL_VALUE_TYPE max = real_max_representable (type);
91 : 1460 : r.set (type, max, inf);
92 : : }
93 : : }
94 : :
95 : 5537486 : r.flush_denormals_to_zero ();
96 : :
97 : 5537486 : return true;
98 : : }
99 : :
100 : : // For a given operation, fold two sets of ranges into [lb, ub].
101 : : // MAYBE_NAN is set to TRUE if, in addition to any result in LB or
102 : : // UB, the final range has the possibility of a NAN.
103 : : void
104 : 1265956 : range_operator::rv_fold (frange &r, tree type,
105 : : const REAL_VALUE_TYPE &,
106 : : const REAL_VALUE_TYPE &,
107 : : const REAL_VALUE_TYPE &,
108 : : const REAL_VALUE_TYPE &, relation_kind) const
109 : : {
110 : 1265956 : r.set (type, dconstninf, dconstinf, nan_state (true));
111 : 1265956 : }
112 : :
113 : : bool
114 : 0 : range_operator::fold_range (irange &r ATTRIBUTE_UNUSED,
115 : : tree type ATTRIBUTE_UNUSED,
116 : : const frange &lh ATTRIBUTE_UNUSED,
117 : : const irange &rh ATTRIBUTE_UNUSED,
118 : : relation_trio) const
119 : : {
120 : 0 : return false;
121 : : }
122 : :
123 : : bool
124 : 0 : range_operator::fold_range (irange &r ATTRIBUTE_UNUSED,
125 : : tree type ATTRIBUTE_UNUSED,
126 : : const frange &lh ATTRIBUTE_UNUSED,
127 : : const frange &rh ATTRIBUTE_UNUSED,
128 : : relation_trio) const
129 : : {
130 : 0 : return false;
131 : : }
132 : :
133 : : bool
134 : 0 : range_operator::fold_range (frange &r ATTRIBUTE_UNUSED,
135 : : tree type ATTRIBUTE_UNUSED,
136 : : const irange &lh ATTRIBUTE_UNUSED,
137 : : const irange &rh ATTRIBUTE_UNUSED,
138 : : relation_trio) const
139 : : {
140 : 0 : return false;
141 : : }
142 : :
143 : : bool
144 : 28815 : range_operator::op1_range (frange &r ATTRIBUTE_UNUSED,
145 : : tree type ATTRIBUTE_UNUSED,
146 : : const frange &lhs ATTRIBUTE_UNUSED,
147 : : const frange &op2 ATTRIBUTE_UNUSED,
148 : : relation_trio) const
149 : : {
150 : 28815 : return false;
151 : : }
152 : :
153 : : bool
154 : 0 : range_operator::op1_range (frange &r ATTRIBUTE_UNUSED,
155 : : tree type ATTRIBUTE_UNUSED,
156 : : const irange &lhs ATTRIBUTE_UNUSED,
157 : : const frange &op2 ATTRIBUTE_UNUSED,
158 : : relation_trio) const
159 : : {
160 : 0 : return false;
161 : : }
162 : :
163 : : bool
164 : 2344 : range_operator::op2_range (frange &r ATTRIBUTE_UNUSED,
165 : : tree type ATTRIBUTE_UNUSED,
166 : : const frange &lhs ATTRIBUTE_UNUSED,
167 : : const frange &op1 ATTRIBUTE_UNUSED,
168 : : relation_trio) const
169 : : {
170 : 2344 : return false;
171 : : }
172 : :
173 : : bool
174 : 0 : range_operator::op2_range (frange &r ATTRIBUTE_UNUSED,
175 : : tree type ATTRIBUTE_UNUSED,
176 : : const irange &lhs ATTRIBUTE_UNUSED,
177 : : const frange &op1 ATTRIBUTE_UNUSED,
178 : : relation_trio) const
179 : : {
180 : 0 : return false;
181 : : }
182 : :
183 : : relation_kind
184 : 5091251 : range_operator::lhs_op1_relation (const frange &lhs ATTRIBUTE_UNUSED,
185 : : const frange &op1 ATTRIBUTE_UNUSED,
186 : : const frange &op2 ATTRIBUTE_UNUSED,
187 : : relation_kind) const
188 : : {
189 : 5091251 : return VREL_VARYING;
190 : : }
191 : :
192 : : relation_kind
193 : 720528 : range_operator::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED,
194 : : const frange &op1 ATTRIBUTE_UNUSED,
195 : : const frange &op2 ATTRIBUTE_UNUSED,
196 : : relation_kind) const
197 : : {
198 : 720528 : return VREL_VARYING;
199 : : }
200 : :
201 : : relation_kind
202 : 156528 : range_operator::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
203 : : const frange &op1 ATTRIBUTE_UNUSED,
204 : : const frange &op2 ATTRIBUTE_UNUSED,
205 : : relation_kind) const
206 : : {
207 : 156528 : return VREL_VARYING;
208 : : }
209 : :
210 : : relation_kind
211 : 3313834 : range_operator::lhs_op2_relation (const frange &lhs ATTRIBUTE_UNUSED,
212 : : const frange &op1 ATTRIBUTE_UNUSED,
213 : : const frange &op2 ATTRIBUTE_UNUSED,
214 : : relation_kind) const
215 : : {
216 : 3313834 : return VREL_VARYING;
217 : : }
218 : :
219 : : relation_kind
220 : 342751 : range_operator::op1_op2_relation (const irange &,
221 : : const frange &,
222 : : const frange &) const
223 : : {
224 : 342751 : return VREL_VARYING;
225 : : }
226 : :
227 : :
228 : : relation_kind
229 : 311623 : range_operator::op1_op2_relation (const frange &,
230 : : const frange &,
231 : : const frange &) const
232 : : {
233 : 311623 : return VREL_VARYING;
234 : : }
235 : :
236 : : // Return TRUE if OP1 and OP2 may be a NAN.
237 : :
238 : : static inline bool
239 : 3495602 : maybe_isnan (const frange &op1, const frange &op2)
240 : : {
241 : 6000691 : return op1.maybe_isnan () || op2.maybe_isnan ();
242 : : }
243 : :
244 : : // Floating point version of relop_early_resolve that takes NANs into
245 : : // account.
246 : : //
247 : : // For relation opcodes, first try to see if the supplied relation
248 : : // forces a true or false result, and return that.
249 : : // Then check for undefined operands. If none of this applies,
250 : : // return false.
251 : : //
252 : : // TRIO are the relations between operands as they appear in the IL.
253 : : // MY_REL is the relation that corresponds to the operator being
254 : : // folded. For example, when attempting to fold x_3 == y_5, MY_REL is
255 : : // VREL_EQ, and if the statement is dominated by x_3 > y_5, then
256 : : // TRIO.op1_op2() is VREL_GT.
257 : :
258 : : static inline bool
259 : 2015421 : frelop_early_resolve (irange &r, tree type,
260 : : const frange &op1, const frange &op2,
261 : : relation_trio trio, relation_kind my_rel)
262 : : {
263 : 2015421 : relation_kind rel = trio.op1_op2 ();
264 : :
265 : : // If known relation is a complete subset of this relation, always
266 : : // return true. However, avoid doing this when NAN is a possibility
267 : : // as we'll incorrectly fold conditions:
268 : : //
269 : : // if (x_3 >= y_5)
270 : : // ;
271 : : // else
272 : : // ;; With NANs the relation here is basically VREL_UNLT, so we
273 : : // ;; can't fold the following:
274 : : // if (x_3 < y_5)
275 : 2015421 : if (!maybe_isnan (op1, op2) && relation_union (rel, my_rel) == my_rel)
276 : : {
277 : 628 : r = range_true (type);
278 : 628 : return true;
279 : : }
280 : :
281 : : // If known relation has no subset of this relation, always false.
282 : 2014793 : if (relation_intersect (rel, my_rel) == VREL_UNDEFINED)
283 : : {
284 : 799 : r = range_false (type);
285 : 799 : return true;
286 : : }
287 : :
288 : : // If either operand is undefined, return VARYING.
289 : 2013994 : if (empty_range_varying (r, type, op1, op2))
290 : 2222 : return true;
291 : :
292 : : return false;
293 : : }
294 : :
295 : : // Set VALUE to its next real value, or INF if the operation overflows.
296 : :
297 : : void
298 : 993746 : frange_nextafter (enum machine_mode mode,
299 : : REAL_VALUE_TYPE &value,
300 : : const REAL_VALUE_TYPE &inf)
301 : : {
302 : 6956222 : if (MODE_COMPOSITE_P (mode)
303 : 0 : && (real_isdenormal (&value, mode) || real_iszero (&value)))
304 : : {
305 : : // IBM extended denormals only have DFmode precision.
306 : 0 : REAL_VALUE_TYPE tmp, tmp2;
307 : 0 : real_convert (&tmp2, DFmode, &value);
308 : 0 : real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2, &inf);
309 : 0 : real_convert (&value, mode, &tmp);
310 : : }
311 : : else
312 : : {
313 : 993746 : REAL_VALUE_TYPE tmp;
314 : 993746 : real_nextafter (&tmp, REAL_MODE_FORMAT (mode), &value, &inf);
315 : 993746 : value = tmp;
316 : : }
317 : 993746 : }
318 : :
319 : : // Like real_arithmetic, but round the result to INF if the operation
320 : : // produced inexact results.
321 : : //
322 : : // ?? There is still one problematic case, i387. With
323 : : // -fexcess-precision=standard we perform most SF/DFmode arithmetic in
324 : : // XFmode (long_double_type_node), so that case is OK. But without
325 : : // -mfpmath=sse, all the SF/DFmode computations are in XFmode
326 : : // precision (64-bit mantissa) and only occasionally rounded to
327 : : // SF/DFmode (when storing into memory from the 387 stack). Maybe
328 : : // this is ok as well though it is just occasionally more precise. ??
329 : :
330 : : void
331 : 11073548 : frange_arithmetic (enum tree_code code, tree type,
332 : : REAL_VALUE_TYPE &result,
333 : : const REAL_VALUE_TYPE &op1,
334 : : const REAL_VALUE_TYPE &op2,
335 : : const REAL_VALUE_TYPE &inf)
336 : : {
337 : 11073548 : REAL_VALUE_TYPE value;
338 : 11073548 : enum machine_mode mode = TYPE_MODE (type);
339 : 77514836 : bool mode_composite = MODE_COMPOSITE_P (mode);
340 : :
341 : 11073548 : bool inexact = real_arithmetic (&value, code, &op1, &op2);
342 : 11073548 : real_convert (&result, mode, &value);
343 : :
344 : : /* When rounding towards negative infinity, x + (-x) and
345 : : x - x is -0 rather than +0 real_arithmetic computes.
346 : : So, when we are looking for lower bound (inf is negative),
347 : : use -0 rather than +0. */
348 : 11073548 : if (flag_rounding_math
349 : 16404 : && (code == PLUS_EXPR || code == MINUS_EXPR)
350 : 4688 : && !inexact
351 : 4688 : && real_iszero (&result)
352 : 66 : && !real_isneg (&result)
353 : 11073614 : && real_isneg (&inf))
354 : : {
355 : 36 : REAL_VALUE_TYPE op2a = op2;
356 : 36 : if (code == PLUS_EXPR)
357 : 30 : op2a.sign ^= 1;
358 : 36 : if (real_isneg (&op1) == real_isneg (&op2a) && real_equal (&op1, &op2a))
359 : 36 : result.sign = 1;
360 : : }
361 : :
362 : : // Be extra careful if there may be discrepancies between the
363 : : // compile and runtime results.
364 : 11073548 : bool round = false;
365 : 11073548 : if (mode_composite)
366 : : round = true;
367 : : else
368 : : {
369 : 11073548 : bool low = real_isneg (&inf);
370 : 16610390 : round = (low ? !real_less (&result, &value)
371 : 5536842 : : !real_less (&value, &result));
372 : 11073548 : if (real_isinf (&result, !low)
373 : 2001035 : && !real_isinf (&value)
374 : 11442471 : && !flag_rounding_math)
375 : : {
376 : : // Use just [+INF, +INF] rather than [MAX, +INF]
377 : : // even if value is larger than MAX and rounds to
378 : : // nearest to +INF. Similarly just [-INF, -INF]
379 : : // rather than [-INF, +MAX] even if value is smaller
380 : : // than -MAX and rounds to nearest to -INF.
381 : : // Unless INEXACT is true, in that case we need some
382 : : // extra buffer.
383 : 366998 : if (!inexact)
384 : : round = false;
385 : : else
386 : : {
387 : 56272 : REAL_VALUE_TYPE tmp = result, tmp2;
388 : 56272 : frange_nextafter (mode, tmp, inf);
389 : : // TMP is at this point the maximum representable
390 : : // number.
391 : 56272 : real_arithmetic (&tmp2, MINUS_EXPR, &value, &tmp);
392 : 56272 : if (real_isneg (&tmp2) != low
393 : 56272 : && (REAL_EXP (&tmp2) - REAL_EXP (&tmp)
394 : 56272 : >= 2 - REAL_MODE_FORMAT (mode)->p))
395 : 56272 : round = false;
396 : : }
397 : : }
398 : : }
399 : 10762822 : if (round && (inexact || !real_identical (&result, &value)))
400 : : {
401 : 193123 : if (mode_composite
402 : 193123 : && (real_isdenormal (&result, mode) || real_iszero (&result)))
403 : : {
404 : : // IBM extended denormals only have DFmode precision.
405 : 0 : REAL_VALUE_TYPE tmp, tmp2;
406 : 0 : real_convert (&tmp2, DFmode, &value);
407 : 0 : real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2, &inf);
408 : 0 : real_convert (&result, mode, &tmp);
409 : : }
410 : : else
411 : 193123 : frange_nextafter (mode, result, inf);
412 : : }
413 : 11073548 : if (mode_composite)
414 : 0 : switch (code)
415 : : {
416 : 0 : case PLUS_EXPR:
417 : 0 : case MINUS_EXPR:
418 : : // ibm-ldouble-format documents 1ulp for + and -.
419 : 0 : frange_nextafter (mode, result, inf);
420 : 0 : break;
421 : 0 : case MULT_EXPR:
422 : : // ibm-ldouble-format documents 2ulps for *.
423 : 0 : frange_nextafter (mode, result, inf);
424 : 0 : frange_nextafter (mode, result, inf);
425 : 0 : break;
426 : 0 : case RDIV_EXPR:
427 : : // ibm-ldouble-format documents 3ulps for /.
428 : 0 : frange_nextafter (mode, result, inf);
429 : 0 : frange_nextafter (mode, result, inf);
430 : 0 : frange_nextafter (mode, result, inf);
431 : 0 : break;
432 : : default:
433 : : break;
434 : : }
435 : 11073548 : }
436 : :
437 : : // Crop R to [-INF, MAX] where MAX is the maximum representable number
438 : : // for TYPE.
439 : :
440 : : static inline void
441 : 146969 : frange_drop_inf (frange &r, tree type)
442 : : {
443 : 146969 : REAL_VALUE_TYPE max = real_max_representable (type);
444 : 146969 : frange tmp (type, r.lower_bound (), max);
445 : 146969 : r.intersect (tmp);
446 : 146969 : }
447 : :
448 : : // Crop R to [MIN, +INF] where MIN is the minimum representable number
449 : : // for TYPE.
450 : :
451 : : static inline void
452 : 71570 : frange_drop_ninf (frange &r, tree type)
453 : : {
454 : 71570 : REAL_VALUE_TYPE min = real_min_representable (type);
455 : 71570 : frange tmp (type, min, r.upper_bound ());
456 : 71570 : r.intersect (tmp);
457 : 71570 : }
458 : :
459 : : // Crop R to [MIN, MAX] where MAX is the maximum representable number
460 : : // for TYPE and MIN the minimum representable number for TYPE.
461 : :
462 : : static inline void
463 : 79597 : frange_drop_infs (frange &r, tree type)
464 : : {
465 : 79597 : REAL_VALUE_TYPE max = real_max_representable (type);
466 : 79597 : REAL_VALUE_TYPE min = real_min_representable (type);
467 : 79597 : frange tmp (type, min, max);
468 : 79597 : r.intersect (tmp);
469 : 79597 : }
470 : :
471 : : // If zero is in R, make sure both -0.0 and +0.0 are in the range.
472 : :
473 : : static inline void
474 : 673212 : frange_add_zeros (frange &r, tree type)
475 : : {
476 : 673212 : if (r.undefined_p () || r.known_isnan ())
477 : : return;
478 : :
479 : 673212 : if (HONOR_SIGNED_ZEROS (type)
480 : 673212 : && (real_iszero (&r.lower_bound ()) || real_iszero (&r.upper_bound ())))
481 : : {
482 : 126486 : frange zero;
483 : 126486 : zero.set_zero (type);
484 : 126486 : r.union_ (zero);
485 : 126486 : }
486 : : }
487 : :
488 : : // Build a range that is <= VAL and store it in R. Return TRUE if
489 : : // further changes may be needed for R, or FALSE if R is in its final
490 : : // form.
491 : :
492 : : static bool
493 : 218003 : build_le (frange &r, tree type, const frange &val)
494 : : {
495 : 218003 : gcc_checking_assert (!val.known_isnan ());
496 : :
497 : 218003 : REAL_VALUE_TYPE ninf = frange_val_min (type);
498 : 218003 : r.set (type, ninf, val.upper_bound ());
499 : :
500 : : // Add both zeros if there's the possibility of zero equality.
501 : 218003 : frange_add_zeros (r, type);
502 : :
503 : 218003 : return true;
504 : : }
505 : :
506 : : // Build a range that is < VAL and store it in R. Return TRUE if
507 : : // further changes may be needed for R, or FALSE if R is in its final
508 : : // form.
509 : :
510 : : static bool
511 : 269643 : build_lt (frange &r, tree type, const frange &val)
512 : : {
513 : 269643 : gcc_checking_assert (!val.known_isnan ());
514 : :
515 : : // < -INF is outside the range.
516 : 269643 : if (real_isinf (&val.upper_bound (), 1))
517 : : {
518 : 1052 : if (HONOR_NANS (type))
519 : 1052 : r.set_nan (type);
520 : : else
521 : 0 : r.set_undefined ();
522 : 1052 : return false;
523 : : }
524 : :
525 : 268591 : REAL_VALUE_TYPE ninf = frange_val_min (type);
526 : 268591 : REAL_VALUE_TYPE prev = val.upper_bound ();
527 : 268591 : machine_mode mode = TYPE_MODE (type);
528 : : // Default to the conservatively correct closed ranges for
529 : : // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
530 : : // !HONOR_INFINITIES, nextafter will yield -INF, but frange::set()
531 : : // will crop the range appropriately.
532 : 1880137 : if (!MODE_COMPOSITE_P (mode))
533 : 268591 : frange_nextafter (mode, prev, ninf);
534 : 268591 : r.set (type, ninf, prev);
535 : 268591 : return true;
536 : : }
537 : :
538 : : // Build a range that is >= VAL and store it in R. Return TRUE if
539 : : // further changes may be needed for R, or FALSE if R is in its final
540 : : // form.
541 : :
542 : : static bool
543 : 337611 : build_ge (frange &r, tree type, const frange &val)
544 : : {
545 : 337611 : gcc_checking_assert (!val.known_isnan ());
546 : :
547 : 337611 : REAL_VALUE_TYPE inf = frange_val_max (type);
548 : 337611 : r.set (type, val.lower_bound (), inf);
549 : :
550 : : // Add both zeros if there's the possibility of zero equality.
551 : 337611 : frange_add_zeros (r, type);
552 : :
553 : 337611 : return true;
554 : : }
555 : :
556 : : // Build a range that is > VAL and store it in R. Return TRUE if
557 : : // further changes may be needed for R, or FALSE if R is in its final
558 : : // form.
559 : :
560 : : static bool
561 : 173429 : build_gt (frange &r, tree type, const frange &val)
562 : : {
563 : 173429 : gcc_checking_assert (!val.known_isnan ());
564 : :
565 : : // > +INF is outside the range.
566 : 173429 : if (real_isinf (&val.lower_bound (), 0))
567 : : {
568 : 2385 : if (HONOR_NANS (type))
569 : 2385 : r.set_nan (type);
570 : : else
571 : 0 : r.set_undefined ();
572 : 2385 : return false;
573 : : }
574 : :
575 : 171044 : REAL_VALUE_TYPE inf = frange_val_max (type);
576 : 171044 : REAL_VALUE_TYPE next = val.lower_bound ();
577 : 171044 : machine_mode mode = TYPE_MODE (type);
578 : : // Default to the conservatively correct closed ranges for
579 : : // MODE_COMPOSITE_P, otherwise use nextafter. Note that for
580 : : // !HONOR_INFINITIES, nextafter will yield +INF, but frange::set()
581 : : // will crop the range appropriately.
582 : 1197308 : if (!MODE_COMPOSITE_P (mode))
583 : 171044 : frange_nextafter (mode, next, inf);
584 : 171044 : r.set (type, next, inf);
585 : 171044 : return true;
586 : : }
587 : :
588 : :
589 : : bool
590 : 37351 : operator_identity::fold_range (frange &r, tree, const frange &op1,
591 : : const frange &, relation_trio) const
592 : : {
593 : 37351 : r = op1;
594 : 37351 : return true;
595 : : }
596 : :
597 : : bool
598 : 3898 : operator_identity::op1_range (frange &r, tree, const frange &lhs,
599 : : const frange &, relation_trio) const
600 : : {
601 : 3898 : r = lhs;
602 : 3898 : return true;
603 : : }
604 : :
605 : : bool
606 : 1072 : operator_cst::fold_range (frange &r, tree, const frange &op1,
607 : : const frange &, relation_trio) const
608 : : {
609 : 1072 : r = op1;
610 : 1072 : return true;
611 : : }
612 : :
613 : : bool
614 : 23522 : operator_equal::op2_range (frange &r, tree type,
615 : : const irange &lhs, const frange &op1,
616 : : relation_trio rel) const
617 : : {
618 : 23522 : return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
619 : : }
620 : :
621 : : bool
622 : 139041 : operator_equal::fold_range (irange &r, tree type,
623 : : const frange &op1, const frange &op2,
624 : : relation_trio rel) const
625 : : {
626 : 139041 : if (frelop_early_resolve (r, type, op1, op2, rel, VREL_EQ))
627 : : return true;
628 : :
629 : 138613 : if (op1.known_isnan () || op2.known_isnan ())
630 : 300 : r = range_false (type);
631 : : // We can be sure the values are always equal or not if both ranges
632 : : // consist of a single value, and then compare them.
633 : 138313 : else if (op1.singleton_p () && op2.singleton_p ())
634 : : {
635 : 428 : if (op1 == op2)
636 : 112 : r = range_true (type);
637 : : // If one operand is -0.0 and other 0.0, they are still equal.
638 : 316 : else if (real_iszero (&op1.lower_bound ())
639 : 316 : && real_iszero (&op2.lower_bound ()))
640 : 30 : r = range_true (type);
641 : : else
642 : 286 : r = range_false (type);
643 : : }
644 : 137885 : else if (real_iszero (&op1.lower_bound ())
645 : 3999 : && real_iszero (&op1.upper_bound ())
646 : 690 : && real_iszero (&op2.lower_bound ())
647 : 270 : && real_iszero (&op2.upper_bound ())
648 : 138155 : && !maybe_isnan (op1, op2))
649 : : // [-0.0, 0.0] == [-0.0, 0.0] or similar.
650 : 127 : r = range_true (type);
651 : : else
652 : : {
653 : : // If ranges do not intersect, we know the range is not equal,
654 : : // otherwise we don't know anything for sure.
655 : 137758 : frange tmp = op1;
656 : 137758 : tmp.intersect (op2);
657 : 137758 : if (tmp.undefined_p ())
658 : : {
659 : : // If one range is [whatever, -0.0] and another
660 : : // [0.0, whatever2], we don't know anything either,
661 : : // because -0.0 == 0.0.
662 : 267 : if ((real_iszero (&op1.upper_bound ())
663 : 44 : && real_iszero (&op2.lower_bound ()))
664 : 270 : || (real_iszero (&op1.lower_bound ())
665 : 35 : && real_iszero (&op2.upper_bound ())))
666 : 41 : r = range_true_and_false (type);
667 : : else
668 : 226 : r = range_false (type);
669 : : }
670 : : else
671 : 137491 : r = range_true_and_false (type);
672 : 137758 : }
673 : : return true;
674 : : }
675 : :
676 : : bool
677 : 121126 : operator_equal::op1_range (frange &r, tree type,
678 : : const irange &lhs,
679 : : const frange &op2,
680 : : relation_trio trio) const
681 : : {
682 : 121126 : relation_kind rel = trio.op1_op2 ();
683 : 121126 : switch (get_bool_state (r, lhs, type))
684 : : {
685 : 27698 : case BRS_TRUE:
686 : : // The TRUE side of x == NAN is unreachable.
687 : 27698 : if (op2.known_isnan ())
688 : 0 : r.set_undefined ();
689 : : else
690 : : {
691 : : // If it's true, the result is the same as OP2.
692 : 27698 : r = op2;
693 : : // Add both zeros if there's the possibility of zero equality.
694 : 27698 : frange_add_zeros (r, type);
695 : : // The TRUE side of op1 == op2 implies op1 is !NAN.
696 : 27698 : r.clear_nan ();
697 : : }
698 : : break;
699 : :
700 : 91804 : case BRS_FALSE:
701 : : // The FALSE side of op1 == op1 implies op1 is a NAN.
702 : 91804 : if (rel == VREL_EQ)
703 : 1648 : r.set_nan (type);
704 : : // On the FALSE side of x == NAN, we know nothing about x.
705 : 90156 : else if (op2.known_isnan ())
706 : 0 : r.set_varying (type);
707 : : // If the result is false, the only time we know anything is
708 : : // if OP2 is a constant.
709 : 90156 : else if (op2.singleton_p ()
710 : 96327 : || (!op2.maybe_isnan () && op2.zero_p ()))
711 : : {
712 : 59565 : REAL_VALUE_TYPE tmp = op2.lower_bound ();
713 : 59565 : r.set (type, tmp, tmp, VR_ANTI_RANGE);
714 : : }
715 : : else
716 : 30591 : r.set_varying (type);
717 : : break;
718 : :
719 : : default:
720 : : break;
721 : : }
722 : 121126 : return true;
723 : : }
724 : :
725 : : // Check if the LHS range indicates a relation between OP1 and OP2.
726 : :
727 : : relation_kind
728 : 108252 : operator_equal::op1_op2_relation (const irange &lhs, const frange &,
729 : : const frange &) const
730 : : {
731 : 108252 : if (lhs.undefined_p ())
732 : : return VREL_UNDEFINED;
733 : :
734 : : // FALSE = op1 == op2 indicates NE_EXPR.
735 : 108252 : if (lhs.zero_p ())
736 : : return VREL_NE;
737 : :
738 : : // TRUE = op1 == op2 indicates EQ_EXPR.
739 : 47770 : if (!contains_zero_p (lhs))
740 : 46342 : return VREL_EQ;
741 : : return VREL_VARYING;
742 : : }
743 : :
744 : : bool
745 : 837293 : operator_not_equal::fold_range (irange &r, tree type,
746 : : const frange &op1, const frange &op2,
747 : : relation_trio trio) const
748 : : {
749 : 837293 : relation_kind rel = trio.op1_op2 ();
750 : :
751 : : // VREL_NE & NE_EXPR is always true, even with NANs.
752 : 837293 : if (rel == VREL_NE)
753 : : {
754 : 30 : r = range_true (type);
755 : 30 : return true;
756 : : }
757 : 837263 : if (rel == VREL_EQ && maybe_isnan (op1, op2))
758 : : {
759 : : // Avoid frelop_early_resolve() below as it could fold to FALSE
760 : : // without regards to NANs. This would be incorrect if trying
761 : : // to fold x_5 != x_5 without prior knowledge of NANs.
762 : : }
763 : 821069 : else if (frelop_early_resolve (r, type, op1, op2, trio, VREL_NE))
764 : : return true;
765 : :
766 : : // x != NAN is always TRUE.
767 : 836173 : if (op1.known_isnan () || op2.known_isnan ())
768 : 1048 : r = range_true (type);
769 : : // We can be sure the values are always equal or not if both ranges
770 : : // consist of a single value, and then compare them.
771 : 835125 : else if (op1.singleton_p () && op2.singleton_p ())
772 : : {
773 : 878 : if (op1 == op2)
774 : 606 : r = range_false (type);
775 : : // If one operand is -0.0 and other 0.0, they are still equal.
776 : 272 : else if (real_iszero (&op1.lower_bound ())
777 : 272 : && real_iszero (&op2.lower_bound ()))
778 : 0 : r = range_false (type);
779 : : else
780 : 272 : r = range_true (type);
781 : : }
782 : 834247 : else if (real_iszero (&op1.lower_bound ())
783 : 2987 : && real_iszero (&op1.upper_bound ())
784 : 369 : && real_iszero (&op2.lower_bound ())
785 : 248 : && real_iszero (&op2.upper_bound ())
786 : 834495 : && !maybe_isnan (op1, op2))
787 : : // [-0.0, 0.0] != [-0.0, 0.0] or similar.
788 : 99 : r = range_false (type);
789 : : else
790 : : {
791 : : // If ranges do not intersect, we know the range is not equal,
792 : : // otherwise we don't know anything for sure.
793 : 834148 : frange tmp = op1;
794 : 834148 : tmp.intersect (op2);
795 : 834148 : if (tmp.undefined_p ())
796 : : {
797 : : // If one range is [whatever, -0.0] and another
798 : : // [0.0, whatever2], we don't know anything either,
799 : : // because -0.0 == 0.0.
800 : 558 : if ((real_iszero (&op1.upper_bound ())
801 : 3 : && real_iszero (&op2.lower_bound ()))
802 : 561 : || (real_iszero (&op1.lower_bound ())
803 : 7 : && real_iszero (&op2.upper_bound ())))
804 : 0 : r = range_true_and_false (type);
805 : : else
806 : 558 : r = range_true (type);
807 : : }
808 : : else
809 : 833590 : r = range_true_and_false (type);
810 : 834148 : }
811 : : return true;
812 : : }
813 : :
814 : : bool
815 : 129469 : operator_not_equal::op1_range (frange &r, tree type,
816 : : const irange &lhs,
817 : : const frange &op2,
818 : : relation_trio trio) const
819 : : {
820 : 129469 : relation_kind rel = trio.op1_op2 ();
821 : 129469 : switch (get_bool_state (r, lhs, type))
822 : : {
823 : 38105 : case BRS_TRUE:
824 : : // If the result is true, the only time we know anything is if
825 : : // OP2 is a constant.
826 : 38105 : if (op2.singleton_p ())
827 : : {
828 : : // This is correct even if op1 is NAN, because the following
829 : : // range would be ~[tmp, tmp] with the NAN property set to
830 : : // maybe (VARYING).
831 : 22763 : REAL_VALUE_TYPE tmp = op2.lower_bound ();
832 : 22763 : r.set (type, tmp, tmp, VR_ANTI_RANGE);
833 : : }
834 : : // The TRUE side of op1 != op1 implies op1 is NAN.
835 : 15342 : else if (rel == VREL_EQ)
836 : 1182 : r.set_nan (type);
837 : : else
838 : 14160 : r.set_varying (type);
839 : : break;
840 : :
841 : 89896 : case BRS_FALSE:
842 : : // The FALSE side of x != NAN is impossible.
843 : 89896 : if (op2.known_isnan ())
844 : 9 : r.set_undefined ();
845 : : else
846 : : {
847 : : // If it's false, the result is the same as OP2.
848 : 89887 : r = op2;
849 : : // Add both zeros if there's the possibility of zero equality.
850 : 89887 : frange_add_zeros (r, type);
851 : : // The FALSE side of op1 != op2 implies op1 is !NAN.
852 : 89887 : r.clear_nan ();
853 : : }
854 : : break;
855 : :
856 : : default:
857 : : break;
858 : : }
859 : 129469 : return true;
860 : : }
861 : :
862 : : bool
863 : 54587 : operator_not_equal::op2_range (frange &r, tree type,
864 : : const irange &lhs,
865 : : const frange &op1,
866 : : relation_trio trio) const
867 : : {
868 : 54587 : return op1_range (r, type, lhs, op1, trio);
869 : : }
870 : :
871 : : // Check if the LHS range indicates a relation between OP1 and OP2.
872 : :
873 : : relation_kind
874 : 443786 : operator_not_equal::op1_op2_relation (const irange &lhs, const frange &,
875 : : const frange &) const
876 : : {
877 : 443786 : if (lhs.undefined_p ())
878 : : return VREL_UNDEFINED;
879 : :
880 : : // FALSE = op1 != op2 indicates EQ_EXPR.
881 : 443786 : if (lhs.zero_p ())
882 : : return VREL_EQ;
883 : :
884 : : // TRUE = op1 != op2 indicates NE_EXPR.
885 : 91025 : if (!contains_zero_p (lhs))
886 : 89586 : return VREL_NE;
887 : : return VREL_VARYING;
888 : : }
889 : :
890 : : bool
891 : 255921 : operator_lt::fold_range (irange &r, tree type,
892 : : const frange &op1, const frange &op2,
893 : : relation_trio trio) const
894 : : {
895 : 255921 : if (frelop_early_resolve (r, type, op1, op2, trio, VREL_LT))
896 : : return true;
897 : :
898 : 255315 : if (op1.known_isnan ()
899 : 254871 : || op2.known_isnan ()
900 : 509893 : || !real_less (&op1.lower_bound (), &op2.upper_bound ()))
901 : 2455 : r = range_false (type);
902 : 252860 : else if (!maybe_isnan (op1, op2)
903 : 252860 : && real_less (&op1.upper_bound (), &op2.lower_bound ()))
904 : 1058 : r = range_true (type);
905 : : else
906 : 251802 : r = range_true_and_false (type);
907 : : return true;
908 : : }
909 : :
910 : : bool
911 : 362373 : operator_lt::op1_range (frange &r,
912 : : tree type,
913 : : const irange &lhs,
914 : : const frange &op2,
915 : : relation_trio) const
916 : : {
917 : 362373 : switch (get_bool_state (r, lhs, type))
918 : : {
919 : 125200 : case BRS_TRUE:
920 : : // The TRUE side of x < NAN is unreachable.
921 : 125200 : if (op2.known_isnan ())
922 : 50 : r.set_undefined ();
923 : 125150 : else if (op2.undefined_p ())
924 : : return false;
925 : 125150 : else if (build_lt (r, type, op2))
926 : : {
927 : 125150 : r.clear_nan ();
928 : : // x < y implies x is not +INF.
929 : 125150 : frange_drop_inf (r, type);
930 : : }
931 : : break;
932 : :
933 : 236624 : case BRS_FALSE:
934 : : // On the FALSE side of x < NAN, we know nothing about x.
935 : 447834 : if (op2.maybe_isnan ())
936 : 25414 : r.set_varying (type);
937 : : else
938 : 211210 : build_ge (r, type, op2);
939 : : break;
940 : :
941 : : default:
942 : : break;
943 : : }
944 : : return true;
945 : : }
946 : :
947 : : bool
948 : 54419 : operator_lt::op2_range (frange &r,
949 : : tree type,
950 : : const irange &lhs,
951 : : const frange &op1,
952 : : relation_trio) const
953 : : {
954 : 54419 : switch (get_bool_state (r, lhs, type))
955 : : {
956 : 22697 : case BRS_TRUE:
957 : : // The TRUE side of NAN < x is unreachable.
958 : 22697 : if (op1.known_isnan ())
959 : 40 : r.set_undefined ();
960 : 22657 : else if (op1.undefined_p ())
961 : : return false;
962 : 22657 : else if (build_gt (r, type, op1))
963 : : {
964 : 22657 : r.clear_nan ();
965 : : // x < y implies y is not -INF.
966 : 22657 : frange_drop_ninf (r, type);
967 : : }
968 : : break;
969 : :
970 : 31352 : case BRS_FALSE:
971 : : // On the FALSE side of NAN < x, we know nothing about x.
972 : 32837 : if (op1.maybe_isnan ())
973 : 29867 : r.set_varying (type);
974 : : else
975 : 1485 : build_le (r, type, op1);
976 : : break;
977 : :
978 : : default:
979 : : break;
980 : : }
981 : : return true;
982 : : }
983 : :
984 : :
985 : : // Check if the LHS range indicates a relation between OP1 and OP2.
986 : :
987 : : relation_kind
988 : 218621 : operator_lt::op1_op2_relation (const irange &lhs, const frange &,
989 : : const frange &) const
990 : : {
991 : 218621 : if (lhs.undefined_p ())
992 : : return VREL_UNDEFINED;
993 : :
994 : : // FALSE = op1 < op2 indicates GE_EXPR.
995 : 218621 : if (lhs.zero_p ())
996 : : return VREL_GE;
997 : :
998 : : // TRUE = op1 < op2 indicates LT_EXPR.
999 : 101088 : if (!contains_zero_p (lhs))
1000 : 100388 : return VREL_LT;
1001 : : return VREL_VARYING;
1002 : : }
1003 : :
1004 : : bool
1005 : 271938 : operator_le::fold_range (irange &r, tree type,
1006 : : const frange &op1, const frange &op2,
1007 : : relation_trio rel) const
1008 : : {
1009 : 271938 : if (frelop_early_resolve (r, type, op1, op2, rel, VREL_LE))
1010 : : return true;
1011 : :
1012 : 271484 : if (op1.known_isnan ()
1013 : 270595 : || op2.known_isnan ()
1014 : 542049 : || !real_compare (LE_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
1015 : 1638 : r = range_false (type);
1016 : 269846 : else if (!maybe_isnan (op1, op2)
1017 : 269846 : && real_compare (LE_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
1018 : 684 : r = range_true (type);
1019 : : else
1020 : 269162 : r = range_true_and_false (type);
1021 : : return true;
1022 : : }
1023 : :
1024 : : bool
1025 : 89562 : operator_le::op1_range (frange &r,
1026 : : tree type,
1027 : : const irange &lhs,
1028 : : const frange &op2,
1029 : : relation_trio) const
1030 : : {
1031 : 89562 : switch (get_bool_state (r, lhs, type))
1032 : : {
1033 : 62469 : case BRS_TRUE:
1034 : : // The TRUE side of x <= NAN is unreachable.
1035 : 62469 : if (op2.known_isnan ())
1036 : 0 : r.set_undefined ();
1037 : 62469 : else if (op2.undefined_p ())
1038 : : return false;
1039 : 62469 : else if (build_le (r, type, op2))
1040 : 62469 : r.clear_nan ();
1041 : : break;
1042 : :
1043 : 26795 : case BRS_FALSE:
1044 : : // On the FALSE side of x <= NAN, we know nothing about x.
1045 : 49383 : if (op2.maybe_isnan ())
1046 : 4207 : r.set_varying (type);
1047 : : else
1048 : 22588 : build_gt (r, type, op2);
1049 : : break;
1050 : :
1051 : : default:
1052 : : break;
1053 : : }
1054 : : return true;
1055 : : }
1056 : :
1057 : : bool
1058 : 13949 : operator_le::op2_range (frange &r,
1059 : : tree type,
1060 : : const irange &lhs,
1061 : : const frange &op1,
1062 : : relation_trio) const
1063 : : {
1064 : 13949 : switch (get_bool_state (r, lhs, type))
1065 : : {
1066 : 4285 : case BRS_TRUE:
1067 : : // The TRUE side of NAN <= x is unreachable.
1068 : 4285 : if (op1.known_isnan ())
1069 : 0 : r.set_undefined ();
1070 : 4285 : else if (op1.undefined_p ())
1071 : : return false;
1072 : 4285 : else if (build_ge (r, type, op1))
1073 : 4285 : r.clear_nan ();
1074 : : break;
1075 : :
1076 : 9398 : case BRS_FALSE:
1077 : : // On the FALSE side of NAN <= x, we know nothing about x.
1078 : 9769 : if (op1.maybe_isnan ())
1079 : 9027 : r.set_varying (type);
1080 : 371 : else if (op1.undefined_p ())
1081 : : return false;
1082 : : else
1083 : 371 : build_lt (r, type, op1);
1084 : : break;
1085 : :
1086 : : default:
1087 : : break;
1088 : : }
1089 : : return true;
1090 : : }
1091 : :
1092 : : // Check if the LHS range indicates a relation between OP1 and OP2.
1093 : :
1094 : : relation_kind
1095 : 57567 : operator_le::op1_op2_relation (const irange &lhs, const frange &,
1096 : : const frange &) const
1097 : : {
1098 : 57567 : if (lhs.undefined_p ())
1099 : : return VREL_UNDEFINED;
1100 : :
1101 : : // FALSE = op1 <= op2 indicates GT_EXPR.
1102 : 57567 : if (lhs.zero_p ())
1103 : : return VREL_GT;
1104 : :
1105 : : // TRUE = op1 <= op2 indicates LE_EXPR.
1106 : 28970 : if (!contains_zero_p (lhs))
1107 : 28438 : return VREL_LE;
1108 : : return VREL_VARYING;
1109 : : }
1110 : :
1111 : : bool
1112 : 258815 : operator_gt::fold_range (irange &r, tree type,
1113 : : const frange &op1, const frange &op2,
1114 : : relation_trio trio) const
1115 : : {
1116 : 258815 : if (frelop_early_resolve (r, type, op1, op2, trio, VREL_GT))
1117 : : return true;
1118 : :
1119 : 258121 : if (op1.known_isnan ()
1120 : 257738 : || op2.known_isnan ()
1121 : 515551 : || !real_compare (GT_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
1122 : 4052 : r = range_false (type);
1123 : 254069 : else if (!maybe_isnan (op1, op2)
1124 : 254069 : && real_compare (GT_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
1125 : 756 : r = range_true (type);
1126 : : else
1127 : 253313 : r = range_true_and_false (type);
1128 : : return true;
1129 : : }
1130 : :
1131 : : bool
1132 : 126126 : operator_gt::op1_range (frange &r,
1133 : : tree type,
1134 : : const irange &lhs,
1135 : : const frange &op2,
1136 : : relation_trio) const
1137 : : {
1138 : 126126 : switch (get_bool_state (r, lhs, type))
1139 : : {
1140 : 48923 : case BRS_TRUE:
1141 : : // The TRUE side of x > NAN is unreachable.
1142 : 48923 : if (op2.known_isnan ())
1143 : 10 : r.set_undefined ();
1144 : 48913 : else if (op2.undefined_p ())
1145 : : return false;
1146 : 48913 : else if (build_gt (r, type, op2))
1147 : : {
1148 : 48913 : r.clear_nan ();
1149 : : // x > y implies x is not -INF.
1150 : 48913 : frange_drop_ninf (r, type);
1151 : : }
1152 : : break;
1153 : :
1154 : 76516 : case BRS_FALSE:
1155 : : // On the FALSE side of x > NAN, we know nothing about x.
1156 : 129462 : if (op2.maybe_isnan ())
1157 : 23570 : r.set_varying (type);
1158 : 52946 : else if (op2.undefined_p ())
1159 : : return false;
1160 : : else
1161 : 52946 : build_le (r, type, op2);
1162 : : break;
1163 : :
1164 : : default:
1165 : : break;
1166 : : }
1167 : : return true;
1168 : : }
1169 : :
1170 : : bool
1171 : 53648 : operator_gt::op2_range (frange &r,
1172 : : tree type,
1173 : : const irange &lhs,
1174 : : const frange &op1,
1175 : : relation_trio) const
1176 : : {
1177 : 53648 : switch (get_bool_state (r, lhs, type))
1178 : : {
1179 : 21859 : case BRS_TRUE:
1180 : : // The TRUE side of NAN > x is unreachable.
1181 : 21859 : if (op1.known_isnan ())
1182 : 40 : r.set_undefined ();
1183 : 21819 : else if (op1.undefined_p ())
1184 : : return false;
1185 : 21819 : else if (build_lt (r, type, op1))
1186 : : {
1187 : 21819 : r.clear_nan ();
1188 : : // x > y implies y is not +INF.
1189 : 21819 : frange_drop_inf (r, type);
1190 : : }
1191 : : break;
1192 : :
1193 : 31403 : case BRS_FALSE:
1194 : : // On The FALSE side of NAN > x, we know nothing about x.
1195 : 32463 : if (op1.maybe_isnan ())
1196 : 30343 : r.set_varying (type);
1197 : 1060 : else if (op1.undefined_p ())
1198 : : return false;
1199 : : else
1200 : 1060 : build_ge (r, type, op1);
1201 : : break;
1202 : :
1203 : : default:
1204 : : break;
1205 : : }
1206 : : return true;
1207 : : }
1208 : :
1209 : : // Check if the LHS range indicates a relation between OP1 and OP2.
1210 : :
1211 : : relation_kind
1212 : 211898 : operator_gt::op1_op2_relation (const irange &lhs, const frange &,
1213 : : const frange &) const
1214 : : {
1215 : 211898 : if (lhs.undefined_p ())
1216 : : return VREL_UNDEFINED;
1217 : :
1218 : : // FALSE = op1 > op2 indicates LE_EXPR.
1219 : 211898 : if (lhs.zero_p ())
1220 : : return VREL_LE;
1221 : :
1222 : : // TRUE = op1 > op2 indicates GT_EXPR.
1223 : 93656 : if (!contains_zero_p (lhs))
1224 : 92852 : return VREL_GT;
1225 : : return VREL_VARYING;
1226 : : }
1227 : :
1228 : : bool
1229 : 268637 : operator_ge::fold_range (irange &r, tree type,
1230 : : const frange &op1, const frange &op2,
1231 : : relation_trio rel) const
1232 : : {
1233 : 268637 : if (frelop_early_resolve (r, type, op1, op2, rel, VREL_GE))
1234 : : return true;
1235 : :
1236 : 268260 : if (op1.known_isnan ()
1237 : 267608 : || op2.known_isnan ()
1238 : 535842 : || !real_compare (GE_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
1239 : 926 : r = range_false (type);
1240 : 267334 : else if (!maybe_isnan (op1, op2)
1241 : 267334 : && real_compare (GE_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
1242 : 1625 : r = range_true (type);
1243 : : else
1244 : 265709 : r = range_true_and_false (type);
1245 : : return true;
1246 : : }
1247 : :
1248 : : bool
1249 : 107398 : operator_ge::op1_range (frange &r,
1250 : : tree type,
1251 : : const irange &lhs,
1252 : : const frange &op2,
1253 : : relation_trio) const
1254 : : {
1255 : 107398 : switch (get_bool_state (r, lhs, type))
1256 : : {
1257 : 61406 : case BRS_TRUE:
1258 : : // The TRUE side of x >= NAN is unreachable.
1259 : 61406 : if (op2.known_isnan ())
1260 : 0 : r.set_undefined ();
1261 : 61406 : else if (op2.undefined_p ())
1262 : : return false;
1263 : 61406 : else if (build_ge (r, type, op2))
1264 : 61406 : r.clear_nan ();
1265 : : break;
1266 : :
1267 : 45694 : case BRS_FALSE:
1268 : : // On the FALSE side of x >= NAN, we know nothing about x.
1269 : 84537 : if (op2.maybe_isnan ())
1270 : 6851 : r.set_varying (type);
1271 : 38843 : else if (op2.undefined_p ())
1272 : : return false;
1273 : : else
1274 : 38843 : build_lt (r, type, op2);
1275 : : break;
1276 : :
1277 : : default:
1278 : : break;
1279 : : }
1280 : : return true;
1281 : : }
1282 : :
1283 : : bool
1284 : 11580 : operator_ge::op2_range (frange &r, tree type,
1285 : : const irange &lhs,
1286 : : const frange &op1,
1287 : : relation_trio) const
1288 : : {
1289 : 11580 : switch (get_bool_state (r, lhs, type))
1290 : : {
1291 : 4789 : case BRS_TRUE:
1292 : : // The TRUE side of NAN >= x is unreachable.
1293 : 4789 : if (op1.known_isnan ())
1294 : 0 : r.set_undefined ();
1295 : 4789 : else if (op1.undefined_p ())
1296 : : return false;
1297 : 4789 : else if (build_le (r, type, op1))
1298 : 4789 : r.clear_nan ();
1299 : : break;
1300 : :
1301 : 6525 : case BRS_FALSE:
1302 : : // On the FALSE side of NAN >= x, we know nothing about x.
1303 : 6814 : if (op1.maybe_isnan ())
1304 : 6236 : r.set_varying (type);
1305 : 289 : else if (op1.undefined_p ())
1306 : : return false;
1307 : : else
1308 : 289 : build_gt (r, type, op1);
1309 : : break;
1310 : :
1311 : : default:
1312 : : break;
1313 : : }
1314 : : return true;
1315 : : }
1316 : :
1317 : : // Check if the LHS range indicates a relation between OP1 and OP2.
1318 : :
1319 : : relation_kind
1320 : 55117 : operator_ge::op1_op2_relation (const irange &lhs, const frange &,
1321 : : const frange &) const
1322 : : {
1323 : 55117 : if (lhs.undefined_p ())
1324 : : return VREL_UNDEFINED;
1325 : :
1326 : : // FALSE = op1 >= op2 indicates LT_EXPR.
1327 : 55117 : if (lhs.zero_p ())
1328 : : return VREL_LT;
1329 : :
1330 : : // TRUE = op1 >= op2 indicates GE_EXPR.
1331 : 28397 : if (!contains_zero_p (lhs))
1332 : 27865 : return VREL_GE;
1333 : : return VREL_VARYING;
1334 : : }
1335 : :
1336 : : // UNORDERED_EXPR comparison.
1337 : :
1338 : : class foperator_unordered : public range_operator
1339 : : {
1340 : : using range_operator::fold_range;
1341 : : using range_operator::op1_range;
1342 : : using range_operator::op2_range;
1343 : : public:
1344 : : bool fold_range (irange &r, tree type,
1345 : : const frange &op1, const frange &op2,
1346 : : relation_trio = TRIO_VARYING) const final override;
1347 : : bool op1_range (frange &r, tree type,
1348 : : const irange &lhs, const frange &op2,
1349 : : relation_trio = TRIO_VARYING) const final override;
1350 : 55091 : bool op2_range (frange &r, tree type,
1351 : : const irange &lhs, const frange &op1,
1352 : : relation_trio rel = TRIO_VARYING) const final override
1353 : : {
1354 : 55091 : return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
1355 : : }
1356 : : } fop_unordered;
1357 : :
1358 : : bool
1359 : 49183 : foperator_unordered::fold_range (irange &r, tree type,
1360 : : const frange &op1, const frange &op2,
1361 : : relation_trio) const
1362 : : {
1363 : : // UNORDERED is TRUE if either operand is a NAN.
1364 : 49183 : if (op1.known_isnan () || op2.known_isnan ())
1365 : 42 : r = range_true (type);
1366 : : // UNORDERED is FALSE if neither operand is a NAN.
1367 : 51113 : else if (!op1.maybe_isnan () && !op2.maybe_isnan ())
1368 : 988 : r = range_false (type);
1369 : : else
1370 : 48153 : r = range_true_and_false (type);
1371 : 49183 : return true;
1372 : : }
1373 : :
1374 : : bool
1375 : 98582 : foperator_unordered::op1_range (frange &r, tree type,
1376 : : const irange &lhs,
1377 : : const frange &op2,
1378 : : relation_trio trio) const
1379 : : {
1380 : 98582 : relation_kind rel = trio.op1_op2 ();
1381 : 98582 : switch (get_bool_state (r, lhs, type))
1382 : : {
1383 : 35566 : case BRS_TRUE:
1384 : : // Since at least one operand must be NAN, if one of them is
1385 : : // not, the other must be.
1386 : 35566 : if (rel == VREL_EQ || !op2.maybe_isnan ())
1387 : 7527 : r.set_nan (type);
1388 : : else
1389 : 28039 : r.set_varying (type);
1390 : : break;
1391 : :
1392 : 55374 : case BRS_FALSE:
1393 : : // A false UNORDERED means both operands are !NAN, so it's
1394 : : // impossible for op2 to be a NAN.
1395 : 55374 : if (op2.known_isnan ())
1396 : 0 : r.set_undefined ();
1397 : : else
1398 : : {
1399 : 55374 : r.set_varying (type);
1400 : 55374 : r.clear_nan ();
1401 : : }
1402 : : break;
1403 : :
1404 : : default:
1405 : : break;
1406 : : }
1407 : 98582 : return true;
1408 : : }
1409 : :
1410 : : // ORDERED_EXPR comparison.
1411 : :
1412 : : class foperator_ordered : public range_operator
1413 : : {
1414 : : using range_operator::fold_range;
1415 : : using range_operator::op1_range;
1416 : : using range_operator::op2_range;
1417 : : public:
1418 : : bool fold_range (irange &r, tree type,
1419 : : const frange &op1, const frange &op2,
1420 : : relation_trio = TRIO_VARYING) const final override;
1421 : : bool op1_range (frange &r, tree type,
1422 : : const irange &lhs, const frange &op2,
1423 : : relation_trio = TRIO_VARYING) const final override;
1424 : 29341 : bool op2_range (frange &r, tree type,
1425 : : const irange &lhs, const frange &op1,
1426 : : relation_trio rel = TRIO_VARYING) const final override
1427 : : {
1428 : 29341 : return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
1429 : : }
1430 : : } fop_ordered;
1431 : :
1432 : : bool
1433 : 34227 : foperator_ordered::fold_range (irange &r, tree type,
1434 : : const frange &op1, const frange &op2,
1435 : : relation_trio) const
1436 : : {
1437 : 34227 : if (op1.known_isnan () || op2.known_isnan ())
1438 : 367 : r = range_false (type);
1439 : 36666 : else if (!op1.maybe_isnan () && !op2.maybe_isnan ())
1440 : 1400 : r = range_true (type);
1441 : : else
1442 : 32460 : r = range_true_and_false (type);
1443 : 34227 : return true;
1444 : : }
1445 : :
1446 : : bool
1447 : 62976 : foperator_ordered::op1_range (frange &r, tree type,
1448 : : const irange &lhs,
1449 : : const frange &op2,
1450 : : relation_trio trio) const
1451 : : {
1452 : 62976 : relation_kind rel = trio.op1_op2 ();
1453 : 62976 : switch (get_bool_state (r, lhs, type))
1454 : : {
1455 : 56692 : case BRS_TRUE:
1456 : : // The TRUE side of ORDERED means both operands are !NAN, so
1457 : : // it's impossible for op2 to be a NAN.
1458 : 56692 : if (op2.known_isnan ())
1459 : 10 : r.set_undefined ();
1460 : : else
1461 : : {
1462 : 56682 : r.set_varying (type);
1463 : 56682 : r.clear_nan ();
1464 : : }
1465 : : break;
1466 : :
1467 : 4441 : case BRS_FALSE:
1468 : : // The FALSE side of op1 ORDERED op1 implies op1 is NAN.
1469 : 4441 : if (rel == VREL_EQ)
1470 : 2176 : r.set_nan (type);
1471 : : else
1472 : 2265 : r.set_varying (type);
1473 : : break;
1474 : :
1475 : : default:
1476 : : break;
1477 : : }
1478 : 62976 : return true;
1479 : : }
1480 : :
1481 : : bool
1482 : 235036 : operator_negate::fold_range (frange &r, tree type,
1483 : : const frange &op1, const frange &op2,
1484 : : relation_trio) const
1485 : : {
1486 : 235036 : if (empty_range_varying (r, type, op1, op2))
1487 : 189 : return true;
1488 : 234847 : if (op1.known_isnan ())
1489 : : {
1490 : 356 : bool sign;
1491 : 356 : if (op1.nan_signbit_p (sign))
1492 : 38 : r.set_nan (type, !sign);
1493 : : else
1494 : 318 : r.set_nan (type);
1495 : 356 : return true;
1496 : : }
1497 : :
1498 : 234491 : REAL_VALUE_TYPE lh_lb = op1.lower_bound ();
1499 : 234491 : REAL_VALUE_TYPE lh_ub = op1.upper_bound ();
1500 : 234491 : lh_lb = real_value_negate (&lh_lb);
1501 : 234491 : lh_ub = real_value_negate (&lh_ub);
1502 : 234491 : r.set (type, lh_ub, lh_lb);
1503 : 417212 : if (op1.maybe_isnan ())
1504 : : {
1505 : 51774 : bool sign;
1506 : 51774 : if (op1.nan_signbit_p (sign))
1507 : 3848 : r.update_nan (!sign);
1508 : : else
1509 : 47926 : r.update_nan ();
1510 : : }
1511 : : else
1512 : 182717 : r.clear_nan ();
1513 : : return true;
1514 : : }
1515 : :
1516 : : bool
1517 : 2779 : operator_negate::op1_range (frange &r, tree type,
1518 : : const frange &lhs, const frange &op2,
1519 : : relation_trio rel) const
1520 : : {
1521 : 2779 : return fold_range (r, type, lhs, op2, rel);
1522 : : }
1523 : :
1524 : : bool
1525 : 504121 : operator_abs::fold_range (frange &r, tree type,
1526 : : const frange &op1, const frange &op2,
1527 : : relation_trio) const
1528 : : {
1529 : 504121 : if (empty_range_varying (r, type, op1, op2))
1530 : 41 : return true;
1531 : 504080 : if (op1.known_isnan ())
1532 : : {
1533 : 582 : r.set_nan (type, /*sign=*/false);
1534 : 582 : return true;
1535 : : }
1536 : :
1537 : 503498 : const REAL_VALUE_TYPE lh_lb = op1.lower_bound ();
1538 : 503498 : const REAL_VALUE_TYPE lh_ub = op1.upper_bound ();
1539 : : // Handle the easy case where everything is positive.
1540 : 503498 : if (real_compare (GE_EXPR, &lh_lb, &dconst0)
1541 : 159345 : && !real_iszero (&lh_lb, /*sign=*/true)
1542 : 660577 : && !op1.maybe_isnan (/*sign=*/true))
1543 : : {
1544 : 156788 : r = op1;
1545 : 156788 : return true;
1546 : : }
1547 : :
1548 : 346710 : REAL_VALUE_TYPE min = real_value_abs (&lh_lb);
1549 : 346710 : REAL_VALUE_TYPE max = real_value_abs (&lh_ub);
1550 : : // If the range contains zero then we know that the minimum value in the
1551 : : // range will be zero.
1552 : 346710 : if (real_compare (LE_EXPR, &lh_lb, &dconst0)
1553 : 346710 : && real_compare (GE_EXPR, &lh_ub, &dconst0))
1554 : : {
1555 : 345916 : if (real_compare (GT_EXPR, &min, &max))
1556 : 2822 : max = min;
1557 : 345916 : min = dconst0;
1558 : : }
1559 : : else
1560 : : {
1561 : : // If the range was reversed, swap MIN and MAX.
1562 : 794 : if (real_compare (GT_EXPR, &min, &max))
1563 : 715 : std::swap (min, max);
1564 : : }
1565 : :
1566 : 346710 : r.set (type, min, max);
1567 : 360846 : if (op1.maybe_isnan ())
1568 : 334485 : r.update_nan (/*sign=*/false);
1569 : : else
1570 : 12225 : r.clear_nan ();
1571 : : return true;
1572 : : }
1573 : :
1574 : : bool
1575 : 253261 : operator_abs::op1_range (frange &r, tree type,
1576 : : const frange &lhs, const frange &op2,
1577 : : relation_trio) const
1578 : : {
1579 : 253261 : if (empty_range_varying (r, type, lhs, op2))
1580 : 0 : return true;
1581 : 253261 : if (lhs.known_isnan ())
1582 : : {
1583 : 2697 : r.set_nan (type);
1584 : 2697 : return true;
1585 : : }
1586 : :
1587 : : // Start with the positives because negatives are an impossible result.
1588 : 250564 : frange positives (type, dconst0, frange_val_max (type));
1589 : 250564 : positives.update_nan (/*sign=*/false);
1590 : 250564 : positives.intersect (lhs);
1591 : 250564 : r = positives;
1592 : : // Add -NAN if relevant.
1593 : 377019 : if (r.maybe_isnan ())
1594 : : {
1595 : 124049 : frange neg_nan;
1596 : 124049 : neg_nan.set_nan (type, true);
1597 : 124049 : r.union_ (neg_nan);
1598 : 124049 : }
1599 : 250564 : if (r.known_isnan () || r.undefined_p ())
1600 : : return true;
1601 : : // Then add the negative of each pair:
1602 : : // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
1603 : 250492 : frange negatives (type, real_value_negate (&positives.upper_bound ()),
1604 : 250492 : real_value_negate (&positives.lower_bound ()));
1605 : 250492 : negatives.clear_nan ();
1606 : 250492 : r.union_ (negatives);
1607 : 250492 : return true;
1608 : 501056 : }
1609 : :
1610 : : class foperator_unordered_lt : public range_operator
1611 : : {
1612 : : using range_operator::fold_range;
1613 : : using range_operator::op1_range;
1614 : : using range_operator::op2_range;
1615 : : public:
1616 : 10826 : bool fold_range (irange &r, tree type,
1617 : : const frange &op1, const frange &op2,
1618 : : relation_trio trio = TRIO_VARYING) const final override
1619 : : {
1620 : 10826 : if (op1.known_isnan () || op2.known_isnan ())
1621 : : {
1622 : 39 : r = range_true (type);
1623 : 39 : return true;
1624 : : }
1625 : 10787 : frange op1_no_nan = op1;
1626 : 10787 : frange op2_no_nan = op2;
1627 : 12590 : if (op1.maybe_isnan ())
1628 : 8961 : op1_no_nan.clear_nan ();
1629 : 18128 : if (op2.maybe_isnan ())
1630 : 3446 : op2_no_nan.clear_nan ();
1631 : 10787 : if (!range_op_handler (LT_EXPR).fold_range (r, type, op1_no_nan,
1632 : : op2_no_nan, trio))
1633 : : return false;
1634 : : // The result is the same as the ordered version when the
1635 : : // comparison is true or when the operands cannot be NANs.
1636 : 10787 : if (!maybe_isnan (op1, op2) || r == range_true (type))
1637 : : return true;
1638 : : else
1639 : : {
1640 : 8789 : r = range_true_and_false (type);
1641 : 8789 : return true;
1642 : : }
1643 : 10787 : }
1644 : : bool op1_range (frange &r, tree type,
1645 : : const irange &lhs,
1646 : : const frange &op2,
1647 : : relation_trio trio) const final override;
1648 : : bool op2_range (frange &r, tree type,
1649 : : const irange &lhs,
1650 : : const frange &op1,
1651 : : relation_trio trio) const final override;
1652 : : } fop_unordered_lt;
1653 : :
1654 : : bool
1655 : 3315 : foperator_unordered_lt::op1_range (frange &r, tree type,
1656 : : const irange &lhs,
1657 : : const frange &op2,
1658 : : relation_trio) const
1659 : : {
1660 : 3315 : switch (get_bool_state (r, lhs, type))
1661 : : {
1662 : 1478 : case BRS_TRUE:
1663 : 2900 : if (op2.maybe_isnan ())
1664 : 56 : r.set_varying (type);
1665 : 1422 : else if (op2.undefined_p ())
1666 : : return false;
1667 : : else
1668 : 1422 : build_lt (r, type, op2);
1669 : : break;
1670 : :
1671 : 1233 : case BRS_FALSE:
1672 : : // A false UNORDERED_LT means both operands are !NAN, so it's
1673 : : // impossible for op2 to be a NAN.
1674 : 1233 : if (op2.known_isnan ())
1675 : 0 : r.set_undefined ();
1676 : 1233 : else if (op2.undefined_p ())
1677 : : return false;
1678 : 1233 : else if (build_ge (r, type, op2))
1679 : 1233 : r.clear_nan ();
1680 : : break;
1681 : :
1682 : : default:
1683 : : break;
1684 : : }
1685 : : return true;
1686 : : }
1687 : :
1688 : : bool
1689 : 660 : foperator_unordered_lt::op2_range (frange &r, tree type,
1690 : : const irange &lhs,
1691 : : const frange &op1,
1692 : : relation_trio) const
1693 : : {
1694 : 660 : switch (get_bool_state (r, lhs, type))
1695 : : {
1696 : 56 : case BRS_TRUE:
1697 : 56 : if (op1.maybe_isnan ())
1698 : 56 : r.set_varying (type);
1699 : 0 : else if (op1.undefined_p ())
1700 : : return false;
1701 : : else
1702 : 0 : build_gt (r, type, op1);
1703 : : break;
1704 : :
1705 : 0 : case BRS_FALSE:
1706 : : // A false UNORDERED_LT means both operands are !NAN, so it's
1707 : : // impossible for op1 to be a NAN.
1708 : 0 : if (op1.known_isnan ())
1709 : 0 : r.set_undefined ();
1710 : 0 : else if (op1.undefined_p ())
1711 : : return false;
1712 : 0 : else if (build_le (r, type, op1))
1713 : 0 : r.clear_nan ();
1714 : : break;
1715 : :
1716 : : default:
1717 : : break;
1718 : : }
1719 : : return true;
1720 : : }
1721 : :
1722 : : class foperator_unordered_le : public range_operator
1723 : : {
1724 : : using range_operator::fold_range;
1725 : : using range_operator::op1_range;
1726 : : using range_operator::op2_range;
1727 : : public:
1728 : 180747 : bool fold_range (irange &r, tree type,
1729 : : const frange &op1, const frange &op2,
1730 : : relation_trio trio = TRIO_VARYING) const final override
1731 : : {
1732 : 180747 : if (op1.known_isnan () || op2.known_isnan ())
1733 : : {
1734 : 99 : r = range_true (type);
1735 : 99 : return true;
1736 : : }
1737 : 180648 : frange op1_no_nan = op1;
1738 : 180648 : frange op2_no_nan = op2;
1739 : 202330 : if (op1.maybe_isnan ())
1740 : 158940 : op1_no_nan.clear_nan ();
1741 : 354248 : if (op2.maybe_isnan ())
1742 : 7042 : op2_no_nan.clear_nan ();
1743 : 180648 : if (!range_op_handler (LE_EXPR).fold_range (r, type, op1_no_nan,
1744 : : op2_no_nan, trio))
1745 : : return false;
1746 : : // The result is the same as the ordered version when the
1747 : : // comparison is true or when the operands cannot be NANs.
1748 : 180648 : if (!maybe_isnan (op1, op2) || r == range_true (type))
1749 : : return true;
1750 : : else
1751 : : {
1752 : 160698 : r = range_true_and_false (type);
1753 : 160698 : return true;
1754 : : }
1755 : 180648 : }
1756 : : bool op1_range (frange &r, tree type,
1757 : : const irange &lhs, const frange &op2,
1758 : : relation_trio = TRIO_VARYING) const final override;
1759 : : bool op2_range (frange &r, tree type,
1760 : : const irange &lhs, const frange &op1,
1761 : : relation_trio = TRIO_VARYING) const final override;
1762 : : } fop_unordered_le;
1763 : :
1764 : : bool
1765 : 158237 : foperator_unordered_le::op1_range (frange &r, tree type,
1766 : : const irange &lhs, const frange &op2,
1767 : : relation_trio) const
1768 : : {
1769 : 158237 : switch (get_bool_state (r, lhs, type))
1770 : : {
1771 : 87368 : case BRS_TRUE:
1772 : 169619 : if (op2.maybe_isnan ())
1773 : 5117 : r.set_varying (type);
1774 : 82251 : else if (op2.undefined_p ())
1775 : : return false;
1776 : : else
1777 : 82251 : build_le (r, type, op2);
1778 : : break;
1779 : :
1780 : 70253 : case BRS_FALSE:
1781 : : // A false UNORDERED_LE means both operands are !NAN, so it's
1782 : : // impossible for op2 to be a NAN.
1783 : 70253 : if (op2.known_isnan ())
1784 : 0 : r.set_undefined ();
1785 : 70253 : else if (build_gt (r, type, op2))
1786 : 70251 : r.clear_nan ();
1787 : : break;
1788 : :
1789 : : default:
1790 : : break;
1791 : : }
1792 : : return true;
1793 : : }
1794 : :
1795 : : bool
1796 : 14068 : foperator_unordered_le::op2_range (frange &r,
1797 : : tree type,
1798 : : const irange &lhs,
1799 : : const frange &op1,
1800 : : relation_trio) const
1801 : : {
1802 : 14068 : switch (get_bool_state (r, lhs, type))
1803 : : {
1804 : 9851 : case BRS_TRUE:
1805 : 14857 : if (op1.maybe_isnan ())
1806 : 4845 : r.set_varying (type);
1807 : 5006 : else if (op1.undefined_p ())
1808 : : return false;
1809 : : else
1810 : 5006 : build_ge (r, type, op1);
1811 : : break;
1812 : :
1813 : 3601 : case BRS_FALSE:
1814 : : // A false UNORDERED_LE means both operands are !NAN, so it's
1815 : : // impossible for op1 to be a NAN.
1816 : 3601 : if (op1.known_isnan ())
1817 : 0 : r.set_undefined ();
1818 : 3601 : else if (op1.undefined_p ())
1819 : : return false;
1820 : 3601 : else if (build_lt (r, type, op1))
1821 : 3601 : r.clear_nan ();
1822 : : break;
1823 : :
1824 : : default:
1825 : : break;
1826 : : }
1827 : : return true;
1828 : : }
1829 : :
1830 : : class foperator_unordered_gt : public range_operator
1831 : : {
1832 : : using range_operator::fold_range;
1833 : : using range_operator::op1_range;
1834 : : using range_operator::op2_range;
1835 : : public:
1836 : 47809 : bool fold_range (irange &r, tree type,
1837 : : const frange &op1, const frange &op2,
1838 : : relation_trio trio = TRIO_VARYING) const final override
1839 : : {
1840 : 47809 : if (op1.known_isnan () || op2.known_isnan ())
1841 : : {
1842 : 169 : r = range_true (type);
1843 : 169 : return true;
1844 : : }
1845 : 47640 : frange op1_no_nan = op1;
1846 : 47640 : frange op2_no_nan = op2;
1847 : 50532 : if (op1.maybe_isnan ())
1848 : 44730 : op1_no_nan.clear_nan ();
1849 : 91736 : if (op2.maybe_isnan ())
1850 : 3544 : op2_no_nan.clear_nan ();
1851 : 47640 : if (!range_op_handler (GT_EXPR).fold_range (r, type, op1_no_nan,
1852 : : op2_no_nan, trio))
1853 : : return false;
1854 : : // The result is the same as the ordered version when the
1855 : : // comparison is true or when the operands cannot be NANs.
1856 : 47640 : if (!maybe_isnan (op1, op2) || r == range_true (type))
1857 : : return true;
1858 : : else
1859 : : {
1860 : 44565 : r = range_true_and_false (type);
1861 : 44565 : return true;
1862 : : }
1863 : 47640 : }
1864 : : bool op1_range (frange &r, tree type,
1865 : : const irange &lhs, const frange &op2,
1866 : : relation_trio = TRIO_VARYING) const final override;
1867 : : bool op2_range (frange &r, tree type,
1868 : : const irange &lhs, const frange &op1,
1869 : : relation_trio = TRIO_VARYING) const final override;
1870 : : } fop_unordered_gt;
1871 : :
1872 : : bool
1873 : 13690 : foperator_unordered_gt::op1_range (frange &r,
1874 : : tree type,
1875 : : const irange &lhs,
1876 : : const frange &op2,
1877 : : relation_trio) const
1878 : : {
1879 : 13690 : switch (get_bool_state (r, lhs, type))
1880 : : {
1881 : 3421 : case BRS_TRUE:
1882 : 6766 : if (op2.maybe_isnan ())
1883 : 76 : r.set_varying (type);
1884 : 3345 : else if (op2.undefined_p ())
1885 : : return false;
1886 : : else
1887 : 3345 : build_gt (r, type, op2);
1888 : : break;
1889 : :
1890 : 9689 : case BRS_FALSE:
1891 : : // A false UNORDERED_GT means both operands are !NAN, so it's
1892 : : // impossible for op2 to be a NAN.
1893 : 9689 : if (op2.known_isnan ())
1894 : 0 : r.set_undefined ();
1895 : 9689 : else if (op2.undefined_p ())
1896 : : return false;
1897 : 9689 : else if (build_le (r, type, op2))
1898 : 9689 : r.clear_nan ();
1899 : : break;
1900 : :
1901 : : default:
1902 : : break;
1903 : : }
1904 : : return true;
1905 : : }
1906 : :
1907 : : bool
1908 : 656 : foperator_unordered_gt::op2_range (frange &r,
1909 : : tree type,
1910 : : const irange &lhs,
1911 : : const frange &op1,
1912 : : relation_trio) const
1913 : : {
1914 : 656 : switch (get_bool_state (r, lhs, type))
1915 : : {
1916 : 76 : case BRS_TRUE:
1917 : 76 : if (op1.maybe_isnan ())
1918 : 76 : r.set_varying (type);
1919 : 0 : else if (op1.undefined_p ())
1920 : : return false;
1921 : : else
1922 : 0 : build_lt (r, type, op1);
1923 : : break;
1924 : :
1925 : 0 : case BRS_FALSE:
1926 : : // A false UNORDERED_GT means both operands are !NAN, so it's
1927 : : // impossible for op1 to be a NAN.
1928 : 0 : if (op1.known_isnan ())
1929 : 0 : r.set_undefined ();
1930 : 0 : else if (op1.undefined_p ())
1931 : : return false;
1932 : 0 : else if (build_ge (r, type, op1))
1933 : 0 : r.clear_nan ();
1934 : : break;
1935 : :
1936 : : default:
1937 : : break;
1938 : : }
1939 : : return true;
1940 : : }
1941 : :
1942 : : class foperator_unordered_ge : public range_operator
1943 : : {
1944 : : using range_operator::fold_range;
1945 : : using range_operator::op1_range;
1946 : : using range_operator::op2_range;
1947 : : public:
1948 : 174472 : bool fold_range (irange &r, tree type,
1949 : : const frange &op1, const frange &op2,
1950 : : relation_trio trio = TRIO_VARYING) const final override
1951 : : {
1952 : 174472 : if (op1.known_isnan () || op2.known_isnan ())
1953 : : {
1954 : 45 : r = range_true (type);
1955 : 45 : return true;
1956 : : }
1957 : 174427 : frange op1_no_nan = op1;
1958 : 174427 : frange op2_no_nan = op2;
1959 : 181823 : if (op1.maybe_isnan ())
1960 : 166975 : op1_no_nan.clear_nan ();
1961 : 341877 : if (op2.maybe_isnan ())
1962 : 6971 : op2_no_nan.clear_nan ();
1963 : 174427 : if (!range_op_handler (GE_EXPR).fold_range (r, type, op1_no_nan,
1964 : : op2_no_nan, trio))
1965 : : return false;
1966 : : // The result is the same as the ordered version when the
1967 : : // comparison is true or when the operands cannot be NANs.
1968 : 174427 : if (!maybe_isnan (op1, op2) || r == range_true (type))
1969 : : return true;
1970 : : else
1971 : : {
1972 : 167519 : r = range_true_and_false (type);
1973 : 167519 : return true;
1974 : : }
1975 : 174427 : }
1976 : : bool op1_range (frange &r, tree type,
1977 : : const irange &lhs, const frange &op2,
1978 : : relation_trio = TRIO_VARYING) const final override;
1979 : : bool op2_range (frange &r, tree type,
1980 : : const irange &lhs, const frange &op1,
1981 : : relation_trio = TRIO_VARYING) const final override;
1982 : : } fop_unordered_ge;
1983 : :
1984 : : bool
1985 : 137149 : foperator_unordered_ge::op1_range (frange &r,
1986 : : tree type,
1987 : : const irange &lhs,
1988 : : const frange &op2,
1989 : : relation_trio) const
1990 : : {
1991 : 137149 : switch (get_bool_state (r, lhs, type))
1992 : : {
1993 : 58056 : case BRS_TRUE:
1994 : 111467 : if (op2.maybe_isnan ())
1995 : 4645 : r.set_varying (type);
1996 : 53411 : else if (op2.undefined_p ())
1997 : : return false;
1998 : : else
1999 : 53411 : build_ge (r, type, op2);
2000 : : break;
2001 : :
2002 : 78437 : case BRS_FALSE:
2003 : : // A false UNORDERED_GE means both operands are !NAN, so it's
2004 : : // impossible for op2 to be a NAN.
2005 : 78437 : if (op2.known_isnan ())
2006 : 0 : r.set_undefined ();
2007 : 78437 : else if (op2.undefined_p ())
2008 : : return false;
2009 : 78437 : else if (build_lt (r, type, op2))
2010 : 78433 : r.clear_nan ();
2011 : : break;
2012 : :
2013 : : default:
2014 : : break;
2015 : : }
2016 : : return true;
2017 : : }
2018 : :
2019 : : bool
2020 : 14813 : foperator_unordered_ge::op2_range (frange &r, tree type,
2021 : : const irange &lhs,
2022 : : const frange &op1,
2023 : : relation_trio) const
2024 : : {
2025 : 14813 : switch (get_bool_state (r, lhs, type))
2026 : : {
2027 : 8861 : case BRS_TRUE:
2028 : 13235 : if (op1.maybe_isnan ())
2029 : 4487 : r.set_varying (type);
2030 : 4374 : else if (op1.undefined_p ())
2031 : : return false;
2032 : : else
2033 : 4374 : build_le (r, type, op1);
2034 : : break;
2035 : :
2036 : 5384 : case BRS_FALSE:
2037 : : // A false UNORDERED_GE means both operands are !NAN, so it's
2038 : : // impossible for op1 to be a NAN.
2039 : 5384 : if (op1.known_isnan ())
2040 : 0 : r.set_undefined ();
2041 : 5384 : else if (op1.undefined_p ())
2042 : : return false;
2043 : 5384 : else if (build_gt (r, type, op1))
2044 : 5384 : r.clear_nan ();
2045 : : break;
2046 : :
2047 : : default:
2048 : : break;
2049 : : }
2050 : : return true;
2051 : : }
2052 : :
2053 : : class foperator_unordered_equal : public range_operator
2054 : : {
2055 : : using range_operator::fold_range;
2056 : : using range_operator::op1_range;
2057 : : using range_operator::op2_range;
2058 : : public:
2059 : 3463 : bool fold_range (irange &r, tree type,
2060 : : const frange &op1, const frange &op2,
2061 : : relation_trio trio = TRIO_VARYING) const final override
2062 : : {
2063 : 3463 : if (op1.known_isnan () || op2.known_isnan ())
2064 : : {
2065 : 0 : r = range_true (type);
2066 : 0 : return true;
2067 : : }
2068 : 3463 : frange op1_no_nan = op1;
2069 : 3463 : frange op2_no_nan = op2;
2070 : 3771 : if (op1.maybe_isnan ())
2071 : 3155 : op1_no_nan.clear_nan ();
2072 : 3866 : if (op2.maybe_isnan ())
2073 : 3060 : op2_no_nan.clear_nan ();
2074 : 3463 : if (!range_op_handler (EQ_EXPR).fold_range (r, type, op1_no_nan,
2075 : : op2_no_nan, trio))
2076 : : return false;
2077 : : // The result is the same as the ordered version when the
2078 : : // comparison is true or when the operands cannot be NANs.
2079 : 3463 : if (!maybe_isnan (op1, op2) || r == range_true (type))
2080 : : return true;
2081 : : else
2082 : : {
2083 : 3154 : r = range_true_and_false (type);
2084 : 3154 : return true;
2085 : : }
2086 : 3463 : }
2087 : : bool op1_range (frange &r, tree type,
2088 : : const irange &lhs, const frange &op2,
2089 : : relation_trio = TRIO_VARYING) const final override;
2090 : 608 : bool op2_range (frange &r, tree type,
2091 : : const irange &lhs, const frange &op1,
2092 : : relation_trio rel = TRIO_VARYING) const final override
2093 : : {
2094 : 608 : return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
2095 : : }
2096 : : } fop_unordered_equal;
2097 : :
2098 : : bool
2099 : 1219 : foperator_unordered_equal::op1_range (frange &r, tree type,
2100 : : const irange &lhs,
2101 : : const frange &op2,
2102 : : relation_trio) const
2103 : : {
2104 : 1219 : switch (get_bool_state (r, lhs, type))
2105 : : {
2106 : 3 : case BRS_TRUE:
2107 : : // If it's true, the result is the same as OP2 plus a NAN.
2108 : 3 : r = op2;
2109 : : // Add both zeros if there's the possibility of zero equality.
2110 : 3 : frange_add_zeros (r, type);
2111 : : // Add the possibility of a NAN.
2112 : 3 : r.update_nan ();
2113 : 3 : break;
2114 : :
2115 : 0 : case BRS_FALSE:
2116 : : // A false UNORDERED_EQ means both operands are !NAN, so it's
2117 : : // impossible for op2 to be a NAN.
2118 : 0 : if (op2.known_isnan ())
2119 : 0 : r.set_undefined ();
2120 : : else
2121 : : {
2122 : : // The false side indicates !NAN and not equal. We can at least
2123 : : // represent !NAN.
2124 : 0 : r.set_varying (type);
2125 : 0 : r.clear_nan ();
2126 : : }
2127 : : break;
2128 : :
2129 : : default:
2130 : : break;
2131 : : }
2132 : 1219 : return true;
2133 : : }
2134 : :
2135 : : class foperator_ltgt : public range_operator
2136 : : {
2137 : : using range_operator::fold_range;
2138 : : using range_operator::op1_range;
2139 : : using range_operator::op2_range;
2140 : : public:
2141 : 2021 : bool fold_range (irange &r, tree type,
2142 : : const frange &op1, const frange &op2,
2143 : : relation_trio trio = TRIO_VARYING) const final override
2144 : : {
2145 : 2021 : if (op1.known_isnan () || op2.known_isnan ())
2146 : : {
2147 : 0 : r = range_false (type);
2148 : 0 : return true;
2149 : : }
2150 : 2021 : frange op1_no_nan = op1;
2151 : 2021 : frange op2_no_nan = op2;
2152 : 2329 : if (op1.maybe_isnan ())
2153 : 1697 : op1_no_nan.clear_nan ();
2154 : 2329 : if (op2.maybe_isnan ())
2155 : 1697 : op2_no_nan.clear_nan ();
2156 : 2021 : if (!range_op_handler (NE_EXPR).fold_range (r, type, op1_no_nan,
2157 : : op2_no_nan, trio))
2158 : : return false;
2159 : : // The result is the same as the ordered version when the
2160 : : // comparison is true or when the operands cannot be NANs.
2161 : 2021 : if (!maybe_isnan (op1, op2) || r == range_false (type))
2162 : : return true;
2163 : : else
2164 : : {
2165 : 1697 : r = range_true_and_false (type);
2166 : 1697 : return true;
2167 : : }
2168 : 2021 : }
2169 : : bool op1_range (frange &r, tree type,
2170 : : const irange &lhs, const frange &op2,
2171 : : relation_trio = TRIO_VARYING) const final override;
2172 : 764 : bool op2_range (frange &r, tree type,
2173 : : const irange &lhs, const frange &op1,
2174 : : relation_trio rel = TRIO_VARYING) const final override
2175 : : {
2176 : 764 : return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
2177 : : }
2178 : : } fop_ltgt;
2179 : :
2180 : : bool
2181 : 1518 : foperator_ltgt::op1_range (frange &r, tree type,
2182 : : const irange &lhs,
2183 : : const frange &op2,
2184 : : relation_trio) const
2185 : : {
2186 : 1518 : switch (get_bool_state (r, lhs, type))
2187 : : {
2188 : 0 : case BRS_TRUE:
2189 : : // A true LTGT means both operands are !NAN, so it's
2190 : : // impossible for op2 to be a NAN.
2191 : 0 : if (op2.known_isnan ())
2192 : 0 : r.set_undefined ();
2193 : : else
2194 : : {
2195 : : // The true side indicates !NAN and not equal. We can at least
2196 : : // represent !NAN.
2197 : 0 : r.set_varying (type);
2198 : 0 : r.clear_nan ();
2199 : : }
2200 : : break;
2201 : :
2202 : 10 : case BRS_FALSE:
2203 : : // If it's false, the result is the same as OP2 plus a NAN.
2204 : 10 : r = op2;
2205 : : // Add both zeros if there's the possibility of zero equality.
2206 : 10 : frange_add_zeros (r, type);
2207 : : // Add the possibility of a NAN.
2208 : 10 : r.update_nan ();
2209 : 10 : break;
2210 : :
2211 : : default:
2212 : : break;
2213 : : }
2214 : 1518 : return true;
2215 : : }
2216 : :
2217 : : // Final tweaks for float binary op op1_range/op2_range.
2218 : : // Return TRUE if the operation is performed and a valid range is available.
2219 : :
2220 : : static bool
2221 : 329450 : float_binary_op_range_finish (bool ret, frange &r, tree type,
2222 : : const frange &lhs, bool div_op2 = false)
2223 : : {
2224 : 329450 : if (!ret)
2225 : : return false;
2226 : :
2227 : : // If we get a known NAN from reverse op, it means either that
2228 : : // the other operand was known NAN (in that case we know nothing),
2229 : : // or the reverse operation introduced a known NAN.
2230 : : // Say for lhs = op1 * op2 if lhs is [-0, +0] and op2 is too,
2231 : : // 0 / 0 is known NAN. Just punt in that case.
2232 : : // If NANs aren't honored, we get for 0 / 0 UNDEFINED, so punt as well.
2233 : : // Or if lhs is a known NAN, we also don't know anything.
2234 : 329450 : if (r.known_isnan () || lhs.known_isnan () || r.undefined_p ())
2235 : : {
2236 : 4129 : r.set_varying (type);
2237 : 4129 : return true;
2238 : : }
2239 : :
2240 : : // If lhs isn't NAN, then neither operand could be NAN,
2241 : : // even if the reverse operation does introduce a maybe_nan.
2242 : 522650 : if (!lhs.maybe_isnan ())
2243 : : {
2244 : 197329 : r.clear_nan ();
2245 : 197329 : if (div_op2
2246 : 208150 : ? !(real_compare (LE_EXPR, &lhs.lower_bound (), &dconst0)
2247 : 10821 : && real_compare (GE_EXPR, &lhs.upper_bound (), &dconst0))
2248 : 274245 : : !(real_isinf (&lhs.lower_bound ())
2249 : 94375 : || real_isinf (&lhs.upper_bound ())))
2250 : : // For reverse + or - or * or op1 of /, if result is finite, then
2251 : : // r must be finite too, as X + INF or X - INF or X * INF or
2252 : : // INF / X is always +-INF or NAN. For op2 of /, if result is
2253 : : // non-zero and not NAN, r must be finite, as X / INF is always
2254 : : // 0 or NAN.
2255 : 79597 : frange_drop_infs (r, type);
2256 : : }
2257 : : // If lhs is a maybe or known NAN, the operand could be
2258 : : // NAN.
2259 : : else
2260 : 127992 : r.update_nan ();
2261 : : return true;
2262 : : }
2263 : :
2264 : : // True if [lb, ub] is [+-0, +-0].
2265 : : static bool
2266 : 3819072 : zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2267 : : {
2268 : 3819072 : return real_iszero (&lb) && real_iszero (&ub);
2269 : : }
2270 : :
2271 : : // True if +0 or -0 is in [lb, ub] range.
2272 : : static bool
2273 : 2519015 : contains_zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2274 : : {
2275 : 2519015 : return (real_compare (LE_EXPR, &lb, &dconst0)
2276 : 2519015 : && real_compare (GE_EXPR, &ub, &dconst0));
2277 : : }
2278 : :
2279 : : // True if [lb, ub] is [-INF, -INF] or [+INF, +INF].
2280 : : static bool
2281 : 2020182 : singleton_inf_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
2282 : : {
2283 : 2020182 : return real_isinf (&lb) && real_isinf (&ub, real_isneg (&lb));
2284 : : }
2285 : :
2286 : : // Return -1 if binary op result must have sign bit set,
2287 : : // 1 if binary op result must have sign bit clear,
2288 : : // 0 otherwise.
2289 : : // Sign bit of binary op result is exclusive or of the
2290 : : // operand's sign bits.
2291 : : static int
2292 : 915055 : signbit_known_p (const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
2293 : : const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub)
2294 : : {
2295 : 915055 : if (real_isneg (&lh_lb) == real_isneg (&lh_ub)
2296 : 915055 : && real_isneg (&rh_lb) == real_isneg (&rh_ub))
2297 : : {
2298 : 25795 : if (real_isneg (&lh_lb) == real_isneg (&rh_ub))
2299 : : return 1;
2300 : : else
2301 : 3787 : return -1;
2302 : : }
2303 : : return 0;
2304 : : }
2305 : :
2306 : : // Set [lb, ub] to [-0, -0], [-0, +0] or [+0, +0] depending on
2307 : : // signbit_known.
2308 : : static void
2309 : 5956 : zero_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2310 : : {
2311 : 5956 : ub = lb = dconst0;
2312 : 5956 : if (signbit_known <= 0)
2313 : 5912 : lb = dconstm0;
2314 : 5912 : if (signbit_known < 0)
2315 : 41 : ub = lb;
2316 : 5956 : }
2317 : :
2318 : : // Set [lb, ub] to [-INF, -INF], [-INF, +INF] or [+INF, +INF] depending on
2319 : : // signbit_known.
2320 : : static void
2321 : 3180 : inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2322 : : {
2323 : 3180 : if (signbit_known > 0)
2324 : 897 : ub = lb = dconstinf;
2325 : 2283 : else if (signbit_known < 0)
2326 : 96 : ub = lb = dconstninf;
2327 : : else
2328 : : {
2329 : 2187 : lb = dconstninf;
2330 : 2187 : ub = dconstinf;
2331 : : }
2332 : 3180 : }
2333 : :
2334 : : // Set [lb, ub] to [-INF, -0], [-INF, +INF] or [+0, +INF] depending on
2335 : : // signbit_known.
2336 : : static void
2337 : 752747 : zero_to_inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
2338 : : {
2339 : 752747 : if (signbit_known > 0)
2340 : : {
2341 : 4120 : lb = dconst0;
2342 : 4120 : ub = dconstinf;
2343 : : }
2344 : 748627 : else if (signbit_known < 0)
2345 : : {
2346 : 190 : lb = dconstninf;
2347 : 190 : ub = dconstm0;
2348 : : }
2349 : : else
2350 : : {
2351 : 748437 : lb = dconstninf;
2352 : 748437 : ub = dconstinf;
2353 : : }
2354 : 752747 : }
2355 : :
2356 : : /* Extend the LHS range by 1ulp in each direction. For op1_range
2357 : : or op2_range of binary operations just computing the inverse
2358 : : operation on ranges isn't sufficient. Consider e.g.
2359 : : [1., 1.] = op1 + [1., 1.]. op1's range is not [0., 0.], but
2360 : : [-0x1.0p-54, 0x1.0p-53] (when not -frounding-math), any value for
2361 : : which adding 1. to it results in 1. after rounding to nearest.
2362 : : So, for op1_range/op2_range extend the lhs range by 1ulp (or 0.5ulp)
2363 : : in each direction. See PR109008 for more details. */
2364 : :
2365 : : static frange
2366 : 329450 : float_widen_lhs_range (tree type, const frange &lhs)
2367 : : {
2368 : 329450 : frange ret = lhs;
2369 : 329450 : if (lhs.known_isnan ())
2370 : : return ret;
2371 : 325321 : REAL_VALUE_TYPE lb = lhs.lower_bound ();
2372 : 325321 : REAL_VALUE_TYPE ub = lhs.upper_bound ();
2373 : 325321 : if (real_isfinite (&lb))
2374 : : {
2375 : 184493 : frange_nextafter (TYPE_MODE (type), lb, dconstninf);
2376 : 184493 : if (real_isinf (&lb))
2377 : : {
2378 : : /* For -DBL_MAX, instead of -Inf use
2379 : : nexttoward (-DBL_MAX, -LDBL_MAX) in a hypothetical
2380 : : wider type with the same mantissa precision but larger
2381 : : exponent range; it is outside of range of double values,
2382 : : but makes it clear it is just one ulp larger rather than
2383 : : infinite amount larger. */
2384 : 29364 : lb = dconstm1;
2385 : 117456 : SET_REAL_EXP (&lb, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
2386 : : }
2387 : 1291379 : if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)))
2388 : : {
2389 : : /* If not -frounding-math nor IBM double double, actually widen
2390 : : just by 0.5ulp rather than 1ulp. */
2391 : 184481 : REAL_VALUE_TYPE tem;
2392 : 184481 : real_arithmetic (&tem, PLUS_EXPR, &lhs.lower_bound (), &lb);
2393 : 184481 : real_arithmetic (&lb, RDIV_EXPR, &tem, &dconst2);
2394 : : }
2395 : : }
2396 : 325321 : if (real_isfinite (&ub))
2397 : : {
2398 : 117252 : frange_nextafter (TYPE_MODE (type), ub, dconstinf);
2399 : 117252 : if (real_isinf (&ub))
2400 : : {
2401 : : /* For DBL_MAX similarly. */
2402 : 26844 : ub = dconst1;
2403 : 107376 : SET_REAL_EXP (&ub, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
2404 : : }
2405 : 820692 : if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)))
2406 : : {
2407 : : /* If not -frounding-math nor IBM double double, actually widen
2408 : : just by 0.5ulp rather than 1ulp. */
2409 : 117240 : REAL_VALUE_TYPE tem;
2410 : 117240 : real_arithmetic (&tem, PLUS_EXPR, &lhs.upper_bound (), &ub);
2411 : 117240 : real_arithmetic (&ub, RDIV_EXPR, &tem, &dconst2);
2412 : : }
2413 : : }
2414 : : /* Temporarily disable -ffinite-math-only, so that frange::set doesn't
2415 : : reduce the range back to real_min_representable (type) as lower bound
2416 : : or real_max_representable (type) as upper bound. */
2417 : 325321 : bool save_flag_finite_math_only = flag_finite_math_only;
2418 : 325321 : flag_finite_math_only = false;
2419 : 325321 : ret.set (type, lb, ub, lhs.get_nan_state ());
2420 : 325321 : flag_finite_math_only = save_flag_finite_math_only;
2421 : 325321 : return ret;
2422 : : }
2423 : :
2424 : : bool
2425 : 97519 : operator_plus::op1_range (frange &r, tree type, const frange &lhs,
2426 : : const frange &op2, relation_trio) const
2427 : : {
2428 : 97519 : if (lhs.undefined_p ())
2429 : : return false;
2430 : 97519 : range_op_handler minus (MINUS_EXPR);
2431 : 97519 : if (!minus)
2432 : : return false;
2433 : 97519 : frange wlhs = float_widen_lhs_range (type, lhs);
2434 : 97519 : return float_binary_op_range_finish (minus.fold_range (r, type, wlhs, op2),
2435 : : r, type, wlhs);
2436 : 97519 : }
2437 : :
2438 : : bool
2439 : 53730 : operator_plus::op2_range (frange &r, tree type,
2440 : : const frange &lhs, const frange &op1,
2441 : : relation_trio) const
2442 : : {
2443 : 53730 : return op1_range (r, type, lhs, op1);
2444 : : }
2445 : :
2446 : : void
2447 : 2304049 : operator_plus::rv_fold (frange &r, tree type,
2448 : : const REAL_VALUE_TYPE &lh_lb,
2449 : : const REAL_VALUE_TYPE &lh_ub,
2450 : : const REAL_VALUE_TYPE &rh_lb,
2451 : : const REAL_VALUE_TYPE &rh_ub,
2452 : : relation_kind) const
2453 : : {
2454 : 2304049 : REAL_VALUE_TYPE lb, ub;
2455 : 2304049 : bool maybe_nan = false;
2456 : :
2457 : 2304049 : frange_arithmetic (PLUS_EXPR, type, lb, lh_lb, rh_lb, dconstninf);
2458 : 2304049 : frange_arithmetic (PLUS_EXPR, type, ub, lh_ub, rh_ub, dconstinf);
2459 : :
2460 : : // [-INF] + [+INF] = NAN
2461 : 2304049 : if (real_isinf (&lh_lb, true) && real_isinf (&rh_ub, false))
2462 : : maybe_nan = true;
2463 : : // [+INF] + [-INF] = NAN
2464 : 424465 : else if (real_isinf (&lh_ub, false) && real_isinf (&rh_lb, true))
2465 : : maybe_nan = true;
2466 : :
2467 : : // Handle possible NANs by saturating to the appropriate INF if only
2468 : : // one end is a NAN. If both ends are a NAN, just return a NAN.
2469 : 2304049 : bool lb_nan = real_isnan (&lb);
2470 : 2304049 : bool ub_nan = real_isnan (&ub);
2471 : 2304049 : if (lb_nan && ub_nan)
2472 : : {
2473 : 0 : r.set_nan (type);
2474 : 0 : return;
2475 : : }
2476 : 2304049 : if (lb_nan)
2477 : 306 : lb = dconstninf;
2478 : 2303743 : else if (ub_nan)
2479 : 0 : ub = dconstinf;
2480 : 2304049 : r.set (type, lb, ub, nan_state (maybe_nan));
2481 : : }
2482 : :
2483 : :
2484 : : bool
2485 : 56328 : operator_minus::op1_range (frange &r, tree type,
2486 : : const frange &lhs, const frange &op2,
2487 : : relation_trio) const
2488 : : {
2489 : 56328 : if (lhs.undefined_p ())
2490 : : return false;
2491 : 56328 : frange wlhs = float_widen_lhs_range (type, lhs);
2492 : 56328 : return float_binary_op_range_finish (
2493 : 112656 : range_op_handler (PLUS_EXPR).fold_range (r, type, wlhs, op2),
2494 : : r, type, wlhs);
2495 : 56328 : }
2496 : :
2497 : : bool
2498 : 30820 : operator_minus::op2_range (frange &r, tree type,
2499 : : const frange &lhs, const frange &op1,
2500 : : relation_trio) const
2501 : : {
2502 : 30820 : if (lhs.undefined_p ())
2503 : : return false;
2504 : 30820 : frange wlhs = float_widen_lhs_range (type, lhs);
2505 : 30820 : return float_binary_op_range_finish (fold_range (r, type, op1, wlhs),
2506 : : r, type, wlhs);
2507 : 30820 : }
2508 : :
2509 : : void
2510 : 641538 : operator_minus::rv_fold (frange &r, tree type,
2511 : : const REAL_VALUE_TYPE &lh_lb,
2512 : : const REAL_VALUE_TYPE &lh_ub,
2513 : : const REAL_VALUE_TYPE &rh_lb,
2514 : : const REAL_VALUE_TYPE &rh_ub,
2515 : : relation_kind) const
2516 : : {
2517 : 641538 : REAL_VALUE_TYPE lb, ub;
2518 : 641538 : bool maybe_nan = false;
2519 : :
2520 : 641538 : frange_arithmetic (MINUS_EXPR, type, lb, lh_lb, rh_ub, dconstninf);
2521 : 641538 : frange_arithmetic (MINUS_EXPR, type, ub, lh_ub, rh_lb, dconstinf);
2522 : :
2523 : : // [+INF] - [+INF] = NAN
2524 : 641538 : if (real_isinf (&lh_ub, false) && real_isinf (&rh_ub, false))
2525 : : maybe_nan = true;
2526 : : // [-INF] - [-INF] = NAN
2527 : 294378 : else if (real_isinf (&lh_lb, true) && real_isinf (&rh_lb, true))
2528 : : maybe_nan = true;
2529 : :
2530 : : // Handle possible NANs by saturating to the appropriate INF if only
2531 : : // one end is a NAN. If both ends are a NAN, just return a NAN.
2532 : 641538 : bool lb_nan = real_isnan (&lb);
2533 : 641538 : bool ub_nan = real_isnan (&ub);
2534 : 641538 : if (lb_nan && ub_nan)
2535 : : {
2536 : 0 : r.set_nan (type);
2537 : 0 : return;
2538 : : }
2539 : 641538 : if (lb_nan)
2540 : 174 : lb = dconstninf;
2541 : 641364 : else if (ub_nan)
2542 : 239 : ub = dconstinf;
2543 : 641538 : r.set (type, lb, ub, nan_state (maybe_nan));
2544 : : }
2545 : :
2546 : :
2547 : : // Given CP[0] to CP[3] floating point values rounded to -INF,
2548 : : // set LB to the smallest of them (treating -0 as smaller to +0).
2549 : : // Given CP[4] to CP[7] floating point values rounded to +INF,
2550 : : // set UB to the largest of them (treating -0 as smaller to +0).
2551 : :
2552 : : static void
2553 : 665252 : find_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
2554 : : const REAL_VALUE_TYPE (&cp)[8])
2555 : : {
2556 : 665252 : lb = cp[0];
2557 : 665252 : ub = cp[4];
2558 : 2661008 : for (int i = 1; i < 4; ++i)
2559 : : {
2560 : 1995756 : if (real_less (&cp[i], &lb)
2561 : 1995756 : || (real_iszero (&lb) && real_isnegzero (&cp[i])))
2562 : 223173 : lb = cp[i];
2563 : 1995756 : if (real_less (&ub, &cp[i + 4])
2564 : 1995756 : || (real_isnegzero (&ub) && real_iszero (&cp[i + 4])))
2565 : 544186 : ub = cp[i + 4];
2566 : : }
2567 : 665252 : }
2568 : :
2569 : :
2570 : : bool
2571 : 98657 : operator_mult::op1_range (frange &r, tree type,
2572 : : const frange &lhs, const frange &op2,
2573 : : relation_trio) const
2574 : : {
2575 : 98657 : if (lhs.undefined_p ())
2576 : : return false;
2577 : 98657 : range_op_handler rdiv (RDIV_EXPR);
2578 : 98657 : if (!rdiv)
2579 : : return false;
2580 : 98657 : frange wlhs = float_widen_lhs_range (type, lhs);
2581 : 98657 : bool ret = rdiv.fold_range (r, type, wlhs, op2);
2582 : 98657 : if (ret == false)
2583 : : return false;
2584 : 98657 : if (wlhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
2585 : 16 : return float_binary_op_range_finish (ret, r, type, wlhs);
2586 : 98641 : const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
2587 : 98641 : const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
2588 : 98641 : const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
2589 : 98641 : const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
2590 : 180753 : if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op2_lb, op2_ub))
2591 : 121415 : || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
2592 : 30474 : && (real_isinf (&op2_lb) || real_isinf (&op2_ub))))
2593 : : {
2594 : : // If both lhs and op2 could be zeros or both could be infinities,
2595 : : // we don't know anything about op1 except maybe for the sign
2596 : : // and perhaps if it can be NAN or not.
2597 : 64493 : REAL_VALUE_TYPE lb, ub;
2598 : 64493 : int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
2599 : 64493 : zero_to_inf_range (lb, ub, signbit_known);
2600 : 64493 : r.set (type, lb, ub);
2601 : : }
2602 : : // Otherwise, if op2 is a singleton INF and lhs doesn't include INF,
2603 : : // or if lhs must be zero and op2 doesn't include zero, it would be
2604 : : // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF
2605 : : // range. Those are supersets of UNDEFINED, so let's keep that way.
2606 : 98641 : return float_binary_op_range_finish (ret, r, type, wlhs);
2607 : 98657 : }
2608 : :
2609 : : bool
2610 : 28685 : operator_mult::op2_range (frange &r, tree type,
2611 : : const frange &lhs, const frange &op1,
2612 : : relation_trio) const
2613 : : {
2614 : 28685 : return op1_range (r, type, lhs, op1);
2615 : : }
2616 : :
2617 : : void
2618 : 936492 : operator_mult::rv_fold (frange &r, tree type,
2619 : : const REAL_VALUE_TYPE &lh_lb,
2620 : : const REAL_VALUE_TYPE &lh_ub,
2621 : : const REAL_VALUE_TYPE &rh_lb,
2622 : : const REAL_VALUE_TYPE &rh_ub,
2623 : : relation_kind kind) const
2624 : : {
2625 : 936492 : bool is_square
2626 : : = (kind == VREL_EQ
2627 : 35009 : && real_equal (&lh_lb, &rh_lb)
2628 : 35009 : && real_equal (&lh_ub, &rh_ub)
2629 : 35009 : && real_isneg (&lh_lb) == real_isneg (&rh_lb)
2630 : 971501 : && real_isneg (&lh_ub) == real_isneg (&rh_ub));
2631 : 901483 : REAL_VALUE_TYPE lb, ub;
2632 : 1413563 : bool maybe_nan = false;
2633 : : // x * x never produces a new NAN and we only multiply the same
2634 : : // values, so the 0 * INF problematic cases never appear there.
2635 : 901483 : if (!is_square)
2636 : : {
2637 : : // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN.
2638 : 902265 : if ((zero_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub))
2639 : 902259 : || (zero_p (rh_lb, rh_ub) && singleton_inf_p (lh_lb, lh_ub)))
2640 : : {
2641 : 37 : r.set_nan (type);
2642 : 424412 : return;
2643 : : }
2644 : :
2645 : : // Otherwise, if one range includes zero and the other ends with +-INF,
2646 : : // it is a maybe NAN.
2647 : 901446 : if ((contains_zero_p (lh_lb, lh_ub)
2648 : 862139 : && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
2649 : 1358163 : || (contains_zero_p (rh_lb, rh_ub)
2650 : 116691 : && (real_isinf (&lh_lb) || real_isinf (&lh_ub))))
2651 : : {
2652 : 424375 : maybe_nan = true;
2653 : :
2654 : 424375 : int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
2655 : :
2656 : : // If one of the ranges that includes INF is singleton
2657 : : // and the other range includes zero, the resulting
2658 : : // range is INF and NAN, because the 0 * INF boundary
2659 : : // case will be NAN, but already nextafter (0, 1) * INF
2660 : : // is INF.
2661 : 424375 : if (singleton_inf_p (lh_lb, lh_ub)
2662 : 424375 : || singleton_inf_p (rh_lb, rh_ub))
2663 : : {
2664 : 937 : inf_range (lb, ub, signbit_known);
2665 : 937 : r.set (type, lb, ub, nan_state (true));
2666 : 937 : return;
2667 : : }
2668 : :
2669 : : // If one of the multiplicands must be zero, the resulting
2670 : : // range is +-0 and NAN.
2671 : 423438 : if (zero_p (lh_lb, lh_ub) || zero_p (rh_lb, rh_ub))
2672 : : {
2673 : 5450 : zero_range (lb, ub, signbit_known);
2674 : 5450 : r.set (type, lb, ub, nan_state (true));
2675 : 5450 : return;
2676 : : }
2677 : :
2678 : : // Otherwise one of the multiplicands could be
2679 : : // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF]
2680 : : // or similarly with different signs. 0.0 * DBL_MAX
2681 : : // is still 0.0, nextafter (0.0, 1.0) * INF is still INF,
2682 : : // so if the signs are always the same or always different,
2683 : : // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING.
2684 : 417988 : zero_to_inf_range (lb, ub, signbit_known);
2685 : 417988 : r.set (type, lb, ub, nan_state (true));
2686 : 417988 : return;
2687 : : }
2688 : : }
2689 : :
2690 : 512080 : REAL_VALUE_TYPE cp[8];
2691 : : // Do a cross-product. At this point none of the multiplications
2692 : : // should produce a NAN.
2693 : 512080 : frange_arithmetic (MULT_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
2694 : 512080 : frange_arithmetic (MULT_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
2695 : 512080 : if (is_square)
2696 : : {
2697 : : // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub)
2698 : : // as maximum and -0.0 as minimum if 0.0 is in the range,
2699 : : // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub).
2700 : : // -0.0 rather than 0.0 because VREL_EQ doesn't prove that
2701 : : // x and y are bitwise equal, just that they compare equal.
2702 : 35009 : if (contains_zero_p (lh_lb, lh_ub))
2703 : : {
2704 : 33261 : if (real_isneg (&lh_lb) == real_isneg (&lh_ub))
2705 : 817 : cp[1] = dconst0;
2706 : : else
2707 : 32444 : cp[1] = dconstm0;
2708 : : }
2709 : : else
2710 : 1748 : cp[1] = cp[0];
2711 : 35009 : cp[2] = cp[0];
2712 : 35009 : cp[5] = cp[4];
2713 : 35009 : cp[6] = cp[4];
2714 : : }
2715 : : else
2716 : : {
2717 : 477071 : frange_arithmetic (MULT_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
2718 : 477071 : frange_arithmetic (MULT_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
2719 : 477071 : frange_arithmetic (MULT_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
2720 : 477071 : frange_arithmetic (MULT_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
2721 : : }
2722 : 512080 : frange_arithmetic (MULT_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
2723 : 512080 : frange_arithmetic (MULT_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);
2724 : :
2725 : 512080 : find_range (lb, ub, cp);
2726 : :
2727 : 512080 : gcc_checking_assert (!real_isnan (&lb));
2728 : 512080 : gcc_checking_assert (!real_isnan (&ub));
2729 : 512080 : r.set (type, lb, ub, nan_state (maybe_nan));
2730 : : }
2731 : :
2732 : :
2733 : : class foperator_div : public range_operator
2734 : : {
2735 : : using range_operator::op1_range;
2736 : : using range_operator::op2_range;
2737 : : public:
2738 : 19928 : virtual bool op1_range (frange &r, tree type,
2739 : : const frange &lhs,
2740 : : const frange &op2,
2741 : : relation_trio = TRIO_VARYING) const final override
2742 : : {
2743 : 19928 : if (lhs.undefined_p ())
2744 : : return false;
2745 : 19928 : frange wlhs = float_widen_lhs_range (type, lhs);
2746 : 19928 : bool ret = range_op_handler (MULT_EXPR).fold_range (r, type, wlhs, op2);
2747 : 19928 : if (!ret)
2748 : : return ret;
2749 : 19928 : if (wlhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
2750 : 4 : return float_binary_op_range_finish (ret, r, type, wlhs);
2751 : 19924 : const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
2752 : 19924 : const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
2753 : 19924 : const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
2754 : 19924 : const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
2755 : 19924 : if ((contains_zero_p (lhs_lb, lhs_ub)
2756 : 12755 : && (real_isinf (&op2_lb) || real_isinf (&op2_ub)))
2757 : 22797 : || ((contains_zero_p (op2_lb, op2_ub))
2758 : 6467 : && (real_isinf (&lhs_lb) || real_isinf (&lhs_ub))))
2759 : : {
2760 : : // If both lhs could be zero and op2 infinity or vice versa,
2761 : : // we don't know anything about op1 except maybe for the sign
2762 : : // and perhaps if it can be NAN or not.
2763 : 16092 : REAL_VALUE_TYPE lb, ub;
2764 : 16092 : int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
2765 : 16092 : zero_to_inf_range (lb, ub, signbit_known);
2766 : 16092 : r.set (type, lb, ub);
2767 : : }
2768 : 19924 : return float_binary_op_range_finish (ret, r, type, wlhs);
2769 : 19928 : }
2770 : 26198 : virtual bool op2_range (frange &r, tree type,
2771 : : const frange &lhs,
2772 : : const frange &op1,
2773 : : relation_trio = TRIO_VARYING) const final override
2774 : : {
2775 : 26198 : if (lhs.undefined_p ())
2776 : : return false;
2777 : 26198 : frange wlhs = float_widen_lhs_range (type, lhs);
2778 : 26198 : bool ret = fold_range (r, type, op1, wlhs);
2779 : 26198 : if (!ret)
2780 : : return ret;
2781 : 26198 : if (wlhs.known_isnan () || op1.known_isnan () || op1.undefined_p ())
2782 : 20 : return float_binary_op_range_finish (ret, r, type, wlhs, true);
2783 : 26178 : const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
2784 : 26178 : const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
2785 : 26178 : const REAL_VALUE_TYPE &op1_lb = op1.lower_bound ();
2786 : 26178 : const REAL_VALUE_TYPE &op1_ub = op1.upper_bound ();
2787 : 43424 : if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op1_lb, op1_ub))
2788 : 28171 : || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
2789 : 7863 : && (real_isinf (&op1_lb) || real_isinf (&op1_ub))))
2790 : : {
2791 : : // If both lhs and op1 could be zeros or both could be infinities,
2792 : : // we don't know anything about op2 except maybe for the sign
2793 : : // and perhaps if it can be NAN or not.
2794 : 20607 : REAL_VALUE_TYPE lb, ub;
2795 : 20607 : int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op1_lb, op1_ub);
2796 : 20607 : zero_to_inf_range (lb, ub, signbit_known);
2797 : 20607 : r.set (type, lb, ub);
2798 : : }
2799 : 26178 : return float_binary_op_range_finish (ret, r, type, wlhs, true);
2800 : 26198 : }
2801 : : private:
2802 : 390067 : void rv_fold (frange &r, tree type,
2803 : : const REAL_VALUE_TYPE &lh_lb,
2804 : : const REAL_VALUE_TYPE &lh_ub,
2805 : : const REAL_VALUE_TYPE &rh_lb,
2806 : : const REAL_VALUE_TYPE &rh_ub,
2807 : : relation_kind) const final override
2808 : : {
2809 : : // +-0.0 / +-0.0 or +-INF / +-INF is a known NAN.
2810 : 391145 : if ((zero_p (lh_lb, lh_ub) && zero_p (rh_lb, rh_ub))
2811 : 390572 : || (singleton_inf_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub)))
2812 : : {
2813 : 579 : r.set_nan (type);
2814 : 236895 : return;
2815 : : }
2816 : :
2817 : 389488 : REAL_VALUE_TYPE lb, ub;
2818 : 389488 : bool maybe_nan = false;
2819 : : // If +-0.0 is in both ranges, it is a maybe NAN.
2820 : 389488 : if (contains_zero_p (lh_lb, lh_ub) && contains_zero_p (rh_lb, rh_ub))
2821 : : maybe_nan = true;
2822 : : // If +-INF is in both ranges, it is a maybe NAN.
2823 : 281550 : else if ((real_isinf (&lh_lb) || real_isinf (&lh_ub))
2824 : 189080 : && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
2825 : : maybe_nan = true;
2826 : :
2827 : 389488 : int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
2828 : :
2829 : : // If dividend must be zero, the range is just +-0
2830 : : // (including if the divisor is +-INF).
2831 : : // If divisor must be +-INF, the range is just +-0
2832 : : // (including if the dividend is zero).
2833 : 389488 : if (zero_p (lh_lb, lh_ub) || singleton_inf_p (rh_lb, rh_ub))
2834 : : {
2835 : 506 : zero_range (lb, ub, signbit_known);
2836 : 506 : r.set (type, lb, ub, nan_state (maybe_nan));
2837 : 506 : return;
2838 : : }
2839 : :
2840 : : // If divisor must be zero, the range is just +-INF
2841 : : // (including if the dividend is +-INF).
2842 : : // If dividend must be +-INF, the range is just +-INF
2843 : : // (including if the dividend is zero).
2844 : 388982 : if (zero_p (rh_lb, rh_ub) || singleton_inf_p (lh_lb, lh_ub))
2845 : : {
2846 : 2243 : inf_range (lb, ub, signbit_known);
2847 : 2243 : r.set (type, lb, ub, nan_state (maybe_nan));
2848 : 2243 : return;
2849 : : }
2850 : :
2851 : : // Otherwise if both operands may be zero, divisor could be
2852 : : // nextafter(0.0, +-1.0) and dividend +-0.0
2853 : : // in which case result is going to INF or vice versa and
2854 : : // result +0.0. So, all we can say for that case is if the
2855 : : // signs of divisor and dividend are always the same we have
2856 : : // [+0.0, +INF], if they are always different we have
2857 : : // [-INF, -0.0]. If they vary, VARYING.
2858 : : // If both may be +-INF, divisor could be INF and dividend FLT_MAX,
2859 : : // in which case result is going to INF or vice versa and
2860 : : // result +0.0. So, all we can say for that case is if the
2861 : : // signs of divisor and dividend are always the same we have
2862 : : // [+0.0, +INF], if they are always different we have
2863 : : // [-INF, -0.0]. If they vary, VARYING.
2864 : 386739 : if (maybe_nan)
2865 : : {
2866 : 233567 : zero_to_inf_range (lb, ub, signbit_known);
2867 : 233567 : r.set (type, lb, ub, nan_state (maybe_nan));
2868 : 233567 : return;
2869 : : }
2870 : :
2871 : 153172 : REAL_VALUE_TYPE cp[8];
2872 : : // Do a cross-division. At this point none of the divisions should
2873 : : // produce a NAN.
2874 : 153172 : frange_arithmetic (RDIV_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
2875 : 153172 : frange_arithmetic (RDIV_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
2876 : 153172 : frange_arithmetic (RDIV_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
2877 : 153172 : frange_arithmetic (RDIV_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
2878 : 153172 : frange_arithmetic (RDIV_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
2879 : 153172 : frange_arithmetic (RDIV_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
2880 : 153172 : frange_arithmetic (RDIV_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
2881 : 153172 : frange_arithmetic (RDIV_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);
2882 : :
2883 : 153172 : find_range (lb, ub, cp);
2884 : :
2885 : : // If divisor may be zero (but is not known to be only zero),
2886 : : // and dividend can't be zero, the range can go up to -INF or +INF
2887 : : // depending on the signs.
2888 : 153172 : if (contains_zero_p (rh_lb, rh_ub))
2889 : : {
2890 : 73926 : if (signbit_known <= 0)
2891 : 73665 : real_inf (&lb, true);
2892 : 73665 : if (signbit_known >= 0)
2893 : 73899 : real_inf (&ub, false);
2894 : : }
2895 : :
2896 : 153172 : gcc_checking_assert (!real_isnan (&lb));
2897 : 153172 : gcc_checking_assert (!real_isnan (&ub));
2898 : 153172 : r.set (type, lb, ub, nan_state (maybe_nan));
2899 : : }
2900 : : } fop_div;
2901 : :
2902 : :
2903 : : // Initialize any float operators to the primary table
2904 : :
2905 : : void
2906 : 282096 : range_op_table::initialize_float_ops ()
2907 : : {
2908 : 282096 : set (UNLE_EXPR, fop_unordered_le);
2909 : 282096 : set (UNLT_EXPR, fop_unordered_lt);
2910 : 282096 : set (UNGE_EXPR, fop_unordered_ge);
2911 : 282096 : set (UNGT_EXPR, fop_unordered_gt);
2912 : 282096 : set (UNEQ_EXPR, fop_unordered_equal);
2913 : 282096 : set (ORDERED_EXPR, fop_ordered);
2914 : 282096 : set (UNORDERED_EXPR, fop_unordered);
2915 : 282096 : set (LTGT_EXPR, fop_ltgt);
2916 : 282096 : set (RDIV_EXPR, fop_div);
2917 : 282096 : }
2918 : :
2919 : : #if CHECKING_P
2920 : : #include "selftest.h"
2921 : :
2922 : : namespace selftest
2923 : : {
2924 : :
2925 : : // Build an frange from string endpoints.
2926 : :
2927 : : static inline frange
2928 : 16 : frange_float (const char *lb, const char *ub, tree type = float_type_node)
2929 : : {
2930 : 16 : REAL_VALUE_TYPE min, max;
2931 : 16 : gcc_assert (real_from_string (&min, lb) == 0);
2932 : 16 : gcc_assert (real_from_string (&max, ub) == 0);
2933 : 16 : return frange (type, min, max);
2934 : : }
2935 : :
2936 : : void
2937 : 4 : range_op_float_tests ()
2938 : : {
2939 : 4 : frange r, r0, r1;
2940 : 4 : frange trange (float_type_node);
2941 : :
2942 : : // negate([-5, +10]) => [-10, 5]
2943 : 4 : r0 = frange_float ("-5", "10");
2944 : 4 : range_op_handler (NEGATE_EXPR).fold_range (r, float_type_node, r0, trange);
2945 : 4 : ASSERT_EQ (r, frange_float ("-10", "5"));
2946 : :
2947 : : // negate([0, 1] -NAN) => [-1, -0] +NAN
2948 : 4 : r0 = frange_float ("0", "1");
2949 : 4 : r0.update_nan (true);
2950 : 4 : range_op_handler (NEGATE_EXPR).fold_range (r, float_type_node, r0, trange);
2951 : 4 : r1 = frange_float ("-1", "-0");
2952 : 4 : r1.update_nan (false);
2953 : 4 : ASSERT_EQ (r, r1);
2954 : :
2955 : : // [-INF,+INF] + [-INF,+INF] could be a NAN.
2956 : 4 : range_op_handler plus (PLUS_EXPR);
2957 : 4 : r0.set_varying (float_type_node);
2958 : 4 : r1.set_varying (float_type_node);
2959 : 4 : r0.clear_nan ();
2960 : 4 : r1.clear_nan ();
2961 : 4 : plus.fold_range (r, float_type_node, r0, r1);
2962 : 4 : if (HONOR_NANS (float_type_node))
2963 : 8 : ASSERT_TRUE (r.maybe_isnan ());
2964 : 4 : }
2965 : :
2966 : : } // namespace selftest
2967 : :
2968 : : #endif // CHECKING_P
|