]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/range-op-ptr.cc
[prange] Reword dispatch error message
[thirdparty/gcc.git] / gcc / range-op-ptr.cc
CommitLineData
f6e160e3 1/* Code for range operators.
a945c346 2 Copyright (C) 2017-2024 Free Software Foundation, Inc.
f6e160e3
AM
3 Contributed by Andrew MacLeod <amacleod@redhat.com>
4 and Aldy Hernandez <aldyh@redhat.com>.
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GCC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along 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-iterator.h"
42#include "gimple-fold.h"
43#include "tree-eh.h"
44#include "gimple-walk.h"
45#include "tree-cfg.h"
46#include "wide-int.h"
47#include "value-relation.h"
48#include "range-op.h"
49#include "tree-ssa-ccp.h"
50#include "range-op-mixed.h"
51
31377eed
AH
52// Return TRUE if a range-op folder TYPE either handles or can safely
53// ignore the dispatch pattern in DISPATCH. Return FALSE for any
54// combination not handled, which will result in a hard fail up the
55// chain.
56
57bool
58range_operator::pointers_handled_p (range_op_dispatch_type ATTRIBUTE_UNUSED,
59 unsigned dispatch ATTRIBUTE_UNUSED) const
60{
61 return false;
62}
63
64bool
65range_operator::fold_range (prange &r, tree type,
66 const prange &op1,
67 const prange &op2,
68 relation_trio trio) const
69{
70 relation_kind rel = trio.op1_op2 ();
71 r.set_varying (type);
72 op1_op2_relation_effect (r, type, op1, op2, rel);
73 return true;
74}
75
76bool
77range_operator::fold_range (prange &r, tree type,
78 const prange &op1,
79 const irange &op2,
80 relation_trio trio) const
81{
82 relation_kind rel = trio.op1_op2 ();
83 r.set_varying (type);
84 op1_op2_relation_effect (r, type, op1, op2, rel);
85 return true;
86}
87
88bool
89range_operator::fold_range (irange &r, tree type,
90 const prange &op1,
91 const prange &op2,
92 relation_trio trio) const
93{
94 relation_kind rel = trio.op1_op2 ();
95 r.set_varying (type);
96 op1_op2_relation_effect (r, type, op1, op2, rel);
97 return true;
98}
99
100bool
101range_operator::fold_range (prange &r, tree type,
102 const irange &op1,
103 const prange &op2,
104 relation_trio trio) const
105{
106 relation_kind rel = trio.op1_op2 ();
107 r.set_varying (type);
108 op1_op2_relation_effect (r, type, op1, op2, rel);
109 return true;
110}
111
112bool
113range_operator::fold_range (irange &r, tree type,
114 const prange &op1,
115 const irange &op2,
116 relation_trio trio) const
117{
118 relation_kind rel = trio.op1_op2 ();
119 r.set_varying (type);
120 op1_op2_relation_effect (r, type, op1, op2, rel);
121 return true;
122}
123
124bool
125range_operator::op1_op2_relation_effect (prange &, tree,
126 const prange &,
127 const prange &,
128 relation_kind) const
129{
130 return false;
131}
132
133bool
134range_operator::op1_op2_relation_effect (prange &, tree,
135 const prange &,
136 const irange &,
137 relation_kind) const
138{
139 return false;
140}
141
142bool
143range_operator::op1_op2_relation_effect (irange &, tree,
144 const prange &,
145 const prange &,
146 relation_kind) const
147{
148 return false;
149}
150
151bool
152range_operator::op1_op2_relation_effect (prange &, tree,
153 const irange &,
154 const prange &,
155 relation_kind) const
156{
157 return false;
158}
159
160bool
161range_operator::op1_op2_relation_effect (irange &, tree,
162 const prange &,
163 const irange &,
164 relation_kind) const
165{
166 return false;
167}
168
169bool
170range_operator::op1_range (prange &, tree,
171 const prange &lhs ATTRIBUTE_UNUSED,
172 const prange &op2 ATTRIBUTE_UNUSED,
173 relation_trio) const
174{
175 return false;
176}
177
178bool
179range_operator::op1_range (prange &, tree,
180 const irange &lhs ATTRIBUTE_UNUSED,
181 const prange &op2 ATTRIBUTE_UNUSED,
182 relation_trio) const
183{
184 return false;
185}
186
187bool
188range_operator::op1_range (prange &, tree,
189 const prange &lhs ATTRIBUTE_UNUSED,
190 const irange &op2 ATTRIBUTE_UNUSED,
191 relation_trio) const
192{
193 return false;
194}
195
196bool
197range_operator::op1_range (irange &, tree,
198 const prange &lhs ATTRIBUTE_UNUSED,
199 const irange &op2 ATTRIBUTE_UNUSED,
200 relation_trio) const
201{
202 return false;
203}
204
205bool
206range_operator::op2_range (prange &, tree,
207 const irange &lhs ATTRIBUTE_UNUSED,
208 const prange &op1 ATTRIBUTE_UNUSED,
209 relation_trio) const
210{
211 return false;
212}
213
214bool
215range_operator::op2_range (irange &, tree,
216 const prange &lhs ATTRIBUTE_UNUSED,
217 const prange &op1 ATTRIBUTE_UNUSED,
218 relation_trio) const
219{
220 return false;
221}
222
223relation_kind
224range_operator::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
225 const prange &op1 ATTRIBUTE_UNUSED,
226 const prange &op2 ATTRIBUTE_UNUSED) const
227{
228 return VREL_VARYING;
229}
230
231relation_kind
232range_operator::lhs_op1_relation (const prange &lhs ATTRIBUTE_UNUSED,
233 const irange &op1 ATTRIBUTE_UNUSED,
234 const irange &op2 ATTRIBUTE_UNUSED,
235 relation_kind rel ATTRIBUTE_UNUSED) const
236{
237 return VREL_VARYING;
238}
239
240relation_kind
241range_operator::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED,
242 const prange &op1 ATTRIBUTE_UNUSED,
243 const prange &op2 ATTRIBUTE_UNUSED,
244 relation_kind rel ATTRIBUTE_UNUSED) const
245{
246 return VREL_VARYING;
247}
248
249relation_kind
250range_operator::lhs_op1_relation (const prange &lhs ATTRIBUTE_UNUSED,
251 const prange &op1 ATTRIBUTE_UNUSED,
252 const prange &op2 ATTRIBUTE_UNUSED,
253 relation_kind rel ATTRIBUTE_UNUSED) const
254{
255 return VREL_VARYING;
256}
257
258void
259range_operator::update_bitmask (irange &,
260 const prange &,
261 const prange &) const
262{
263}
264
bfa2323d
AH
265// Return the upper limit for a type.
266
267static inline wide_int
268max_limit (const_tree type)
269{
270 return wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
271}
272
273// Return the lower limit for a type.
274
275static inline wide_int
276min_limit (const_tree type)
277{
278 return wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
279}
280
281// Build a range that is < VAL and store it in R.
282
283static void
284build_lt (prange &r, tree type, const prange &val)
285{
286 wi::overflow_type ov;
287 wide_int lim = wi::sub (val.upper_bound (), 1, UNSIGNED, &ov);
288
289 // If val - 1 underflows, check if X < MIN, which is an empty range.
290 if (ov)
291 r.set_undefined ();
292 else
293 r.set (type, min_limit (type), lim);
294}
295
296// Build a range that is <= VAL and store it in R.
297
298static void
299build_le (prange &r, tree type, const prange &val)
300{
301 r.set (type, min_limit (type), val.upper_bound ());
302}
303
304// Build a range that is > VAL and store it in R.
305
306static void
307build_gt (prange &r, tree type, const prange &val)
308{
309 wi::overflow_type ov;
310 wide_int lim = wi::add (val.lower_bound (), 1, UNSIGNED, &ov);
311
312 // If val + 1 overflows, check is for X > MAX, which is an empty range.
313 if (ov)
314 r.set_undefined ();
315 else
316 r.set (type, lim, max_limit (type));
317
318}
319
320// Build a range that is >= VAL and store it in R.
321
322static void
323build_ge (prange &r, tree type, const prange &val)
324{
325 r.set (type, val.lower_bound (), max_limit (type));
326}
327
f6e160e3
AM
328class pointer_plus_operator : public range_operator
329{
31377eed 330 using range_operator::update_bitmask;
86ff3c45 331 using range_operator::fold_range;
f6e160e3
AM
332 using range_operator::op2_range;
333public:
86ff3c45
AH
334 virtual bool fold_range (prange &r, tree type,
335 const prange &op1,
336 const irange &op2,
337 relation_trio) const final override;
338 virtual bool op2_range (irange &r, tree type,
339 const prange &lhs,
340 const prange &op1,
341 relation_trio = TRIO_VARYING) const final override;
f6e160e3
AM
342 virtual void wi_fold (irange &r, tree type,
343 const wide_int &lh_lb,
344 const wide_int &lh_ub,
345 const wide_int &rh_lb,
346 const wide_int &rh_ub) const;
347 virtual bool op2_range (irange &r, tree type,
348 const irange &lhs,
349 const irange &op1,
350 relation_trio = TRIO_VARYING) const;
86ff3c45 351 bool pointers_handled_p (range_op_dispatch_type, unsigned) const final override;
f6e160e3
AM
352 void update_bitmask (irange &r, const irange &lh, const irange &rh) const
353 { update_known_bitmask (r, POINTER_PLUS_EXPR, lh, rh); }
354} op_pointer_plus;
355
86ff3c45
AH
356bool
357pointer_plus_operator::fold_range (prange &r, tree type,
358 const prange &op1,
359 const irange &op2,
360 relation_trio) const
361{
362 if (empty_range_varying (r, type, op1, op2))
363 return true;
364
365 const wide_int lh_lb = op1.lower_bound ();
366 const wide_int lh_ub = op1.upper_bound ();
367 const wide_int rh_lb = op2.lower_bound ();
368 const wide_int rh_ub = op2.upper_bound ();
369
370 // Check for [0,0] + const, and simply return the const.
371 if (lh_lb == 0 && lh_ub == 0 && rh_lb == rh_ub)
372 {
373 r.set (type, rh_lb, rh_lb);
374 return true;
375 }
376
377 // For pointer types, we are really only interested in asserting
378 // whether the expression evaluates to non-NULL.
379 //
380 // With -fno-delete-null-pointer-checks we need to be more
381 // conservative. As some object might reside at address 0,
382 // then some offset could be added to it and the same offset
383 // subtracted again and the result would be NULL.
384 // E.g.
385 // static int a[12]; where &a[0] is NULL and
386 // ptr = &a[6];
387 // ptr -= 6;
388 // ptr will be NULL here, even when there is POINTER_PLUS_EXPR
389 // where the first range doesn't include zero and the second one
390 // doesn't either. As the second operand is sizetype (unsigned),
391 // consider all ranges where the MSB could be set as possible
392 // subtractions where the result might be NULL.
393 if ((!wi_includes_zero_p (type, lh_lb, lh_ub)
394 || !wi_includes_zero_p (type, rh_lb, rh_ub))
395 && !TYPE_OVERFLOW_WRAPS (type)
396 && (flag_delete_null_pointer_checks
397 || !wi::sign_mask (rh_ub)))
398 r.set_nonzero (type);
399 else if (lh_lb == lh_ub && lh_lb == 0
400 && rh_lb == rh_ub && rh_lb == 0)
401 r.set_zero (type);
402 else
403 r.set_varying (type);
404
405 update_known_bitmask (r, POINTER_PLUS_EXPR, op1, op2);
406 return true;
407}
408
409bool
410pointer_plus_operator::op2_range (irange &r, tree type,
411 const prange &lhs ATTRIBUTE_UNUSED,
412 const prange &op1 ATTRIBUTE_UNUSED,
413 relation_trio trio) const
414{
415 relation_kind rel = trio.lhs_op1 ();
416 r.set_varying (type);
417
418 // If the LHS and OP1 are equal, the op2 must be zero.
419 if (rel == VREL_EQ)
420 r.set_zero (type);
421 // If the LHS and OP1 are not equal, the offset must be non-zero.
422 else if (rel == VREL_NE)
423 r.set_nonzero (type);
424 else
425 return false;
426 return true;
427}
428
429bool
430pointer_plus_operator::pointers_handled_p (range_op_dispatch_type type,
431 unsigned dispatch) const
432{
433 switch (type)
434 {
435 case DISPATCH_FOLD_RANGE:
436 return dispatch == RO_PPI;
437 case DISPATCH_OP2_RANGE:
438 return dispatch == RO_IPP;
439 default:
440 return true;
441 }
442}
443
f6e160e3
AM
444void
445pointer_plus_operator::wi_fold (irange &r, tree type,
446 const wide_int &lh_lb,
447 const wide_int &lh_ub,
448 const wide_int &rh_lb,
449 const wide_int &rh_ub) const
450{
451 // Check for [0,0] + const, and simply return the const.
452 if (lh_lb == 0 && lh_ub == 0 && rh_lb == rh_ub)
453 {
454 r.set (type, rh_lb, rh_lb);
455 return;
456 }
457
458 // For pointer types, we are really only interested in asserting
459 // whether the expression evaluates to non-NULL.
460 //
461 // With -fno-delete-null-pointer-checks we need to be more
462 // conservative. As some object might reside at address 0,
463 // then some offset could be added to it and the same offset
464 // subtracted again and the result would be NULL.
465 // E.g.
466 // static int a[12]; where &a[0] is NULL and
467 // ptr = &a[6];
468 // ptr -= 6;
469 // ptr will be NULL here, even when there is POINTER_PLUS_EXPR
470 // where the first range doesn't include zero and the second one
471 // doesn't either. As the second operand is sizetype (unsigned),
472 // consider all ranges where the MSB could be set as possible
473 // subtractions where the result might be NULL.
474 if ((!wi_includes_zero_p (type, lh_lb, lh_ub)
475 || !wi_includes_zero_p (type, rh_lb, rh_ub))
476 && !TYPE_OVERFLOW_WRAPS (type)
477 && (flag_delete_null_pointer_checks
478 || !wi::sign_mask (rh_ub)))
3b9abfd2 479 r.set_nonzero (type);
f6e160e3
AM
480 else if (lh_lb == lh_ub && lh_lb == 0
481 && rh_lb == rh_ub && rh_lb == 0)
3b9abfd2 482 r.set_zero (type);
f6e160e3
AM
483 else
484 r.set_varying (type);
485}
486
487bool
488pointer_plus_operator::op2_range (irange &r, tree type,
489 const irange &lhs ATTRIBUTE_UNUSED,
490 const irange &op1 ATTRIBUTE_UNUSED,
491 relation_trio trio) const
492{
493 relation_kind rel = trio.lhs_op1 ();
494 r.set_varying (type);
495
496 // If the LHS and OP1 are equal, the op2 must be zero.
497 if (rel == VREL_EQ)
498 r.set_zero (type);
499 // If the LHS and OP1 are not equal, the offset must be non-zero.
500 else if (rel == VREL_NE)
501 r.set_nonzero (type);
502 else
503 return false;
504 return true;
505}
506
507class pointer_min_max_operator : public range_operator
508{
509public:
510 virtual void wi_fold (irange & r, tree type,
511 const wide_int &lh_lb, const wide_int &lh_ub,
512 const wide_int &rh_lb, const wide_int &rh_ub) const;
513} op_ptr_min_max;
514
515void
516pointer_min_max_operator::wi_fold (irange &r, tree type,
517 const wide_int &lh_lb,
518 const wide_int &lh_ub,
519 const wide_int &rh_lb,
520 const wide_int &rh_ub) const
521{
522 // For MIN/MAX expressions with pointers, we only care about
523 // nullness. If both are non null, then the result is nonnull.
524 // If both are null, then the result is null. Otherwise they
525 // are varying.
526 if (!wi_includes_zero_p (type, lh_lb, lh_ub)
527 && !wi_includes_zero_p (type, rh_lb, rh_ub))
3b9abfd2 528 r.set_nonzero (type);
f6e160e3 529 else if (wi_zero_p (type, lh_lb, lh_ub) && wi_zero_p (type, rh_lb, rh_ub))
3b9abfd2 530 r.set_zero (type);
f6e160e3
AM
531 else
532 r.set_varying (type);
533}
534
f6e160e3
AM
535class pointer_and_operator : public range_operator
536{
537public:
538 virtual void wi_fold (irange &r, tree type,
539 const wide_int &lh_lb, const wide_int &lh_ub,
540 const wide_int &rh_lb, const wide_int &rh_ub) const;
541} op_pointer_and;
542
543void
544pointer_and_operator::wi_fold (irange &r, tree type,
545 const wide_int &lh_lb,
546 const wide_int &lh_ub,
547 const wide_int &rh_lb ATTRIBUTE_UNUSED,
548 const wide_int &rh_ub ATTRIBUTE_UNUSED) const
549{
550 // For pointer types, we are really only interested in asserting
551 // whether the expression evaluates to non-NULL.
552 if (wi_zero_p (type, lh_lb, lh_ub) || wi_zero_p (type, lh_lb, lh_ub))
3b9abfd2 553 r.set_zero (type);
f6e160e3
AM
554 else
555 r.set_varying (type);
556}
557
558
559class pointer_or_operator : public range_operator
560{
af5e7f06 561public:
f6e160e3
AM
562 using range_operator::op1_range;
563 using range_operator::op2_range;
f6e160e3
AM
564 virtual bool op1_range (irange &r, tree type,
565 const irange &lhs,
566 const irange &op2,
567 relation_trio rel = TRIO_VARYING) const;
568 virtual bool op2_range (irange &r, tree type,
569 const irange &lhs,
570 const irange &op1,
571 relation_trio rel = TRIO_VARYING) const;
572 virtual void wi_fold (irange &r, tree type,
573 const wide_int &lh_lb, const wide_int &lh_ub,
574 const wide_int &rh_lb, const wide_int &rh_ub) const;
575} op_pointer_or;
576
577bool
578pointer_or_operator::op1_range (irange &r, tree type,
579 const irange &lhs,
580 const irange &op2 ATTRIBUTE_UNUSED,
581 relation_trio) const
582{
583 if (lhs.undefined_p ())
584 return false;
585 if (lhs.zero_p ())
586 {
587 r.set_zero (type);
588 return true;
589 }
590 r.set_varying (type);
591 return true;
592}
593
594bool
595pointer_or_operator::op2_range (irange &r, tree type,
596 const irange &lhs,
597 const irange &op1,
598 relation_trio) const
599{
600 return pointer_or_operator::op1_range (r, type, lhs, op1);
601}
602
603void
604pointer_or_operator::wi_fold (irange &r, tree type,
605 const wide_int &lh_lb,
606 const wide_int &lh_ub,
607 const wide_int &rh_lb,
608 const wide_int &rh_ub) const
609{
610 // For pointer types, we are really only interested in asserting
611 // whether the expression evaluates to non-NULL.
612 if (!wi_includes_zero_p (type, lh_lb, lh_ub)
613 && !wi_includes_zero_p (type, rh_lb, rh_ub))
3b9abfd2 614 r.set_nonzero (type);
f6e160e3 615 else if (wi_zero_p (type, lh_lb, lh_ub) && wi_zero_p (type, rh_lb, rh_ub))
3b9abfd2 616 r.set_zero (type);
f6e160e3
AM
617 else
618 r.set_varying (type);
619}
620
621class operator_pointer_diff : public range_operator
622{
31377eed
AH
623 using range_operator::update_bitmask;
624 using range_operator::op1_op2_relation_effect;
f6e160e3
AM
625 virtual bool op1_op2_relation_effect (irange &lhs_range,
626 tree type,
627 const irange &op1_range,
628 const irange &op2_range,
629 relation_kind rel) const;
f803b93f
AH
630 virtual bool op1_op2_relation_effect (irange &lhs_range,
631 tree type,
632 const prange &op1_range,
633 const prange &op2_range,
634 relation_kind rel) const final override;
f6e160e3
AM
635 void update_bitmask (irange &r, const irange &lh, const irange &rh) const
636 { update_known_bitmask (r, POINTER_DIFF_EXPR, lh, rh); }
f803b93f
AH
637 void update_bitmask (irange &r,
638 const prange &lh, const prange &rh) const final override
639 { update_known_bitmask (r, POINTER_DIFF_EXPR, lh, rh); }
640 bool pointers_handled_p (range_op_dispatch_type, unsigned) const final override;
f6e160e3
AM
641} op_pointer_diff;
642
f803b93f
AH
643bool
644operator_pointer_diff::op1_op2_relation_effect (irange &lhs_range, tree type,
645 const prange &op1_range,
646 const prange &op2_range,
647 relation_kind rel) const
648{
649 int_range<2> op1, op2, tmp;
650 range_op_handler cast (CONVERT_EXPR);
651
652 if (!cast.fold_range (op1, type, op1_range, tmp)
653 || !cast.fold_range (op2, type, op2_range, tmp))
654 return false;
655
656 return minus_op1_op2_relation_effect (lhs_range, type, op1, op2, rel);
657}
658
659bool
660operator_pointer_diff::pointers_handled_p (range_op_dispatch_type,
661 unsigned) const
662{
663 return true;
664}
665
f6e160e3
AM
666bool
667operator_pointer_diff::op1_op2_relation_effect (irange &lhs_range, tree type,
668 const irange &op1_range,
669 const irange &op2_range,
670 relation_kind rel) const
671{
672 return minus_op1_op2_relation_effect (lhs_range, type, op1_range, op2_range,
673 rel);
674}
675
8e0f292f
AM
676// ----------------------------------------------------------------------
677// Hybrid operators for the 4 operations which integer and pointers share,
678// but which have different implementations. Simply check the type in
679// the call and choose the appropriate method.
680// Once there is a PRANGE signature, simply add the appropriate
681// prototypes in the rmixed range class, and remove these hybrid classes.
682
683class hybrid_and_operator : public operator_bitwise_and
684{
685public:
31377eed 686 using range_operator::update_bitmask;
8e0f292f
AM
687 using range_operator::op1_range;
688 using range_operator::op2_range;
689 using range_operator::lhs_op1_relation;
690 bool op1_range (irange &r, tree type,
691 const irange &lhs, const irange &op2,
692 relation_trio rel = TRIO_VARYING) const final override
693 {
694 if (INTEGRAL_TYPE_P (type))
695 return operator_bitwise_and::op1_range (r, type, lhs, op2, rel);
696 else
697 return false;
698 }
699 bool op2_range (irange &r, tree type,
700 const irange &lhs, const irange &op1,
701 relation_trio rel = TRIO_VARYING) const final override
702 {
703 if (INTEGRAL_TYPE_P (type))
704 return operator_bitwise_and::op2_range (r, type, lhs, op1, rel);
705 else
706 return false;
707 }
708 relation_kind lhs_op1_relation (const irange &lhs,
709 const irange &op1, const irange &op2,
710 relation_kind rel) const final override
711 {
712 if (!lhs.undefined_p () && INTEGRAL_TYPE_P (lhs.type ()))
713 return operator_bitwise_and::lhs_op1_relation (lhs, op1, op2, rel);
714 else
715 return VREL_VARYING;
716 }
717 void update_bitmask (irange &r, const irange &lh,
718 const irange &rh) const final override
719 {
720 if (!r.undefined_p () && INTEGRAL_TYPE_P (r.type ()))
721 operator_bitwise_and::update_bitmask (r, lh, rh);
722 }
723
724 void wi_fold (irange &r, tree type, const wide_int &lh_lb,
725 const wide_int &lh_ub, const wide_int &rh_lb,
726 const wide_int &rh_ub) const final override
727 {
728 if (INTEGRAL_TYPE_P (type))
729 return operator_bitwise_and::wi_fold (r, type, lh_lb, lh_ub,
730 rh_lb, rh_ub);
731 else
732 return op_pointer_and.wi_fold (r, type, lh_lb, lh_ub, rh_lb, rh_ub);
733 }
734} op_hybrid_and;
735
af5e7f06
AM
736// Temporary class which dispatches routines to either the INT version or
737// the pointer version depending on the type. Once PRANGE is a range
738// class, we can remove the hybrid.
739
740class hybrid_or_operator : public operator_bitwise_or
741{
742public:
31377eed 743 using range_operator::update_bitmask;
af5e7f06
AM
744 using range_operator::op1_range;
745 using range_operator::op2_range;
746 using range_operator::lhs_op1_relation;
747 bool op1_range (irange &r, tree type,
748 const irange &lhs, const irange &op2,
749 relation_trio rel = TRIO_VARYING) const final override
750 {
751 if (INTEGRAL_TYPE_P (type))
752 return operator_bitwise_or::op1_range (r, type, lhs, op2, rel);
753 else
754 return op_pointer_or.op1_range (r, type, lhs, op2, rel);
755 }
756 bool op2_range (irange &r, tree type,
757 const irange &lhs, const irange &op1,
758 relation_trio rel = TRIO_VARYING) const final override
759 {
760 if (INTEGRAL_TYPE_P (type))
761 return operator_bitwise_or::op2_range (r, type, lhs, op1, rel);
762 else
763 return op_pointer_or.op2_range (r, type, lhs, op1, rel);
764 }
765 void update_bitmask (irange &r, const irange &lh,
766 const irange &rh) const final override
767 {
768 if (!r.undefined_p () && INTEGRAL_TYPE_P (r.type ()))
769 operator_bitwise_or::update_bitmask (r, lh, rh);
770 }
771
772 void wi_fold (irange &r, tree type, const wide_int &lh_lb,
773 const wide_int &lh_ub, const wide_int &rh_lb,
774 const wide_int &rh_ub) const final override
775 {
776 if (INTEGRAL_TYPE_P (type))
777 return operator_bitwise_or::wi_fold (r, type, lh_lb, lh_ub,
778 rh_lb, rh_ub);
779 else
780 return op_pointer_or.wi_fold (r, type, lh_lb, lh_ub, rh_lb, rh_ub);
781 }
782} op_hybrid_or;
783
73cbf402
AM
784// Temporary class which dispatches routines to either the INT version or
785// the pointer version depending on the type. Once PRANGE is a range
786// class, we can remove the hybrid.
787
788class hybrid_min_operator : public operator_min
789{
31377eed 790 using range_operator::update_bitmask;
73cbf402
AM
791public:
792 void update_bitmask (irange &r, const irange &lh,
793 const irange &rh) const final override
794 {
795 if (!r.undefined_p () && INTEGRAL_TYPE_P (r.type ()))
796 operator_min::update_bitmask (r, lh, rh);
797 }
798
799 void wi_fold (irange &r, tree type, const wide_int &lh_lb,
800 const wide_int &lh_ub, const wide_int &rh_lb,
801 const wide_int &rh_ub) const final override
802 {
803 if (INTEGRAL_TYPE_P (type))
804 return operator_min::wi_fold (r, type, lh_lb, lh_ub, rh_lb, rh_ub);
805 else
806 return op_ptr_min_max.wi_fold (r, type, lh_lb, lh_ub, rh_lb, rh_ub);
807 }
808} op_hybrid_min;
809
110c1f8d
AM
810class hybrid_max_operator : public operator_max
811{
31377eed 812 using range_operator::update_bitmask;
110c1f8d
AM
813public:
814 void update_bitmask (irange &r, const irange &lh,
815 const irange &rh) const final override
816 {
817 if (!r.undefined_p () && INTEGRAL_TYPE_P (r.type ()))
818 operator_max::update_bitmask (r, lh, rh);
819 }
73cbf402 820
110c1f8d
AM
821 void wi_fold (irange &r, tree type, const wide_int &lh_lb,
822 const wide_int &lh_ub, const wide_int &rh_lb,
823 const wide_int &rh_ub) const final override
824 {
825 if (INTEGRAL_TYPE_P (type))
826 return operator_max::wi_fold (r, type, lh_lb, lh_ub, rh_lb, rh_ub);
827 else
828 return op_ptr_min_max.wi_fold (r, type, lh_lb, lh_ub, rh_lb, rh_ub);
829 }
830} op_hybrid_max;
8e0f292f 831
e7b6e966
AH
832bool
833operator_identity::fold_range (prange &r, tree type ATTRIBUTE_UNUSED,
834 const prange &lh ATTRIBUTE_UNUSED,
835 const prange &rh ATTRIBUTE_UNUSED,
836 relation_trio) const
837{
838 r = lh;
839 return true;
840}
841
842relation_kind
843operator_identity::lhs_op1_relation (const prange &lhs,
844 const prange &op1 ATTRIBUTE_UNUSED,
845 const prange &op2 ATTRIBUTE_UNUSED,
846 relation_kind) const
847{
848 if (lhs.undefined_p ())
849 return VREL_VARYING;
850 // Simply a copy, so they are equivalent.
851 return VREL_EQ;
852}
853
854bool
855operator_identity::op1_range (prange &r, tree type ATTRIBUTE_UNUSED,
856 const prange &lhs,
857 const prange &op2 ATTRIBUTE_UNUSED,
858 relation_trio) const
859{
860 r = lhs;
861 return true;
862}
863
864bool
865operator_identity::pointers_handled_p (range_op_dispatch_type type,
866 unsigned dispatch) const
867{
868 switch (type)
869 {
870 case DISPATCH_FOLD_RANGE:
871 case DISPATCH_OP1_RANGE:
872 case DISPATCH_LHS_OP1_RELATION:
873 return dispatch == RO_PPP;
874 default:
875 return true;
876 }
877}
878
a91fd7b4
AH
879bool
880operator_cst::fold_range (prange &r, tree type ATTRIBUTE_UNUSED,
881 const prange &lh,
882 const prange & ATTRIBUTE_UNUSED,
883 relation_trio) const
884{
885 r = lh;
886 return true;
887}
888
889bool
890operator_cst::pointers_handled_p (range_op_dispatch_type type,
891 unsigned dispatch) const
892{
893 switch (type)
894 {
895 case DISPATCH_FOLD_RANGE:
896 return dispatch == RO_PPP;
897 default:
898 return true;
899 }
900}
901
95fce0dc
AH
902// Cast between pointers.
903
904bool
905operator_cast::fold_range (prange &r, tree type,
906 const prange &inner,
907 const prange &outer,
908 relation_trio) const
909{
910 if (empty_range_varying (r, type, inner, outer))
911 return true;
912
913 r.set (type, inner.lower_bound (), inner.upper_bound ());
914 r.update_bitmask (inner.get_bitmask ());
915 return true;
916}
917
918// Cast a pointer to an integer.
919
920bool
921operator_cast::fold_range (irange &r, tree type,
922 const prange &inner,
923 const irange &outer,
924 relation_trio) const
925{
926 if (empty_range_varying (r, type, inner, outer))
927 return true;
928
929 // Represent INNER as an integer of the same size, and then cast it
930 // to the resulting integer type.
931 tree pointer_uint_type = make_unsigned_type (TYPE_PRECISION (inner.type ()));
932 r.set (pointer_uint_type, inner.lower_bound (), inner.upper_bound ());
933 r.update_bitmask (inner.get_bitmask ());
934 range_cast (r, type);
935 return true;
936}
937
938// Cast an integer to a pointer.
939
940bool
941operator_cast::fold_range (prange &r, tree type,
942 const irange &inner,
943 const prange &outer,
944 relation_trio) const
945{
946 if (empty_range_varying (r, type, inner, outer))
947 return true;
948
949 // Cast INNER to an integer of the same size as the pointer we want,
950 // and then copy the bounds to the resulting pointer range.
951 int_range<2> tmp = inner;
952 tree pointer_uint_type = make_unsigned_type (TYPE_PRECISION (type));
953 range_cast (tmp, pointer_uint_type);
954 r.set (type, tmp.lower_bound (), tmp.upper_bound ());
955 r.update_bitmask (tmp.get_bitmask ());
956 return true;
957}
958
959bool
960operator_cast::op1_range (prange &r, tree type,
961 const prange &lhs,
962 const prange &op2,
963 relation_trio trio) const
964{
965 if (lhs.undefined_p ())
966 return false;
967 gcc_checking_assert (types_compatible_p (op2.type(), type));
968
969 // Conversion from other pointers or a constant (including 0/NULL)
970 // are straightforward.
971 if (POINTER_TYPE_P (lhs.type ())
972 || (lhs.singleton_p ()
973 && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
974 fold_range (r, type, lhs, op2, trio);
975 else
976 {
977 // If the LHS is not a pointer nor a singleton, then it is
978 // either VARYING or non-zero.
979 if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
980 r.set_nonzero (type);
981 else
982 r.set_varying (type);
983 }
984 r.intersect (op2);
985 return true;
986}
987
988bool
989operator_cast::op1_range (irange &r, tree type,
990 const prange &lhs,
991 const irange &op2,
992 relation_trio trio) const
993{
994 if (lhs.undefined_p ())
995 return false;
996 gcc_checking_assert (types_compatible_p (op2.type(), type));
997
998 // Conversion from other pointers or a constant (including 0/NULL)
999 // are straightforward.
1000 if (POINTER_TYPE_P (lhs.type ())
1001 || (lhs.singleton_p ()
1002 && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
1003 fold_range (r, type, lhs, op2, trio);
1004 else
1005 {
1006 // If the LHS is not a pointer nor a singleton, then it is
1007 // either VARYING or non-zero.
1008 if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
1009 r.set_nonzero (type);
1010 else
1011 r.set_varying (type);
1012 }
1013 r.intersect (op2);
1014 return true;
1015}
1016
1017bool
1018operator_cast::op1_range (prange &r, tree type,
1019 const irange &lhs,
1020 const prange &op2,
1021 relation_trio trio) const
1022{
1023 if (lhs.undefined_p ())
1024 return false;
1025 gcc_checking_assert (types_compatible_p (op2.type(), type));
1026
1027 // Conversion from other pointers or a constant (including 0/NULL)
1028 // are straightforward.
1029 if (POINTER_TYPE_P (lhs.type ())
1030 || (lhs.singleton_p ()
1031 && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
1032 fold_range (r, type, lhs, op2, trio);
1033 else
1034 {
1035 // If the LHS is not a pointer nor a singleton, then it is
1036 // either VARYING or non-zero.
1037 if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
1038 r.set_nonzero (type);
1039 else
1040 r.set_varying (type);
1041 }
1042 r.intersect (op2);
1043 return true;
1044}
1045
1046relation_kind
1047operator_cast::lhs_op1_relation (const prange &lhs,
1048 const prange &op1,
1049 const prange &op2 ATTRIBUTE_UNUSED,
1050 relation_kind) const
1051{
1052 if (lhs.undefined_p () || op1.undefined_p ())
1053 return VREL_VARYING;
1054 unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
1055 unsigned op1_prec = TYPE_PRECISION (op1.type ());
1056 // If the result gets sign extended into a larger type check first if this
1057 // qualifies as a partial equivalence.
1058 if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
1059 {
1060 // If the result is sign extended, and the LHS is larger than op1,
1061 // check if op1's range can be negative as the sign extension will
1062 // cause the upper bits to be 1 instead of 0, invalidating the PE.
1063 int_range<3> negs = range_negatives (op1.type ());
1064 negs.intersect (op1);
1065 if (!negs.undefined_p ())
1066 return VREL_VARYING;
1067 }
1068
1069 unsigned prec = MIN (lhs_prec, op1_prec);
1070 return bits_to_pe (prec);
1071}
1072
1073relation_kind
1074operator_cast::lhs_op1_relation (const prange &lhs,
1075 const irange &op1,
1076 const irange &op2 ATTRIBUTE_UNUSED,
1077 relation_kind) const
1078{
1079 if (lhs.undefined_p () || op1.undefined_p ())
1080 return VREL_VARYING;
1081 unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
1082 unsigned op1_prec = TYPE_PRECISION (op1.type ());
1083 // If the result gets sign extended into a larger type check first if this
1084 // qualifies as a partial equivalence.
1085 if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
1086 {
1087 // If the result is sign extended, and the LHS is larger than op1,
1088 // check if op1's range can be negative as the sign extension will
1089 // cause the upper bits to be 1 instead of 0, invalidating the PE.
1090 int_range<3> negs = range_negatives (op1.type ());
1091 negs.intersect (op1);
1092 if (!negs.undefined_p ())
1093 return VREL_VARYING;
1094 }
1095
1096 unsigned prec = MIN (lhs_prec, op1_prec);
1097 return bits_to_pe (prec);
1098}
1099
1100relation_kind
1101operator_cast::lhs_op1_relation (const irange &lhs,
1102 const prange &op1,
1103 const prange &op2 ATTRIBUTE_UNUSED,
1104 relation_kind) const
1105{
1106 if (lhs.undefined_p () || op1.undefined_p ())
1107 return VREL_VARYING;
1108 unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
1109 unsigned op1_prec = TYPE_PRECISION (op1.type ());
1110 // If the result gets sign extended into a larger type check first if this
1111 // qualifies as a partial equivalence.
1112 if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
1113 {
1114 // If the result is sign extended, and the LHS is larger than op1,
1115 // check if op1's range can be negative as the sign extension will
1116 // cause the upper bits to be 1 instead of 0, invalidating the PE.
1117 int_range<3> negs = range_negatives (op1.type ());
1118 negs.intersect (op1);
1119 if (!negs.undefined_p ())
1120 return VREL_VARYING;
1121 }
1122
1123 unsigned prec = MIN (lhs_prec, op1_prec);
1124 return bits_to_pe (prec);
1125}
1126
1127bool
1128operator_cast::pointers_handled_p (range_op_dispatch_type type,
1129 unsigned dispatch) const
1130{
1131 switch (type)
1132 {
1133 case DISPATCH_FOLD_RANGE:
1134 case DISPATCH_OP1_RANGE:
1135 return (dispatch == RO_PPP
1136 || dispatch == RO_IPI
1137 || dispatch == RO_PIP);
1138 case DISPATCH_LHS_OP1_RELATION:
1139 return (dispatch == RO_PPP
1140 || dispatch == RO_PII
1141 || dispatch == RO_IPP);
1142 default:
1143 return true;
1144 }
1145}
1146
1a4f5d49
AH
1147bool
1148operator_min::fold_range (prange &r, tree type,
1149 const prange &op1,
1150 const prange &op2,
1151 relation_trio) const
1152{
1153 // For MIN/MAX expressions with pointers, we only care about
1154 // nullness. If both are non null, then the result is nonnull.
1155 // If both are null, then the result is null. Otherwise they
1156 // are varying.
1157 if (!range_includes_zero_p (op1)
1158 && !range_includes_zero_p (op2))
1159 r.set_nonzero (type);
1160 else if (op1.zero_p () && op2.zero_p ())
1161 r.set_zero (type);
1162 else
1163 r.set_varying (type);
1164
1165 update_known_bitmask (r, MIN_EXPR, op1, op2);
1166 return true;
1167}
1168
1169bool
1170operator_min::pointers_handled_p (range_op_dispatch_type type,
1171 unsigned dispatch) const
1172{
1173 switch (type)
1174 {
1175 case DISPATCH_FOLD_RANGE:
1176 return dispatch == RO_PPP;
1177 default:
1178 return true;
1179 }
1180}
1181
1182bool
1183operator_max::fold_range (prange &r, tree type,
1184 const prange &op1,
1185 const prange &op2,
1186 relation_trio) const
1187{
1188 // For MIN/MAX expressions with pointers, we only care about
1189 // nullness. If both are non null, then the result is nonnull.
1190 // If both are null, then the result is null. Otherwise they
1191 // are varying.
1192 if (!range_includes_zero_p (op1)
1193 && !range_includes_zero_p (op2))
1194 r.set_nonzero (type);
1195 else if (op1.zero_p () && op2.zero_p ())
1196 r.set_zero (type);
1197 else
1198 r.set_varying (type);
1199
1200 update_known_bitmask (r, MAX_EXPR, op1, op2);
1201 return true;
1202}
1203
1204bool
1205operator_max::pointers_handled_p (range_op_dispatch_type type,
1206 unsigned dispatch) const
1207{
1208 switch (type)
1209 {
1210 case DISPATCH_FOLD_RANGE:
1211 return dispatch == RO_PPP;
1212 default:
1213 return true;
1214 }
1215}
1216
54d3fd6d
AH
1217bool
1218operator_addr_expr::op1_range (prange &r, tree type,
1219 const prange &lhs,
1220 const prange &op2,
1221 relation_trio) const
1222{
1223 if (empty_range_varying (r, type, lhs, op2))
1224 return true;
1225
1226 // Return a non-null pointer of the LHS type (passed in op2), but only
1227 // if we cant overflow, eitherwise a no-zero offset could wrap to zero.
1228 // See PR 111009.
1229 if (!lhs.undefined_p ()
1230 && !range_includes_zero_p (lhs)
1231 && TYPE_OVERFLOW_UNDEFINED (type))
1232 r.set_nonzero (type);
1233 else
1234 r.set_varying (type);
1235 return true;
1236}
1237
1238bool
1239operator_addr_expr::pointers_handled_p (range_op_dispatch_type type,
1240 unsigned dispatch) const
1241{
1242 switch (type)
1243 {
1244 case DISPATCH_FOLD_RANGE:
1245 // NOTE: It looks like we never generate this combination.
1246 gcc_unreachable ();
1247 return false;
1248 case DISPATCH_OP1_RANGE:
1249 return dispatch == RO_PPP;
1250 default:
1251 return true;
1252 }
1253}
1254
e58f1491
AH
1255bool
1256operator_bitwise_and::fold_range (prange &r, tree type,
1257 const prange &op1,
1258 const prange &op2 ATTRIBUTE_UNUSED,
1259 relation_trio) const
1260{
1261 // For pointer types, we are really only interested in asserting
1262 // whether the expression evaluates to non-NULL.
1263 if (op1.zero_p () || op2.zero_p ())
1264 r.set_zero (type);
1265 else
1266 r.set_varying (type);
1267
1268 update_known_bitmask (r, BIT_AND_EXPR, op1, op2);
1269 return true;
1270}
1271
1272bool
1273operator_bitwise_and::pointers_handled_p (range_op_dispatch_type type,
1274 unsigned dispatch) const
1275{
1276 switch (type)
1277 {
1278 case DISPATCH_FOLD_RANGE:
1279 return dispatch == RO_PPP;
1280 default:
1281 return true;
1282 }
1283}
1284
6b9e640d
AH
1285bool
1286operator_bitwise_or::pointers_handled_p (range_op_dispatch_type,
1287 unsigned) const
1288{
1289 // NOTE: It looks like we never generate bitwise OR with pointers.
1290 // If this is indeed the case, we can move operator_bitwise_or from
1291 // range-op-mixed.h to range-op.h.
1292 gcc_unreachable ();
1293 return false;
1294}
1295
bcb22692
AH
1296bool
1297operator_equal::fold_range (irange &r, tree type,
1298 const prange &op1,
1299 const prange &op2,
1300 relation_trio rel) const
1301{
1302 if (relop_early_resolve (r, type, op1, op2, rel, VREL_EQ))
1303 return true;
1304
1305 // We can be sure the values are always equal or not if both ranges
1306 // consist of a single value, and then compare them.
1307 bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ());
1308 bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ());
1309 if (op1_const && op2_const)
1310 {
1311 if (wi::eq_p (op1.lower_bound (), op2.upper_bound()))
1312 r = range_true ();
1313 else
1314 r = range_false ();
1315 }
1316 else
1317 {
1318 // If ranges do not intersect, we know the range is not equal,
1319 // otherwise we don't know anything for sure.
1320 prange tmp = op1;
1321 tmp.intersect (op2);
1322 if (tmp.undefined_p ())
1323 r = range_false ();
1324 // Check if a constant cannot satisfy the bitmask requirements.
1325 else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ()))
1326 r = range_false ();
1327 else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ()))
1328 r = range_false ();
1329 else
1330 r = range_true_and_false ();
1331 }
1332
1333 //update_known_bitmask (r, EQ_EXPR, op1, op2);
1334 return true;
1335}
1336
1337bool
1338operator_equal::op1_range (prange &r, tree type,
1339 const irange &lhs,
1340 const prange &op2,
1341 relation_trio) const
1342{
1343 switch (get_bool_state (r, lhs, type))
1344 {
1345 case BRS_TRUE:
1346 // If it's true, the result is the same as OP2.
1347 r = op2;
1348 break;
1349
1350 case BRS_FALSE:
1351 // If the result is false, the only time we know anything is
1352 // if OP2 is a constant.
1353 if (!op2.undefined_p ()
1354 && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
1355 {
1356 r = op2;
1357 r.invert ();
1358 }
1359 else
1360 r.set_varying (type);
1361 break;
1362
1363 default:
1364 break;
1365 }
1366 return true;
1367}
1368
1369bool
1370operator_equal::op2_range (prange &r, tree type,
1371 const irange &lhs,
1372 const prange &op1,
1373 relation_trio rel) const
1374{
1375 return operator_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
1376}
1377
1378relation_kind
1379operator_equal::op1_op2_relation (const irange &lhs, const prange &,
1380 const prange &) const
1381{
1382 if (lhs.undefined_p ())
1383 return VREL_UNDEFINED;
1384
1385 // FALSE = op1 == op2 indicates NE_EXPR.
1386 if (lhs.zero_p ())
1387 return VREL_NE;
1388
1389 // TRUE = op1 == op2 indicates EQ_EXPR.
1390 if (!range_includes_zero_p (lhs))
1391 return VREL_EQ;
1392 return VREL_VARYING;
1393}
1394
1395bool
1396operator_equal::pointers_handled_p (range_op_dispatch_type type,
1397 unsigned dispatch) const
1398{
1399 switch (type)
1400 {
1401 case DISPATCH_FOLD_RANGE:
1402 return dispatch == RO_IPP;
1403 case DISPATCH_OP1_RANGE:
1404 case DISPATCH_OP2_RANGE:
1405 return dispatch == RO_PIP;
1406 case DISPATCH_OP1_OP2_RELATION:
1407 return dispatch == RO_IPP;
1408 default:
1409 return true;
1410 }
1411}
1412
d1be4c90
AH
1413bool
1414operator_not_equal::fold_range (irange &r, tree type,
1415 const prange &op1,
1416 const prange &op2,
1417 relation_trio rel) const
1418{
1419 if (relop_early_resolve (r, type, op1, op2, rel, VREL_NE))
1420 return true;
1421
1422 // We can be sure the values are always equal or not if both ranges
1423 // consist of a single value, and then compare them.
1424 bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ());
1425 bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ());
1426 if (op1_const && op2_const)
1427 {
1428 if (wi::ne_p (op1.lower_bound (), op2.upper_bound()))
1429 r = range_true ();
1430 else
1431 r = range_false ();
1432 }
1433 else
1434 {
1435 // If ranges do not intersect, we know the range is not equal,
1436 // otherwise we don't know anything for sure.
1437 prange tmp = op1;
1438 tmp.intersect (op2);
1439 if (tmp.undefined_p ())
1440 r = range_true ();
1441 // Check if a constant cannot satisfy the bitmask requirements.
1442 else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ()))
1443 r = range_true ();
1444 else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ()))
1445 r = range_true ();
1446 else
1447 r = range_true_and_false ();
1448 }
1449
1450 //update_known_bitmask (r, NE_EXPR, op1, op2);
1451 return true;
1452}
1453
1454bool
1455operator_not_equal::op1_range (prange &r, tree type,
1456 const irange &lhs,
1457 const prange &op2,
1458 relation_trio) const
1459{
1460 switch (get_bool_state (r, lhs, type))
1461 {
1462 case BRS_TRUE:
1463 // If the result is true, the only time we know anything is if
1464 // OP2 is a constant.
1465 if (!op2.undefined_p ()
1466 && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
1467 {
1468 r = op2;
1469 r.invert ();
1470 }
1471 else
1472 r.set_varying (type);
1473 break;
1474
1475 case BRS_FALSE:
1476 // If it's false, the result is the same as OP2.
1477 r = op2;
1478 break;
1479
1480 default:
1481 break;
1482 }
1483 return true;
1484}
1485
1486
1487bool
1488operator_not_equal::op2_range (prange &r, tree type,
1489 const irange &lhs,
1490 const prange &op1,
1491 relation_trio rel) const
1492{
1493 return operator_not_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
1494}
1495
1496relation_kind
1497operator_not_equal::op1_op2_relation (const irange &lhs, const prange &,
1498 const prange &) const
1499{
1500 if (lhs.undefined_p ())
1501 return VREL_UNDEFINED;
1502
1503 // FALSE = op1 != op2 indicates EQ_EXPR.
1504 if (lhs.zero_p ())
1505 return VREL_EQ;
1506
1507 // TRUE = op1 != op2 indicates NE_EXPR.
1508 if (!range_includes_zero_p (lhs))
1509 return VREL_NE;
1510 return VREL_VARYING;
1511}
1512
1513bool
1514operator_not_equal::pointers_handled_p (range_op_dispatch_type type,
1515 unsigned dispatch) const
1516{
1517 switch (type)
1518 {
1519 case DISPATCH_FOLD_RANGE:
1520 return dispatch == RO_IPP;
1521 case DISPATCH_OP1_RANGE:
1522 case DISPATCH_OP2_RANGE:
1523 return dispatch == RO_PIP;
1524 case DISPATCH_OP1_OP2_RELATION:
1525 return dispatch == RO_IPP;
1526 default:
1527 return true;
1528 }
1529}
1530
bfa2323d
AH
1531bool
1532operator_lt::fold_range (irange &r, tree type,
1533 const prange &op1,
1534 const prange &op2,
1535 relation_trio rel) const
1536{
1537 if (relop_early_resolve (r, type, op1, op2, rel, VREL_LT))
1538 return true;
1539
1540 signop sign = TYPE_SIGN (op1.type ());
1541 gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
1542
1543 if (wi::lt_p (op1.upper_bound (), op2.lower_bound (), sign))
1544 r = range_true ();
1545 else if (!wi::lt_p (op1.lower_bound (), op2.upper_bound (), sign))
1546 r = range_false ();
1547 // Use nonzero bits to determine if < 0 is false.
1548 else if (op2.zero_p () && !wi::neg_p (op1.get_nonzero_bits (), sign))
1549 r = range_false ();
1550 else
1551 r = range_true_and_false ();
1552
1553 //update_known_bitmask (r, LT_EXPR, op1, op2);
1554 return true;
1555}
1556
1557bool
1558operator_lt::op1_range (prange &r, tree type,
1559 const irange &lhs,
1560 const prange &op2,
1561 relation_trio) const
1562{
1563 if (op2.undefined_p ())
1564 return false;
1565
1566 switch (get_bool_state (r, lhs, type))
1567 {
1568 case BRS_TRUE:
1569 build_lt (r, type, op2);
1570 break;
1571
1572 case BRS_FALSE:
1573 build_ge (r, type, op2);
1574 break;
1575
1576 default:
1577 break;
1578 }
1579 return true;
1580}
1581
1582bool
1583operator_lt::op2_range (prange &r, tree type,
1584 const irange &lhs,
1585 const prange &op1,
1586 relation_trio) const
1587{
1588 if (op1.undefined_p ())
1589 return false;
1590
1591 switch (get_bool_state (r, lhs, type))
1592 {
1593 case BRS_TRUE:
1594 build_gt (r, type, op1);
1595 break;
1596
1597 case BRS_FALSE:
1598 build_le (r, type, op1);
1599 break;
1600
1601 default:
1602 break;
1603 }
1604 return true;
1605}
1606
1607relation_kind
1608operator_lt::op1_op2_relation (const irange &lhs, const prange &,
1609 const prange &) const
1610{
1611 if (lhs.undefined_p ())
1612 return VREL_UNDEFINED;
1613
1614 // FALSE = op1 < op2 indicates GE_EXPR.
1615 if (lhs.zero_p ())
1616 return VREL_GE;
1617
1618 // TRUE = op1 < op2 indicates LT_EXPR.
1619 if (!range_includes_zero_p (lhs))
1620 return VREL_LT;
1621 return VREL_VARYING;
1622}
1623
1624bool
1625operator_lt::pointers_handled_p (range_op_dispatch_type type,
1626 unsigned dispatch) const
1627{
1628 switch (type)
1629 {
1630 case DISPATCH_FOLD_RANGE:
1631 return dispatch == RO_IPP;
1632 case DISPATCH_OP1_RANGE:
1633 case DISPATCH_OP2_RANGE:
1634 return dispatch == RO_PIP;
1635 case DISPATCH_OP1_OP2_RELATION:
1636 return dispatch == RO_IPP;
1637 default:
1638 return true;
1639 }
1640}
1641
3a4ee6ea
AH
1642bool
1643operator_le::fold_range (irange &r, tree type,
1644 const prange &op1,
1645 const prange &op2,
1646 relation_trio rel) const
1647{
1648 if (relop_early_resolve (r, type, op1, op2, rel, VREL_LE))
1649 return true;
1650
1651 signop sign = TYPE_SIGN (op1.type ());
1652 gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
1653
1654 if (wi::le_p (op1.upper_bound (), op2.lower_bound (), sign))
1655 r = range_true ();
1656 else if (!wi::le_p (op1.lower_bound (), op2.upper_bound (), sign))
1657 r = range_false ();
1658 else
1659 r = range_true_and_false ();
1660
1661 //update_known_bitmask (r, LE_EXPR, op1, op2);
1662 return true;
1663}
1664
1665bool
1666operator_le::op1_range (prange &r, tree type,
1667 const irange &lhs,
1668 const prange &op2,
1669 relation_trio) const
1670{
1671 if (op2.undefined_p ())
1672 return false;
1673
1674 switch (get_bool_state (r, lhs, type))
1675 {
1676 case BRS_TRUE:
1677 build_le (r, type, op2);
1678 break;
1679
1680 case BRS_FALSE:
1681 build_gt (r, type, op2);
1682 break;
1683
1684 default:
1685 break;
1686 }
1687 return true;
1688}
1689
1690bool
1691operator_le::op2_range (prange &r, tree type,
1692 const irange &lhs,
1693 const prange &op1,
1694 relation_trio) const
1695{
1696 if (op1.undefined_p ())
1697 return false;
1698
1699 switch (get_bool_state (r, lhs, type))
1700 {
1701 case BRS_TRUE:
1702 build_ge (r, type, op1);
1703 break;
1704
1705 case BRS_FALSE:
1706 build_lt (r, type, op1);
1707 break;
1708
1709 default:
1710 break;
1711 }
1712 return true;
1713}
1714
1715relation_kind
1716operator_le::op1_op2_relation (const irange &lhs, const prange &,
1717 const prange &) const
1718{
1719 if (lhs.undefined_p ())
1720 return VREL_UNDEFINED;
1721
1722 // FALSE = op1 <= op2 indicates GT_EXPR.
1723 if (lhs.zero_p ())
1724 return VREL_GT;
1725
1726 // TRUE = op1 <= op2 indicates LE_EXPR.
1727 if (!range_includes_zero_p (lhs))
1728 return VREL_LE;
1729 return VREL_VARYING;
1730}
1731
1732bool
1733operator_le::pointers_handled_p (range_op_dispatch_type type,
1734 unsigned dispatch) const
1735{
1736 switch (type)
1737 {
1738 case DISPATCH_FOLD_RANGE:
1739 return dispatch == RO_IPP;
1740 case DISPATCH_OP1_RANGE:
1741 case DISPATCH_OP2_RANGE:
1742 return dispatch == RO_PIP;
1743 case DISPATCH_OP1_OP2_RELATION:
1744 return dispatch == RO_IPP;
1745 default:
1746 return true;
1747 }
1748}
1749
76fae405
AH
1750bool
1751operator_gt::fold_range (irange &r, tree type,
1752 const prange &op1, const prange &op2,
1753 relation_trio rel) const
1754{
1755 if (relop_early_resolve (r, type, op1, op2, rel, VREL_GT))
1756 return true;
1757
1758 signop sign = TYPE_SIGN (op1.type ());
1759 gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
1760
1761 if (wi::gt_p (op1.lower_bound (), op2.upper_bound (), sign))
1762 r = range_true ();
1763 else if (!wi::gt_p (op1.upper_bound (), op2.lower_bound (), sign))
1764 r = range_false ();
1765 else
1766 r = range_true_and_false ();
1767
1768 //update_known_bitmask (r, GT_EXPR, op1, op2);
1769 return true;
1770}
1771
1772bool
1773operator_gt::op1_range (prange &r, tree type,
1774 const irange &lhs, const prange &op2,
1775 relation_trio) const
1776{
1777 if (op2.undefined_p ())
1778 return false;
1779
1780 switch (get_bool_state (r, lhs, type))
1781 {
1782 case BRS_TRUE:
1783 build_gt (r, type, op2);
1784 break;
1785
1786 case BRS_FALSE:
1787 build_le (r, type, op2);
1788 break;
1789
1790 default:
1791 break;
1792 }
1793 return true;
1794}
1795
1796bool
1797operator_gt::op2_range (prange &r, tree type,
1798 const irange &lhs,
1799 const prange &op1,
1800 relation_trio) const
1801{
1802 if (op1.undefined_p ())
1803 return false;
1804
1805 switch (get_bool_state (r, lhs, type))
1806 {
1807 case BRS_TRUE:
1808 build_lt (r, type, op1);
1809 break;
1810
1811 case BRS_FALSE:
1812 build_ge (r, type, op1);
1813 break;
1814
1815 default:
1816 break;
1817 }
1818 return true;
1819}
1820
1821relation_kind
1822operator_gt::op1_op2_relation (const irange &lhs, const prange &,
1823 const prange &) const
1824{
1825 if (lhs.undefined_p ())
1826 return VREL_UNDEFINED;
1827
1828 // FALSE = op1 > op2 indicates LE_EXPR.
1829 if (lhs.zero_p ())
1830 return VREL_LE;
1831
1832 // TRUE = op1 > op2 indicates GT_EXPR.
1833 if (!range_includes_zero_p (lhs))
1834 return VREL_GT;
1835 return VREL_VARYING;
1836}
1837
1838bool
1839operator_gt::pointers_handled_p (range_op_dispatch_type type,
1840 unsigned dispatch) const
1841{
1842 switch (type)
1843 {
1844 case DISPATCH_FOLD_RANGE:
1845 return dispatch == RO_IPP;
1846 case DISPATCH_OP1_RANGE:
1847 case DISPATCH_OP2_RANGE:
1848 return dispatch == RO_PIP;
1849 case DISPATCH_OP1_OP2_RELATION:
1850 return dispatch == RO_IPP;
1851 default:
1852 return true;
1853 }
1854}
1855
ff306c77
AH
1856bool
1857operator_ge::fold_range (irange &r, tree type,
1858 const prange &op1,
1859 const prange &op2,
1860 relation_trio rel) const
1861{
1862 if (relop_early_resolve (r, type, op1, op2, rel, VREL_GE))
1863 return true;
1864
1865 signop sign = TYPE_SIGN (op1.type ());
1866 gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
1867
1868 if (wi::ge_p (op1.lower_bound (), op2.upper_bound (), sign))
1869 r = range_true ();
1870 else if (!wi::ge_p (op1.upper_bound (), op2.lower_bound (), sign))
1871 r = range_false ();
1872 else
1873 r = range_true_and_false ();
1874
1875 //update_known_bitmask (r, GE_EXPR, op1, op2);
1876 return true;
1877}
1878
1879bool
1880operator_ge::op1_range (prange &r, tree type,
1881 const irange &lhs,
1882 const prange &op2,
1883 relation_trio) const
1884{
1885 if (op2.undefined_p ())
1886 return false;
1887
1888 switch (get_bool_state (r, lhs, type))
1889 {
1890 case BRS_TRUE:
1891 build_ge (r, type, op2);
1892 break;
1893
1894 case BRS_FALSE:
1895 build_lt (r, type, op2);
1896 break;
1897
1898 default:
1899 break;
1900 }
1901 return true;
1902}
1903
1904bool
1905operator_ge::op2_range (prange &r, tree type,
1906 const irange &lhs,
1907 const prange &op1,
1908 relation_trio) const
1909{
1910 if (op1.undefined_p ())
1911 return false;
1912
1913 switch (get_bool_state (r, lhs, type))
1914 {
1915 case BRS_TRUE:
1916 build_le (r, type, op1);
1917 break;
1918
1919 case BRS_FALSE:
1920 build_gt (r, type, op1);
1921 break;
1922
1923 default:
1924 break;
1925 }
1926 return true;
1927}
1928
1929relation_kind
1930operator_ge::op1_op2_relation (const irange &lhs, const prange &,
1931 const prange &) const
1932{
1933 if (lhs.undefined_p ())
1934 return VREL_UNDEFINED;
1935
1936 // FALSE = op1 >= op2 indicates LT_EXPR.
1937 if (lhs.zero_p ())
1938 return VREL_LT;
1939
1940 // TRUE = op1 >= op2 indicates GE_EXPR.
1941 if (!range_includes_zero_p (lhs))
1942 return VREL_GE;
1943 return VREL_VARYING;
1944}
1945
1946bool
1947operator_ge::pointers_handled_p (range_op_dispatch_type type,
1948 unsigned dispatch) const
1949{
1950 switch (type)
1951 {
1952 case DISPATCH_FOLD_RANGE:
1953 return dispatch == RO_IPP;
1954 case DISPATCH_OP1_RANGE:
1955 case DISPATCH_OP2_RANGE:
1956 return dispatch == RO_PIP;
1957 case DISPATCH_OP1_OP2_RELATION:
1958 return dispatch == RO_IPP;
1959 default:
1960 return true;
1961 }
1962}
1963
f6e160e3
AM
1964// Initialize any pointer operators to the primary table
1965
1966void
1967range_op_table::initialize_pointer_ops ()
1968{
1969 set (POINTER_PLUS_EXPR, op_pointer_plus);
1970 set (POINTER_DIFF_EXPR, op_pointer_diff);
1971}