1 /* Code for range operators.
2 Copyright (C) 2017-2025 Free Software Foundation, Inc.
3 Contributed by Andrew MacLeod <amacleod@redhat.com>
4 and Aldy Hernandez <aldyh@redhat.com>.
6 This file is part of GCC.
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)
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.
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/>. */
24 #include "coretypes.h"
26 #include "insn-codes.h"
31 #include "tree-pass.h"
33 #include "optabs-tree.h"
34 #include "gimple-pretty-print.h"
35 #include "diagnostic-core.h"
37 #include "fold-const.h"
38 #include "stor-layout.h"
41 #include "gimple-iterator.h"
42 #include "gimple-fold.h"
44 #include "gimple-walk.h"
47 #include "value-relation.h"
49 #include "tree-ssa-ccp.h"
50 #include "range-op-mixed.h"
53 range_operator::fold_range (prange
&, tree
, const prange
&, const prange
&,
60 range_operator::fold_range (prange
&, tree
, const prange
&, const irange
&,
67 range_operator::fold_range (irange
&, tree
, const prange
&, const prange
&,
74 range_operator::fold_range (prange
&, tree
, const irange
&, const prange
&,
81 range_operator::fold_range (irange
&, tree
, const prange
&, const irange
&,
88 range_operator::op1_op2_relation_effect (prange
&, tree
,
97 range_operator::op1_op2_relation_effect (prange
&, tree
,
106 range_operator::op1_op2_relation_effect (irange
&, tree
,
115 range_operator::op1_op2_relation_effect (prange
&, tree
,
124 range_operator::op1_op2_relation_effect (irange
&, tree
,
133 range_operator::op1_range (prange
&, tree
,
134 const prange
&lhs ATTRIBUTE_UNUSED
,
135 const prange
&op2 ATTRIBUTE_UNUSED
,
142 range_operator::op1_range (prange
&, tree
,
143 const irange
&lhs ATTRIBUTE_UNUSED
,
144 const prange
&op2 ATTRIBUTE_UNUSED
,
151 range_operator::op1_range (prange
&, tree
,
152 const prange
&lhs ATTRIBUTE_UNUSED
,
153 const irange
&op2 ATTRIBUTE_UNUSED
,
160 range_operator::op1_range (irange
&, tree
,
161 const prange
&lhs ATTRIBUTE_UNUSED
,
162 const irange
&op2 ATTRIBUTE_UNUSED
,
169 range_operator::op2_range (prange
&, tree
,
170 const irange
&lhs ATTRIBUTE_UNUSED
,
171 const prange
&op1 ATTRIBUTE_UNUSED
,
178 range_operator::op2_range (irange
&, tree
,
179 const prange
&lhs ATTRIBUTE_UNUSED
,
180 const prange
&op1 ATTRIBUTE_UNUSED
,
187 range_operator::op1_op2_relation (const irange
&lhs ATTRIBUTE_UNUSED
,
188 const prange
&op1 ATTRIBUTE_UNUSED
,
189 const prange
&op2 ATTRIBUTE_UNUSED
) const
195 range_operator::lhs_op1_relation (const prange
&lhs ATTRIBUTE_UNUSED
,
196 const irange
&op1 ATTRIBUTE_UNUSED
,
197 const irange
&op2 ATTRIBUTE_UNUSED
,
198 relation_kind rel ATTRIBUTE_UNUSED
) const
204 range_operator::lhs_op1_relation (const irange
&lhs ATTRIBUTE_UNUSED
,
205 const prange
&op1 ATTRIBUTE_UNUSED
,
206 const prange
&op2 ATTRIBUTE_UNUSED
,
207 relation_kind rel ATTRIBUTE_UNUSED
) const
213 range_operator::lhs_op1_relation (const prange
&lhs ATTRIBUTE_UNUSED
,
214 const prange
&op1 ATTRIBUTE_UNUSED
,
215 const prange
&op2 ATTRIBUTE_UNUSED
,
216 relation_kind rel ATTRIBUTE_UNUSED
) const
222 range_operator::update_bitmask (irange
&,
224 const prange
&) const
228 // Return the upper limit for a type.
230 static inline wide_int
231 max_limit (const_tree type
)
233 return wi::max_value (TYPE_PRECISION (type
), TYPE_SIGN (type
));
236 // Return the lower limit for a type.
238 static inline wide_int
239 min_limit (const_tree type
)
241 return wi::min_value (TYPE_PRECISION (type
), TYPE_SIGN (type
));
244 // Build a range that is < VAL and store it in R.
247 build_lt (prange
&r
, tree type
, const prange
&val
)
249 wi::overflow_type ov
;
250 wide_int lim
= wi::sub (val
.upper_bound (), 1, UNSIGNED
, &ov
);
252 // If val - 1 underflows, check if X < MIN, which is an empty range.
256 r
.set (type
, min_limit (type
), lim
);
259 // Build a range that is <= VAL and store it in R.
262 build_le (prange
&r
, tree type
, const prange
&val
)
264 r
.set (type
, min_limit (type
), val
.upper_bound ());
267 // Build a range that is > VAL and store it in R.
270 build_gt (prange
&r
, tree type
, const prange
&val
)
272 wi::overflow_type ov
;
273 wide_int lim
= wi::add (val
.lower_bound (), 1, UNSIGNED
, &ov
);
275 // If val + 1 overflows, check is for X > MAX, which is an empty range.
279 r
.set (type
, lim
, max_limit (type
));
283 // Build a range that is >= VAL and store it in R.
286 build_ge (prange
&r
, tree type
, const prange
&val
)
288 r
.set (type
, val
.lower_bound (), max_limit (type
));
291 class pointer_plus_operator
: public range_operator
293 using range_operator::update_bitmask
;
294 using range_operator::fold_range
;
295 using range_operator::op2_range
;
297 virtual bool fold_range (prange
&r
, tree type
,
300 relation_trio
) const final override
;
301 virtual bool op2_range (irange
&r
, tree type
,
304 relation_trio
= TRIO_VARYING
) const final override
;
305 void update_bitmask (prange
&r
, const prange
&lh
, const irange
&rh
) const
306 { update_known_bitmask (r
, POINTER_PLUS_EXPR
, lh
, rh
); }
310 pointer_plus_operator::fold_range (prange
&r
, tree type
,
315 if (empty_range_varying (r
, type
, op1
, op2
))
318 const wide_int lh_lb
= op1
.lower_bound ();
319 const wide_int lh_ub
= op1
.upper_bound ();
320 const wide_int rh_lb
= op2
.lower_bound ();
321 const wide_int rh_ub
= op2
.upper_bound ();
323 // Check for [0,0] + const, and simply return the const.
324 if (lh_lb
== 0 && lh_ub
== 0 && rh_lb
== rh_ub
)
326 r
.set (type
, rh_lb
, rh_lb
);
330 // For pointer types, we are really only interested in asserting
331 // whether the expression evaluates to non-NULL.
333 // With -fno-delete-null-pointer-checks we need to be more
334 // conservative. As some object might reside at address 0,
335 // then some offset could be added to it and the same offset
336 // subtracted again and the result would be NULL.
338 // static int a[12]; where &a[0] is NULL and
341 // ptr will be NULL here, even when there is POINTER_PLUS_EXPR
342 // where the first range doesn't include zero and the second one
343 // doesn't either. As the second operand is sizetype (unsigned),
344 // consider all ranges where the MSB could be set as possible
345 // subtractions where the result might be NULL.
346 if ((!wi_includes_zero_p (type
, lh_lb
, lh_ub
)
347 || !wi_includes_zero_p (type
, rh_lb
, rh_ub
))
348 && !TYPE_OVERFLOW_WRAPS (type
)
349 && (flag_delete_null_pointer_checks
350 || !wi::sign_mask (rh_ub
)))
351 r
.set_nonzero (type
);
352 else if (lh_lb
== lh_ub
&& lh_lb
== 0
353 && rh_lb
== rh_ub
&& rh_lb
== 0)
356 r
.set_varying (type
);
358 update_known_bitmask (r
, POINTER_PLUS_EXPR
, op1
, op2
);
363 pointer_plus_operator::op2_range (irange
&r
, tree type
,
364 const prange
&lhs ATTRIBUTE_UNUSED
,
365 const prange
&op1 ATTRIBUTE_UNUSED
,
366 relation_trio trio
) const
368 relation_kind rel
= trio
.lhs_op1 ();
369 r
.set_varying (type
);
371 // If the LHS and OP1 are equal, the op2 must be zero.
374 // If the LHS and OP1 are not equal, the offset must be non-zero.
375 else if (rel
== VREL_NE
)
376 r
.set_nonzero (type
);
383 operator_bitwise_or::fold_range (prange
&r
, tree type
,
388 // For pointer types, we are really only interested in asserting
389 // whether the expression evaluates to non-NULL.
390 if (!range_includes_zero_p (op1
) || !range_includes_zero_p (op2
))
391 r
.set_nonzero (type
);
392 else if (op1
.zero_p () && op2
.zero_p ())
395 r
.set_varying (type
);
397 update_known_bitmask (r
, BIT_IOR_EXPR
, op1
, op2
);
402 class operator_pointer_diff
: public range_operator
404 using range_operator::fold_range
;
405 using range_operator::update_bitmask
;
406 using range_operator::op1_op2_relation_effect
;
407 virtual bool fold_range (irange
&r
, tree type
,
410 relation_trio trio
) const final override
;
411 virtual bool op1_op2_relation_effect (irange
&lhs_range
,
413 const prange
&op1_range
,
414 const prange
&op2_range
,
415 relation_kind rel
) const final override
;
416 void update_bitmask (irange
&r
,
417 const prange
&lh
, const prange
&rh
) const final override
418 { update_known_bitmask (r
, POINTER_DIFF_EXPR
, lh
, rh
); }
422 operator_pointer_diff::fold_range (irange
&r
, tree type
,
425 relation_trio trio
) const
427 gcc_checking_assert (r
.supports_type_p (type
));
429 r
.set_varying (type
);
430 relation_kind rel
= trio
.op1_op2 ();
431 op1_op2_relation_effect (r
, type
, op1
, op2
, rel
);
432 update_bitmask (r
, op1
, op2
);
437 operator_pointer_diff::op1_op2_relation_effect (irange
&lhs_range
, tree type
,
438 const prange
&op1_range
,
439 const prange
&op2_range
,
440 relation_kind rel
) const
442 int_range
<2> op1
, op2
, tmp
;
443 range_op_handler
cast (CONVERT_EXPR
);
445 if (!cast
.fold_range (op1
, type
, op1_range
, tmp
)
446 || !cast
.fold_range (op2
, type
, op2_range
, tmp
))
449 return minus_op1_op2_relation_effect (lhs_range
, type
, op1
, op2
, rel
);
453 operator_identity::fold_range (prange
&r
, tree type ATTRIBUTE_UNUSED
,
454 const prange
&lh ATTRIBUTE_UNUSED
,
455 const prange
&rh ATTRIBUTE_UNUSED
,
463 operator_identity::lhs_op1_relation (const prange
&lhs
,
464 const prange
&op1 ATTRIBUTE_UNUSED
,
465 const prange
&op2 ATTRIBUTE_UNUSED
,
468 if (lhs
.undefined_p ())
470 // Simply a copy, so they are equivalent.
475 operator_identity::op1_range (prange
&r
, tree type ATTRIBUTE_UNUSED
,
477 const prange
&op2 ATTRIBUTE_UNUSED
,
485 operator_cst::fold_range (prange
&r
, tree type ATTRIBUTE_UNUSED
,
487 const prange
& ATTRIBUTE_UNUSED
,
494 // Cast between pointers.
497 operator_cast::fold_range (prange
&r
, tree type
,
502 if (empty_range_varying (r
, type
, inner
, outer
))
505 r
.set (type
, inner
.lower_bound (), inner
.upper_bound ());
506 r
.update_bitmask (inner
.get_bitmask ());
510 // Cast a pointer to an integer.
513 operator_cast::fold_range (irange
&r
, tree type
,
518 if (empty_range_varying (r
, type
, inner
, outer
))
521 // Represent INNER as an integer of the same size, and then cast it
522 // to the resulting integer type.
523 tree pointer_uint_type
= make_unsigned_type (TYPE_PRECISION (inner
.type ()));
524 r
.set (pointer_uint_type
, inner
.lower_bound (), inner
.upper_bound ());
525 r
.update_bitmask (inner
.get_bitmask ());
526 range_cast (r
, type
);
530 // Cast an integer to a pointer.
533 operator_cast::fold_range (prange
&r
, tree type
,
538 if (empty_range_varying (r
, type
, inner
, outer
))
541 // Cast INNER to an integer of the same size as the pointer we want,
542 // and then copy the bounds to the resulting pointer range.
543 int_range
<2> tmp
= inner
;
544 tree pointer_uint_type
= make_unsigned_type (TYPE_PRECISION (type
));
545 range_cast (tmp
, pointer_uint_type
);
546 r
.set (type
, tmp
.lower_bound (), tmp
.upper_bound ());
547 r
.update_bitmask (tmp
.get_bitmask ());
552 operator_cast::op1_range (prange
&r
, tree type
,
555 relation_trio trio
) const
557 if (lhs
.undefined_p ())
559 gcc_checking_assert (types_compatible_p (op2
.type(), type
));
561 // Conversion from other pointers or a constant (including 0/NULL)
562 // are straightforward.
563 if (POINTER_TYPE_P (lhs
.type ())
564 || (lhs
.singleton_p ()
565 && TYPE_PRECISION (lhs
.type ()) >= TYPE_PRECISION (type
)))
566 fold_range (r
, type
, lhs
, op2
, trio
);
569 // If the LHS is not a pointer nor a singleton, then it is
570 // either VARYING or non-zero.
571 if (!lhs
.undefined_p () && !range_includes_zero_p (lhs
))
572 r
.set_nonzero (type
);
574 r
.set_varying (type
);
581 operator_cast::op1_range (irange
&r
, tree type
,
584 relation_trio trio
) const
586 if (lhs
.undefined_p ())
588 gcc_checking_assert (types_compatible_p (op2
.type(), type
));
590 // Conversion from other pointers or a constant (including 0/NULL)
591 // are straightforward.
592 if (POINTER_TYPE_P (lhs
.type ())
593 || (lhs
.singleton_p ()
594 && TYPE_PRECISION (lhs
.type ()) >= TYPE_PRECISION (type
)))
595 fold_range (r
, type
, lhs
, op2
, trio
);
598 // If the LHS is not a pointer nor a singleton, then it is
599 // either VARYING or non-zero.
600 if (!lhs
.undefined_p () && !range_includes_zero_p (lhs
))
601 r
.set_nonzero (type
);
603 r
.set_varying (type
);
610 operator_cast::op1_range (prange
&r
, tree type
,
613 relation_trio trio
) const
615 if (lhs
.undefined_p ())
617 gcc_checking_assert (types_compatible_p (op2
.type(), type
));
619 // Conversion from other pointers or a constant (including 0/NULL)
620 // are straightforward.
621 if (POINTER_TYPE_P (lhs
.type ())
622 || (lhs
.singleton_p ()
623 && TYPE_PRECISION (lhs
.type ()) >= TYPE_PRECISION (type
)))
624 fold_range (r
, type
, lhs
, op2
, trio
);
627 // If the LHS is not a pointer nor a singleton, then it is
628 // either VARYING or non-zero.
629 if (!lhs
.undefined_p () && !range_includes_zero_p (lhs
))
630 r
.set_nonzero (type
);
632 r
.set_varying (type
);
639 operator_cast::lhs_op1_relation (const prange
&lhs
,
641 const prange
&op2 ATTRIBUTE_UNUSED
,
644 if (lhs
.undefined_p () || op1
.undefined_p ())
646 unsigned lhs_prec
= TYPE_PRECISION (lhs
.type ());
647 unsigned op1_prec
= TYPE_PRECISION (op1
.type ());
648 // If the result gets sign extended into a larger type check first if this
649 // qualifies as a partial equivalence.
650 if (TYPE_SIGN (op1
.type ()) == SIGNED
&& lhs_prec
> op1_prec
)
652 // If the result is sign extended, and the LHS is larger than op1,
653 // check if op1's range can be negative as the sign extension will
654 // cause the upper bits to be 1 instead of 0, invalidating the PE.
655 int_range
<3> negs
= range_negatives (op1
.type ());
656 negs
.intersect (op1
);
657 if (!negs
.undefined_p ())
661 unsigned prec
= MIN (lhs_prec
, op1_prec
);
662 return bits_to_pe (prec
);
666 operator_cast::lhs_op1_relation (const prange
&lhs
,
668 const irange
&op2 ATTRIBUTE_UNUSED
,
671 if (lhs
.undefined_p () || op1
.undefined_p ())
673 unsigned lhs_prec
= TYPE_PRECISION (lhs
.type ());
674 unsigned op1_prec
= TYPE_PRECISION (op1
.type ());
675 // If the result gets sign extended into a larger type check first if this
676 // qualifies as a partial equivalence.
677 if (TYPE_SIGN (op1
.type ()) == SIGNED
&& lhs_prec
> op1_prec
)
679 // If the result is sign extended, and the LHS is larger than op1,
680 // check if op1's range can be negative as the sign extension will
681 // cause the upper bits to be 1 instead of 0, invalidating the PE.
682 int_range
<3> negs
= range_negatives (op1
.type ());
683 negs
.intersect (op1
);
684 if (!negs
.undefined_p ())
688 unsigned prec
= MIN (lhs_prec
, op1_prec
);
689 return bits_to_pe (prec
);
693 operator_cast::lhs_op1_relation (const irange
&lhs
,
695 const prange
&op2 ATTRIBUTE_UNUSED
,
698 if (lhs
.undefined_p () || op1
.undefined_p ())
700 unsigned lhs_prec
= TYPE_PRECISION (lhs
.type ());
701 unsigned op1_prec
= TYPE_PRECISION (op1
.type ());
702 // If the result gets sign extended into a larger type check first if this
703 // qualifies as a partial equivalence.
704 if (TYPE_SIGN (op1
.type ()) == SIGNED
&& lhs_prec
> op1_prec
)
706 // If the result is sign extended, and the LHS is larger than op1,
707 // check if op1's range can be negative as the sign extension will
708 // cause the upper bits to be 1 instead of 0, invalidating the PE.
709 int_range
<3> negs
= range_negatives (op1
.type ());
710 negs
.intersect (op1
);
711 if (!negs
.undefined_p ())
715 unsigned prec
= MIN (lhs_prec
, op1_prec
);
716 return bits_to_pe (prec
);
720 operator_min::fold_range (prange
&r
, tree type
,
725 // For MIN/MAX expressions with pointers, we only care about
726 // nullness. If both are non null, then the result is nonnull.
727 // If both are null, then the result is null. Otherwise they
729 if (!range_includes_zero_p (op1
)
730 && !range_includes_zero_p (op2
))
731 r
.set_nonzero (type
);
732 else if (op1
.zero_p () && op2
.zero_p ())
735 r
.set_varying (type
);
737 update_known_bitmask (r
, MIN_EXPR
, op1
, op2
);
742 operator_max::fold_range (prange
&r
, tree type
,
747 // For MIN/MAX expressions with pointers, we only care about
748 // nullness. If both are non null, then the result is nonnull.
749 // If both are null, then the result is null. Otherwise they
751 if (!range_includes_zero_p (op1
)
752 && !range_includes_zero_p (op2
))
753 r
.set_nonzero (type
);
754 else if (op1
.zero_p () && op2
.zero_p ())
757 r
.set_varying (type
);
759 update_known_bitmask (r
, MAX_EXPR
, op1
, op2
);
764 operator_addr_expr::op1_range (prange
&r
, tree type
,
769 if (empty_range_varying (r
, type
, lhs
, op2
))
772 // Return a non-null pointer of the LHS type (passed in op2), but only
773 // if we cant overflow, eitherwise a no-zero offset could wrap to zero.
775 if (!lhs
.undefined_p ()
776 && !range_includes_zero_p (lhs
)
777 && TYPE_OVERFLOW_UNDEFINED (type
))
778 r
.set_nonzero (type
);
780 r
.set_varying (type
);
785 operator_bitwise_and::fold_range (prange
&r
, tree type
,
787 const prange
&op2 ATTRIBUTE_UNUSED
,
790 // For pointer types, we are really only interested in asserting
791 // whether the expression evaluates to non-NULL.
792 if (op1
.zero_p () || op2
.zero_p ())
795 r
.set_varying (type
);
797 update_known_bitmask (r
, BIT_AND_EXPR
, op1
, op2
);
802 operator_equal::fold_range (irange
&r
, tree type
,
805 relation_trio rel
) const
807 if (relop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_EQ
))
810 // We can be sure the values are always equal or not if both ranges
811 // consist of a single value, and then compare them.
812 bool op1_const
= wi::eq_p (op1
.lower_bound (), op1
.upper_bound ());
813 bool op2_const
= wi::eq_p (op2
.lower_bound (), op2
.upper_bound ());
814 if (op1_const
&& op2_const
)
816 if (wi::eq_p (op1
.lower_bound (), op2
.upper_bound()))
817 r
= range_true (type
);
819 r
= range_false (type
);
823 // If ranges do not intersect, we know the range is not equal,
824 // otherwise we don't know anything for sure.
827 if (tmp
.undefined_p ())
828 r
= range_false (type
);
829 // Check if a constant cannot satisfy the bitmask requirements.
830 else if (op2_const
&& !op1
.get_bitmask ().member_p (op2
.lower_bound ()))
831 r
= range_false (type
);
832 else if (op1_const
&& !op2
.get_bitmask ().member_p (op1
.lower_bound ()))
833 r
= range_false (type
);
835 r
= range_true_and_false (type
);
838 //update_known_bitmask (r, EQ_EXPR, op1, op2);
843 operator_equal::op1_range (prange
&r
, tree type
,
848 switch (get_bool_state (r
, lhs
, type
))
851 // If it's true, the result is the same as OP2.
856 // If the result is false, the only time we know anything is
857 // if OP2 is a constant.
858 if (!op2
.undefined_p ()
859 && wi::eq_p (op2
.lower_bound(), op2
.upper_bound()))
865 r
.set_varying (type
);
875 operator_equal::op2_range (prange
&r
, tree type
,
878 relation_trio rel
) const
880 return operator_equal::op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
884 operator_equal::op1_op2_relation (const irange
&lhs
, const prange
&,
885 const prange
&) const
887 if (lhs
.undefined_p ())
888 return VREL_UNDEFINED
;
890 // FALSE = op1 == op2 indicates NE_EXPR.
894 // TRUE = op1 == op2 indicates EQ_EXPR.
895 if (!range_includes_zero_p (lhs
))
901 operator_not_equal::fold_range (irange
&r
, tree type
,
904 relation_trio rel
) const
906 if (relop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_NE
))
909 // We can be sure the values are always equal or not if both ranges
910 // consist of a single value, and then compare them.
911 bool op1_const
= wi::eq_p (op1
.lower_bound (), op1
.upper_bound ());
912 bool op2_const
= wi::eq_p (op2
.lower_bound (), op2
.upper_bound ());
913 if (op1_const
&& op2_const
)
915 if (wi::ne_p (op1
.lower_bound (), op2
.upper_bound()))
916 r
= range_true (type
);
918 r
= range_false (type
);
922 // If ranges do not intersect, we know the range is not equal,
923 // otherwise we don't know anything for sure.
926 if (tmp
.undefined_p ())
927 r
= range_true (type
);
928 // Check if a constant cannot satisfy the bitmask requirements.
929 else if (op2_const
&& !op1
.get_bitmask ().member_p (op2
.lower_bound ()))
930 r
= range_true (type
);
931 else if (op1_const
&& !op2
.get_bitmask ().member_p (op1
.lower_bound ()))
932 r
= range_true (type
);
934 r
= range_true_and_false (type
);
937 //update_known_bitmask (r, NE_EXPR, op1, op2);
942 operator_not_equal::op1_range (prange
&r
, tree type
,
947 switch (get_bool_state (r
, lhs
, type
))
950 // If the result is true, the only time we know anything is if
951 // OP2 is a constant.
952 if (!op2
.undefined_p ()
953 && wi::eq_p (op2
.lower_bound(), op2
.upper_bound()))
959 r
.set_varying (type
);
963 // If it's false, the result is the same as OP2.
975 operator_not_equal::op2_range (prange
&r
, tree type
,
978 relation_trio rel
) const
980 return operator_not_equal::op1_range (r
, type
, lhs
, op1
, rel
.swap_op1_op2 ());
984 operator_not_equal::op1_op2_relation (const irange
&lhs
, const prange
&,
985 const prange
&) const
987 if (lhs
.undefined_p ())
988 return VREL_UNDEFINED
;
990 // FALSE = op1 != op2 indicates EQ_EXPR.
994 // TRUE = op1 != op2 indicates NE_EXPR.
995 if (!range_includes_zero_p (lhs
))
1001 operator_lt::fold_range (irange
&r
, tree type
,
1004 relation_trio rel
) const
1006 if (relop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_LT
))
1009 signop sign
= TYPE_SIGN (op1
.type ());
1010 gcc_checking_assert (sign
== TYPE_SIGN (op2
.type ()));
1012 if (wi::lt_p (op1
.upper_bound (), op2
.lower_bound (), sign
))
1013 r
= range_true (type
);
1014 else if (!wi::lt_p (op1
.lower_bound (), op2
.upper_bound (), sign
))
1015 r
= range_false (type
);
1016 // Use nonzero bits to determine if < 0 is false.
1017 else if (op2
.zero_p () && !wi::neg_p (op1
.get_nonzero_bits (), sign
))
1018 r
= range_false (type
);
1020 r
= range_true_and_false (type
);
1022 //update_known_bitmask (r, LT_EXPR, op1, op2);
1027 operator_lt::op1_range (prange
&r
, tree type
,
1030 relation_trio
) const
1032 if (op2
.undefined_p ())
1035 switch (get_bool_state (r
, lhs
, type
))
1038 build_lt (r
, type
, op2
);
1042 build_ge (r
, type
, op2
);
1052 operator_lt::op2_range (prange
&r
, tree type
,
1055 relation_trio
) const
1057 if (op1
.undefined_p ())
1060 switch (get_bool_state (r
, lhs
, type
))
1063 build_gt (r
, type
, op1
);
1067 build_le (r
, type
, op1
);
1077 operator_lt::op1_op2_relation (const irange
&lhs
, const prange
&,
1078 const prange
&) const
1080 if (lhs
.undefined_p ())
1081 return VREL_UNDEFINED
;
1083 // FALSE = op1 < op2 indicates GE_EXPR.
1087 // TRUE = op1 < op2 indicates LT_EXPR.
1088 if (!range_includes_zero_p (lhs
))
1090 return VREL_VARYING
;
1094 operator_le::fold_range (irange
&r
, tree type
,
1097 relation_trio rel
) const
1099 if (relop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_LE
))
1102 signop sign
= TYPE_SIGN (op1
.type ());
1103 gcc_checking_assert (sign
== TYPE_SIGN (op2
.type ()));
1105 if (wi::le_p (op1
.upper_bound (), op2
.lower_bound (), sign
))
1106 r
= range_true (type
);
1107 else if (!wi::le_p (op1
.lower_bound (), op2
.upper_bound (), sign
))
1108 r
= range_false (type
);
1110 r
= range_true_and_false (type
);
1112 //update_known_bitmask (r, LE_EXPR, op1, op2);
1117 operator_le::op1_range (prange
&r
, tree type
,
1120 relation_trio
) const
1122 if (op2
.undefined_p ())
1125 switch (get_bool_state (r
, lhs
, type
))
1128 build_le (r
, type
, op2
);
1132 build_gt (r
, type
, op2
);
1142 operator_le::op2_range (prange
&r
, tree type
,
1145 relation_trio
) const
1147 if (op1
.undefined_p ())
1150 switch (get_bool_state (r
, lhs
, type
))
1153 build_ge (r
, type
, op1
);
1157 build_lt (r
, type
, op1
);
1167 operator_le::op1_op2_relation (const irange
&lhs
, const prange
&,
1168 const prange
&) const
1170 if (lhs
.undefined_p ())
1171 return VREL_UNDEFINED
;
1173 // FALSE = op1 <= op2 indicates GT_EXPR.
1177 // TRUE = op1 <= op2 indicates LE_EXPR.
1178 if (!range_includes_zero_p (lhs
))
1180 return VREL_VARYING
;
1184 operator_gt::fold_range (irange
&r
, tree type
,
1185 const prange
&op1
, const prange
&op2
,
1186 relation_trio rel
) const
1188 if (relop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_GT
))
1191 signop sign
= TYPE_SIGN (op1
.type ());
1192 gcc_checking_assert (sign
== TYPE_SIGN (op2
.type ()));
1194 if (wi::gt_p (op1
.lower_bound (), op2
.upper_bound (), sign
))
1195 r
= range_true (type
);
1196 else if (!wi::gt_p (op1
.upper_bound (), op2
.lower_bound (), sign
))
1197 r
= range_false (type
);
1199 r
= range_true_and_false (type
);
1201 //update_known_bitmask (r, GT_EXPR, op1, op2);
1206 operator_gt::op1_range (prange
&r
, tree type
,
1207 const irange
&lhs
, const prange
&op2
,
1208 relation_trio
) const
1210 if (op2
.undefined_p ())
1213 switch (get_bool_state (r
, lhs
, type
))
1216 build_gt (r
, type
, op2
);
1220 build_le (r
, type
, op2
);
1230 operator_gt::op2_range (prange
&r
, tree type
,
1233 relation_trio
) const
1235 if (op1
.undefined_p ())
1238 switch (get_bool_state (r
, lhs
, type
))
1241 build_lt (r
, type
, op1
);
1245 build_ge (r
, type
, op1
);
1255 operator_gt::op1_op2_relation (const irange
&lhs
, const prange
&,
1256 const prange
&) const
1258 if (lhs
.undefined_p ())
1259 return VREL_UNDEFINED
;
1261 // FALSE = op1 > op2 indicates LE_EXPR.
1265 // TRUE = op1 > op2 indicates GT_EXPR.
1266 if (!range_includes_zero_p (lhs
))
1268 return VREL_VARYING
;
1272 operator_ge::fold_range (irange
&r
, tree type
,
1275 relation_trio rel
) const
1277 if (relop_early_resolve (r
, type
, op1
, op2
, rel
, VREL_GE
))
1280 signop sign
= TYPE_SIGN (op1
.type ());
1281 gcc_checking_assert (sign
== TYPE_SIGN (op2
.type ()));
1283 if (wi::ge_p (op1
.lower_bound (), op2
.upper_bound (), sign
))
1284 r
= range_true (type
);
1285 else if (!wi::ge_p (op1
.upper_bound (), op2
.lower_bound (), sign
))
1286 r
= range_false (type
);
1288 r
= range_true_and_false (type
);
1290 //update_known_bitmask (r, GE_EXPR, op1, op2);
1295 operator_ge::op1_range (prange
&r
, tree type
,
1298 relation_trio
) const
1300 if (op2
.undefined_p ())
1303 switch (get_bool_state (r
, lhs
, type
))
1306 build_ge (r
, type
, op2
);
1310 build_lt (r
, type
, op2
);
1320 operator_ge::op2_range (prange
&r
, tree type
,
1323 relation_trio
) const
1325 if (op1
.undefined_p ())
1328 switch (get_bool_state (r
, lhs
, type
))
1331 build_le (r
, type
, op1
);
1335 build_gt (r
, type
, op1
);
1345 operator_ge::op1_op2_relation (const irange
&lhs
, const prange
&,
1346 const prange
&) const
1348 if (lhs
.undefined_p ())
1349 return VREL_UNDEFINED
;
1351 // FALSE = op1 >= op2 indicates LT_EXPR.
1355 // TRUE = op1 >= op2 indicates GE_EXPR.
1356 if (!range_includes_zero_p (lhs
))
1358 return VREL_VARYING
;
1361 // Initialize any pointer operators to the primary table
1364 range_op_table::initialize_pointer_ops ()
1366 set (POINTER_PLUS_EXPR
, op_pointer_plus
);
1367 set (POINTER_DIFF_EXPR
, op_pointer_diff
);