1 /* Support routines for range operations on wide ints.
2    Copyright (C) 2018-2019 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
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.
10 
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.
15 
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/>.  */
19 
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"
27 
28 /* Wrapper around wide_int_binop that adjusts for overflow.
29 
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.
35 
36    Return false for division by zero, for which the result is
37    indeterminate.  */
38 
39 static bool
wide_int_binop_overflow(wide_int & res,enum tree_code code,const wide_int & w0,const wide_int & w1,signop sign,bool overflow_undefined)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)
44 {
45   wi::overflow_type overflow;
46   if (!wide_int_binop (res, code, w0, w1, sign, &overflow))
47     return false;
48 
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)
52     {
53       switch (code)
54 	{
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;
63 
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;
72 
73 	default:
74 	  gcc_unreachable ();
75 	}
76     }
77   return !overflow;
78 }
79 
80 /* For range [LB, UB] compute two wide_int bit masks.
81 
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.
85 
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.  */
89 
90 void
wide_int_range_set_zero_nonzero_bits(signop sign,const wide_int & lb,const wide_int & ub,wide_int & may_be_nonzero,wide_int & must_be_nonzero)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)
95 {
96   may_be_nonzero = wi::minus_one (lb.get_precision ());
97   must_be_nonzero = wi::zero (lb.get_precision ());
98 
99   if (wi::eq_p (lb, ub))
100     {
101       may_be_nonzero = lb;
102       must_be_nonzero = may_be_nonzero;
103     }
104   else if (wi::ge_p (lb, 0, sign) || wi::lt_p (ub, 0, sign))
105     {
106       wide_int xor_mask = lb ^ ub;
107       may_be_nonzero = lb | ub;
108       must_be_nonzero = lb & ub;
109       if (xor_mask != 0)
110 	{
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);
115 	}
116     }
117 }
118 
119 /* Order 2 sets of wide int ranges (w0/w1, w2/w3) and set MIN/MAX
120    accordingly.  */
121 
122 static void
wide_int_range_order_set(wide_int & min,wide_int & max,wide_int & w0,wide_int & w1,wide_int & w2,wide_int & w3,signop sign)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)
127 {
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);
133 
134   /* Choose min and max from the ordered pairs.  */
135   min = wi::min (w0, w2, sign);
136   max = wi::max (w1, w3, sign);
137 }
138 
139 /* Calculate the cross product of two sets of ranges (VR0 and VR1) and
140    store the result in [RES_LB, RES_UB].
141 
142    CODE is the operation to perform with sign SIGN.
143 
144    OVERFLOW_UNDEFINED is set if overflow is undefined for the operation type.
145 
146    Return TRUE if we were able to calculate the cross product.  */
147 
148 bool
wide_int_range_cross_product(wide_int & res_lb,wide_int & res_ub,enum tree_code code,signop sign,const wide_int & vr0_lb,const wide_int & vr0_ub,const wide_int & vr1_lb,const wide_int & vr1_ub,bool overflow_undefined)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)
154 {
155   wide_int cp1, cp2, cp3, cp4;
156 
157   /* Compute the 4 cross operations, bailing if we get an overflow we
158      can't handle.  */
159 
160   if (!wide_int_binop_overflow (cp1, code, vr0_lb, vr1_lb, sign,
161 				overflow_undefined))
162     return false;
163 
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;
169 
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;
175 
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;
181 
182   wide_int_range_order_set (res_lb, res_ub, cp1, cp2, cp3, cp4, sign);
183   return true;
184 }
185 
186 /* Multiply two ranges when TYPE_OVERFLOW_WRAPS:
187 
188      [RES_LB, RES_UB] = [MIN0, MAX0] * [MIN1, MAX1]
189 
190    This is basically fancy code so we don't drop to varying with an
191    unsigned [-3,-1]*[-3,-1].
192 
193    Return TRUE if we were able to perform the operation.  */
194 
195 bool
wide_int_range_mult_wrapping(wide_int & res_lb,wide_int & res_ub,signop sign,unsigned prec,const wide_int & min0_,const wide_int & max0_,const wide_int & min1_,const wide_int & max1_)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_)
204 {
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;
216 
217   /* Canonicalize the intervals.  */
218   if (sign == UNSIGNED)
219     {
220       if (wi::ltu_p (size, min0 + max0))
221 	{
222 	  min0 -= size;
223 	  max0 -= size;
224 	}
225 
226       if (wi::ltu_p (size, min1 + max1))
227 	{
228 	  min1 -= size;
229 	  max1 -= size;
230 	}
231     }
232 
233   widest2_int prod0 = min0 * min1;
234   widest2_int prod1 = min0 * max1;
235   widest2_int prod2 = max0 * min1;
236   widest2_int prod3 = max0 * max1;
237 
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);
243 
244   /* min0max1 > max0min1 */
245   if (prod1 > prod2)
246     std::swap (prod1, prod2);
247 
248   if (prod0 > prod1)
249     std::swap (prod0, prod1);
250 
251   if (prod2 > prod3)
252     std::swap (prod2, prod3);
253 
254   /* diff = max - min.  */
255   prod2 = prod3 - prod0;
256   if (wi::geu_p (prod2, sizem1))
257     /* The range covers all values.  */
258     return false;
259 
260   res_lb = wide_int::from (prod0, prec, sign);
261   res_ub = wide_int::from (prod3, prec, sign);
262   return true;
263 }
264 
265 /* Perform multiplicative operation CODE on two ranges:
266 
267      [RES_LB, RES_UB] = [VR0_LB, VR0_UB] .CODE. [VR1_LB, VR1_LB]
268 
269    Return TRUE if we were able to perform the operation.
270 
271    NOTE: If code is MULT_EXPR and !TYPE_OVERFLOW_UNDEFINED, the resulting
272    range must be canonicalized by the caller because its components
273    may be swapped.  */
274 
275 bool
wide_int_range_multiplicative_op(wide_int & res_lb,wide_int & res_ub,enum tree_code code,signop sign,unsigned prec,const wide_int & vr0_lb,const wide_int & vr0_ub,const wide_int & vr1_lb,const wide_int & vr1_ub,bool overflow_undefined)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 {
286   /* Multiplications, divisions and shifts are a bit tricky to handle,
287      depending on the mix of signs we have in the two ranges, we
288      need to operate on different values to get the minimum and
289      maximum values for the new range.  One approach is to figure
290      out all the variations of range combinations and do the
291      operations.
292 
293      However, this involves several calls to compare_values and it
294      is pretty convoluted.  It's simpler to do the 4 operations
295      (MIN0 OP MIN1, MIN0 OP MAX1, MAX0 OP MIN1 and MAX0 OP MAX0 OP
296      MAX1) and then figure the smallest and largest values to form
297      the new range.  */
298   if (code == MULT_EXPR && !overflow_undefined)
299     return wide_int_range_mult_wrapping (res_lb, res_ub,
300 					 sign, prec,
301 					 vr0_lb, vr0_ub, vr1_lb, vr1_ub);
302   return wide_int_range_cross_product (res_lb, res_ub,
303 				       code, sign,
304 				       vr0_lb, vr0_ub, vr1_lb, vr1_ub,
305 				       overflow_undefined);
306 }
307 
308 /* Perform a left shift operation on two ranges:
309 
310      [RES_LB, RES_UB] = [VR0_LB, VR0_UB] << [VR1_LB, VR1_LB]
311 
312    Return TRUE if we were able to perform the operation.
313 
314    NOTE: The resulting range must be canonicalized by the caller
315    because its contents components may be swapped.  */
316 
317 bool
wide_int_range_lshift(wide_int & res_lb,wide_int & res_ub,signop sign,unsigned prec,const wide_int & vr0_lb,const wide_int & vr0_ub,const wide_int & vr1_lb,const wide_int & vr1_ub,bool overflow_undefined)318 wide_int_range_lshift (wide_int &res_lb, wide_int &res_ub,
319 		       signop sign, unsigned prec,
320 		       const wide_int &vr0_lb, const wide_int &vr0_ub,
321 		       const wide_int &vr1_lb, const wide_int &vr1_ub,
322 		       bool overflow_undefined)
323 {
324   /* Transform left shifts by constants into multiplies.  */
325   if (wi::eq_p (vr1_lb, vr1_ub))
326     {
327       unsigned shift = vr1_ub.to_uhwi ();
328       wide_int tmp = wi::set_bit_in_zero (shift, prec);
329       return wide_int_range_multiplicative_op (res_lb, res_ub,
330 					       MULT_EXPR, sign, prec,
331 					       vr0_lb, vr0_ub, tmp, tmp,
332 					       /*overflow_undefined=*/false);
333     }
334 
335   int overflow_pos = prec;
336   if (sign == SIGNED)
337     overflow_pos -= 1;
338   int bound_shift = overflow_pos - vr1_ub.to_shwi ();
339   /* If bound_shift == HOST_BITS_PER_WIDE_INT, the llshift can
340      overflow.  However, for that to happen, vr1.max needs to be
341      zero, which means vr1 is a singleton range of zero, which
342      means it should be handled by the previous LSHIFT_EXPR
343      if-clause.  */
344   wide_int bound = wi::set_bit_in_zero (bound_shift, prec);
345   wide_int complement = ~(bound - 1);
346   wide_int low_bound, high_bound;
347   bool in_bounds = false;
348   if (sign == UNSIGNED)
349     {
350       low_bound = bound;
351       high_bound = complement;
352       if (wi::ltu_p (vr0_ub, low_bound))
353 	{
354 	  /* [5, 6] << [1, 2] == [10, 24].  */
355 	  /* We're shifting out only zeroes, the value increases
356 	     monotonically.  */
357 	  in_bounds = true;
358 	}
359       else if (wi::ltu_p (high_bound, vr0_lb))
360 	{
361 	  /* [0xffffff00, 0xffffffff] << [1, 2]
362 	     == [0xfffffc00, 0xfffffffe].  */
363 	  /* We're shifting out only ones, the value decreases
364 	     monotonically.  */
365 	  in_bounds = true;
366 	}
367     }
368   else
369     {
370       /* [-1, 1] << [1, 2] == [-4, 4].  */
371       low_bound = complement;
372       high_bound = bound;
373       if (wi::lts_p (vr0_ub, high_bound)
374 	  && wi::lts_p (low_bound, vr0_lb))
375 	{
376 	  /* For non-negative numbers, we're shifting out only
377 	     zeroes, the value increases monotonically.
378 	     For negative numbers, we're shifting out only ones, the
379 	     value decreases monotomically.  */
380 	  in_bounds = true;
381 	}
382     }
383   if (in_bounds)
384     return wide_int_range_multiplicative_op (res_lb, res_ub,
385 					     LSHIFT_EXPR, sign, prec,
386 					     vr0_lb, vr0_ub,
387 					     vr1_lb, vr1_ub,
388 					     overflow_undefined);
389   return false;
390 }
391 
392 /* Return TRUE if a bit operation on two ranges can be easily
393    optimized in terms of a mask.
394 
395    Basically, for BIT_AND_EXPR or BIT_IOR_EXPR see if we can optimize:
396 
397 	[LB, UB] op Z
398    into:
399 	[LB op Z, UB op Z]
400 
401    It is up to the caller to perform the actual folding above.  */
402 
403 static bool
wide_int_range_can_optimize_bit_op(tree_code code,const wide_int & lb,const wide_int & ub,const wide_int & mask)404 wide_int_range_can_optimize_bit_op (tree_code code,
405 				    const wide_int &lb, const wide_int &ub,
406 				    const wide_int &mask)
407 
408 {
409   if (code != BIT_AND_EXPR && code != BIT_IOR_EXPR)
410     return false;
411   /* If Z is a constant which (for op | its bitwise not) has n
412      consecutive least significant bits cleared followed by m 1
413      consecutive bits set immediately above it and either
414      m + n == precision, or (x >> (m + n)) == (y >> (m + n)).
415 
416      The least significant n bits of all the values in the range are
417      cleared or set, the m bits above it are preserved and any bits
418      above these are required to be the same for all values in the
419      range.  */
420 
421   wide_int w = mask;
422   int m = 0, n = 0;
423   if (code == BIT_IOR_EXPR)
424     w = ~w;
425   if (wi::eq_p (w, 0))
426     n = w.get_precision ();
427   else
428     {
429       n = wi::ctz (w);
430       w = ~(w | wi::mask (n, false, w.get_precision ()));
431       if (wi::eq_p (w, 0))
432 	m = w.get_precision () - n;
433       else
434 	m = wi::ctz (w) - n;
435     }
436   wide_int new_mask = wi::mask (m + n, true, w.get_precision ());
437   if ((new_mask & lb) == (new_mask & ub))
438     return true;
439 
440   return false;
441 }
442 
443 /* Helper function for wide_int_range_optimize_bit_op.
444 
445    Calculates bounds and mask for a pair of ranges.  The mask is the
446    singleton range among the ranges, if any.  The bounds are the
447    bounds for the remaining range.  */
448 
449 bool
wide_int_range_get_mask_and_bounds(wide_int & mask,wide_int & lower_bound,wide_int & upper_bound,const wide_int & vr0_min,const wide_int & vr0_max,const wide_int & vr1_min,const wide_int & vr1_max)450 wide_int_range_get_mask_and_bounds (wide_int &mask,
451 				    wide_int &lower_bound,
452 				    wide_int &upper_bound,
453 				    const wide_int &vr0_min,
454 				    const wide_int &vr0_max,
455 				    const wide_int &vr1_min,
456 				    const wide_int &vr1_max)
457 {
458   if (wi::eq_p (vr1_min, vr1_max))
459     {
460       mask = vr1_min;
461       lower_bound = vr0_min;
462       upper_bound = vr0_max;
463       return true;
464     }
465   else if (wi::eq_p (vr0_min, vr0_max))
466     {
467       mask = vr0_min;
468       lower_bound = vr1_min;
469       upper_bound = vr1_max;
470       return true;
471     }
472   return false;
473 }
474 
475 /* Optimize a bit operation (BIT_AND_EXPR or BIT_IOR_EXPR) if
476    possible.  If so, return TRUE and store the result in
477    [RES_LB, RES_UB].  */
478 
479 bool
wide_int_range_optimize_bit_op(wide_int & res_lb,wide_int & res_ub,enum tree_code code,signop sign,const wide_int & vr0_min,const wide_int & vr0_max,const wide_int & vr1_min,const wide_int & vr1_max)480 wide_int_range_optimize_bit_op (wide_int &res_lb, wide_int &res_ub,
481 				enum tree_code code,
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 {
488   gcc_assert (code == BIT_AND_EXPR || code == BIT_IOR_EXPR);
489 
490   wide_int lower_bound, upper_bound, mask;
491   if (!wide_int_range_get_mask_and_bounds (mask, lower_bound, upper_bound,
492 					   vr0_min, vr0_max, vr1_min, vr1_max))
493     return false;
494   if (wide_int_range_can_optimize_bit_op (code,
495 					  lower_bound, upper_bound, mask))
496     {
497       wi::overflow_type ovf;
498       wide_int_binop (res_lb, code, lower_bound, mask, sign, &ovf);
499       wide_int_binop (res_ub, code, upper_bound, mask, sign, &ovf);
500       return true;
501     }
502   return false;
503 }
504 
505 /* Calculate the XOR of two ranges and store the result in [WMIN,WMAX].
506    The two input ranges are described by their MUST_BE_NONZERO and
507    MAY_BE_NONZERO bit masks.
508 
509    Return TRUE if we were able to successfully calculate the new range.  */
510 
511 bool
wide_int_range_bit_xor(wide_int & wmin,wide_int & wmax,signop sign,unsigned prec,const wide_int & must_be_nonzero0,const wide_int & may_be_nonzero0,const wide_int & must_be_nonzero1,const wide_int & may_be_nonzero1)512 wide_int_range_bit_xor (wide_int &wmin, wide_int &wmax,
513 			signop sign,
514 			unsigned prec,
515 			const wide_int &must_be_nonzero0,
516 			const wide_int &may_be_nonzero0,
517 			const wide_int &must_be_nonzero1,
518 			const wide_int &may_be_nonzero1)
519 {
520   wide_int result_zero_bits = ((must_be_nonzero0 & must_be_nonzero1)
521 			       | ~(may_be_nonzero0 | may_be_nonzero1));
522   wide_int result_one_bits
523     = (wi::bit_and_not (must_be_nonzero0, may_be_nonzero1)
524        | wi::bit_and_not (must_be_nonzero1, may_be_nonzero0));
525   wmax = ~result_zero_bits;
526   wmin = result_one_bits;
527   /* If the range has all positive or all negative values, the result
528      is better than VARYING.  */
529   if (wi::lt_p (wmin, 0, sign) || wi::ge_p (wmax, 0, sign))
530     return true;
531   wmin = wi::min_value (prec, sign);
532   wmax = wi::max_value (prec, sign);
533   return false;
534 }
535 
536 /* Calculate the IOR of two ranges and store the result in [WMIN,WMAX].
537    Return TRUE if we were able to successfully calculate the new range.  */
538 
539 bool
wide_int_range_bit_ior(wide_int & wmin,wide_int & wmax,signop sign,const wide_int & vr0_min,const wide_int & vr0_max,const wide_int & vr1_min,const wide_int & vr1_max,const wide_int & must_be_nonzero0,const wide_int & may_be_nonzero0,const wide_int & must_be_nonzero1,const wide_int & may_be_nonzero1)540 wide_int_range_bit_ior (wide_int &wmin, wide_int &wmax,
541 			signop sign,
542 			const wide_int &vr0_min,
543 			const wide_int &vr0_max,
544 			const wide_int &vr1_min,
545 			const wide_int &vr1_max,
546 			const wide_int &must_be_nonzero0,
547 			const wide_int &may_be_nonzero0,
548 			const wide_int &must_be_nonzero1,
549 			const wide_int &may_be_nonzero1)
550 {
551   if (wide_int_range_optimize_bit_op (wmin, wmax, BIT_IOR_EXPR, sign,
552 				      vr0_min, vr0_max,
553 				      vr1_min, vr1_max))
554     return true;
555   wmin = must_be_nonzero0 | must_be_nonzero1;
556   wmax = may_be_nonzero0 | may_be_nonzero1;
557   /* If the input ranges contain only positive values we can
558      truncate the minimum of the result range to the maximum
559      of the input range minima.  */
560   if (wi::ge_p (vr0_min, 0, sign)
561       && wi::ge_p (vr1_min, 0, sign))
562     {
563       wmin = wi::max (wmin, vr0_min, sign);
564       wmin = wi::max (wmin, vr1_min, sign);
565     }
566   /* If either input range contains only negative values
567      we can truncate the minimum of the result range to the
568      respective minimum range.  */
569   if (wi::lt_p (vr0_max, 0, sign))
570     wmin = wi::max (wmin, vr0_min, sign);
571   if (wi::lt_p (vr1_max, 0, sign))
572     wmin = wi::max (wmin, vr1_min, sign);
573   /* If the limits got swapped around, indicate error so we can adjust
574      the range to VARYING.  */
575   if (wi::gt_p (wmin, wmax,sign))
576     return false;
577   return true;
578 }
579 
580 /* Calculate the bitwise AND of two ranges and store the result in [WMIN,WMAX].
581    Return TRUE if we were able to successfully calculate the new range.  */
582 
583 bool
wide_int_range_bit_and(wide_int & wmin,wide_int & wmax,signop sign,unsigned prec,const wide_int & vr0_min,const wide_int & vr0_max,const wide_int & vr1_min,const wide_int & vr1_max,const wide_int & must_be_nonzero0,const wide_int & may_be_nonzero0,const wide_int & must_be_nonzero1,const wide_int & may_be_nonzero1)584 wide_int_range_bit_and (wide_int &wmin, wide_int &wmax,
585 			signop sign,
586 			unsigned prec,
587 			const wide_int &vr0_min,
588 			const wide_int &vr0_max,
589 			const wide_int &vr1_min,
590 			const wide_int &vr1_max,
591 			const wide_int &must_be_nonzero0,
592 			const wide_int &may_be_nonzero0,
593 			const wide_int &must_be_nonzero1,
594 			const wide_int &may_be_nonzero1)
595 {
596   if (wide_int_range_optimize_bit_op (wmin, wmax, BIT_AND_EXPR, sign,
597 				      vr0_min, vr0_max,
598 				      vr1_min, vr1_max))
599     return true;
600   wmin = must_be_nonzero0 & must_be_nonzero1;
601   wmax = may_be_nonzero0 & may_be_nonzero1;
602   /* If both input ranges contain only negative values we can
603      truncate the result range maximum to the minimum of the
604      input range maxima.  */
605   if (wi::lt_p (vr0_max, 0, sign) && wi::lt_p (vr1_max, 0, sign))
606     {
607       wmax = wi::min (wmax, vr0_max, sign);
608       wmax = wi::min (wmax, vr1_max, sign);
609     }
610   /* If either input range contains only non-negative values
611      we can truncate the result range maximum to the respective
612      maximum of the input range.  */
613   if (wi::ge_p (vr0_min, 0, sign))
614     wmax = wi::min (wmax, vr0_max, sign);
615   if (wi::ge_p (vr1_min, 0, sign))
616     wmax = wi::min (wmax, vr1_max, sign);
617   /* PR68217: In case of signed & sign-bit-CST should
618      result in [-INF, 0] instead of [-INF, INF].  */
619   if (wi::gt_p (wmin, wmax, sign))
620     {
621       wide_int sign_bit = wi::set_bit_in_zero (prec - 1, prec);
622       if (sign == SIGNED
623 	  && ((wi::eq_p (vr0_min, vr0_max)
624 	       && !wi::cmps (vr0_min, sign_bit))
625 	      || (wi::eq_p (vr1_min, vr1_max)
626 		  && !wi::cmps (vr1_min, sign_bit))))
627 	{
628 	  wmin = wi::min_value (prec, sign);
629 	  wmax = wi::zero (prec);
630 	}
631     }
632   /* If the limits got swapped around, indicate error so we can adjust
633      the range to VARYING.  */
634   if (wi::gt_p (wmin, wmax,sign))
635     return false;
636   return true;
637 }
638 
639 /* Calculate TRUNC_MOD_EXPR on two ranges and store the result in
640    [WMIN,WMAX].  */
641 
642 void
wide_int_range_trunc_mod(wide_int & wmin,wide_int & wmax,signop sign,unsigned prec,const wide_int & vr0_min,const wide_int & vr0_max,const wide_int & vr1_min,const wide_int & vr1_max)643 wide_int_range_trunc_mod (wide_int &wmin, wide_int &wmax,
644 			  signop sign,
645 			  unsigned prec,
646 			  const wide_int &vr0_min,
647 			  const wide_int &vr0_max,
648 			  const wide_int &vr1_min,
649 			  const wide_int &vr1_max)
650 {
651   wide_int tmp;
652 
653   /* ABS (A % B) < ABS (B) and either
654      0 <= A % B <= A or A <= A % B <= 0.  */
655   wmax = vr1_max - 1;
656   if (sign == SIGNED)
657     {
658       tmp = -1 - vr1_min;
659       wmax = wi::smax (wmax, tmp);
660     }
661 
662   if (sign == UNSIGNED)
663     wmin = wi::zero (prec);
664   else
665     {
666       wmin = -wmax;
667       tmp = vr0_min;
668       if (wi::gts_p (tmp, 0))
669 	tmp = wi::zero (prec);
670       wmin = wi::smax (wmin, tmp);
671     }
672   tmp = vr0_max;
673   if (sign == SIGNED && wi::neg_p (tmp))
674     tmp = wi::zero (prec);
675   wmax = wi::min (wmax, tmp, sign);
676 }
677 
678 /* Calculate ABS_EXPR on a range and store the result in [MIN, MAX].  */
679 
680 bool
wide_int_range_abs(wide_int & min,wide_int & max,signop sign,unsigned prec,const wide_int & vr0_min,const wide_int & vr0_max,bool overflow_undefined)681 wide_int_range_abs (wide_int &min, wide_int &max,
682 		    signop sign, unsigned prec,
683 		    const wide_int &vr0_min, const wide_int &vr0_max,
684 		    bool overflow_undefined)
685 {
686   /* Pass through VR0 the easy cases.  */
687   if (sign == UNSIGNED || wi::ge_p (vr0_min, 0, sign))
688     {
689       min = vr0_min;
690       max = vr0_max;
691       return true;
692     }
693 
694   /* -TYPE_MIN_VALUE = TYPE_MIN_VALUE with flag_wrapv so we can't get a
695      useful range.  */
696   wide_int min_value = wi::min_value (prec, sign);
697   wide_int max_value = wi::max_value (prec, sign);
698   if (!overflow_undefined && wi::eq_p (vr0_min, min_value))
699     return false;
700 
701   /* ABS_EXPR may flip the range around, if the original range
702      included negative values.  */
703   if (wi::eq_p (vr0_min, min_value))
704     min = max_value;
705   else
706     min = wi::abs (vr0_min);
707   if (wi::eq_p (vr0_max, min_value))
708     max = max_value;
709   else
710     max = wi::abs (vr0_max);
711 
712   /* If the range contains zero then we know that the minimum value in the
713      range will be zero.  */
714   if (wi::le_p (vr0_min, 0, sign) && wi::ge_p (vr0_max, 0, sign))
715     {
716       if (wi::gt_p (min, max, sign))
717 	max = min;
718       min = wi::zero (prec);
719     }
720   else
721     {
722       /* If the range was reversed, swap MIN and MAX.  */
723       if (wi::gt_p (min, max, sign))
724 	std::swap (min, max);
725     }
726 
727   /* If the new range has its limits swapped around (MIN > MAX), then
728      the operation caused one of them to wrap around.  The only thing
729      we know is that the result is positive.  */
730   if (wi::gt_p (min, max, sign))
731     {
732       min = wi::zero (prec);
733       max = max_value;
734     }
735   return true;
736 }
737 
738 /* Calculate ABSU_EXPR on a range and store the result in [MIN, MAX].  */
739 
740 void
wide_int_range_absu(wide_int & min,wide_int & max,unsigned prec,const wide_int & vr0_min,const wide_int & vr0_max)741 wide_int_range_absu (wide_int &min, wide_int &max,
742 		     unsigned prec, const wide_int &vr0_min,
743 		     const wide_int &vr0_max)
744 {
745   /* Pass through VR0 the easy cases.  */
746   if (wi::ges_p (vr0_min, 0))
747     {
748       min = vr0_min;
749       max = vr0_max;
750       return;
751     }
752 
753   min = wi::abs (vr0_min);
754   max = wi::abs (vr0_max);
755 
756   /* If the range contains zero then we know that the minimum value in the
757      range will be zero.  */
758   if (wi::ges_p (vr0_max, 0))
759     {
760       if (wi::gtu_p (min, max))
761 	max = min;
762       min = wi::zero (prec);
763     }
764   else
765     /* Otherwise, swap MIN and MAX.  */
766     std::swap (min, max);
767 }
768 
769 /* Convert range in [VR0_MIN, VR0_MAX] with INNER_SIGN and INNER_PREC,
770    to a range in [MIN, MAX] with OUTER_SIGN and OUTER_PREC.
771 
772    Return TRUE if we were able to successfully calculate the new range.
773 
774    Caller is responsible for canonicalizing the resulting range.  */
775 
776 bool
wide_int_range_convert(wide_int & min,wide_int & max,signop inner_sign,unsigned inner_prec,signop outer_sign,unsigned outer_prec,const wide_int & vr0_min,const wide_int & vr0_max)777 wide_int_range_convert (wide_int &min, wide_int &max,
778 			signop inner_sign,
779 			unsigned inner_prec,
780 			signop outer_sign,
781 			unsigned outer_prec,
782 			const wide_int &vr0_min,
783 			const wide_int &vr0_max)
784 {
785   /* If the conversion is not truncating we can convert the min and
786      max values and canonicalize the resulting range.  Otherwise we
787      can do the conversion if the size of the range is less than what
788      the precision of the target type can represent.  */
789   if (outer_prec >= inner_prec
790       || wi::rshift (wi::sub (vr0_max, vr0_min),
791 		     wi::uhwi (outer_prec, inner_prec),
792 		     inner_sign) == 0)
793     {
794       min = wide_int::from (vr0_min, outer_prec, inner_sign);
795       max = wide_int::from (vr0_max, outer_prec, inner_sign);
796       return (!wi::eq_p (min, wi::min_value (outer_prec, outer_sign))
797 	      || !wi::eq_p (max, wi::max_value (outer_prec, outer_sign)));
798     }
799   return false;
800 }
801 
802 /* Calculate a division operation on two ranges and store the result in
803    [WMIN, WMAX] U [EXTRA_MIN, EXTRA_MAX].
804 
805    If EXTRA_RANGE_P is set upon return, EXTRA_MIN/EXTRA_MAX hold
806    meaningful information, otherwise they should be ignored.
807 
808    Return TRUE if we were able to successfully calculate the new range.  */
809 
810 bool
wide_int_range_div(wide_int & wmin,wide_int & wmax,tree_code code,signop sign,unsigned prec,const wide_int & dividend_min,const wide_int & dividend_max,const wide_int & divisor_min,const wide_int & divisor_max,bool overflow_undefined,bool & extra_range_p,wide_int & extra_min,wide_int & extra_max)811 wide_int_range_div (wide_int &wmin, wide_int &wmax,
812 		    tree_code code, signop sign, unsigned prec,
813 		    const wide_int &dividend_min, const wide_int &dividend_max,
814 		    const wide_int &divisor_min, const wide_int &divisor_max,
815 		    bool overflow_undefined,
816 		    bool &extra_range_p,
817 		    wide_int &extra_min, wide_int &extra_max)
818 {
819   extra_range_p = false;
820 
821   /* If we know we won't divide by zero, just do the division.  */
822   if (!wide_int_range_includes_zero_p (divisor_min, divisor_max, sign))
823     return wide_int_range_multiplicative_op (wmin, wmax, code, sign, prec,
824 					     dividend_min, dividend_max,
825 					     divisor_min, divisor_max,
826 					     overflow_undefined);
827 
828   /* If flag_non_call_exceptions, we must not eliminate a division
829      by zero.  */
830   if (cfun->can_throw_non_call_exceptions)
831     return false;
832 
833   /* If we're definitely dividing by zero, there's nothing to do.  */
834   if (wide_int_range_zero_p (divisor_min, divisor_max, prec))
835     return false;
836 
837   /* Perform the division in 2 parts, [LB, -1] and [1, UB],
838      which will skip any division by zero.
839 
840      First divide by the negative numbers, if any.  */
841   if (wi::neg_p (divisor_min, sign))
842     {
843       if (!wide_int_range_multiplicative_op (wmin, wmax,
844 					     code, sign, prec,
845 					     dividend_min, dividend_max,
846 					     divisor_min, wi::minus_one (prec),
847 					     overflow_undefined))
848 	return false;
849       extra_range_p = true;
850     }
851   /* Then divide by the non-zero positive numbers, if any.  */
852   if (wi::gt_p (divisor_max, wi::zero (prec), sign))
853     {
854       if (!wide_int_range_multiplicative_op (extra_range_p ? extra_min : wmin,
855 					     extra_range_p ? extra_max : wmax,
856 					     code, sign, prec,
857 					     dividend_min, dividend_max,
858 					     wi::one (prec), divisor_max,
859 					     overflow_undefined))
860 	return false;
861     }
862   else
863     extra_range_p = false;
864   return true;
865 }
866