LCOV - code coverage report
Current view: top level - gcc - range-op-ptr.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.3 % 498 425
Test Date: 2026-08-22 16:33:35 Functions: 79.2 % 77 61
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Code for range operators.
       2              :    Copyright (C) 2017-2026 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          158 : range_operator::op1_range (prange &, tree,
     134              :                            const prange &lhs ATTRIBUTE_UNUSED,
     135              :                            const prange &op2 ATTRIBUTE_UNUSED,
     136              :                            relation_trio) const
     137              : {
     138          158 :   return false;
     139              : }
     140              : 
     141              : bool
     142       886911 : range_operator::op1_range (prange &, tree,
     143              :                            const irange &lhs ATTRIBUTE_UNUSED,
     144              :                            const prange &op2 ATTRIBUTE_UNUSED,
     145              :                            relation_trio) const
     146              : {
     147       886911 :   return false;
     148              : }
     149              : 
     150              : bool
     151       377015 : range_operator::op1_range (prange &, tree,
     152              :                            const prange &lhs ATTRIBUTE_UNUSED,
     153              :                            const irange &op2 ATTRIBUTE_UNUSED,
     154              :                            relation_trio) const
     155              : {
     156       377015 :   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      1299075 : range_operator::op2_range (prange &, tree,
     170              :                            const irange &lhs ATTRIBUTE_UNUSED,
     171              :                            const prange &op1 ATTRIBUTE_UNUSED,
     172              :                            relation_trio) const
     173              : {
     174      1299075 :   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      2166581 : 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      2166581 :   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      4246638 : 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      4246638 :   return VREL_VARYING;
     210              : }
     211              : 
     212              : relation_kind
     213        81100 : 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        81100 :   return VREL_VARYING;
     219              : }
     220              : 
     221              : relation_kind
     222            0 : range_operator::lhs_op1_relation (const prange &lhs ATTRIBUTE_UNUSED,
     223              :                                   const prange &op1 ATTRIBUTE_UNUSED,
     224              :                                   const irange &op2 ATTRIBUTE_UNUSED,
     225              :                                   relation_kind rel ATTRIBUTE_UNUSED) const
     226              : {
     227            0 :   return VREL_VARYING;
     228              : }
     229              : 
     230              : void
     231            0 : range_operator::update_bitmask (irange &,
     232              :                                 const prange &,
     233              :                                 const prange &) const
     234              : {
     235            0 : }
     236              : 
     237              : // Return the upper limit for a type.
     238              : 
     239              : static inline wide_int
     240       735588 : max_limit (const_tree type)
     241              : {
     242       735588 :   return wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
     243              : }
     244              : 
     245              : // Return the lower limit for a type.
     246              : 
     247              : static inline wide_int
     248       776578 : min_limit (const_tree type)
     249              : {
     250       776578 :   return wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
     251              : }
     252              : 
     253              : // Build a range that is < VAL and store it in R.
     254              : 
     255              : static void
     256       502618 : build_lt (prange &r, tree type, const prange &val)
     257              : {
     258       502618 :   wi::overflow_type ov;
     259       502618 :   wide_int lim = wi::sub (val.upper_bound (), 1, UNSIGNED, &ov);
     260              : 
     261              :   // If val - 1 underflows, check if X < MIN, which is an empty range.
     262       502618 :   if (ov)
     263            0 :     r.set_undefined ();
     264              :   else
     265       502618 :     r.set (type, min_limit (type), lim);
     266       502618 : }
     267              : 
     268              : // Build a range that is <= VAL and store it in R.
     269              : 
     270              : static void
     271       273960 : build_le (prange &r, tree type, const prange &val)
     272              : {
     273       273960 :   r.set (type, min_limit (type), val.upper_bound ());
     274       273960 : }
     275              : 
     276              : // Build a range that is > VAL and store it in R.
     277              : 
     278              : static void
     279       352142 : build_gt (prange &r, tree type, const prange &val)
     280              : {
     281       352142 :   wi::overflow_type ov;
     282       352142 :   wide_int lim = wi::add (val.lower_bound (), 1, UNSIGNED, &ov);
     283              : 
     284              :   // If val + 1 overflows, check is for X > MAX, which is an empty range.
     285       352142 :   if (ov)
     286            0 :     r.set_undefined ();
     287              :   else
     288       352142 :     r.set (type, lim, max_limit (type));
     289              : 
     290       352142 : }
     291              : 
     292              : // Build a range that is >= VAL and store it in R.
     293              : 
     294              : static void
     295       383446 : build_ge (prange &r, tree type, const prange &val)
     296              : {
     297       383446 :   r.set (type, val.lower_bound (), max_limit (type));
     298       383446 : }
     299              : 
     300              : class pointer_plus_operator : public range_operator
     301              : {
     302              :   using range_operator::update_bitmask;
     303              :   using range_operator::fold_range;
     304              :   using range_operator::op2_range;
     305              :   using range_operator::lhs_op1_relation;
     306              : public:
     307              :   virtual bool fold_range (prange &r, tree type,
     308              :                            const prange &op1,
     309              :                            const irange &op2,
     310              :                            relation_trio) const final override;
     311              :   virtual bool op2_range (irange &r, tree type,
     312              :                           const prange &lhs,
     313              :                           const prange &op1,
     314              :                           relation_trio = TRIO_VARYING) const final override;
     315              :   virtual relation_kind lhs_op1_relation (const prange &lhs,
     316              :                                           const prange &op1,
     317              :                                           const irange &op2,
     318              :                                           relation_kind) const final override;
     319              :   void update_bitmask (prange &r, const prange &lh, const irange &rh) const
     320              :     { update_known_bitmask (r, POINTER_PLUS_EXPR, lh, rh); }
     321              : };
     322              : static const pointer_plus_operator op_pointer_plus;
     323              : 
     324              : bool
     325      9611415 : pointer_plus_operator::fold_range (prange &r, tree type,
     326              :                                    const prange &op1,
     327              :                                    const irange &op2,
     328              :                                    relation_trio) const
     329              : {
     330      9611415 :   if (empty_range_varying (r, type, op1, op2))
     331         6169 :     return true;
     332              : 
     333      9605246 :   const wide_int lh_lb = op1.lower_bound ();
     334      9605246 :   const wide_int lh_ub = op1.upper_bound ();
     335      9605246 :   const wide_int rh_lb = op2.lower_bound ();
     336      9605246 :   const wide_int rh_ub = op2.upper_bound ();
     337              : 
     338              :   // Check for [0,0] + const, and simply return the const.
     339      9613071 :   if (lh_lb == 0 && lh_ub == 0 && rh_lb == rh_ub)
     340              :     {
     341          539 :       r.set (type, rh_lb, rh_lb);
     342          539 :       return true;
     343              :     }
     344              : 
     345              :   // For pointer types, we are really only interested in asserting
     346              :   // whether the expression evaluates to non-NULL.
     347              :   //
     348              :   // With -fno-delete-null-pointer-checks we need to be more
     349              :   // conservative.  As some object might reside at address 0,
     350              :   // then some offset could be added to it and the same offset
     351              :   // subtracted again and the result would be NULL.
     352              :   // E.g.
     353              :   // static int a[12]; where &a[0] is NULL and
     354              :   // ptr = &a[6];
     355              :   // ptr -= 6;
     356              :   // ptr will be NULL here, even when there is POINTER_PLUS_EXPR
     357              :   // where the first range doesn't include zero and the second one
     358              :   // doesn't either.  As the second operand is sizetype (unsigned),
     359              :   // consider all ranges where the MSB could be set as possible
     360              :   // subtractions where the result might be NULL.
     361      9604707 :   if ((!wi_includes_zero_p (type, lh_lb, lh_ub)
     362      5679352 :        || !wi_includes_zero_p (type, rh_lb, rh_ub))
     363      6342016 :       && !TYPE_OVERFLOW_WRAPS (type)
     364     15946201 :       && (flag_delete_null_pointer_checks
     365         1169 :           || !wi::sign_mask (rh_ub)))
     366      6341088 :     r.set_nonzero (type);
     367      3270125 :   else if (lh_lb == lh_ub && lh_lb == 0
     368      3270125 :            && rh_lb == rh_ub && rh_lb == 0)
     369            0 :     r.set_zero (type);
     370              :   else
     371      3263619 :    r.set_varying (type);
     372              : 
     373              :   // If op1 refers to an object, op1 + 0 will also refer to the object.
     374      9604707 :   if (rh_lb == rh_ub && rh_lb == 0)
     375        22035 :     r.set_pt (op1);
     376              : 
     377      9604707 :   update_known_bitmask (r, POINTER_PLUS_EXPR, op1, op2);
     378      9604707 :   return true;
     379      9605246 : }
     380              : 
     381              : bool
     382       204540 : pointer_plus_operator::op2_range (irange &r, tree type,
     383              :                                   const prange &lhs,
     384              :                                   const prange &op1,
     385              :                                   relation_trio trio) const
     386              : {
     387       204540 :   relation_kind rel = trio.lhs_op1 ();
     388       204540 :   r.set_varying (type);
     389              : 
     390              :   // If the LHS and OP1 are equal, the op2 must be zero.
     391       204540 :   if (rel == VREL_EQ || lhs.pt_invariant_p (op1))
     392          177 :     r.set_zero (type);
     393              :   // If the LHS and OP1 are not equal, the offset must be non-zero.
     394              :   // AWM: Check if aliasing may mean we can't do the not_equal check.
     395       204363 :   else if (rel == VREL_NE || lhs.pt_inverted_p (op1))
     396          132 :     r.set_nonzero (type);
     397              :   else
     398              :     return false;
     399              :   return true;
     400              : }
     401              : 
     402              : // Return the relation between the LHS and OP1 based on the value of the
     403              : // operand being added.  Pointer_plus is define to have a size_type for
     404              : // operand 2 which can be interpreted as negative, so always used SIGNED.
     405              : // Any overflow is considered UB and thus ignored.
     406              : 
     407              : relation_kind
     408      8303323 : pointer_plus_operator::lhs_op1_relation (const prange &lhs,
     409              :                                          const prange &op1,
     410              :                                          const irange &op2,
     411              :                                          relation_kind) const
     412              : {
     413      8303323 :   if (lhs.undefined_p () || op1.undefined_p () || op2.undefined_p ())
     414              :     return VREL_VARYING;
     415              : 
     416      8297536 :   unsigned prec = TYPE_PRECISION (op2.type ());
     417              : 
     418              :   // LHS = OP1 + 0  indicates LHS == OP1.
     419      8297536 :   if (op2.zero_p ())
     420              :     return VREL_EQ;
     421              : 
     422      8277850 :   tree val;
     423              :   // Only deal with singletons for now.
     424      8277850 :   if (TYPE_OVERFLOW_UNDEFINED (lhs.type ()) && op2.singleton_p (&val))
     425              :     {
     426              :       // Always interpret VALUE as a signed value.  Positive will increase
     427              :       // the pointer value, and negative will decrease the poiinter value.
     428              :       // It cannot be zero or the earlier zero_p () condition will catch it.
     429      4053684 :       wide_int value = wi::to_wide (val);
     430              : 
     431              :       // Positive op2 means lhs > op1.
     432      4053684 :       if (wi::gt_p (value, wi::zero (prec), SIGNED))
     433              :         return VREL_GT;
     434              : 
     435              :       // Negative op2 means lhs < op1.
     436       467084 :       if (wi::lt_p (value, wi::zero (prec), SIGNED))
     437              :         return VREL_LT;
     438      4053684 :     }
     439              : 
     440              :   // If op2 does not contain 0, then LHS and OP1 can never be equal.
     441      4224166 :   if (!range_includes_zero_p (op2))
     442       611247 :     return VREL_NE;
     443              : 
     444              :   return VREL_VARYING;
     445              : }
     446              : 
     447              : bool
     448            0 : operator_bitwise_or::fold_range (prange &r, tree type,
     449              :                                  const prange &op1,
     450              :                                  const prange &op2,
     451              :                                  relation_trio) const
     452              : {
     453              :   // For pointer types, we are really only interested in asserting
     454              :   // whether the expression evaluates to non-NULL.
     455            0 :   if (!range_includes_zero_p (op1) || !range_includes_zero_p (op2))
     456            0 :     r.set_nonzero (type);
     457            0 :   else if (op1.zero_p () && op2.zero_p ())
     458            0 :     r.set_zero (type);
     459              :   else
     460            0 :     r.set_varying (type);
     461              : 
     462            0 :   update_known_bitmask (r, BIT_IOR_EXPR, op1, op2);
     463            0 :   return true;
     464              : }
     465              : 
     466              : 
     467              : class operator_pointer_diff : public range_operator
     468              : {
     469              :   using range_operator::fold_range;
     470              :   using range_operator::update_bitmask;
     471              :   using range_operator::op1_op2_relation_effect;
     472              :   virtual bool fold_range (irange &r, tree type,
     473              :                            const prange &op1,
     474              :                            const prange &op2,
     475              :                            relation_trio trio) const final override;
     476              :   virtual bool op1_op2_relation_effect (irange &lhs_range,
     477              :                                         tree type,
     478              :                                         const prange &op1_range,
     479              :                                         const prange &op2_range,
     480              :                                         relation_kind rel) const final override;
     481      2891091 :   void update_bitmask (irange &r,
     482              :                        const prange &lh, const prange &rh) const final override
     483            0 :   { update_known_bitmask (r, POINTER_DIFF_EXPR, lh, rh); }
     484              : };
     485              : static const operator_pointer_diff op_pointer_diff;
     486              : 
     487              : bool
     488      2891091 : operator_pointer_diff::fold_range (irange &r, tree type,
     489              :                                    const prange &op1,
     490              :                                    const prange &op2,
     491              :                                    relation_trio trio) const
     492              : {
     493      2891091 :   gcc_checking_assert (r.supports_type_p (type));
     494              : 
     495      2891091 :   r.set_varying (type);
     496      2891091 :   relation_kind rel = trio.op1_op2 ();
     497      2891091 :   op1_op2_relation_effect (r, type, op1, op2, rel);
     498              :   // if op1 and op2 point to the same object, the diff is 0.
     499      2891091 :   if (op1.pt_invariant_p (op2))
     500          748 :     r.set_zero (type);
     501      2891091 :   update_bitmask (r, op1, op2);
     502      2891091 :   return true;
     503              : }
     504              : 
     505              : bool
     506      2891091 : operator_pointer_diff::op1_op2_relation_effect (irange &lhs_range, tree type,
     507              :                                                 const prange &op1_range,
     508              :                                                 const prange &op2_range,
     509              :                                                 relation_kind rel) const
     510              : {
     511      2891091 :   int_range<2> op1, op2, tmp;
     512      2891091 :   range_op_handler cast (CONVERT_EXPR);
     513              : 
     514      2891091 :   if (!cast.fold_range (op1, type, op1_range, tmp)
     515      2891091 :       || !cast.fold_range (op2, type, op2_range, tmp))
     516              :     return false;
     517              : 
     518      2891091 :   return minus_op1_op2_relation_effect (lhs_range, type, op1, op2, rel);
     519      2891091 : }
     520              : 
     521              : bool
     522      1605331 : operator_identity::fold_range (prange &r, tree type ATTRIBUTE_UNUSED,
     523              :                                const prange &lh ATTRIBUTE_UNUSED,
     524              :                                const prange &rh ATTRIBUTE_UNUSED,
     525              :                                relation_trio) const
     526              : {
     527      1605331 :   r = lh;
     528      1605331 :   return true;
     529              : }
     530              : 
     531              : relation_kind
     532      1442115 : operator_identity::lhs_op1_relation (const prange &lhs,
     533              :                                      const prange &op1 ATTRIBUTE_UNUSED,
     534              :                                      const prange &op2 ATTRIBUTE_UNUSED,
     535              :                                      relation_kind) const
     536              : {
     537      1442115 :   if (lhs.undefined_p ())
     538          400 :     return VREL_VARYING;
     539              :   // Simply a copy, so they are equivalent.
     540              :   return VREL_EQ;
     541              : }
     542              : 
     543              : bool
     544       209935 : operator_identity::op1_range (prange &r, tree type ATTRIBUTE_UNUSED,
     545              :                               const prange &lhs,
     546              :                               const prange &op2 ATTRIBUTE_UNUSED,
     547              :                               relation_trio) const
     548              : {
     549       209935 :   r = lhs;
     550       209935 :   return true;
     551              : }
     552              : 
     553              : bool
     554        19995 : operator_cst::fold_range (prange &r, tree type ATTRIBUTE_UNUSED,
     555              :                           const prange &lh,
     556              :                           const prange & ATTRIBUTE_UNUSED,
     557              :                           relation_trio) const
     558              : {
     559        19995 :   r = lh;
     560        19995 :   return true;
     561              : }
     562              : 
     563              : // Cast between pointers.
     564              : 
     565              : bool
     566     17736575 : operator_cast::fold_range (prange &r, tree type,
     567              :                            const prange &inner,
     568              :                            const prange &outer,
     569              :                            relation_trio) const
     570              : {
     571     17736575 :   if (empty_range_varying (r, type, inner, outer))
     572          569 :     return true;
     573              : 
     574     17736006 :   r.set (type, inner.lower_bound (), inner.upper_bound ());
     575              : 
     576              :   // The resulting pointer still points to the same object.
     577     17736006 :   r.set_pt (inner);
     578              : 
     579     17736006 :   r.update_bitmask (inner.get_bitmask ());
     580     17736006 :   return true;
     581              : }
     582              : 
     583              : // Cast a pointer to an integer.
     584              : 
     585              : bool
     586     11704112 : operator_cast::fold_range (irange &r, tree type,
     587              :                            const prange &inner,
     588              :                            const irange &outer,
     589              :                            relation_trio) const
     590              : {
     591     11704112 :   if (empty_range_varying (r, type, inner, outer))
     592      5783595 :     return true;
     593              : 
     594              :   // Represent INNER as an integer of the same size, and then cast it
     595              :   // to the resulting integer type.
     596      5920517 :   tree pointer_uint_type = make_unsigned_type (TYPE_PRECISION (inner.type ()));
     597      5920517 :   r.set (pointer_uint_type, inner.lower_bound (), inner.upper_bound ());
     598      5920517 :   r.update_bitmask (inner.get_bitmask ());
     599      5920517 :   range_cast (r, type);
     600      5920517 :   return true;
     601              : }
     602              : 
     603              : // Cast an integer to a pointer.
     604              : 
     605              : bool
     606      2150852 : operator_cast::fold_range (prange &r, tree type,
     607              :                            const irange &inner,
     608              :                            const prange &outer,
     609              :                            relation_trio) const
     610              : {
     611      2150852 :   if (empty_range_varying (r, type, inner, outer))
     612         1782 :     return true;
     613              : 
     614              :   // Cast INNER to an integer of the same size as the pointer we want,
     615              :   // and then copy the bounds to the resulting pointer range.
     616      2149070 :   int_range<2> tmp = inner;
     617      2149070 :   tree pointer_uint_type = make_unsigned_type (TYPE_PRECISION (type));
     618      2149070 :   range_cast (tmp, pointer_uint_type);
     619              :   // Casts may cause ranges to become UNDEFINED based on bitmasks.
     620      2149070 :   if (tmp.undefined_p ())
     621            0 :     r.set_varying (type);
     622              :   else
     623              :     {
     624      2149070 :       r.set (type, tmp.lower_bound (), tmp.upper_bound ());
     625      2149070 :       r.update_bitmask (tmp.get_bitmask ());
     626              :     }
     627      2149070 :   return true;
     628      2149070 : }
     629              : 
     630              : bool
     631           69 : operator_cast::op1_range (prange &r, tree type,
     632              :                           const prange &lhs,
     633              :                           const prange &op2,
     634              :                           relation_trio trio) const
     635              : {
     636           69 :   if (lhs.undefined_p ())
     637              :     return false;
     638           69 :   gcc_checking_assert (types_compatible_p (op2.type(), type));
     639              : 
     640              :   // Conversion from other pointers or a constant (including 0/NULL)
     641              :   // are straightforward.
     642           69 :   if (POINTER_TYPE_P (lhs.type ())
     643           69 :       || (lhs.singleton_p ()
     644            0 :           && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
     645           69 :     fold_range (r, type, lhs, op2, trio);
     646              :   else
     647              :     {
     648              :       // If the LHS is not a pointer nor a singleton, then it is
     649              :       // either VARYING or non-zero.
     650            0 :       if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
     651            0 :         r.set_nonzero (type);
     652              :       else
     653            0 :         r.set_varying (type);
     654              :     }
     655           69 :   r.intersect (op2);
     656           69 :   return true;
     657              : }
     658              : 
     659              : bool
     660       255816 : operator_cast::op1_range (irange &r, tree type,
     661              :                           const prange &lhs,
     662              :                           const irange &op2,
     663              :                           relation_trio trio) const
     664              : {
     665       255816 :   if (lhs.undefined_p ())
     666              :     return false;
     667       255816 :   gcc_checking_assert (types_compatible_p (op2.type(), type));
     668              : 
     669              :   // Conversion from other pointers or a constant (including 0/NULL)
     670              :   // are straightforward.
     671       255816 :   if (POINTER_TYPE_P (lhs.type ())
     672       255816 :       || (lhs.singleton_p ()
     673            0 :           && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
     674       255816 :     fold_range (r, type, lhs, op2, trio);
     675              :   else
     676              :     {
     677              :       // If the LHS is not a pointer nor a singleton, then it is
     678              :       // either VARYING or non-zero.
     679            0 :       if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
     680            0 :         r.set_nonzero (type);
     681              :       else
     682            0 :         r.set_varying (type);
     683              :     }
     684       255816 :   r.intersect (op2);
     685       255816 :   return true;
     686              : }
     687              : 
     688              : bool
     689       539232 : operator_cast::op1_range (prange &r, tree type,
     690              :                           const irange &lhs,
     691              :                           const prange &op2,
     692              :                           relation_trio trio) const
     693              : {
     694       539232 :   if (lhs.undefined_p ())
     695              :     return false;
     696       539232 :   gcc_checking_assert (types_compatible_p (op2.type(), type));
     697              : 
     698              :   // Conversion from other pointers or a constant (including 0/NULL)
     699              :   // are straightforward.
     700      1078464 :   if (POINTER_TYPE_P (lhs.type ())
     701      1078464 :       || (lhs.singleton_p ()
     702         1343 :           && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
     703         1337 :     fold_range (r, type, lhs, op2, trio);
     704              :   else
     705              :     {
     706              :       // If the LHS is not a pointer nor a singleton, then it is
     707              :       // either VARYING or non-zero.
     708       537895 :       if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
     709       240468 :         r.set_nonzero (type);
     710              :       else
     711       297427 :         r.set_varying (type);
     712              :     }
     713       539232 :   r.intersect (op2);
     714       539232 :   return true;
     715              : }
     716              : 
     717              : relation_kind
     718       137438 : operator_cast::lhs_op1_relation (const prange &lhs,
     719              :                                  const prange &op1,
     720              :                                  const prange &op2 ATTRIBUTE_UNUSED,
     721              :                                  relation_kind) const
     722              : {
     723       137438 :   if (lhs.undefined_p () || op1.undefined_p ())
     724              :     return VREL_VARYING;
     725       137438 :   unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
     726       137438 :   unsigned op1_prec = TYPE_PRECISION (op1.type ());
     727              :   // If the result gets sign extended into a larger type check first if this
     728              :   // qualifies as a partial equivalence.
     729       137438 :   if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
     730              :     {
     731              :       // If the result is sign extended, and the LHS is larger than op1,
     732              :       // check if op1's range can be negative as the sign extension will
     733              :       // cause the upper bits to be 1 instead of 0, invalidating the PE.
     734            0 :       int_range<3> negs = range_negatives (op1.type ());
     735            0 :       negs.intersect (op1);
     736            0 :       if (!negs.undefined_p ())
     737            0 :         return VREL_VARYING;
     738            0 :     }
     739              : 
     740              :   // If the pointer precisions are the same, check for equality and
     741              :   // inequality in the points to fields.
     742       137438 :   if (lhs_prec == op1_prec)
     743              :     {
     744       137438 :       if (lhs.pt_invariant_p (op1))
     745              :         return VREL_EQ;
     746       137317 :       if (lhs.pt_inverted_p (op1))
     747              :         return VREL_NE;
     748              :     }
     749       137317 :   unsigned prec = MIN (lhs_prec, op1_prec);
     750       137317 :   return bits_to_pe (prec);
     751              : }
     752              : 
     753              : relation_kind
     754      1609131 : operator_cast::lhs_op1_relation (const prange &lhs,
     755              :                                  const irange &op1,
     756              :                                  const irange &op2 ATTRIBUTE_UNUSED,
     757              :                                  relation_kind) const
     758              : {
     759      1609131 :   if (lhs.undefined_p () || op1.undefined_p ())
     760              :     return VREL_VARYING;
     761      1607363 :   unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
     762      1607363 :   unsigned op1_prec = TYPE_PRECISION (op1.type ());
     763              :   // If the result gets sign extended into a larger type check first if this
     764              :   // qualifies as a partial equivalence.
     765      1607363 :   if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
     766              :     {
     767              :       // If the result is sign extended, and the LHS is larger than op1,
     768              :       // check if op1's range can be negative as the sign extension will
     769              :       // cause the upper bits to be 1 instead of 0, invalidating the PE.
     770          222 :       int_range<3> negs = range_negatives (op1.type ());
     771          222 :       negs.intersect (op1);
     772          222 :       if (!negs.undefined_p ())
     773          214 :         return VREL_VARYING;
     774          222 :     }
     775              : 
     776      1607149 :   unsigned prec = MIN (lhs_prec, op1_prec);
     777      1607149 :   return bits_to_pe (prec);
     778              : }
     779              : 
     780              : relation_kind
     781      2321737 : operator_cast::lhs_op1_relation (const irange &lhs,
     782              :                                  const prange &op1,
     783              :                                  const prange &op2 ATTRIBUTE_UNUSED,
     784              :                                  relation_kind) const
     785              : {
     786      2321737 :   if (lhs.undefined_p () || op1.undefined_p ())
     787              :     return VREL_VARYING;
     788      2320780 :   unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
     789      2320780 :   unsigned op1_prec = TYPE_PRECISION (op1.type ());
     790              :   // If the result gets sign extended into a larger type check first if this
     791              :   // qualifies as a partial equivalence.
     792      2320780 :   if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
     793              :     {
     794              :       // If the result is sign extended, and the LHS is larger than op1,
     795              :       // check if op1's range can be negative as the sign extension will
     796              :       // cause the upper bits to be 1 instead of 0, invalidating the PE.
     797            0 :       int_range<3> negs = range_negatives (op1.type ());
     798            0 :       negs.intersect (op1);
     799            0 :       if (!negs.undefined_p ())
     800            0 :         return VREL_VARYING;
     801            0 :     }
     802              : 
     803      2320780 :   unsigned prec = MIN (lhs_prec, op1_prec);
     804      2320780 :   return bits_to_pe (prec);
     805              : }
     806              : 
     807              : bool
     808         1318 : operator_min::fold_range (prange &r, tree type,
     809              :                           const prange &op1,
     810              :                           const prange &op2,
     811              :                           relation_trio) const
     812              : {
     813              :   // For MIN/MAX expressions with pointers, we only care about
     814              :   // nullness.  If both are non null, then the result is nonnull.
     815              :   // If both are null, then the result is null.  Otherwise they
     816              :   // are varying.
     817         1318 :   if (!range_includes_zero_p (op1)
     818         1318 :       && !range_includes_zero_p (op2))
     819          148 :     r.set_nonzero (type);
     820         1170 :   else if (op1.zero_p () && op2.zero_p ())
     821            0 :     r.set_zero (type);
     822              :   else
     823         1170 :     r.set_varying (type);
     824              : 
     825         1318 :   update_known_bitmask (r, MIN_EXPR, op1, op2);
     826         1318 :   return true;
     827              : }
     828              : 
     829              : bool
     830         1313 : operator_max::fold_range (prange &r, tree type,
     831              :                           const prange &op1,
     832              :                           const prange &op2,
     833              :                           relation_trio) const
     834              : {
     835              :   // For MIN/MAX expressions with pointers, we only care about
     836              :   // nullness.  If both are non null, then the result is nonnull.
     837              :   // If both are null, then the result is null.  Otherwise they
     838              :   // are varying.
     839         1313 :   if (!range_includes_zero_p (op1)
     840         1313 :       && !range_includes_zero_p (op2))
     841          114 :     r.set_nonzero (type);
     842         1199 :   else if (op1.zero_p () && op2.zero_p ())
     843            0 :     r.set_zero (type);
     844              :   else
     845         1199 :     r.set_varying (type);
     846              : 
     847         1313 :   update_known_bitmask (r, MAX_EXPR, op1, op2);
     848         1313 :   return true;
     849              : }
     850              : 
     851              : bool
     852       669182 : operator_addr_expr::op1_range (prange &r, tree type,
     853              :                                const prange &lhs,
     854              :                                const prange &op2,
     855              :                                relation_trio) const
     856              : {
     857       669182 :   if (empty_range_varying (r, type, lhs, op2))
     858            0 :     return true;
     859              : 
     860              :   // Return a non-null pointer of the LHS type (passed in op2), but only
     861              :   // if we cant overflow, eitherwise a no-zero offset could wrap to zero.
     862              :   // See PR 111009.
     863       669182 :   if (!lhs.undefined_p ()
     864       669182 :       && !range_includes_zero_p (lhs)
     865       662247 :       && TYPE_OVERFLOW_UNDEFINED (type))
     866       662231 :     r.set_nonzero (type);
     867              :   else
     868         6951 :     r.set_varying (type);
     869              :   return true;
     870              : }
     871              : 
     872              : bool
     873          857 : operator_bitwise_and::fold_range (prange &r, tree type,
     874              :                                   const prange &op1,
     875              :                                   const prange &op2 ATTRIBUTE_UNUSED,
     876              :                                   relation_trio) const
     877              : {
     878              :   // For pointer types, we are really only interested in asserting
     879              :   // whether the expression evaluates to non-NULL.
     880          857 :   if (op1.zero_p () || op2.zero_p ())
     881            0 :     r.set_zero (type);
     882              :   else
     883          857 :     r.set_varying (type);
     884              : 
     885          857 :   update_known_bitmask (r, BIT_AND_EXPR, op1, op2);
     886          857 :   return true;
     887              : }
     888              : 
     889              : bool
     890      6944558 : operator_equal::fold_range (irange &r, tree type,
     891              :                             const prange &op1,
     892              :                             const prange &op2,
     893              :                             relation_trio rel) const
     894              : {
     895      6944558 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_EQ))
     896              :     return true;
     897              : 
     898              :   // We can be sure the values are always equal or not if both ranges
     899              :   // consist of a single value, and then compare them.
     900      6921597 :   bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ());
     901      6921597 :   bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ());
     902              :   // Check for points to equality and inequality first.
     903      6921597 :   if (op1.pt_invariant_p (op2))
     904        14561 :     r = range_true (type);
     905      6907036 :   else if (op1.pt_inverted_p (op2))
     906            0 :     r = range_false (type);
     907      6907036 :   else if (op1_const && op2_const)
     908              :     {
     909        31602 :       if (wi::eq_p (op1.lower_bound (), op2.upper_bound()))
     910        31441 :         r = range_true (type);
     911              :       else
     912          161 :         r = range_false (type);
     913              :     }
     914              :   else
     915              :     {
     916              :       // If ranges do not intersect, we know the range is not equal,
     917              :       // otherwise we don't know anything for sure.
     918      6875434 :       prange tmp = op1;
     919      6875434 :       tmp.intersect (op2);
     920      6875434 :       if (tmp.undefined_p ())
     921       177385 :         r = range_false (type);
     922              :       // Check if a constant cannot satisfy the bitmask requirements.
     923     11591695 :       else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ()))
     924            0 :          r = range_false (type);
     925      6707765 :       else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ()))
     926            0 :          r = range_false (type);
     927              :       else
     928      6698049 :         r = range_true_and_false (type);
     929      6875434 :     }
     930              : 
     931              :   //update_known_bitmask (r, EQ_EXPR, op1, op2);
     932              :   return true;
     933              : }
     934              : 
     935              : bool
     936      4554201 : operator_equal::op1_range (prange &r, tree type,
     937              :                            const irange &lhs,
     938              :                            const prange &op2,
     939              :                            relation_trio) const
     940              : {
     941      4554201 :   switch (get_bool_state (r, lhs, type))
     942              :     {
     943      1260859 :     case BRS_TRUE:
     944              :       // If it's true, the result is the same as OP2.
     945      1260859 :       r = op2;
     946      1260859 :       break;
     947              : 
     948      3285772 :     case BRS_FALSE:
     949              :       // If the result is false, the only time we know anything is
     950              :       // if OP2 is a constant.
     951      3285772 :       if (!op2.undefined_p ()
     952      9857316 :           && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
     953              :         {
     954      1064675 :           r = op2;
     955      1064675 :           if (!r.invert ())
     956              :             return false;
     957              :         }
     958              :       else
     959      2221097 :         r.set_varying (type);
     960              :       break;
     961              : 
     962              :     default:
     963              :       break;
     964              :     }
     965              :   return true;
     966              : }
     967              : 
     968              : bool
     969      1570674 : operator_equal::op2_range (prange &r, tree type,
     970              :                            const irange &lhs,
     971              :                            const prange &op1,
     972              :                            relation_trio rel) const
     973              : {
     974      1570674 :   return operator_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
     975              : }
     976              : 
     977              : relation_kind
     978      5810154 : operator_equal::op1_op2_relation (const irange &lhs, const prange &,
     979              :                                   const prange &) const
     980              : {
     981      5810154 :   if (lhs.undefined_p ())
     982              :     return VREL_UNDEFINED;
     983              : 
     984              :   // FALSE = op1 == op2 indicates NE_EXPR.
     985      5810154 :   if (lhs.zero_p ())
     986              :     return VREL_NE;
     987              : 
     988              :   // TRUE = op1 == op2 indicates EQ_EXPR.
     989      2632158 :   if (!range_includes_zero_p (lhs))
     990      2631526 :     return VREL_EQ;
     991              :   return VREL_VARYING;
     992              : }
     993              : 
     994              : bool
     995      8234303 : operator_not_equal::fold_range (irange &r, tree type,
     996              :                                 const prange &op1,
     997              :                                 const prange &op2,
     998              :                                 relation_trio rel) const
     999              : {
    1000      8234303 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_NE))
    1001              :     return true;
    1002              : 
    1003              :   // We can be sure the values are always equal or not if both ranges
    1004              :   // consist of a single value, and then compare them.
    1005      8212537 :   bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ());
    1006      8212537 :   bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ());
    1007              :   // Check for points to equality and inequality first.
    1008      8212537 :   if (op1.pt_inverted_p (op2))
    1009            0 :     r = range_true (type);
    1010      8212537 :   else if (op1.pt_invariant_p (op2))
    1011         2654 :     r = range_false (type);
    1012      8209883 :   else if (op1_const && op2_const)
    1013              :     {
    1014        59129 :       if (wi::ne_p (op1.lower_bound (), op2.upper_bound()))
    1015          190 :         r = range_true (type);
    1016              :       else
    1017        58939 :         r = range_false (type);
    1018              :     }
    1019              :   else
    1020              :     {
    1021              :       // If ranges do not intersect, we know the range is not equal,
    1022              :       // otherwise we don't know anything for sure.
    1023      8150754 :       prange tmp = op1;
    1024      8150754 :       tmp.intersect (op2);
    1025      8150754 :       if (tmp.undefined_p ())
    1026       208572 :         r = range_true (type);
    1027              :       // Check if a constant cannot satisfy the bitmask requirements.
    1028     16909902 :       else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ()))
    1029            0 :          r = range_true (type);
    1030      7945788 :       else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ()))
    1031            0 :          r = range_true (type);
    1032              :       else
    1033      7942182 :         r = range_true_and_false (type);
    1034      8150754 :     }
    1035              : 
    1036              :   //update_known_bitmask (r, NE_EXPR, op1, op2);
    1037              :   return true;
    1038              : }
    1039              : 
    1040              : bool
    1041      5442732 : operator_not_equal::op1_range (prange &r, tree type,
    1042              :                                const irange &lhs,
    1043              :                                const prange &op2,
    1044              :                                relation_trio) const
    1045              : {
    1046      5442732 :   switch (get_bool_state (r, lhs, type))
    1047              :     {
    1048      4275780 :     case BRS_TRUE:
    1049              :       // If the result is true, the only time we know anything is if
    1050              :       // OP2 is a constant.
    1051      4275780 :       if (!op2.undefined_p ()
    1052     12827340 :           && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
    1053              :         {
    1054      1679541 :           r = op2;
    1055      1679541 :           if (!r.invert ())
    1056              :             return false;
    1057              :         }
    1058              :       else
    1059      2596239 :         r.set_varying (type);
    1060              :       break;
    1061              : 
    1062      1142803 :     case BRS_FALSE:
    1063              :       // If it's false, the result is the same as OP2.
    1064      1142803 :       r = op2;
    1065      1142803 :       break;
    1066              : 
    1067              :     default:
    1068              :       break;
    1069              :     }
    1070              :   return true;
    1071              : }
    1072              : 
    1073              : 
    1074              : bool
    1075      1645516 : operator_not_equal::op2_range (prange &r, tree type,
    1076              :                                const irange &lhs,
    1077              :                                const prange &op1,
    1078              :                                relation_trio rel) const
    1079              : {
    1080      1645516 :   return operator_not_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
    1081              : }
    1082              : 
    1083              : relation_kind
    1084      6205574 : operator_not_equal::op1_op2_relation (const irange &lhs, const prange &,
    1085              :                                       const prange &) const
    1086              : {
    1087      6205574 :   if (lhs.undefined_p ())
    1088              :     return VREL_UNDEFINED;
    1089              : 
    1090              :   // FALSE = op1 != op2  indicates EQ_EXPR.
    1091      6205574 :   if (lhs.zero_p ())
    1092              :     return VREL_EQ;
    1093              : 
    1094              :   // TRUE = op1 != op2  indicates NE_EXPR.
    1095      4133965 :   if (!range_includes_zero_p (lhs))
    1096      4129208 :     return VREL_NE;
    1097              :   return VREL_VARYING;
    1098              : }
    1099              : 
    1100              : bool
    1101       405239 : operator_lt::fold_range (irange &r, tree type,
    1102              :                          const prange &op1,
    1103              :                          const prange &op2,
    1104              :                          relation_trio rel) const
    1105              : {
    1106       405239 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_LT))
    1107              :     return true;
    1108              : 
    1109       402941 :   signop sign = TYPE_SIGN (op1.type ());
    1110       402941 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1111              : 
    1112       402941 :   if (wi::lt_p (op1.upper_bound (), op2.lower_bound (), sign))
    1113            2 :     r = range_true (type);
    1114       402939 :   else if (!wi::lt_p (op1.lower_bound (), op2.upper_bound (), sign))
    1115           28 :     r = range_false (type);
    1116              :   // Use nonzero bits to determine if < 0 is false.
    1117       402911 :   else if (op2.zero_p () && !wi::neg_p (op1.get_nonzero_bits (), sign))
    1118            0 :     r = range_false (type);
    1119              :   else
    1120       402911 :     r = range_true_and_false (type);
    1121              : 
    1122              :   //update_known_bitmask (r, LT_EXPR, op1, op2);
    1123              :   return true;
    1124              : }
    1125              : 
    1126              : bool
    1127       305212 : operator_lt::op1_range (prange &r, tree type,
    1128              :                         const irange &lhs,
    1129              :                         const prange &op2,
    1130              :                         relation_trio) const
    1131              : {
    1132       305212 :   if (op2.undefined_p ())
    1133              :     return false;
    1134              : 
    1135       305212 :   switch (get_bool_state (r, lhs, type))
    1136              :     {
    1137       259978 :     case BRS_TRUE:
    1138       259978 :       build_lt (r, type, op2);
    1139       259978 :       break;
    1140              : 
    1141        45234 :     case BRS_FALSE:
    1142        45234 :       build_ge (r, type, op2);
    1143        45234 :       break;
    1144              : 
    1145              :     default:
    1146              :       break;
    1147              :     }
    1148              :   return true;
    1149              : }
    1150              : 
    1151              : bool
    1152       187938 : operator_lt::op2_range (prange &r, tree type,
    1153              :                         const irange &lhs,
    1154              :                         const prange &op1,
    1155              :                         relation_trio) const
    1156              : {
    1157       187938 :   if (op1.undefined_p ())
    1158              :     return false;
    1159              : 
    1160       187938 :   switch (get_bool_state (r, lhs, type))
    1161              :     {
    1162       132234 :     case BRS_TRUE:
    1163       132234 :       build_gt (r, type, op1);
    1164       132234 :       break;
    1165              : 
    1166        55700 :     case BRS_FALSE:
    1167        55700 :       build_le (r, type, op1);
    1168        55700 :       break;
    1169              : 
    1170              :     default:
    1171              :       break;
    1172              :     }
    1173              :   return true;
    1174              : }
    1175              : 
    1176              : relation_kind
    1177       857234 : operator_lt::op1_op2_relation (const irange &lhs, const prange &,
    1178              :                                const prange &) const
    1179              : {
    1180       857234 :   if (lhs.undefined_p ())
    1181              :     return VREL_UNDEFINED;
    1182              : 
    1183              :   // FALSE = op1 < op2 indicates GE_EXPR.
    1184       857234 :   if (lhs.zero_p ())
    1185              :     return VREL_GE;
    1186              : 
    1187              :   // TRUE = op1 < op2 indicates LT_EXPR.
    1188       631099 :   if (!range_includes_zero_p (lhs))
    1189       630679 :     return VREL_LT;
    1190              :   return VREL_VARYING;
    1191              : }
    1192              : 
    1193              : bool
    1194       126048 : operator_le::fold_range (irange &r, tree type,
    1195              :                          const prange &op1,
    1196              :                          const prange &op2,
    1197              :                          relation_trio rel) const
    1198              : {
    1199       126048 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_LE))
    1200              :     return true;
    1201              : 
    1202       125611 :   signop sign = TYPE_SIGN (op1.type ());
    1203       125611 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1204              : 
    1205       125611 :   if (wi::le_p (op1.upper_bound (), op2.lower_bound (), sign))
    1206           43 :     r = range_true (type);
    1207       125568 :   else if (!wi::le_p (op1.lower_bound (), op2.upper_bound (), sign))
    1208           10 :     r = range_false (type);
    1209              :   else
    1210       125558 :     r = range_true_and_false (type);
    1211              : 
    1212              :   //update_known_bitmask (r, LE_EXPR, op1, op2);
    1213              :   return true;
    1214              : }
    1215              : 
    1216              : bool
    1217        87159 : operator_le::op1_range (prange &r, tree type,
    1218              :                         const irange &lhs,
    1219              :                         const prange &op2,
    1220              :                         relation_trio) const
    1221              : {
    1222        87159 :   if (op2.undefined_p ())
    1223              :     return false;
    1224              : 
    1225        87159 :   switch (get_bool_state (r, lhs, type))
    1226              :     {
    1227        64626 :     case BRS_TRUE:
    1228        64626 :       build_le (r, type, op2);
    1229        64626 :       break;
    1230              : 
    1231        22533 :     case BRS_FALSE:
    1232        22533 :       build_gt (r, type, op2);
    1233        22533 :       break;
    1234              : 
    1235              :     default:
    1236              :       break;
    1237              :     }
    1238              :   return true;
    1239              : }
    1240              : 
    1241              : bool
    1242       128069 : operator_le::op2_range (prange &r, tree type,
    1243              :                         const irange &lhs,
    1244              :                         const prange &op1,
    1245              :                         relation_trio) const
    1246              : {
    1247       128069 :   if (op1.undefined_p ())
    1248              :     return false;
    1249              : 
    1250       128069 :   switch (get_bool_state (r, lhs, type))
    1251              :     {
    1252       106865 :     case BRS_TRUE:
    1253       106865 :       build_ge (r, type, op1);
    1254       106865 :       break;
    1255              : 
    1256        21204 :     case BRS_FALSE:
    1257        21204 :       build_lt (r, type, op1);
    1258        21204 :       break;
    1259              : 
    1260              :     default:
    1261              :       break;
    1262              :     }
    1263              :   return true;
    1264              : }
    1265              : 
    1266              : relation_kind
    1267       365343 : operator_le::op1_op2_relation (const irange &lhs, const prange &,
    1268              :                                const prange &) const
    1269              : {
    1270       365343 :   if (lhs.undefined_p ())
    1271              :     return VREL_UNDEFINED;
    1272              : 
    1273              :   // FALSE = op1 <= op2 indicates GT_EXPR.
    1274       365343 :   if (lhs.zero_p ())
    1275              :     return VREL_GT;
    1276              : 
    1277              :   // TRUE = op1 <= op2 indicates LE_EXPR.
    1278       269827 :   if (!range_includes_zero_p (lhs))
    1279       269083 :     return VREL_LE;
    1280              :   return VREL_VARYING;
    1281              : }
    1282              : 
    1283              : bool
    1284       419225 : operator_gt::fold_range (irange &r, tree type,
    1285              :                          const prange &op1, const prange &op2,
    1286              :                          relation_trio rel) const
    1287              : {
    1288       419225 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_GT))
    1289              :     return true;
    1290              : 
    1291       416771 :   signop sign = TYPE_SIGN (op1.type ());
    1292       416771 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1293              : 
    1294       416771 :   if (wi::gt_p (op1.lower_bound (), op2.upper_bound (), sign))
    1295            2 :     r = range_true (type);
    1296       416769 :   else if (!wi::gt_p (op1.upper_bound (), op2.lower_bound (), sign))
    1297            9 :     r = range_false (type);
    1298              :   else
    1299       416760 :     r = range_true_and_false (type);
    1300              : 
    1301              :   //update_known_bitmask (r, GT_EXPR, op1, op2);
    1302              :   return true;
    1303              : }
    1304              : 
    1305              : bool
    1306       263675 : operator_gt::op1_range (prange &r, tree type,
    1307              :                         const irange &lhs, const prange &op2,
    1308              :                         relation_trio) const
    1309              : {
    1310       263675 :   if (op2.undefined_p ())
    1311              :     return false;
    1312              : 
    1313       263675 :   switch (get_bool_state (r, lhs, type))
    1314              :     {
    1315       171824 :     case BRS_TRUE:
    1316       171824 :       build_gt (r, type, op2);
    1317       171824 :       break;
    1318              : 
    1319        91851 :     case BRS_FALSE:
    1320        91851 :       build_le (r, type, op2);
    1321        91851 :       break;
    1322              : 
    1323              :     default:
    1324              :       break;
    1325              :     }
    1326              :   return true;
    1327              : }
    1328              : 
    1329              : bool
    1330       252864 : operator_gt::op2_range (prange &r, tree type,
    1331              :                         const irange &lhs,
    1332              :                         const prange &op1,
    1333              :                         relation_trio) const
    1334              : {
    1335       252864 :   if (op1.undefined_p ())
    1336              :     return false;
    1337              : 
    1338       252864 :   switch (get_bool_state (r, lhs, type))
    1339              :     {
    1340       197042 :     case BRS_TRUE:
    1341       197042 :       build_lt (r, type, op1);
    1342       197042 :       break;
    1343              : 
    1344        55822 :     case BRS_FALSE:
    1345        55822 :       build_ge (r, type, op1);
    1346        55822 :       break;
    1347              : 
    1348              :     default:
    1349              :       break;
    1350              :     }
    1351              :   return true;
    1352              : }
    1353              : 
    1354              : relation_kind
    1355       905832 : operator_gt::op1_op2_relation (const irange &lhs, const prange &,
    1356              :                                const prange &) const
    1357              : {
    1358       905832 :   if (lhs.undefined_p ())
    1359              :     return VREL_UNDEFINED;
    1360              : 
    1361              :   // FALSE = op1 > op2 indicates LE_EXPR.
    1362       905832 :   if (lhs.zero_p ())
    1363              :     return VREL_LE;
    1364              : 
    1365              :   // TRUE = op1 > op2 indicates GT_EXPR.
    1366       626210 :   if (!range_includes_zero_p (lhs))
    1367       626168 :     return VREL_GT;
    1368              :   return VREL_VARYING;
    1369              : }
    1370              : 
    1371              : bool
    1372       208155 : operator_ge::fold_range (irange &r, tree type,
    1373              :                          const prange &op1,
    1374              :                          const prange &op2,
    1375              :                          relation_trio rel) const
    1376              : {
    1377       208155 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_GE))
    1378              :     return true;
    1379              : 
    1380       207855 :   signop sign = TYPE_SIGN (op1.type ());
    1381       207855 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1382              : 
    1383       207855 :   if (wi::ge_p (op1.lower_bound (), op2.upper_bound (), sign))
    1384           65 :     r = range_true (type);
    1385       207790 :   else if (!wi::ge_p (op1.upper_bound (), op2.lower_bound (), sign))
    1386            0 :     r = range_false (type);
    1387              :   else
    1388       207790 :     r = range_true_and_false (type);
    1389              : 
    1390              :   //update_known_bitmask (r, GE_EXPR, op1, op2);
    1391              :   return true;
    1392              : }
    1393              : 
    1394              : bool
    1395       199919 : operator_ge::op1_range (prange &r, tree type,
    1396              :                         const irange &lhs,
    1397              :                         const prange &op2,
    1398              :                         relation_trio) const
    1399              : {
    1400       199919 :   if (op2.undefined_p ())
    1401              :     return false;
    1402              : 
    1403       199919 :   switch (get_bool_state (r, lhs, type))
    1404              :     {
    1405       175525 :     case BRS_TRUE:
    1406       175525 :       build_ge (r, type, op2);
    1407       175525 :       break;
    1408              : 
    1409        24394 :     case BRS_FALSE:
    1410        24394 :       build_lt (r, type, op2);
    1411        24394 :       break;
    1412              : 
    1413              :     default:
    1414              :       break;
    1415              :     }
    1416              :   return true;
    1417              : }
    1418              : 
    1419              : bool
    1420        87334 : operator_ge::op2_range (prange &r, tree type,
    1421              :                         const irange &lhs,
    1422              :                         const prange &op1,
    1423              :                         relation_trio) const
    1424              : {
    1425        87334 :   if (op1.undefined_p ())
    1426              :     return false;
    1427              : 
    1428        87334 :   switch (get_bool_state (r, lhs, type))
    1429              :     {
    1430        61783 :     case BRS_TRUE:
    1431        61783 :       build_le (r, type, op1);
    1432        61783 :       break;
    1433              : 
    1434        25551 :     case BRS_FALSE:
    1435        25551 :       build_gt (r, type, op1);
    1436        25551 :       break;
    1437              : 
    1438              :     default:
    1439              :       break;
    1440              :     }
    1441              :   return true;
    1442              : }
    1443              : 
    1444              : relation_kind
    1445       521601 : operator_ge::op1_op2_relation (const irange &lhs, const prange &,
    1446              :                                const prange &) const
    1447              : {
    1448       521601 :   if (lhs.undefined_p ())
    1449              :     return VREL_UNDEFINED;
    1450              : 
    1451              :   // FALSE = op1 >= op2 indicates LT_EXPR.
    1452       521601 :   if (lhs.zero_p ())
    1453              :     return VREL_LT;
    1454              : 
    1455              :   // TRUE = op1 >= op2 indicates GE_EXPR.
    1456       392275 :   if (!range_includes_zero_p (lhs))
    1457       392263 :     return VREL_GE;
    1458              :   return VREL_VARYING;
    1459              : }
    1460              : 
    1461              : // Initialize any pointer operators to the primary table
    1462              : 
    1463              : void
    1464       293026 : range_op_table::initialize_pointer_ops ()
    1465              : {
    1466       293026 :   set (POINTER_PLUS_EXPR, op_pointer_plus);
    1467       293026 :   set (POINTER_DIFF_EXPR, op_pointer_diff);
    1468       293026 : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.