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