1 /* Code for range operators.
2    Copyright (C) 2017-2021 Free Software Foundation, Inc.
3    Contributed by Andrew MacLeod <amacleod@redhat.com>
4    and Aldy Hernandez <aldyh@redhat.com>.
5 
6 This file is part of GCC.
7 
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12 
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21 
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "backend.h"
26 #include "insn-codes.h"
27 #include "rtl.h"
28 #include "tree.h"
29 #include "gimple.h"
30 #include "cfghooks.h"
31 #include "tree-pass.h"
32 #include "ssa.h"
33 #include "optabs-tree.h"
34 #include "gimple-pretty-print.h"
35 #include "diagnostic-core.h"
36 #include "flags.h"
37 #include "fold-const.h"
38 #include "stor-layout.h"
39 #include "calls.h"
40 #include "cfganal.h"
41 #include "gimple-fold.h"
42 #include "tree-eh.h"
43 #include "gimple-iterator.h"
44 #include "gimple-walk.h"
45 #include "tree-cfg.h"
46 #include "wide-int.h"
47 #include "range-op.h"
48 
49 // Return the upper limit for a type.
50 
51 static inline wide_int
max_limit(const_tree type)52 max_limit (const_tree type)
53 {
54   return wi::max_value (TYPE_PRECISION (type) , TYPE_SIGN (type));
55 }
56 
57 // Return the lower limit for a type.
58 
59 static inline wide_int
min_limit(const_tree type)60 min_limit (const_tree type)
61 {
62   return wi::min_value (TYPE_PRECISION (type) , TYPE_SIGN (type));
63 }
64 
65 // If the range of either op1 or op2 is undefined, set the result to
66 // varying and return TRUE.  If the caller truely cares about a result,
67 // they should pass in a varying if it has an undefined that it wants
68 // treated as a varying.
69 
70 inline bool
empty_range_varying(irange & r,tree type,const irange & op1,const irange & op2)71 empty_range_varying (irange &r, tree type,
72 		     const irange &op1, const irange & op2)
73 {
74   if (op1.undefined_p () || op2.undefined_p ())
75     {
76       r.set_varying (type);
77       return true;
78     }
79   else
80     return false;
81 }
82 
83 // Return false if shifting by OP is undefined behavior.  Otherwise, return
84 // true and the range it is to be shifted by.  This allows trimming out of
85 // undefined ranges, leaving only valid ranges if there are any.
86 
87 static inline bool
get_shift_range(irange & r,tree type,const irange & op)88 get_shift_range (irange &r, tree type, const irange &op)
89 {
90   if (op.undefined_p ())
91     return false;
92 
93   // Build valid range and intersect it with the shift range.
94   r = value_range (build_int_cst_type (op.type (), 0),
95 		   build_int_cst_type (op.type (), TYPE_PRECISION (type) - 1));
96   r.intersect (op);
97 
98   // If there are no valid ranges in the shift range, returned false.
99   if (r.undefined_p ())
100     return false;
101   return true;
102 }
103 
104 // Return TRUE if 0 is within [WMIN, WMAX].
105 
106 static inline bool
wi_includes_zero_p(tree type,const wide_int & wmin,const wide_int & wmax)107 wi_includes_zero_p (tree type, const wide_int &wmin, const wide_int &wmax)
108 {
109   signop sign = TYPE_SIGN (type);
110   return wi::le_p (wmin, 0, sign) && wi::ge_p (wmax, 0, sign);
111 }
112 
113 // Return TRUE if [WMIN, WMAX] is the singleton 0.
114 
115 static inline bool
wi_zero_p(tree type,const wide_int & wmin,const wide_int & wmax)116 wi_zero_p (tree type, const wide_int &wmin, const wide_int &wmax)
117 {
118   unsigned prec = TYPE_PRECISION (type);
119   return wmin == wmax && wi::eq_p (wmin, wi::zero (prec));
120 }
121 
122 // Default wide_int fold operation returns [MIN, MAX].
123 
124 void
wi_fold(irange & r,tree type,const wide_int & lh_lb ATTRIBUTE_UNUSED,const wide_int & lh_ub ATTRIBUTE_UNUSED,const wide_int & rh_lb ATTRIBUTE_UNUSED,const wide_int & rh_ub ATTRIBUTE_UNUSED) const125 range_operator::wi_fold (irange &r, tree type,
126 			 const wide_int &lh_lb ATTRIBUTE_UNUSED,
127 			 const wide_int &lh_ub ATTRIBUTE_UNUSED,
128 			 const wide_int &rh_lb ATTRIBUTE_UNUSED,
129 			 const wide_int &rh_ub ATTRIBUTE_UNUSED) const
130 {
131   gcc_checking_assert (irange::supports_type_p (type));
132   r.set_varying (type);
133 }
134 
135 // The default for fold is to break all ranges into sub-ranges and
136 // invoke the wi_fold method on each sub-range pair.
137 
138 bool
fold_range(irange & r,tree type,const irange & lh,const irange & rh) const139 range_operator::fold_range (irange &r, tree type,
140 			    const irange &lh,
141 			    const irange &rh) const
142 {
143   gcc_checking_assert (irange::supports_type_p (type));
144   if (empty_range_varying (r, type, lh, rh))
145     return true;
146 
147   unsigned num_lh = lh.num_pairs ();
148   unsigned num_rh = rh.num_pairs ();
149 
150   // If both ranges are single pairs, fold directly into the result range.
151   if (num_lh == 1 && num_rh == 1)
152     {
153       wi_fold (r, type, lh.lower_bound (0), lh.upper_bound (0),
154 	       rh.lower_bound (0), rh.upper_bound (0));
155       return true;
156     }
157 
158   int_range_max tmp;
159   r.set_undefined ();
160   for (unsigned x = 0; x < num_lh; ++x)
161     for (unsigned y = 0; y < num_rh; ++y)
162       {
163 	wide_int lh_lb = lh.lower_bound (x);
164 	wide_int lh_ub = lh.upper_bound (x);
165 	wide_int rh_lb = rh.lower_bound (y);
166 	wide_int rh_ub = rh.upper_bound (y);
167 	wi_fold (tmp, type, lh_lb, lh_ub, rh_lb, rh_ub);
168 	r.union_ (tmp);
169 	if (r.varying_p ())
170 	  return true;
171       }
172   return true;
173 }
174 
175 // The default for op1_range is to return false.
176 
177 bool
op1_range(irange & r ATTRIBUTE_UNUSED,tree type ATTRIBUTE_UNUSED,const irange & lhs ATTRIBUTE_UNUSED,const irange & op2 ATTRIBUTE_UNUSED) const178 range_operator::op1_range (irange &r ATTRIBUTE_UNUSED,
179 			   tree type ATTRIBUTE_UNUSED,
180 			   const irange &lhs ATTRIBUTE_UNUSED,
181 			   const irange &op2 ATTRIBUTE_UNUSED) const
182 {
183   return false;
184 }
185 
186 // The default for op2_range is to return false.
187 
188 bool
op2_range(irange & r ATTRIBUTE_UNUSED,tree type ATTRIBUTE_UNUSED,const irange & lhs ATTRIBUTE_UNUSED,const irange & op1 ATTRIBUTE_UNUSED) const189 range_operator::op2_range (irange &r ATTRIBUTE_UNUSED,
190 			   tree type ATTRIBUTE_UNUSED,
191 			   const irange &lhs ATTRIBUTE_UNUSED,
192 			   const irange &op1 ATTRIBUTE_UNUSED) const
193 {
194   return false;
195 }
196 
197 
198 // Create and return a range from a pair of wide-ints that are known
199 // to have overflowed (or underflowed).
200 
201 static void
value_range_from_overflowed_bounds(irange & r,tree type,const wide_int & wmin,const wide_int & wmax)202 value_range_from_overflowed_bounds (irange &r, tree type,
203 				    const wide_int &wmin,
204 				    const wide_int &wmax)
205 {
206   const signop sgn = TYPE_SIGN (type);
207   const unsigned int prec = TYPE_PRECISION (type);
208 
209   wide_int tmin = wide_int::from (wmin, prec, sgn);
210   wide_int tmax = wide_int::from (wmax, prec, sgn);
211 
212   bool covers = false;
213   wide_int tem = tmin;
214   tmin = tmax + 1;
215   if (wi::cmp (tmin, tmax, sgn) < 0)
216     covers = true;
217   tmax = tem - 1;
218   if (wi::cmp (tmax, tem, sgn) > 0)
219     covers = true;
220 
221   // If the anti-range would cover nothing, drop to varying.
222   // Likewise if the anti-range bounds are outside of the types
223   // values.
224   if (covers || wi::cmp (tmin, tmax, sgn) > 0)
225     r.set_varying (type);
226   else
227     {
228       tree tree_min = wide_int_to_tree (type, tmin);
229       tree tree_max = wide_int_to_tree (type, tmax);
230       r.set (tree_min, tree_max, VR_ANTI_RANGE);
231     }
232 }
233 
234 // Create and return a range from a pair of wide-ints.  MIN_OVF and
235 // MAX_OVF describe any overflow that might have occurred while
236 // calculating WMIN and WMAX respectively.
237 
238 static void
value_range_with_overflow(irange & r,tree type,const wide_int & wmin,const wide_int & wmax,wi::overflow_type min_ovf=wi::OVF_NONE,wi::overflow_type max_ovf=wi::OVF_NONE)239 value_range_with_overflow (irange &r, tree type,
240 			   const wide_int &wmin, const wide_int &wmax,
241 			   wi::overflow_type min_ovf = wi::OVF_NONE,
242 			   wi::overflow_type max_ovf = wi::OVF_NONE)
243 {
244   const signop sgn = TYPE_SIGN (type);
245   const unsigned int prec = TYPE_PRECISION (type);
246   const bool overflow_wraps = TYPE_OVERFLOW_WRAPS (type);
247 
248   // For one bit precision if max != min, then the range covers all
249   // values.
250   if (prec == 1 && wi::ne_p (wmax, wmin))
251     {
252       r.set_varying (type);
253       return;
254     }
255 
256   if (overflow_wraps)
257     {
258       // If overflow wraps, truncate the values and adjust the range,
259       // kind, and bounds appropriately.
260       if ((min_ovf != wi::OVF_NONE) == (max_ovf != wi::OVF_NONE))
261 	{
262 	  wide_int tmin = wide_int::from (wmin, prec, sgn);
263 	  wide_int tmax = wide_int::from (wmax, prec, sgn);
264 	  // If the limits are swapped, we wrapped around and cover
265 	  // the entire range.
266 	  if (wi::gt_p (tmin, tmax, sgn))
267 	    r.set_varying (type);
268 	  else
269 	    // No overflow or both overflow or underflow.  The range
270 	    // kind stays normal.
271 	    r.set (wide_int_to_tree (type, tmin),
272 		   wide_int_to_tree (type, tmax));
273 	  return;
274 	}
275 
276       if ((min_ovf == wi::OVF_UNDERFLOW && max_ovf == wi::OVF_NONE)
277 	  || (max_ovf == wi::OVF_OVERFLOW && min_ovf == wi::OVF_NONE))
278 	value_range_from_overflowed_bounds (r, type, wmin, wmax);
279       else
280 	// Other underflow and/or overflow, drop to VR_VARYING.
281 	r.set_varying (type);
282     }
283   else
284     {
285       // If both bounds either underflowed or overflowed, then the result
286       // is undefined.
287       if ((min_ovf == wi::OVF_OVERFLOW && max_ovf == wi::OVF_OVERFLOW)
288 	  || (min_ovf == wi::OVF_UNDERFLOW && max_ovf == wi::OVF_UNDERFLOW))
289 	{
290 	  r.set_undefined ();
291 	  return;
292 	}
293 
294       // If overflow does not wrap, saturate to [MIN, MAX].
295       wide_int new_lb, new_ub;
296       if (min_ovf == wi::OVF_UNDERFLOW)
297 	new_lb = wi::min_value (prec, sgn);
298       else if (min_ovf == wi::OVF_OVERFLOW)
299 	new_lb = wi::max_value (prec, sgn);
300       else
301         new_lb = wmin;
302 
303       if (max_ovf == wi::OVF_UNDERFLOW)
304 	new_ub = wi::min_value (prec, sgn);
305       else if (max_ovf == wi::OVF_OVERFLOW)
306 	new_ub = wi::max_value (prec, sgn);
307       else
308         new_ub = wmax;
309 
310       r.set (wide_int_to_tree (type, new_lb),
311 	     wide_int_to_tree (type, new_ub));
312     }
313 }
314 
315 // Create and return a range from a pair of wide-ints.  Canonicalize
316 // the case where the bounds are swapped.  In which case, we transform
317 // [10,5] into [MIN,5][10,MAX].
318 
319 static inline void
create_possibly_reversed_range(irange & r,tree type,const wide_int & new_lb,const wide_int & new_ub)320 create_possibly_reversed_range (irange &r, tree type,
321 				const wide_int &new_lb, const wide_int &new_ub)
322 {
323   signop s = TYPE_SIGN (type);
324   // If the bounds are swapped, treat the result as if an overflow occured.
325   if (wi::gt_p (new_lb, new_ub, s))
326     value_range_from_overflowed_bounds (r, type, new_lb, new_ub);
327   else
328     // Otherwise it's just a normal range.
329     r.set (wide_int_to_tree (type, new_lb), wide_int_to_tree (type, new_ub));
330 }
331 
332 // Return an irange instance that is a boolean TRUE.
333 
334 static inline int_range<1>
range_true(tree type)335 range_true (tree type)
336 {
337   unsigned prec = TYPE_PRECISION (type);
338   return int_range<1> (type, wi::one (prec), wi::one (prec));
339 }
340 
341 // Return an irange instance that is a boolean FALSE.
342 
343 static inline int_range<1>
range_false(tree type)344 range_false (tree type)
345 {
346   unsigned prec = TYPE_PRECISION (type);
347   return int_range<1> (type, wi::zero (prec), wi::zero (prec));
348 }
349 
350 // Return an irange that covers both true and false.
351 
352 static inline int_range<1>
range_true_and_false(tree type)353 range_true_and_false (tree type)
354 {
355   unsigned prec = TYPE_PRECISION (type);
356   return int_range<1> (type, wi::zero (prec), wi::one (prec));
357 }
358 
359 enum bool_range_state { BRS_FALSE, BRS_TRUE, BRS_EMPTY, BRS_FULL };
360 
361 // Return the summary information about boolean range LHS.  If EMPTY/FULL,
362 // return the equivalent range for TYPE in R; if FALSE/TRUE, do nothing.
363 
364 static bool_range_state
get_bool_state(irange & r,const irange & lhs,tree val_type)365 get_bool_state (irange &r, const irange &lhs, tree val_type)
366 {
367   // If there is no result, then this is unexecutable.
368   if (lhs.undefined_p ())
369     {
370       r.set_undefined ();
371       return BRS_EMPTY;
372     }
373 
374   if (lhs.zero_p ())
375     return BRS_FALSE;
376 
377   // For TRUE, we can't just test for [1,1] because Ada can have
378   // multi-bit booleans, and TRUE values can be: [1, MAX], ~[0], etc.
379   if (lhs.contains_p (build_zero_cst (lhs.type ())))
380     {
381       r.set_varying (val_type);
382       return BRS_FULL;
383     }
384 
385   return BRS_TRUE;
386 }
387 
388 
389 class operator_equal : public range_operator
390 {
391 public:
392   virtual bool fold_range (irange &r, tree type,
393 			   const irange &op1,
394 			   const irange &op2) const;
395   virtual bool op1_range (irange &r, tree type,
396 			  const irange &lhs,
397 			  const irange &val) const;
398   virtual bool op2_range (irange &r, tree type,
399 			  const irange &lhs,
400 			  const irange &val) const;
401 } op_equal;
402 
403 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2) const404 operator_equal::fold_range (irange &r, tree type,
405 			    const irange &op1,
406 			    const irange &op2) const
407 {
408   if (empty_range_varying (r, type, op1, op2))
409     return true;
410 
411   // We can be sure the values are always equal or not if both ranges
412   // consist of a single value, and then compare them.
413   if (wi::eq_p (op1.lower_bound (), op1.upper_bound ())
414       && wi::eq_p (op2.lower_bound (), op2.upper_bound ()))
415     {
416       if (wi::eq_p (op1.lower_bound (), op2.upper_bound()))
417 	r = range_true (type);
418       else
419 	r = range_false (type);
420     }
421   else
422     {
423       // If ranges do not intersect, we know the range is not equal,
424       // otherwise we don't know anything for sure.
425       int_range_max tmp = op1;
426       tmp.intersect (op2);
427       if (tmp.undefined_p ())
428 	r = range_false (type);
429       else
430 	r = range_true_and_false (type);
431     }
432   return true;
433 }
434 
435 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const436 operator_equal::op1_range (irange &r, tree type,
437 			   const irange &lhs,
438 			   const irange &op2) const
439 {
440   switch (get_bool_state (r, lhs, type))
441     {
442     case BRS_FALSE:
443       // If the result is false, the only time we know anything is
444       // if OP2 is a constant.
445       if (wi::eq_p (op2.lower_bound(), op2.upper_bound()))
446 	{
447 	  r = op2;
448 	  r.invert ();
449 	}
450       else
451 	r.set_varying (type);
452       break;
453 
454     case BRS_TRUE:
455       // If it's true, the result is the same as OP2.
456       r = op2;
457       break;
458 
459     default:
460       break;
461     }
462   return true;
463 }
464 
465 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1) const466 operator_equal::op2_range (irange &r, tree type,
467 			   const irange &lhs,
468 			   const irange &op1) const
469 {
470   return operator_equal::op1_range (r, type, lhs, op1);
471 }
472 
473 
474 class operator_not_equal : public range_operator
475 {
476 public:
477   virtual bool fold_range (irange &r, tree type,
478 			   const irange &op1,
479 			   const irange &op2) const;
480   virtual bool op1_range (irange &r, tree type,
481 			  const irange &lhs,
482 			  const irange &op2) const;
483   virtual bool op2_range (irange &r, tree type,
484 			  const irange &lhs,
485 			  const irange &op1) const;
486 } op_not_equal;
487 
488 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2) const489 operator_not_equal::fold_range (irange &r, tree type,
490 				const irange &op1,
491 				const irange &op2) const
492 {
493   if (empty_range_varying (r, type, op1, op2))
494     return true;
495 
496   // We can be sure the values are always equal or not if both ranges
497   // consist of a single value, and then compare them.
498   if (wi::eq_p (op1.lower_bound (), op1.upper_bound ())
499       && wi::eq_p (op2.lower_bound (), op2.upper_bound ()))
500     {
501       if (wi::ne_p (op1.lower_bound (), op2.upper_bound()))
502 	r = range_true (type);
503       else
504 	r = range_false (type);
505     }
506   else
507     {
508       // If ranges do not intersect, we know the range is not equal,
509       // otherwise we don't know anything for sure.
510       int_range_max tmp = op1;
511       tmp.intersect (op2);
512       if (tmp.undefined_p ())
513 	r = range_true (type);
514       else
515 	r = range_true_and_false (type);
516     }
517   return true;
518 }
519 
520 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const521 operator_not_equal::op1_range (irange &r, tree type,
522 			       const irange &lhs,
523 			       const irange &op2) const
524 {
525   switch (get_bool_state (r, lhs, type))
526     {
527     case BRS_TRUE:
528       // If the result is true, the only time we know anything is if
529       // OP2 is a constant.
530       if (wi::eq_p (op2.lower_bound(), op2.upper_bound()))
531 	{
532 	  r = op2;
533 	  r.invert ();
534 	}
535       else
536 	r.set_varying (type);
537       break;
538 
539     case BRS_FALSE:
540       // If it's false, the result is the same as OP2.
541       r = op2;
542       break;
543 
544     default:
545       break;
546     }
547   return true;
548 }
549 
550 
551 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1) const552 operator_not_equal::op2_range (irange &r, tree type,
553 			       const irange &lhs,
554 			       const irange &op1) const
555 {
556   return operator_not_equal::op1_range (r, type, lhs, op1);
557 }
558 
559 // (X < VAL) produces the range of [MIN, VAL - 1].
560 
561 static void
build_lt(irange & r,tree type,const wide_int & val)562 build_lt (irange &r, tree type, const wide_int &val)
563 {
564   wi::overflow_type ov;
565   wide_int lim;
566   signop sgn = TYPE_SIGN (type);
567 
568   // Signed 1 bit cannot represent 1 for subtraction.
569   if (sgn == SIGNED)
570     lim = wi::add (val, -1, sgn, &ov);
571   else
572     lim = wi::sub (val, 1, sgn, &ov);
573 
574   // If val - 1 underflows, check if X < MIN, which is an empty range.
575   if (ov)
576     r.set_undefined ();
577   else
578     r = int_range<1> (type, min_limit (type), lim);
579 }
580 
581 // (X <= VAL) produces the range of [MIN, VAL].
582 
583 static void
build_le(irange & r,tree type,const wide_int & val)584 build_le (irange &r, tree type, const wide_int &val)
585 {
586   r = int_range<1> (type, min_limit (type), val);
587 }
588 
589 // (X > VAL) produces the range of [VAL + 1, MAX].
590 
591 static void
build_gt(irange & r,tree type,const wide_int & val)592 build_gt (irange &r, tree type, const wide_int &val)
593 {
594   wi::overflow_type ov;
595   wide_int lim;
596   signop sgn = TYPE_SIGN (type);
597 
598   // Signed 1 bit cannot represent 1 for addition.
599   if (sgn == SIGNED)
600     lim = wi::sub (val, -1, sgn, &ov);
601   else
602     lim = wi::add (val, 1, sgn, &ov);
603   // If val + 1 overflows, check is for X > MAX, which is an empty range.
604   if (ov)
605     r.set_undefined ();
606   else
607     r = int_range<1> (type, lim, max_limit (type));
608 }
609 
610 // (X >= val) produces the range of [VAL, MAX].
611 
612 static void
build_ge(irange & r,tree type,const wide_int & val)613 build_ge (irange &r, tree type, const wide_int &val)
614 {
615   r = int_range<1> (type, val, max_limit (type));
616 }
617 
618 
619 class operator_lt :  public range_operator
620 {
621 public:
622   virtual bool fold_range (irange &r, tree type,
623 			   const irange &op1,
624 			   const irange &op2) const;
625   virtual bool op1_range (irange &r, tree type,
626 			  const irange &lhs,
627 			  const irange &op2) const;
628   virtual bool op2_range (irange &r, tree type,
629 			  const irange &lhs,
630 			  const irange &op1) const;
631 } op_lt;
632 
633 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2) const634 operator_lt::fold_range (irange &r, tree type,
635 			 const irange &op1,
636 			 const irange &op2) const
637 {
638   if (empty_range_varying (r, type, op1, op2))
639     return true;
640 
641   signop sign = TYPE_SIGN (op1.type ());
642   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
643 
644   if (wi::lt_p (op1.upper_bound (), op2.lower_bound (), sign))
645     r = range_true (type);
646   else if (!wi::lt_p (op1.lower_bound (), op2.upper_bound (), sign))
647     r = range_false (type);
648   else
649     r = range_true_and_false (type);
650   return true;
651 }
652 
653 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const654 operator_lt::op1_range (irange &r, tree type,
655 			const irange &lhs,
656 			const irange &op2) const
657 {
658   switch (get_bool_state (r, lhs, type))
659     {
660     case BRS_TRUE:
661       build_lt (r, type, op2.upper_bound ());
662       break;
663 
664     case BRS_FALSE:
665       build_ge (r, type, op2.lower_bound ());
666       break;
667 
668     default:
669       break;
670     }
671   return true;
672 }
673 
674 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1) const675 operator_lt::op2_range (irange &r, tree type,
676 			const irange &lhs,
677 			const irange &op1) const
678 {
679   switch (get_bool_state (r, lhs, type))
680     {
681     case BRS_FALSE:
682       build_le (r, type, op1.upper_bound ());
683       break;
684 
685     case BRS_TRUE:
686       build_gt (r, type, op1.lower_bound ());
687       break;
688 
689     default:
690       break;
691     }
692   return true;
693 }
694 
695 
696 class operator_le :  public range_operator
697 {
698 public:
699   virtual bool fold_range (irange &r, tree type,
700 			   const irange &op1,
701 			   const irange &op2) const;
702   virtual bool op1_range (irange &r, tree type,
703 			  const irange &lhs,
704 			  const irange &op2) const;
705   virtual bool op2_range (irange &r, tree type,
706 			  const irange &lhs,
707 			  const irange &op1) const;
708 } op_le;
709 
710 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2) const711 operator_le::fold_range (irange &r, tree type,
712 			 const irange &op1,
713 			 const irange &op2) const
714 {
715   if (empty_range_varying (r, type, op1, op2))
716     return true;
717 
718   signop sign = TYPE_SIGN (op1.type ());
719   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
720 
721   if (wi::le_p (op1.upper_bound (), op2.lower_bound (), sign))
722     r = range_true (type);
723   else if (!wi::le_p (op1.lower_bound (), op2.upper_bound (), sign))
724     r = range_false (type);
725   else
726     r = range_true_and_false (type);
727   return true;
728 }
729 
730 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const731 operator_le::op1_range (irange &r, tree type,
732 			const irange &lhs,
733 			const irange &op2) const
734 {
735   switch (get_bool_state (r, lhs, type))
736     {
737     case BRS_TRUE:
738       build_le (r, type, op2.upper_bound ());
739       break;
740 
741     case BRS_FALSE:
742       build_gt (r, type, op2.lower_bound ());
743       break;
744 
745     default:
746       break;
747     }
748   return true;
749 }
750 
751 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1) const752 operator_le::op2_range (irange &r, tree type,
753 			const irange &lhs,
754 			const irange &op1) const
755 {
756   switch (get_bool_state (r, lhs, type))
757     {
758     case BRS_FALSE:
759       build_lt (r, type, op1.upper_bound ());
760       break;
761 
762     case BRS_TRUE:
763       build_ge (r, type, op1.lower_bound ());
764       break;
765 
766     default:
767       break;
768     }
769   return true;
770 }
771 
772 
773 class operator_gt :  public range_operator
774 {
775 public:
776   virtual bool fold_range (irange &r, tree type,
777 			   const irange &op1,
778 			   const irange &op2) const;
779   virtual bool op1_range (irange &r, tree type,
780 			  const irange &lhs,
781 			  const irange &op2) const;
782   virtual bool op2_range (irange &r, tree type,
783 			  const irange &lhs,
784 			  const irange &op1) const;
785 } op_gt;
786 
787 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2) const788 operator_gt::fold_range (irange &r, tree type,
789 			 const irange &op1, const irange &op2) const
790 {
791   if (empty_range_varying (r, type, op1, op2))
792     return true;
793 
794   signop sign = TYPE_SIGN (op1.type ());
795   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
796 
797   if (wi::gt_p (op1.lower_bound (), op2.upper_bound (), sign))
798     r = range_true (type);
799   else if (!wi::gt_p (op1.upper_bound (), op2.lower_bound (), sign))
800     r = range_false (type);
801   else
802     r = range_true_and_false (type);
803   return true;
804 }
805 
806 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const807 operator_gt::op1_range (irange &r, tree type,
808 			const irange &lhs, const irange &op2) const
809 {
810   switch (get_bool_state (r, lhs, type))
811     {
812     case BRS_TRUE:
813       build_gt (r, type, op2.lower_bound ());
814       break;
815 
816     case BRS_FALSE:
817       build_le (r, type, op2.upper_bound ());
818       break;
819 
820     default:
821       break;
822     }
823   return true;
824 }
825 
826 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1) const827 operator_gt::op2_range (irange &r, tree type,
828 			const irange &lhs,
829 			const irange &op1) const
830 {
831   switch (get_bool_state (r, lhs, type))
832     {
833     case BRS_FALSE:
834       build_ge (r, type, op1.lower_bound ());
835       break;
836 
837     case BRS_TRUE:
838       build_lt (r, type, op1.upper_bound ());
839       break;
840 
841     default:
842       break;
843     }
844   return true;
845 }
846 
847 
848 class operator_ge :  public range_operator
849 {
850 public:
851   virtual bool fold_range (irange &r, tree type,
852 			   const irange &op1,
853 			   const irange &op2) const;
854   virtual bool op1_range (irange &r, tree type,
855 			  const irange &lhs,
856 			  const irange &op2) const;
857   virtual bool op2_range (irange &r, tree type,
858 			  const irange &lhs,
859 			  const irange &op1) const;
860 } op_ge;
861 
862 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2) const863 operator_ge::fold_range (irange &r, tree type,
864 			 const irange &op1,
865 			 const irange &op2) const
866 {
867   if (empty_range_varying (r, type, op1, op2))
868     return true;
869 
870   signop sign = TYPE_SIGN (op1.type ());
871   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
872 
873   if (wi::ge_p (op1.lower_bound (), op2.upper_bound (), sign))
874     r = range_true (type);
875   else if (!wi::ge_p (op1.upper_bound (), op2.lower_bound (), sign))
876     r = range_false (type);
877   else
878     r = range_true_and_false (type);
879   return true;
880 }
881 
882 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const883 operator_ge::op1_range (irange &r, tree type,
884 			const irange &lhs,
885 			const irange &op2) const
886 {
887   switch (get_bool_state (r, lhs, type))
888     {
889     case BRS_TRUE:
890       build_ge (r, type, op2.lower_bound ());
891       break;
892 
893     case BRS_FALSE:
894       build_lt (r, type, op2.upper_bound ());
895       break;
896 
897     default:
898       break;
899     }
900   return true;
901 }
902 
903 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1) const904 operator_ge::op2_range (irange &r, tree type,
905 			const irange &lhs,
906 			const irange &op1) const
907 {
908   switch (get_bool_state (r, lhs, type))
909     {
910     case BRS_FALSE:
911       build_gt (r, type, op1.lower_bound ());
912       break;
913 
914     case BRS_TRUE:
915       build_le (r, type, op1.upper_bound ());
916       break;
917 
918     default:
919       break;
920     }
921   return true;
922 }
923 
924 
925 class operator_plus : public range_operator
926 {
927 public:
928   virtual bool op1_range (irange &r, tree type,
929 			  const irange &lhs,
930 			  const irange &op2) const;
931   virtual bool op2_range (irange &r, tree type,
932 			  const irange &lhs,
933 			  const irange &op1) const;
934   virtual void wi_fold (irange &r, tree type,
935 		        const wide_int &lh_lb,
936 		        const wide_int &lh_ub,
937 		        const wide_int &rh_lb,
938 		        const wide_int &rh_ub) const;
939 } op_plus;
940 
941 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const942 operator_plus::wi_fold (irange &r, tree type,
943 			const wide_int &lh_lb, const wide_int &lh_ub,
944 			const wide_int &rh_lb, const wide_int &rh_ub) const
945 {
946   wi::overflow_type ov_lb, ov_ub;
947   signop s = TYPE_SIGN (type);
948   wide_int new_lb = wi::add (lh_lb, rh_lb, s, &ov_lb);
949   wide_int new_ub = wi::add (lh_ub, rh_ub, s, &ov_ub);
950   value_range_with_overflow (r, type, new_lb, new_ub, ov_lb, ov_ub);
951 }
952 
953 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const954 operator_plus::op1_range (irange &r, tree type,
955 			  const irange &lhs,
956 			  const irange &op2) const
957 {
958   return range_op_handler (MINUS_EXPR, type)->fold_range (r, type, lhs, op2);
959 }
960 
961 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1) const962 operator_plus::op2_range (irange &r, tree type,
963 			  const irange &lhs,
964 			  const irange &op1) const
965 {
966   return range_op_handler (MINUS_EXPR, type)->fold_range (r, type, lhs, op1);
967 }
968 
969 
970 class operator_minus : public range_operator
971 {
972 public:
973   virtual bool op1_range (irange &r, tree type,
974 			  const irange &lhs,
975 			  const irange &op2) const;
976   virtual bool op2_range (irange &r, tree type,
977 			  const irange &lhs,
978 			  const irange &op1) const;
979   virtual void wi_fold (irange &r, tree type,
980 		        const wide_int &lh_lb,
981 		        const wide_int &lh_ub,
982 		        const wide_int &rh_lb,
983 		        const wide_int &rh_ub) const;
984 } op_minus;
985 
986 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const987 operator_minus::wi_fold (irange &r, tree type,
988 			 const wide_int &lh_lb, const wide_int &lh_ub,
989 			 const wide_int &rh_lb, const wide_int &rh_ub) const
990 {
991   wi::overflow_type ov_lb, ov_ub;
992   signop s = TYPE_SIGN (type);
993   wide_int new_lb = wi::sub (lh_lb, rh_ub, s, &ov_lb);
994   wide_int new_ub = wi::sub (lh_ub, rh_lb, s, &ov_ub);
995   value_range_with_overflow (r, type, new_lb, new_ub, ov_lb, ov_ub);
996 }
997 
998 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const999 operator_minus::op1_range (irange &r, tree type,
1000 			   const irange &lhs,
1001 			   const irange &op2) const
1002 {
1003   return range_op_handler (PLUS_EXPR, type)->fold_range (r, type, lhs, op2);
1004 }
1005 
1006 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1) const1007 operator_minus::op2_range (irange &r, tree type,
1008 			   const irange &lhs,
1009 			   const irange &op1) const
1010 {
1011   return fold_range (r, type, op1, lhs);
1012 }
1013 
1014 
1015 class operator_min : public range_operator
1016 {
1017 public:
1018   virtual void wi_fold (irange &r, tree type,
1019 		        const wide_int &lh_lb,
1020 		        const wide_int &lh_ub,
1021 		        const wide_int &rh_lb,
1022 		        const wide_int &rh_ub) const;
1023 } op_min;
1024 
1025 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const1026 operator_min::wi_fold (irange &r, tree type,
1027 		       const wide_int &lh_lb, const wide_int &lh_ub,
1028 		       const wide_int &rh_lb, const wide_int &rh_ub) const
1029 {
1030   signop s = TYPE_SIGN (type);
1031   wide_int new_lb = wi::min (lh_lb, rh_lb, s);
1032   wide_int new_ub = wi::min (lh_ub, rh_ub, s);
1033   value_range_with_overflow (r, type, new_lb, new_ub);
1034 }
1035 
1036 
1037 class operator_max : public range_operator
1038 {
1039 public:
1040   virtual void wi_fold (irange &r, tree type,
1041 		        const wide_int &lh_lb,
1042 		        const wide_int &lh_ub,
1043 		        const wide_int &rh_lb,
1044 		        const wide_int &rh_ub) const;
1045 } op_max;
1046 
1047 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const1048 operator_max::wi_fold (irange &r, tree type,
1049 		       const wide_int &lh_lb, const wide_int &lh_ub,
1050 		       const wide_int &rh_lb, const wide_int &rh_ub) const
1051 {
1052   signop s = TYPE_SIGN (type);
1053   wide_int new_lb = wi::max (lh_lb, rh_lb, s);
1054   wide_int new_ub = wi::max (lh_ub, rh_ub, s);
1055   value_range_with_overflow (r, type, new_lb, new_ub);
1056 }
1057 
1058 
1059 class cross_product_operator : public range_operator
1060 {
1061 public:
1062   // Perform an operation between two wide-ints and place the result
1063   // in R.  Return true if the operation overflowed.
1064   virtual bool wi_op_overflows (wide_int &r,
1065 				tree type,
1066 				const wide_int &,
1067 				const wide_int &) const = 0;
1068 
1069   // Calculate the cross product of two sets of sub-ranges and return it.
1070   void wi_cross_product (irange &r, tree type,
1071 			 const wide_int &lh_lb,
1072 			 const wide_int &lh_ub,
1073 			 const wide_int &rh_lb,
1074 			 const wide_int &rh_ub) const;
1075 };
1076 
1077 // Calculate the cross product of two sets of ranges and return it.
1078 //
1079 // Multiplications, divisions and shifts are a bit tricky to handle,
1080 // depending on the mix of signs we have in the two ranges, we need to
1081 // operate on different values to get the minimum and maximum values
1082 // for the new range.  One approach is to figure out all the
1083 // variations of range combinations and do the operations.
1084 //
1085 // However, this involves several calls to compare_values and it is
1086 // pretty convoluted.  It's simpler to do the 4 operations (MIN0 OP
1087 // MIN1, MIN0 OP MAX1, MAX0 OP MIN1 and MAX0 OP MAX0 OP MAX1) and then
1088 // figure the smallest and largest values to form the new range.
1089 
1090 void
wi_cross_product(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const1091 cross_product_operator::wi_cross_product (irange &r, tree type,
1092 					  const wide_int &lh_lb,
1093 					  const wide_int &lh_ub,
1094 					  const wide_int &rh_lb,
1095 					  const wide_int &rh_ub) const
1096 {
1097   wide_int cp1, cp2, cp3, cp4;
1098   // Default to varying.
1099   r.set_varying (type);
1100 
1101   // Compute the 4 cross operations, bailing if we get an overflow we
1102   // can't handle.
1103   if (wi_op_overflows (cp1, type, lh_lb, rh_lb))
1104     return;
1105   if (wi::eq_p (lh_lb, lh_ub))
1106     cp3 = cp1;
1107   else if (wi_op_overflows (cp3, type, lh_ub, rh_lb))
1108     return;
1109   if (wi::eq_p (rh_lb, rh_ub))
1110     cp2 = cp1;
1111   else if (wi_op_overflows (cp2, type, lh_lb, rh_ub))
1112     return;
1113   if (wi::eq_p (lh_lb, lh_ub))
1114     cp4 = cp2;
1115   else if (wi_op_overflows (cp4, type, lh_ub, rh_ub))
1116     return;
1117 
1118   // Order pairs.
1119   signop sign = TYPE_SIGN (type);
1120   if (wi::gt_p (cp1, cp2, sign))
1121     std::swap (cp1, cp2);
1122   if (wi::gt_p (cp3, cp4, sign))
1123     std::swap (cp3, cp4);
1124 
1125   // Choose min and max from the ordered pairs.
1126   wide_int res_lb = wi::min (cp1, cp3, sign);
1127   wide_int res_ub = wi::max (cp2, cp4, sign);
1128   value_range_with_overflow (r, type, res_lb, res_ub);
1129 }
1130 
1131 
1132 class operator_mult : public cross_product_operator
1133 {
1134 public:
1135   virtual void wi_fold (irange &r, tree type,
1136 		        const wide_int &lh_lb,
1137 		        const wide_int &lh_ub,
1138 		        const wide_int &rh_lb,
1139 		        const wide_int &rh_ub) const;
1140   virtual bool wi_op_overflows (wide_int &res, tree type,
1141 				const wide_int &w0, const wide_int &w1) const;
1142   virtual bool op1_range (irange &r, tree type,
1143 			  const irange &lhs,
1144 			  const irange &op2) const;
1145   virtual bool op2_range (irange &r, tree type,
1146 			  const irange &lhs,
1147 			  const irange &op1) const;
1148 } op_mult;
1149 
1150 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const1151 operator_mult::op1_range (irange &r, tree type,
1152 			  const irange &lhs, const irange &op2) const
1153 {
1154   tree offset;
1155 
1156   // We can't solve 0 = OP1 * N by dividing by N with a wrapping type.
1157   // For example: For 0 = OP1 * 2, OP1 could be 0, or MAXINT, whereas
1158   // for 4 = OP1 * 2, OP1 could be 2 or 130 (unsigned 8-bit)
1159   if (TYPE_OVERFLOW_WRAPS (type))
1160     return false;
1161 
1162   if (op2.singleton_p (&offset) && !integer_zerop (offset))
1163     return range_op_handler (TRUNC_DIV_EXPR, type)->fold_range (r, type,
1164 								lhs, op2);
1165   return false;
1166 }
1167 
1168 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1) const1169 operator_mult::op2_range (irange &r, tree type,
1170 			  const irange &lhs, const irange &op1) const
1171 {
1172   return operator_mult::op1_range (r, type, lhs, op1);
1173 }
1174 
1175 bool
wi_op_overflows(wide_int & res,tree type,const wide_int & w0,const wide_int & w1) const1176 operator_mult::wi_op_overflows (wide_int &res, tree type,
1177 				const wide_int &w0, const wide_int &w1) const
1178 {
1179   wi::overflow_type overflow = wi::OVF_NONE;
1180   signop sign = TYPE_SIGN (type);
1181   res = wi::mul (w0, w1, sign, &overflow);
1182    if (overflow && TYPE_OVERFLOW_UNDEFINED (type))
1183      {
1184        // For multiplication, the sign of the overflow is given
1185        // by the comparison of the signs of the operands.
1186        if (sign == UNSIGNED || w0.sign_mask () == w1.sign_mask ())
1187 	 res = wi::max_value (w0.get_precision (), sign);
1188        else
1189 	 res = wi::min_value (w0.get_precision (), sign);
1190        return false;
1191      }
1192    return overflow;
1193 }
1194 
1195 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const1196 operator_mult::wi_fold (irange &r, tree type,
1197 			const wide_int &lh_lb, const wide_int &lh_ub,
1198 			const wide_int &rh_lb, const wide_int &rh_ub) const
1199 {
1200   if (TYPE_OVERFLOW_UNDEFINED (type))
1201     {
1202       wi_cross_product (r, type, lh_lb, lh_ub, rh_lb, rh_ub);
1203       return;
1204     }
1205 
1206   // Multiply the ranges when overflow wraps.  This is basically fancy
1207   // code so we don't drop to varying with an unsigned
1208   // [-3,-1]*[-3,-1].
1209   //
1210   // This test requires 2*prec bits if both operands are signed and
1211   // 2*prec + 2 bits if either is not.  Therefore, extend the values
1212   // using the sign of the result to PREC2.  From here on out,
1213   // everthing is just signed math no matter what the input types
1214   // were.
1215 
1216   signop sign = TYPE_SIGN (type);
1217   unsigned prec = TYPE_PRECISION (type);
1218   widest2_int min0 = widest2_int::from (lh_lb, sign);
1219   widest2_int max0 = widest2_int::from (lh_ub, sign);
1220   widest2_int min1 = widest2_int::from (rh_lb, sign);
1221   widest2_int max1 = widest2_int::from (rh_ub, sign);
1222   widest2_int sizem1 = wi::mask <widest2_int> (prec, false);
1223   widest2_int size = sizem1 + 1;
1224 
1225   // Canonicalize the intervals.
1226   if (sign == UNSIGNED)
1227     {
1228       if (wi::ltu_p (size, min0 + max0))
1229 	{
1230 	  min0 -= size;
1231 	  max0 -= size;
1232 	}
1233       if (wi::ltu_p (size, min1 + max1))
1234 	{
1235 	  min1 -= size;
1236 	  max1 -= size;
1237 	}
1238     }
1239 
1240   // Sort the 4 products so that min is in prod0 and max is in
1241   // prod3.
1242   widest2_int prod0 = min0 * min1;
1243   widest2_int prod1 = min0 * max1;
1244   widest2_int prod2 = max0 * min1;
1245   widest2_int prod3 = max0 * max1;
1246 
1247   // min0min1 > max0max1
1248   if (prod0 > prod3)
1249     std::swap (prod0, prod3);
1250 
1251   // min0max1 > max0min1
1252   if (prod1 > prod2)
1253     std::swap (prod1, prod2);
1254 
1255   if (prod0 > prod1)
1256     std::swap (prod0, prod1);
1257 
1258   if (prod2 > prod3)
1259     std::swap (prod2, prod3);
1260 
1261   // diff = max - min
1262   prod2 = prod3 - prod0;
1263   if (wi::geu_p (prod2, sizem1))
1264     // The range covers all values.
1265     r.set_varying (type);
1266   else
1267     {
1268       wide_int new_lb = wide_int::from (prod0, prec, sign);
1269       wide_int new_ub = wide_int::from (prod3, prec, sign);
1270       create_possibly_reversed_range (r, type, new_lb, new_ub);
1271     }
1272 }
1273 
1274 
1275 class operator_div : public cross_product_operator
1276 {
1277 public:
operator_div(enum tree_code c)1278   operator_div (enum tree_code c)  { code = c; }
1279   virtual void wi_fold (irange &r, tree type,
1280 		        const wide_int &lh_lb,
1281 		        const wide_int &lh_ub,
1282 		        const wide_int &rh_lb,
1283 		        const wide_int &rh_ub) const;
1284   virtual bool wi_op_overflows (wide_int &res, tree type,
1285 				const wide_int &, const wide_int &) const;
1286 private:
1287   enum tree_code code;
1288 };
1289 
1290 bool
wi_op_overflows(wide_int & res,tree type,const wide_int & w0,const wide_int & w1) const1291 operator_div::wi_op_overflows (wide_int &res, tree type,
1292 			       const wide_int &w0, const wide_int &w1) const
1293 {
1294   if (w1 == 0)
1295     return true;
1296 
1297   wi::overflow_type overflow = wi::OVF_NONE;
1298   signop sign = TYPE_SIGN (type);
1299 
1300   switch (code)
1301     {
1302     case EXACT_DIV_EXPR:
1303       // EXACT_DIV_EXPR is implemented as TRUNC_DIV_EXPR in
1304       // operator_exact_divide.  No need to handle it here.
1305       gcc_unreachable ();
1306       break;
1307     case TRUNC_DIV_EXPR:
1308       res = wi::div_trunc (w0, w1, sign, &overflow);
1309       break;
1310     case FLOOR_DIV_EXPR:
1311       res = wi::div_floor (w0, w1, sign, &overflow);
1312       break;
1313     case ROUND_DIV_EXPR:
1314       res = wi::div_round (w0, w1, sign, &overflow);
1315       break;
1316     case CEIL_DIV_EXPR:
1317       res = wi::div_ceil (w0, w1, sign, &overflow);
1318       break;
1319     default:
1320       gcc_unreachable ();
1321     }
1322 
1323   if (overflow && TYPE_OVERFLOW_UNDEFINED (type))
1324     {
1325       // For division, the only case is -INF / -1 = +INF.
1326       res = wi::max_value (w0.get_precision (), sign);
1327       return false;
1328     }
1329   return overflow;
1330 }
1331 
1332 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const1333 operator_div::wi_fold (irange &r, tree type,
1334 		       const wide_int &lh_lb, const wide_int &lh_ub,
1335 		       const wide_int &rh_lb, const wide_int &rh_ub) const
1336 {
1337   // If we know we will divide by zero...
1338   if (rh_lb == 0 && rh_ub == 0)
1339     {
1340       r.set_varying (type);
1341       return;
1342     }
1343 
1344   const wide_int dividend_min = lh_lb;
1345   const wide_int dividend_max = lh_ub;
1346   const wide_int divisor_min = rh_lb;
1347   const wide_int divisor_max = rh_ub;
1348   signop sign = TYPE_SIGN (type);
1349   unsigned prec = TYPE_PRECISION (type);
1350   wide_int extra_min, extra_max;
1351 
1352   // If we know we won't divide by zero, just do the division.
1353   if (!wi_includes_zero_p (type, divisor_min, divisor_max))
1354     {
1355       wi_cross_product (r, type, dividend_min, dividend_max,
1356 		       divisor_min, divisor_max);
1357       return;
1358     }
1359 
1360   // If flag_non_call_exceptions, we must not eliminate a division by zero.
1361   if (cfun->can_throw_non_call_exceptions)
1362     {
1363       r.set_varying (type);
1364       return;
1365     }
1366 
1367   // If we're definitely dividing by zero, there's nothing to do.
1368   if (wi_zero_p (type, divisor_min, divisor_max))
1369     {
1370       r.set_varying (type);
1371       return;
1372     }
1373 
1374   // Perform the division in 2 parts, [LB, -1] and [1, UB], which will
1375   // skip any division by zero.
1376 
1377   // First divide by the negative numbers, if any.
1378   if (wi::neg_p (divisor_min, sign))
1379     wi_cross_product (r, type, dividend_min, dividend_max,
1380 		      divisor_min, wi::minus_one (prec));
1381   else
1382     r.set_undefined ();
1383 
1384   // Then divide by the non-zero positive numbers, if any.
1385   if (wi::gt_p (divisor_max, wi::zero (prec), sign))
1386     {
1387       int_range_max tmp;
1388       wi_cross_product (tmp, type, dividend_min, dividend_max,
1389 			wi::one (prec), divisor_max);
1390       r.union_ (tmp);
1391     }
1392   // We shouldn't still have undefined here.
1393   gcc_checking_assert (!r.undefined_p ());
1394 }
1395 
1396 operator_div op_trunc_div (TRUNC_DIV_EXPR);
1397 operator_div op_floor_div (FLOOR_DIV_EXPR);
1398 operator_div op_round_div (ROUND_DIV_EXPR);
1399 operator_div op_ceil_div (CEIL_DIV_EXPR);
1400 
1401 
1402 class operator_exact_divide : public operator_div
1403 {
1404 public:
operator_exact_divide()1405   operator_exact_divide () : operator_div (TRUNC_DIV_EXPR) { }
1406   virtual bool op1_range (irange &r, tree type,
1407 			  const irange &lhs,
1408 			  const irange &op2) const;
1409 
1410 } op_exact_div;
1411 
1412 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const1413 operator_exact_divide::op1_range (irange &r, tree type,
1414 				  const irange &lhs,
1415 				  const irange &op2) const
1416 {
1417   tree offset;
1418   // [2, 4] = op1 / [3,3]   since its exact divide, no need to worry about
1419   // remainders in the endpoints, so op1 = [2,4] * [3,3] = [6,12].
1420   // We wont bother trying to enumerate all the in between stuff :-P
1421   // TRUE accuraacy is [6,6][9,9][12,12].  This is unlikely to matter most of
1422   // the time however.
1423   // If op2 is a multiple of 2, we would be able to set some non-zero bits.
1424   if (op2.singleton_p (&offset)
1425       && !integer_zerop (offset))
1426     return range_op_handler (MULT_EXPR, type)->fold_range (r, type, lhs, op2);
1427   return false;
1428 }
1429 
1430 
1431 class operator_lshift : public cross_product_operator
1432 {
1433 public:
1434   virtual bool op1_range (irange &r, tree type,
1435 			  const irange &lhs,
1436 			  const irange &op2) const;
1437   virtual bool fold_range (irange &r, tree type,
1438 			   const irange &op1,
1439 			   const irange &op2) const;
1440 
1441   virtual void wi_fold (irange &r, tree type,
1442 			const wide_int &lh_lb, const wide_int &lh_ub,
1443 			const wide_int &rh_lb, const wide_int &rh_ub) const;
1444   virtual bool wi_op_overflows (wide_int &res,
1445 				tree type,
1446 				const wide_int &,
1447 				const wide_int &) const;
1448 } op_lshift;
1449 
1450 class operator_rshift : public cross_product_operator
1451 {
1452 public:
1453   virtual bool fold_range (irange &r, tree type,
1454 			   const irange &op1,
1455 			   const irange &op2) const;
1456   virtual void wi_fold (irange &r, tree type,
1457 			const wide_int &lh_lb,
1458 			const wide_int &lh_ub,
1459 			const wide_int &rh_lb,
1460 			const wide_int &rh_ub) const;
1461   virtual bool wi_op_overflows (wide_int &res,
1462 				tree type,
1463 				const wide_int &w0,
1464 				const wide_int &w1) const;
1465   virtual bool op1_range (irange &, tree type,
1466 			  const irange &lhs,
1467 			  const irange &op2) const;
1468 } op_rshift;
1469 
1470 
1471 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2) const1472 operator_lshift::fold_range (irange &r, tree type,
1473 			     const irange &op1,
1474 			     const irange &op2) const
1475 {
1476   int_range_max shift_range;
1477   if (!get_shift_range (shift_range, type, op2))
1478     {
1479       if (op2.undefined_p ())
1480 	r.set_undefined ();
1481       else
1482 	r.set_varying (type);
1483       return true;
1484     }
1485 
1486   // Transform left shifts by constants into multiplies.
1487   if (shift_range.singleton_p ())
1488     {
1489       unsigned shift = shift_range.lower_bound ().to_uhwi ();
1490       wide_int tmp = wi::set_bit_in_zero (shift, TYPE_PRECISION (type));
1491       int_range<1> mult (type, tmp, tmp);
1492 
1493       // Force wrapping multiplication.
1494       bool saved_flag_wrapv = flag_wrapv;
1495       bool saved_flag_wrapv_pointer = flag_wrapv_pointer;
1496       flag_wrapv = 1;
1497       flag_wrapv_pointer = 1;
1498       bool b = op_mult.fold_range (r, type, op1, mult);
1499       flag_wrapv = saved_flag_wrapv;
1500       flag_wrapv_pointer = saved_flag_wrapv_pointer;
1501       return b;
1502     }
1503   else
1504     // Otherwise, invoke the generic fold routine.
1505     return range_operator::fold_range (r, type, op1, shift_range);
1506 }
1507 
1508 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const1509 operator_lshift::wi_fold (irange &r, tree type,
1510 			  const wide_int &lh_lb, const wide_int &lh_ub,
1511 			  const wide_int &rh_lb, const wide_int &rh_ub) const
1512 {
1513   signop sign = TYPE_SIGN (type);
1514   unsigned prec = TYPE_PRECISION (type);
1515   int overflow_pos = sign == SIGNED ? prec - 1 : prec;
1516   int bound_shift = overflow_pos - rh_ub.to_shwi ();
1517   // If bound_shift == HOST_BITS_PER_WIDE_INT, the llshift can
1518   // overflow.  However, for that to happen, rh.max needs to be zero,
1519   // which means rh is a singleton range of zero, which means it
1520   // should be handled by the lshift fold_range above.
1521   wide_int bound = wi::set_bit_in_zero (bound_shift, prec);
1522   wide_int complement = ~(bound - 1);
1523   wide_int low_bound, high_bound;
1524   bool in_bounds = false;
1525 
1526   if (sign == UNSIGNED)
1527     {
1528       low_bound = bound;
1529       high_bound = complement;
1530       if (wi::ltu_p (lh_ub, low_bound))
1531 	{
1532 	  // [5, 6] << [1, 2] == [10, 24].
1533 	  // We're shifting out only zeroes, the value increases
1534 	  // monotonically.
1535 	  in_bounds = true;
1536 	}
1537       else if (wi::ltu_p (high_bound, lh_lb))
1538 	{
1539 	  // [0xffffff00, 0xffffffff] << [1, 2]
1540 	  // == [0xfffffc00, 0xfffffffe].
1541 	  // We're shifting out only ones, the value decreases
1542 	  // monotonically.
1543 	  in_bounds = true;
1544 	}
1545     }
1546   else
1547     {
1548       // [-1, 1] << [1, 2] == [-4, 4]
1549       low_bound = complement;
1550       high_bound = bound;
1551       if (wi::lts_p (lh_ub, high_bound)
1552 	  && wi::lts_p (low_bound, lh_lb))
1553 	{
1554 	  // For non-negative numbers, we're shifting out only zeroes,
1555 	  // the value increases monotonically.  For negative numbers,
1556 	  // we're shifting out only ones, the value decreases
1557 	  // monotonically.
1558 	  in_bounds = true;
1559 	}
1560     }
1561 
1562   if (in_bounds)
1563     wi_cross_product (r, type, lh_lb, lh_ub, rh_lb, rh_ub);
1564   else
1565    r.set_varying (type);
1566 }
1567 
1568 bool
wi_op_overflows(wide_int & res,tree type,const wide_int & w0,const wide_int & w1) const1569 operator_lshift::wi_op_overflows (wide_int &res, tree type,
1570 				  const wide_int &w0, const wide_int &w1) const
1571 {
1572   signop sign = TYPE_SIGN (type);
1573   if (wi::neg_p (w1))
1574     {
1575       // It's unclear from the C standard whether shifts can overflow.
1576       // The following code ignores overflow; perhaps a C standard
1577       // interpretation ruling is needed.
1578       res = wi::rshift (w0, -w1, sign);
1579     }
1580   else
1581     res = wi::lshift (w0, w1);
1582   return false;
1583 }
1584 
1585 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const1586 operator_lshift::op1_range (irange &r,
1587 			    tree type,
1588 			    const irange &lhs,
1589 			    const irange &op2) const
1590 {
1591   tree shift_amount;
1592   if (op2.singleton_p (&shift_amount))
1593     {
1594       wide_int shift = wi::to_wide (shift_amount);
1595       if (wi::lt_p (shift, 0, SIGNED))
1596 	return false;
1597       if (wi::ge_p (shift, wi::uhwi (TYPE_PRECISION (type),
1598 				     TYPE_PRECISION (op2.type ())),
1599 		    UNSIGNED))
1600 	return false;
1601       if (shift == 0)
1602 	{
1603 	  r = lhs;
1604 	  return true;
1605 	}
1606 
1607       // Work completely in unsigned mode to start.
1608       tree utype = type;
1609       if (TYPE_SIGN (type) == SIGNED)
1610 	{
1611 	  int_range_max tmp = lhs;
1612 	  utype = unsigned_type_for (type);
1613 	  range_cast (tmp, utype);
1614 	  op_rshift.fold_range (r, utype, tmp, op2);
1615 	}
1616       else
1617 	op_rshift.fold_range (r, utype, lhs, op2);
1618 
1619       // Start with ranges which can produce the LHS by right shifting the
1620       // result by the shift amount.
1621       // ie   [0x08, 0xF0] = op1 << 2 will start with
1622       //      [00001000, 11110000] = op1 << 2
1623       //  [0x02, 0x4C] aka [00000010, 00111100]
1624 
1625       // Then create a range from the LB with the least significant upper bit
1626       // set, to the upper bound with all the bits set.
1627       // This would be [0x42, 0xFC] aka [01000010, 11111100].
1628 
1629       // Ideally we do this for each subrange, but just lump them all for now.
1630       unsigned low_bits = TYPE_PRECISION (utype)
1631 			  - TREE_INT_CST_LOW (shift_amount);
1632       wide_int up_mask = wi::mask (low_bits, true, TYPE_PRECISION (utype));
1633       wide_int new_ub = wi::bit_or (up_mask, r.upper_bound ());
1634       wide_int new_lb = wi::set_bit (r.lower_bound (), low_bits);
1635       int_range<2> fill_range (utype, new_lb, new_ub);
1636       r.union_ (fill_range);
1637 
1638       if (utype != type)
1639 	range_cast (r, type);
1640       return true;
1641     }
1642   return false;
1643 }
1644 
1645 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const1646 operator_rshift::op1_range (irange &r,
1647 			    tree type,
1648 			    const irange &lhs,
1649 			    const irange &op2) const
1650 {
1651   tree shift;
1652   if (op2.singleton_p (&shift))
1653     {
1654       // Ignore nonsensical shifts.
1655       unsigned prec = TYPE_PRECISION (type);
1656       if (wi::ge_p (wi::to_wide (shift),
1657 		    wi::uhwi (prec, TYPE_PRECISION (TREE_TYPE (shift))),
1658 		    UNSIGNED))
1659 	return false;
1660       if (wi::to_wide (shift) == 0)
1661 	{
1662 	  r = lhs;
1663 	  return true;
1664 	}
1665 
1666       // Folding the original operation may discard some impossible
1667       // ranges from the LHS.
1668       int_range_max lhs_refined;
1669       op_rshift.fold_range (lhs_refined, type, int_range<1> (type), op2);
1670       lhs_refined.intersect (lhs);
1671       if (lhs_refined.undefined_p ())
1672 	{
1673 	  r.set_undefined ();
1674 	  return true;
1675 	}
1676       int_range_max shift_range (shift, shift);
1677       int_range_max lb, ub;
1678       op_lshift.fold_range (lb, type, lhs_refined, shift_range);
1679       //    LHS
1680       // 0000 0111 = OP1 >> 3
1681       //
1682       // OP1 is anything from 0011 1000 to 0011 1111.  That is, a
1683       // range from LHS<<3 plus a mask of the 3 bits we shifted on the
1684       // right hand side (0x07).
1685       tree mask = fold_build1 (BIT_NOT_EXPR, type,
1686 			       fold_build2 (LSHIFT_EXPR, type,
1687 					    build_minus_one_cst (type),
1688 					    shift));
1689       int_range_max mask_range (build_zero_cst (type), mask);
1690       op_plus.fold_range (ub, type, lb, mask_range);
1691       r = lb;
1692       r.union_ (ub);
1693       if (!lhs_refined.contains_p (build_zero_cst (type)))
1694 	{
1695 	  mask_range.invert ();
1696 	  r.intersect (mask_range);
1697 	}
1698       return true;
1699     }
1700   return false;
1701 }
1702 
1703 bool
wi_op_overflows(wide_int & res,tree type,const wide_int & w0,const wide_int & w1) const1704 operator_rshift::wi_op_overflows (wide_int &res,
1705 				  tree type,
1706 				  const wide_int &w0,
1707 				  const wide_int &w1) const
1708 {
1709   signop sign = TYPE_SIGN (type);
1710   if (wi::neg_p (w1))
1711     res = wi::lshift (w0, -w1);
1712   else
1713     {
1714       // It's unclear from the C standard whether shifts can overflow.
1715       // The following code ignores overflow; perhaps a C standard
1716       // interpretation ruling is needed.
1717       res = wi::rshift (w0, w1, sign);
1718     }
1719   return false;
1720 }
1721 
1722 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2) const1723 operator_rshift::fold_range (irange &r, tree type,
1724 			     const irange &op1,
1725 			     const irange &op2) const
1726 {
1727   int_range_max shift;
1728   if (!get_shift_range (shift, type, op2))
1729     {
1730       if (op2.undefined_p ())
1731 	r.set_undefined ();
1732       else
1733 	r.set_varying (type);
1734       return true;
1735     }
1736 
1737   return range_operator::fold_range (r, type, op1, shift);
1738 }
1739 
1740 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const1741 operator_rshift::wi_fold (irange &r, tree type,
1742 			  const wide_int &lh_lb, const wide_int &lh_ub,
1743 			  const wide_int &rh_lb, const wide_int &rh_ub) const
1744 {
1745   wi_cross_product (r, type, lh_lb, lh_ub, rh_lb, rh_ub);
1746 }
1747 
1748 
1749 class operator_cast: public range_operator
1750 {
1751 public:
1752   virtual bool fold_range (irange &r, tree type,
1753 			   const irange &op1,
1754 			   const irange &op2) const;
1755   virtual bool op1_range (irange &r, tree type,
1756 			  const irange &lhs,
1757 			  const irange &op2) const;
1758 private:
1759   bool truncating_cast_p (const irange &inner, const irange &outer) const;
1760   bool inside_domain_p (const wide_int &min, const wide_int &max,
1761 			const irange &outer) const;
1762   void fold_pair (irange &r, unsigned index, const irange &inner,
1763 			   const irange &outer) const;
1764 } op_convert;
1765 
1766 // Return TRUE if casting from INNER to OUTER is a truncating cast.
1767 
1768 inline bool
truncating_cast_p(const irange & inner,const irange & outer) const1769 operator_cast::truncating_cast_p (const irange &inner,
1770 				  const irange &outer) const
1771 {
1772   return TYPE_PRECISION (outer.type ()) < TYPE_PRECISION (inner.type ());
1773 }
1774 
1775 // Return TRUE if [MIN,MAX] is inside the domain of RANGE's type.
1776 
1777 bool
inside_domain_p(const wide_int & min,const wide_int & max,const irange & range) const1778 operator_cast::inside_domain_p (const wide_int &min,
1779 				const wide_int &max,
1780 				const irange &range) const
1781 {
1782   wide_int domain_min = wi::to_wide (vrp_val_min (range.type ()));
1783   wide_int domain_max = wi::to_wide (vrp_val_max (range.type ()));
1784   signop domain_sign = TYPE_SIGN (range.type ());
1785   return (wi::le_p (min, domain_max, domain_sign)
1786 	  && wi::le_p (max, domain_max, domain_sign)
1787 	  && wi::ge_p (min, domain_min, domain_sign)
1788 	  && wi::ge_p (max, domain_min, domain_sign));
1789 }
1790 
1791 
1792 // Helper for fold_range which work on a pair at a time.
1793 
1794 void
fold_pair(irange & r,unsigned index,const irange & inner,const irange & outer) const1795 operator_cast::fold_pair (irange &r, unsigned index,
1796 			   const irange &inner,
1797 			   const irange &outer) const
1798 {
1799   tree inner_type = inner.type ();
1800   tree outer_type = outer.type ();
1801   signop inner_sign = TYPE_SIGN (inner_type);
1802   unsigned outer_prec = TYPE_PRECISION (outer_type);
1803 
1804   // check to see if casting from INNER to OUTER is a conversion that
1805   // fits in the resulting OUTER type.
1806   wide_int inner_lb = inner.lower_bound (index);
1807   wide_int inner_ub = inner.upper_bound (index);
1808   if (truncating_cast_p (inner, outer))
1809     {
1810       // We may be able to accomodate a truncating cast if the
1811       // resulting range can be represented in the target type...
1812       if (wi::rshift (wi::sub (inner_ub, inner_lb),
1813 		      wi::uhwi (outer_prec, TYPE_PRECISION (inner.type ())),
1814 				inner_sign) != 0)
1815 	{
1816 	  r.set_varying (outer_type);
1817 	  return;
1818 	}
1819     }
1820   // ...but we must still verify that the final range fits in the
1821   // domain.  This catches -fstrict-enum restrictions where the domain
1822   // range is smaller than what fits in the underlying type.
1823   wide_int min = wide_int::from (inner_lb, outer_prec, inner_sign);
1824   wide_int max = wide_int::from (inner_ub, outer_prec, inner_sign);
1825   if (inside_domain_p (min, max, outer))
1826     create_possibly_reversed_range (r, outer_type, min, max);
1827   else
1828     r.set_varying (outer_type);
1829 }
1830 
1831 
1832 bool
fold_range(irange & r,tree type ATTRIBUTE_UNUSED,const irange & inner,const irange & outer) const1833 operator_cast::fold_range (irange &r, tree type ATTRIBUTE_UNUSED,
1834 			   const irange &inner,
1835 			   const irange &outer) const
1836 {
1837   if (empty_range_varying (r, type, inner, outer))
1838     return true;
1839 
1840   gcc_checking_assert (outer.varying_p ());
1841   gcc_checking_assert (inner.num_pairs () > 0);
1842 
1843   // Avoid a temporary by folding the first pair directly into the result.
1844   fold_pair (r, 0, inner, outer);
1845 
1846   // Then process any additonal pairs by unioning with their results.
1847   for (unsigned x = 1; x < inner.num_pairs (); ++x)
1848     {
1849       int_range_max tmp;
1850       fold_pair (tmp, x, inner, outer);
1851       r.union_ (tmp);
1852       if (r.varying_p ())
1853 	return true;
1854     }
1855   return true;
1856 }
1857 
1858 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const1859 operator_cast::op1_range (irange &r, tree type,
1860 			  const irange &lhs,
1861 			  const irange &op2) const
1862 {
1863   tree lhs_type = lhs.type ();
1864   gcc_checking_assert (types_compatible_p (op2.type(), type));
1865 
1866   // If we are calculating a pointer, shortcut to what we really care about.
1867   if (POINTER_TYPE_P (type))
1868     {
1869       // Conversion from other pointers or a constant (including 0/NULL)
1870       // are straightforward.
1871       if (POINTER_TYPE_P (lhs.type ())
1872 	  || (lhs.singleton_p ()
1873 	      && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
1874 	{
1875 	  r = lhs;
1876 	  range_cast (r, type);
1877 	}
1878       else
1879 	{
1880 	  // If the LHS is not a pointer nor a singleton, then it is
1881 	  // either VARYING or non-zero.
1882 	  if (!lhs.contains_p (build_zero_cst (lhs.type ())))
1883 	    r.set_nonzero (type);
1884 	  else
1885 	    r.set_varying (type);
1886 	}
1887       r.intersect (op2);
1888       return true;
1889     }
1890 
1891   if (truncating_cast_p (op2, lhs))
1892     {
1893       if (lhs.varying_p ())
1894 	r.set_varying (type);
1895       else
1896         {
1897 	  // We want to insert the LHS as an unsigned value since it
1898 	  // would not trigger the signed bit of the larger type.
1899 	  int_range_max converted_lhs = lhs;
1900 	  range_cast (converted_lhs, unsigned_type_for (lhs_type));
1901 	  range_cast (converted_lhs, type);
1902 	  // Start by building the positive signed outer range for the type.
1903 	  wide_int lim = wi::set_bit_in_zero (TYPE_PRECISION (lhs_type),
1904 					      TYPE_PRECISION (type));
1905 	  r = int_range<1> (type, lim, wi::max_value (TYPE_PRECISION (type),
1906 						      SIGNED));
1907 	  // For the signed part, we need to simply union the 2 ranges now.
1908 	  r.union_ (converted_lhs);
1909 
1910 	  // Create maximal negative number outside of LHS bits.
1911 	  lim = wi::mask (TYPE_PRECISION (lhs_type), true,
1912 			  TYPE_PRECISION (type));
1913 	  // Add this to the unsigned LHS range(s).
1914 	  int_range_max lim_range (type, lim, lim);
1915 	  int_range_max lhs_neg;
1916 	  range_op_handler (PLUS_EXPR, type)->fold_range (lhs_neg,
1917 							  type,
1918 							  converted_lhs,
1919 							  lim_range);
1920 	  // lhs_neg now has all the negative versions of the LHS.
1921 	  // Now union in all the values from SIGNED MIN (0x80000) to
1922 	  // lim-1 in order to fill in all the ranges with the upper
1923 	  // bits set.
1924 
1925 	  // PR 97317.  If the lhs has only 1 bit less precision than the rhs,
1926 	  // we don't need to create a range from min to lim-1
1927 	  // calculate neg range traps trying to create [lim, lim - 1].
1928 	  wide_int min_val = wi::min_value (TYPE_PRECISION (type), SIGNED);
1929 	  if (lim != min_val)
1930 	    {
1931 	      int_range_max neg (type,
1932 				 wi::min_value (TYPE_PRECISION (type),
1933 						SIGNED),
1934 				 lim - 1);
1935 	      lhs_neg.union_ (neg);
1936 	    }
1937 	  // And finally, munge the signed and unsigned portions.
1938 	  r.union_ (lhs_neg);
1939 	}
1940       // And intersect with any known value passed in the extra operand.
1941       r.intersect (op2);
1942       return true;
1943     }
1944 
1945   int_range_max tmp;
1946   if (TYPE_PRECISION (lhs_type) == TYPE_PRECISION (type))
1947     tmp = lhs;
1948   else
1949     {
1950       // The cast is not truncating, and the range is restricted to
1951       // the range of the RHS by this assignment.
1952       //
1953       // Cast the range of the RHS to the type of the LHS.
1954       fold_range (tmp, lhs_type, int_range<1> (type), int_range<1> (lhs_type));
1955       // Intersect this with the LHS range will produce the range,
1956       // which will be cast to the RHS type before returning.
1957       tmp.intersect (lhs);
1958     }
1959 
1960   // Cast the calculated range to the type of the RHS.
1961   fold_range (r, type, tmp, int_range<1> (type));
1962   return true;
1963 }
1964 
1965 
1966 class operator_logical_and : public range_operator
1967 {
1968 public:
1969   virtual bool fold_range (irange &r, tree type,
1970 			   const irange &lh,
1971 			   const irange &rh) const;
1972   virtual bool op1_range (irange &r, tree type,
1973 			  const irange &lhs,
1974 			  const irange &op2) const;
1975   virtual bool op2_range (irange &r, tree type,
1976 			  const irange &lhs,
1977 			  const irange &op1) const;
1978 } op_logical_and;
1979 
1980 
1981 bool
fold_range(irange & r,tree type,const irange & lh,const irange & rh) const1982 operator_logical_and::fold_range (irange &r, tree type,
1983 				  const irange &lh,
1984 				  const irange &rh) const
1985 {
1986   if (empty_range_varying (r, type, lh, rh))
1987     return true;
1988 
1989   // 0 && anything is 0.
1990   if ((wi::eq_p (lh.lower_bound (), 0) && wi::eq_p (lh.upper_bound (), 0))
1991       || (wi::eq_p (lh.lower_bound (), 0) && wi::eq_p (rh.upper_bound (), 0)))
1992     r = range_false (type);
1993   else if (lh.contains_p (build_zero_cst (lh.type ()))
1994 	   || rh.contains_p (build_zero_cst (rh.type ())))
1995     // To reach this point, there must be a logical 1 on each side, and
1996     // the only remaining question is whether there is a zero or not.
1997     r = range_true_and_false (type);
1998   else
1999     r = range_true (type);
2000   return true;
2001 }
2002 
2003 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2 ATTRIBUTE_UNUSED) const2004 operator_logical_and::op1_range (irange &r, tree type,
2005 				 const irange &lhs,
2006 				 const irange &op2 ATTRIBUTE_UNUSED) const
2007 {
2008    switch (get_bool_state (r, lhs, type))
2009      {
2010      case BRS_TRUE:
2011        // A true result means both sides of the AND must be true.
2012        r = range_true (type);
2013        break;
2014      default:
2015        // Any other result means only one side has to be false, the
2016        // other side can be anything. So we cannott be sure of any
2017        // result here.
2018        r = range_true_and_false (type);
2019        break;
2020      }
2021   return true;
2022 }
2023 
2024 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1) const2025 operator_logical_and::op2_range (irange &r, tree type,
2026 				 const irange &lhs,
2027 				 const irange &op1) const
2028 {
2029   return operator_logical_and::op1_range (r, type, lhs, op1);
2030 }
2031 
2032 
2033 class operator_bitwise_and : public range_operator
2034 {
2035 public:
2036   virtual bool fold_range (irange &r, tree type,
2037 			   const irange &lh,
2038 			   const irange &rh) const;
2039   virtual bool op1_range (irange &r, tree type,
2040 			  const irange &lhs,
2041 			  const irange &op2) const;
2042   virtual bool op2_range (irange &r, tree type,
2043 			  const irange &lhs,
2044 			  const irange &op1) const;
2045   virtual void wi_fold (irange &r, tree type,
2046 		        const wide_int &lh_lb,
2047 		        const wide_int &lh_ub,
2048 		        const wide_int &rh_lb,
2049 		        const wide_int &rh_ub) const;
2050 private:
2051   void simple_op1_range_solver (irange &r, tree type,
2052 				const irange &lhs,
2053 				const irange &op2) const;
2054   void remove_impossible_ranges (irange &r, const irange &rh) const;
2055 } op_bitwise_and;
2056 
2057 static bool
unsigned_singleton_p(const irange & op)2058 unsigned_singleton_p (const irange &op)
2059 {
2060   tree mask;
2061   if (op.singleton_p (&mask))
2062     {
2063       wide_int x = wi::to_wide (mask);
2064       return wi::ge_p (x, 0, TYPE_SIGN (op.type ()));
2065     }
2066   return false;
2067 }
2068 
2069 // Remove any ranges from R that are known to be impossible when an
2070 // range is ANDed with MASK.
2071 
2072 void
remove_impossible_ranges(irange & r,const irange & rmask) const2073 operator_bitwise_and::remove_impossible_ranges (irange &r,
2074 						const irange &rmask) const
2075 {
2076   if (r.undefined_p () || !unsigned_singleton_p (rmask))
2077     return;
2078 
2079   wide_int mask = rmask.lower_bound ();
2080   tree type = r.type ();
2081   int prec = TYPE_PRECISION (type);
2082   int leading_zeros = wi::clz (mask);
2083   int_range_max impossible_ranges;
2084 
2085   /* We know that starting at the most significant bit, any 0 in the
2086      mask means the resulting range cannot contain a 1 in that same
2087      position.  This means the following ranges are impossible:
2088 
2089 	x & 0b1001 1010
2090 			  IMPOSSIBLE RANGES
2091 	      01xx xxxx   [0100 0000, 0111 1111]
2092 	      001x xxxx   [0010 0000, 0011 1111]
2093 	      0000 01xx   [0000 0100, 0000 0111]
2094 	      0000 0001   [0000 0001, 0000 0001]
2095   */
2096   wide_int one = wi::one (prec);
2097   for (int i = 0; i < prec - leading_zeros - 1; ++i)
2098     if (wi::bit_and (mask, wi::lshift (one, wi::uhwi (i, prec))) == 0)
2099       {
2100 	tree lb = fold_build2 (LSHIFT_EXPR, type,
2101 			       build_one_cst (type),
2102 			       build_int_cst (type, i));
2103 	tree ub_left = fold_build1 (BIT_NOT_EXPR, type,
2104 				    fold_build2 (LSHIFT_EXPR, type,
2105 						 build_minus_one_cst (type),
2106 						 build_int_cst (type, i)));
2107 	tree ub_right = fold_build2 (LSHIFT_EXPR, type,
2108 				     build_one_cst (type),
2109 				     build_int_cst (type, i));
2110 	tree ub = fold_build2 (BIT_IOR_EXPR, type, ub_left, ub_right);
2111 	impossible_ranges.union_ (int_range<1> (lb, ub));
2112       }
2113   if (!impossible_ranges.undefined_p ())
2114     {
2115       impossible_ranges.invert ();
2116       r.intersect (impossible_ranges);
2117     }
2118 }
2119 
2120 bool
fold_range(irange & r,tree type,const irange & lh,const irange & rh) const2121 operator_bitwise_and::fold_range (irange &r, tree type,
2122 				  const irange &lh,
2123 				  const irange &rh) const
2124 {
2125   if (range_operator::fold_range (r, type, lh, rh))
2126     {
2127       // FIXME: This is temporarily disabled because, though it
2128       // generates better ranges, it's noticeably slower for evrp.
2129       // remove_impossible_ranges (r, rh);
2130       return true;
2131     }
2132   return false;
2133 }
2134 
2135 
2136 // Optimize BIT_AND_EXPR and BIT_IOR_EXPR in terms of a mask if
2137 // possible.  Basically, see if we can optimize:
2138 //
2139 //	[LB, UB] op Z
2140 //   into:
2141 //	[LB op Z, UB op Z]
2142 //
2143 // If the optimization was successful, accumulate the range in R and
2144 // return TRUE.
2145 
2146 static bool
wi_optimize_and_or(irange & r,enum tree_code code,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub)2147 wi_optimize_and_or (irange &r,
2148 		    enum tree_code code,
2149 		    tree type,
2150 		    const wide_int &lh_lb, const wide_int &lh_ub,
2151 		    const wide_int &rh_lb, const wide_int &rh_ub)
2152 {
2153   // Calculate the singleton mask among the ranges, if any.
2154   wide_int lower_bound, upper_bound, mask;
2155   if (wi::eq_p (rh_lb, rh_ub))
2156     {
2157       mask = rh_lb;
2158       lower_bound = lh_lb;
2159       upper_bound = lh_ub;
2160     }
2161   else if (wi::eq_p (lh_lb, lh_ub))
2162     {
2163       mask = lh_lb;
2164       lower_bound = rh_lb;
2165       upper_bound = rh_ub;
2166     }
2167   else
2168     return false;
2169 
2170   // If Z is a constant which (for op | its bitwise not) has n
2171   // consecutive least significant bits cleared followed by m 1
2172   // consecutive bits set immediately above it and either
2173   // m + n == precision, or (x >> (m + n)) == (y >> (m + n)).
2174   //
2175   // The least significant n bits of all the values in the range are
2176   // cleared or set, the m bits above it are preserved and any bits
2177   // above these are required to be the same for all values in the
2178   // range.
2179   wide_int w = mask;
2180   int m = 0, n = 0;
2181   if (code == BIT_IOR_EXPR)
2182     w = ~w;
2183   if (wi::eq_p (w, 0))
2184     n = w.get_precision ();
2185   else
2186     {
2187       n = wi::ctz (w);
2188       w = ~(w | wi::mask (n, false, w.get_precision ()));
2189       if (wi::eq_p (w, 0))
2190 	m = w.get_precision () - n;
2191       else
2192 	m = wi::ctz (w) - n;
2193     }
2194   wide_int new_mask = wi::mask (m + n, true, w.get_precision ());
2195   if ((new_mask & lower_bound) != (new_mask & upper_bound))
2196     return false;
2197 
2198   wide_int res_lb, res_ub;
2199   if (code == BIT_AND_EXPR)
2200     {
2201       res_lb = wi::bit_and (lower_bound, mask);
2202       res_ub = wi::bit_and (upper_bound, mask);
2203     }
2204   else if (code == BIT_IOR_EXPR)
2205     {
2206       res_lb = wi::bit_or (lower_bound, mask);
2207       res_ub = wi::bit_or (upper_bound, mask);
2208     }
2209   else
2210     gcc_unreachable ();
2211   value_range_with_overflow (r, type, res_lb, res_ub);
2212 
2213   // Furthermore, if the mask is non-zero, an IOR cannot contain zero.
2214   if (code == BIT_IOR_EXPR && wi::ne_p (mask, 0))
2215     {
2216       int_range<2> tmp;
2217       tmp.set_nonzero (type);
2218       r.intersect (tmp);
2219     }
2220   return true;
2221 }
2222 
2223 // For range [LB, UB] compute two wide_int bit masks.
2224 //
2225 // In the MAYBE_NONZERO bit mask, if some bit is unset, it means that
2226 // for all numbers in the range the bit is 0, otherwise it might be 0
2227 // or 1.
2228 //
2229 // In the MUSTBE_NONZERO bit mask, if some bit is set, it means that
2230 // for all numbers in the range the bit is 1, otherwise it might be 0
2231 // or 1.
2232 
2233 void
wi_set_zero_nonzero_bits(tree type,const wide_int & lb,const wide_int & ub,wide_int & maybe_nonzero,wide_int & mustbe_nonzero)2234 wi_set_zero_nonzero_bits (tree type,
2235 			  const wide_int &lb, const wide_int &ub,
2236 			  wide_int &maybe_nonzero,
2237 			  wide_int &mustbe_nonzero)
2238 {
2239   signop sign = TYPE_SIGN (type);
2240 
2241   if (wi::eq_p (lb, ub))
2242     maybe_nonzero = mustbe_nonzero = lb;
2243   else if (wi::ge_p (lb, 0, sign) || wi::lt_p (ub, 0, sign))
2244     {
2245       wide_int xor_mask = lb ^ ub;
2246       maybe_nonzero = lb | ub;
2247       mustbe_nonzero = lb & ub;
2248       if (xor_mask != 0)
2249 	{
2250 	  wide_int mask = wi::mask (wi::floor_log2 (xor_mask), false,
2251 				    maybe_nonzero.get_precision ());
2252 	  maybe_nonzero = maybe_nonzero | mask;
2253 	  mustbe_nonzero = wi::bit_and_not (mustbe_nonzero, mask);
2254 	}
2255     }
2256   else
2257     {
2258       maybe_nonzero = wi::minus_one (lb.get_precision ());
2259       mustbe_nonzero = wi::zero (lb.get_precision ());
2260     }
2261 }
2262 
2263 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const2264 operator_bitwise_and::wi_fold (irange &r, tree type,
2265 			       const wide_int &lh_lb,
2266 			       const wide_int &lh_ub,
2267 			       const wide_int &rh_lb,
2268 			       const wide_int &rh_ub) const
2269 {
2270   if (wi_optimize_and_or (r, BIT_AND_EXPR, type, lh_lb, lh_ub, rh_lb, rh_ub))
2271     return;
2272 
2273   wide_int maybe_nonzero_lh, mustbe_nonzero_lh;
2274   wide_int maybe_nonzero_rh, mustbe_nonzero_rh;
2275   wi_set_zero_nonzero_bits (type, lh_lb, lh_ub,
2276 			    maybe_nonzero_lh, mustbe_nonzero_lh);
2277   wi_set_zero_nonzero_bits (type, rh_lb, rh_ub,
2278 			    maybe_nonzero_rh, mustbe_nonzero_rh);
2279 
2280   wide_int new_lb = mustbe_nonzero_lh & mustbe_nonzero_rh;
2281   wide_int new_ub = maybe_nonzero_lh & maybe_nonzero_rh;
2282   signop sign = TYPE_SIGN (type);
2283   unsigned prec = TYPE_PRECISION (type);
2284   // If both input ranges contain only negative values, we can
2285   // truncate the result range maximum to the minimum of the
2286   // input range maxima.
2287   if (wi::lt_p (lh_ub, 0, sign) && wi::lt_p (rh_ub, 0, sign))
2288     {
2289       new_ub = wi::min (new_ub, lh_ub, sign);
2290       new_ub = wi::min (new_ub, rh_ub, sign);
2291     }
2292   // If either input range contains only non-negative values
2293   // we can truncate the result range maximum to the respective
2294   // maximum of the input range.
2295   if (wi::ge_p (lh_lb, 0, sign))
2296     new_ub = wi::min (new_ub, lh_ub, sign);
2297   if (wi::ge_p (rh_lb, 0, sign))
2298     new_ub = wi::min (new_ub, rh_ub, sign);
2299   // PR68217: In case of signed & sign-bit-CST should
2300   // result in [-INF, 0] instead of [-INF, INF].
2301   if (wi::gt_p (new_lb, new_ub, sign))
2302     {
2303       wide_int sign_bit = wi::set_bit_in_zero (prec - 1, prec);
2304       if (sign == SIGNED
2305 	  && ((wi::eq_p (lh_lb, lh_ub)
2306 	       && !wi::cmps (lh_lb, sign_bit))
2307 	      || (wi::eq_p (rh_lb, rh_ub)
2308 		  && !wi::cmps (rh_lb, sign_bit))))
2309 	{
2310 	  new_lb = wi::min_value (prec, sign);
2311 	  new_ub = wi::zero (prec);
2312 	}
2313     }
2314   // If the limits got swapped around, return varying.
2315   if (wi::gt_p (new_lb, new_ub,sign))
2316     r.set_varying (type);
2317   else
2318     value_range_with_overflow (r, type, new_lb, new_ub);
2319 }
2320 
2321 static void
set_nonzero_range_from_mask(irange & r,tree type,const irange & lhs)2322 set_nonzero_range_from_mask (irange &r, tree type, const irange &lhs)
2323 {
2324   if (!lhs.contains_p (build_zero_cst (type)))
2325     r = range_nonzero (type);
2326   else
2327     r.set_varying (type);
2328 }
2329 
2330 // This was shamelessly stolen from register_edge_assert_for_2 and
2331 // adjusted to work with iranges.
2332 
2333 void
simple_op1_range_solver(irange & r,tree type,const irange & lhs,const irange & op2) const2334 operator_bitwise_and::simple_op1_range_solver (irange &r, tree type,
2335 					       const irange &lhs,
2336 					       const irange &op2) const
2337 {
2338   if (!op2.singleton_p ())
2339     {
2340       set_nonzero_range_from_mask (r, type, lhs);
2341       return;
2342     }
2343   unsigned int nprec = TYPE_PRECISION (type);
2344   wide_int cst2v = op2.lower_bound ();
2345   bool cst2n = wi::neg_p (cst2v, TYPE_SIGN (type));
2346   wide_int sgnbit;
2347   if (cst2n)
2348     sgnbit = wi::set_bit_in_zero (nprec - 1, nprec);
2349   else
2350     sgnbit = wi::zero (nprec);
2351 
2352   // Solve [lhs.lower_bound (), +INF] = x & MASK.
2353   //
2354   // Minimum unsigned value for >= if (VAL & CST2) == VAL is VAL and
2355   // maximum unsigned value is ~0.  For signed comparison, if CST2
2356   // doesn't have the most significant bit set, handle it similarly.  If
2357   // CST2 has MSB set, the minimum is the same, and maximum is ~0U/2.
2358   wide_int valv = lhs.lower_bound ();
2359   wide_int minv = valv & cst2v, maxv;
2360   bool we_know_nothing = false;
2361   if (minv != valv)
2362     {
2363       // If (VAL & CST2) != VAL, X & CST2 can't be equal to VAL.
2364       minv = masked_increment (valv, cst2v, sgnbit, nprec);
2365       if (minv == valv)
2366 	{
2367 	  // If we can't determine anything on this bound, fall
2368 	  // through and conservatively solve for the other end point.
2369 	  we_know_nothing = true;
2370 	}
2371     }
2372   maxv = wi::mask (nprec - (cst2n ? 1 : 0), false, nprec);
2373   if (we_know_nothing)
2374     r.set_varying (type);
2375   else
2376     r = int_range<1> (type, minv, maxv);
2377 
2378   // Solve [-INF, lhs.upper_bound ()] = x & MASK.
2379   //
2380   // Minimum unsigned value for <= is 0 and maximum unsigned value is
2381   // VAL | ~CST2 if (VAL & CST2) == VAL.  Otherwise, find smallest
2382   // VAL2 where
2383   // VAL2 > VAL && (VAL2 & CST2) == VAL2 and use (VAL2 - 1) | ~CST2
2384   // as maximum.
2385   // For signed comparison, if CST2 doesn't have most significant bit
2386   // set, handle it similarly.  If CST2 has MSB set, the maximum is
2387   // the same and minimum is INT_MIN.
2388   valv = lhs.upper_bound ();
2389   minv = valv & cst2v;
2390   if (minv == valv)
2391     maxv = valv;
2392   else
2393     {
2394       maxv = masked_increment (valv, cst2v, sgnbit, nprec);
2395       if (maxv == valv)
2396 	{
2397 	  // If we couldn't determine anything on either bound, return
2398 	  // undefined.
2399 	  if (we_know_nothing)
2400 	    r.set_undefined ();
2401 	  return;
2402 	}
2403       maxv -= 1;
2404     }
2405   maxv |= ~cst2v;
2406   minv = sgnbit;
2407   int_range<1> upper_bits (type, minv, maxv);
2408   r.intersect (upper_bits);
2409 }
2410 
2411 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const2412 operator_bitwise_and::op1_range (irange &r, tree type,
2413 				 const irange &lhs,
2414 				 const irange &op2) const
2415 {
2416   if (types_compatible_p (type, boolean_type_node))
2417     return op_logical_and.op1_range (r, type, lhs, op2);
2418 
2419   r.set_undefined ();
2420   for (unsigned i = 0; i < lhs.num_pairs (); ++i)
2421     {
2422       int_range_max chunk (lhs.type (),
2423 			   lhs.lower_bound (i),
2424 			   lhs.upper_bound (i));
2425       int_range_max res;
2426       simple_op1_range_solver (res, type, chunk, op2);
2427       r.union_ (res);
2428     }
2429   if (r.undefined_p ())
2430     set_nonzero_range_from_mask (r, type, lhs);
2431   return true;
2432 }
2433 
2434 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1) const2435 operator_bitwise_and::op2_range (irange &r, tree type,
2436 				 const irange &lhs,
2437 				 const irange &op1) const
2438 {
2439   return operator_bitwise_and::op1_range (r, type, lhs, op1);
2440 }
2441 
2442 
2443 class operator_logical_or : public range_operator
2444 {
2445 public:
2446   virtual bool fold_range (irange &r, tree type,
2447 			   const irange &lh,
2448 			   const irange &rh) const;
2449   virtual bool op1_range (irange &r, tree type,
2450 			  const irange &lhs,
2451 			  const irange &op2) const;
2452   virtual bool op2_range (irange &r, tree type,
2453 			  const irange &lhs,
2454 			  const irange &op1) const;
2455 } op_logical_or;
2456 
2457 bool
fold_range(irange & r,tree type ATTRIBUTE_UNUSED,const irange & lh,const irange & rh) const2458 operator_logical_or::fold_range (irange &r, tree type ATTRIBUTE_UNUSED,
2459 				 const irange &lh,
2460 				 const irange &rh) const
2461 {
2462   if (empty_range_varying (r, type, lh, rh))
2463     return true;
2464 
2465   r = lh;
2466   r.union_ (rh);
2467   return true;
2468 }
2469 
2470 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2 ATTRIBUTE_UNUSED) const2471 operator_logical_or::op1_range (irange &r, tree type,
2472 				const irange &lhs,
2473 				const irange &op2 ATTRIBUTE_UNUSED) const
2474 {
2475    switch (get_bool_state (r, lhs, type))
2476      {
2477      case BRS_FALSE:
2478        // A false result means both sides of the OR must be false.
2479        r = range_false (type);
2480        break;
2481      default:
2482        // Any other result means only one side has to be true, the
2483        // other side can be anything. so we can't be sure of any result
2484        // here.
2485        r = range_true_and_false (type);
2486        break;
2487     }
2488   return true;
2489 }
2490 
2491 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1) const2492 operator_logical_or::op2_range (irange &r, tree type,
2493 				const irange &lhs,
2494 				const irange &op1) const
2495 {
2496   return operator_logical_or::op1_range (r, type, lhs, op1);
2497 }
2498 
2499 
2500 class operator_bitwise_or : public range_operator
2501 {
2502 public:
2503   virtual bool op1_range (irange &r, tree type,
2504 			  const irange &lhs,
2505 			  const irange &op2) const;
2506   virtual bool op2_range (irange &r, tree type,
2507 			  const irange &lhs,
2508 			  const irange &op1) const;
2509   virtual void wi_fold (irange &r, tree type,
2510 		        const wide_int &lh_lb,
2511 		        const wide_int &lh_ub,
2512 		        const wide_int &rh_lb,
2513 		        const wide_int &rh_ub) const;
2514 } op_bitwise_or;
2515 
2516 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const2517 operator_bitwise_or::wi_fold (irange &r, tree type,
2518 			      const wide_int &lh_lb,
2519 			      const wide_int &lh_ub,
2520 			      const wide_int &rh_lb,
2521 			      const wide_int &rh_ub) const
2522 {
2523   if (wi_optimize_and_or (r, BIT_IOR_EXPR, type, lh_lb, lh_ub, rh_lb, rh_ub))
2524     return;
2525 
2526   wide_int maybe_nonzero_lh, mustbe_nonzero_lh;
2527   wide_int maybe_nonzero_rh, mustbe_nonzero_rh;
2528   wi_set_zero_nonzero_bits (type, lh_lb, lh_ub,
2529 			    maybe_nonzero_lh, mustbe_nonzero_lh);
2530   wi_set_zero_nonzero_bits (type, rh_lb, rh_ub,
2531 			    maybe_nonzero_rh, mustbe_nonzero_rh);
2532   wide_int new_lb = mustbe_nonzero_lh | mustbe_nonzero_rh;
2533   wide_int new_ub = maybe_nonzero_lh | maybe_nonzero_rh;
2534   signop sign = TYPE_SIGN (type);
2535   // If the input ranges contain only positive values we can
2536   // truncate the minimum of the result range to the maximum
2537   // of the input range minima.
2538   if (wi::ge_p (lh_lb, 0, sign)
2539       && wi::ge_p (rh_lb, 0, sign))
2540     {
2541       new_lb = wi::max (new_lb, lh_lb, sign);
2542       new_lb = wi::max (new_lb, rh_lb, sign);
2543     }
2544   // If either input range contains only negative values
2545   // we can truncate the minimum of the result range to the
2546   // respective minimum range.
2547   if (wi::lt_p (lh_ub, 0, sign))
2548     new_lb = wi::max (new_lb, lh_lb, sign);
2549   if (wi::lt_p (rh_ub, 0, sign))
2550     new_lb = wi::max (new_lb, rh_lb, sign);
2551   // If the limits got swapped around, return varying.
2552   if (wi::gt_p (new_lb, new_ub,sign))
2553     r.set_varying (type);
2554   else
2555     value_range_with_overflow (r, type, new_lb, new_ub);
2556 }
2557 
2558 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const2559 operator_bitwise_or::op1_range (irange &r, tree type,
2560 				const irange &lhs,
2561 				const irange &op2) const
2562 {
2563   // If this is really a logical wi_fold, call that.
2564   if (types_compatible_p (type, boolean_type_node))
2565     return op_logical_or.op1_range (r, type, lhs, op2);
2566 
2567   if (lhs.zero_p ())
2568     {
2569       tree zero = build_zero_cst (type);
2570       r = int_range<1> (zero, zero);
2571       return true;
2572     }
2573   r.set_varying (type);
2574   return true;
2575 }
2576 
2577 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1) const2578 operator_bitwise_or::op2_range (irange &r, tree type,
2579 				const irange &lhs,
2580 				const irange &op1) const
2581 {
2582   return operator_bitwise_or::op1_range (r, type, lhs, op1);
2583 }
2584 
2585 
2586 class operator_bitwise_xor : public range_operator
2587 {
2588 public:
2589   virtual void wi_fold (irange &r, tree type,
2590 		        const wide_int &lh_lb,
2591 		        const wide_int &lh_ub,
2592 		        const wide_int &rh_lb,
2593 		        const wide_int &rh_ub) const;
2594   virtual bool op1_range (irange &r, tree type,
2595 			  const irange &lhs,
2596 			  const irange &op2) const;
2597   virtual bool op2_range (irange &r, tree type,
2598 			  const irange &lhs,
2599 			  const irange &op1) const;
2600 } op_bitwise_xor;
2601 
2602 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const2603 operator_bitwise_xor::wi_fold (irange &r, tree type,
2604 			       const wide_int &lh_lb,
2605 			       const wide_int &lh_ub,
2606 			       const wide_int &rh_lb,
2607 			       const wide_int &rh_ub) const
2608 {
2609   signop sign = TYPE_SIGN (type);
2610   wide_int maybe_nonzero_lh, mustbe_nonzero_lh;
2611   wide_int maybe_nonzero_rh, mustbe_nonzero_rh;
2612   wi_set_zero_nonzero_bits (type, lh_lb, lh_ub,
2613 			    maybe_nonzero_lh, mustbe_nonzero_lh);
2614   wi_set_zero_nonzero_bits (type, rh_lb, rh_ub,
2615 			    maybe_nonzero_rh, mustbe_nonzero_rh);
2616 
2617   wide_int result_zero_bits = ((mustbe_nonzero_lh & mustbe_nonzero_rh)
2618 			       | ~(maybe_nonzero_lh | maybe_nonzero_rh));
2619   wide_int result_one_bits
2620     = (wi::bit_and_not (mustbe_nonzero_lh, maybe_nonzero_rh)
2621        | wi::bit_and_not (mustbe_nonzero_rh, maybe_nonzero_lh));
2622   wide_int new_ub = ~result_zero_bits;
2623   wide_int new_lb = result_one_bits;
2624 
2625   // If the range has all positive or all negative values, the result
2626   // is better than VARYING.
2627   if (wi::lt_p (new_lb, 0, sign) || wi::ge_p (new_ub, 0, sign))
2628     value_range_with_overflow (r, type, new_lb, new_ub);
2629   else
2630     r.set_varying (type);
2631 }
2632 
2633 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const2634 operator_bitwise_xor::op1_range (irange &r, tree type,
2635 				 const irange &lhs,
2636 				 const irange &op2) const
2637 {
2638   if (lhs.undefined_p () || lhs.varying_p ())
2639     {
2640       r = lhs;
2641       return true;
2642     }
2643   if (types_compatible_p (type, boolean_type_node))
2644     {
2645       switch (get_bool_state (r, lhs, type))
2646 	{
2647 	case BRS_TRUE:
2648 	  if (op2.varying_p ())
2649 	    r.set_varying (type);
2650 	  else if (op2.zero_p ())
2651 	    r = range_true (type);
2652 	  else
2653 	    r = range_false (type);
2654 	  break;
2655 	case BRS_FALSE:
2656 	  r = op2;
2657 	  break;
2658 	default:
2659 	  break;
2660 	}
2661       return true;
2662     }
2663   r.set_varying (type);
2664   return true;
2665 }
2666 
2667 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1) const2668 operator_bitwise_xor::op2_range (irange &r, tree type,
2669 				 const irange &lhs,
2670 				 const irange &op1) const
2671 {
2672   return operator_bitwise_xor::op1_range (r, type, lhs, op1);
2673 }
2674 
2675 class operator_trunc_mod : public range_operator
2676 {
2677 public:
2678   virtual void wi_fold (irange &r, tree type,
2679 		        const wide_int &lh_lb,
2680 		        const wide_int &lh_ub,
2681 		        const wide_int &rh_lb,
2682 		        const wide_int &rh_ub) const;
2683   virtual bool op1_range (irange &r, tree type,
2684 			  const irange &lhs,
2685 			  const irange &op2) const;
2686   virtual bool op2_range (irange &r, tree type,
2687 			  const irange &lhs,
2688 			  const irange &op1) const;
2689 } op_trunc_mod;
2690 
2691 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const2692 operator_trunc_mod::wi_fold (irange &r, tree type,
2693 			     const wide_int &lh_lb,
2694 			     const wide_int &lh_ub,
2695 			     const wide_int &rh_lb,
2696 			     const wide_int &rh_ub) const
2697 {
2698   wide_int new_lb, new_ub, tmp;
2699   signop sign = TYPE_SIGN (type);
2700   unsigned prec = TYPE_PRECISION (type);
2701 
2702   // Mod 0 is undefined.
2703   if (wi_zero_p (type, rh_lb, rh_ub))
2704     {
2705       r.set_varying (type);
2706       return;
2707     }
2708 
2709   // ABS (A % B) < ABS (B) and either 0 <= A % B <= A or A <= A % B <= 0.
2710   new_ub = rh_ub - 1;
2711   if (sign == SIGNED)
2712     {
2713       tmp = -1 - rh_lb;
2714       new_ub = wi::smax (new_ub, tmp);
2715     }
2716 
2717   if (sign == UNSIGNED)
2718     new_lb = wi::zero (prec);
2719   else
2720     {
2721       new_lb = -new_ub;
2722       tmp = lh_lb;
2723       if (wi::gts_p (tmp, 0))
2724 	tmp = wi::zero (prec);
2725       new_lb = wi::smax (new_lb, tmp);
2726     }
2727   tmp = lh_ub;
2728   if (sign == SIGNED && wi::neg_p (tmp))
2729     tmp = wi::zero (prec);
2730   new_ub = wi::min (new_ub, tmp, sign);
2731 
2732   value_range_with_overflow (r, type, new_lb, new_ub);
2733 }
2734 
2735 bool
op1_range(irange & r,tree type,const irange & lhs,const irange &) const2736 operator_trunc_mod::op1_range (irange &r, tree type,
2737 			       const irange &lhs,
2738 			       const irange &) const
2739 {
2740   // PR 91029.
2741   signop sign = TYPE_SIGN (type);
2742   unsigned prec = TYPE_PRECISION (type);
2743   // (a % b) >= x && x > 0 , then a >= x.
2744   if (wi::gt_p (lhs.lower_bound (), 0, sign))
2745     {
2746       r = value_range (type, lhs.lower_bound (), wi::max_value (prec, sign));
2747       return true;
2748     }
2749   // (a % b) <= x && x < 0 , then a <= x.
2750   if (wi::lt_p (lhs.upper_bound (), 0, sign))
2751     {
2752       r = value_range (type, wi::min_value (prec, sign), lhs.upper_bound ());
2753       return true;
2754     }
2755   return false;
2756 }
2757 
2758 bool
op2_range(irange & r,tree type,const irange & lhs,const irange &) const2759 operator_trunc_mod::op2_range (irange &r, tree type,
2760 			       const irange &lhs,
2761 			       const irange &) const
2762 {
2763   // PR 91029.
2764   signop sign = TYPE_SIGN (type);
2765   unsigned prec = TYPE_PRECISION (type);
2766   // (a % b) >= x && x > 0 , then b is in ~[-x, x] for signed
2767   //			       or b > x for unsigned.
2768   if (wi::gt_p (lhs.lower_bound (), 0, sign))
2769     {
2770       if (sign == SIGNED)
2771 	r = value_range (type, wi::neg (lhs.lower_bound ()),
2772 			 lhs.lower_bound (), VR_ANTI_RANGE);
2773       else if (wi::lt_p (lhs.lower_bound (), wi::max_value (prec, sign),
2774 			 sign))
2775 	r = value_range (type, lhs.lower_bound () + 1,
2776 			 wi::max_value (prec, sign));
2777       else
2778 	return false;
2779       return true;
2780     }
2781   // (a % b) <= x && x < 0 , then b is in ~[x, -x].
2782   if (wi::lt_p (lhs.upper_bound (), 0, sign))
2783     {
2784       if (wi::gt_p (lhs.upper_bound (), wi::min_value (prec, sign), sign))
2785 	r = value_range (type, lhs.upper_bound (),
2786 			 wi::neg (lhs.upper_bound ()), VR_ANTI_RANGE);
2787       else
2788 	return false;
2789       return true;
2790     }
2791   return false;
2792 }
2793 
2794 
2795 class operator_logical_not : public range_operator
2796 {
2797 public:
2798   virtual bool fold_range (irange &r, tree type,
2799 			   const irange &lh,
2800 			   const irange &rh) const;
2801   virtual bool op1_range (irange &r, tree type,
2802 			  const irange &lhs,
2803 			  const irange &op2) const;
2804 } op_logical_not;
2805 
2806 // Folding a logical NOT, oddly enough, involves doing nothing on the
2807 // forward pass through.  During the initial walk backwards, the
2808 // logical NOT reversed the desired outcome on the way back, so on the
2809 // way forward all we do is pass the range forward.
2810 //
2811 // 	b_2 = x_1 < 20
2812 // 	b_3 = !b_2
2813 // 	if (b_3)
2814 //  to determine the TRUE branch, walking  backward
2815 //       if (b_3)		if ([1,1])
2816 //       b_3 = !b_2		[1,1] = ![0,0]
2817 // 	 b_2 = x_1 < 20		[0,0] = x_1 < 20,   false, so x_1 == [20, 255]
2818 //   which is the result we are looking for.. so.. pass it through.
2819 
2820 bool
fold_range(irange & r,tree type,const irange & lh,const irange & rh ATTRIBUTE_UNUSED) const2821 operator_logical_not::fold_range (irange &r, tree type,
2822 				  const irange &lh,
2823 				  const irange &rh ATTRIBUTE_UNUSED) const
2824 {
2825   if (empty_range_varying (r, type, lh, rh))
2826     return true;
2827 
2828   r = lh;
2829   if (!lh.varying_p () && !lh.undefined_p ())
2830     r.invert ();
2831 
2832   return true;
2833 }
2834 
2835 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const2836 operator_logical_not::op1_range (irange &r,
2837 				 tree type,
2838 				 const irange &lhs,
2839 				 const irange &op2) const
2840 {
2841   // Logical NOT is involutary...do it again.
2842   return fold_range (r, type, lhs, op2);
2843 }
2844 
2845 
2846 class operator_bitwise_not : public range_operator
2847 {
2848 public:
2849   virtual bool fold_range (irange &r, tree type,
2850 			   const irange &lh,
2851 			   const irange &rh) const;
2852   virtual bool op1_range (irange &r, tree type,
2853 			  const irange &lhs,
2854 			  const irange &op2) const;
2855 } op_bitwise_not;
2856 
2857 bool
fold_range(irange & r,tree type,const irange & lh,const irange & rh) const2858 operator_bitwise_not::fold_range (irange &r, tree type,
2859 				  const irange &lh,
2860 				  const irange &rh) const
2861 {
2862   if (empty_range_varying (r, type, lh, rh))
2863     return true;
2864 
2865   if (types_compatible_p (type, boolean_type_node))
2866     return op_logical_not.fold_range (r, type, lh, rh);
2867 
2868   // ~X is simply -1 - X.
2869   int_range<1> minusone (type, wi::minus_one (TYPE_PRECISION (type)),
2870 			 wi::minus_one (TYPE_PRECISION (type)));
2871   return range_op_handler (MINUS_EXPR, type)->fold_range (r, type, minusone,
2872 							  lh);
2873 }
2874 
2875 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const2876 operator_bitwise_not::op1_range (irange &r, tree type,
2877 				 const irange &lhs,
2878 				 const irange &op2) const
2879 {
2880   if (types_compatible_p (type, boolean_type_node))
2881     return op_logical_not.op1_range (r, type, lhs, op2);
2882 
2883   // ~X is -1 - X and since bitwise NOT is involutary...do it again.
2884   return fold_range (r, type, lhs, op2);
2885 }
2886 
2887 
2888 class operator_cst : public range_operator
2889 {
2890 public:
2891   virtual bool fold_range (irange &r, tree type,
2892 			   const irange &op1,
2893 			   const irange &op2) const;
2894 } op_integer_cst;
2895 
2896 bool
fold_range(irange & r,tree type ATTRIBUTE_UNUSED,const irange & lh,const irange & rh ATTRIBUTE_UNUSED) const2897 operator_cst::fold_range (irange &r, tree type ATTRIBUTE_UNUSED,
2898 			  const irange &lh,
2899 			  const irange &rh ATTRIBUTE_UNUSED) const
2900 {
2901   r = lh;
2902   return true;
2903 }
2904 
2905 
2906 class operator_identity : public range_operator
2907 {
2908 public:
2909   virtual bool fold_range (irange &r, tree type,
2910 			   const irange &op1,
2911 			   const irange &op2) const;
2912   virtual bool op1_range (irange &r, tree type,
2913 			  const irange &lhs,
2914 			  const irange &op2) const;
2915 } op_identity;
2916 
2917 bool
fold_range(irange & r,tree type ATTRIBUTE_UNUSED,const irange & lh,const irange & rh ATTRIBUTE_UNUSED) const2918 operator_identity::fold_range (irange &r, tree type ATTRIBUTE_UNUSED,
2919 			       const irange &lh,
2920 			       const irange &rh ATTRIBUTE_UNUSED) const
2921 {
2922   r = lh;
2923   return true;
2924 }
2925 
2926 bool
op1_range(irange & r,tree type ATTRIBUTE_UNUSED,const irange & lhs,const irange & op2 ATTRIBUTE_UNUSED) const2927 operator_identity::op1_range (irange &r, tree type ATTRIBUTE_UNUSED,
2928 			      const irange &lhs,
2929 			      const irange &op2 ATTRIBUTE_UNUSED) const
2930 {
2931   r = lhs;
2932   return true;
2933 }
2934 
2935 
2936 class operator_unknown : public range_operator
2937 {
2938 public:
2939   virtual bool fold_range (irange &r, tree type,
2940 			   const irange &op1,
2941 			   const irange &op2) const;
2942 } op_unknown;
2943 
2944 bool
fold_range(irange & r,tree type,const irange & lh ATTRIBUTE_UNUSED,const irange & rh ATTRIBUTE_UNUSED) const2945 operator_unknown::fold_range (irange &r, tree type,
2946 			      const irange &lh ATTRIBUTE_UNUSED,
2947 			      const irange &rh ATTRIBUTE_UNUSED) const
2948 {
2949   r.set_varying (type);
2950   return true;
2951 }
2952 
2953 
2954 class operator_abs : public range_operator
2955 {
2956  public:
2957   virtual void wi_fold (irange &r, tree type,
2958 		        const wide_int &lh_lb,
2959 		        const wide_int &lh_ub,
2960 		        const wide_int &rh_lb,
2961 		        const wide_int &rh_ub) const;
2962   virtual bool op1_range (irange &r, tree type,
2963 			  const irange &lhs,
2964 			  const irange &op2) const;
2965 } op_abs;
2966 
2967 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb ATTRIBUTE_UNUSED,const wide_int & rh_ub ATTRIBUTE_UNUSED) const2968 operator_abs::wi_fold (irange &r, tree type,
2969 		       const wide_int &lh_lb, const wide_int &lh_ub,
2970 		       const wide_int &rh_lb ATTRIBUTE_UNUSED,
2971 		       const wide_int &rh_ub ATTRIBUTE_UNUSED) const
2972 {
2973   wide_int min, max;
2974   signop sign = TYPE_SIGN (type);
2975   unsigned prec = TYPE_PRECISION (type);
2976 
2977   // Pass through LH for the easy cases.
2978   if (sign == UNSIGNED || wi::ge_p (lh_lb, 0, sign))
2979     {
2980       r = int_range<1> (type, lh_lb, lh_ub);
2981       return;
2982     }
2983 
2984   // -TYPE_MIN_VALUE = TYPE_MIN_VALUE with flag_wrapv so we can't get
2985   // a useful range.
2986   wide_int min_value = wi::min_value (prec, sign);
2987   wide_int max_value = wi::max_value (prec, sign);
2988   if (!TYPE_OVERFLOW_UNDEFINED (type) && wi::eq_p (lh_lb, min_value))
2989     {
2990       r.set_varying (type);
2991       return;
2992     }
2993 
2994   // ABS_EXPR may flip the range around, if the original range
2995   // included negative values.
2996   if (wi::eq_p (lh_lb, min_value))
2997     {
2998       // ABS ([-MIN, -MIN]) isn't representable, but we have traditionally
2999       // returned [-MIN,-MIN] so this preserves that behaviour.  PR37078
3000       if (wi::eq_p (lh_ub, min_value))
3001 	{
3002 	  r = int_range<1> (type, min_value, min_value);
3003 	  return;
3004 	}
3005       min = max_value;
3006     }
3007   else
3008     min = wi::abs (lh_lb);
3009 
3010   if (wi::eq_p (lh_ub, min_value))
3011     max = max_value;
3012   else
3013     max = wi::abs (lh_ub);
3014 
3015   // If the range contains zero then we know that the minimum value in the
3016   // range will be zero.
3017   if (wi::le_p (lh_lb, 0, sign) && wi::ge_p (lh_ub, 0, sign))
3018     {
3019       if (wi::gt_p (min, max, sign))
3020 	max = min;
3021       min = wi::zero (prec);
3022     }
3023   else
3024     {
3025       // If the range was reversed, swap MIN and MAX.
3026       if (wi::gt_p (min, max, sign))
3027 	std::swap (min, max);
3028     }
3029 
3030   // If the new range has its limits swapped around (MIN > MAX), then
3031   // the operation caused one of them to wrap around.  The only thing
3032   // we know is that the result is positive.
3033   if (wi::gt_p (min, max, sign))
3034     {
3035       min = wi::zero (prec);
3036       max = max_value;
3037     }
3038   r = int_range<1> (type, min, max);
3039 }
3040 
3041 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const3042 operator_abs::op1_range (irange &r, tree type,
3043 			 const irange &lhs,
3044 			 const irange &op2) const
3045 {
3046   if (empty_range_varying (r, type, lhs, op2))
3047     return true;
3048   if (TYPE_UNSIGNED (type))
3049     {
3050       r = lhs;
3051       return true;
3052     }
3053   // Start with the positives because negatives are an impossible result.
3054   int_range_max positives = range_positives (type);
3055   positives.intersect (lhs);
3056   r = positives;
3057   // Then add the negative of each pair:
3058   // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
3059   for (unsigned i = 0; i < positives.num_pairs (); ++i)
3060     r.union_ (int_range<1> (type,
3061 			    -positives.upper_bound (i),
3062 			    -positives.lower_bound (i)));
3063   return true;
3064 }
3065 
3066 
3067 class operator_absu : public range_operator
3068 {
3069  public:
3070   virtual void wi_fold (irange &r, tree type,
3071 			const wide_int &lh_lb, const wide_int &lh_ub,
3072 			const wide_int &rh_lb, const wide_int &rh_ub) const;
3073 } op_absu;
3074 
3075 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb ATTRIBUTE_UNUSED,const wide_int & rh_ub ATTRIBUTE_UNUSED) const3076 operator_absu::wi_fold (irange &r, tree type,
3077 			const wide_int &lh_lb, const wide_int &lh_ub,
3078 			const wide_int &rh_lb ATTRIBUTE_UNUSED,
3079 			const wide_int &rh_ub ATTRIBUTE_UNUSED) const
3080 {
3081   wide_int new_lb, new_ub;
3082 
3083   // Pass through VR0 the easy cases.
3084   if (wi::ges_p (lh_lb, 0))
3085     {
3086       new_lb = lh_lb;
3087       new_ub = lh_ub;
3088     }
3089   else
3090     {
3091       new_lb = wi::abs (lh_lb);
3092       new_ub = wi::abs (lh_ub);
3093 
3094       // If the range contains zero then we know that the minimum
3095       // value in the range will be zero.
3096       if (wi::ges_p (lh_ub, 0))
3097 	{
3098 	  if (wi::gtu_p (new_lb, new_ub))
3099 	    new_ub = new_lb;
3100 	  new_lb = wi::zero (TYPE_PRECISION (type));
3101 	}
3102       else
3103 	std::swap (new_lb, new_ub);
3104     }
3105 
3106   gcc_checking_assert (TYPE_UNSIGNED (type));
3107   r = int_range<1> (type, new_lb, new_ub);
3108 }
3109 
3110 
3111 class operator_negate : public range_operator
3112 {
3113  public:
3114   virtual bool fold_range (irange &r, tree type,
3115 			   const irange &op1,
3116 			   const irange &op2) const;
3117   virtual bool op1_range (irange &r, tree type,
3118 			  const irange &lhs,
3119 			  const irange &op2) const;
3120 } op_negate;
3121 
3122 bool
fold_range(irange & r,tree type,const irange & lh,const irange & rh) const3123 operator_negate::fold_range (irange &r, tree type,
3124 			     const irange &lh,
3125 			     const irange &rh) const
3126 {
3127   if (empty_range_varying (r, type, lh, rh))
3128     return true;
3129   // -X is simply 0 - X.
3130   return range_op_handler (MINUS_EXPR, type)->fold_range (r, type,
3131 							  range_zero (type),
3132 							  lh);
3133 }
3134 
3135 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const3136 operator_negate::op1_range (irange &r, tree type,
3137 			    const irange &lhs,
3138 			    const irange &op2) const
3139 {
3140   // NEGATE is involutory.
3141   return fold_range (r, type, lhs, op2);
3142 }
3143 
3144 
3145 class operator_addr_expr : public range_operator
3146 {
3147 public:
3148   virtual bool fold_range (irange &r, tree type,
3149 			   const irange &op1,
3150 			   const irange &op2) const;
3151   virtual bool op1_range (irange &r, tree type,
3152 			  const irange &lhs,
3153 			  const irange &op2) const;
3154 } op_addr;
3155 
3156 bool
fold_range(irange & r,tree type,const irange & lh,const irange & rh) const3157 operator_addr_expr::fold_range (irange &r, tree type,
3158 				const irange &lh,
3159 				const irange &rh) const
3160 {
3161   if (empty_range_varying (r, type, lh, rh))
3162     return true;
3163 
3164   // Return a non-null pointer of the LHS type (passed in op2).
3165   if (lh.zero_p ())
3166     r = range_zero (type);
3167   else if (!lh.contains_p (build_zero_cst (lh.type ())))
3168     r = range_nonzero (type);
3169   else
3170     r.set_varying (type);
3171   return true;
3172 }
3173 
3174 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2) const3175 operator_addr_expr::op1_range (irange &r, tree type,
3176 			       const irange &lhs,
3177 			       const irange &op2) const
3178 {
3179   return operator_addr_expr::fold_range (r, type, lhs, op2);
3180 }
3181 
3182 
3183 class pointer_plus_operator : public range_operator
3184 {
3185 public:
3186   virtual void wi_fold (irange &r, tree type,
3187 		        const wide_int &lh_lb,
3188 		        const wide_int &lh_ub,
3189 		        const wide_int &rh_lb,
3190 		        const wide_int &rh_ub) const;
3191 } op_pointer_plus;
3192 
3193 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const3194 pointer_plus_operator::wi_fold (irange &r, tree type,
3195 				const wide_int &lh_lb,
3196 				const wide_int &lh_ub,
3197 				const wide_int &rh_lb,
3198 				const wide_int &rh_ub) const
3199 {
3200   // Check for [0,0] + const, and simply return the const.
3201   if (lh_lb == 0 && lh_ub == 0 && rh_lb == rh_ub)
3202     {
3203       tree val = wide_int_to_tree (type, rh_lb);
3204       r.set (val, val);
3205       return;
3206     }
3207 
3208   // For pointer types, we are really only interested in asserting
3209   // whether the expression evaluates to non-NULL.
3210   //
3211   // With -fno-delete-null-pointer-checks we need to be more
3212   // conservative.  As some object might reside at address 0,
3213   // then some offset could be added to it and the same offset
3214   // subtracted again and the result would be NULL.
3215   // E.g.
3216   // static int a[12]; where &a[0] is NULL and
3217   // ptr = &a[6];
3218   // ptr -= 6;
3219   // ptr will be NULL here, even when there is POINTER_PLUS_EXPR
3220   // where the first range doesn't include zero and the second one
3221   // doesn't either.  As the second operand is sizetype (unsigned),
3222   // consider all ranges where the MSB could be set as possible
3223   // subtractions where the result might be NULL.
3224   if ((!wi_includes_zero_p (type, lh_lb, lh_ub)
3225        || !wi_includes_zero_p (type, rh_lb, rh_ub))
3226       && !TYPE_OVERFLOW_WRAPS (type)
3227       && (flag_delete_null_pointer_checks
3228 	  || !wi::sign_mask (rh_ub)))
3229     r = range_nonzero (type);
3230   else if (lh_lb == lh_ub && lh_lb == 0
3231 	   && rh_lb == rh_ub && rh_lb == 0)
3232     r = range_zero (type);
3233   else
3234    r.set_varying (type);
3235 }
3236 
3237 
3238 class pointer_min_max_operator : public range_operator
3239 {
3240 public:
3241   virtual void wi_fold (irange & r, tree type,
3242 			const wide_int &lh_lb, const wide_int &lh_ub,
3243 			const wide_int &rh_lb, const wide_int &rh_ub) const;
3244 } op_ptr_min_max;
3245 
3246 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const3247 pointer_min_max_operator::wi_fold (irange &r, tree type,
3248 				   const wide_int &lh_lb,
3249 				   const wide_int &lh_ub,
3250 				   const wide_int &rh_lb,
3251 				   const wide_int &rh_ub) const
3252 {
3253   // For MIN/MAX expressions with pointers, we only care about
3254   // nullness.  If both are non null, then the result is nonnull.
3255   // If both are null, then the result is null.  Otherwise they
3256   // are varying.
3257   if (!wi_includes_zero_p (type, lh_lb, lh_ub)
3258       && !wi_includes_zero_p (type, rh_lb, rh_ub))
3259     r = range_nonzero (type);
3260   else if (wi_zero_p (type, lh_lb, lh_ub) && wi_zero_p (type, rh_lb, rh_ub))
3261     r = range_zero (type);
3262   else
3263     r.set_varying (type);
3264 }
3265 
3266 
3267 class pointer_and_operator : public range_operator
3268 {
3269 public:
3270   virtual void wi_fold (irange &r, tree type,
3271 			const wide_int &lh_lb, const wide_int &lh_ub,
3272 			const wide_int &rh_lb, const wide_int &rh_ub) const;
3273 } op_pointer_and;
3274 
3275 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb ATTRIBUTE_UNUSED,const wide_int & rh_ub ATTRIBUTE_UNUSED) const3276 pointer_and_operator::wi_fold (irange &r, tree type,
3277 			       const wide_int &lh_lb,
3278 			       const wide_int &lh_ub,
3279 			       const wide_int &rh_lb ATTRIBUTE_UNUSED,
3280 			       const wide_int &rh_ub ATTRIBUTE_UNUSED) const
3281 {
3282   // For pointer types, we are really only interested in asserting
3283   // whether the expression evaluates to non-NULL.
3284   if (wi_zero_p (type, lh_lb, lh_ub) || wi_zero_p (type, lh_lb, lh_ub))
3285     r = range_zero (type);
3286   else
3287     r.set_varying (type);
3288 }
3289 
3290 
3291 class pointer_or_operator : public range_operator
3292 {
3293 public:
3294   virtual bool op1_range (irange &r, tree type,
3295 			  const irange &lhs,
3296 			  const irange &op2) const;
3297   virtual bool op2_range (irange &r, tree type,
3298 			  const irange &lhs,
3299 			  const irange &op1) const;
3300   virtual void wi_fold (irange &r, tree type,
3301 			const wide_int &lh_lb, const wide_int &lh_ub,
3302 			const wide_int &rh_lb, const wide_int &rh_ub) const;
3303 } op_pointer_or;
3304 
3305 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2 ATTRIBUTE_UNUSED) const3306 pointer_or_operator::op1_range (irange &r, tree type,
3307 				const irange &lhs,
3308 				const irange &op2 ATTRIBUTE_UNUSED) const
3309 {
3310   if (lhs.zero_p ())
3311     {
3312       tree zero = build_zero_cst (type);
3313       r = int_range<1> (zero, zero);
3314       return true;
3315     }
3316   r.set_varying (type);
3317   return true;
3318 }
3319 
3320 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1) const3321 pointer_or_operator::op2_range (irange &r, tree type,
3322 				const irange &lhs,
3323 				const irange &op1) const
3324 {
3325   return pointer_or_operator::op1_range (r, type, lhs, op1);
3326 }
3327 
3328 void
wi_fold(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const3329 pointer_or_operator::wi_fold (irange &r, tree type,
3330 			      const wide_int &lh_lb,
3331 			      const wide_int &lh_ub,
3332 			      const wide_int &rh_lb,
3333 			      const wide_int &rh_ub) const
3334 {
3335   // For pointer types, we are really only interested in asserting
3336   // whether the expression evaluates to non-NULL.
3337   if (!wi_includes_zero_p (type, lh_lb, lh_ub)
3338       && !wi_includes_zero_p (type, rh_lb, rh_ub))
3339     r = range_nonzero (type);
3340   else if (wi_zero_p (type, lh_lb, lh_ub) && wi_zero_p (type, rh_lb, rh_ub))
3341     r = range_zero (type);
3342   else
3343     r.set_varying (type);
3344 }
3345 
3346 // This implements the range operator tables as local objects in this file.
3347 
3348 class range_op_table
3349 {
3350 public:
3351   inline range_operator *operator[] (enum tree_code code);
3352 protected:
3353   void set (enum tree_code code, range_operator &op);
3354 private:
3355   range_operator *m_range_tree[MAX_TREE_CODES];
3356 };
3357 
3358 // Return a pointer to the range_operator instance, if there is one
3359 // associated with tree_code CODE.
3360 
3361 range_operator *
operator [](enum tree_code code)3362 range_op_table::operator[] (enum tree_code code)
3363 {
3364   gcc_checking_assert (code > 0 && code < MAX_TREE_CODES);
3365   return m_range_tree[code];
3366 }
3367 
3368 // Add OP to the handler table for CODE.
3369 
3370 void
set(enum tree_code code,range_operator & op)3371 range_op_table::set (enum tree_code code, range_operator &op)
3372 {
3373   gcc_checking_assert (m_range_tree[code] == NULL);
3374   m_range_tree[code] = &op;
3375 }
3376 
3377 // Instantiate a range op table for integral operations.
3378 
3379 class integral_table : public range_op_table
3380 {
3381 public:
3382   integral_table ();
3383 } integral_tree_table;
3384 
integral_table()3385 integral_table::integral_table ()
3386 {
3387   set (EQ_EXPR, op_equal);
3388   set (NE_EXPR, op_not_equal);
3389   set (LT_EXPR, op_lt);
3390   set (LE_EXPR, op_le);
3391   set (GT_EXPR, op_gt);
3392   set (GE_EXPR, op_ge);
3393   set (PLUS_EXPR, op_plus);
3394   set (MINUS_EXPR, op_minus);
3395   set (MIN_EXPR, op_min);
3396   set (MAX_EXPR, op_max);
3397   set (MULT_EXPR, op_mult);
3398   set (TRUNC_DIV_EXPR, op_trunc_div);
3399   set (FLOOR_DIV_EXPR, op_floor_div);
3400   set (ROUND_DIV_EXPR, op_round_div);
3401   set (CEIL_DIV_EXPR, op_ceil_div);
3402   set (EXACT_DIV_EXPR, op_exact_div);
3403   set (LSHIFT_EXPR, op_lshift);
3404   set (RSHIFT_EXPR, op_rshift);
3405   set (NOP_EXPR, op_convert);
3406   set (CONVERT_EXPR, op_convert);
3407   set (TRUTH_AND_EXPR, op_logical_and);
3408   set (BIT_AND_EXPR, op_bitwise_and);
3409   set (TRUTH_OR_EXPR, op_logical_or);
3410   set (BIT_IOR_EXPR, op_bitwise_or);
3411   set (BIT_XOR_EXPR, op_bitwise_xor);
3412   set (TRUNC_MOD_EXPR, op_trunc_mod);
3413   set (TRUTH_NOT_EXPR, op_logical_not);
3414   set (BIT_NOT_EXPR, op_bitwise_not);
3415   set (INTEGER_CST, op_integer_cst);
3416   set (SSA_NAME, op_identity);
3417   set (PAREN_EXPR, op_identity);
3418   set (OBJ_TYPE_REF, op_identity);
3419   set (IMAGPART_EXPR, op_unknown);
3420   set (POINTER_DIFF_EXPR, op_unknown);
3421   set (ABS_EXPR, op_abs);
3422   set (ABSU_EXPR, op_absu);
3423   set (NEGATE_EXPR, op_negate);
3424   set (ADDR_EXPR, op_addr);
3425 }
3426 
3427 // Instantiate a range op table for pointer operations.
3428 
3429 class pointer_table : public range_op_table
3430 {
3431 public:
3432   pointer_table ();
3433 } pointer_tree_table;
3434 
pointer_table()3435 pointer_table::pointer_table ()
3436 {
3437   set (BIT_AND_EXPR, op_pointer_and);
3438   set (BIT_IOR_EXPR, op_pointer_or);
3439   set (MIN_EXPR, op_ptr_min_max);
3440   set (MAX_EXPR, op_ptr_min_max);
3441   set (POINTER_PLUS_EXPR, op_pointer_plus);
3442 
3443   set (EQ_EXPR, op_equal);
3444   set (NE_EXPR, op_not_equal);
3445   set (LT_EXPR, op_lt);
3446   set (LE_EXPR, op_le);
3447   set (GT_EXPR, op_gt);
3448   set (GE_EXPR, op_ge);
3449   set (SSA_NAME, op_identity);
3450   set (INTEGER_CST, op_integer_cst);
3451   set (ADDR_EXPR, op_addr);
3452   set (NOP_EXPR, op_convert);
3453   set (CONVERT_EXPR, op_convert);
3454 
3455   set (BIT_NOT_EXPR, op_bitwise_not);
3456   set (BIT_XOR_EXPR, op_bitwise_xor);
3457 }
3458 
3459 // The tables are hidden and accessed via a simple extern function.
3460 
3461 range_operator *
range_op_handler(enum tree_code code,tree type)3462 range_op_handler (enum tree_code code, tree type)
3463 {
3464   // First check if there is a pointer specialization.
3465   if (POINTER_TYPE_P (type))
3466     return pointer_tree_table[code];
3467   if (INTEGRAL_TYPE_P (type))
3468     return integral_tree_table[code];
3469   return NULL;
3470 }
3471 
3472 // Cast the range in R to TYPE.
3473 
3474 void
range_cast(irange & r,tree type)3475 range_cast (irange &r, tree type)
3476 {
3477   int_range_max tmp = r;
3478   range_operator *op = range_op_handler (CONVERT_EXPR, type);
3479   // Call op_convert, if it fails, the result is varying.
3480   if (!op->fold_range (r, type, tmp, int_range<1> (type)))
3481     r.set_varying (type);
3482 }
3483 
3484 #if CHECKING_P
3485 #include "selftest.h"
3486 
3487 namespace selftest
3488 {
3489 #define INT(N) build_int_cst (integer_type_node, (N))
3490 #define UINT(N) build_int_cstu (unsigned_type_node, (N))
3491 #define INT16(N) build_int_cst (short_integer_type_node, (N))
3492 #define UINT16(N) build_int_cstu (short_unsigned_type_node, (N))
3493 #define SCHAR(N) build_int_cst (signed_char_type_node, (N))
3494 #define UCHAR(N) build_int_cstu (unsigned_char_type_node, (N))
3495 
3496 static void
range_op_cast_tests()3497 range_op_cast_tests ()
3498 {
3499   int_range<1> r0, r1, r2, rold;
3500   r0.set_varying (integer_type_node);
3501   tree maxint = wide_int_to_tree (integer_type_node, r0.upper_bound ());
3502 
3503   // If a range is in any way outside of the range for the converted
3504   // to range, default to the range for the new type.
3505   r0.set_varying (short_integer_type_node);
3506   tree minshort = wide_int_to_tree (short_integer_type_node, r0.lower_bound ());
3507   tree maxshort = wide_int_to_tree (short_integer_type_node, r0.upper_bound ());
3508   if (TYPE_PRECISION (TREE_TYPE (maxint))
3509       > TYPE_PRECISION (short_integer_type_node))
3510     {
3511       r1 = int_range<1> (integer_zero_node, maxint);
3512       range_cast (r1, short_integer_type_node);
3513       ASSERT_TRUE (r1.lower_bound () == wi::to_wide (minshort)
3514 		   && r1.upper_bound() == wi::to_wide (maxshort));
3515     }
3516 
3517   // (unsigned char)[-5,-1] => [251,255].
3518   r0 = rold = int_range<1> (SCHAR (-5), SCHAR (-1));
3519   range_cast (r0, unsigned_char_type_node);
3520   ASSERT_TRUE (r0 == int_range<1> (UCHAR (251), UCHAR (255)));
3521   range_cast (r0, signed_char_type_node);
3522   ASSERT_TRUE (r0 == rold);
3523 
3524   // (signed char)[15, 150] => [-128,-106][15,127].
3525   r0 = rold = int_range<1> (UCHAR (15), UCHAR (150));
3526   range_cast (r0, signed_char_type_node);
3527   r1 = int_range<1> (SCHAR (15), SCHAR (127));
3528   r2 = int_range<1> (SCHAR (-128), SCHAR (-106));
3529   r1.union_ (r2);
3530   ASSERT_TRUE (r1 == r0);
3531   range_cast (r0, unsigned_char_type_node);
3532   ASSERT_TRUE (r0 == rold);
3533 
3534   // (unsigned char)[-5, 5] => [0,5][251,255].
3535   r0 = rold = int_range<1> (SCHAR (-5), SCHAR (5));
3536   range_cast (r0, unsigned_char_type_node);
3537   r1 = int_range<1> (UCHAR (251), UCHAR (255));
3538   r2 = int_range<1> (UCHAR (0), UCHAR (5));
3539   r1.union_ (r2);
3540   ASSERT_TRUE (r0 == r1);
3541   range_cast (r0, signed_char_type_node);
3542   ASSERT_TRUE (r0 == rold);
3543 
3544   // (unsigned char)[-5,5] => [0,5][251,255].
3545   r0 = int_range<1> (INT (-5), INT (5));
3546   range_cast (r0, unsigned_char_type_node);
3547   r1 = int_range<1> (UCHAR (0), UCHAR (5));
3548   r1.union_ (int_range<1> (UCHAR (251), UCHAR (255)));
3549   ASSERT_TRUE (r0 == r1);
3550 
3551   // (unsigned char)[5U,1974U] => [0,255].
3552   r0 = int_range<1> (UINT (5), UINT (1974));
3553   range_cast (r0, unsigned_char_type_node);
3554   ASSERT_TRUE (r0 == int_range<1> (UCHAR (0), UCHAR (255)));
3555   range_cast (r0, integer_type_node);
3556   // Going to a wider range should not sign extend.
3557   ASSERT_TRUE (r0 == int_range<1> (INT (0), INT (255)));
3558 
3559   // (unsigned char)[-350,15] => [0,255].
3560   r0 = int_range<1> (INT (-350), INT (15));
3561   range_cast (r0, unsigned_char_type_node);
3562   ASSERT_TRUE (r0 == (int_range<1>
3563 		      (TYPE_MIN_VALUE (unsigned_char_type_node),
3564 		       TYPE_MAX_VALUE (unsigned_char_type_node))));
3565 
3566   // Casting [-120,20] from signed char to unsigned short.
3567   // => [0, 20][0xff88, 0xffff].
3568   r0 = int_range<1> (SCHAR (-120), SCHAR (20));
3569   range_cast (r0, short_unsigned_type_node);
3570   r1 = int_range<1> (UINT16 (0), UINT16 (20));
3571   r2 = int_range<1> (UINT16 (0xff88), UINT16 (0xffff));
3572   r1.union_ (r2);
3573   ASSERT_TRUE (r0 == r1);
3574   // A truncating cast back to signed char will work because [-120, 20]
3575   // is representable in signed char.
3576   range_cast (r0, signed_char_type_node);
3577   ASSERT_TRUE (r0 == int_range<1> (SCHAR (-120), SCHAR (20)));
3578 
3579   // unsigned char -> signed short
3580   //	(signed short)[(unsigned char)25, (unsigned char)250]
3581   // => [(signed short)25, (signed short)250]
3582   r0 = rold = int_range<1> (UCHAR (25), UCHAR (250));
3583   range_cast (r0, short_integer_type_node);
3584   r1 = int_range<1> (INT16 (25), INT16 (250));
3585   ASSERT_TRUE (r0 == r1);
3586   range_cast (r0, unsigned_char_type_node);
3587   ASSERT_TRUE (r0 == rold);
3588 
3589   // Test casting a wider signed [-MIN,MAX] to a nar`rower unsigned.
3590   r0 = int_range<1> (TYPE_MIN_VALUE (long_long_integer_type_node),
3591 	       TYPE_MAX_VALUE (long_long_integer_type_node));
3592   range_cast (r0, short_unsigned_type_node);
3593   r1 = int_range<1> (TYPE_MIN_VALUE (short_unsigned_type_node),
3594 	       TYPE_MAX_VALUE (short_unsigned_type_node));
3595   ASSERT_TRUE (r0 == r1);
3596 
3597   // Casting NONZERO to a narrower type will wrap/overflow so
3598   // it's just the entire range for the narrower type.
3599   //
3600   // "NOT 0 at signed 32-bits" ==> [-MIN_32,-1][1, +MAX_32].  This is
3601   // is outside of the range of a smaller range, return the full
3602   // smaller range.
3603   if (TYPE_PRECISION (integer_type_node)
3604       > TYPE_PRECISION (short_integer_type_node))
3605     {
3606       r0 = range_nonzero (integer_type_node);
3607       range_cast (r0, short_integer_type_node);
3608       r1 = int_range<1> (TYPE_MIN_VALUE (short_integer_type_node),
3609 			 TYPE_MAX_VALUE (short_integer_type_node));
3610       ASSERT_TRUE (r0 == r1);
3611     }
3612 
3613   // Casting NONZERO from a narrower signed to a wider signed.
3614   //
3615   // NONZERO signed 16-bits is [-MIN_16,-1][1, +MAX_16].
3616   // Converting this to 32-bits signed is [-MIN_16,-1][1, +MAX_16].
3617   r0 = range_nonzero (short_integer_type_node);
3618   range_cast (r0, integer_type_node);
3619   r1 = int_range<1> (INT (-32768), INT (-1));
3620   r2 = int_range<1> (INT (1), INT (32767));
3621   r1.union_ (r2);
3622   ASSERT_TRUE (r0 == r1);
3623 }
3624 
3625 static void
range_op_lshift_tests()3626 range_op_lshift_tests ()
3627 {
3628   // Test that 0x808.... & 0x8.... still contains 0x8....
3629   // for a large set of numbers.
3630   {
3631     int_range_max res;
3632     tree big_type = long_long_unsigned_type_node;
3633     // big_num = 0x808,0000,0000,0000
3634     tree big_num = fold_build2 (LSHIFT_EXPR, big_type,
3635 				build_int_cst (big_type, 0x808),
3636 				build_int_cst (big_type, 48));
3637     op_bitwise_and.fold_range (res, big_type,
3638 			       int_range <1> (big_type),
3639 			       int_range <1> (big_num, big_num));
3640     // val = 0x8,0000,0000,0000
3641     tree val = fold_build2 (LSHIFT_EXPR, big_type,
3642 			    build_int_cst (big_type, 0x8),
3643 			    build_int_cst (big_type, 48));
3644     ASSERT_TRUE (res.contains_p (val));
3645   }
3646 
3647   if (TYPE_PRECISION (unsigned_type_node) > 31)
3648     {
3649       // unsigned VARYING = op1 << 1 should be VARYING.
3650       int_range<2> lhs (unsigned_type_node);
3651       int_range<2> shift (INT (1), INT (1));
3652       int_range_max op1;
3653       op_lshift.op1_range (op1, unsigned_type_node, lhs, shift);
3654       ASSERT_TRUE (op1.varying_p ());
3655 
3656       // 0 = op1 << 1  should be [0,0], [0x8000000, 0x8000000].
3657       int_range<2> zero (UINT (0), UINT (0));
3658       op_lshift.op1_range (op1, unsigned_type_node, zero, shift);
3659       ASSERT_TRUE (op1.num_pairs () == 2);
3660       // Remove the [0,0] range.
3661       op1.intersect (zero);
3662       ASSERT_TRUE (op1.num_pairs () == 1);
3663       //  op1 << 1   should be [0x8000,0x8000] << 1,
3664       //  which should result in [0,0].
3665       int_range_max result;
3666       op_lshift.fold_range (result, unsigned_type_node, op1, shift);
3667       ASSERT_TRUE (result == zero);
3668     }
3669   // signed VARYING = op1 << 1 should be VARYING.
3670   if (TYPE_PRECISION (integer_type_node) > 31)
3671     {
3672       // unsigned VARYING = op1 << 1  hould be VARYING.
3673       int_range<2> lhs (integer_type_node);
3674       int_range<2> shift (INT (1), INT (1));
3675       int_range_max op1;
3676       op_lshift.op1_range (op1, integer_type_node, lhs, shift);
3677       ASSERT_TRUE (op1.varying_p ());
3678 
3679       //  0 = op1 << 1  should be [0,0], [0x8000000, 0x8000000].
3680       int_range<2> zero (INT (0), INT (0));
3681       op_lshift.op1_range (op1, integer_type_node, zero, shift);
3682       ASSERT_TRUE (op1.num_pairs () == 2);
3683       // Remove the [0,0] range.
3684       op1.intersect (zero);
3685       ASSERT_TRUE (op1.num_pairs () == 1);
3686       //  op1 << 1   shuould be [0x8000,0x8000] << 1,
3687       //  which should result in [0,0].
3688       int_range_max result;
3689       op_lshift.fold_range (result, unsigned_type_node, op1, shift);
3690       ASSERT_TRUE (result == zero);
3691     }
3692 }
3693 
3694 static void
range_op_rshift_tests()3695 range_op_rshift_tests ()
3696 {
3697   // unsigned: [3, MAX] = OP1 >> 1
3698   {
3699     int_range_max lhs (build_int_cst (unsigned_type_node, 3),
3700 		       TYPE_MAX_VALUE (unsigned_type_node));
3701     int_range_max one (build_one_cst (unsigned_type_node),
3702 		       build_one_cst (unsigned_type_node));
3703     int_range_max op1;
3704     op_rshift.op1_range (op1, unsigned_type_node, lhs, one);
3705     ASSERT_FALSE (op1.contains_p (UINT (3)));
3706   }
3707 
3708   // signed: [3, MAX] = OP1 >> 1
3709   {
3710     int_range_max lhs (INT (3), TYPE_MAX_VALUE (integer_type_node));
3711     int_range_max one (INT (1), INT (1));
3712     int_range_max op1;
3713     op_rshift.op1_range (op1, integer_type_node, lhs, one);
3714     ASSERT_FALSE (op1.contains_p (INT (-2)));
3715   }
3716 
3717   // This is impossible, so OP1 should be [].
3718   // signed: [MIN, MIN] = OP1 >> 1
3719   {
3720     int_range_max lhs (TYPE_MIN_VALUE (integer_type_node),
3721 		       TYPE_MIN_VALUE (integer_type_node));
3722     int_range_max one (INT (1), INT (1));
3723     int_range_max op1;
3724     op_rshift.op1_range (op1, integer_type_node, lhs, one);
3725     ASSERT_TRUE (op1.undefined_p ());
3726   }
3727 
3728   // signed: ~[-1] = OP1 >> 31
3729   if (TYPE_PRECISION (integer_type_node) > 31)
3730     {
3731       int_range_max lhs (INT (-1), INT (-1), VR_ANTI_RANGE);
3732       int_range_max shift (INT (31), INT (31));
3733       int_range_max op1;
3734       op_rshift.op1_range (op1, integer_type_node, lhs, shift);
3735       int_range_max negatives = range_negatives (integer_type_node);
3736       negatives.intersect (op1);
3737       ASSERT_TRUE (negatives.undefined_p ());
3738     }
3739 }
3740 
3741 static void
range_op_bitwise_and_tests()3742 range_op_bitwise_and_tests ()
3743 {
3744   int_range_max res;
3745   tree min = vrp_val_min (integer_type_node);
3746   tree max = vrp_val_max (integer_type_node);
3747   tree tiny = fold_build2 (PLUS_EXPR, integer_type_node, min,
3748 			   build_one_cst (integer_type_node));
3749   int_range_max i1 (tiny, max);
3750   int_range_max i2 (build_int_cst (integer_type_node, 255),
3751 		    build_int_cst (integer_type_node, 255));
3752 
3753   // [MIN+1, MAX] = OP1 & 255: OP1 is VARYING
3754   op_bitwise_and.op1_range (res, integer_type_node, i1, i2);
3755   ASSERT_TRUE (res == int_range<1> (integer_type_node));
3756 
3757   // VARYING = OP1 & 255: OP1 is VARYING
3758   i1 = int_range<1> (integer_type_node);
3759   op_bitwise_and.op1_range (res, integer_type_node, i1, i2);
3760   ASSERT_TRUE (res == int_range<1> (integer_type_node));
3761 }
3762 
3763 void
range_op_tests()3764 range_op_tests ()
3765 {
3766   range_op_rshift_tests ();
3767   range_op_lshift_tests ();
3768   range_op_bitwise_and_tests ();
3769   range_op_cast_tests ();
3770 }
3771 
3772 } // namespace selftest
3773 
3774 #endif // CHECKING_P
3775