gcc:
[official-gcc.git] / gcc / wide-int-range.cc
blob3cdcede04cdaf588c3604d53f4f22144f595f664
1 /* Support routines for range operations on wide ints.
2 Copyright (C) 2018 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tree.h"
24 #include "function.h"
25 #include "fold-const.h"
26 #include "wide-int-range.h"
28 /* Wrapper around wide_int_binop that adjusts for overflow.
30 Return true if we can compute the result; i.e. if the operation
31 doesn't overflow or if the overflow is undefined. In the latter
32 case (if the operation overflows and overflow is undefined), then
33 adjust the result to be -INF or +INF depending on CODE, VAL1 and
34 VAL2. Return the value in *RES.
36 Return false for division by zero, for which the result is
37 indeterminate. */
39 static bool
40 wide_int_binop_overflow (wide_int &res,
41 enum tree_code code,
42 const wide_int &w0, const wide_int &w1,
43 signop sign, bool overflow_undefined)
45 wi::overflow_type overflow;
46 if (!wide_int_binop (res, code, w0, w1, sign, &overflow))
47 return false;
49 /* If the operation overflowed return -INF or +INF depending on the
50 operation and the combination of signs of the operands. */
51 if (overflow && overflow_undefined)
53 switch (code)
55 case MULT_EXPR:
56 /* For multiplication, the sign of the overflow is given
57 by the comparison of the signs of the operands. */
58 if (sign == UNSIGNED || w0.sign_mask () == w1.sign_mask ())
59 res = wi::max_value (w0.get_precision (), sign);
60 else
61 res = wi::min_value (w0.get_precision (), sign);
62 return true;
64 case TRUNC_DIV_EXPR:
65 case FLOOR_DIV_EXPR:
66 case CEIL_DIV_EXPR:
67 case EXACT_DIV_EXPR:
68 case ROUND_DIV_EXPR:
69 /* For division, the only case is -INF / -1 = +INF. */
70 res = wi::max_value (w0.get_precision (), sign);
71 return true;
73 default:
74 gcc_unreachable ();
77 return !overflow;
80 /* For range [LB, UB] compute two wide_int bit masks.
82 In the MAY_BE_NONZERO bit mask, if some bit is unset, it means that
83 for all numbers in the range the bit is 0, otherwise it might be 0
84 or 1.
86 In the MUST_BE_NONZERO bit mask, if some bit is set, it means that
87 for all numbers in the range the bit is 1, otherwise it might be 0
88 or 1. */
90 void
91 wide_int_range_set_zero_nonzero_bits (signop sign,
92 const wide_int &lb, const wide_int &ub,
93 wide_int &may_be_nonzero,
94 wide_int &must_be_nonzero)
96 may_be_nonzero = wi::minus_one (lb.get_precision ());
97 must_be_nonzero = wi::zero (lb.get_precision ());
99 if (wi::eq_p (lb, ub))
101 may_be_nonzero = lb;
102 must_be_nonzero = may_be_nonzero;
104 else if (wi::ge_p (lb, 0, sign) || wi::lt_p (ub, 0, sign))
106 wide_int xor_mask = lb ^ ub;
107 may_be_nonzero = lb | ub;
108 must_be_nonzero = lb & ub;
109 if (xor_mask != 0)
111 wide_int mask = wi::mask (wi::floor_log2 (xor_mask), false,
112 may_be_nonzero.get_precision ());
113 may_be_nonzero = may_be_nonzero | mask;
114 must_be_nonzero = wi::bit_and_not (must_be_nonzero, mask);
119 /* Order 2 sets of wide int ranges (w0/w1, w2/w3) and set MIN/MAX
120 accordingly. */
122 static void
123 wide_int_range_order_set (wide_int &min, wide_int &max,
124 wide_int &w0, wide_int &w1,
125 wide_int &w2, wide_int &w3,
126 signop sign)
128 /* Order pairs w0,w1 and w2,w3. */
129 if (wi::gt_p (w0, w1, sign))
130 std::swap (w0, w1);
131 if (wi::gt_p (w2, w3, sign))
132 std::swap (w2, w3);
134 /* Choose min and max from the ordered pairs. */
135 min = wi::min (w0, w2, sign);
136 max = wi::max (w1, w3, sign);
139 /* Calculate the cross product of two sets of ranges (VR0 and VR1) and
140 store the result in [RES_LB, RES_UB].
142 CODE is the operation to perform with sign SIGN.
144 OVERFLOW_UNDEFINED is set if overflow is undefined for the operation type.
146 Return TRUE if we were able to calculate the cross product. */
148 bool
149 wide_int_range_cross_product (wide_int &res_lb, wide_int &res_ub,
150 enum tree_code code, signop sign,
151 const wide_int &vr0_lb, const wide_int &vr0_ub,
152 const wide_int &vr1_lb, const wide_int &vr1_ub,
153 bool overflow_undefined)
155 wide_int cp1, cp2, cp3, cp4;
157 /* Compute the 4 cross operations, bailing if we get an overflow we
158 can't handle. */
160 if (!wide_int_binop_overflow (cp1, code, vr0_lb, vr1_lb, sign,
161 overflow_undefined))
162 return false;
164 if (wi::eq_p (vr0_lb, vr0_ub))
165 cp3 = cp1;
166 else if (!wide_int_binop_overflow (cp3, code, vr0_ub, vr1_lb, sign,
167 overflow_undefined))
168 return false;
170 if (wi::eq_p (vr1_lb, vr1_ub))
171 cp2 = cp1;
172 else if (!wide_int_binop_overflow (cp2, code, vr0_lb, vr1_ub, sign,
173 overflow_undefined))
174 return false;
176 if (wi::eq_p (vr0_lb, vr0_ub))
177 cp4 = cp2;
178 else if (!wide_int_binop_overflow (cp4, code, vr0_ub, vr1_ub, sign,
179 overflow_undefined))
180 return false;
182 wide_int_range_order_set (res_lb, res_ub, cp1, cp2, cp3, cp4, sign);
183 return true;
186 /* Multiply two ranges when TYPE_OVERFLOW_WRAPS:
188 [RES_LB, RES_UB] = [MIN0, MAX0] * [MIN1, MAX1]
190 This is basically fancy code so we don't drop to varying with an
191 unsigned [-3,-1]*[-3,-1].
193 Return TRUE if we were able to perform the operation. */
195 bool
196 wide_int_range_mult_wrapping (wide_int &res_lb,
197 wide_int &res_ub,
198 signop sign,
199 unsigned prec,
200 const wide_int &min0_,
201 const wide_int &max0_,
202 const wide_int &min1_,
203 const wide_int &max1_)
205 /* This test requires 2*prec bits if both operands are signed and
206 2*prec + 2 bits if either is not. Therefore, extend the values
207 using the sign of the result to PREC2. From here on out,
208 everthing is just signed math no matter what the input types
209 were. */
210 widest2_int min0 = widest2_int::from (min0_, sign);
211 widest2_int max0 = widest2_int::from (max0_, sign);
212 widest2_int min1 = widest2_int::from (min1_, sign);
213 widest2_int max1 = widest2_int::from (max1_, sign);
214 widest2_int sizem1 = wi::mask <widest2_int> (prec, false);
215 widest2_int size = sizem1 + 1;
217 /* Canonicalize the intervals. */
218 if (sign == UNSIGNED)
220 if (wi::ltu_p (size, min0 + max0))
222 min0 -= size;
223 max0 -= size;
226 if (wi::ltu_p (size, min1 + max1))
228 min1 -= size;
229 max1 -= size;
233 widest2_int prod0 = min0 * min1;
234 widest2_int prod1 = min0 * max1;
235 widest2_int prod2 = max0 * min1;
236 widest2_int prod3 = max0 * max1;
238 /* Sort the 4 products so that min is in prod0 and max is in
239 prod3. */
240 /* min0min1 > max0max1 */
241 if (prod0 > prod3)
242 std::swap (prod0, prod3);
244 /* min0max1 > max0min1 */
245 if (prod1 > prod2)
246 std::swap (prod1, prod2);
248 if (prod0 > prod1)
249 std::swap (prod0, prod1);
251 if (prod2 > prod3)
252 std::swap (prod2, prod3);
254 /* diff = max - min. */
255 prod2 = prod3 - prod0;
256 if (wi::geu_p (prod2, sizem1))
257 /* The range covers all values. */
258 return false;
260 res_lb = wide_int::from (prod0, prec, sign);
261 res_ub = wide_int::from (prod3, prec, sign);
262 return true;
265 /* Perform multiplicative operation CODE on two ranges:
267 [RES_LB, RES_UB] = [VR0_LB, VR0_UB] .CODE. [VR1_LB, VR1_LB]
269 Return TRUE if we were able to perform the operation.
271 NOTE: If code is MULT_EXPR and TYPE_OVERFLOW_WRAPS, the resulting
272 range must be canonicalized by the caller because its components
273 may be swapped. */
275 bool
276 wide_int_range_multiplicative_op (wide_int &res_lb, wide_int &res_ub,
277 enum tree_code code,
278 signop sign,
279 unsigned prec,
280 const wide_int &vr0_lb,
281 const wide_int &vr0_ub,
282 const wide_int &vr1_lb,
283 const wide_int &vr1_ub,
284 bool overflow_undefined,
285 bool overflow_wraps)
287 /* Multiplications, divisions and shifts are a bit tricky to handle,
288 depending on the mix of signs we have in the two ranges, we
289 need to operate on different values to get the minimum and
290 maximum values for the new range. One approach is to figure
291 out all the variations of range combinations and do the
292 operations.
294 However, this involves several calls to compare_values and it
295 is pretty convoluted. It's simpler to do the 4 operations
296 (MIN0 OP MIN1, MIN0 OP MAX1, MAX0 OP MIN1 and MAX0 OP MAX0 OP
297 MAX1) and then figure the smallest and largest values to form
298 the new range. */
299 if (code == MULT_EXPR && overflow_wraps)
300 return wide_int_range_mult_wrapping (res_lb, res_ub,
301 sign, prec,
302 vr0_lb, vr0_ub, vr1_lb, vr1_ub);
303 return wide_int_range_cross_product (res_lb, res_ub,
304 code, sign,
305 vr0_lb, vr0_ub, vr1_lb, vr1_ub,
306 overflow_undefined);
309 /* Perform a left shift operation on two ranges:
311 [RES_LB, RES_UB] = [VR0_LB, VR0_UB] << [VR1_LB, VR1_LB]
313 Return TRUE if we were able to perform the operation.
315 NOTE: The resulting range must be canonicalized by the caller
316 because its contents components may be swapped. */
318 bool
319 wide_int_range_lshift (wide_int &res_lb, wide_int &res_ub,
320 signop sign, unsigned prec,
321 const wide_int &vr0_lb, const wide_int &vr0_ub,
322 const wide_int &vr1_lb, const wide_int &vr1_ub,
323 bool overflow_undefined, bool overflow_wraps)
325 /* Transform left shifts by constants into multiplies. */
326 if (wi::eq_p (vr1_lb, vr1_ub))
328 unsigned shift = vr1_ub.to_uhwi ();
329 wide_int tmp = wi::set_bit_in_zero (shift, prec);
330 return wide_int_range_multiplicative_op (res_lb, res_ub,
331 MULT_EXPR, sign, prec,
332 vr0_lb, vr0_ub, tmp, tmp,
333 overflow_undefined,
334 /*overflow_wraps=*/true);
337 int overflow_pos = prec;
338 if (sign == SIGNED)
339 overflow_pos -= 1;
340 int bound_shift = overflow_pos - vr1_ub.to_shwi ();
341 /* If bound_shift == HOST_BITS_PER_WIDE_INT, the llshift can
342 overflow. However, for that to happen, vr1.max needs to be
343 zero, which means vr1 is a singleton range of zero, which
344 means it should be handled by the previous LSHIFT_EXPR
345 if-clause. */
346 wide_int bound = wi::set_bit_in_zero (bound_shift, prec);
347 wide_int complement = ~(bound - 1);
348 wide_int low_bound, high_bound;
349 bool in_bounds = false;
350 if (sign == UNSIGNED)
352 low_bound = bound;
353 high_bound = complement;
354 if (wi::ltu_p (vr0_ub, low_bound))
356 /* [5, 6] << [1, 2] == [10, 24]. */
357 /* We're shifting out only zeroes, the value increases
358 monotonically. */
359 in_bounds = true;
361 else if (wi::ltu_p (high_bound, vr0_lb))
363 /* [0xffffff00, 0xffffffff] << [1, 2]
364 == [0xfffffc00, 0xfffffffe]. */
365 /* We're shifting out only ones, the value decreases
366 monotonically. */
367 in_bounds = true;
370 else
372 /* [-1, 1] << [1, 2] == [-4, 4]. */
373 low_bound = complement;
374 high_bound = bound;
375 if (wi::lts_p (vr0_ub, high_bound)
376 && wi::lts_p (low_bound, vr0_lb))
378 /* For non-negative numbers, we're shifting out only
379 zeroes, the value increases monotonically.
380 For negative numbers, we're shifting out only ones, the
381 value decreases monotomically. */
382 in_bounds = true;
385 if (in_bounds)
386 return wide_int_range_multiplicative_op (res_lb, res_ub,
387 LSHIFT_EXPR, sign, prec,
388 vr0_lb, vr0_ub,
389 vr1_lb, vr1_ub,
390 overflow_undefined,
391 overflow_wraps);
392 return false;
395 /* Return TRUE if a bit operation on two ranges can be easily
396 optimized in terms of a mask.
398 Basically, for BIT_AND_EXPR or BIT_IOR_EXPR see if we can optimize:
400 [LB, UB] op Z
401 into:
402 [LB op Z, UB op Z]
404 It is up to the caller to perform the actual folding above. */
406 bool
407 wide_int_range_can_optimize_bit_op (tree_code code,
408 const wide_int &lb, const wide_int &ub,
409 const wide_int &mask)
412 if (code != BIT_AND_EXPR && code != BIT_IOR_EXPR)
413 return false;
414 /* If Z is a constant which (for op | its bitwise not) has n
415 consecutive least significant bits cleared followed by m 1
416 consecutive bits set immediately above it and either
417 m + n == precision, or (x >> (m + n)) == (y >> (m + n)).
419 The least significant n bits of all the values in the range are
420 cleared or set, the m bits above it are preserved and any bits
421 above these are required to be the same for all values in the
422 range. */
424 wide_int w = mask;
425 int m = 0, n = 0;
426 if (code == BIT_IOR_EXPR)
427 w = ~w;
428 if (wi::eq_p (w, 0))
429 n = w.get_precision ();
430 else
432 n = wi::ctz (w);
433 w = ~(w | wi::mask (n, false, w.get_precision ()));
434 if (wi::eq_p (w, 0))
435 m = w.get_precision () - n;
436 else
437 m = wi::ctz (w) - n;
439 wide_int new_mask = wi::mask (m + n, true, w.get_precision ());
440 if ((new_mask & lb) == (new_mask & ub))
441 return true;
443 return false;
446 /* Calculate the XOR of two ranges and store the result in [WMIN,WMAX].
447 The two input ranges are described by their MUST_BE_NONZERO and
448 MAY_BE_NONZERO bit masks.
450 Return TRUE if we were able to successfully calculate the new range. */
452 bool
453 wide_int_range_bit_xor (wide_int &wmin, wide_int &wmax,
454 signop sign,
455 unsigned prec,
456 const wide_int &must_be_nonzero0,
457 const wide_int &may_be_nonzero0,
458 const wide_int &must_be_nonzero1,
459 const wide_int &may_be_nonzero1)
461 wide_int result_zero_bits = ((must_be_nonzero0 & must_be_nonzero1)
462 | ~(may_be_nonzero0 | may_be_nonzero1));
463 wide_int result_one_bits
464 = (wi::bit_and_not (must_be_nonzero0, may_be_nonzero1)
465 | wi::bit_and_not (must_be_nonzero1, may_be_nonzero0));
466 wmax = ~result_zero_bits;
467 wmin = result_one_bits;
468 /* If the range has all positive or all negative values, the result
469 is better than VARYING. */
470 if (wi::lt_p (wmin, 0, sign) || wi::ge_p (wmax, 0, sign))
471 return true;
472 wmin = wi::min_value (prec, sign);
473 wmax = wi::max_value (prec, sign);
474 return false;
477 /* Calculate the IOR of two ranges and store the result in [WMIN,WMAX].
478 Return TRUE if we were able to successfully calculate the new range. */
480 bool
481 wide_int_range_bit_ior (wide_int &wmin, wide_int &wmax,
482 signop sign,
483 const wide_int &vr0_min,
484 const wide_int &vr0_max,
485 const wide_int &vr1_min,
486 const wide_int &vr1_max,
487 const wide_int &must_be_nonzero0,
488 const wide_int &may_be_nonzero0,
489 const wide_int &must_be_nonzero1,
490 const wide_int &may_be_nonzero1)
492 wmin = must_be_nonzero0 | must_be_nonzero1;
493 wmax = may_be_nonzero0 | may_be_nonzero1;
494 /* If the input ranges contain only positive values we can
495 truncate the minimum of the result range to the maximum
496 of the input range minima. */
497 if (wi::ge_p (vr0_min, 0, sign)
498 && wi::ge_p (vr1_min, 0, sign))
500 wmin = wi::max (wmin, vr0_min, sign);
501 wmin = wi::max (wmin, vr1_min, sign);
503 /* If either input range contains only negative values
504 we can truncate the minimum of the result range to the
505 respective minimum range. */
506 if (wi::lt_p (vr0_max, 0, sign))
507 wmin = wi::max (wmin, vr0_min, sign);
508 if (wi::lt_p (vr1_max, 0, sign))
509 wmin = wi::max (wmin, vr1_min, sign);
510 /* If the limits got swapped around, indicate error so we can adjust
511 the range to VARYING. */
512 if (wi::gt_p (wmin, wmax,sign))
513 return false;
514 return true;
517 /* Calculate the bitwise AND of two ranges and store the result in [WMIN,WMAX].
518 Return TRUE if we were able to successfully calculate the new range. */
520 bool
521 wide_int_range_bit_and (wide_int &wmin, wide_int &wmax,
522 signop sign,
523 unsigned prec,
524 const wide_int &vr0_min,
525 const wide_int &vr0_max,
526 const wide_int &vr1_min,
527 const wide_int &vr1_max,
528 const wide_int &must_be_nonzero0,
529 const wide_int &may_be_nonzero0,
530 const wide_int &must_be_nonzero1,
531 const wide_int &may_be_nonzero1)
533 wmin = must_be_nonzero0 & must_be_nonzero1;
534 wmax = may_be_nonzero0 & may_be_nonzero1;
535 /* If both input ranges contain only negative values we can
536 truncate the result range maximum to the minimum of the
537 input range maxima. */
538 if (wi::lt_p (vr0_max, 0, sign) && wi::lt_p (vr1_max, 0, sign))
540 wmax = wi::min (wmax, vr0_max, sign);
541 wmax = wi::min (wmax, vr1_max, sign);
543 /* If either input range contains only non-negative values
544 we can truncate the result range maximum to the respective
545 maximum of the input range. */
546 if (wi::ge_p (vr0_min, 0, sign))
547 wmax = wi::min (wmax, vr0_max, sign);
548 if (wi::ge_p (vr1_min, 0, sign))
549 wmax = wi::min (wmax, vr1_max, sign);
550 /* PR68217: In case of signed & sign-bit-CST should
551 result in [-INF, 0] instead of [-INF, INF]. */
552 if (wi::gt_p (wmin, wmax, sign))
554 wide_int sign_bit = wi::set_bit_in_zero (prec - 1, prec);
555 if (sign == SIGNED
556 && ((wi::eq_p (vr0_min, vr0_max)
557 && !wi::cmps (vr0_min, sign_bit))
558 || (wi::eq_p (vr1_min, vr1_max)
559 && !wi::cmps (vr1_min, sign_bit))))
561 wmin = wi::min_value (prec, sign);
562 wmax = wi::zero (prec);
565 /* If the limits got swapped around, indicate error so we can adjust
566 the range to VARYING. */
567 if (wi::gt_p (wmin, wmax,sign))
568 return false;
569 return true;
572 /* Calculate TRUNC_MOD_EXPR on two ranges and store the result in
573 [WMIN,WMAX]. */
575 void
576 wide_int_range_trunc_mod (wide_int &wmin, wide_int &wmax,
577 signop sign,
578 unsigned prec,
579 const wide_int &vr0_min,
580 const wide_int &vr0_max,
581 const wide_int &vr1_min,
582 const wide_int &vr1_max)
584 wide_int tmp;
586 /* ABS (A % B) < ABS (B) and either
587 0 <= A % B <= A or A <= A % B <= 0. */
588 wmax = vr1_max - 1;
589 if (sign == SIGNED)
591 tmp = -1 - vr1_min;
592 wmax = wi::smax (wmax, tmp);
595 if (sign == UNSIGNED)
596 wmin = wi::zero (prec);
597 else
599 wmin = -wmax;
600 tmp = vr0_min;
601 if (wi::gts_p (tmp, 0))
602 tmp = wi::zero (prec);
603 wmin = wi::smax (wmin, tmp);
605 tmp = vr0_max;
606 if (sign == SIGNED && wi::neg_p (tmp))
607 tmp = wi::zero (prec);
608 wmax = wi::min (wmax, tmp, sign);
611 /* Calculate ABS_EXPR on a range and store the result in [MIN, MAX]. */
613 bool
614 wide_int_range_abs (wide_int &min, wide_int &max,
615 signop sign, unsigned prec,
616 const wide_int &vr0_min, const wide_int &vr0_max,
617 bool overflow_undefined)
619 /* Pass through VR0 the easy cases. */
620 if (sign == UNSIGNED || wi::ge_p (vr0_min, 0, sign))
622 min = vr0_min;
623 max = vr0_max;
624 return true;
627 /* -TYPE_MIN_VALUE = TYPE_MIN_VALUE with flag_wrapv so we can't get a
628 useful range. */
629 wide_int min_value = wi::min_value (prec, sign);
630 wide_int max_value = wi::max_value (prec, sign);
631 if (!overflow_undefined && wi::eq_p (vr0_min, min_value))
632 return false;
634 /* ABS_EXPR may flip the range around, if the original range
635 included negative values. */
636 if (wi::eq_p (vr0_min, min_value))
637 min = max_value;
638 else
639 min = wi::abs (vr0_min);
640 if (wi::eq_p (vr0_max, min_value))
641 max = max_value;
642 else
643 max = wi::abs (vr0_max);
645 /* If the range contains zero then we know that the minimum value in the
646 range will be zero. */
647 if (wi::le_p (vr0_min, 0, sign) && wi::ge_p (vr0_max, 0, sign))
649 if (wi::gt_p (min, max, sign))
650 max = min;
651 min = wi::zero (prec);
653 else
655 /* If the range was reversed, swap MIN and MAX. */
656 if (wi::gt_p (min, max, sign))
657 std::swap (min, max);
660 /* If the new range has its limits swapped around (MIN > MAX), then
661 the operation caused one of them to wrap around, mark the new
662 range VARYING. */
663 if (wi::gt_p (min, max, sign))
664 return false;
665 return true;
668 /* Calculate a division operation on two ranges and store the result in
669 [WMIN, WMAX] U [EXTRA_MIN, EXTRA_MAX].
671 If EXTRA_RANGE_P is set upon return, EXTRA_MIN/EXTRA_MAX hold
672 meaningful information, otherwise they should be ignored.
674 Return TRUE if we were able to successfully calculate the new range. */
676 bool
677 wide_int_range_div (wide_int &wmin, wide_int &wmax,
678 tree_code code, signop sign, unsigned prec,
679 const wide_int &dividend_min, const wide_int &dividend_max,
680 const wide_int &divisor_min, const wide_int &divisor_max,
681 bool overflow_undefined,
682 bool overflow_wraps,
683 bool &extra_range_p,
684 wide_int &extra_min, wide_int &extra_max)
686 extra_range_p = false;
688 /* If we know we won't divide by zero, just do the division. */
689 if (!wide_int_range_includes_zero_p (divisor_min, divisor_max, sign))
690 return wide_int_range_multiplicative_op (wmin, wmax, code, sign, prec,
691 dividend_min, dividend_max,
692 divisor_min, divisor_max,
693 overflow_undefined,
694 overflow_wraps);
696 /* If flag_non_call_exceptions, we must not eliminate a division
697 by zero. */
698 if (cfun->can_throw_non_call_exceptions)
699 return false;
701 /* If we're definitely dividing by zero, there's nothing to do. */
702 if (wide_int_range_zero_p (divisor_min, divisor_max, prec))
703 return false;
705 /* Perform the division in 2 parts, [LB, -1] and [1, UB],
706 which will skip any division by zero.
708 First divide by the negative numbers, if any. */
709 if (wi::neg_p (divisor_min, sign))
711 if (!wide_int_range_multiplicative_op (wmin, wmax,
712 code, sign, prec,
713 dividend_min, dividend_max,
714 divisor_min, wi::minus_one (prec),
715 overflow_undefined,
716 overflow_wraps))
717 return false;
718 extra_range_p = true;
720 /* Then divide by the non-zero positive numbers, if any. */
721 if (wi::gt_p (divisor_max, wi::zero (prec), sign))
723 if (!wide_int_range_multiplicative_op (extra_range_p ? extra_min : wmin,
724 extra_range_p ? extra_max : wmax,
725 code, sign, prec,
726 dividend_min, dividend_max,
727 wi::one (prec), divisor_max,
728 overflow_undefined,
729 overflow_wraps))
730 return false;
732 else
733 extra_range_p = false;
734 return true;