Branch data Line data Source code
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>.
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-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 : :
52 : : bool
53 : 0 : range_operator::fold_range (prange &, tree, const prange &, const prange &,
54 : : relation_trio) const
55 : : {
56 : 0 : return false;
57 : : }
58 : :
59 : : bool
60 : 0 : range_operator::fold_range (prange &, tree, const prange &, const irange &,
61 : : relation_trio) const
62 : : {
63 : 0 : return false;
64 : : }
65 : :
66 : : bool
67 : 0 : range_operator::fold_range (irange &, tree, const prange &, const prange &,
68 : : relation_trio) const
69 : : {
70 : 0 : return false;
71 : : }
72 : :
73 : : bool
74 : 0 : range_operator::fold_range (prange &, tree, const irange &, const prange &,
75 : : relation_trio) const
76 : : {
77 : 0 : return false;
78 : : }
79 : :
80 : : bool
81 : 0 : range_operator::fold_range (irange &, tree, const prange &, const irange &,
82 : : relation_trio) const
83 : : {
84 : 0 : return false;
85 : : }
86 : :
87 : : bool
88 : 0 : range_operator::op1_op2_relation_effect (prange &, tree,
89 : : const prange &,
90 : : const prange &,
91 : : relation_kind) const
92 : : {
93 : 0 : return false;
94 : : }
95 : :
96 : : bool
97 : 0 : range_operator::op1_op2_relation_effect (prange &, tree,
98 : : const prange &,
99 : : const irange &,
100 : : relation_kind) const
101 : : {
102 : 0 : return false;
103 : : }
104 : :
105 : : bool
106 : 0 : range_operator::op1_op2_relation_effect (irange &, tree,
107 : : const prange &,
108 : : const prange &,
109 : : relation_kind) const
110 : : {
111 : 0 : return false;
112 : : }
113 : :
114 : : bool
115 : 0 : range_operator::op1_op2_relation_effect (prange &, tree,
116 : : const irange &,
117 : : const prange &,
118 : : relation_kind) const
119 : : {
120 : 0 : return false;
121 : : }
122 : :
123 : : bool
124 : 0 : range_operator::op1_op2_relation_effect (irange &, tree,
125 : : const prange &,
126 : : const irange &,
127 : : relation_kind) const
128 : : {
129 : 0 : return false;
130 : : }
131 : :
132 : : bool
133 : 112 : range_operator::op1_range (prange &, tree,
134 : : const prange &lhs ATTRIBUTE_UNUSED,
135 : : const prange &op2 ATTRIBUTE_UNUSED,
136 : : relation_trio) const
137 : : {
138 : 112 : return false;
139 : : }
140 : :
141 : : bool
142 : 548586 : range_operator::op1_range (prange &, tree,
143 : : const irange &lhs ATTRIBUTE_UNUSED,
144 : : const prange &op2 ATTRIBUTE_UNUSED,
145 : : relation_trio) const
146 : : {
147 : 548586 : return false;
148 : : }
149 : :
150 : : bool
151 : 304548 : range_operator::op1_range (prange &, tree,
152 : : const prange &lhs ATTRIBUTE_UNUSED,
153 : : const irange &op2 ATTRIBUTE_UNUSED,
154 : : relation_trio) const
155 : : {
156 : 304548 : return false;
157 : : }
158 : :
159 : : bool
160 : 0 : range_operator::op1_range (irange &, tree,
161 : : const prange &lhs ATTRIBUTE_UNUSED,
162 : : const irange &op2 ATTRIBUTE_UNUSED,
163 : : relation_trio) const
164 : : {
165 : 0 : return false;
166 : : }
167 : :
168 : : bool
169 : 706070 : range_operator::op2_range (prange &, tree,
170 : : const irange &lhs ATTRIBUTE_UNUSED,
171 : : const prange &op1 ATTRIBUTE_UNUSED,
172 : : relation_trio) const
173 : : {
174 : 706070 : return false;
175 : : }
176 : :
177 : : bool
178 : 0 : range_operator::op2_range (irange &, tree,
179 : : const prange &lhs ATTRIBUTE_UNUSED,
180 : : const prange &op1 ATTRIBUTE_UNUSED,
181 : : relation_trio) const
182 : : {
183 : 0 : return false;
184 : : }
185 : :
186 : : relation_kind
187 : 1206413 : range_operator::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
188 : : const prange &op1 ATTRIBUTE_UNUSED,
189 : : const prange &op2 ATTRIBUTE_UNUSED) const
190 : : {
191 : 1206413 : return VREL_VARYING;
192 : : }
193 : :
194 : : relation_kind
195 : 0 : 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
199 : : {
200 : 0 : return VREL_VARYING;
201 : : }
202 : :
203 : : relation_kind
204 : 2923228 : 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
208 : : {
209 : 2923228 : return VREL_VARYING;
210 : : }
211 : :
212 : : relation_kind
213 : 66757 : 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
217 : : {
218 : 66757 : return VREL_VARYING;
219 : : }
220 : :
221 : : void
222 : 0 : range_operator::update_bitmask (irange &,
223 : : const prange &,
224 : : const prange &) const
225 : : {
226 : 0 : }
227 : :
228 : : // Return the upper limit for a type.
229 : :
230 : : static inline wide_int
231 : 497386 : max_limit (const_tree type)
232 : : {
233 : 497386 : return wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
234 : : }
235 : :
236 : : // Return the lower limit for a type.
237 : :
238 : : static inline wide_int
239 : 509511 : min_limit (const_tree type)
240 : : {
241 : 509511 : return wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
242 : : }
243 : :
244 : : // Build a range that is < VAL and store it in R.
245 : :
246 : : static void
247 : 343605 : build_lt (prange &r, tree type, const prange &val)
248 : : {
249 : 343605 : wi::overflow_type ov;
250 : 343605 : wide_int lim = wi::sub (val.upper_bound (), 1, UNSIGNED, &ov);
251 : :
252 : : // If val - 1 underflows, check if X < MIN, which is an empty range.
253 : 343605 : if (ov)
254 : 0 : r.set_undefined ();
255 : : else
256 : 343605 : r.set (type, min_limit (type), lim);
257 : 343605 : }
258 : :
259 : : // Build a range that is <= VAL and store it in R.
260 : :
261 : : static void
262 : 165906 : build_le (prange &r, tree type, const prange &val)
263 : : {
264 : 165906 : r.set (type, min_limit (type), val.upper_bound ());
265 : 165906 : }
266 : :
267 : : // Build a range that is > VAL and store it in R.
268 : :
269 : : static void
270 : 264512 : build_gt (prange &r, tree type, const prange &val)
271 : : {
272 : 264512 : wi::overflow_type ov;
273 : 264512 : wide_int lim = wi::add (val.lower_bound (), 1, UNSIGNED, &ov);
274 : :
275 : : // If val + 1 overflows, check is for X > MAX, which is an empty range.
276 : 264512 : if (ov)
277 : 0 : r.set_undefined ();
278 : : else
279 : 264512 : r.set (type, lim, max_limit (type));
280 : :
281 : 264512 : }
282 : :
283 : : // Build a range that is >= VAL and store it in R.
284 : :
285 : : static void
286 : 232874 : build_ge (prange &r, tree type, const prange &val)
287 : : {
288 : 232874 : r.set (type, val.lower_bound (), max_limit (type));
289 : 232874 : }
290 : :
291 : : class pointer_plus_operator : public range_operator
292 : : {
293 : : using range_operator::update_bitmask;
294 : : using range_operator::fold_range;
295 : : using range_operator::op2_range;
296 : : public:
297 : : virtual bool fold_range (prange &r, tree type,
298 : : const prange &op1,
299 : : const irange &op2,
300 : : relation_trio) const final override;
301 : : virtual bool op2_range (irange &r, tree type,
302 : : const prange &lhs,
303 : : const prange &op1,
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); }
307 : : } op_pointer_plus;
308 : :
309 : : bool
310 : 7810501 : pointer_plus_operator::fold_range (prange &r, tree type,
311 : : const prange &op1,
312 : : const irange &op2,
313 : : relation_trio) const
314 : : {
315 : 7810501 : if (empty_range_varying (r, type, op1, op2))
316 : 4080 : return true;
317 : :
318 : 7806421 : const wide_int lh_lb = op1.lower_bound ();
319 : 7806421 : const wide_int lh_ub = op1.upper_bound ();
320 : 7806421 : const wide_int rh_lb = op2.lower_bound ();
321 : 7806421 : const wide_int rh_ub = op2.upper_bound ();
322 : :
323 : : // Check for [0,0] + const, and simply return the const.
324 : 7814497 : if (lh_lb == 0 && lh_ub == 0 && rh_lb == rh_ub)
325 : : {
326 : 579 : r.set (type, rh_lb, rh_lb);
327 : 579 : return true;
328 : : }
329 : :
330 : : // For pointer types, we are really only interested in asserting
331 : : // whether the expression evaluates to non-NULL.
332 : : //
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.
337 : : // E.g.
338 : : // static int a[12]; where &a[0] is NULL and
339 : : // ptr = &a[6];
340 : : // ptr -= 6;
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 : 7805842 : if ((!wi_includes_zero_p (type, lh_lb, lh_ub)
347 : 4720811 : || !wi_includes_zero_p (type, rh_lb, rh_ub))
348 : 4876128 : && !TYPE_OVERFLOW_WRAPS (type)
349 : 12681322 : && (flag_delete_null_pointer_checks
350 : 1093 : || !wi::sign_mask (rh_ub)))
351 : 4875135 : r.set_nonzero (type);
352 : 2937138 : else if (lh_lb == lh_ub && lh_lb == 0
353 : 2937138 : && rh_lb == rh_ub && rh_lb == 0)
354 : 0 : r.set_zero (type);
355 : : else
356 : 2930707 : r.set_varying (type);
357 : :
358 : 7805842 : update_known_bitmask (r, POINTER_PLUS_EXPR, op1, op2);
359 : 7805842 : return true;
360 : 7806421 : }
361 : :
362 : : bool
363 : 144997 : 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
367 : : {
368 : 144997 : relation_kind rel = trio.lhs_op1 ();
369 : 144997 : r.set_varying (type);
370 : :
371 : : // If the LHS and OP1 are equal, the op2 must be zero.
372 : 144997 : if (rel == VREL_EQ)
373 : 7616 : r.set_zero (type);
374 : : // If the LHS and OP1 are not equal, the offset must be non-zero.
375 : 137381 : else if (rel == VREL_NE)
376 : 10726 : r.set_nonzero (type);
377 : : else
378 : : return false;
379 : : return true;
380 : : }
381 : :
382 : : bool
383 : 0 : operator_bitwise_or::fold_range (prange &r, tree type,
384 : : const prange &op1,
385 : : const prange &op2,
386 : : relation_trio) const
387 : : {
388 : : // For pointer types, we are really only interested in asserting
389 : : // whether the expression evaluates to non-NULL.
390 : 0 : if (!range_includes_zero_p (op1) || !range_includes_zero_p (op2))
391 : 0 : r.set_nonzero (type);
392 : 0 : else if (op1.zero_p () && op2.zero_p ())
393 : 0 : r.set_zero (type);
394 : : else
395 : 0 : r.set_varying (type);
396 : :
397 : 0 : update_known_bitmask (r, BIT_IOR_EXPR, op1, op2);
398 : 0 : return true;
399 : : }
400 : :
401 : :
402 : : class operator_pointer_diff : public range_operator
403 : : {
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,
408 : : const prange &op1,
409 : : const prange &op2,
410 : : relation_trio trio) const final override;
411 : : virtual bool op1_op2_relation_effect (irange &lhs_range,
412 : : tree type,
413 : : const prange &op1_range,
414 : : const prange &op2_range,
415 : : relation_kind rel) const final override;
416 : 1851449 : void update_bitmask (irange &r,
417 : : const prange &lh, const prange &rh) const final override
418 : 0 : { update_known_bitmask (r, POINTER_DIFF_EXPR, lh, rh); }
419 : : } op_pointer_diff;
420 : :
421 : : bool
422 : 1851449 : operator_pointer_diff::fold_range (irange &r, tree type,
423 : : const prange &op1,
424 : : const prange &op2,
425 : : relation_trio trio) const
426 : : {
427 : 1851449 : gcc_checking_assert (r.supports_type_p (type));
428 : :
429 : 1851449 : r.set_varying (type);
430 : 1851449 : relation_kind rel = trio.op1_op2 ();
431 : 1851449 : op1_op2_relation_effect (r, type, op1, op2, rel);
432 : 1851449 : update_bitmask (r, op1, op2);
433 : 1851449 : return true;
434 : : }
435 : :
436 : : bool
437 : 1851449 : 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
441 : : {
442 : 1851449 : int_range<2> op1, op2, tmp;
443 : 1851449 : range_op_handler cast (CONVERT_EXPR);
444 : :
445 : 1851449 : if (!cast.fold_range (op1, type, op1_range, tmp)
446 : 1851449 : || !cast.fold_range (op2, type, op2_range, tmp))
447 : 0 : return false;
448 : :
449 : 1851449 : return minus_op1_op2_relation_effect (lhs_range, type, op1, op2, rel);
450 : 1851449 : }
451 : :
452 : : bool
453 : 966412 : operator_identity::fold_range (prange &r, tree type ATTRIBUTE_UNUSED,
454 : : const prange &lh ATTRIBUTE_UNUSED,
455 : : const prange &rh ATTRIBUTE_UNUSED,
456 : : relation_trio) const
457 : : {
458 : 966412 : r = lh;
459 : 966412 : return true;
460 : : }
461 : :
462 : : relation_kind
463 : 907704 : operator_identity::lhs_op1_relation (const prange &lhs,
464 : : const prange &op1 ATTRIBUTE_UNUSED,
465 : : const prange &op2 ATTRIBUTE_UNUSED,
466 : : relation_kind) const
467 : : {
468 : 907704 : if (lhs.undefined_p ())
469 : 419 : return VREL_VARYING;
470 : : // Simply a copy, so they are equivalent.
471 : : return VREL_EQ;
472 : : }
473 : :
474 : : bool
475 : 138765 : operator_identity::op1_range (prange &r, tree type ATTRIBUTE_UNUSED,
476 : : const prange &lhs,
477 : : const prange &op2 ATTRIBUTE_UNUSED,
478 : : relation_trio) const
479 : : {
480 : 138765 : r = lhs;
481 : 138765 : return true;
482 : : }
483 : :
484 : : bool
485 : 19435 : operator_cst::fold_range (prange &r, tree type ATTRIBUTE_UNUSED,
486 : : const prange &lh,
487 : : const prange & ATTRIBUTE_UNUSED,
488 : : relation_trio) const
489 : : {
490 : 19435 : r = lh;
491 : 19435 : return true;
492 : : }
493 : :
494 : : // Cast between pointers.
495 : :
496 : : bool
497 : 13726523 : operator_cast::fold_range (prange &r, tree type,
498 : : const prange &inner,
499 : : const prange &outer,
500 : : relation_trio) const
501 : : {
502 : 13726523 : if (empty_range_varying (r, type, inner, outer))
503 : 480 : return true;
504 : :
505 : 13726043 : r.set (type, inner.lower_bound (), inner.upper_bound ());
506 : 13726043 : r.update_bitmask (inner.get_bitmask ());
507 : 13726043 : return true;
508 : : }
509 : :
510 : : // Cast a pointer to an integer.
511 : :
512 : : bool
513 : 7536030 : operator_cast::fold_range (irange &r, tree type,
514 : : const prange &inner,
515 : : const irange &outer,
516 : : relation_trio) const
517 : : {
518 : 7536030 : if (empty_range_varying (r, type, inner, outer))
519 : 3703886 : return true;
520 : :
521 : : // Represent INNER as an integer of the same size, and then cast it
522 : : // to the resulting integer type.
523 : 3832144 : tree pointer_uint_type = make_unsigned_type (TYPE_PRECISION (inner.type ()));
524 : 3832144 : r.set (pointer_uint_type, inner.lower_bound (), inner.upper_bound ());
525 : 3832144 : r.update_bitmask (inner.get_bitmask ());
526 : 3832144 : range_cast (r, type);
527 : 3832144 : return true;
528 : : }
529 : :
530 : : // Cast an integer to a pointer.
531 : :
532 : : bool
533 : 1554955 : operator_cast::fold_range (prange &r, tree type,
534 : : const irange &inner,
535 : : const prange &outer,
536 : : relation_trio) const
537 : : {
538 : 1554955 : if (empty_range_varying (r, type, inner, outer))
539 : 1790 : return true;
540 : :
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 : 1553165 : int_range<2> tmp = inner;
544 : 1553165 : tree pointer_uint_type = make_unsigned_type (TYPE_PRECISION (type));
545 : 1553165 : range_cast (tmp, pointer_uint_type);
546 : 1553165 : r.set (type, tmp.lower_bound (), tmp.upper_bound ());
547 : 1553165 : r.update_bitmask (tmp.get_bitmask ());
548 : 1553165 : return true;
549 : 1553165 : }
550 : :
551 : : bool
552 : 69 : operator_cast::op1_range (prange &r, tree type,
553 : : const prange &lhs,
554 : : const prange &op2,
555 : : relation_trio trio) const
556 : : {
557 : 69 : if (lhs.undefined_p ())
558 : : return false;
559 : 69 : gcc_checking_assert (types_compatible_p (op2.type(), type));
560 : :
561 : : // Conversion from other pointers or a constant (including 0/NULL)
562 : : // are straightforward.
563 : 69 : if (POINTER_TYPE_P (lhs.type ())
564 : 69 : || (lhs.singleton_p ()
565 : 0 : && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
566 : 69 : fold_range (r, type, lhs, op2, trio);
567 : : else
568 : : {
569 : : // If the LHS is not a pointer nor a singleton, then it is
570 : : // either VARYING or non-zero.
571 : 0 : if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
572 : 0 : r.set_nonzero (type);
573 : : else
574 : 0 : r.set_varying (type);
575 : : }
576 : 69 : r.intersect (op2);
577 : 69 : return true;
578 : : }
579 : :
580 : : bool
581 : 169541 : operator_cast::op1_range (irange &r, tree type,
582 : : const prange &lhs,
583 : : const irange &op2,
584 : : relation_trio trio) const
585 : : {
586 : 169541 : if (lhs.undefined_p ())
587 : : return false;
588 : 169541 : gcc_checking_assert (types_compatible_p (op2.type(), type));
589 : :
590 : : // Conversion from other pointers or a constant (including 0/NULL)
591 : : // are straightforward.
592 : 169541 : if (POINTER_TYPE_P (lhs.type ())
593 : 169541 : || (lhs.singleton_p ()
594 : 0 : && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
595 : 169541 : fold_range (r, type, lhs, op2, trio);
596 : : else
597 : : {
598 : : // If the LHS is not a pointer nor a singleton, then it is
599 : : // either VARYING or non-zero.
600 : 0 : if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
601 : 0 : r.set_nonzero (type);
602 : : else
603 : 0 : r.set_varying (type);
604 : : }
605 : 169541 : r.intersect (op2);
606 : 169541 : return true;
607 : : }
608 : :
609 : : bool
610 : 315474 : operator_cast::op1_range (prange &r, tree type,
611 : : const irange &lhs,
612 : : const prange &op2,
613 : : relation_trio trio) const
614 : : {
615 : 315474 : if (lhs.undefined_p ())
616 : : return false;
617 : 315474 : gcc_checking_assert (types_compatible_p (op2.type(), type));
618 : :
619 : : // Conversion from other pointers or a constant (including 0/NULL)
620 : : // are straightforward.
621 : 630948 : if (POINTER_TYPE_P (lhs.type ())
622 : 630948 : || (lhs.singleton_p ()
623 : 893 : && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
624 : 887 : fold_range (r, type, lhs, op2, trio);
625 : : else
626 : : {
627 : : // If the LHS is not a pointer nor a singleton, then it is
628 : : // either VARYING or non-zero.
629 : 314587 : if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
630 : 169300 : r.set_nonzero (type);
631 : : else
632 : 145287 : r.set_varying (type);
633 : : }
634 : 315474 : r.intersect (op2);
635 : 315474 : return true;
636 : : }
637 : :
638 : : relation_kind
639 : 136833 : operator_cast::lhs_op1_relation (const prange &lhs,
640 : : const prange &op1,
641 : : const prange &op2 ATTRIBUTE_UNUSED,
642 : : relation_kind) const
643 : : {
644 : 136833 : if (lhs.undefined_p () || op1.undefined_p ())
645 : : return VREL_VARYING;
646 : 136833 : unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
647 : 136833 : 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 : 136833 : if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
651 : : {
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 : 0 : int_range<3> negs = range_negatives (op1.type ());
656 : 0 : negs.intersect (op1);
657 : 0 : if (!negs.undefined_p ())
658 : 0 : return VREL_VARYING;
659 : 0 : }
660 : :
661 : 136833 : unsigned prec = MIN (lhs_prec, op1_prec);
662 : 136833 : return bits_to_pe (prec);
663 : : }
664 : :
665 : : relation_kind
666 : 1210207 : operator_cast::lhs_op1_relation (const prange &lhs,
667 : : const irange &op1,
668 : : const irange &op2 ATTRIBUTE_UNUSED,
669 : : relation_kind) const
670 : : {
671 : 1210207 : if (lhs.undefined_p () || op1.undefined_p ())
672 : : return VREL_VARYING;
673 : 1208430 : unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
674 : 1208430 : 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 : 1208430 : if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
678 : : {
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 : 370 : int_range<3> negs = range_negatives (op1.type ());
683 : 370 : negs.intersect (op1);
684 : 370 : if (!negs.undefined_p ())
685 : 268 : return VREL_VARYING;
686 : 370 : }
687 : :
688 : 1208162 : unsigned prec = MIN (lhs_prec, op1_prec);
689 : 1208162 : return bits_to_pe (prec);
690 : : }
691 : :
692 : : relation_kind
693 : 1742295 : operator_cast::lhs_op1_relation (const irange &lhs,
694 : : const prange &op1,
695 : : const prange &op2 ATTRIBUTE_UNUSED,
696 : : relation_kind) const
697 : : {
698 : 1742295 : if (lhs.undefined_p () || op1.undefined_p ())
699 : : return VREL_VARYING;
700 : 1741623 : unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
701 : 1741623 : 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 : 1741623 : if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
705 : : {
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 : 0 : int_range<3> negs = range_negatives (op1.type ());
710 : 0 : negs.intersect (op1);
711 : 0 : if (!negs.undefined_p ())
712 : 0 : return VREL_VARYING;
713 : 0 : }
714 : :
715 : 1741623 : unsigned prec = MIN (lhs_prec, op1_prec);
716 : 1741623 : return bits_to_pe (prec);
717 : : }
718 : :
719 : : bool
720 : 783 : operator_min::fold_range (prange &r, tree type,
721 : : const prange &op1,
722 : : const prange &op2,
723 : : relation_trio) const
724 : : {
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
728 : : // are varying.
729 : 783 : if (!range_includes_zero_p (op1)
730 : 783 : && !range_includes_zero_p (op2))
731 : 142 : r.set_nonzero (type);
732 : 641 : else if (op1.zero_p () && op2.zero_p ())
733 : 0 : r.set_zero (type);
734 : : else
735 : 641 : r.set_varying (type);
736 : :
737 : 783 : update_known_bitmask (r, MIN_EXPR, op1, op2);
738 : 783 : return true;
739 : : }
740 : :
741 : : bool
742 : 834 : operator_max::fold_range (prange &r, tree type,
743 : : const prange &op1,
744 : : const prange &op2,
745 : : relation_trio) const
746 : : {
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
750 : : // are varying.
751 : 834 : if (!range_includes_zero_p (op1)
752 : 834 : && !range_includes_zero_p (op2))
753 : 103 : r.set_nonzero (type);
754 : 731 : else if (op1.zero_p () && op2.zero_p ())
755 : 0 : r.set_zero (type);
756 : : else
757 : 731 : r.set_varying (type);
758 : :
759 : 834 : update_known_bitmask (r, MAX_EXPR, op1, op2);
760 : 834 : return true;
761 : : }
762 : :
763 : : bool
764 : 411416 : operator_addr_expr::op1_range (prange &r, tree type,
765 : : const prange &lhs,
766 : : const prange &op2,
767 : : relation_trio) const
768 : : {
769 : 411416 : if (empty_range_varying (r, type, lhs, op2))
770 : 0 : return true;
771 : :
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.
774 : : // See PR 111009.
775 : 411416 : if (!lhs.undefined_p ()
776 : 411416 : && !range_includes_zero_p (lhs)
777 : 405519 : && TYPE_OVERFLOW_UNDEFINED (type))
778 : 405500 : r.set_nonzero (type);
779 : : else
780 : 5916 : r.set_varying (type);
781 : : return true;
782 : : }
783 : :
784 : : bool
785 : 770 : operator_bitwise_and::fold_range (prange &r, tree type,
786 : : const prange &op1,
787 : : const prange &op2 ATTRIBUTE_UNUSED,
788 : : relation_trio) const
789 : : {
790 : : // For pointer types, we are really only interested in asserting
791 : : // whether the expression evaluates to non-NULL.
792 : 770 : if (op1.zero_p () || op2.zero_p ())
793 : 0 : r.set_zero (type);
794 : : else
795 : 770 : r.set_varying (type);
796 : :
797 : 770 : update_known_bitmask (r, BIT_AND_EXPR, op1, op2);
798 : 770 : return true;
799 : : }
800 : :
801 : : bool
802 : 5302302 : operator_equal::fold_range (irange &r, tree type,
803 : : const prange &op1,
804 : : const prange &op2,
805 : : relation_trio rel) const
806 : : {
807 : 5302302 : if (relop_early_resolve (r, type, op1, op2, rel, VREL_EQ))
808 : : return true;
809 : :
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 : 5291269 : bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ());
813 : 5291269 : bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ());
814 : 5291269 : if (op1_const && op2_const)
815 : : {
816 : 22068 : if (wi::eq_p (op1.lower_bound (), op2.upper_bound()))
817 : 21867 : r = range_true (type);
818 : : else
819 : 201 : r = range_false (type);
820 : : }
821 : : else
822 : : {
823 : : // If ranges do not intersect, we know the range is not equal,
824 : : // otherwise we don't know anything for sure.
825 : 5269201 : prange tmp = op1;
826 : 5269201 : tmp.intersect (op2);
827 : 5269201 : if (tmp.undefined_p ())
828 : 164903 : r = range_false (type);
829 : : // Check if a constant cannot satisfy the bitmask requirements.
830 : 9928190 : else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ()))
831 : 6 : r = range_false (type);
832 : 5112360 : else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ()))
833 : 0 : r = range_false (type);
834 : : else
835 : 5104292 : r = range_true_and_false (type);
836 : 5269201 : }
837 : :
838 : : //update_known_bitmask (r, EQ_EXPR, op1, op2);
839 : : return true;
840 : : }
841 : :
842 : : bool
843 : 3256825 : operator_equal::op1_range (prange &r, tree type,
844 : : const irange &lhs,
845 : : const prange &op2,
846 : : relation_trio) const
847 : : {
848 : 3256825 : switch (get_bool_state (r, lhs, type))
849 : : {
850 : 757251 : case BRS_TRUE:
851 : : // If it's true, the result is the same as OP2.
852 : 757251 : r = op2;
853 : 757251 : break;
854 : :
855 : 2492788 : case BRS_FALSE:
856 : : // If the result is false, the only time we know anything is
857 : : // if OP2 is a constant.
858 : 2492788 : if (!op2.undefined_p ()
859 : 7478364 : && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
860 : : {
861 : 907086 : r = op2;
862 : 907086 : r.invert ();
863 : : }
864 : : else
865 : 1585702 : r.set_varying (type);
866 : : break;
867 : :
868 : : default:
869 : : break;
870 : : }
871 : 3256825 : return true;
872 : : }
873 : :
874 : : bool
875 : 1334335 : operator_equal::op2_range (prange &r, tree type,
876 : : const irange &lhs,
877 : : const prange &op1,
878 : : relation_trio rel) const
879 : : {
880 : 1334335 : return operator_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
881 : : }
882 : :
883 : : relation_kind
884 : 3552344 : operator_equal::op1_op2_relation (const irange &lhs, const prange &,
885 : : const prange &) const
886 : : {
887 : 3552344 : if (lhs.undefined_p ())
888 : : return VREL_UNDEFINED;
889 : :
890 : : // FALSE = op1 == op2 indicates NE_EXPR.
891 : 3552344 : if (lhs.zero_p ())
892 : : return VREL_NE;
893 : :
894 : : // TRUE = op1 == op2 indicates EQ_EXPR.
895 : 1438768 : if (!range_includes_zero_p (lhs))
896 : 1438696 : return VREL_EQ;
897 : : return VREL_VARYING;
898 : : }
899 : :
900 : : bool
901 : 6848666 : operator_not_equal::fold_range (irange &r, tree type,
902 : : const prange &op1,
903 : : const prange &op2,
904 : : relation_trio rel) const
905 : : {
906 : 6848666 : if (relop_early_resolve (r, type, op1, op2, rel, VREL_NE))
907 : : return true;
908 : :
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 : 6835350 : bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ());
912 : 6835350 : bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ());
913 : 6835350 : if (op1_const && op2_const)
914 : : {
915 : 47278 : if (wi::ne_p (op1.lower_bound (), op2.upper_bound()))
916 : 175 : r = range_true (type);
917 : : else
918 : 47103 : r = range_false (type);
919 : : }
920 : : else
921 : : {
922 : : // If ranges do not intersect, we know the range is not equal,
923 : : // otherwise we don't know anything for sure.
924 : 6788072 : prange tmp = op1;
925 : 6788072 : tmp.intersect (op2);
926 : 6788072 : if (tmp.undefined_p ())
927 : 171119 : r = range_true (type);
928 : : // Check if a constant cannot satisfy the bitmask requirements.
929 : 14239787 : else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ()))
930 : 12 : r = range_true (type);
931 : 6619477 : else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ()))
932 : 0 : r = range_true (type);
933 : : else
934 : 6616941 : r = range_true_and_false (type);
935 : 6788072 : }
936 : :
937 : : //update_known_bitmask (r, NE_EXPR, op1, op2);
938 : : return true;
939 : : }
940 : :
941 : : bool
942 : 4166353 : operator_not_equal::op1_range (prange &r, tree type,
943 : : const irange &lhs,
944 : : const prange &op2,
945 : : relation_trio) const
946 : : {
947 : 4166353 : switch (get_bool_state (r, lhs, type))
948 : : {
949 : 3361257 : case BRS_TRUE:
950 : : // If the result is true, the only time we know anything is if
951 : : // OP2 is a constant.
952 : 3361257 : if (!op2.undefined_p ()
953 : 10083771 : && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
954 : : {
955 : 1457757 : r = op2;
956 : 1457757 : r.invert ();
957 : : }
958 : : else
959 : 1903500 : r.set_varying (type);
960 : : break;
961 : :
962 : 785370 : case BRS_FALSE:
963 : : // If it's false, the result is the same as OP2.
964 : 785370 : r = op2;
965 : 785370 : break;
966 : :
967 : : default:
968 : : break;
969 : : }
970 : 4166353 : return true;
971 : : }
972 : :
973 : :
974 : : bool
975 : 1237341 : operator_not_equal::op2_range (prange &r, tree type,
976 : : const irange &lhs,
977 : : const prange &op1,
978 : : relation_trio rel) const
979 : : {
980 : 1237341 : return operator_not_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
981 : : }
982 : :
983 : : relation_kind
984 : 4365366 : operator_not_equal::op1_op2_relation (const irange &lhs, const prange &,
985 : : const prange &) const
986 : : {
987 : 4365366 : if (lhs.undefined_p ())
988 : : return VREL_UNDEFINED;
989 : :
990 : : // FALSE = op1 != op2 indicates EQ_EXPR.
991 : 4365366 : if (lhs.zero_p ())
992 : : return VREL_EQ;
993 : :
994 : : // TRUE = op1 != op2 indicates NE_EXPR.
995 : 2879655 : if (!range_includes_zero_p (lhs))
996 : 2876497 : return VREL_NE;
997 : : return VREL_VARYING;
998 : : }
999 : :
1000 : : bool
1001 : 264077 : operator_lt::fold_range (irange &r, tree type,
1002 : : const prange &op1,
1003 : : const prange &op2,
1004 : : relation_trio rel) const
1005 : : {
1006 : 264077 : if (relop_early_resolve (r, type, op1, op2, rel, VREL_LT))
1007 : : return true;
1008 : :
1009 : 263655 : signop sign = TYPE_SIGN (op1.type ());
1010 : 263655 : gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
1011 : :
1012 : 263655 : if (wi::lt_p (op1.upper_bound (), op2.lower_bound (), sign))
1013 : 0 : r = range_true (type);
1014 : 263655 : else if (!wi::lt_p (op1.lower_bound (), op2.upper_bound (), sign))
1015 : 31 : r = range_false (type);
1016 : : // Use nonzero bits to determine if < 0 is false.
1017 : 263624 : else if (op2.zero_p () && !wi::neg_p (op1.get_nonzero_bits (), sign))
1018 : 0 : r = range_false (type);
1019 : : else
1020 : 263624 : r = range_true_and_false (type);
1021 : :
1022 : : //update_known_bitmask (r, LT_EXPR, op1, op2);
1023 : : return true;
1024 : : }
1025 : :
1026 : : bool
1027 : 199889 : operator_lt::op1_range (prange &r, tree type,
1028 : : const irange &lhs,
1029 : : const prange &op2,
1030 : : relation_trio) const
1031 : : {
1032 : 199889 : if (op2.undefined_p ())
1033 : : return false;
1034 : :
1035 : 199889 : switch (get_bool_state (r, lhs, type))
1036 : : {
1037 : 86508 : case BRS_TRUE:
1038 : 86508 : build_lt (r, type, op2);
1039 : 86508 : break;
1040 : :
1041 : 113381 : case BRS_FALSE:
1042 : 113381 : build_ge (r, type, op2);
1043 : 113381 : break;
1044 : :
1045 : : default:
1046 : : break;
1047 : : }
1048 : : return true;
1049 : : }
1050 : :
1051 : : bool
1052 : 148967 : operator_lt::op2_range (prange &r, tree type,
1053 : : const irange &lhs,
1054 : : const prange &op1,
1055 : : relation_trio) const
1056 : : {
1057 : 148967 : if (op1.undefined_p ())
1058 : : return false;
1059 : :
1060 : 148967 : switch (get_bool_state (r, lhs, type))
1061 : : {
1062 : 84357 : case BRS_TRUE:
1063 : 84357 : build_gt (r, type, op1);
1064 : 84357 : break;
1065 : :
1066 : 64606 : case BRS_FALSE:
1067 : 64606 : build_le (r, type, op1);
1068 : 64606 : break;
1069 : :
1070 : : default:
1071 : : break;
1072 : : }
1073 : : return true;
1074 : : }
1075 : :
1076 : : relation_kind
1077 : 574096 : operator_lt::op1_op2_relation (const irange &lhs, const prange &,
1078 : : const prange &) const
1079 : : {
1080 : 574096 : if (lhs.undefined_p ())
1081 : : return VREL_UNDEFINED;
1082 : :
1083 : : // FALSE = op1 < op2 indicates GE_EXPR.
1084 : 574096 : if (lhs.zero_p ())
1085 : : return VREL_GE;
1086 : :
1087 : : // TRUE = op1 < op2 indicates LT_EXPR.
1088 : 270509 : if (!range_includes_zero_p (lhs))
1089 : 270505 : return VREL_LT;
1090 : : return VREL_VARYING;
1091 : : }
1092 : :
1093 : : bool
1094 : 136249 : operator_le::fold_range (irange &r, tree type,
1095 : : const prange &op1,
1096 : : const prange &op2,
1097 : : relation_trio rel) const
1098 : : {
1099 : 136249 : if (relop_early_resolve (r, type, op1, op2, rel, VREL_LE))
1100 : : return true;
1101 : :
1102 : 135272 : signop sign = TYPE_SIGN (op1.type ());
1103 : 135272 : gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
1104 : :
1105 : 135272 : if (wi::le_p (op1.upper_bound (), op2.lower_bound (), sign))
1106 : 5 : r = range_true (type);
1107 : 135267 : else if (!wi::le_p (op1.lower_bound (), op2.upper_bound (), sign))
1108 : 4 : r = range_false (type);
1109 : : else
1110 : 135263 : r = range_true_and_false (type);
1111 : :
1112 : : //update_known_bitmask (r, LE_EXPR, op1, op2);
1113 : : return true;
1114 : : }
1115 : :
1116 : : bool
1117 : 58677 : operator_le::op1_range (prange &r, tree type,
1118 : : const irange &lhs,
1119 : : const prange &op2,
1120 : : relation_trio) const
1121 : : {
1122 : 58677 : if (op2.undefined_p ())
1123 : : return false;
1124 : :
1125 : 58677 : switch (get_bool_state (r, lhs, type))
1126 : : {
1127 : 13067 : case BRS_TRUE:
1128 : 13067 : build_le (r, type, op2);
1129 : 13067 : break;
1130 : :
1131 : 45610 : case BRS_FALSE:
1132 : 45610 : build_gt (r, type, op2);
1133 : 45610 : break;
1134 : :
1135 : : default:
1136 : : break;
1137 : : }
1138 : : return true;
1139 : : }
1140 : :
1141 : : bool
1142 : 113453 : operator_le::op2_range (prange &r, tree type,
1143 : : const irange &lhs,
1144 : : const prange &op1,
1145 : : relation_trio) const
1146 : : {
1147 : 113453 : if (op1.undefined_p ())
1148 : : return false;
1149 : :
1150 : 113453 : switch (get_bool_state (r, lhs, type))
1151 : : {
1152 : 10866 : case BRS_TRUE:
1153 : 10866 : build_ge (r, type, op1);
1154 : 10866 : break;
1155 : :
1156 : 102587 : case BRS_FALSE:
1157 : 102587 : build_lt (r, type, op1);
1158 : 102587 : break;
1159 : :
1160 : : default:
1161 : : break;
1162 : : }
1163 : : return true;
1164 : : }
1165 : :
1166 : : relation_kind
1167 : 279265 : operator_le::op1_op2_relation (const irange &lhs, const prange &,
1168 : : const prange &) const
1169 : : {
1170 : 279265 : if (lhs.undefined_p ())
1171 : : return VREL_UNDEFINED;
1172 : :
1173 : : // FALSE = op1 <= op2 indicates GT_EXPR.
1174 : 279265 : if (lhs.zero_p ())
1175 : : return VREL_GT;
1176 : :
1177 : : // TRUE = op1 <= op2 indicates LE_EXPR.
1178 : 63598 : if (!range_includes_zero_p (lhs))
1179 : 63598 : return VREL_LE;
1180 : : return VREL_VARYING;
1181 : : }
1182 : :
1183 : : bool
1184 : 252184 : operator_gt::fold_range (irange &r, tree type,
1185 : : const prange &op1, const prange &op2,
1186 : : relation_trio rel) const
1187 : : {
1188 : 252184 : if (relop_early_resolve (r, type, op1, op2, rel, VREL_GT))
1189 : : return true;
1190 : :
1191 : 251812 : signop sign = TYPE_SIGN (op1.type ());
1192 : 251812 : gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
1193 : :
1194 : 251812 : if (wi::gt_p (op1.lower_bound (), op2.upper_bound (), sign))
1195 : 2 : r = range_true (type);
1196 : 251810 : else if (!wi::gt_p (op1.upper_bound (), op2.lower_bound (), sign))
1197 : 9 : r = range_false (type);
1198 : : else
1199 : 251801 : r = range_true_and_false (type);
1200 : :
1201 : : //update_known_bitmask (r, GT_EXPR, op1, op2);
1202 : : return true;
1203 : : }
1204 : :
1205 : : bool
1206 : 170910 : operator_gt::op1_range (prange &r, tree type,
1207 : : const irange &lhs, const prange &op2,
1208 : : relation_trio) const
1209 : : {
1210 : 170910 : if (op2.undefined_p ())
1211 : : return false;
1212 : :
1213 : 170910 : switch (get_bool_state (r, lhs, type))
1214 : : {
1215 : 91426 : case BRS_TRUE:
1216 : 91426 : build_gt (r, type, op2);
1217 : 91426 : break;
1218 : :
1219 : 79484 : case BRS_FALSE:
1220 : 79484 : build_le (r, type, op2);
1221 : 79484 : break;
1222 : :
1223 : : default:
1224 : : break;
1225 : : }
1226 : : return true;
1227 : : }
1228 : :
1229 : : bool
1230 : 170663 : operator_gt::op2_range (prange &r, tree type,
1231 : : const irange &lhs,
1232 : : const prange &op1,
1233 : : relation_trio) const
1234 : : {
1235 : 170663 : if (op1.undefined_p ())
1236 : : return false;
1237 : :
1238 : 170663 : switch (get_bool_state (r, lhs, type))
1239 : : {
1240 : 73790 : case BRS_TRUE:
1241 : 73790 : build_lt (r, type, op1);
1242 : 73790 : break;
1243 : :
1244 : 96873 : case BRS_FALSE:
1245 : 96873 : build_ge (r, type, op1);
1246 : 96873 : break;
1247 : :
1248 : : default:
1249 : : break;
1250 : : }
1251 : : return true;
1252 : : }
1253 : :
1254 : : relation_kind
1255 : 529958 : operator_gt::op1_op2_relation (const irange &lhs, const prange &,
1256 : : const prange &) const
1257 : : {
1258 : 529958 : if (lhs.undefined_p ())
1259 : : return VREL_UNDEFINED;
1260 : :
1261 : : // FALSE = op1 > op2 indicates LE_EXPR.
1262 : 529958 : if (lhs.zero_p ())
1263 : : return VREL_LE;
1264 : :
1265 : : // TRUE = op1 > op2 indicates GT_EXPR.
1266 : 267688 : if (!range_includes_zero_p (lhs))
1267 : 267688 : return VREL_GT;
1268 : : return VREL_VARYING;
1269 : : }
1270 : :
1271 : : bool
1272 : 141714 : operator_ge::fold_range (irange &r, tree type,
1273 : : const prange &op1,
1274 : : const prange &op2,
1275 : : relation_trio rel) const
1276 : : {
1277 : 141714 : if (relop_early_resolve (r, type, op1, op2, rel, VREL_GE))
1278 : : return true;
1279 : :
1280 : 141288 : signop sign = TYPE_SIGN (op1.type ());
1281 : 141288 : gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
1282 : :
1283 : 141288 : if (wi::ge_p (op1.lower_bound (), op2.upper_bound (), sign))
1284 : 62 : r = range_true (type);
1285 : 141226 : else if (!wi::ge_p (op1.upper_bound (), op2.lower_bound (), sign))
1286 : 0 : r = range_false (type);
1287 : : else
1288 : 141226 : r = range_true_and_false (type);
1289 : :
1290 : : //update_known_bitmask (r, GE_EXPR, op1, op2);
1291 : : return true;
1292 : : }
1293 : :
1294 : : bool
1295 : 92474 : operator_ge::op1_range (prange &r, tree type,
1296 : : const irange &lhs,
1297 : : const prange &op2,
1298 : : relation_trio) const
1299 : : {
1300 : 92474 : if (op2.undefined_p ())
1301 : : return false;
1302 : :
1303 : 92474 : switch (get_bool_state (r, lhs, type))
1304 : : {
1305 : 11754 : case BRS_TRUE:
1306 : 11754 : build_ge (r, type, op2);
1307 : 11754 : break;
1308 : :
1309 : 80720 : case BRS_FALSE:
1310 : 80720 : build_lt (r, type, op2);
1311 : 80720 : break;
1312 : :
1313 : : default:
1314 : : break;
1315 : : }
1316 : : return true;
1317 : : }
1318 : :
1319 : : bool
1320 : 51868 : operator_ge::op2_range (prange &r, tree type,
1321 : : const irange &lhs,
1322 : : const prange &op1,
1323 : : relation_trio) const
1324 : : {
1325 : 51868 : if (op1.undefined_p ())
1326 : : return false;
1327 : :
1328 : 51868 : switch (get_bool_state (r, lhs, type))
1329 : : {
1330 : 8749 : case BRS_TRUE:
1331 : 8749 : build_le (r, type, op1);
1332 : 8749 : break;
1333 : :
1334 : 43119 : case BRS_FALSE:
1335 : 43119 : build_gt (r, type, op1);
1336 : 43119 : break;
1337 : :
1338 : : default:
1339 : : break;
1340 : : }
1341 : : return true;
1342 : : }
1343 : :
1344 : : relation_kind
1345 : 281308 : operator_ge::op1_op2_relation (const irange &lhs, const prange &,
1346 : : const prange &) const
1347 : : {
1348 : 281308 : if (lhs.undefined_p ())
1349 : : return VREL_UNDEFINED;
1350 : :
1351 : : // FALSE = op1 >= op2 indicates LT_EXPR.
1352 : 281308 : if (lhs.zero_p ())
1353 : : return VREL_LT;
1354 : :
1355 : : // TRUE = op1 >= op2 indicates GE_EXPR.
1356 : 50455 : if (!range_includes_zero_p (lhs))
1357 : 50455 : return VREL_GE;
1358 : : return VREL_VARYING;
1359 : : }
1360 : :
1361 : : // Initialize any pointer operators to the primary table
1362 : :
1363 : : void
1364 : 281805 : range_op_table::initialize_pointer_ops ()
1365 : : {
1366 : 281805 : set (POINTER_PLUS_EXPR, op_pointer_plus);
1367 : 281805 : set (POINTER_DIFF_EXPR, op_pointer_diff);
1368 : 281805 : }
|