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 "value-relation.h"
48 #include "range-op.h"
49 
50 // Return the upper limit for a type.
51 
52 static inline wide_int
max_limit(const_tree type)53 max_limit (const_tree type)
54 {
55   return wi::max_value (TYPE_PRECISION (type) , TYPE_SIGN (type));
56 }
57 
58 // Return the lower limit for a type.
59 
60 static inline wide_int
min_limit(const_tree type)61 min_limit (const_tree type)
62 {
63   return wi::min_value (TYPE_PRECISION (type) , TYPE_SIGN (type));
64 }
65 
66 // If the range of either op1 or op2 is undefined, set the result to
67 // varying and return TRUE.  If the caller truely cares about a result,
68 // they should pass in a varying if it has an undefined that it wants
69 // treated as a varying.
70 
71 inline bool
empty_range_varying(irange & r,tree type,const irange & op1,const irange & op2)72 empty_range_varying (irange &r, tree type,
73 		     const irange &op1, const irange & op2)
74 {
75   if (op1.undefined_p () || op2.undefined_p ())
76     {
77       r.set_varying (type);
78       return true;
79     }
80   else
81     return false;
82 }
83 
84 // Return false if shifting by OP is undefined behavior.  Otherwise, return
85 // true and the range it is to be shifted by.  This allows trimming out of
86 // undefined ranges, leaving only valid ranges if there are any.
87 
88 static inline bool
get_shift_range(irange & r,tree type,const irange & op)89 get_shift_range (irange &r, tree type, const irange &op)
90 {
91   if (op.undefined_p ())
92     return false;
93 
94   // Build valid range and intersect it with the shift range.
95   r = value_range (build_int_cst_type (op.type (), 0),
96 		   build_int_cst_type (op.type (), TYPE_PRECISION (type) - 1));
97   r.intersect (op);
98 
99   // If there are no valid ranges in the shift range, returned false.
100   if (r.undefined_p ())
101     return false;
102   return true;
103 }
104 
105 // Return TRUE if 0 is within [WMIN, WMAX].
106 
107 static inline bool
wi_includes_zero_p(tree type,const wide_int & wmin,const wide_int & wmax)108 wi_includes_zero_p (tree type, const wide_int &wmin, const wide_int &wmax)
109 {
110   signop sign = TYPE_SIGN (type);
111   return wi::le_p (wmin, 0, sign) && wi::ge_p (wmax, 0, sign);
112 }
113 
114 // Return TRUE if [WMIN, WMAX] is the singleton 0.
115 
116 static inline bool
wi_zero_p(tree type,const wide_int & wmin,const wide_int & wmax)117 wi_zero_p (tree type, const wide_int &wmin, const wide_int &wmax)
118 {
119   unsigned prec = TYPE_PRECISION (type);
120   return wmin == wmax && wi::eq_p (wmin, wi::zero (prec));
121 }
122 
123 // Default wide_int fold operation returns [MIN, MAX].
124 
125 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) const126 range_operator::wi_fold (irange &r, tree type,
127 			 const wide_int &lh_lb ATTRIBUTE_UNUSED,
128 			 const wide_int &lh_ub ATTRIBUTE_UNUSED,
129 			 const wide_int &rh_lb ATTRIBUTE_UNUSED,
130 			 const wide_int &rh_ub ATTRIBUTE_UNUSED) const
131 {
132   gcc_checking_assert (irange::supports_type_p (type));
133   r.set_varying (type);
134 }
135 
136 // Call wi_fold, except further split small subranges into constants.
137 // This can provide better precision. For something   8 >> [0,1]
138 // Instead of [8, 16], we will produce [8,8][16,16]
139 
140 void
wi_fold_in_parts(irange & r,tree type,const wide_int & lh_lb,const wide_int & lh_ub,const wide_int & rh_lb,const wide_int & rh_ub) const141 range_operator::wi_fold_in_parts (irange &r, tree type,
142 				  const wide_int &lh_lb,
143 				  const wide_int &lh_ub,
144 				  const wide_int &rh_lb,
145 				  const wide_int &rh_ub) const
146 {
147   wi::overflow_type ov_rh, ov_lh;
148   int_range_max tmp;
149   wide_int rh_range = wi::sub (rh_ub, rh_lb, TYPE_SIGN (type), &ov_rh);
150   wide_int lh_range = wi::sub (lh_ub, lh_lb, TYPE_SIGN (type), &ov_lh);
151   signop sign = TYPE_SIGN (type);;
152   // If there are 2, 3, or 4 values in the RH range, do them separately.
153   // Call wi_fold_in_parts to check the RH side.
154   if (wi::gt_p (rh_range, 0, sign) && wi::lt_p (rh_range, 4, sign)
155       && ov_rh == wi::OVF_NONE)
156     {
157       wi_fold_in_parts (r, type, lh_lb, lh_ub, rh_lb, rh_lb);
158       if (wi::gt_p (rh_range, 1, sign))
159 	{
160 	  wi_fold_in_parts (tmp, type, lh_lb, lh_ub, rh_lb + 1, rh_lb + 1);
161 	  r.union_ (tmp);
162 	  if (wi::eq_p (rh_range, 3))
163 	    {
164 	      wi_fold_in_parts (tmp, type, lh_lb, lh_ub, rh_lb + 2, rh_lb + 2);
165 	      r.union_ (tmp);
166 	    }
167 	}
168       wi_fold_in_parts (tmp, type, lh_lb, lh_ub, rh_ub, rh_ub);
169       r.union_ (tmp);
170     }
171   // Otherise check for 2, 3, or 4 values in the LH range and split them up.
172   // The RH side has been checked, so no recursion needed.
173   else if (wi::gt_p (lh_range, 0, sign) && wi::lt_p (lh_range, 4, sign)
174 	   && ov_lh == wi::OVF_NONE)
175     {
176       wi_fold (r, type, lh_lb, lh_lb, rh_lb, rh_ub);
177       if (wi::gt_p (lh_range, 1, sign))
178 	{
179 	  wi_fold (tmp, type, lh_lb + 1, lh_lb + 1, rh_lb, rh_ub);
180 	  r.union_ (tmp);
181 	  if (wi::eq_p (lh_range, 3))
182 	    {
183 	      wi_fold (tmp, type, lh_lb + 2, lh_lb + 2, rh_lb, rh_ub);
184 	      r.union_ (tmp);
185 	    }
186 	}
187       wi_fold (tmp, type, lh_ub, lh_ub, rh_lb, rh_ub);
188       r.union_ (tmp);
189     }
190   // Otherwise just call wi_fold.
191   else
192     wi_fold (r, type, lh_lb, lh_ub, rh_lb, rh_ub);
193 }
194 
195 // The default for fold is to break all ranges into sub-ranges and
196 // invoke the wi_fold method on each sub-range pair.
197 
198 bool
fold_range(irange & r,tree type,const irange & lh,const irange & rh,relation_kind rel) const199 range_operator::fold_range (irange &r, tree type,
200 			    const irange &lh,
201 			    const irange &rh,
202 			    relation_kind rel) const
203 {
204   gcc_checking_assert (irange::supports_type_p (type));
205   if (empty_range_varying (r, type, lh, rh))
206     return true;
207 
208   unsigned num_lh = lh.num_pairs ();
209   unsigned num_rh = rh.num_pairs ();
210 
211   // If both ranges are single pairs, fold directly into the result range.
212   if (num_lh == 1 && num_rh == 1)
213     {
214       wi_fold_in_parts (r, type, lh.lower_bound (0), lh.upper_bound (0),
215 			rh.lower_bound (0), rh.upper_bound (0));
216       op1_op2_relation_effect (r, type, lh, rh, rel);
217       return true;
218     }
219 
220   int_range_max tmp;
221   r.set_undefined ();
222   for (unsigned x = 0; x < num_lh; ++x)
223     for (unsigned y = 0; y < num_rh; ++y)
224       {
225 	wide_int lh_lb = lh.lower_bound (x);
226 	wide_int lh_ub = lh.upper_bound (x);
227 	wide_int rh_lb = rh.lower_bound (y);
228 	wide_int rh_ub = rh.upper_bound (y);
229 	wi_fold_in_parts (tmp, type, lh_lb, lh_ub, rh_lb, rh_ub);
230 	r.union_ (tmp);
231 	if (r.varying_p ())
232 	  {
233 	    op1_op2_relation_effect (r, type, lh, rh, rel);
234 	    return true;
235 	  }
236       }
237   op1_op2_relation_effect (r, type, lh, rh, rel);
238   return true;
239 }
240 
241 // The default for op1_range is to return false.
242 
243 bool
op1_range(irange & r ATTRIBUTE_UNUSED,tree type ATTRIBUTE_UNUSED,const irange & lhs ATTRIBUTE_UNUSED,const irange & op2 ATTRIBUTE_UNUSED,relation_kind rel ATTRIBUTE_UNUSED) const244 range_operator::op1_range (irange &r ATTRIBUTE_UNUSED,
245 			   tree type ATTRIBUTE_UNUSED,
246 			   const irange &lhs ATTRIBUTE_UNUSED,
247 			   const irange &op2 ATTRIBUTE_UNUSED,
248 			   relation_kind rel ATTRIBUTE_UNUSED) const
249 {
250   return false;
251 }
252 
253 // The default for op2_range is to return false.
254 
255 bool
op2_range(irange & r ATTRIBUTE_UNUSED,tree type ATTRIBUTE_UNUSED,const irange & lhs ATTRIBUTE_UNUSED,const irange & op1 ATTRIBUTE_UNUSED,relation_kind rel ATTRIBUTE_UNUSED) const256 range_operator::op2_range (irange &r ATTRIBUTE_UNUSED,
257 			   tree type ATTRIBUTE_UNUSED,
258 			   const irange &lhs ATTRIBUTE_UNUSED,
259 			   const irange &op1 ATTRIBUTE_UNUSED,
260 			   relation_kind rel ATTRIBUTE_UNUSED) const
261 {
262   return false;
263 }
264 
265 // The default relation routines return VREL_NONE.
266 
267 enum tree_code
lhs_op1_relation(const irange & lhs ATTRIBUTE_UNUSED,const irange & op1 ATTRIBUTE_UNUSED,const irange & op2 ATTRIBUTE_UNUSED) const268 range_operator::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED,
269 				  const irange &op1 ATTRIBUTE_UNUSED,
270 				  const irange &op2 ATTRIBUTE_UNUSED) const
271 {
272   return VREL_NONE;
273 }
274 
275 enum tree_code
lhs_op2_relation(const irange & lhs ATTRIBUTE_UNUSED,const irange & op1 ATTRIBUTE_UNUSED,const irange & op2 ATTRIBUTE_UNUSED) const276 range_operator::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
277 				  const irange &op1 ATTRIBUTE_UNUSED,
278 				  const irange &op2 ATTRIBUTE_UNUSED) const
279 {
280   return VREL_NONE;
281 }
282 
283 enum tree_code
op1_op2_relation(const irange & lhs ATTRIBUTE_UNUSED) const284 range_operator::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED) const
285 {
286   return VREL_NONE;
287 }
288 
289 // Default is no relation affects the LHS.
290 
291 bool
op1_op2_relation_effect(irange & lhs_range ATTRIBUTE_UNUSED,tree type ATTRIBUTE_UNUSED,const irange & op1_range ATTRIBUTE_UNUSED,const irange & op2_range ATTRIBUTE_UNUSED,relation_kind rel ATTRIBUTE_UNUSED) const292 range_operator::op1_op2_relation_effect (irange &lhs_range ATTRIBUTE_UNUSED,
293 				       tree type ATTRIBUTE_UNUSED,
294 				       const irange &op1_range ATTRIBUTE_UNUSED,
295 				       const irange &op2_range ATTRIBUTE_UNUSED,
296 				       relation_kind rel ATTRIBUTE_UNUSED) const
297 {
298   return false;
299 }
300 
301 // Create and return a range from a pair of wide-ints that are known
302 // to have overflowed (or underflowed).
303 
304 static void
value_range_from_overflowed_bounds(irange & r,tree type,const wide_int & wmin,const wide_int & wmax)305 value_range_from_overflowed_bounds (irange &r, tree type,
306 				    const wide_int &wmin,
307 				    const wide_int &wmax)
308 {
309   const signop sgn = TYPE_SIGN (type);
310   const unsigned int prec = TYPE_PRECISION (type);
311 
312   wide_int tmin = wide_int::from (wmin, prec, sgn);
313   wide_int tmax = wide_int::from (wmax, prec, sgn);
314 
315   bool covers = false;
316   wide_int tem = tmin;
317   tmin = tmax + 1;
318   if (wi::cmp (tmin, tmax, sgn) < 0)
319     covers = true;
320   tmax = tem - 1;
321   if (wi::cmp (tmax, tem, sgn) > 0)
322     covers = true;
323 
324   // If the anti-range would cover nothing, drop to varying.
325   // Likewise if the anti-range bounds are outside of the types
326   // values.
327   if (covers || wi::cmp (tmin, tmax, sgn) > 0)
328     r.set_varying (type);
329   else
330     {
331       tree tree_min = wide_int_to_tree (type, tmin);
332       tree tree_max = wide_int_to_tree (type, tmax);
333       r.set (tree_min, tree_max, VR_ANTI_RANGE);
334     }
335 }
336 
337 // Create and return a range from a pair of wide-ints.  MIN_OVF and
338 // MAX_OVF describe any overflow that might have occurred while
339 // calculating WMIN and WMAX respectively.
340 
341 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)342 value_range_with_overflow (irange &r, tree type,
343 			   const wide_int &wmin, const wide_int &wmax,
344 			   wi::overflow_type min_ovf = wi::OVF_NONE,
345 			   wi::overflow_type max_ovf = wi::OVF_NONE)
346 {
347   const signop sgn = TYPE_SIGN (type);
348   const unsigned int prec = TYPE_PRECISION (type);
349   const bool overflow_wraps = TYPE_OVERFLOW_WRAPS (type);
350 
351   // For one bit precision if max != min, then the range covers all
352   // values.
353   if (prec == 1 && wi::ne_p (wmax, wmin))
354     {
355       r.set_varying (type);
356       return;
357     }
358 
359   if (overflow_wraps)
360     {
361       // If overflow wraps, truncate the values and adjust the range,
362       // kind, and bounds appropriately.
363       if ((min_ovf != wi::OVF_NONE) == (max_ovf != wi::OVF_NONE))
364 	{
365 	  wide_int tmin = wide_int::from (wmin, prec, sgn);
366 	  wide_int tmax = wide_int::from (wmax, prec, sgn);
367 	  // If the limits are swapped, we wrapped around and cover
368 	  // the entire range.
369 	  if (wi::gt_p (tmin, tmax, sgn))
370 	    r.set_varying (type);
371 	  else
372 	    // No overflow or both overflow or underflow.  The range
373 	    // kind stays normal.
374 	    r.set (wide_int_to_tree (type, tmin),
375 		   wide_int_to_tree (type, tmax));
376 	  return;
377 	}
378 
379       if ((min_ovf == wi::OVF_UNDERFLOW && max_ovf == wi::OVF_NONE)
380 	  || (max_ovf == wi::OVF_OVERFLOW && min_ovf == wi::OVF_NONE))
381 	value_range_from_overflowed_bounds (r, type, wmin, wmax);
382       else
383 	// Other underflow and/or overflow, drop to VR_VARYING.
384 	r.set_varying (type);
385     }
386   else
387     {
388       // If both bounds either underflowed or overflowed, then the result
389       // is undefined.
390       if ((min_ovf == wi::OVF_OVERFLOW && max_ovf == wi::OVF_OVERFLOW)
391 	  || (min_ovf == wi::OVF_UNDERFLOW && max_ovf == wi::OVF_UNDERFLOW))
392 	{
393 	  r.set_undefined ();
394 	  return;
395 	}
396 
397       // If overflow does not wrap, saturate to [MIN, MAX].
398       wide_int new_lb, new_ub;
399       if (min_ovf == wi::OVF_UNDERFLOW)
400 	new_lb = wi::min_value (prec, sgn);
401       else if (min_ovf == wi::OVF_OVERFLOW)
402 	new_lb = wi::max_value (prec, sgn);
403       else
404         new_lb = wmin;
405 
406       if (max_ovf == wi::OVF_UNDERFLOW)
407 	new_ub = wi::min_value (prec, sgn);
408       else if (max_ovf == wi::OVF_OVERFLOW)
409 	new_ub = wi::max_value (prec, sgn);
410       else
411         new_ub = wmax;
412 
413       r.set (wide_int_to_tree (type, new_lb),
414 	     wide_int_to_tree (type, new_ub));
415     }
416 }
417 
418 // Create and return a range from a pair of wide-ints.  Canonicalize
419 // the case where the bounds are swapped.  In which case, we transform
420 // [10,5] into [MIN,5][10,MAX].
421 
422 static inline void
create_possibly_reversed_range(irange & r,tree type,const wide_int & new_lb,const wide_int & new_ub)423 create_possibly_reversed_range (irange &r, tree type,
424 				const wide_int &new_lb, const wide_int &new_ub)
425 {
426   signop s = TYPE_SIGN (type);
427   // If the bounds are swapped, treat the result as if an overflow occured.
428   if (wi::gt_p (new_lb, new_ub, s))
429     value_range_from_overflowed_bounds (r, type, new_lb, new_ub);
430   else
431     // Otherwise it's just a normal range.
432     r.set (wide_int_to_tree (type, new_lb), wide_int_to_tree (type, new_ub));
433 }
434 
435 // Return an irange instance that is a boolean TRUE.
436 
437 static inline int_range<1>
range_true(tree type)438 range_true (tree type)
439 {
440   unsigned prec = TYPE_PRECISION (type);
441   return int_range<1> (type, wi::one (prec), wi::one (prec));
442 }
443 
444 // Return an irange instance that is a boolean FALSE.
445 
446 static inline int_range<1>
range_false(tree type)447 range_false (tree type)
448 {
449   unsigned prec = TYPE_PRECISION (type);
450   return int_range<1> (type, wi::zero (prec), wi::zero (prec));
451 }
452 
453 // Return an irange that covers both true and false.
454 
455 static inline int_range<1>
range_true_and_false(tree type)456 range_true_and_false (tree type)
457 {
458   unsigned prec = TYPE_PRECISION (type);
459   return int_range<1> (type, wi::zero (prec), wi::one (prec));
460 }
461 
462 enum bool_range_state { BRS_FALSE, BRS_TRUE, BRS_EMPTY, BRS_FULL };
463 
464 // Return the summary information about boolean range LHS.  If EMPTY/FULL,
465 // return the equivalent range for TYPE in R; if FALSE/TRUE, do nothing.
466 
467 static bool_range_state
get_bool_state(irange & r,const irange & lhs,tree val_type)468 get_bool_state (irange &r, const irange &lhs, tree val_type)
469 {
470   // If there is no result, then this is unexecutable.
471   if (lhs.undefined_p ())
472     {
473       r.set_undefined ();
474       return BRS_EMPTY;
475     }
476 
477   if (lhs.zero_p ())
478     return BRS_FALSE;
479 
480   // For TRUE, we can't just test for [1,1] because Ada can have
481   // multi-bit booleans, and TRUE values can be: [1, MAX], ~[0], etc.
482   if (lhs.contains_p (build_zero_cst (lhs.type ())))
483     {
484       r.set_varying (val_type);
485       return BRS_FULL;
486     }
487 
488   return BRS_TRUE;
489 }
490 
491 // For relation opcodes, first try to see if the supplied relation
492 // forces a true or false result, and return that.
493 // Then check for undefined operands.  If none of this applies,
494 // return false.
495 
496 static inline bool
relop_early_resolve(irange & r,tree type,const irange & op1,const irange & op2,relation_kind rel,relation_kind my_rel)497 relop_early_resolve (irange &r, tree type, const irange &op1,
498 		     const irange &op2, relation_kind rel,
499 		     relation_kind my_rel)
500 {
501   // If known relation is a complete subset of this relation, always true.
502   if (relation_union (rel, my_rel) == my_rel)
503     {
504       r = range_true (type);
505       return true;
506     }
507 
508   // If known relation has no subset of this relation, always false.
509   if (relation_intersect (rel, my_rel) == VREL_EMPTY)
510     {
511       r = range_false (type);
512       return true;
513     }
514 
515   // If either operand is undefined, return VARYING.
516   if (empty_range_varying (r, type, op1, op2))
517     return true;
518 
519   return false;
520 }
521 
522 
523 class operator_equal : public range_operator
524 {
525 public:
526   virtual bool fold_range (irange &r, tree type,
527 			   const irange &op1,
528 			   const irange &op2,
529 			   relation_kind rel = VREL_NONE) const;
530   virtual bool op1_range (irange &r, tree type,
531 			  const irange &lhs,
532 			  const irange &val,
533 			  relation_kind rel = VREL_NONE) const;
534   virtual bool op2_range (irange &r, tree type,
535 			  const irange &lhs,
536 			  const irange &val,
537 			  relation_kind rel = VREL_NONE) const;
538   virtual enum tree_code op1_op2_relation (const irange &lhs) const;
539 } op_equal;
540 
541 // Check if the LHS range indicates a relation between OP1 and OP2.
542 
543 enum tree_code
op1_op2_relation(const irange & lhs) const544 operator_equal::op1_op2_relation (const irange &lhs) const
545 {
546   if (lhs.undefined_p ())
547     return VREL_EMPTY;
548 
549   // FALSE = op1 == op2 indicates NE_EXPR.
550   if (lhs.zero_p ())
551     return NE_EXPR;
552 
553   // TRUE = op1 == op2 indicates EQ_EXPR.
554   if (!lhs.contains_p (build_zero_cst (lhs.type ())))
555     return EQ_EXPR;
556   return VREL_NONE;
557 }
558 
559 
560 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2,relation_kind rel) const561 operator_equal::fold_range (irange &r, tree type,
562 			    const irange &op1,
563 			    const irange &op2,
564 			    relation_kind rel) const
565 {
566   if (relop_early_resolve (r, type, op1, op2, rel, EQ_EXPR))
567     return true;
568 
569   // We can be sure the values are always equal or not if both ranges
570   // consist of a single value, and then compare them.
571   if (wi::eq_p (op1.lower_bound (), op1.upper_bound ())
572       && wi::eq_p (op2.lower_bound (), op2.upper_bound ()))
573     {
574       if (wi::eq_p (op1.lower_bound (), op2.upper_bound()))
575 	r = range_true (type);
576       else
577 	r = range_false (type);
578     }
579   else
580     {
581       // If ranges do not intersect, we know the range is not equal,
582       // otherwise we don't know anything for sure.
583       int_range_max tmp = op1;
584       tmp.intersect (op2);
585       if (tmp.undefined_p ())
586 	r = range_false (type);
587       else
588 	r = range_true_and_false (type);
589     }
590   return true;
591 }
592 
593 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const594 operator_equal::op1_range (irange &r, tree type,
595 			   const irange &lhs,
596 			   const irange &op2,
597 			   relation_kind rel ATTRIBUTE_UNUSED) const
598 {
599   switch (get_bool_state (r, lhs, type))
600     {
601     case BRS_FALSE:
602       // If the result is false, the only time we know anything is
603       // if OP2 is a constant.
604       if (wi::eq_p (op2.lower_bound(), op2.upper_bound()))
605 	{
606 	  r = op2;
607 	  r.invert ();
608 	}
609       else
610 	r.set_varying (type);
611       break;
612 
613     case BRS_TRUE:
614       // If it's true, the result is the same as OP2.
615       r = op2;
616       break;
617 
618     default:
619       break;
620     }
621   return true;
622 }
623 
624 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1,relation_kind rel) const625 operator_equal::op2_range (irange &r, tree type,
626 			   const irange &lhs,
627 			   const irange &op1,
628 			   relation_kind rel) const
629 {
630   return operator_equal::op1_range (r, type, lhs, op1, rel);
631 }
632 
633 class operator_not_equal : public range_operator
634 {
635 public:
636   virtual bool fold_range (irange &r, tree type,
637 			   const irange &op1,
638 			   const irange &op2,
639 			   relation_kind rel = VREL_NONE) const;
640   virtual bool op1_range (irange &r, tree type,
641 			  const irange &lhs,
642 			  const irange &op2,
643 			  relation_kind rel = VREL_NONE) const;
644   virtual bool op2_range (irange &r, tree type,
645 			  const irange &lhs,
646 			  const irange &op1,
647 			  relation_kind rel = VREL_NONE) const;
648   virtual enum tree_code op1_op2_relation (const irange &lhs) const;
649 } op_not_equal;
650 
651 // Check if the LHS range indicates a relation between OP1 and OP2.
652 
653 enum tree_code
op1_op2_relation(const irange & lhs) const654 operator_not_equal::op1_op2_relation (const irange &lhs) const
655 {
656   if (lhs.undefined_p ())
657     return VREL_EMPTY;
658 
659   // FALSE = op1 != op2  indicates EQ_EXPR.
660   if (lhs.zero_p ())
661     return EQ_EXPR;
662 
663   // TRUE = op1 != op2  indicates NE_EXPR.
664   if (!lhs.contains_p (build_zero_cst (lhs.type ())))
665     return NE_EXPR;
666   return VREL_NONE;
667 }
668 
669 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2,relation_kind rel) const670 operator_not_equal::fold_range (irange &r, tree type,
671 				const irange &op1,
672 				const irange &op2,
673 				relation_kind rel) const
674 {
675   if (relop_early_resolve (r, type, op1, op2, rel, NE_EXPR))
676     return true;
677 
678   // We can be sure the values are always equal or not if both ranges
679   // consist of a single value, and then compare them.
680   if (wi::eq_p (op1.lower_bound (), op1.upper_bound ())
681       && wi::eq_p (op2.lower_bound (), op2.upper_bound ()))
682     {
683       if (wi::ne_p (op1.lower_bound (), op2.upper_bound()))
684 	r = range_true (type);
685       else
686 	r = range_false (type);
687     }
688   else
689     {
690       // If ranges do not intersect, we know the range is not equal,
691       // otherwise we don't know anything for sure.
692       int_range_max tmp = op1;
693       tmp.intersect (op2);
694       if (tmp.undefined_p ())
695 	r = range_true (type);
696       else
697 	r = range_true_and_false (type);
698     }
699   return true;
700 }
701 
702 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const703 operator_not_equal::op1_range (irange &r, tree type,
704 			       const irange &lhs,
705 			       const irange &op2,
706 			       relation_kind rel ATTRIBUTE_UNUSED) const
707 {
708   switch (get_bool_state (r, lhs, type))
709     {
710     case BRS_TRUE:
711       // If the result is true, the only time we know anything is if
712       // OP2 is a constant.
713       if (wi::eq_p (op2.lower_bound(), op2.upper_bound()))
714 	{
715 	  r = op2;
716 	  r.invert ();
717 	}
718       else
719 	r.set_varying (type);
720       break;
721 
722     case BRS_FALSE:
723       // If it's false, the result is the same as OP2.
724       r = op2;
725       break;
726 
727     default:
728       break;
729     }
730   return true;
731 }
732 
733 
734 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1,relation_kind rel) const735 operator_not_equal::op2_range (irange &r, tree type,
736 			       const irange &lhs,
737 			       const irange &op1,
738 			       relation_kind rel) const
739 {
740   return operator_not_equal::op1_range (r, type, lhs, op1, rel);
741 }
742 
743 // (X < VAL) produces the range of [MIN, VAL - 1].
744 
745 static void
build_lt(irange & r,tree type,const wide_int & val)746 build_lt (irange &r, tree type, const wide_int &val)
747 {
748   wi::overflow_type ov;
749   wide_int lim;
750   signop sgn = TYPE_SIGN (type);
751 
752   // Signed 1 bit cannot represent 1 for subtraction.
753   if (sgn == SIGNED)
754     lim = wi::add (val, -1, sgn, &ov);
755   else
756     lim = wi::sub (val, 1, sgn, &ov);
757 
758   // If val - 1 underflows, check if X < MIN, which is an empty range.
759   if (ov)
760     r.set_undefined ();
761   else
762     r = int_range<1> (type, min_limit (type), lim);
763 }
764 
765 // (X <= VAL) produces the range of [MIN, VAL].
766 
767 static void
build_le(irange & r,tree type,const wide_int & val)768 build_le (irange &r, tree type, const wide_int &val)
769 {
770   r = int_range<1> (type, min_limit (type), val);
771 }
772 
773 // (X > VAL) produces the range of [VAL + 1, MAX].
774 
775 static void
build_gt(irange & r,tree type,const wide_int & val)776 build_gt (irange &r, tree type, const wide_int &val)
777 {
778   wi::overflow_type ov;
779   wide_int lim;
780   signop sgn = TYPE_SIGN (type);
781 
782   // Signed 1 bit cannot represent 1 for addition.
783   if (sgn == SIGNED)
784     lim = wi::sub (val, -1, sgn, &ov);
785   else
786     lim = wi::add (val, 1, sgn, &ov);
787   // If val + 1 overflows, check is for X > MAX, which is an empty range.
788   if (ov)
789     r.set_undefined ();
790   else
791     r = int_range<1> (type, lim, max_limit (type));
792 }
793 
794 // (X >= val) produces the range of [VAL, MAX].
795 
796 static void
build_ge(irange & r,tree type,const wide_int & val)797 build_ge (irange &r, tree type, const wide_int &val)
798 {
799   r = int_range<1> (type, val, max_limit (type));
800 }
801 
802 
803 class operator_lt :  public range_operator
804 {
805 public:
806   virtual bool fold_range (irange &r, tree type,
807 			   const irange &op1,
808 			   const irange &op2,
809 			   relation_kind rel = VREL_NONE) const;
810   virtual bool op1_range (irange &r, tree type,
811 			  const irange &lhs,
812 			  const irange &op2,
813 			  relation_kind rel = VREL_NONE) const;
814   virtual bool op2_range (irange &r, tree type,
815 			  const irange &lhs,
816 			  const irange &op1,
817 			  relation_kind rel = VREL_NONE) const;
818   virtual enum tree_code op1_op2_relation (const irange &lhs) const;
819 } op_lt;
820 
821 // Check if the LHS range indicates a relation between OP1 and OP2.
822 
823 enum tree_code
op1_op2_relation(const irange & lhs) const824 operator_lt::op1_op2_relation (const irange &lhs) const
825 {
826   if (lhs.undefined_p ())
827     return VREL_EMPTY;
828 
829   // FALSE = op1 < op2 indicates GE_EXPR.
830   if (lhs.zero_p ())
831     return GE_EXPR;
832 
833   // TRUE = op1 < op2 indicates LT_EXPR.
834   if (!lhs.contains_p (build_zero_cst (lhs.type ())))
835     return LT_EXPR;
836   return VREL_NONE;
837 }
838 
839 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2,relation_kind rel) const840 operator_lt::fold_range (irange &r, tree type,
841 			 const irange &op1,
842 			 const irange &op2,
843 			 relation_kind rel) const
844 {
845   if (relop_early_resolve (r, type, op1, op2, rel, LT_EXPR))
846     return true;
847 
848   signop sign = TYPE_SIGN (op1.type ());
849   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
850 
851   if (wi::lt_p (op1.upper_bound (), op2.lower_bound (), sign))
852     r = range_true (type);
853   else if (!wi::lt_p (op1.lower_bound (), op2.upper_bound (), sign))
854     r = range_false (type);
855   else
856     r = range_true_and_false (type);
857   return true;
858 }
859 
860 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const861 operator_lt::op1_range (irange &r, tree type,
862 			const irange &lhs,
863 			const irange &op2,
864 			relation_kind rel ATTRIBUTE_UNUSED) const
865 {
866   switch (get_bool_state (r, lhs, type))
867     {
868     case BRS_TRUE:
869       build_lt (r, type, op2.upper_bound ());
870       break;
871 
872     case BRS_FALSE:
873       build_ge (r, type, op2.lower_bound ());
874       break;
875 
876     default:
877       break;
878     }
879   return true;
880 }
881 
882 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1,relation_kind rel ATTRIBUTE_UNUSED) const883 operator_lt::op2_range (irange &r, tree type,
884 			const irange &lhs,
885 			const irange &op1,
886 			relation_kind rel ATTRIBUTE_UNUSED) const
887 {
888   switch (get_bool_state (r, lhs, type))
889     {
890     case BRS_FALSE:
891       build_le (r, type, op1.upper_bound ());
892       break;
893 
894     case BRS_TRUE:
895       build_gt (r, type, op1.lower_bound ());
896       break;
897 
898     default:
899       break;
900     }
901   return true;
902 }
903 
904 
905 class operator_le :  public range_operator
906 {
907 public:
908   virtual bool fold_range (irange &r, tree type,
909 			   const irange &op1,
910 			   const irange &op2,
911 			   relation_kind rel = VREL_NONE) const;
912   virtual bool op1_range (irange &r, tree type,
913 			  const irange &lhs,
914 			  const irange &op2,
915 			  relation_kind rel = VREL_NONE) const;
916   virtual bool op2_range (irange &r, tree type,
917 			  const irange &lhs,
918 			  const irange &op1,
919 			  relation_kind rel = VREL_NONE) const;
920   virtual enum tree_code op1_op2_relation (const irange &lhs) const;
921 } op_le;
922 
923 // Check if the LHS range indicates a relation between OP1 and OP2.
924 
925 enum tree_code
op1_op2_relation(const irange & lhs) const926 operator_le::op1_op2_relation (const irange &lhs) const
927 {
928   if (lhs.undefined_p ())
929     return VREL_EMPTY;
930 
931   // FALSE = op1 <= op2 indicates GT_EXPR.
932   if (lhs.zero_p ())
933     return GT_EXPR;
934 
935   // TRUE = op1 <= op2 indicates LE_EXPR.
936   if (!lhs.contains_p (build_zero_cst (lhs.type ())))
937     return LE_EXPR;
938   return VREL_NONE;
939 }
940 
941 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2,relation_kind rel) const942 operator_le::fold_range (irange &r, tree type,
943 			 const irange &op1,
944 			 const irange &op2,
945 			 relation_kind rel) const
946 {
947   if (relop_early_resolve (r, type, op1, op2, rel, LE_EXPR))
948     return true;
949 
950   signop sign = TYPE_SIGN (op1.type ());
951   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
952 
953   if (wi::le_p (op1.upper_bound (), op2.lower_bound (), sign))
954     r = range_true (type);
955   else if (!wi::le_p (op1.lower_bound (), op2.upper_bound (), sign))
956     r = range_false (type);
957   else
958     r = range_true_and_false (type);
959   return true;
960 }
961 
962 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const963 operator_le::op1_range (irange &r, tree type,
964 			const irange &lhs,
965 			const irange &op2,
966 			relation_kind rel ATTRIBUTE_UNUSED) const
967 {
968   switch (get_bool_state (r, lhs, type))
969     {
970     case BRS_TRUE:
971       build_le (r, type, op2.upper_bound ());
972       break;
973 
974     case BRS_FALSE:
975       build_gt (r, type, op2.lower_bound ());
976       break;
977 
978     default:
979       break;
980     }
981   return true;
982 }
983 
984 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1,relation_kind rel ATTRIBUTE_UNUSED) const985 operator_le::op2_range (irange &r, tree type,
986 			const irange &lhs,
987 			const irange &op1,
988 			relation_kind rel ATTRIBUTE_UNUSED) const
989 {
990   switch (get_bool_state (r, lhs, type))
991     {
992     case BRS_FALSE:
993       build_lt (r, type, op1.upper_bound ());
994       break;
995 
996     case BRS_TRUE:
997       build_ge (r, type, op1.lower_bound ());
998       break;
999 
1000     default:
1001       break;
1002     }
1003   return true;
1004 }
1005 
1006 
1007 class operator_gt :  public range_operator
1008 {
1009 public:
1010   virtual bool fold_range (irange &r, tree type,
1011 			   const irange &op1,
1012 			   const irange &op2,
1013 			   relation_kind rel = VREL_NONE) const;
1014   virtual bool op1_range (irange &r, tree type,
1015 			  const irange &lhs,
1016 			  const irange &op2,
1017 			  relation_kind rel = VREL_NONE) const;
1018   virtual bool op2_range (irange &r, tree type,
1019 			  const irange &lhs,
1020 			  const irange &op1,
1021 			  relation_kind rel = VREL_NONE) const;
1022   virtual enum tree_code op1_op2_relation (const irange &lhs) const;
1023 } op_gt;
1024 
1025 // Check if the LHS range indicates a relation between OP1 and OP2.
1026 
1027 enum tree_code
op1_op2_relation(const irange & lhs) const1028 operator_gt::op1_op2_relation (const irange &lhs) const
1029 {
1030   if (lhs.undefined_p ())
1031     return VREL_EMPTY;
1032 
1033   // FALSE = op1 > op2 indicates LE_EXPR.
1034   if (lhs.zero_p ())
1035     return LE_EXPR;
1036 
1037   // TRUE = op1 > op2 indicates GT_EXPR.
1038   if (!lhs.contains_p (build_zero_cst (lhs.type ())))
1039     return GT_EXPR;
1040   return VREL_NONE;
1041 }
1042 
1043 
1044 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2,relation_kind rel) const1045 operator_gt::fold_range (irange &r, tree type,
1046 			 const irange &op1, const irange &op2,
1047 			 relation_kind rel) const
1048 {
1049   if (relop_early_resolve (r, type, op1, op2, rel, GT_EXPR))
1050     return true;
1051 
1052   signop sign = TYPE_SIGN (op1.type ());
1053   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
1054 
1055   if (wi::gt_p (op1.lower_bound (), op2.upper_bound (), sign))
1056     r = range_true (type);
1057   else if (!wi::gt_p (op1.upper_bound (), op2.lower_bound (), sign))
1058     r = range_false (type);
1059   else
1060     r = range_true_and_false (type);
1061   return true;
1062 }
1063 
1064 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const1065 operator_gt::op1_range (irange &r, tree type,
1066 			const irange &lhs, const irange &op2,
1067 			relation_kind rel ATTRIBUTE_UNUSED) const
1068 {
1069   switch (get_bool_state (r, lhs, type))
1070     {
1071     case BRS_TRUE:
1072       build_gt (r, type, op2.lower_bound ());
1073       break;
1074 
1075     case BRS_FALSE:
1076       build_le (r, type, op2.upper_bound ());
1077       break;
1078 
1079     default:
1080       break;
1081     }
1082   return true;
1083 }
1084 
1085 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1,relation_kind rel ATTRIBUTE_UNUSED) const1086 operator_gt::op2_range (irange &r, tree type,
1087 			const irange &lhs,
1088 			const irange &op1,
1089 			relation_kind rel ATTRIBUTE_UNUSED) const
1090 {
1091   switch (get_bool_state (r, lhs, type))
1092     {
1093     case BRS_FALSE:
1094       build_ge (r, type, op1.lower_bound ());
1095       break;
1096 
1097     case BRS_TRUE:
1098       build_lt (r, type, op1.upper_bound ());
1099       break;
1100 
1101     default:
1102       break;
1103     }
1104   return true;
1105 }
1106 
1107 
1108 class operator_ge :  public range_operator
1109 {
1110 public:
1111   virtual bool fold_range (irange &r, tree type,
1112 			   const irange &op1,
1113 			   const irange &op2,
1114 			   relation_kind rel = VREL_NONE) const;
1115   virtual bool op1_range (irange &r, tree type,
1116 			  const irange &lhs,
1117 			  const irange &op2,
1118 			  relation_kind rel = VREL_NONE) const;
1119   virtual bool op2_range (irange &r, tree type,
1120 			  const irange &lhs,
1121 			  const irange &op1,
1122 			  relation_kind rel = VREL_NONE) const;
1123   virtual enum tree_code op1_op2_relation (const irange &lhs) const;
1124 } op_ge;
1125 
1126 // Check if the LHS range indicates a relation between OP1 and OP2.
1127 
1128 enum tree_code
op1_op2_relation(const irange & lhs) const1129 operator_ge::op1_op2_relation (const irange &lhs) const
1130 {
1131   if (lhs.undefined_p ())
1132     return VREL_EMPTY;
1133 
1134   // FALSE = op1 >= op2 indicates LT_EXPR.
1135   if (lhs.zero_p ())
1136     return LT_EXPR;
1137 
1138   // TRUE = op1 >= op2 indicates GE_EXPR.
1139   if (!lhs.contains_p (build_zero_cst (lhs.type ())))
1140     return GE_EXPR;
1141   return VREL_NONE;
1142 }
1143 
1144 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2,relation_kind rel) const1145 operator_ge::fold_range (irange &r, tree type,
1146 			 const irange &op1,
1147 			 const irange &op2,
1148 			 relation_kind rel) const
1149 {
1150   if (relop_early_resolve (r, type, op1, op2, rel, GE_EXPR))
1151     return true;
1152 
1153   signop sign = TYPE_SIGN (op1.type ());
1154   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
1155 
1156   if (wi::ge_p (op1.lower_bound (), op2.upper_bound (), sign))
1157     r = range_true (type);
1158   else if (!wi::ge_p (op1.upper_bound (), op2.lower_bound (), sign))
1159     r = range_false (type);
1160   else
1161     r = range_true_and_false (type);
1162   return true;
1163 }
1164 
1165 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const1166 operator_ge::op1_range (irange &r, tree type,
1167 			const irange &lhs,
1168 			const irange &op2,
1169 			relation_kind rel ATTRIBUTE_UNUSED) const
1170 {
1171   switch (get_bool_state (r, lhs, type))
1172     {
1173     case BRS_TRUE:
1174       build_ge (r, type, op2.lower_bound ());
1175       break;
1176 
1177     case BRS_FALSE:
1178       build_lt (r, type, op2.upper_bound ());
1179       break;
1180 
1181     default:
1182       break;
1183     }
1184   return true;
1185 }
1186 
1187 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1,relation_kind rel ATTRIBUTE_UNUSED) const1188 operator_ge::op2_range (irange &r, tree type,
1189 			const irange &lhs,
1190 			const irange &op1,
1191 			relation_kind rel ATTRIBUTE_UNUSED) const
1192 {
1193   switch (get_bool_state (r, lhs, type))
1194     {
1195     case BRS_FALSE:
1196       build_gt (r, type, op1.lower_bound ());
1197       break;
1198 
1199     case BRS_TRUE:
1200       build_le (r, type, op1.upper_bound ());
1201       break;
1202 
1203     default:
1204       break;
1205     }
1206   return true;
1207 }
1208 
1209 
1210 class operator_plus : public range_operator
1211 {
1212 public:
1213   virtual bool op1_range (irange &r, tree type,
1214 			  const irange &lhs,
1215 			  const irange &op2,
1216 			  relation_kind rel ATTRIBUTE_UNUSED) const;
1217   virtual bool op2_range (irange &r, tree type,
1218 			  const irange &lhs,
1219 			  const irange &op1,
1220 			  relation_kind rel ATTRIBUTE_UNUSED) const;
1221   virtual void wi_fold (irange &r, tree type,
1222 		        const wide_int &lh_lb,
1223 		        const wide_int &lh_ub,
1224 		        const wide_int &rh_lb,
1225 		        const wide_int &rh_ub) const;
1226   virtual enum tree_code lhs_op1_relation (const irange &lhs, const irange &op1,
1227 					   const irange &op2) const;
1228   virtual enum tree_code lhs_op2_relation (const irange &lhs, const irange &op1,
1229 					   const irange &op2) const;
1230 } op_plus;
1231 
1232 // Check to see if the range of OP2 indicates anything about the relation
1233 // between LHS and OP1.
1234 
1235 enum tree_code
lhs_op1_relation(const irange & lhs,const irange & op1,const irange & op2) const1236 operator_plus::lhs_op1_relation (const irange &lhs,
1237 				 const irange &op1,
1238 				 const irange &op2) const
1239 {
1240   if (lhs.undefined_p () || op1.undefined_p () || op2.undefined_p ())
1241     return VREL_NONE;
1242 
1243   tree type = lhs.type ();
1244   unsigned prec = TYPE_PRECISION (type);
1245   wi::overflow_type ovf1, ovf2;
1246   signop sign = TYPE_SIGN (type);
1247 
1248   // LHS = OP1 + 0  indicates LHS == OP1.
1249   if (op2.zero_p ())
1250     return EQ_EXPR;
1251 
1252   if (TYPE_OVERFLOW_WRAPS (type))
1253     {
1254       wi::add (op1.lower_bound (), op2.lower_bound (), sign, &ovf1);
1255       wi::add (op1.upper_bound (), op2.upper_bound (), sign, &ovf2);
1256     }
1257   else
1258     ovf1 = ovf2 = wi::OVF_NONE;
1259 
1260   // Never wrapping additions.
1261   if (!ovf1 && !ovf2)
1262     {
1263       // Positive op2 means lhs > op1.
1264       if (wi::gt_p (op2.lower_bound (), wi::zero (prec), sign))
1265 	return GT_EXPR;
1266       if (wi::ge_p (op2.lower_bound (), wi::zero (prec), sign))
1267 	return GE_EXPR;
1268 
1269       // Negative op2 means lhs < op1.
1270       if (wi::lt_p (op2.upper_bound (), wi::zero (prec), sign))
1271 	return LT_EXPR;
1272       if (wi::le_p (op2.upper_bound (), wi::zero (prec), sign))
1273 	return LE_EXPR;
1274     }
1275   // Always wrapping additions.
1276   else if (ovf1 && ovf1 == ovf2)
1277     {
1278       // Positive op2 means lhs < op1.
1279       if (wi::gt_p (op2.lower_bound (), wi::zero (prec), sign))
1280 	return LT_EXPR;
1281       if (wi::ge_p (op2.lower_bound (), wi::zero (prec), sign))
1282 	return LE_EXPR;
1283 
1284       // Negative op2 means lhs > op1.
1285       if (wi::lt_p (op2.upper_bound (), wi::zero (prec), sign))
1286 	return GT_EXPR;
1287       if (wi::le_p (op2.upper_bound (), wi::zero (prec), sign))
1288 	return GE_EXPR;
1289     }
1290 
1291   // If op2 does not contain 0, then LHS and OP1 can never be equal.
1292   if (!range_includes_zero_p (&op2))
1293     return NE_EXPR;
1294 
1295   return VREL_NONE;
1296 }
1297 
1298 // PLUS is symmetrical, so we can simply call lhs_op1_relation with reversed
1299 // operands.
1300 
1301 enum tree_code
lhs_op2_relation(const irange & lhs,const irange & op1,const irange & op2) const1302 operator_plus::lhs_op2_relation (const irange &lhs, const irange &op1,
1303 				 const irange &op2) const
1304 {
1305   return lhs_op1_relation (lhs, op2, op1);
1306 }
1307 
1308 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) const1309 operator_plus::wi_fold (irange &r, tree type,
1310 			const wide_int &lh_lb, const wide_int &lh_ub,
1311 			const wide_int &rh_lb, const wide_int &rh_ub) const
1312 {
1313   wi::overflow_type ov_lb, ov_ub;
1314   signop s = TYPE_SIGN (type);
1315   wide_int new_lb = wi::add (lh_lb, rh_lb, s, &ov_lb);
1316   wide_int new_ub = wi::add (lh_ub, rh_ub, s, &ov_ub);
1317   value_range_with_overflow (r, type, new_lb, new_ub, ov_lb, ov_ub);
1318 }
1319 
1320 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const1321 operator_plus::op1_range (irange &r, tree type,
1322 			  const irange &lhs,
1323 			  const irange &op2,
1324 			  relation_kind rel ATTRIBUTE_UNUSED) const
1325 {
1326   return range_op_handler (MINUS_EXPR, type)->fold_range (r, type, lhs, op2);
1327 }
1328 
1329 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1,relation_kind rel ATTRIBUTE_UNUSED) const1330 operator_plus::op2_range (irange &r, tree type,
1331 			  const irange &lhs,
1332 			  const irange &op1,
1333 			  relation_kind rel ATTRIBUTE_UNUSED) const
1334 {
1335   return range_op_handler (MINUS_EXPR, type)->fold_range (r, type, lhs, op1);
1336 }
1337 
1338 
1339 class operator_minus : public range_operator
1340 {
1341 public:
1342   virtual bool op1_range (irange &r, tree type,
1343 			  const irange &lhs,
1344 			  const irange &op2,
1345 			  relation_kind rel ATTRIBUTE_UNUSED) const;
1346   virtual bool op2_range (irange &r, tree type,
1347 			  const irange &lhs,
1348 			  const irange &op1,
1349 			  relation_kind rel ATTRIBUTE_UNUSED) const;
1350   virtual void wi_fold (irange &r, tree type,
1351 		        const wide_int &lh_lb,
1352 		        const wide_int &lh_ub,
1353 		        const wide_int &rh_lb,
1354 		        const wide_int &rh_ub) const;
1355   virtual bool op1_op2_relation_effect (irange &lhs_range,
1356 					tree type,
1357 					const irange &op1_range,
1358 					const irange &op2_range,
1359 					relation_kind rel) const;
1360 } op_minus;
1361 
1362 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) const1363 operator_minus::wi_fold (irange &r, tree type,
1364 			 const wide_int &lh_lb, const wide_int &lh_ub,
1365 			 const wide_int &rh_lb, const wide_int &rh_ub) const
1366 {
1367   wi::overflow_type ov_lb, ov_ub;
1368   signop s = TYPE_SIGN (type);
1369   wide_int new_lb = wi::sub (lh_lb, rh_ub, s, &ov_lb);
1370   wide_int new_ub = wi::sub (lh_ub, rh_lb, s, &ov_ub);
1371   value_range_with_overflow (r, type, new_lb, new_ub, ov_lb, ov_ub);
1372 }
1373 
1374 // Check to see if the relation REL between OP1 and OP2 has any effect on the
1375 // LHS of the expression.  If so, apply it to LHS_RANGE.  This is a helper
1376 // function for both MINUS_EXPR and POINTER_DIFF_EXPR.
1377 
1378 static bool
minus_op1_op2_relation_effect(irange & lhs_range,tree type,const irange & op1_range ATTRIBUTE_UNUSED,const irange & op2_range ATTRIBUTE_UNUSED,relation_kind rel)1379 minus_op1_op2_relation_effect (irange &lhs_range, tree type,
1380 			       const irange &op1_range ATTRIBUTE_UNUSED,
1381 			       const irange &op2_range ATTRIBUTE_UNUSED,
1382 			       relation_kind rel)
1383 {
1384   if (rel == VREL_NONE)
1385     return false;
1386 
1387   int_range<2> rel_range;
1388   unsigned prec = TYPE_PRECISION (type);
1389   signop sgn = TYPE_SIGN (type);
1390 
1391   // == and != produce [0,0] and ~[0,0] regardless of wrapping.
1392   if (rel == EQ_EXPR)
1393     rel_range = int_range<2> (type, wi::zero (prec), wi::zero (prec));
1394   else if (rel == NE_EXPR)
1395     rel_range = int_range<2> (type, wi::zero (prec), wi::zero (prec),
1396 			      VR_ANTI_RANGE);
1397   else if (TYPE_OVERFLOW_WRAPS (type))
1398     {
1399       switch (rel)
1400 	{
1401 	  // For wrapping signed values and unsigned, if op1 > op2 or
1402 	  // op1 < op2, then op1 - op2 can be restricted to ~[0, 0].
1403 	  case GT_EXPR:
1404 	  case LT_EXPR:
1405 	      rel_range = int_range<2> (type, wi::zero (prec), wi::zero (prec),
1406 					VR_ANTI_RANGE);
1407 	    break;
1408 	  default:
1409 	    return false;
1410 	}
1411     }
1412   else
1413     {
1414       switch (rel)
1415 	{
1416 	  // op1 > op2, op1 - op2 can be restricted to [1, +INF]
1417 	  case GT_EXPR:
1418 	    rel_range = int_range<2> (type, wi::one (prec),
1419 				      wi::max_value (prec, sgn));
1420 	    break;
1421 	  // op1 >= op2, op1 - op2 can be restricted to [0, +INF]
1422 	  case GE_EXPR:
1423 	    rel_range = int_range<2> (type, wi::zero (prec),
1424 				      wi::max_value (prec, sgn));
1425 	    break;
1426 	  // op1 < op2, op1 - op2 can be restricted to [-INF, -1]
1427 	  case LT_EXPR:
1428 	    rel_range = int_range<2> (type, wi::min_value (prec, sgn),
1429 				      wi::minus_one (prec));
1430 	    break;
1431 	  // op1 <= op2, op1 - op2 can be restricted to [-INF, 0]
1432 	  case LE_EXPR:
1433 	    rel_range = int_range<2> (type, wi::min_value (prec, sgn),
1434 				      wi::zero (prec));
1435 	    break;
1436 	  default:
1437 	    return false;
1438 	}
1439     }
1440   lhs_range.intersect (rel_range);
1441   return true;
1442 }
1443 
1444 bool
op1_op2_relation_effect(irange & lhs_range,tree type,const irange & op1_range,const irange & op2_range,relation_kind rel) const1445 operator_minus::op1_op2_relation_effect (irange &lhs_range, tree type,
1446 					 const irange &op1_range,
1447 					 const irange &op2_range,
1448 					 relation_kind rel) const
1449 {
1450   return minus_op1_op2_relation_effect (lhs_range, type, op1_range, op2_range,
1451 					rel);
1452 }
1453 
1454 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const1455 operator_minus::op1_range (irange &r, tree type,
1456 			   const irange &lhs,
1457 			   const irange &op2,
1458 			   relation_kind rel ATTRIBUTE_UNUSED) const
1459 {
1460   return range_op_handler (PLUS_EXPR, type)->fold_range (r, type, lhs, op2);
1461 }
1462 
1463 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1,relation_kind rel ATTRIBUTE_UNUSED) const1464 operator_minus::op2_range (irange &r, tree type,
1465 			   const irange &lhs,
1466 			   const irange &op1,
1467 			   relation_kind rel ATTRIBUTE_UNUSED) const
1468 {
1469   return fold_range (r, type, op1, lhs);
1470 }
1471 
1472 
1473 class operator_pointer_diff : public range_operator
1474 {
1475   virtual bool op1_op2_relation_effect (irange &lhs_range,
1476 					tree type,
1477 					const irange &op1_range,
1478 					const irange &op2_range,
1479 					relation_kind rel) const;
1480 } op_pointer_diff;
1481 
1482 bool
op1_op2_relation_effect(irange & lhs_range,tree type,const irange & op1_range,const irange & op2_range,relation_kind rel) const1483 operator_pointer_diff::op1_op2_relation_effect (irange &lhs_range, tree type,
1484 						const irange &op1_range,
1485 						const irange &op2_range,
1486 						relation_kind rel) const
1487 {
1488   return minus_op1_op2_relation_effect (lhs_range, type, op1_range, op2_range,
1489 					rel);
1490 }
1491 
1492 
1493 class operator_min : public range_operator
1494 {
1495 public:
1496   virtual void wi_fold (irange &r, tree type,
1497 		        const wide_int &lh_lb,
1498 		        const wide_int &lh_ub,
1499 		        const wide_int &rh_lb,
1500 		        const wide_int &rh_ub) const;
1501 } op_min;
1502 
1503 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) const1504 operator_min::wi_fold (irange &r, tree type,
1505 		       const wide_int &lh_lb, const wide_int &lh_ub,
1506 		       const wide_int &rh_lb, const wide_int &rh_ub) const
1507 {
1508   signop s = TYPE_SIGN (type);
1509   wide_int new_lb = wi::min (lh_lb, rh_lb, s);
1510   wide_int new_ub = wi::min (lh_ub, rh_ub, s);
1511   value_range_with_overflow (r, type, new_lb, new_ub);
1512 }
1513 
1514 
1515 class operator_max : public range_operator
1516 {
1517 public:
1518   virtual void wi_fold (irange &r, tree type,
1519 		        const wide_int &lh_lb,
1520 		        const wide_int &lh_ub,
1521 		        const wide_int &rh_lb,
1522 		        const wide_int &rh_ub) const;
1523 } op_max;
1524 
1525 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) const1526 operator_max::wi_fold (irange &r, tree type,
1527 		       const wide_int &lh_lb, const wide_int &lh_ub,
1528 		       const wide_int &rh_lb, const wide_int &rh_ub) const
1529 {
1530   signop s = TYPE_SIGN (type);
1531   wide_int new_lb = wi::max (lh_lb, rh_lb, s);
1532   wide_int new_ub = wi::max (lh_ub, rh_ub, s);
1533   value_range_with_overflow (r, type, new_lb, new_ub);
1534 }
1535 
1536 
1537 class cross_product_operator : public range_operator
1538 {
1539 public:
1540   // Perform an operation between two wide-ints and place the result
1541   // in R.  Return true if the operation overflowed.
1542   virtual bool wi_op_overflows (wide_int &r,
1543 				tree type,
1544 				const wide_int &,
1545 				const wide_int &) const = 0;
1546 
1547   // Calculate the cross product of two sets of sub-ranges and return it.
1548   void wi_cross_product (irange &r, tree type,
1549 			 const wide_int &lh_lb,
1550 			 const wide_int &lh_ub,
1551 			 const wide_int &rh_lb,
1552 			 const wide_int &rh_ub) const;
1553 };
1554 
1555 // Calculate the cross product of two sets of ranges and return it.
1556 //
1557 // Multiplications, divisions and shifts are a bit tricky to handle,
1558 // depending on the mix of signs we have in the two ranges, we need to
1559 // operate on different values to get the minimum and maximum values
1560 // for the new range.  One approach is to figure out all the
1561 // variations of range combinations and do the operations.
1562 //
1563 // However, this involves several calls to compare_values and it is
1564 // pretty convoluted.  It's simpler to do the 4 operations (MIN0 OP
1565 // MIN1, MIN0 OP MAX1, MAX0 OP MIN1 and MAX0 OP MAX0 OP MAX1) and then
1566 // figure the smallest and largest values to form the new range.
1567 
1568 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) const1569 cross_product_operator::wi_cross_product (irange &r, tree type,
1570 					  const wide_int &lh_lb,
1571 					  const wide_int &lh_ub,
1572 					  const wide_int &rh_lb,
1573 					  const wide_int &rh_ub) const
1574 {
1575   wide_int cp1, cp2, cp3, cp4;
1576   // Default to varying.
1577   r.set_varying (type);
1578 
1579   // Compute the 4 cross operations, bailing if we get an overflow we
1580   // can't handle.
1581   if (wi_op_overflows (cp1, type, lh_lb, rh_lb))
1582     return;
1583   if (wi::eq_p (lh_lb, lh_ub))
1584     cp3 = cp1;
1585   else if (wi_op_overflows (cp3, type, lh_ub, rh_lb))
1586     return;
1587   if (wi::eq_p (rh_lb, rh_ub))
1588     cp2 = cp1;
1589   else if (wi_op_overflows (cp2, type, lh_lb, rh_ub))
1590     return;
1591   if (wi::eq_p (lh_lb, lh_ub))
1592     cp4 = cp2;
1593   else if (wi_op_overflows (cp4, type, lh_ub, rh_ub))
1594     return;
1595 
1596   // Order pairs.
1597   signop sign = TYPE_SIGN (type);
1598   if (wi::gt_p (cp1, cp2, sign))
1599     std::swap (cp1, cp2);
1600   if (wi::gt_p (cp3, cp4, sign))
1601     std::swap (cp3, cp4);
1602 
1603   // Choose min and max from the ordered pairs.
1604   wide_int res_lb = wi::min (cp1, cp3, sign);
1605   wide_int res_ub = wi::max (cp2, cp4, sign);
1606   value_range_with_overflow (r, type, res_lb, res_ub);
1607 }
1608 
1609 
1610 class operator_mult : public cross_product_operator
1611 {
1612 public:
1613   virtual void wi_fold (irange &r, tree type,
1614 		        const wide_int &lh_lb,
1615 		        const wide_int &lh_ub,
1616 		        const wide_int &rh_lb,
1617 		        const wide_int &rh_ub) const;
1618   virtual bool wi_op_overflows (wide_int &res, tree type,
1619 				const wide_int &w0, const wide_int &w1) const;
1620   virtual bool op1_range (irange &r, tree type,
1621 			  const irange &lhs,
1622 			  const irange &op2,
1623 			  relation_kind rel ATTRIBUTE_UNUSED) const;
1624   virtual bool op2_range (irange &r, tree type,
1625 			  const irange &lhs,
1626 			  const irange &op1,
1627 			  relation_kind rel ATTRIBUTE_UNUSED) const;
1628 } op_mult;
1629 
1630 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const1631 operator_mult::op1_range (irange &r, tree type,
1632 			  const irange &lhs, const irange &op2,
1633 			  relation_kind rel ATTRIBUTE_UNUSED) const
1634 {
1635   tree offset;
1636 
1637   // We can't solve 0 = OP1 * N by dividing by N with a wrapping type.
1638   // For example: For 0 = OP1 * 2, OP1 could be 0, or MAXINT, whereas
1639   // for 4 = OP1 * 2, OP1 could be 2 or 130 (unsigned 8-bit)
1640   if (TYPE_OVERFLOW_WRAPS (type))
1641     return false;
1642 
1643   if (op2.singleton_p (&offset) && !integer_zerop (offset))
1644     return range_op_handler (TRUNC_DIV_EXPR, type)->fold_range (r, type,
1645 								lhs, op2);
1646   return false;
1647 }
1648 
1649 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1,relation_kind rel) const1650 operator_mult::op2_range (irange &r, tree type,
1651 			  const irange &lhs, const irange &op1,
1652 			  relation_kind rel) const
1653 {
1654   return operator_mult::op1_range (r, type, lhs, op1, rel);
1655 }
1656 
1657 bool
wi_op_overflows(wide_int & res,tree type,const wide_int & w0,const wide_int & w1) const1658 operator_mult::wi_op_overflows (wide_int &res, tree type,
1659 				const wide_int &w0, const wide_int &w1) const
1660 {
1661   wi::overflow_type overflow = wi::OVF_NONE;
1662   signop sign = TYPE_SIGN (type);
1663   res = wi::mul (w0, w1, sign, &overflow);
1664    if (overflow && TYPE_OVERFLOW_UNDEFINED (type))
1665      {
1666        // For multiplication, the sign of the overflow is given
1667        // by the comparison of the signs of the operands.
1668        if (sign == UNSIGNED || w0.sign_mask () == w1.sign_mask ())
1669 	 res = wi::max_value (w0.get_precision (), sign);
1670        else
1671 	 res = wi::min_value (w0.get_precision (), sign);
1672        return false;
1673      }
1674    return overflow;
1675 }
1676 
1677 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) const1678 operator_mult::wi_fold (irange &r, tree type,
1679 			const wide_int &lh_lb, const wide_int &lh_ub,
1680 			const wide_int &rh_lb, const wide_int &rh_ub) const
1681 {
1682   if (TYPE_OVERFLOW_UNDEFINED (type))
1683     {
1684       wi_cross_product (r, type, lh_lb, lh_ub, rh_lb, rh_ub);
1685       return;
1686     }
1687 
1688   // Multiply the ranges when overflow wraps.  This is basically fancy
1689   // code so we don't drop to varying with an unsigned
1690   // [-3,-1]*[-3,-1].
1691   //
1692   // This test requires 2*prec bits if both operands are signed and
1693   // 2*prec + 2 bits if either is not.  Therefore, extend the values
1694   // using the sign of the result to PREC2.  From here on out,
1695   // everthing is just signed math no matter what the input types
1696   // were.
1697 
1698   signop sign = TYPE_SIGN (type);
1699   unsigned prec = TYPE_PRECISION (type);
1700   widest2_int min0 = widest2_int::from (lh_lb, sign);
1701   widest2_int max0 = widest2_int::from (lh_ub, sign);
1702   widest2_int min1 = widest2_int::from (rh_lb, sign);
1703   widest2_int max1 = widest2_int::from (rh_ub, sign);
1704   widest2_int sizem1 = wi::mask <widest2_int> (prec, false);
1705   widest2_int size = sizem1 + 1;
1706 
1707   // Canonicalize the intervals.
1708   if (sign == UNSIGNED)
1709     {
1710       if (wi::ltu_p (size, min0 + max0))
1711 	{
1712 	  min0 -= size;
1713 	  max0 -= size;
1714 	}
1715       if (wi::ltu_p (size, min1 + max1))
1716 	{
1717 	  min1 -= size;
1718 	  max1 -= size;
1719 	}
1720     }
1721 
1722   // Sort the 4 products so that min is in prod0 and max is in
1723   // prod3.
1724   widest2_int prod0 = min0 * min1;
1725   widest2_int prod1 = min0 * max1;
1726   widest2_int prod2 = max0 * min1;
1727   widest2_int prod3 = max0 * max1;
1728 
1729   // min0min1 > max0max1
1730   if (prod0 > prod3)
1731     std::swap (prod0, prod3);
1732 
1733   // min0max1 > max0min1
1734   if (prod1 > prod2)
1735     std::swap (prod1, prod2);
1736 
1737   if (prod0 > prod1)
1738     std::swap (prod0, prod1);
1739 
1740   if (prod2 > prod3)
1741     std::swap (prod2, prod3);
1742 
1743   // diff = max - min
1744   prod2 = prod3 - prod0;
1745   if (wi::geu_p (prod2, sizem1))
1746     // The range covers all values.
1747     r.set_varying (type);
1748   else
1749     {
1750       wide_int new_lb = wide_int::from (prod0, prec, sign);
1751       wide_int new_ub = wide_int::from (prod3, prec, sign);
1752       create_possibly_reversed_range (r, type, new_lb, new_ub);
1753     }
1754 }
1755 
1756 
1757 class operator_div : public cross_product_operator
1758 {
1759 public:
operator_div(enum tree_code c)1760   operator_div (enum tree_code c)  { code = c; }
1761   virtual void wi_fold (irange &r, tree type,
1762 		        const wide_int &lh_lb,
1763 		        const wide_int &lh_ub,
1764 		        const wide_int &rh_lb,
1765 		        const wide_int &rh_ub) const;
1766   virtual bool wi_op_overflows (wide_int &res, tree type,
1767 				const wide_int &, const wide_int &) const;
1768 private:
1769   enum tree_code code;
1770 };
1771 
1772 bool
wi_op_overflows(wide_int & res,tree type,const wide_int & w0,const wide_int & w1) const1773 operator_div::wi_op_overflows (wide_int &res, tree type,
1774 			       const wide_int &w0, const wide_int &w1) const
1775 {
1776   if (w1 == 0)
1777     return true;
1778 
1779   wi::overflow_type overflow = wi::OVF_NONE;
1780   signop sign = TYPE_SIGN (type);
1781 
1782   switch (code)
1783     {
1784     case EXACT_DIV_EXPR:
1785       // EXACT_DIV_EXPR is implemented as TRUNC_DIV_EXPR in
1786       // operator_exact_divide.  No need to handle it here.
1787       gcc_unreachable ();
1788       break;
1789     case TRUNC_DIV_EXPR:
1790       res = wi::div_trunc (w0, w1, sign, &overflow);
1791       break;
1792     case FLOOR_DIV_EXPR:
1793       res = wi::div_floor (w0, w1, sign, &overflow);
1794       break;
1795     case ROUND_DIV_EXPR:
1796       res = wi::div_round (w0, w1, sign, &overflow);
1797       break;
1798     case CEIL_DIV_EXPR:
1799       res = wi::div_ceil (w0, w1, sign, &overflow);
1800       break;
1801     default:
1802       gcc_unreachable ();
1803     }
1804 
1805   if (overflow && TYPE_OVERFLOW_UNDEFINED (type))
1806     {
1807       // For division, the only case is -INF / -1 = +INF.
1808       res = wi::max_value (w0.get_precision (), sign);
1809       return false;
1810     }
1811   return overflow;
1812 }
1813 
1814 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) const1815 operator_div::wi_fold (irange &r, tree type,
1816 		       const wide_int &lh_lb, const wide_int &lh_ub,
1817 		       const wide_int &rh_lb, const wide_int &rh_ub) const
1818 {
1819   const wide_int dividend_min = lh_lb;
1820   const wide_int dividend_max = lh_ub;
1821   const wide_int divisor_min = rh_lb;
1822   const wide_int divisor_max = rh_ub;
1823   signop sign = TYPE_SIGN (type);
1824   unsigned prec = TYPE_PRECISION (type);
1825   wide_int extra_min, extra_max;
1826 
1827   // If we know we won't divide by zero, just do the division.
1828   if (!wi_includes_zero_p (type, divisor_min, divisor_max))
1829     {
1830       wi_cross_product (r, type, dividend_min, dividend_max,
1831 		       divisor_min, divisor_max);
1832       return;
1833     }
1834 
1835   // If we're definitely dividing by zero, there's nothing to do.
1836   if (wi_zero_p (type, divisor_min, divisor_max))
1837     {
1838       r.set_undefined ();
1839       return;
1840     }
1841 
1842   // Perform the division in 2 parts, [LB, -1] and [1, UB], which will
1843   // skip any division by zero.
1844 
1845   // First divide by the negative numbers, if any.
1846   if (wi::neg_p (divisor_min, sign))
1847     wi_cross_product (r, type, dividend_min, dividend_max,
1848 		      divisor_min, wi::minus_one (prec));
1849   else
1850     r.set_undefined ();
1851 
1852   // Then divide by the non-zero positive numbers, if any.
1853   if (wi::gt_p (divisor_max, wi::zero (prec), sign))
1854     {
1855       int_range_max tmp;
1856       wi_cross_product (tmp, type, dividend_min, dividend_max,
1857 			wi::one (prec), divisor_max);
1858       r.union_ (tmp);
1859     }
1860   // We shouldn't still have undefined here.
1861   gcc_checking_assert (!r.undefined_p ());
1862 }
1863 
1864 operator_div op_trunc_div (TRUNC_DIV_EXPR);
1865 operator_div op_floor_div (FLOOR_DIV_EXPR);
1866 operator_div op_round_div (ROUND_DIV_EXPR);
1867 operator_div op_ceil_div (CEIL_DIV_EXPR);
1868 
1869 
1870 class operator_exact_divide : public operator_div
1871 {
1872 public:
operator_exact_divide()1873   operator_exact_divide () : operator_div (TRUNC_DIV_EXPR) { }
1874   virtual bool op1_range (irange &r, tree type,
1875 			  const irange &lhs,
1876 			  const irange &op2,
1877 			  relation_kind rel ATTRIBUTE_UNUSED) const;
1878 
1879 } op_exact_div;
1880 
1881 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const1882 operator_exact_divide::op1_range (irange &r, tree type,
1883 				  const irange &lhs,
1884 				  const irange &op2,
1885 				  relation_kind rel ATTRIBUTE_UNUSED) const
1886 {
1887   tree offset;
1888   // [2, 4] = op1 / [3,3]   since its exact divide, no need to worry about
1889   // remainders in the endpoints, so op1 = [2,4] * [3,3] = [6,12].
1890   // We wont bother trying to enumerate all the in between stuff :-P
1891   // TRUE accuraacy is [6,6][9,9][12,12].  This is unlikely to matter most of
1892   // the time however.
1893   // If op2 is a multiple of 2, we would be able to set some non-zero bits.
1894   if (op2.singleton_p (&offset)
1895       && !integer_zerop (offset))
1896     return range_op_handler (MULT_EXPR, type)->fold_range (r, type, lhs, op2);
1897   return false;
1898 }
1899 
1900 
1901 class operator_lshift : public cross_product_operator
1902 {
1903 public:
1904   virtual bool op1_range (irange &r, tree type,
1905 			  const irange &lhs,
1906 			  const irange &op2,
1907 			  relation_kind rel = VREL_NONE) const;
1908   virtual bool fold_range (irange &r, tree type,
1909 			   const irange &op1,
1910 			   const irange &op2,
1911 			   relation_kind rel = VREL_NONE) const;
1912 
1913   virtual void wi_fold (irange &r, tree type,
1914 			const wide_int &lh_lb, const wide_int &lh_ub,
1915 			const wide_int &rh_lb, const wide_int &rh_ub) const;
1916   virtual bool wi_op_overflows (wide_int &res,
1917 				tree type,
1918 				const wide_int &,
1919 				const wide_int &) const;
1920 } op_lshift;
1921 
1922 class operator_rshift : public cross_product_operator
1923 {
1924 public:
1925   virtual bool fold_range (irange &r, tree type,
1926 			   const irange &op1,
1927 			   const irange &op2,
1928 			   relation_kind rel = VREL_NONE) const;
1929   virtual void wi_fold (irange &r, tree type,
1930 			const wide_int &lh_lb,
1931 			const wide_int &lh_ub,
1932 			const wide_int &rh_lb,
1933 			const wide_int &rh_ub) const;
1934   virtual bool wi_op_overflows (wide_int &res,
1935 				tree type,
1936 				const wide_int &w0,
1937 				const wide_int &w1) const;
1938   virtual bool op1_range (irange &, tree type,
1939 			  const irange &lhs,
1940 			  const irange &op2,
1941 			  relation_kind rel = VREL_NONE) const;
1942 } op_rshift;
1943 
1944 
1945 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2,relation_kind rel) const1946 operator_lshift::fold_range (irange &r, tree type,
1947 			     const irange &op1,
1948 			     const irange &op2,
1949 			     relation_kind rel) const
1950 {
1951   int_range_max shift_range;
1952   if (!get_shift_range (shift_range, type, op2))
1953     {
1954       if (op2.undefined_p ())
1955 	r.set_undefined ();
1956       else
1957 	r.set_varying (type);
1958       return true;
1959     }
1960 
1961   // Transform left shifts by constants into multiplies.
1962   if (shift_range.singleton_p ())
1963     {
1964       unsigned shift = shift_range.lower_bound ().to_uhwi ();
1965       wide_int tmp = wi::set_bit_in_zero (shift, TYPE_PRECISION (type));
1966       int_range<1> mult (type, tmp, tmp);
1967 
1968       // Force wrapping multiplication.
1969       bool saved_flag_wrapv = flag_wrapv;
1970       bool saved_flag_wrapv_pointer = flag_wrapv_pointer;
1971       flag_wrapv = 1;
1972       flag_wrapv_pointer = 1;
1973       bool b = op_mult.fold_range (r, type, op1, mult);
1974       flag_wrapv = saved_flag_wrapv;
1975       flag_wrapv_pointer = saved_flag_wrapv_pointer;
1976       return b;
1977     }
1978   else
1979     // Otherwise, invoke the generic fold routine.
1980     return range_operator::fold_range (r, type, op1, shift_range, rel);
1981 }
1982 
1983 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) const1984 operator_lshift::wi_fold (irange &r, tree type,
1985 			  const wide_int &lh_lb, const wide_int &lh_ub,
1986 			  const wide_int &rh_lb, const wide_int &rh_ub) const
1987 {
1988   signop sign = TYPE_SIGN (type);
1989   unsigned prec = TYPE_PRECISION (type);
1990   int overflow_pos = sign == SIGNED ? prec - 1 : prec;
1991   int bound_shift = overflow_pos - rh_ub.to_shwi ();
1992   // If bound_shift == HOST_BITS_PER_WIDE_INT, the llshift can
1993   // overflow.  However, for that to happen, rh.max needs to be zero,
1994   // which means rh is a singleton range of zero, which means we simply return
1995   // [lh_lb, lh_ub] as the range.
1996   if (wi::eq_p (rh_ub, rh_lb) && wi::eq_p (rh_ub, 0))
1997     {
1998       r = int_range<2> (type, lh_lb, lh_ub);
1999       return;
2000     }
2001 
2002   wide_int bound = wi::set_bit_in_zero (bound_shift, prec);
2003   wide_int complement = ~(bound - 1);
2004   wide_int low_bound, high_bound;
2005   bool in_bounds = false;
2006 
2007   if (sign == UNSIGNED)
2008     {
2009       low_bound = bound;
2010       high_bound = complement;
2011       if (wi::ltu_p (lh_ub, low_bound))
2012 	{
2013 	  // [5, 6] << [1, 2] == [10, 24].
2014 	  // We're shifting out only zeroes, the value increases
2015 	  // monotonically.
2016 	  in_bounds = true;
2017 	}
2018       else if (wi::ltu_p (high_bound, lh_lb))
2019 	{
2020 	  // [0xffffff00, 0xffffffff] << [1, 2]
2021 	  // == [0xfffffc00, 0xfffffffe].
2022 	  // We're shifting out only ones, the value decreases
2023 	  // monotonically.
2024 	  in_bounds = true;
2025 	}
2026     }
2027   else
2028     {
2029       // [-1, 1] << [1, 2] == [-4, 4]
2030       low_bound = complement;
2031       high_bound = bound;
2032       if (wi::lts_p (lh_ub, high_bound)
2033 	  && wi::lts_p (low_bound, lh_lb))
2034 	{
2035 	  // For non-negative numbers, we're shifting out only zeroes,
2036 	  // the value increases monotonically.  For negative numbers,
2037 	  // we're shifting out only ones, the value decreases
2038 	  // monotonically.
2039 	  in_bounds = true;
2040 	}
2041     }
2042 
2043   if (in_bounds)
2044     wi_cross_product (r, type, lh_lb, lh_ub, rh_lb, rh_ub);
2045   else
2046    r.set_varying (type);
2047 }
2048 
2049 bool
wi_op_overflows(wide_int & res,tree type,const wide_int & w0,const wide_int & w1) const2050 operator_lshift::wi_op_overflows (wide_int &res, tree type,
2051 				  const wide_int &w0, const wide_int &w1) const
2052 {
2053   signop sign = TYPE_SIGN (type);
2054   if (wi::neg_p (w1))
2055     {
2056       // It's unclear from the C standard whether shifts can overflow.
2057       // The following code ignores overflow; perhaps a C standard
2058       // interpretation ruling is needed.
2059       res = wi::rshift (w0, -w1, sign);
2060     }
2061   else
2062     res = wi::lshift (w0, w1);
2063   return false;
2064 }
2065 
2066 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const2067 operator_lshift::op1_range (irange &r,
2068 			    tree type,
2069 			    const irange &lhs,
2070 			    const irange &op2,
2071 			    relation_kind rel ATTRIBUTE_UNUSED) const
2072 {
2073   tree shift_amount;
2074 
2075   if (!lhs.contains_p (build_zero_cst (type)))
2076     r.set_nonzero (type);
2077   else
2078     r.set_varying (type);
2079 
2080   if (op2.singleton_p (&shift_amount))
2081     {
2082       wide_int shift = wi::to_wide (shift_amount);
2083       if (wi::lt_p (shift, 0, SIGNED))
2084 	return false;
2085       if (wi::ge_p (shift, wi::uhwi (TYPE_PRECISION (type),
2086 				     TYPE_PRECISION (op2.type ())),
2087 		    UNSIGNED))
2088 	return false;
2089       if (shift == 0)
2090 	{
2091 	  r.intersect (lhs);
2092 	  return true;
2093 	}
2094 
2095       // Work completely in unsigned mode to start.
2096       tree utype = type;
2097       int_range_max tmp_range;
2098       if (TYPE_SIGN (type) == SIGNED)
2099 	{
2100 	  int_range_max tmp = lhs;
2101 	  utype = unsigned_type_for (type);
2102 	  range_cast (tmp, utype);
2103 	  op_rshift.fold_range (tmp_range, utype, tmp, op2);
2104 	}
2105       else
2106 	op_rshift.fold_range (tmp_range, utype, lhs, op2);
2107 
2108       // Start with ranges which can produce the LHS by right shifting the
2109       // result by the shift amount.
2110       // ie   [0x08, 0xF0] = op1 << 2 will start with
2111       //      [00001000, 11110000] = op1 << 2
2112       //  [0x02, 0x4C] aka [00000010, 00111100]
2113 
2114       // Then create a range from the LB with the least significant upper bit
2115       // set, to the upper bound with all the bits set.
2116       // This would be [0x42, 0xFC] aka [01000010, 11111100].
2117 
2118       // Ideally we do this for each subrange, but just lump them all for now.
2119       unsigned low_bits = TYPE_PRECISION (utype)
2120 			  - TREE_INT_CST_LOW (shift_amount);
2121       wide_int up_mask = wi::mask (low_bits, true, TYPE_PRECISION (utype));
2122       wide_int new_ub = wi::bit_or (up_mask, tmp_range.upper_bound ());
2123       wide_int new_lb = wi::set_bit (tmp_range.lower_bound (), low_bits);
2124       int_range<2> fill_range (utype, new_lb, new_ub);
2125       tmp_range.union_ (fill_range);
2126 
2127       if (utype != type)
2128 	range_cast (tmp_range, type);
2129 
2130       r.intersect (tmp_range);
2131       return true;
2132     }
2133 
2134   return !r.varying_p ();
2135 }
2136 
2137 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const2138 operator_rshift::op1_range (irange &r,
2139 			    tree type,
2140 			    const irange &lhs,
2141 			    const irange &op2,
2142 			    relation_kind rel ATTRIBUTE_UNUSED) const
2143 {
2144   tree shift;
2145   if (op2.singleton_p (&shift))
2146     {
2147       // Ignore nonsensical shifts.
2148       unsigned prec = TYPE_PRECISION (type);
2149       if (wi::ge_p (wi::to_wide (shift),
2150 		    wi::uhwi (prec, TYPE_PRECISION (TREE_TYPE (shift))),
2151 		    UNSIGNED))
2152 	return false;
2153       if (wi::to_wide (shift) == 0)
2154 	{
2155 	  r = lhs;
2156 	  return true;
2157 	}
2158 
2159       // Folding the original operation may discard some impossible
2160       // ranges from the LHS.
2161       int_range_max lhs_refined;
2162       op_rshift.fold_range (lhs_refined, type, int_range<1> (type), op2);
2163       lhs_refined.intersect (lhs);
2164       if (lhs_refined.undefined_p ())
2165 	{
2166 	  r.set_undefined ();
2167 	  return true;
2168 	}
2169       int_range_max shift_range (shift, shift);
2170       int_range_max lb, ub;
2171       op_lshift.fold_range (lb, type, lhs_refined, shift_range);
2172       //    LHS
2173       // 0000 0111 = OP1 >> 3
2174       //
2175       // OP1 is anything from 0011 1000 to 0011 1111.  That is, a
2176       // range from LHS<<3 plus a mask of the 3 bits we shifted on the
2177       // right hand side (0x07).
2178       tree mask = fold_build1 (BIT_NOT_EXPR, type,
2179 			       fold_build2 (LSHIFT_EXPR, type,
2180 					    build_minus_one_cst (type),
2181 					    shift));
2182       int_range_max mask_range (build_zero_cst (type), mask);
2183       op_plus.fold_range (ub, type, lb, mask_range);
2184       r = lb;
2185       r.union_ (ub);
2186       if (!lhs_refined.contains_p (build_zero_cst (type)))
2187 	{
2188 	  mask_range.invert ();
2189 	  r.intersect (mask_range);
2190 	}
2191       return true;
2192     }
2193   return false;
2194 }
2195 
2196 bool
wi_op_overflows(wide_int & res,tree type,const wide_int & w0,const wide_int & w1) const2197 operator_rshift::wi_op_overflows (wide_int &res,
2198 				  tree type,
2199 				  const wide_int &w0,
2200 				  const wide_int &w1) const
2201 {
2202   signop sign = TYPE_SIGN (type);
2203   if (wi::neg_p (w1))
2204     res = wi::lshift (w0, -w1);
2205   else
2206     {
2207       // It's unclear from the C standard whether shifts can overflow.
2208       // The following code ignores overflow; perhaps a C standard
2209       // interpretation ruling is needed.
2210       res = wi::rshift (w0, w1, sign);
2211     }
2212   return false;
2213 }
2214 
2215 bool
fold_range(irange & r,tree type,const irange & op1,const irange & op2,relation_kind rel) const2216 operator_rshift::fold_range (irange &r, tree type,
2217 			     const irange &op1,
2218 			     const irange &op2,
2219 			     relation_kind rel) const
2220 {
2221   int_range_max shift;
2222   if (!get_shift_range (shift, type, op2))
2223     {
2224       if (op2.undefined_p ())
2225 	r.set_undefined ();
2226       else
2227 	r.set_varying (type);
2228       return true;
2229     }
2230 
2231   return range_operator::fold_range (r, type, op1, shift, rel);
2232 }
2233 
2234 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) const2235 operator_rshift::wi_fold (irange &r, tree type,
2236 			  const wide_int &lh_lb, const wide_int &lh_ub,
2237 			  const wide_int &rh_lb, const wide_int &rh_ub) const
2238 {
2239   wi_cross_product (r, type, lh_lb, lh_ub, rh_lb, rh_ub);
2240 }
2241 
2242 
2243 class operator_cast: public range_operator
2244 {
2245 public:
2246   virtual bool fold_range (irange &r, tree type,
2247 			   const irange &op1,
2248 			   const irange &op2,
2249 			   relation_kind rel = VREL_NONE) const;
2250   virtual bool op1_range (irange &r, tree type,
2251 			  const irange &lhs,
2252 			  const irange &op2,
2253 			  relation_kind rel = VREL_NONE) const;
2254 private:
2255   bool truncating_cast_p (const irange &inner, const irange &outer) const;
2256   bool inside_domain_p (const wide_int &min, const wide_int &max,
2257 			const irange &outer) const;
2258   void fold_pair (irange &r, unsigned index, const irange &inner,
2259 			   const irange &outer) const;
2260 } op_convert;
2261 
2262 // Return TRUE if casting from INNER to OUTER is a truncating cast.
2263 
2264 inline bool
truncating_cast_p(const irange & inner,const irange & outer) const2265 operator_cast::truncating_cast_p (const irange &inner,
2266 				  const irange &outer) const
2267 {
2268   return TYPE_PRECISION (outer.type ()) < TYPE_PRECISION (inner.type ());
2269 }
2270 
2271 // Return TRUE if [MIN,MAX] is inside the domain of RANGE's type.
2272 
2273 bool
inside_domain_p(const wide_int & min,const wide_int & max,const irange & range) const2274 operator_cast::inside_domain_p (const wide_int &min,
2275 				const wide_int &max,
2276 				const irange &range) const
2277 {
2278   wide_int domain_min = wi::to_wide (vrp_val_min (range.type ()));
2279   wide_int domain_max = wi::to_wide (vrp_val_max (range.type ()));
2280   signop domain_sign = TYPE_SIGN (range.type ());
2281   return (wi::le_p (min, domain_max, domain_sign)
2282 	  && wi::le_p (max, domain_max, domain_sign)
2283 	  && wi::ge_p (min, domain_min, domain_sign)
2284 	  && wi::ge_p (max, domain_min, domain_sign));
2285 }
2286 
2287 
2288 // Helper for fold_range which work on a pair at a time.
2289 
2290 void
fold_pair(irange & r,unsigned index,const irange & inner,const irange & outer) const2291 operator_cast::fold_pair (irange &r, unsigned index,
2292 			   const irange &inner,
2293 			   const irange &outer) const
2294 {
2295   tree inner_type = inner.type ();
2296   tree outer_type = outer.type ();
2297   signop inner_sign = TYPE_SIGN (inner_type);
2298   unsigned outer_prec = TYPE_PRECISION (outer_type);
2299 
2300   // check to see if casting from INNER to OUTER is a conversion that
2301   // fits in the resulting OUTER type.
2302   wide_int inner_lb = inner.lower_bound (index);
2303   wide_int inner_ub = inner.upper_bound (index);
2304   if (truncating_cast_p (inner, outer))
2305     {
2306       // We may be able to accomodate a truncating cast if the
2307       // resulting range can be represented in the target type...
2308       if (wi::rshift (wi::sub (inner_ub, inner_lb),
2309 		      wi::uhwi (outer_prec, TYPE_PRECISION (inner.type ())),
2310 				inner_sign) != 0)
2311 	{
2312 	  r.set_varying (outer_type);
2313 	  return;
2314 	}
2315     }
2316   // ...but we must still verify that the final range fits in the
2317   // domain.  This catches -fstrict-enum restrictions where the domain
2318   // range is smaller than what fits in the underlying type.
2319   wide_int min = wide_int::from (inner_lb, outer_prec, inner_sign);
2320   wide_int max = wide_int::from (inner_ub, outer_prec, inner_sign);
2321   if (inside_domain_p (min, max, outer))
2322     create_possibly_reversed_range (r, outer_type, min, max);
2323   else
2324     r.set_varying (outer_type);
2325 }
2326 
2327 
2328 bool
fold_range(irange & r,tree type ATTRIBUTE_UNUSED,const irange & inner,const irange & outer,relation_kind rel ATTRIBUTE_UNUSED) const2329 operator_cast::fold_range (irange &r, tree type ATTRIBUTE_UNUSED,
2330 			   const irange &inner,
2331 			   const irange &outer,
2332 			   relation_kind rel ATTRIBUTE_UNUSED) const
2333 {
2334   if (empty_range_varying (r, type, inner, outer))
2335     return true;
2336 
2337   gcc_checking_assert (outer.varying_p ());
2338   gcc_checking_assert (inner.num_pairs () > 0);
2339 
2340   // Avoid a temporary by folding the first pair directly into the result.
2341   fold_pair (r, 0, inner, outer);
2342 
2343   // Then process any additonal pairs by unioning with their results.
2344   for (unsigned x = 1; x < inner.num_pairs (); ++x)
2345     {
2346       int_range_max tmp;
2347       fold_pair (tmp, x, inner, outer);
2348       r.union_ (tmp);
2349       if (r.varying_p ())
2350 	return true;
2351     }
2352   return true;
2353 }
2354 
2355 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const2356 operator_cast::op1_range (irange &r, tree type,
2357 			  const irange &lhs,
2358 			  const irange &op2,
2359 			  relation_kind rel ATTRIBUTE_UNUSED) const
2360 {
2361   tree lhs_type = lhs.type ();
2362   gcc_checking_assert (types_compatible_p (op2.type(), type));
2363 
2364   // If we are calculating a pointer, shortcut to what we really care about.
2365   if (POINTER_TYPE_P (type))
2366     {
2367       // Conversion from other pointers or a constant (including 0/NULL)
2368       // are straightforward.
2369       if (POINTER_TYPE_P (lhs.type ())
2370 	  || (lhs.singleton_p ()
2371 	      && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
2372 	{
2373 	  r = lhs;
2374 	  range_cast (r, type);
2375 	}
2376       else
2377 	{
2378 	  // If the LHS is not a pointer nor a singleton, then it is
2379 	  // either VARYING or non-zero.
2380 	  if (!lhs.contains_p (build_zero_cst (lhs.type ())))
2381 	    r.set_nonzero (type);
2382 	  else
2383 	    r.set_varying (type);
2384 	}
2385       r.intersect (op2);
2386       return true;
2387     }
2388 
2389   if (truncating_cast_p (op2, lhs))
2390     {
2391       if (lhs.varying_p ())
2392 	r.set_varying (type);
2393       else
2394         {
2395 	  // We want to insert the LHS as an unsigned value since it
2396 	  // would not trigger the signed bit of the larger type.
2397 	  int_range_max converted_lhs = lhs;
2398 	  range_cast (converted_lhs, unsigned_type_for (lhs_type));
2399 	  range_cast (converted_lhs, type);
2400 	  // Start by building the positive signed outer range for the type.
2401 	  wide_int lim = wi::set_bit_in_zero (TYPE_PRECISION (lhs_type),
2402 					      TYPE_PRECISION (type));
2403 	  r = int_range<1> (type, lim, wi::max_value (TYPE_PRECISION (type),
2404 						      SIGNED));
2405 	  // For the signed part, we need to simply union the 2 ranges now.
2406 	  r.union_ (converted_lhs);
2407 
2408 	  // Create maximal negative number outside of LHS bits.
2409 	  lim = wi::mask (TYPE_PRECISION (lhs_type), true,
2410 			  TYPE_PRECISION (type));
2411 	  // Add this to the unsigned LHS range(s).
2412 	  int_range_max lim_range (type, lim, lim);
2413 	  int_range_max lhs_neg;
2414 	  range_op_handler (PLUS_EXPR, type)->fold_range (lhs_neg,
2415 							  type,
2416 							  converted_lhs,
2417 							  lim_range);
2418 	  // lhs_neg now has all the negative versions of the LHS.
2419 	  // Now union in all the values from SIGNED MIN (0x80000) to
2420 	  // lim-1 in order to fill in all the ranges with the upper
2421 	  // bits set.
2422 
2423 	  // PR 97317.  If the lhs has only 1 bit less precision than the rhs,
2424 	  // we don't need to create a range from min to lim-1
2425 	  // calculate neg range traps trying to create [lim, lim - 1].
2426 	  wide_int min_val = wi::min_value (TYPE_PRECISION (type), SIGNED);
2427 	  if (lim != min_val)
2428 	    {
2429 	      int_range_max neg (type,
2430 				 wi::min_value (TYPE_PRECISION (type),
2431 						SIGNED),
2432 				 lim - 1);
2433 	      lhs_neg.union_ (neg);
2434 	    }
2435 	  // And finally, munge the signed and unsigned portions.
2436 	  r.union_ (lhs_neg);
2437 	}
2438       // And intersect with any known value passed in the extra operand.
2439       r.intersect (op2);
2440       return true;
2441     }
2442 
2443   int_range_max tmp;
2444   if (TYPE_PRECISION (lhs_type) == TYPE_PRECISION (type))
2445     tmp = lhs;
2446   else
2447     {
2448       // The cast is not truncating, and the range is restricted to
2449       // the range of the RHS by this assignment.
2450       //
2451       // Cast the range of the RHS to the type of the LHS.
2452       fold_range (tmp, lhs_type, int_range<1> (type), int_range<1> (lhs_type));
2453       // Intersect this with the LHS range will produce the range,
2454       // which will be cast to the RHS type before returning.
2455       tmp.intersect (lhs);
2456     }
2457 
2458   // Cast the calculated range to the type of the RHS.
2459   fold_range (r, type, tmp, int_range<1> (type));
2460   return true;
2461 }
2462 
2463 
2464 class operator_logical_and : public range_operator
2465 {
2466 public:
2467   virtual bool fold_range (irange &r, tree type,
2468 			   const irange &lh,
2469 			   const irange &rh,
2470 			   relation_kind rel = VREL_NONE) const;
2471   virtual bool op1_range (irange &r, tree type,
2472 			  const irange &lhs,
2473 			  const irange &op2,
2474 			  relation_kind rel = VREL_NONE) const;
2475   virtual bool op2_range (irange &r, tree type,
2476 			  const irange &lhs,
2477 			  const irange &op1,
2478 			  relation_kind rel = VREL_NONE) const;
2479 } op_logical_and;
2480 
2481 
2482 bool
fold_range(irange & r,tree type,const irange & lh,const irange & rh,relation_kind rel ATTRIBUTE_UNUSED) const2483 operator_logical_and::fold_range (irange &r, tree type,
2484 				  const irange &lh,
2485 				  const irange &rh,
2486 				  relation_kind rel ATTRIBUTE_UNUSED) const
2487 {
2488   if (empty_range_varying (r, type, lh, rh))
2489     return true;
2490 
2491   // 0 && anything is 0.
2492   if ((wi::eq_p (lh.lower_bound (), 0) && wi::eq_p (lh.upper_bound (), 0))
2493       || (wi::eq_p (lh.lower_bound (), 0) && wi::eq_p (rh.upper_bound (), 0)))
2494     r = range_false (type);
2495   else if (lh.contains_p (build_zero_cst (lh.type ()))
2496 	   || rh.contains_p (build_zero_cst (rh.type ())))
2497     // To reach this point, there must be a logical 1 on each side, and
2498     // the only remaining question is whether there is a zero or not.
2499     r = range_true_and_false (type);
2500   else
2501     r = range_true (type);
2502   return true;
2503 }
2504 
2505 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2 ATTRIBUTE_UNUSED,relation_kind rel ATTRIBUTE_UNUSED) const2506 operator_logical_and::op1_range (irange &r, tree type,
2507 				 const irange &lhs,
2508 				 const irange &op2 ATTRIBUTE_UNUSED,
2509 				 relation_kind rel ATTRIBUTE_UNUSED) const
2510 {
2511    switch (get_bool_state (r, lhs, type))
2512      {
2513      case BRS_TRUE:
2514        // A true result means both sides of the AND must be true.
2515        r = range_true (type);
2516        break;
2517      default:
2518        // Any other result means only one side has to be false, the
2519        // other side can be anything. So we cannott be sure of any
2520        // result here.
2521        r = range_true_and_false (type);
2522        break;
2523      }
2524   return true;
2525 }
2526 
2527 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1,relation_kind rel ATTRIBUTE_UNUSED) const2528 operator_logical_and::op2_range (irange &r, tree type,
2529 				 const irange &lhs,
2530 				 const irange &op1,
2531 				 relation_kind rel ATTRIBUTE_UNUSED) const
2532 {
2533   return operator_logical_and::op1_range (r, type, lhs, op1);
2534 }
2535 
2536 
2537 class operator_bitwise_and : public range_operator
2538 {
2539 public:
2540   virtual bool fold_range (irange &r, tree type,
2541 			   const irange &lh,
2542 			   const irange &rh,
2543 			   relation_kind rel = VREL_NONE) const;
2544   virtual bool op1_range (irange &r, tree type,
2545 			  const irange &lhs,
2546 			  const irange &op2,
2547 			  relation_kind rel = VREL_NONE) const;
2548   virtual bool op2_range (irange &r, tree type,
2549 			  const irange &lhs,
2550 			  const irange &op1,
2551 			  relation_kind rel = VREL_NONE) const;
2552   virtual void wi_fold (irange &r, tree type,
2553 		        const wide_int &lh_lb,
2554 		        const wide_int &lh_ub,
2555 		        const wide_int &rh_lb,
2556 		        const wide_int &rh_ub) const;
2557 private:
2558   void simple_op1_range_solver (irange &r, tree type,
2559 				const irange &lhs,
2560 				const irange &op2) const;
2561   void remove_impossible_ranges (irange &r, const irange &rh) const;
2562 } op_bitwise_and;
2563 
2564 static bool
unsigned_singleton_p(const irange & op)2565 unsigned_singleton_p (const irange &op)
2566 {
2567   tree mask;
2568   if (op.singleton_p (&mask))
2569     {
2570       wide_int x = wi::to_wide (mask);
2571       return wi::ge_p (x, 0, TYPE_SIGN (op.type ()));
2572     }
2573   return false;
2574 }
2575 
2576 // Remove any ranges from R that are known to be impossible when an
2577 // range is ANDed with MASK.
2578 
2579 void
remove_impossible_ranges(irange & r,const irange & rmask) const2580 operator_bitwise_and::remove_impossible_ranges (irange &r,
2581 						const irange &rmask) const
2582 {
2583   if (r.undefined_p () || !unsigned_singleton_p (rmask))
2584     return;
2585 
2586   wide_int mask = rmask.lower_bound ();
2587   tree type = r.type ();
2588   int prec = TYPE_PRECISION (type);
2589   int leading_zeros = wi::clz (mask);
2590   int_range_max impossible_ranges;
2591 
2592   /* We know that starting at the most significant bit, any 0 in the
2593      mask means the resulting range cannot contain a 1 in that same
2594      position.  This means the following ranges are impossible:
2595 
2596 	x & 0b1001 1010
2597 			  IMPOSSIBLE RANGES
2598 	      01xx xxxx   [0100 0000, 0111 1111]
2599 	      001x xxxx   [0010 0000, 0011 1111]
2600 	      0000 01xx   [0000 0100, 0000 0111]
2601 	      0000 0001   [0000 0001, 0000 0001]
2602   */
2603   wide_int one = wi::one (prec);
2604   for (int i = 0; i < prec - leading_zeros - 1; ++i)
2605     if (wi::bit_and (mask, wi::lshift (one, wi::uhwi (i, prec))) == 0)
2606       {
2607 	tree lb = fold_build2 (LSHIFT_EXPR, type,
2608 			       build_one_cst (type),
2609 			       build_int_cst (type, i));
2610 	tree ub_left = fold_build1 (BIT_NOT_EXPR, type,
2611 				    fold_build2 (LSHIFT_EXPR, type,
2612 						 build_minus_one_cst (type),
2613 						 build_int_cst (type, i)));
2614 	tree ub_right = fold_build2 (LSHIFT_EXPR, type,
2615 				     build_one_cst (type),
2616 				     build_int_cst (type, i));
2617 	tree ub = fold_build2 (BIT_IOR_EXPR, type, ub_left, ub_right);
2618 	impossible_ranges.union_ (int_range<1> (lb, ub));
2619       }
2620   if (!impossible_ranges.undefined_p ())
2621     {
2622       impossible_ranges.invert ();
2623       r.intersect (impossible_ranges);
2624     }
2625 }
2626 
2627 bool
fold_range(irange & r,tree type,const irange & lh,const irange & rh,relation_kind rel ATTRIBUTE_UNUSED) const2628 operator_bitwise_and::fold_range (irange &r, tree type,
2629 				  const irange &lh,
2630 				  const irange &rh,
2631 				  relation_kind rel ATTRIBUTE_UNUSED) const
2632 {
2633   if (range_operator::fold_range (r, type, lh, rh))
2634     {
2635       // FIXME: This is temporarily disabled because, though it
2636       // generates better ranges, it's noticeably slower for evrp.
2637       // remove_impossible_ranges (r, rh);
2638       return true;
2639     }
2640   return false;
2641 }
2642 
2643 
2644 // Optimize BIT_AND_EXPR and BIT_IOR_EXPR in terms of a mask if
2645 // possible.  Basically, see if we can optimize:
2646 //
2647 //	[LB, UB] op Z
2648 //   into:
2649 //	[LB op Z, UB op Z]
2650 //
2651 // If the optimization was successful, accumulate the range in R and
2652 // return TRUE.
2653 
2654 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)2655 wi_optimize_and_or (irange &r,
2656 		    enum tree_code code,
2657 		    tree type,
2658 		    const wide_int &lh_lb, const wide_int &lh_ub,
2659 		    const wide_int &rh_lb, const wide_int &rh_ub)
2660 {
2661   // Calculate the singleton mask among the ranges, if any.
2662   wide_int lower_bound, upper_bound, mask;
2663   if (wi::eq_p (rh_lb, rh_ub))
2664     {
2665       mask = rh_lb;
2666       lower_bound = lh_lb;
2667       upper_bound = lh_ub;
2668     }
2669   else if (wi::eq_p (lh_lb, lh_ub))
2670     {
2671       mask = lh_lb;
2672       lower_bound = rh_lb;
2673       upper_bound = rh_ub;
2674     }
2675   else
2676     return false;
2677 
2678   // If Z is a constant which (for op | its bitwise not) has n
2679   // consecutive least significant bits cleared followed by m 1
2680   // consecutive bits set immediately above it and either
2681   // m + n == precision, or (x >> (m + n)) == (y >> (m + n)).
2682   //
2683   // The least significant n bits of all the values in the range are
2684   // cleared or set, the m bits above it are preserved and any bits
2685   // above these are required to be the same for all values in the
2686   // range.
2687   wide_int w = mask;
2688   int m = 0, n = 0;
2689   if (code == BIT_IOR_EXPR)
2690     w = ~w;
2691   if (wi::eq_p (w, 0))
2692     n = w.get_precision ();
2693   else
2694     {
2695       n = wi::ctz (w);
2696       w = ~(w | wi::mask (n, false, w.get_precision ()));
2697       if (wi::eq_p (w, 0))
2698 	m = w.get_precision () - n;
2699       else
2700 	m = wi::ctz (w) - n;
2701     }
2702   wide_int new_mask = wi::mask (m + n, true, w.get_precision ());
2703   if ((new_mask & lower_bound) != (new_mask & upper_bound))
2704     return false;
2705 
2706   wide_int res_lb, res_ub;
2707   if (code == BIT_AND_EXPR)
2708     {
2709       res_lb = wi::bit_and (lower_bound, mask);
2710       res_ub = wi::bit_and (upper_bound, mask);
2711     }
2712   else if (code == BIT_IOR_EXPR)
2713     {
2714       res_lb = wi::bit_or (lower_bound, mask);
2715       res_ub = wi::bit_or (upper_bound, mask);
2716     }
2717   else
2718     gcc_unreachable ();
2719   value_range_with_overflow (r, type, res_lb, res_ub);
2720 
2721   // Furthermore, if the mask is non-zero, an IOR cannot contain zero.
2722   if (code == BIT_IOR_EXPR && wi::ne_p (mask, 0))
2723     {
2724       int_range<2> tmp;
2725       tmp.set_nonzero (type);
2726       r.intersect (tmp);
2727     }
2728   return true;
2729 }
2730 
2731 // For range [LB, UB] compute two wide_int bit masks.
2732 //
2733 // In the MAYBE_NONZERO bit mask, if some bit is unset, it means that
2734 // for all numbers in the range the bit is 0, otherwise it might be 0
2735 // or 1.
2736 //
2737 // In the MUSTBE_NONZERO bit mask, if some bit is set, it means that
2738 // for all numbers in the range the bit is 1, otherwise it might be 0
2739 // or 1.
2740 
2741 void
wi_set_zero_nonzero_bits(tree type,const wide_int & lb,const wide_int & ub,wide_int & maybe_nonzero,wide_int & mustbe_nonzero)2742 wi_set_zero_nonzero_bits (tree type,
2743 			  const wide_int &lb, const wide_int &ub,
2744 			  wide_int &maybe_nonzero,
2745 			  wide_int &mustbe_nonzero)
2746 {
2747   signop sign = TYPE_SIGN (type);
2748 
2749   if (wi::eq_p (lb, ub))
2750     maybe_nonzero = mustbe_nonzero = lb;
2751   else if (wi::ge_p (lb, 0, sign) || wi::lt_p (ub, 0, sign))
2752     {
2753       wide_int xor_mask = lb ^ ub;
2754       maybe_nonzero = lb | ub;
2755       mustbe_nonzero = lb & ub;
2756       if (xor_mask != 0)
2757 	{
2758 	  wide_int mask = wi::mask (wi::floor_log2 (xor_mask), false,
2759 				    maybe_nonzero.get_precision ());
2760 	  maybe_nonzero = maybe_nonzero | mask;
2761 	  mustbe_nonzero = wi::bit_and_not (mustbe_nonzero, mask);
2762 	}
2763     }
2764   else
2765     {
2766       maybe_nonzero = wi::minus_one (lb.get_precision ());
2767       mustbe_nonzero = wi::zero (lb.get_precision ());
2768     }
2769 }
2770 
2771 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) const2772 operator_bitwise_and::wi_fold (irange &r, tree type,
2773 			       const wide_int &lh_lb,
2774 			       const wide_int &lh_ub,
2775 			       const wide_int &rh_lb,
2776 			       const wide_int &rh_ub) const
2777 {
2778   if (wi_optimize_and_or (r, BIT_AND_EXPR, type, lh_lb, lh_ub, rh_lb, rh_ub))
2779     return;
2780 
2781   wide_int maybe_nonzero_lh, mustbe_nonzero_lh;
2782   wide_int maybe_nonzero_rh, mustbe_nonzero_rh;
2783   wi_set_zero_nonzero_bits (type, lh_lb, lh_ub,
2784 			    maybe_nonzero_lh, mustbe_nonzero_lh);
2785   wi_set_zero_nonzero_bits (type, rh_lb, rh_ub,
2786 			    maybe_nonzero_rh, mustbe_nonzero_rh);
2787 
2788   wide_int new_lb = mustbe_nonzero_lh & mustbe_nonzero_rh;
2789   wide_int new_ub = maybe_nonzero_lh & maybe_nonzero_rh;
2790   signop sign = TYPE_SIGN (type);
2791   unsigned prec = TYPE_PRECISION (type);
2792   // If both input ranges contain only negative values, we can
2793   // truncate the result range maximum to the minimum of the
2794   // input range maxima.
2795   if (wi::lt_p (lh_ub, 0, sign) && wi::lt_p (rh_ub, 0, sign))
2796     {
2797       new_ub = wi::min (new_ub, lh_ub, sign);
2798       new_ub = wi::min (new_ub, rh_ub, sign);
2799     }
2800   // If either input range contains only non-negative values
2801   // we can truncate the result range maximum to the respective
2802   // maximum of the input range.
2803   if (wi::ge_p (lh_lb, 0, sign))
2804     new_ub = wi::min (new_ub, lh_ub, sign);
2805   if (wi::ge_p (rh_lb, 0, sign))
2806     new_ub = wi::min (new_ub, rh_ub, sign);
2807   // PR68217: In case of signed & sign-bit-CST should
2808   // result in [-INF, 0] instead of [-INF, INF].
2809   if (wi::gt_p (new_lb, new_ub, sign))
2810     {
2811       wide_int sign_bit = wi::set_bit_in_zero (prec - 1, prec);
2812       if (sign == SIGNED
2813 	  && ((wi::eq_p (lh_lb, lh_ub)
2814 	       && !wi::cmps (lh_lb, sign_bit))
2815 	      || (wi::eq_p (rh_lb, rh_ub)
2816 		  && !wi::cmps (rh_lb, sign_bit))))
2817 	{
2818 	  new_lb = wi::min_value (prec, sign);
2819 	  new_ub = wi::zero (prec);
2820 	}
2821     }
2822   // If the limits got swapped around, return varying.
2823   if (wi::gt_p (new_lb, new_ub,sign))
2824     r.set_varying (type);
2825   else
2826     value_range_with_overflow (r, type, new_lb, new_ub);
2827 }
2828 
2829 static void
set_nonzero_range_from_mask(irange & r,tree type,const irange & lhs)2830 set_nonzero_range_from_mask (irange &r, tree type, const irange &lhs)
2831 {
2832   if (!lhs.contains_p (build_zero_cst (type)))
2833     r = range_nonzero (type);
2834   else
2835     r.set_varying (type);
2836 }
2837 
2838 // This was shamelessly stolen from register_edge_assert_for_2 and
2839 // adjusted to work with iranges.
2840 
2841 void
simple_op1_range_solver(irange & r,tree type,const irange & lhs,const irange & op2) const2842 operator_bitwise_and::simple_op1_range_solver (irange &r, tree type,
2843 					       const irange &lhs,
2844 					       const irange &op2) const
2845 {
2846   if (!op2.singleton_p ())
2847     {
2848       set_nonzero_range_from_mask (r, type, lhs);
2849       return;
2850     }
2851   unsigned int nprec = TYPE_PRECISION (type);
2852   wide_int cst2v = op2.lower_bound ();
2853   bool cst2n = wi::neg_p (cst2v, TYPE_SIGN (type));
2854   wide_int sgnbit;
2855   if (cst2n)
2856     sgnbit = wi::set_bit_in_zero (nprec - 1, nprec);
2857   else
2858     sgnbit = wi::zero (nprec);
2859 
2860   // Solve [lhs.lower_bound (), +INF] = x & MASK.
2861   //
2862   // Minimum unsigned value for >= if (VAL & CST2) == VAL is VAL and
2863   // maximum unsigned value is ~0.  For signed comparison, if CST2
2864   // doesn't have the most significant bit set, handle it similarly.  If
2865   // CST2 has MSB set, the minimum is the same, and maximum is ~0U/2.
2866   wide_int valv = lhs.lower_bound ();
2867   wide_int minv = valv & cst2v, maxv;
2868   bool we_know_nothing = false;
2869   if (minv != valv)
2870     {
2871       // If (VAL & CST2) != VAL, X & CST2 can't be equal to VAL.
2872       minv = masked_increment (valv, cst2v, sgnbit, nprec);
2873       if (minv == valv)
2874 	{
2875 	  // If we can't determine anything on this bound, fall
2876 	  // through and conservatively solve for the other end point.
2877 	  we_know_nothing = true;
2878 	}
2879     }
2880   maxv = wi::mask (nprec - (cst2n ? 1 : 0), false, nprec);
2881   if (we_know_nothing)
2882     r.set_varying (type);
2883   else
2884     r = int_range<1> (type, minv, maxv);
2885 
2886   // Solve [-INF, lhs.upper_bound ()] = x & MASK.
2887   //
2888   // Minimum unsigned value for <= is 0 and maximum unsigned value is
2889   // VAL | ~CST2 if (VAL & CST2) == VAL.  Otherwise, find smallest
2890   // VAL2 where
2891   // VAL2 > VAL && (VAL2 & CST2) == VAL2 and use (VAL2 - 1) | ~CST2
2892   // as maximum.
2893   // For signed comparison, if CST2 doesn't have most significant bit
2894   // set, handle it similarly.  If CST2 has MSB set, the maximum is
2895   // the same and minimum is INT_MIN.
2896   valv = lhs.upper_bound ();
2897   minv = valv & cst2v;
2898   if (minv == valv)
2899     maxv = valv;
2900   else
2901     {
2902       maxv = masked_increment (valv, cst2v, sgnbit, nprec);
2903       if (maxv == valv)
2904 	{
2905 	  // If we couldn't determine anything on either bound, return
2906 	  // undefined.
2907 	  if (we_know_nothing)
2908 	    r.set_undefined ();
2909 	  return;
2910 	}
2911       maxv -= 1;
2912     }
2913   maxv |= ~cst2v;
2914   minv = sgnbit;
2915   int_range<1> upper_bits (type, minv, maxv);
2916   r.intersect (upper_bits);
2917 }
2918 
2919 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const2920 operator_bitwise_and::op1_range (irange &r, tree type,
2921 				 const irange &lhs,
2922 				 const irange &op2,
2923 				 relation_kind rel ATTRIBUTE_UNUSED) const
2924 {
2925   if (types_compatible_p (type, boolean_type_node))
2926     return op_logical_and.op1_range (r, type, lhs, op2);
2927 
2928   r.set_undefined ();
2929   for (unsigned i = 0; i < lhs.num_pairs (); ++i)
2930     {
2931       int_range_max chunk (lhs.type (),
2932 			   lhs.lower_bound (i),
2933 			   lhs.upper_bound (i));
2934       int_range_max res;
2935       simple_op1_range_solver (res, type, chunk, op2);
2936       r.union_ (res);
2937     }
2938   if (r.undefined_p ())
2939     set_nonzero_range_from_mask (r, type, lhs);
2940   return true;
2941 }
2942 
2943 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1,relation_kind rel ATTRIBUTE_UNUSED) const2944 operator_bitwise_and::op2_range (irange &r, tree type,
2945 				 const irange &lhs,
2946 				 const irange &op1,
2947 				 relation_kind rel ATTRIBUTE_UNUSED) const
2948 {
2949   return operator_bitwise_and::op1_range (r, type, lhs, op1);
2950 }
2951 
2952 
2953 class operator_logical_or : public range_operator
2954 {
2955 public:
2956   virtual bool fold_range (irange &r, tree type,
2957 			   const irange &lh,
2958 			   const irange &rh,
2959 			   relation_kind rel = VREL_NONE) const;
2960   virtual bool op1_range (irange &r, tree type,
2961 			  const irange &lhs,
2962 			  const irange &op2,
2963 			  relation_kind rel = VREL_NONE) const;
2964   virtual bool op2_range (irange &r, tree type,
2965 			  const irange &lhs,
2966 			  const irange &op1,
2967 			  relation_kind rel = VREL_NONE) const;
2968 } op_logical_or;
2969 
2970 bool
fold_range(irange & r,tree type ATTRIBUTE_UNUSED,const irange & lh,const irange & rh,relation_kind rel ATTRIBUTE_UNUSED) const2971 operator_logical_or::fold_range (irange &r, tree type ATTRIBUTE_UNUSED,
2972 				 const irange &lh,
2973 				 const irange &rh,
2974 				 relation_kind rel ATTRIBUTE_UNUSED) const
2975 {
2976   if (empty_range_varying (r, type, lh, rh))
2977     return true;
2978 
2979   r = lh;
2980   r.union_ (rh);
2981   return true;
2982 }
2983 
2984 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2 ATTRIBUTE_UNUSED,relation_kind rel ATTRIBUTE_UNUSED) const2985 operator_logical_or::op1_range (irange &r, tree type,
2986 				const irange &lhs,
2987 				const irange &op2 ATTRIBUTE_UNUSED,
2988 				relation_kind rel ATTRIBUTE_UNUSED) const
2989 {
2990    switch (get_bool_state (r, lhs, type))
2991      {
2992      case BRS_FALSE:
2993        // A false result means both sides of the OR must be false.
2994        r = range_false (type);
2995        break;
2996      default:
2997        // Any other result means only one side has to be true, the
2998        // other side can be anything. so we can't be sure of any result
2999        // here.
3000        r = range_true_and_false (type);
3001        break;
3002     }
3003   return true;
3004 }
3005 
3006 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1,relation_kind rel ATTRIBUTE_UNUSED) const3007 operator_logical_or::op2_range (irange &r, tree type,
3008 				const irange &lhs,
3009 				const irange &op1,
3010 				relation_kind rel ATTRIBUTE_UNUSED) const
3011 {
3012   return operator_logical_or::op1_range (r, type, lhs, op1);
3013 }
3014 
3015 
3016 class operator_bitwise_or : public range_operator
3017 {
3018 public:
3019   virtual bool op1_range (irange &r, tree type,
3020 			  const irange &lhs,
3021 			  const irange &op2,
3022 			  relation_kind rel = VREL_NONE) const;
3023   virtual bool op2_range (irange &r, tree type,
3024 			  const irange &lhs,
3025 			  const irange &op1,
3026 			  relation_kind rel= VREL_NONE) const;
3027   virtual void wi_fold (irange &r, tree type,
3028 		        const wide_int &lh_lb,
3029 		        const wide_int &lh_ub,
3030 		        const wide_int &rh_lb,
3031 		        const wide_int &rh_ub) const;
3032 } op_bitwise_or;
3033 
3034 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) const3035 operator_bitwise_or::wi_fold (irange &r, tree type,
3036 			      const wide_int &lh_lb,
3037 			      const wide_int &lh_ub,
3038 			      const wide_int &rh_lb,
3039 			      const wide_int &rh_ub) const
3040 {
3041   if (wi_optimize_and_or (r, BIT_IOR_EXPR, type, lh_lb, lh_ub, rh_lb, rh_ub))
3042     return;
3043 
3044   wide_int maybe_nonzero_lh, mustbe_nonzero_lh;
3045   wide_int maybe_nonzero_rh, mustbe_nonzero_rh;
3046   wi_set_zero_nonzero_bits (type, lh_lb, lh_ub,
3047 			    maybe_nonzero_lh, mustbe_nonzero_lh);
3048   wi_set_zero_nonzero_bits (type, rh_lb, rh_ub,
3049 			    maybe_nonzero_rh, mustbe_nonzero_rh);
3050   wide_int new_lb = mustbe_nonzero_lh | mustbe_nonzero_rh;
3051   wide_int new_ub = maybe_nonzero_lh | maybe_nonzero_rh;
3052   signop sign = TYPE_SIGN (type);
3053   // If the input ranges contain only positive values we can
3054   // truncate the minimum of the result range to the maximum
3055   // of the input range minima.
3056   if (wi::ge_p (lh_lb, 0, sign)
3057       && wi::ge_p (rh_lb, 0, sign))
3058     {
3059       new_lb = wi::max (new_lb, lh_lb, sign);
3060       new_lb = wi::max (new_lb, rh_lb, sign);
3061     }
3062   // If either input range contains only negative values
3063   // we can truncate the minimum of the result range to the
3064   // respective minimum range.
3065   if (wi::lt_p (lh_ub, 0, sign))
3066     new_lb = wi::max (new_lb, lh_lb, sign);
3067   if (wi::lt_p (rh_ub, 0, sign))
3068     new_lb = wi::max (new_lb, rh_lb, sign);
3069   // If the limits got swapped around, return a conservative range.
3070   if (wi::gt_p (new_lb, new_ub, sign))
3071     {
3072       // Make sure that nonzero|X is nonzero.
3073       if (wi::gt_p (lh_lb, 0, sign)
3074 	  || wi::gt_p (rh_lb, 0, sign)
3075 	  || wi::lt_p (lh_ub, 0, sign)
3076 	  || wi::lt_p (rh_ub, 0, sign))
3077 	r.set_nonzero (type);
3078       else
3079 	r.set_varying (type);
3080       return;
3081     }
3082   value_range_with_overflow (r, type, new_lb, new_ub);
3083 }
3084 
3085 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const3086 operator_bitwise_or::op1_range (irange &r, tree type,
3087 				const irange &lhs,
3088 				const irange &op2,
3089 				relation_kind rel ATTRIBUTE_UNUSED) const
3090 {
3091   // If this is really a logical wi_fold, call that.
3092   if (types_compatible_p (type, boolean_type_node))
3093     return op_logical_or.op1_range (r, type, lhs, op2);
3094 
3095   if (lhs.zero_p ())
3096     {
3097       tree zero = build_zero_cst (type);
3098       r = int_range<1> (zero, zero);
3099       return true;
3100     }
3101   r.set_varying (type);
3102   return true;
3103 }
3104 
3105 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1,relation_kind rel ATTRIBUTE_UNUSED) const3106 operator_bitwise_or::op2_range (irange &r, tree type,
3107 				const irange &lhs,
3108 				const irange &op1,
3109 				relation_kind rel ATTRIBUTE_UNUSED) const
3110 {
3111   return operator_bitwise_or::op1_range (r, type, lhs, op1);
3112 }
3113 
3114 
3115 class operator_bitwise_xor : public range_operator
3116 {
3117 public:
3118   virtual void wi_fold (irange &r, tree type,
3119 		        const wide_int &lh_lb,
3120 		        const wide_int &lh_ub,
3121 		        const wide_int &rh_lb,
3122 		        const wide_int &rh_ub) const;
3123   virtual bool op1_range (irange &r, tree type,
3124 			  const irange &lhs,
3125 			  const irange &op2,
3126 			  relation_kind rel = VREL_NONE) const;
3127   virtual bool op2_range (irange &r, tree type,
3128 			  const irange &lhs,
3129 			  const irange &op1,
3130 			  relation_kind rel = VREL_NONE) const;
3131   virtual bool op1_op2_relation_effect (irange &lhs_range,
3132 					tree type,
3133 					const irange &op1_range,
3134 					const irange &op2_range,
3135 					relation_kind rel) const;
3136 } op_bitwise_xor;
3137 
3138 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) const3139 operator_bitwise_xor::wi_fold (irange &r, tree type,
3140 			       const wide_int &lh_lb,
3141 			       const wide_int &lh_ub,
3142 			       const wide_int &rh_lb,
3143 			       const wide_int &rh_ub) const
3144 {
3145   signop sign = TYPE_SIGN (type);
3146   wide_int maybe_nonzero_lh, mustbe_nonzero_lh;
3147   wide_int maybe_nonzero_rh, mustbe_nonzero_rh;
3148   wi_set_zero_nonzero_bits (type, lh_lb, lh_ub,
3149 			    maybe_nonzero_lh, mustbe_nonzero_lh);
3150   wi_set_zero_nonzero_bits (type, rh_lb, rh_ub,
3151 			    maybe_nonzero_rh, mustbe_nonzero_rh);
3152 
3153   wide_int result_zero_bits = ((mustbe_nonzero_lh & mustbe_nonzero_rh)
3154 			       | ~(maybe_nonzero_lh | maybe_nonzero_rh));
3155   wide_int result_one_bits
3156     = (wi::bit_and_not (mustbe_nonzero_lh, maybe_nonzero_rh)
3157        | wi::bit_and_not (mustbe_nonzero_rh, maybe_nonzero_lh));
3158   wide_int new_ub = ~result_zero_bits;
3159   wide_int new_lb = result_one_bits;
3160 
3161   // If the range has all positive or all negative values, the result
3162   // is better than VARYING.
3163   if (wi::lt_p (new_lb, 0, sign) || wi::ge_p (new_ub, 0, sign))
3164     value_range_with_overflow (r, type, new_lb, new_ub);
3165   else
3166     r.set_varying (type);
3167 }
3168 
3169 bool
op1_op2_relation_effect(irange & lhs_range,tree type,const irange &,const irange &,relation_kind rel) const3170 operator_bitwise_xor::op1_op2_relation_effect (irange &lhs_range,
3171 					       tree type,
3172 					       const irange &,
3173 					       const irange &,
3174 					       relation_kind rel) const
3175 {
3176   if (rel == VREL_NONE)
3177     return false;
3178 
3179   int_range<2> rel_range;
3180 
3181   switch (rel)
3182     {
3183     case EQ_EXPR:
3184       rel_range.set_zero (type);
3185       break;
3186     case NE_EXPR:
3187       rel_range.set_nonzero (type);
3188       break;
3189     default:
3190       return false;
3191     }
3192 
3193   lhs_range.intersect (rel_range);
3194   return true;
3195 }
3196 
3197 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const3198 operator_bitwise_xor::op1_range (irange &r, tree type,
3199 				 const irange &lhs,
3200 				 const irange &op2,
3201 				 relation_kind rel ATTRIBUTE_UNUSED) const
3202 {
3203   if (lhs.undefined_p () || lhs.varying_p ())
3204     {
3205       r = lhs;
3206       return true;
3207     }
3208   if (types_compatible_p (type, boolean_type_node))
3209     {
3210       switch (get_bool_state (r, lhs, type))
3211 	{
3212 	case BRS_TRUE:
3213 	  if (op2.varying_p ())
3214 	    r.set_varying (type);
3215 	  else if (op2.zero_p ())
3216 	    r = range_true (type);
3217 	  else
3218 	    r = range_false (type);
3219 	  break;
3220 	case BRS_FALSE:
3221 	  r = op2;
3222 	  break;
3223 	default:
3224 	  break;
3225 	}
3226       return true;
3227     }
3228   r.set_varying (type);
3229   return true;
3230 }
3231 
3232 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1,relation_kind rel ATTRIBUTE_UNUSED) const3233 operator_bitwise_xor::op2_range (irange &r, tree type,
3234 				 const irange &lhs,
3235 				 const irange &op1,
3236 				 relation_kind rel ATTRIBUTE_UNUSED) const
3237 {
3238   return operator_bitwise_xor::op1_range (r, type, lhs, op1);
3239 }
3240 
3241 class operator_trunc_mod : public range_operator
3242 {
3243 public:
3244   virtual void wi_fold (irange &r, tree type,
3245 		        const wide_int &lh_lb,
3246 		        const wide_int &lh_ub,
3247 		        const wide_int &rh_lb,
3248 		        const wide_int &rh_ub) const;
3249   virtual bool op1_range (irange &r, tree type,
3250 			  const irange &lhs,
3251 			  const irange &op2,
3252 			  relation_kind rel ATTRIBUTE_UNUSED) const;
3253   virtual bool op2_range (irange &r, tree type,
3254 			  const irange &lhs,
3255 			  const irange &op1,
3256 			  relation_kind rel ATTRIBUTE_UNUSED) const;
3257 } op_trunc_mod;
3258 
3259 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) const3260 operator_trunc_mod::wi_fold (irange &r, tree type,
3261 			     const wide_int &lh_lb,
3262 			     const wide_int &lh_ub,
3263 			     const wide_int &rh_lb,
3264 			     const wide_int &rh_ub) const
3265 {
3266   wide_int new_lb, new_ub, tmp;
3267   signop sign = TYPE_SIGN (type);
3268   unsigned prec = TYPE_PRECISION (type);
3269 
3270   // Mod 0 is undefined.
3271   if (wi_zero_p (type, rh_lb, rh_ub))
3272     {
3273       r.set_undefined ();
3274       return;
3275     }
3276 
3277   // Check for constant and try to fold.
3278   if (lh_lb == lh_ub && rh_lb == rh_ub)
3279     {
3280       wi::overflow_type ov = wi::OVF_NONE;
3281       tmp = wi::mod_trunc (lh_lb, rh_lb, sign, &ov);
3282       if (ov == wi::OVF_NONE)
3283 	{
3284 	  r = int_range<2> (type, tmp, tmp);
3285 	  return;
3286 	}
3287     }
3288 
3289   // ABS (A % B) < ABS (B) and either 0 <= A % B <= A or A <= A % B <= 0.
3290   new_ub = rh_ub - 1;
3291   if (sign == SIGNED)
3292     {
3293       tmp = -1 - rh_lb;
3294       new_ub = wi::smax (new_ub, tmp);
3295     }
3296 
3297   if (sign == UNSIGNED)
3298     new_lb = wi::zero (prec);
3299   else
3300     {
3301       new_lb = -new_ub;
3302       tmp = lh_lb;
3303       if (wi::gts_p (tmp, 0))
3304 	tmp = wi::zero (prec);
3305       new_lb = wi::smax (new_lb, tmp);
3306     }
3307   tmp = lh_ub;
3308   if (sign == SIGNED && wi::neg_p (tmp))
3309     tmp = wi::zero (prec);
3310   new_ub = wi::min (new_ub, tmp, sign);
3311 
3312   value_range_with_overflow (r, type, new_lb, new_ub);
3313 }
3314 
3315 bool
op1_range(irange & r,tree type,const irange & lhs,const irange &,relation_kind rel ATTRIBUTE_UNUSED) const3316 operator_trunc_mod::op1_range (irange &r, tree type,
3317 			       const irange &lhs,
3318 			       const irange &,
3319 			       relation_kind rel ATTRIBUTE_UNUSED) const
3320 {
3321   // PR 91029.
3322   signop sign = TYPE_SIGN (type);
3323   unsigned prec = TYPE_PRECISION (type);
3324   // (a % b) >= x && x > 0 , then a >= x.
3325   if (wi::gt_p (lhs.lower_bound (), 0, sign))
3326     {
3327       r = value_range (type, lhs.lower_bound (), wi::max_value (prec, sign));
3328       return true;
3329     }
3330   // (a % b) <= x && x < 0 , then a <= x.
3331   if (wi::lt_p (lhs.upper_bound (), 0, sign))
3332     {
3333       r = value_range (type, wi::min_value (prec, sign), lhs.upper_bound ());
3334       return true;
3335     }
3336   return false;
3337 }
3338 
3339 bool
op2_range(irange & r,tree type,const irange & lhs,const irange &,relation_kind rel ATTRIBUTE_UNUSED) const3340 operator_trunc_mod::op2_range (irange &r, tree type,
3341 			       const irange &lhs,
3342 			       const irange &,
3343 			       relation_kind rel ATTRIBUTE_UNUSED) const
3344 {
3345   // PR 91029.
3346   signop sign = TYPE_SIGN (type);
3347   unsigned prec = TYPE_PRECISION (type);
3348   // (a % b) >= x && x > 0 , then b is in ~[-x, x] for signed
3349   //			       or b > x for unsigned.
3350   if (wi::gt_p (lhs.lower_bound (), 0, sign))
3351     {
3352       if (sign == SIGNED)
3353 	r = value_range (type, wi::neg (lhs.lower_bound ()),
3354 			 lhs.lower_bound (), VR_ANTI_RANGE);
3355       else if (wi::lt_p (lhs.lower_bound (), wi::max_value (prec, sign),
3356 			 sign))
3357 	r = value_range (type, lhs.lower_bound () + 1,
3358 			 wi::max_value (prec, sign));
3359       else
3360 	return false;
3361       return true;
3362     }
3363   // (a % b) <= x && x < 0 , then b is in ~[x, -x].
3364   if (wi::lt_p (lhs.upper_bound (), 0, sign))
3365     {
3366       if (wi::gt_p (lhs.upper_bound (), wi::min_value (prec, sign), sign))
3367 	r = value_range (type, lhs.upper_bound (),
3368 			 wi::neg (lhs.upper_bound ()), VR_ANTI_RANGE);
3369       else
3370 	return false;
3371       return true;
3372     }
3373   return false;
3374 }
3375 
3376 
3377 class operator_logical_not : public range_operator
3378 {
3379 public:
3380   virtual bool fold_range (irange &r, tree type,
3381 			   const irange &lh,
3382 			   const irange &rh,
3383 			   relation_kind rel = VREL_NONE) const;
3384   virtual bool op1_range (irange &r, tree type,
3385 			  const irange &lhs,
3386 			  const irange &op2,
3387 			  relation_kind rel = VREL_NONE) const;
3388 } op_logical_not;
3389 
3390 // Folding a logical NOT, oddly enough, involves doing nothing on the
3391 // forward pass through.  During the initial walk backwards, the
3392 // logical NOT reversed the desired outcome on the way back, so on the
3393 // way forward all we do is pass the range forward.
3394 //
3395 // 	b_2 = x_1 < 20
3396 // 	b_3 = !b_2
3397 // 	if (b_3)
3398 //  to determine the TRUE branch, walking  backward
3399 //       if (b_3)		if ([1,1])
3400 //       b_3 = !b_2		[1,1] = ![0,0]
3401 // 	 b_2 = x_1 < 20		[0,0] = x_1 < 20,   false, so x_1 == [20, 255]
3402 //   which is the result we are looking for.. so.. pass it through.
3403 
3404 bool
fold_range(irange & r,tree type,const irange & lh,const irange & rh ATTRIBUTE_UNUSED,relation_kind rel ATTRIBUTE_UNUSED) const3405 operator_logical_not::fold_range (irange &r, tree type,
3406 				  const irange &lh,
3407 				  const irange &rh ATTRIBUTE_UNUSED,
3408 				  relation_kind rel ATTRIBUTE_UNUSED) const
3409 {
3410   if (empty_range_varying (r, type, lh, rh))
3411     return true;
3412 
3413   r = lh;
3414   if (!lh.varying_p () && !lh.undefined_p ())
3415     r.invert ();
3416 
3417   return true;
3418 }
3419 
3420 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const3421 operator_logical_not::op1_range (irange &r,
3422 				 tree type,
3423 				 const irange &lhs,
3424 				 const irange &op2,
3425 				 relation_kind rel ATTRIBUTE_UNUSED) const
3426 {
3427   // Logical NOT is involutary...do it again.
3428   return fold_range (r, type, lhs, op2);
3429 }
3430 
3431 
3432 class operator_bitwise_not : public range_operator
3433 {
3434 public:
3435   virtual bool fold_range (irange &r, tree type,
3436 			   const irange &lh,
3437 			   const irange &rh,
3438 			   relation_kind rel = VREL_NONE) const;
3439   virtual bool op1_range (irange &r, tree type,
3440 			  const irange &lhs,
3441 			  const irange &op2,
3442 			  relation_kind rel = VREL_NONE) const;
3443 } op_bitwise_not;
3444 
3445 bool
fold_range(irange & r,tree type,const irange & lh,const irange & rh,relation_kind rel ATTRIBUTE_UNUSED) const3446 operator_bitwise_not::fold_range (irange &r, tree type,
3447 				  const irange &lh,
3448 				  const irange &rh,
3449 				  relation_kind rel ATTRIBUTE_UNUSED) const
3450 {
3451   if (empty_range_varying (r, type, lh, rh))
3452     return true;
3453 
3454   if (types_compatible_p (type, boolean_type_node))
3455     return op_logical_not.fold_range (r, type, lh, rh);
3456 
3457   // ~X is simply -1 - X.
3458   int_range<1> minusone (type, wi::minus_one (TYPE_PRECISION (type)),
3459 			 wi::minus_one (TYPE_PRECISION (type)));
3460   return range_op_handler (MINUS_EXPR, type)->fold_range (r, type, minusone,
3461 							  lh);
3462 }
3463 
3464 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const3465 operator_bitwise_not::op1_range (irange &r, tree type,
3466 				 const irange &lhs,
3467 				 const irange &op2,
3468 				 relation_kind rel ATTRIBUTE_UNUSED) const
3469 {
3470   if (types_compatible_p (type, boolean_type_node))
3471     return op_logical_not.op1_range (r, type, lhs, op2);
3472 
3473   // ~X is -1 - X and since bitwise NOT is involutary...do it again.
3474   return fold_range (r, type, lhs, op2);
3475 }
3476 
3477 
3478 class operator_cst : public range_operator
3479 {
3480 public:
3481   virtual bool fold_range (irange &r, tree type,
3482 			   const irange &op1,
3483 			   const irange &op2,
3484 			   relation_kind rel = VREL_NONE) const;
3485 } op_integer_cst;
3486 
3487 bool
fold_range(irange & r,tree type ATTRIBUTE_UNUSED,const irange & lh,const irange & rh ATTRIBUTE_UNUSED,relation_kind rel ATTRIBUTE_UNUSED) const3488 operator_cst::fold_range (irange &r, tree type ATTRIBUTE_UNUSED,
3489 			  const irange &lh,
3490 			  const irange &rh ATTRIBUTE_UNUSED,
3491 			  relation_kind rel ATTRIBUTE_UNUSED) const
3492 {
3493   r = lh;
3494   return true;
3495 }
3496 
3497 
3498 class operator_identity : public range_operator
3499 {
3500 public:
3501   virtual bool fold_range (irange &r, tree type,
3502 			   const irange &op1,
3503 			   const irange &op2,
3504 			   relation_kind rel = VREL_NONE) const;
3505   virtual bool op1_range (irange &r, tree type,
3506 			  const irange &lhs,
3507 			  const irange &op2,
3508 			  relation_kind rel = VREL_NONE) const;
3509   virtual enum tree_code lhs_op1_relation (const irange &lhs,
3510 					   const irange &op1,
3511 					   const irange &op2) const;
3512 } op_identity;
3513 
3514 // Determine if there is a relationship between LHS and OP1.
3515 
3516 enum tree_code
lhs_op1_relation(const irange & lhs,const irange & op1 ATTRIBUTE_UNUSED,const irange & op2 ATTRIBUTE_UNUSED) const3517 operator_identity::lhs_op1_relation (const irange &lhs,
3518 				     const irange &op1 ATTRIBUTE_UNUSED,
3519 				     const irange &op2 ATTRIBUTE_UNUSED) const
3520 {
3521   if (lhs.undefined_p ())
3522     return VREL_NONE;
3523   // Simply a copy, so they are equivalent.
3524   return EQ_EXPR;
3525 }
3526 
3527 bool
fold_range(irange & r,tree type ATTRIBUTE_UNUSED,const irange & lh,const irange & rh ATTRIBUTE_UNUSED,relation_kind rel ATTRIBUTE_UNUSED) const3528 operator_identity::fold_range (irange &r, tree type ATTRIBUTE_UNUSED,
3529 			       const irange &lh,
3530 			       const irange &rh ATTRIBUTE_UNUSED,
3531 			       relation_kind rel ATTRIBUTE_UNUSED) const
3532 {
3533   r = lh;
3534   return true;
3535 }
3536 
3537 bool
op1_range(irange & r,tree type ATTRIBUTE_UNUSED,const irange & lhs,const irange & op2 ATTRIBUTE_UNUSED,relation_kind rel ATTRIBUTE_UNUSED) const3538 operator_identity::op1_range (irange &r, tree type ATTRIBUTE_UNUSED,
3539 			      const irange &lhs,
3540 			      const irange &op2 ATTRIBUTE_UNUSED,
3541 			      relation_kind rel ATTRIBUTE_UNUSED) const
3542 {
3543   r = lhs;
3544   return true;
3545 }
3546 
3547 
3548 class operator_unknown : public range_operator
3549 {
3550 public:
3551   virtual bool fold_range (irange &r, tree type,
3552 			   const irange &op1,
3553 			   const irange &op2,
3554 			   relation_kind rel = VREL_NONE) const;
3555 } op_unknown;
3556 
3557 bool
fold_range(irange & r,tree type,const irange & lh ATTRIBUTE_UNUSED,const irange & rh ATTRIBUTE_UNUSED,relation_kind rel ATTRIBUTE_UNUSED) const3558 operator_unknown::fold_range (irange &r, tree type,
3559 			      const irange &lh ATTRIBUTE_UNUSED,
3560 			      const irange &rh ATTRIBUTE_UNUSED,
3561 			      relation_kind rel ATTRIBUTE_UNUSED) const
3562 {
3563   r.set_varying (type);
3564   return true;
3565 }
3566 
3567 
3568 class operator_abs : public range_operator
3569 {
3570  public:
3571   virtual void wi_fold (irange &r, tree type,
3572 		        const wide_int &lh_lb,
3573 		        const wide_int &lh_ub,
3574 		        const wide_int &rh_lb,
3575 		        const wide_int &rh_ub) const;
3576   virtual bool op1_range (irange &r, tree type,
3577 			  const irange &lhs,
3578 			  const irange &op2,
3579 			  relation_kind rel ATTRIBUTE_UNUSED) const;
3580 } op_abs;
3581 
3582 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) const3583 operator_abs::wi_fold (irange &r, tree type,
3584 		       const wide_int &lh_lb, const wide_int &lh_ub,
3585 		       const wide_int &rh_lb ATTRIBUTE_UNUSED,
3586 		       const wide_int &rh_ub ATTRIBUTE_UNUSED) const
3587 {
3588   wide_int min, max;
3589   signop sign = TYPE_SIGN (type);
3590   unsigned prec = TYPE_PRECISION (type);
3591 
3592   // Pass through LH for the easy cases.
3593   if (sign == UNSIGNED || wi::ge_p (lh_lb, 0, sign))
3594     {
3595       r = int_range<1> (type, lh_lb, lh_ub);
3596       return;
3597     }
3598 
3599   // -TYPE_MIN_VALUE = TYPE_MIN_VALUE with flag_wrapv so we can't get
3600   // a useful range.
3601   wide_int min_value = wi::min_value (prec, sign);
3602   wide_int max_value = wi::max_value (prec, sign);
3603   if (!TYPE_OVERFLOW_UNDEFINED (type) && wi::eq_p (lh_lb, min_value))
3604     {
3605       r.set_varying (type);
3606       return;
3607     }
3608 
3609   // ABS_EXPR may flip the range around, if the original range
3610   // included negative values.
3611   if (wi::eq_p (lh_lb, min_value))
3612     {
3613       // ABS ([-MIN, -MIN]) isn't representable, but we have traditionally
3614       // returned [-MIN,-MIN] so this preserves that behaviour.  PR37078
3615       if (wi::eq_p (lh_ub, min_value))
3616 	{
3617 	  r = int_range<1> (type, min_value, min_value);
3618 	  return;
3619 	}
3620       min = max_value;
3621     }
3622   else
3623     min = wi::abs (lh_lb);
3624 
3625   if (wi::eq_p (lh_ub, min_value))
3626     max = max_value;
3627   else
3628     max = wi::abs (lh_ub);
3629 
3630   // If the range contains zero then we know that the minimum value in the
3631   // range will be zero.
3632   if (wi::le_p (lh_lb, 0, sign) && wi::ge_p (lh_ub, 0, sign))
3633     {
3634       if (wi::gt_p (min, max, sign))
3635 	max = min;
3636       min = wi::zero (prec);
3637     }
3638   else
3639     {
3640       // If the range was reversed, swap MIN and MAX.
3641       if (wi::gt_p (min, max, sign))
3642 	std::swap (min, max);
3643     }
3644 
3645   // If the new range has its limits swapped around (MIN > MAX), then
3646   // the operation caused one of them to wrap around.  The only thing
3647   // we know is that the result is positive.
3648   if (wi::gt_p (min, max, sign))
3649     {
3650       min = wi::zero (prec);
3651       max = max_value;
3652     }
3653   r = int_range<1> (type, min, max);
3654 }
3655 
3656 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const3657 operator_abs::op1_range (irange &r, tree type,
3658 			 const irange &lhs,
3659 			 const irange &op2,
3660 			 relation_kind rel ATTRIBUTE_UNUSED) const
3661 {
3662   if (empty_range_varying (r, type, lhs, op2))
3663     return true;
3664   if (TYPE_UNSIGNED (type))
3665     {
3666       r = lhs;
3667       return true;
3668     }
3669   // Start with the positives because negatives are an impossible result.
3670   int_range_max positives = range_positives (type);
3671   positives.intersect (lhs);
3672   r = positives;
3673   // Then add the negative of each pair:
3674   // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
3675   for (unsigned i = 0; i < positives.num_pairs (); ++i)
3676     r.union_ (int_range<1> (type,
3677 			    -positives.upper_bound (i),
3678 			    -positives.lower_bound (i)));
3679   // With flag_wrapv, -TYPE_MIN_VALUE = TYPE_MIN_VALUE which is
3680   // unrepresentable.  Add -TYPE_MIN_VALUE in this case.
3681   wide_int min_value = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
3682   wide_int lb = lhs.lower_bound ();
3683   if (!TYPE_OVERFLOW_UNDEFINED (type) && wi::eq_p (lb, min_value))
3684     r.union_ (int_range<2> (type, lb, lb));
3685   return true;
3686 }
3687 
3688 
3689 class operator_absu : public range_operator
3690 {
3691  public:
3692   virtual void wi_fold (irange &r, tree type,
3693 			const wide_int &lh_lb, const wide_int &lh_ub,
3694 			const wide_int &rh_lb, const wide_int &rh_ub) const;
3695 } op_absu;
3696 
3697 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) const3698 operator_absu::wi_fold (irange &r, tree type,
3699 			const wide_int &lh_lb, const wide_int &lh_ub,
3700 			const wide_int &rh_lb ATTRIBUTE_UNUSED,
3701 			const wide_int &rh_ub ATTRIBUTE_UNUSED) const
3702 {
3703   wide_int new_lb, new_ub;
3704 
3705   // Pass through VR0 the easy cases.
3706   if (wi::ges_p (lh_lb, 0))
3707     {
3708       new_lb = lh_lb;
3709       new_ub = lh_ub;
3710     }
3711   else
3712     {
3713       new_lb = wi::abs (lh_lb);
3714       new_ub = wi::abs (lh_ub);
3715 
3716       // If the range contains zero then we know that the minimum
3717       // value in the range will be zero.
3718       if (wi::ges_p (lh_ub, 0))
3719 	{
3720 	  if (wi::gtu_p (new_lb, new_ub))
3721 	    new_ub = new_lb;
3722 	  new_lb = wi::zero (TYPE_PRECISION (type));
3723 	}
3724       else
3725 	std::swap (new_lb, new_ub);
3726     }
3727 
3728   gcc_checking_assert (TYPE_UNSIGNED (type));
3729   r = int_range<1> (type, new_lb, new_ub);
3730 }
3731 
3732 
3733 class operator_negate : public range_operator
3734 {
3735  public:
3736   virtual bool fold_range (irange &r, tree type,
3737 			   const irange &op1,
3738 			   const irange &op2,
3739 			   relation_kind rel = VREL_NONE) const;
3740   virtual bool op1_range (irange &r, tree type,
3741 			  const irange &lhs,
3742 			  const irange &op2,
3743 			  relation_kind rel = VREL_NONE) const;
3744 } op_negate;
3745 
3746 bool
fold_range(irange & r,tree type,const irange & lh,const irange & rh,relation_kind rel ATTRIBUTE_UNUSED) const3747 operator_negate::fold_range (irange &r, tree type,
3748 			     const irange &lh,
3749 			     const irange &rh,
3750 			     relation_kind rel ATTRIBUTE_UNUSED) const
3751 {
3752   if (empty_range_varying (r, type, lh, rh))
3753     return true;
3754   // -X is simply 0 - X.
3755   return range_op_handler (MINUS_EXPR, type)->fold_range (r, type,
3756 							  range_zero (type),
3757 							  lh);
3758 }
3759 
3760 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const3761 operator_negate::op1_range (irange &r, tree type,
3762 			    const irange &lhs,
3763 			    const irange &op2,
3764 			    relation_kind rel ATTRIBUTE_UNUSED) const
3765 {
3766   // NEGATE is involutory.
3767   return fold_range (r, type, lhs, op2);
3768 }
3769 
3770 
3771 class operator_addr_expr : public range_operator
3772 {
3773 public:
3774   virtual bool fold_range (irange &r, tree type,
3775 			   const irange &op1,
3776 			   const irange &op2,
3777 			   relation_kind rel = VREL_NONE) const;
3778   virtual bool op1_range (irange &r, tree type,
3779 			  const irange &lhs,
3780 			  const irange &op2,
3781 			  relation_kind rel = VREL_NONE) const;
3782 } op_addr;
3783 
3784 bool
fold_range(irange & r,tree type,const irange & lh,const irange & rh,relation_kind rel ATTRIBUTE_UNUSED) const3785 operator_addr_expr::fold_range (irange &r, tree type,
3786 				const irange &lh,
3787 				const irange &rh,
3788 				relation_kind rel ATTRIBUTE_UNUSED) const
3789 {
3790   if (empty_range_varying (r, type, lh, rh))
3791     return true;
3792 
3793   // Return a non-null pointer of the LHS type (passed in op2).
3794   if (lh.zero_p ())
3795     r = range_zero (type);
3796   else if (!lh.contains_p (build_zero_cst (lh.type ())))
3797     r = range_nonzero (type);
3798   else
3799     r.set_varying (type);
3800   return true;
3801 }
3802 
3803 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2,relation_kind rel ATTRIBUTE_UNUSED) const3804 operator_addr_expr::op1_range (irange &r, tree type,
3805 			       const irange &lhs,
3806 			       const irange &op2,
3807 			       relation_kind rel ATTRIBUTE_UNUSED) const
3808 {
3809   return operator_addr_expr::fold_range (r, type, lhs, op2);
3810 }
3811 
3812 
3813 class pointer_plus_operator : public range_operator
3814 {
3815 public:
3816   virtual void wi_fold (irange &r, tree type,
3817 		        const wide_int &lh_lb,
3818 		        const wide_int &lh_ub,
3819 		        const wide_int &rh_lb,
3820 		        const wide_int &rh_ub) const;
3821 } op_pointer_plus;
3822 
3823 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) const3824 pointer_plus_operator::wi_fold (irange &r, tree type,
3825 				const wide_int &lh_lb,
3826 				const wide_int &lh_ub,
3827 				const wide_int &rh_lb,
3828 				const wide_int &rh_ub) const
3829 {
3830   // Check for [0,0] + const, and simply return the const.
3831   if (lh_lb == 0 && lh_ub == 0 && rh_lb == rh_ub)
3832     {
3833       tree val = wide_int_to_tree (type, rh_lb);
3834       r.set (val, val);
3835       return;
3836     }
3837 
3838   // For pointer types, we are really only interested in asserting
3839   // whether the expression evaluates to non-NULL.
3840   //
3841   // With -fno-delete-null-pointer-checks we need to be more
3842   // conservative.  As some object might reside at address 0,
3843   // then some offset could be added to it and the same offset
3844   // subtracted again and the result would be NULL.
3845   // E.g.
3846   // static int a[12]; where &a[0] is NULL and
3847   // ptr = &a[6];
3848   // ptr -= 6;
3849   // ptr will be NULL here, even when there is POINTER_PLUS_EXPR
3850   // where the first range doesn't include zero and the second one
3851   // doesn't either.  As the second operand is sizetype (unsigned),
3852   // consider all ranges where the MSB could be set as possible
3853   // subtractions where the result might be NULL.
3854   if ((!wi_includes_zero_p (type, lh_lb, lh_ub)
3855        || !wi_includes_zero_p (type, rh_lb, rh_ub))
3856       && !TYPE_OVERFLOW_WRAPS (type)
3857       && (flag_delete_null_pointer_checks
3858 	  || !wi::sign_mask (rh_ub)))
3859     r = range_nonzero (type);
3860   else if (lh_lb == lh_ub && lh_lb == 0
3861 	   && rh_lb == rh_ub && rh_lb == 0)
3862     r = range_zero (type);
3863   else
3864    r.set_varying (type);
3865 }
3866 
3867 
3868 class pointer_min_max_operator : public range_operator
3869 {
3870 public:
3871   virtual void wi_fold (irange & r, tree type,
3872 			const wide_int &lh_lb, const wide_int &lh_ub,
3873 			const wide_int &rh_lb, const wide_int &rh_ub) const;
3874 } op_ptr_min_max;
3875 
3876 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) const3877 pointer_min_max_operator::wi_fold (irange &r, tree type,
3878 				   const wide_int &lh_lb,
3879 				   const wide_int &lh_ub,
3880 				   const wide_int &rh_lb,
3881 				   const wide_int &rh_ub) const
3882 {
3883   // For MIN/MAX expressions with pointers, we only care about
3884   // nullness.  If both are non null, then the result is nonnull.
3885   // If both are null, then the result is null.  Otherwise they
3886   // are varying.
3887   if (!wi_includes_zero_p (type, lh_lb, lh_ub)
3888       && !wi_includes_zero_p (type, rh_lb, rh_ub))
3889     r = range_nonzero (type);
3890   else if (wi_zero_p (type, lh_lb, lh_ub) && wi_zero_p (type, rh_lb, rh_ub))
3891     r = range_zero (type);
3892   else
3893     r.set_varying (type);
3894 }
3895 
3896 
3897 class pointer_and_operator : public range_operator
3898 {
3899 public:
3900   virtual void wi_fold (irange &r, tree type,
3901 			const wide_int &lh_lb, const wide_int &lh_ub,
3902 			const wide_int &rh_lb, const wide_int &rh_ub) const;
3903 } op_pointer_and;
3904 
3905 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) const3906 pointer_and_operator::wi_fold (irange &r, tree type,
3907 			       const wide_int &lh_lb,
3908 			       const wide_int &lh_ub,
3909 			       const wide_int &rh_lb ATTRIBUTE_UNUSED,
3910 			       const wide_int &rh_ub ATTRIBUTE_UNUSED) const
3911 {
3912   // For pointer types, we are really only interested in asserting
3913   // whether the expression evaluates to non-NULL.
3914   if (wi_zero_p (type, lh_lb, lh_ub) || wi_zero_p (type, lh_lb, lh_ub))
3915     r = range_zero (type);
3916   else
3917     r.set_varying (type);
3918 }
3919 
3920 
3921 class pointer_or_operator : public range_operator
3922 {
3923 public:
3924   virtual bool op1_range (irange &r, tree type,
3925 			  const irange &lhs,
3926 			  const irange &op2,
3927 			  relation_kind rel = VREL_NONE) const;
3928   virtual bool op2_range (irange &r, tree type,
3929 			  const irange &lhs,
3930 			  const irange &op1,
3931 			  relation_kind rel = VREL_NONE) const;
3932   virtual void wi_fold (irange &r, tree type,
3933 			const wide_int &lh_lb, const wide_int &lh_ub,
3934 			const wide_int &rh_lb, const wide_int &rh_ub) const;
3935 } op_pointer_or;
3936 
3937 bool
op1_range(irange & r,tree type,const irange & lhs,const irange & op2 ATTRIBUTE_UNUSED,relation_kind rel ATTRIBUTE_UNUSED) const3938 pointer_or_operator::op1_range (irange &r, tree type,
3939 				const irange &lhs,
3940 				const irange &op2 ATTRIBUTE_UNUSED,
3941 				relation_kind rel ATTRIBUTE_UNUSED) const
3942 {
3943   if (lhs.zero_p ())
3944     {
3945       tree zero = build_zero_cst (type);
3946       r = int_range<1> (zero, zero);
3947       return true;
3948     }
3949   r.set_varying (type);
3950   return true;
3951 }
3952 
3953 bool
op2_range(irange & r,tree type,const irange & lhs,const irange & op1,relation_kind rel ATTRIBUTE_UNUSED) const3954 pointer_or_operator::op2_range (irange &r, tree type,
3955 				const irange &lhs,
3956 				const irange &op1,
3957 				relation_kind rel ATTRIBUTE_UNUSED) const
3958 {
3959   return pointer_or_operator::op1_range (r, type, lhs, op1);
3960 }
3961 
3962 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) const3963 pointer_or_operator::wi_fold (irange &r, tree type,
3964 			      const wide_int &lh_lb,
3965 			      const wide_int &lh_ub,
3966 			      const wide_int &rh_lb,
3967 			      const wide_int &rh_ub) const
3968 {
3969   // For pointer types, we are really only interested in asserting
3970   // whether the expression evaluates to non-NULL.
3971   if (!wi_includes_zero_p (type, lh_lb, lh_ub)
3972       && !wi_includes_zero_p (type, rh_lb, rh_ub))
3973     r = range_nonzero (type);
3974   else if (wi_zero_p (type, lh_lb, lh_ub) && wi_zero_p (type, rh_lb, rh_ub))
3975     r = range_zero (type);
3976   else
3977     r.set_varying (type);
3978 }
3979 
3980 // This implements the range operator tables as local objects in this file.
3981 
3982 class range_op_table
3983 {
3984 public:
3985   inline range_operator *operator[] (enum tree_code code);
3986 protected:
3987   void set (enum tree_code code, range_operator &op);
3988 private:
3989   range_operator *m_range_tree[MAX_TREE_CODES];
3990 };
3991 
3992 // Return a pointer to the range_operator instance, if there is one
3993 // associated with tree_code CODE.
3994 
3995 range_operator *
operator [](enum tree_code code)3996 range_op_table::operator[] (enum tree_code code)
3997 {
3998   gcc_checking_assert (code > 0 && code < MAX_TREE_CODES);
3999   return m_range_tree[code];
4000 }
4001 
4002 // Add OP to the handler table for CODE.
4003 
4004 void
set(enum tree_code code,range_operator & op)4005 range_op_table::set (enum tree_code code, range_operator &op)
4006 {
4007   gcc_checking_assert (m_range_tree[code] == NULL);
4008   m_range_tree[code] = &op;
4009 }
4010 
4011 // Instantiate a range op table for integral operations.
4012 
4013 class integral_table : public range_op_table
4014 {
4015 public:
4016   integral_table ();
4017 } integral_tree_table;
4018 
integral_table()4019 integral_table::integral_table ()
4020 {
4021   set (EQ_EXPR, op_equal);
4022   set (NE_EXPR, op_not_equal);
4023   set (LT_EXPR, op_lt);
4024   set (LE_EXPR, op_le);
4025   set (GT_EXPR, op_gt);
4026   set (GE_EXPR, op_ge);
4027   set (PLUS_EXPR, op_plus);
4028   set (MINUS_EXPR, op_minus);
4029   set (MIN_EXPR, op_min);
4030   set (MAX_EXPR, op_max);
4031   set (MULT_EXPR, op_mult);
4032   set (TRUNC_DIV_EXPR, op_trunc_div);
4033   set (FLOOR_DIV_EXPR, op_floor_div);
4034   set (ROUND_DIV_EXPR, op_round_div);
4035   set (CEIL_DIV_EXPR, op_ceil_div);
4036   set (EXACT_DIV_EXPR, op_exact_div);
4037   set (LSHIFT_EXPR, op_lshift);
4038   set (RSHIFT_EXPR, op_rshift);
4039   set (NOP_EXPR, op_convert);
4040   set (CONVERT_EXPR, op_convert);
4041   set (TRUTH_AND_EXPR, op_logical_and);
4042   set (BIT_AND_EXPR, op_bitwise_and);
4043   set (TRUTH_OR_EXPR, op_logical_or);
4044   set (BIT_IOR_EXPR, op_bitwise_or);
4045   set (BIT_XOR_EXPR, op_bitwise_xor);
4046   set (TRUNC_MOD_EXPR, op_trunc_mod);
4047   set (TRUTH_NOT_EXPR, op_logical_not);
4048   set (BIT_NOT_EXPR, op_bitwise_not);
4049   set (INTEGER_CST, op_integer_cst);
4050   set (SSA_NAME, op_identity);
4051   set (PAREN_EXPR, op_identity);
4052   set (OBJ_TYPE_REF, op_identity);
4053   set (IMAGPART_EXPR, op_unknown);
4054   set (REALPART_EXPR, op_unknown);
4055   set (POINTER_DIFF_EXPR, op_pointer_diff);
4056   set (ABS_EXPR, op_abs);
4057   set (ABSU_EXPR, op_absu);
4058   set (NEGATE_EXPR, op_negate);
4059   set (ADDR_EXPR, op_addr);
4060 }
4061 
4062 // Instantiate a range op table for pointer operations.
4063 
4064 class pointer_table : public range_op_table
4065 {
4066 public:
4067   pointer_table ();
4068 } pointer_tree_table;
4069 
pointer_table()4070 pointer_table::pointer_table ()
4071 {
4072   set (BIT_AND_EXPR, op_pointer_and);
4073   set (BIT_IOR_EXPR, op_pointer_or);
4074   set (MIN_EXPR, op_ptr_min_max);
4075   set (MAX_EXPR, op_ptr_min_max);
4076   set (POINTER_PLUS_EXPR, op_pointer_plus);
4077 
4078   set (EQ_EXPR, op_equal);
4079   set (NE_EXPR, op_not_equal);
4080   set (LT_EXPR, op_lt);
4081   set (LE_EXPR, op_le);
4082   set (GT_EXPR, op_gt);
4083   set (GE_EXPR, op_ge);
4084   set (SSA_NAME, op_identity);
4085   set (INTEGER_CST, op_integer_cst);
4086   set (ADDR_EXPR, op_addr);
4087   set (NOP_EXPR, op_convert);
4088   set (CONVERT_EXPR, op_convert);
4089 
4090   set (BIT_NOT_EXPR, op_bitwise_not);
4091   set (BIT_XOR_EXPR, op_bitwise_xor);
4092 }
4093 
4094 // The tables are hidden and accessed via a simple extern function.
4095 
4096 range_operator *
range_op_handler(enum tree_code code,tree type)4097 range_op_handler (enum tree_code code, tree type)
4098 {
4099   // First check if there is a pointer specialization.
4100   if (POINTER_TYPE_P (type))
4101     return pointer_tree_table[code];
4102   if (INTEGRAL_TYPE_P (type))
4103     return integral_tree_table[code];
4104   return NULL;
4105 }
4106 
4107 // Cast the range in R to TYPE.
4108 
4109 void
range_cast(irange & r,tree type)4110 range_cast (irange &r, tree type)
4111 {
4112   int_range_max tmp = r;
4113   range_operator *op = range_op_handler (CONVERT_EXPR, type);
4114   // Call op_convert, if it fails, the result is varying.
4115   if (!op->fold_range (r, type, tmp, int_range<1> (type)))
4116     r.set_varying (type);
4117 }
4118 
4119 #if CHECKING_P
4120 #include "selftest.h"
4121 
4122 namespace selftest
4123 {
4124 #define INT(N) build_int_cst (integer_type_node, (N))
4125 #define UINT(N) build_int_cstu (unsigned_type_node, (N))
4126 #define INT16(N) build_int_cst (short_integer_type_node, (N))
4127 #define UINT16(N) build_int_cstu (short_unsigned_type_node, (N))
4128 #define SCHAR(N) build_int_cst (signed_char_type_node, (N))
4129 #define UCHAR(N) build_int_cstu (unsigned_char_type_node, (N))
4130 
4131 static void
range_op_cast_tests()4132 range_op_cast_tests ()
4133 {
4134   int_range<1> r0, r1, r2, rold;
4135   r0.set_varying (integer_type_node);
4136   tree maxint = wide_int_to_tree (integer_type_node, r0.upper_bound ());
4137 
4138   // If a range is in any way outside of the range for the converted
4139   // to range, default to the range for the new type.
4140   r0.set_varying (short_integer_type_node);
4141   tree minshort = wide_int_to_tree (short_integer_type_node, r0.lower_bound ());
4142   tree maxshort = wide_int_to_tree (short_integer_type_node, r0.upper_bound ());
4143   if (TYPE_PRECISION (TREE_TYPE (maxint))
4144       > TYPE_PRECISION (short_integer_type_node))
4145     {
4146       r1 = int_range<1> (integer_zero_node, maxint);
4147       range_cast (r1, short_integer_type_node);
4148       ASSERT_TRUE (r1.lower_bound () == wi::to_wide (minshort)
4149 		   && r1.upper_bound() == wi::to_wide (maxshort));
4150     }
4151 
4152   // (unsigned char)[-5,-1] => [251,255].
4153   r0 = rold = int_range<1> (SCHAR (-5), SCHAR (-1));
4154   range_cast (r0, unsigned_char_type_node);
4155   ASSERT_TRUE (r0 == int_range<1> (UCHAR (251), UCHAR (255)));
4156   range_cast (r0, signed_char_type_node);
4157   ASSERT_TRUE (r0 == rold);
4158 
4159   // (signed char)[15, 150] => [-128,-106][15,127].
4160   r0 = rold = int_range<1> (UCHAR (15), UCHAR (150));
4161   range_cast (r0, signed_char_type_node);
4162   r1 = int_range<1> (SCHAR (15), SCHAR (127));
4163   r2 = int_range<1> (SCHAR (-128), SCHAR (-106));
4164   r1.union_ (r2);
4165   ASSERT_TRUE (r1 == r0);
4166   range_cast (r0, unsigned_char_type_node);
4167   ASSERT_TRUE (r0 == rold);
4168 
4169   // (unsigned char)[-5, 5] => [0,5][251,255].
4170   r0 = rold = int_range<1> (SCHAR (-5), SCHAR (5));
4171   range_cast (r0, unsigned_char_type_node);
4172   r1 = int_range<1> (UCHAR (251), UCHAR (255));
4173   r2 = int_range<1> (UCHAR (0), UCHAR (5));
4174   r1.union_ (r2);
4175   ASSERT_TRUE (r0 == r1);
4176   range_cast (r0, signed_char_type_node);
4177   ASSERT_TRUE (r0 == rold);
4178 
4179   // (unsigned char)[-5,5] => [0,5][251,255].
4180   r0 = int_range<1> (INT (-5), INT (5));
4181   range_cast (r0, unsigned_char_type_node);
4182   r1 = int_range<1> (UCHAR (0), UCHAR (5));
4183   r1.union_ (int_range<1> (UCHAR (251), UCHAR (255)));
4184   ASSERT_TRUE (r0 == r1);
4185 
4186   // (unsigned char)[5U,1974U] => [0,255].
4187   r0 = int_range<1> (UINT (5), UINT (1974));
4188   range_cast (r0, unsigned_char_type_node);
4189   ASSERT_TRUE (r0 == int_range<1> (UCHAR (0), UCHAR (255)));
4190   range_cast (r0, integer_type_node);
4191   // Going to a wider range should not sign extend.
4192   ASSERT_TRUE (r0 == int_range<1> (INT (0), INT (255)));
4193 
4194   // (unsigned char)[-350,15] => [0,255].
4195   r0 = int_range<1> (INT (-350), INT (15));
4196   range_cast (r0, unsigned_char_type_node);
4197   ASSERT_TRUE (r0 == (int_range<1>
4198 		      (TYPE_MIN_VALUE (unsigned_char_type_node),
4199 		       TYPE_MAX_VALUE (unsigned_char_type_node))));
4200 
4201   // Casting [-120,20] from signed char to unsigned short.
4202   // => [0, 20][0xff88, 0xffff].
4203   r0 = int_range<1> (SCHAR (-120), SCHAR (20));
4204   range_cast (r0, short_unsigned_type_node);
4205   r1 = int_range<1> (UINT16 (0), UINT16 (20));
4206   r2 = int_range<1> (UINT16 (0xff88), UINT16 (0xffff));
4207   r1.union_ (r2);
4208   ASSERT_TRUE (r0 == r1);
4209   // A truncating cast back to signed char will work because [-120, 20]
4210   // is representable in signed char.
4211   range_cast (r0, signed_char_type_node);
4212   ASSERT_TRUE (r0 == int_range<1> (SCHAR (-120), SCHAR (20)));
4213 
4214   // unsigned char -> signed short
4215   //	(signed short)[(unsigned char)25, (unsigned char)250]
4216   // => [(signed short)25, (signed short)250]
4217   r0 = rold = int_range<1> (UCHAR (25), UCHAR (250));
4218   range_cast (r0, short_integer_type_node);
4219   r1 = int_range<1> (INT16 (25), INT16 (250));
4220   ASSERT_TRUE (r0 == r1);
4221   range_cast (r0, unsigned_char_type_node);
4222   ASSERT_TRUE (r0 == rold);
4223 
4224   // Test casting a wider signed [-MIN,MAX] to a nar`rower unsigned.
4225   r0 = int_range<1> (TYPE_MIN_VALUE (long_long_integer_type_node),
4226 	       TYPE_MAX_VALUE (long_long_integer_type_node));
4227   range_cast (r0, short_unsigned_type_node);
4228   r1 = int_range<1> (TYPE_MIN_VALUE (short_unsigned_type_node),
4229 	       TYPE_MAX_VALUE (short_unsigned_type_node));
4230   ASSERT_TRUE (r0 == r1);
4231 
4232   // Casting NONZERO to a narrower type will wrap/overflow so
4233   // it's just the entire range for the narrower type.
4234   //
4235   // "NOT 0 at signed 32-bits" ==> [-MIN_32,-1][1, +MAX_32].  This is
4236   // is outside of the range of a smaller range, return the full
4237   // smaller range.
4238   if (TYPE_PRECISION (integer_type_node)
4239       > TYPE_PRECISION (short_integer_type_node))
4240     {
4241       r0 = range_nonzero (integer_type_node);
4242       range_cast (r0, short_integer_type_node);
4243       r1 = int_range<1> (TYPE_MIN_VALUE (short_integer_type_node),
4244 			 TYPE_MAX_VALUE (short_integer_type_node));
4245       ASSERT_TRUE (r0 == r1);
4246     }
4247 
4248   // Casting NONZERO from a narrower signed to a wider signed.
4249   //
4250   // NONZERO signed 16-bits is [-MIN_16,-1][1, +MAX_16].
4251   // Converting this to 32-bits signed is [-MIN_16,-1][1, +MAX_16].
4252   r0 = range_nonzero (short_integer_type_node);
4253   range_cast (r0, integer_type_node);
4254   r1 = int_range<1> (INT (-32768), INT (-1));
4255   r2 = int_range<1> (INT (1), INT (32767));
4256   r1.union_ (r2);
4257   ASSERT_TRUE (r0 == r1);
4258 }
4259 
4260 static void
range_op_lshift_tests()4261 range_op_lshift_tests ()
4262 {
4263   // Test that 0x808.... & 0x8.... still contains 0x8....
4264   // for a large set of numbers.
4265   {
4266     int_range_max res;
4267     tree big_type = long_long_unsigned_type_node;
4268     // big_num = 0x808,0000,0000,0000
4269     tree big_num = fold_build2 (LSHIFT_EXPR, big_type,
4270 				build_int_cst (big_type, 0x808),
4271 				build_int_cst (big_type, 48));
4272     op_bitwise_and.fold_range (res, big_type,
4273 			       int_range <1> (big_type),
4274 			       int_range <1> (big_num, big_num));
4275     // val = 0x8,0000,0000,0000
4276     tree val = fold_build2 (LSHIFT_EXPR, big_type,
4277 			    build_int_cst (big_type, 0x8),
4278 			    build_int_cst (big_type, 48));
4279     ASSERT_TRUE (res.contains_p (val));
4280   }
4281 
4282   if (TYPE_PRECISION (unsigned_type_node) > 31)
4283     {
4284       // unsigned VARYING = op1 << 1 should be VARYING.
4285       int_range<2> lhs (unsigned_type_node);
4286       int_range<2> shift (INT (1), INT (1));
4287       int_range_max op1;
4288       op_lshift.op1_range (op1, unsigned_type_node, lhs, shift);
4289       ASSERT_TRUE (op1.varying_p ());
4290 
4291       // 0 = op1 << 1  should be [0,0], [0x8000000, 0x8000000].
4292       int_range<2> zero (UINT (0), UINT (0));
4293       op_lshift.op1_range (op1, unsigned_type_node, zero, shift);
4294       ASSERT_TRUE (op1.num_pairs () == 2);
4295       // Remove the [0,0] range.
4296       op1.intersect (zero);
4297       ASSERT_TRUE (op1.num_pairs () == 1);
4298       //  op1 << 1   should be [0x8000,0x8000] << 1,
4299       //  which should result in [0,0].
4300       int_range_max result;
4301       op_lshift.fold_range (result, unsigned_type_node, op1, shift);
4302       ASSERT_TRUE (result == zero);
4303     }
4304   // signed VARYING = op1 << 1 should be VARYING.
4305   if (TYPE_PRECISION (integer_type_node) > 31)
4306     {
4307       // unsigned VARYING = op1 << 1  hould be VARYING.
4308       int_range<2> lhs (integer_type_node);
4309       int_range<2> shift (INT (1), INT (1));
4310       int_range_max op1;
4311       op_lshift.op1_range (op1, integer_type_node, lhs, shift);
4312       ASSERT_TRUE (op1.varying_p ());
4313 
4314       //  0 = op1 << 1  should be [0,0], [0x8000000, 0x8000000].
4315       int_range<2> zero (INT (0), INT (0));
4316       op_lshift.op1_range (op1, integer_type_node, zero, shift);
4317       ASSERT_TRUE (op1.num_pairs () == 2);
4318       // Remove the [0,0] range.
4319       op1.intersect (zero);
4320       ASSERT_TRUE (op1.num_pairs () == 1);
4321       //  op1 << 1   shuould be [0x8000,0x8000] << 1,
4322       //  which should result in [0,0].
4323       int_range_max result;
4324       op_lshift.fold_range (result, unsigned_type_node, op1, shift);
4325       ASSERT_TRUE (result == zero);
4326     }
4327 }
4328 
4329 static void
range_op_rshift_tests()4330 range_op_rshift_tests ()
4331 {
4332   // unsigned: [3, MAX] = OP1 >> 1
4333   {
4334     int_range_max lhs (build_int_cst (unsigned_type_node, 3),
4335 		       TYPE_MAX_VALUE (unsigned_type_node));
4336     int_range_max one (build_one_cst (unsigned_type_node),
4337 		       build_one_cst (unsigned_type_node));
4338     int_range_max op1;
4339     op_rshift.op1_range (op1, unsigned_type_node, lhs, one);
4340     ASSERT_FALSE (op1.contains_p (UINT (3)));
4341   }
4342 
4343   // signed: [3, MAX] = OP1 >> 1
4344   {
4345     int_range_max lhs (INT (3), TYPE_MAX_VALUE (integer_type_node));
4346     int_range_max one (INT (1), INT (1));
4347     int_range_max op1;
4348     op_rshift.op1_range (op1, integer_type_node, lhs, one);
4349     ASSERT_FALSE (op1.contains_p (INT (-2)));
4350   }
4351 
4352   // This is impossible, so OP1 should be [].
4353   // signed: [MIN, MIN] = OP1 >> 1
4354   {
4355     int_range_max lhs (TYPE_MIN_VALUE (integer_type_node),
4356 		       TYPE_MIN_VALUE (integer_type_node));
4357     int_range_max one (INT (1), INT (1));
4358     int_range_max op1;
4359     op_rshift.op1_range (op1, integer_type_node, lhs, one);
4360     ASSERT_TRUE (op1.undefined_p ());
4361   }
4362 
4363   // signed: ~[-1] = OP1 >> 31
4364   if (TYPE_PRECISION (integer_type_node) > 31)
4365     {
4366       int_range_max lhs (INT (-1), INT (-1), VR_ANTI_RANGE);
4367       int_range_max shift (INT (31), INT (31));
4368       int_range_max op1;
4369       op_rshift.op1_range (op1, integer_type_node, lhs, shift);
4370       int_range_max negatives = range_negatives (integer_type_node);
4371       negatives.intersect (op1);
4372       ASSERT_TRUE (negatives.undefined_p ());
4373     }
4374 }
4375 
4376 static void
range_op_bitwise_and_tests()4377 range_op_bitwise_and_tests ()
4378 {
4379   int_range_max res;
4380   tree min = vrp_val_min (integer_type_node);
4381   tree max = vrp_val_max (integer_type_node);
4382   tree tiny = fold_build2 (PLUS_EXPR, integer_type_node, min,
4383 			   build_one_cst (integer_type_node));
4384   int_range_max i1 (tiny, max);
4385   int_range_max i2 (build_int_cst (integer_type_node, 255),
4386 		    build_int_cst (integer_type_node, 255));
4387 
4388   // [MIN+1, MAX] = OP1 & 255: OP1 is VARYING
4389   op_bitwise_and.op1_range (res, integer_type_node, i1, i2);
4390   ASSERT_TRUE (res == int_range<1> (integer_type_node));
4391 
4392   // VARYING = OP1 & 255: OP1 is VARYING
4393   i1 = int_range<1> (integer_type_node);
4394   op_bitwise_and.op1_range (res, integer_type_node, i1, i2);
4395   ASSERT_TRUE (res == int_range<1> (integer_type_node));
4396 
4397   // (NONZERO | X) is nonzero.
4398   i1.set_nonzero (integer_type_node);
4399   i2.set_varying (integer_type_node);
4400   op_bitwise_or.fold_range (res, integer_type_node, i1, i2);
4401   ASSERT_TRUE (res.nonzero_p ());
4402 
4403   // (NEGATIVE | X) is nonzero.
4404   i1 = int_range<1> (INT (-5), INT (-3));
4405   i2.set_varying (integer_type_node);
4406   op_bitwise_or.fold_range (res, integer_type_node, i1, i2);
4407   ASSERT_FALSE (res.contains_p (INT (0)));
4408 }
4409 
4410 static void
range_relational_tests()4411 range_relational_tests ()
4412 {
4413   int_range<2> lhs (unsigned_char_type_node);
4414   int_range<2> op1 (UCHAR (8), UCHAR (10));
4415   int_range<2> op2 (UCHAR (20), UCHAR (20));
4416 
4417   // Never wrapping additions mean LHS > OP1.
4418   tree_code code = op_plus.lhs_op1_relation (lhs, op1, op2);
4419   ASSERT_TRUE (code == GT_EXPR);
4420 
4421   // Most wrapping additions mean nothing...
4422   op1 = int_range<2> (UCHAR (8), UCHAR (10));
4423   op2 = int_range<2> (UCHAR (0), UCHAR (255));
4424   code = op_plus.lhs_op1_relation (lhs, op1, op2);
4425   ASSERT_TRUE (code == VREL_NONE);
4426 
4427   // However, always wrapping additions mean LHS < OP1.
4428   op1 = int_range<2> (UCHAR (1), UCHAR (255));
4429   op2 = int_range<2> (UCHAR (255), UCHAR (255));
4430   code = op_plus.lhs_op1_relation (lhs, op1, op2);
4431   ASSERT_TRUE (code == LT_EXPR);
4432 }
4433 
4434 void
range_op_tests()4435 range_op_tests ()
4436 {
4437   range_op_rshift_tests ();
4438   range_op_lshift_tests ();
4439   range_op_bitwise_and_tests ();
4440   range_op_cast_tests ();
4441   range_relational_tests ();
4442 }
4443 
4444 } // namespace selftest
4445 
4446 #endif // CHECKING_P
4447