LCOV - code coverage report
Current view: top level - gcc - range-op-ptr.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.2 % 500 426
Test Date: 2026-06-20 15:32:29 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          152 : range_operator::op1_range (prange &, tree,
     134              :                            const prange &lhs ATTRIBUTE_UNUSED,
     135              :                            const prange &op2 ATTRIBUTE_UNUSED,
     136              :                            relation_trio) const
     137              : {
     138          152 :   return false;
     139              : }
     140              : 
     141              : bool
     142       774220 : range_operator::op1_range (prange &, tree,
     143              :                            const irange &lhs ATTRIBUTE_UNUSED,
     144              :                            const prange &op2 ATTRIBUTE_UNUSED,
     145              :                            relation_trio) const
     146              : {
     147       774220 :   return false;
     148              : }
     149              : 
     150              : bool
     151       399343 : range_operator::op1_range (prange &, tree,
     152              :                            const prange &lhs ATTRIBUTE_UNUSED,
     153              :                            const irange &op2 ATTRIBUTE_UNUSED,
     154              :                            relation_trio) const
     155              : {
     156       399343 :   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      1148418 : range_operator::op2_range (prange &, tree,
     170              :                            const irange &lhs ATTRIBUTE_UNUSED,
     171              :                            const prange &op1 ATTRIBUTE_UNUSED,
     172              :                            relation_trio) const
     173              : {
     174      1148418 :   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      1866465 : 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      1866465 :   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      3818117 : 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      3818117 :   return VREL_VARYING;
     210              : }
     211              : 
     212              : relation_kind
     213        77209 : 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        77209 :   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       670266 : max_limit (const_tree type)
     241              : {
     242       670266 :   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       705490 : min_limit (const_tree type)
     249              : {
     250       705490 :   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       459628 : build_lt (prange &r, tree type, const prange &val)
     257              : {
     258       459628 :   wi::overflow_type ov;
     259       459628 :   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       459628 :   if (ov)
     263            0 :     r.set_undefined ();
     264              :   else
     265       459628 :     r.set (type, min_limit (type), lim);
     266       459628 : }
     267              : 
     268              : // Build a range that is <= VAL and store it in R.
     269              : 
     270              : static void
     271       245862 : build_le (prange &r, tree type, const prange &val)
     272              : {
     273       245862 :   r.set (type, min_limit (type), val.upper_bound ());
     274       245862 : }
     275              : 
     276              : // Build a range that is > VAL and store it in R.
     277              : 
     278              : static void
     279       325693 : build_gt (prange &r, tree type, const prange &val)
     280              : {
     281       325693 :   wi::overflow_type ov;
     282       325693 :   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       325693 :   if (ov)
     286            0 :     r.set_undefined ();
     287              :   else
     288       325693 :     r.set (type, lim, max_limit (type));
     289              : 
     290       325693 : }
     291              : 
     292              : // Build a range that is >= VAL and store it in R.
     293              : 
     294              : static void
     295       344573 : build_ge (prange &r, tree type, const prange &val)
     296              : {
     297       344573 :   r.set (type, val.lower_bound (), max_limit (type));
     298       344573 : }
     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      9171140 : pointer_plus_operator::fold_range (prange &r, tree type,
     326              :                                    const prange &op1,
     327              :                                    const irange &op2,
     328              :                                    relation_trio) const
     329              : {
     330      9171140 :   if (empty_range_varying (r, type, op1, op2))
     331         5556 :     return true;
     332              : 
     333      9165584 :   const wide_int lh_lb = op1.lower_bound ();
     334      9165584 :   const wide_int lh_ub = op1.upper_bound ();
     335      9165584 :   const wide_int rh_lb = op2.lower_bound ();
     336      9165584 :   const wide_int rh_ub = op2.upper_bound ();
     337              : 
     338              :   // Check for [0,0] + const, and simply return the const.
     339      9173266 :   if (lh_lb == 0 && lh_ub == 0 && rh_lb == rh_ub)
     340              :     {
     341          519 :       r.set (type, rh_lb, rh_lb);
     342          519 :       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      9165065 :   if ((!wi_includes_zero_p (type, lh_lb, lh_ub)
     362      5521541 :        || !wi_includes_zero_p (type, rh_lb, rh_ub))
     363      5953410 :       && !TYPE_OVERFLOW_WRAPS (type)
     364     15117846 :       && (flag_delete_null_pointer_checks
     365         1293 :           || !wi::sign_mask (rh_ub)))
     366      5952366 :     r.set_nonzero (type);
     367      3219074 :   else if (lh_lb == lh_ub && lh_lb == 0
     368      3219074 :            && rh_lb == rh_ub && rh_lb == 0)
     369            0 :     r.set_zero (type);
     370              :   else
     371      3212699 :    r.set_varying (type);
     372              : 
     373              :   // If op1 refers to an object, op1 + 0 will also refer to the object.
     374      9165065 :   if (rh_lb == rh_ub && rh_lb == 0)
     375        17811 :     r.set_pt (op1);
     376              : 
     377      9165065 :   update_known_bitmask (r, POINTER_PLUS_EXPR, op1, op2);
     378      9165065 :   return true;
     379      9165584 : }
     380              : 
     381              : bool
     382       225851 : pointer_plus_operator::op2_range (irange &r, tree type,
     383              :                                   const prange &lhs,
     384              :                                   const prange &op1,
     385              :                                   relation_trio trio) const
     386              : {
     387       225851 :   relation_kind rel = trio.lhs_op1 ();
     388       225851 :   r.set_varying (type);
     389              : 
     390              :   // If the LHS and OP1 are equal, the op2 must be zero.
     391       225851 :   if (rel == VREL_EQ || lhs.pt_invariant_p (op1))
     392        11389 :     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       214462 :   else if (rel == VREL_NE || lhs.pt_inverted_p (op1))
     396        16991 :     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      7929526 : pointer_plus_operator::lhs_op1_relation (const prange &lhs,
     409              :                                          const prange &op1,
     410              :                                          const irange &op2,
     411              :                                          relation_kind) const
     412              : {
     413      7929526 :   if (lhs.undefined_p () || op1.undefined_p () || op2.undefined_p ())
     414              :     return VREL_VARYING;
     415              : 
     416      7924348 :   unsigned prec = TYPE_PRECISION (op2.type ());
     417              : 
     418              :   // LHS = OP1 + 0  indicates LHS == OP1.
     419      7924348 :   if (op2.zero_p ())
     420              :     return VREL_EQ;
     421              : 
     422      7908587 :   tree val;
     423              :   // Only deal with singletons for now.
     424      7908587 :   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      3833546 :       wide_int value = wi::to_wide (val);
     430              : 
     431              :       // Positive op2 means lhs > op1.
     432      3833546 :       if (wi::gt_p (value, wi::zero (prec), SIGNED))
     433              :         return VREL_GT;
     434              : 
     435              :       // Negative op2 means lhs < op1.
     436       426591 :       if (wi::lt_p (value, wi::zero (prec), SIGNED))
     437              :         return VREL_LT;
     438      3833546 :     }
     439              : 
     440              :   // If op2 does not contain 0, then LHS and OP1 can never be equal.
     441      4075041 :   if (!range_includes_zero_p (op2))
     442              :     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      2584462 :   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      2584462 : operator_pointer_diff::fold_range (irange &r, tree type,
     489              :                                    const prange &op1,
     490              :                                    const prange &op2,
     491              :                                    relation_trio trio) const
     492              : {
     493      2584462 :   gcc_checking_assert (r.supports_type_p (type));
     494              : 
     495      2584462 :   r.set_varying (type);
     496      2584462 :   relation_kind rel = trio.op1_op2 ();
     497      2584462 :   op1_op2_relation_effect (r, type, op1, op2, rel);
     498              :   // if op1 and op2 point to the same object, the diff is 0.
     499      2584462 :   if (op1.pt_invariant_p (op2))
     500          114 :     r.set_zero (type);
     501      2584462 :   update_bitmask (r, op1, op2);
     502      2584462 :   return true;
     503              : }
     504              : 
     505              : bool
     506      2584462 : 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      2584462 :   int_range<2> op1, op2, tmp;
     512      2584462 :   range_op_handler cast (CONVERT_EXPR);
     513              : 
     514      2584462 :   if (!cast.fold_range (op1, type, op1_range, tmp)
     515      2584462 :       || !cast.fold_range (op2, type, op2_range, tmp))
     516            0 :     return false;
     517              : 
     518      2584462 :   return minus_op1_op2_relation_effect (lhs_range, type, op1, op2, rel);
     519      2584462 : }
     520              : 
     521              : bool
     522      1315929 : 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      1315929 :   r = lh;
     528      1315929 :   return true;
     529              : }
     530              : 
     531              : relation_kind
     532      1167209 : 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      1167209 :   if (lhs.undefined_p ())
     538          356 :     return VREL_VARYING;
     539              :   // Simply a copy, so they are equivalent.
     540              :   return VREL_EQ;
     541              : }
     542              : 
     543              : bool
     544       193303 : 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       193303 :   r = lhs;
     550       193303 :   return true;
     551              : }
     552              : 
     553              : bool
     554        17723 : 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        17723 :   r = lh;
     560        17723 :   return true;
     561              : }
     562              : 
     563              : // Cast between pointers.
     564              : 
     565              : bool
     566     16325619 : operator_cast::fold_range (prange &r, tree type,
     567              :                            const prange &inner,
     568              :                            const prange &outer,
     569              :                            relation_trio) const
     570              : {
     571     16325619 :   if (empty_range_varying (r, type, inner, outer))
     572          518 :     return true;
     573              : 
     574     16325101 :   r.set (type, inner.lower_bound (), inner.upper_bound ());
     575              : 
     576              :   // The resulting pointer still points to the same object.
     577     16325101 :   r.set_pt (inner);
     578              : 
     579     16325101 :   r.update_bitmask (inner.get_bitmask ());
     580     16325101 :   return true;
     581              : }
     582              : 
     583              : // Cast a pointer to an integer.
     584              : 
     585              : bool
     586     10785886 : operator_cast::fold_range (irange &r, tree type,
     587              :                            const prange &inner,
     588              :                            const irange &outer,
     589              :                            relation_trio) const
     590              : {
     591     10785886 :   if (empty_range_varying (r, type, inner, outer))
     592      5170179 :     return true;
     593              : 
     594              :   // Represent INNER as an integer of the same size, and then cast it
     595              :   // to the resulting integer type.
     596      5615707 :   tree pointer_uint_type = make_unsigned_type (TYPE_PRECISION (inner.type ()));
     597      5615707 :   r.set (pointer_uint_type, inner.lower_bound (), inner.upper_bound ());
     598      5615707 :   r.update_bitmask (inner.get_bitmask ());
     599      5615707 :   range_cast (r, type);
     600      5615707 :   return true;
     601              : }
     602              : 
     603              : // Cast an integer to a pointer.
     604              : 
     605              : bool
     606      1868470 : operator_cast::fold_range (prange &r, tree type,
     607              :                            const irange &inner,
     608              :                            const prange &outer,
     609              :                            relation_trio) const
     610              : {
     611      1868470 :   if (empty_range_varying (r, type, inner, outer))
     612         1760 :     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      1866710 :   int_range<2> tmp = inner;
     617      1866710 :   tree pointer_uint_type = make_unsigned_type (TYPE_PRECISION (type));
     618      1866710 :   range_cast (tmp, pointer_uint_type);
     619              :   // Casts may cause ranges to become UNDEFINED based on bitmasks.
     620      1866710 :   if (tmp.undefined_p ())
     621            0 :     r.set_varying (type);
     622              :   else
     623              :     {
     624      1866710 :       r.set (type, tmp.lower_bound (), tmp.upper_bound ());
     625      1866710 :       r.update_bitmask (tmp.get_bitmask ());
     626              :     }
     627      1866710 :   return true;
     628      1866710 : }
     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       228654 : operator_cast::op1_range (irange &r, tree type,
     661              :                           const prange &lhs,
     662              :                           const irange &op2,
     663              :                           relation_trio trio) const
     664              : {
     665       228654 :   if (lhs.undefined_p ())
     666              :     return false;
     667       228654 :   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       228654 :   if (POINTER_TYPE_P (lhs.type ())
     672       228654 :       || (lhs.singleton_p ()
     673            0 :           && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
     674       228654 :     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       228654 :   r.intersect (op2);
     685       228654 :   return true;
     686              : }
     687              : 
     688              : bool
     689       504340 : operator_cast::op1_range (prange &r, tree type,
     690              :                           const irange &lhs,
     691              :                           const prange &op2,
     692              :                           relation_trio trio) const
     693              : {
     694       504340 :   if (lhs.undefined_p ())
     695              :     return false;
     696       504340 :   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      1008680 :   if (POINTER_TYPE_P (lhs.type ())
     701      1008680 :       || (lhs.singleton_p ()
     702         1217 :           && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
     703         1211 :     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       503129 :       if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
     709       224485 :         r.set_nonzero (type);
     710              :       else
     711       278644 :         r.set_varying (type);
     712              :     }
     713       504340 :   r.intersect (op2);
     714       504340 :   return true;
     715              : }
     716              : 
     717              : relation_kind
     718       137410 : operator_cast::lhs_op1_relation (const prange &lhs,
     719              :                                  const prange &op1,
     720              :                                  const prange &op2 ATTRIBUTE_UNUSED,
     721              :                                  relation_kind) const
     722              : {
     723       137410 :   if (lhs.undefined_p () || op1.undefined_p ())
     724              :     return VREL_VARYING;
     725       137410 :   unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
     726       137410 :   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       137410 :   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       137410 :   if (lhs_prec == op1_prec)
     743              :     {
     744       137410 :       if (lhs.pt_invariant_p (op1))
     745              :         return VREL_EQ;
     746       137289 :       if (lhs.pt_inverted_p (op1))
     747              :         return VREL_NE;
     748              :     }
     749       137289 :   unsigned prec = MIN (lhs_prec, op1_prec);
     750       137289 :   return bits_to_pe (prec);
     751              : }
     752              : 
     753              : relation_kind
     754      1386651 : operator_cast::lhs_op1_relation (const prange &lhs,
     755              :                                  const irange &op1,
     756              :                                  const irange &op2 ATTRIBUTE_UNUSED,
     757              :                                  relation_kind) const
     758              : {
     759      1386651 :   if (lhs.undefined_p () || op1.undefined_p ())
     760              :     return VREL_VARYING;
     761      1384897 :   unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
     762      1384897 :   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      1384897 :   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          284 :       int_range<3> negs = range_negatives (op1.type ());
     771          284 :       negs.intersect (op1);
     772          284 :       if (!negs.undefined_p ())
     773          276 :         return VREL_VARYING;
     774          284 :     }
     775              : 
     776      1384621 :   unsigned prec = MIN (lhs_prec, op1_prec);
     777      1384621 :   return bits_to_pe (prec);
     778              : }
     779              : 
     780              : relation_kind
     781      2143880 : operator_cast::lhs_op1_relation (const irange &lhs,
     782              :                                  const prange &op1,
     783              :                                  const prange &op2 ATTRIBUTE_UNUSED,
     784              :                                  relation_kind) const
     785              : {
     786      2143880 :   if (lhs.undefined_p () || op1.undefined_p ())
     787              :     return VREL_VARYING;
     788      2143066 :   unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
     789      2143066 :   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      2143066 :   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      2143066 :   unsigned prec = MIN (lhs_prec, op1_prec);
     804      2143066 :   return bits_to_pe (prec);
     805              : }
     806              : 
     807              : bool
     808         1124 : 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         1124 :   if (!range_includes_zero_p (op1)
     818         1124 :       && !range_includes_zero_p (op2))
     819          144 :     r.set_nonzero (type);
     820          980 :   else if (op1.zero_p () && op2.zero_p ())
     821            0 :     r.set_zero (type);
     822              :   else
     823          980 :     r.set_varying (type);
     824              : 
     825         1124 :   update_known_bitmask (r, MIN_EXPR, op1, op2);
     826         1124 :   return true;
     827              : }
     828              : 
     829              : bool
     830         1108 : 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         1108 :   if (!range_includes_zero_p (op1)
     840         1108 :       && !range_includes_zero_p (op2))
     841          110 :     r.set_nonzero (type);
     842          998 :   else if (op1.zero_p () && op2.zero_p ())
     843            0 :     r.set_zero (type);
     844              :   else
     845          998 :     r.set_varying (type);
     846              : 
     847         1108 :   update_known_bitmask (r, MAX_EXPR, op1, op2);
     848         1108 :   return true;
     849              : }
     850              : 
     851              : bool
     852       554207 : operator_addr_expr::op1_range (prange &r, tree type,
     853              :                                const prange &lhs,
     854              :                                const prange &op2,
     855              :                                relation_trio) const
     856              : {
     857       554207 :   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       554207 :   if (!lhs.undefined_p ()
     864       554207 :       && !range_includes_zero_p (lhs)
     865       547456 :       && TYPE_OVERFLOW_UNDEFINED (type))
     866       547443 :     r.set_nonzero (type);
     867              :   else
     868         6764 :     r.set_varying (type);
     869              :   return true;
     870              : }
     871              : 
     872              : bool
     873          769 : 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          769 :   if (op1.zero_p () || op2.zero_p ())
     881            0 :     r.set_zero (type);
     882              :   else
     883          769 :     r.set_varying (type);
     884              : 
     885          769 :   update_known_bitmask (r, BIT_AND_EXPR, op1, op2);
     886          769 :   return true;
     887              : }
     888              : 
     889              : bool
     890      6565197 : operator_equal::fold_range (irange &r, tree type,
     891              :                             const prange &op1,
     892              :                             const prange &op2,
     893              :                             relation_trio rel) const
     894              : {
     895      6565197 :   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      6545547 :   bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ());
     901      6545547 :   bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ());
     902              :   // Check for points to equality and inequality first.
     903      6545547 :   if (op1.pt_invariant_p (op2))
     904        12396 :     r = range_true (type);
     905      6533151 :   else if (op1.pt_inverted_p (op2))
     906            0 :     r = range_false (type);
     907      6533151 :   else if (op1_const && op2_const)
     908              :     {
     909        22825 :       if (wi::eq_p (op1.lower_bound (), op2.upper_bound()))
     910        22664 :         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      6510326 :       prange tmp = op1;
     919      6510326 :       tmp.intersect (op2);
     920      6510326 :       if (tmp.undefined_p ())
     921       162681 :         r = range_false (type);
     922              :       // Check if a constant cannot satisfy the bitmask requirements.
     923     11390399 :       else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ()))
     924            0 :          r = range_false (type);
     925      6356343 :       else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ()))
     926            0 :          r = range_false (type);
     927              :       else
     928      6347645 :         r = range_true_and_false (type);
     929      6510326 :     }
     930              : 
     931              :   //update_known_bitmask (r, EQ_EXPR, op1, op2);
     932              :   return true;
     933              : }
     934              : 
     935              : bool
     936      4110773 : operator_equal::op1_range (prange &r, tree type,
     937              :                            const irange &lhs,
     938              :                            const prange &op2,
     939              :                            relation_trio) const
     940              : {
     941      4110773 :   switch (get_bool_state (r, lhs, type))
     942              :     {
     943      1119592 :     case BRS_TRUE:
     944              :       // If it's true, the result is the same as OP2.
     945      1119592 :       r = op2;
     946      1119592 :       break;
     947              : 
     948      2983741 :     case BRS_FALSE:
     949              :       // If the result is false, the only time we know anything is
     950              :       // if OP2 is a constant.
     951      2983741 :       if (!op2.undefined_p ()
     952      8951223 :           && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
     953              :         {
     954       994322 :           r = op2;
     955       994322 :           r.invert ();
     956              :         }
     957              :       else
     958      1989419 :         r.set_varying (type);
     959              :       break;
     960              : 
     961              :     default:
     962              :       break;
     963              :     }
     964      4110773 :   return true;
     965              : }
     966              : 
     967              : bool
     968      1363786 : operator_equal::op2_range (prange &r, tree type,
     969              :                            const irange &lhs,
     970              :                            const prange &op1,
     971              :                            relation_trio rel) const
     972              : {
     973      1363786 :   return operator_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
     974              : }
     975              : 
     976              : relation_kind
     977      5113211 : operator_equal::op1_op2_relation (const irange &lhs, const prange &,
     978              :                                   const prange &) const
     979              : {
     980      5113211 :   if (lhs.undefined_p ())
     981              :     return VREL_UNDEFINED;
     982              : 
     983              :   // FALSE = op1 == op2 indicates NE_EXPR.
     984      5113211 :   if (lhs.zero_p ())
     985              :     return VREL_NE;
     986              : 
     987              :   // TRUE = op1 == op2 indicates EQ_EXPR.
     988      2317182 :   if (!range_includes_zero_p (lhs))
     989      2317099 :     return VREL_EQ;
     990              :   return VREL_VARYING;
     991              : }
     992              : 
     993              : bool
     994      7606537 : operator_not_equal::fold_range (irange &r, tree type,
     995              :                                 const prange &op1,
     996              :                                 const prange &op2,
     997              :                                 relation_trio rel) const
     998              : {
     999      7606537 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_NE))
    1000              :     return true;
    1001              : 
    1002              :   // We can be sure the values are always equal or not if both ranges
    1003              :   // consist of a single value, and then compare them.
    1004      7591351 :   bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ());
    1005      7591351 :   bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ());
    1006              :   // Check for points to equality and inequality first.
    1007      7591351 :   if (op1.pt_inverted_p (op2))
    1008            0 :     r = range_true (type);
    1009      7591351 :   else if (op1.pt_invariant_p (op2))
    1010         1177 :     r = range_false (type);
    1011      7590174 :   else if (op1_const && op2_const)
    1012              :     {
    1013        46537 :       if (wi::ne_p (op1.lower_bound (), op2.upper_bound()))
    1014          175 :         r = range_true (type);
    1015              :       else
    1016        46362 :         r = range_false (type);
    1017              :     }
    1018              :   else
    1019              :     {
    1020              :       // If ranges do not intersect, we know the range is not equal,
    1021              :       // otherwise we don't know anything for sure.
    1022      7543637 :       prange tmp = op1;
    1023      7543637 :       tmp.intersect (op2);
    1024      7543637 :       if (tmp.undefined_p ())
    1025       197668 :         r = range_true (type);
    1026              :       // Check if a constant cannot satisfy the bitmask requirements.
    1027     15861439 :       else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ()))
    1028            0 :          r = range_true (type);
    1029      7348635 :       else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ()))
    1030            0 :          r = range_true (type);
    1031              :       else
    1032      7345969 :         r = range_true_and_false (type);
    1033      7543637 :     }
    1034              : 
    1035              :   //update_known_bitmask (r, NE_EXPR, op1, op2);
    1036              :   return true;
    1037              : }
    1038              : 
    1039              : bool
    1040      4931410 : operator_not_equal::op1_range (prange &r, tree type,
    1041              :                                const irange &lhs,
    1042              :                                const prange &op2,
    1043              :                                relation_trio) const
    1044              : {
    1045      4931410 :   switch (get_bool_state (r, lhs, type))
    1046              :     {
    1047      3891423 :     case BRS_TRUE:
    1048              :       // If the result is true, the only time we know anything is if
    1049              :       // OP2 is a constant.
    1050      3891423 :       if (!op2.undefined_p ()
    1051     11674269 :           && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
    1052              :         {
    1053      1590433 :           r = op2;
    1054      1590433 :           r.invert ();
    1055              :         }
    1056              :       else
    1057      2300990 :         r.set_varying (type);
    1058              :       break;
    1059              : 
    1060      1016011 :     case BRS_FALSE:
    1061              :       // If it's false, the result is the same as OP2.
    1062      1016011 :       r = op2;
    1063      1016011 :       break;
    1064              : 
    1065              :     default:
    1066              :       break;
    1067              :     }
    1068      4931410 :   return true;
    1069              : }
    1070              : 
    1071              : 
    1072              : bool
    1073      1459392 : operator_not_equal::op2_range (prange &r, tree type,
    1074              :                                const irange &lhs,
    1075              :                                const prange &op1,
    1076              :                                relation_trio rel) const
    1077              : {
    1078      1459392 :   return operator_not_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
    1079              : }
    1080              : 
    1081              : relation_kind
    1082      5238707 : operator_not_equal::op1_op2_relation (const irange &lhs, const prange &,
    1083              :                                       const prange &) const
    1084              : {
    1085      5238707 :   if (lhs.undefined_p ())
    1086              :     return VREL_UNDEFINED;
    1087              : 
    1088              :   // FALSE = op1 != op2  indicates EQ_EXPR.
    1089      5238707 :   if (lhs.zero_p ())
    1090              :     return VREL_EQ;
    1091              : 
    1092              :   // TRUE = op1 != op2  indicates NE_EXPR.
    1093      3465781 :   if (!range_includes_zero_p (lhs))
    1094      3462396 :     return VREL_NE;
    1095              :   return VREL_VARYING;
    1096              : }
    1097              : 
    1098              : bool
    1099       358638 : operator_lt::fold_range (irange &r, tree type,
    1100              :                          const prange &op1,
    1101              :                          const prange &op2,
    1102              :                          relation_trio rel) const
    1103              : {
    1104       358638 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_LT))
    1105              :     return true;
    1106              : 
    1107       357881 :   signop sign = TYPE_SIGN (op1.type ());
    1108       357881 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1109              : 
    1110       357881 :   if (wi::lt_p (op1.upper_bound (), op2.lower_bound (), sign))
    1111            1 :     r = range_true (type);
    1112       357880 :   else if (!wi::lt_p (op1.lower_bound (), op2.upper_bound (), sign))
    1113           28 :     r = range_false (type);
    1114              :   // Use nonzero bits to determine if < 0 is false.
    1115       357852 :   else if (op2.zero_p () && !wi::neg_p (op1.get_nonzero_bits (), sign))
    1116            0 :     r = range_false (type);
    1117              :   else
    1118       357852 :     r = range_true_and_false (type);
    1119              : 
    1120              :   //update_known_bitmask (r, LT_EXPR, op1, op2);
    1121              :   return true;
    1122              : }
    1123              : 
    1124              : bool
    1125       277515 : operator_lt::op1_range (prange &r, tree type,
    1126              :                         const irange &lhs,
    1127              :                         const prange &op2,
    1128              :                         relation_trio) const
    1129              : {
    1130       277515 :   if (op2.undefined_p ())
    1131              :     return false;
    1132              : 
    1133       277515 :   switch (get_bool_state (r, lhs, type))
    1134              :     {
    1135       235191 :     case BRS_TRUE:
    1136       235191 :       build_lt (r, type, op2);
    1137       235191 :       break;
    1138              : 
    1139        42324 :     case BRS_FALSE:
    1140        42324 :       build_ge (r, type, op2);
    1141        42324 :       break;
    1142              : 
    1143              :     default:
    1144              :       break;
    1145              :     }
    1146              :   return true;
    1147              : }
    1148              : 
    1149              : bool
    1150       171901 : operator_lt::op2_range (prange &r, tree type,
    1151              :                         const irange &lhs,
    1152              :                         const prange &op1,
    1153              :                         relation_trio) const
    1154              : {
    1155       171901 :   if (op1.undefined_p ())
    1156              :     return false;
    1157              : 
    1158       171901 :   switch (get_bool_state (r, lhs, type))
    1159              :     {
    1160       119607 :     case BRS_TRUE:
    1161       119607 :       build_gt (r, type, op1);
    1162       119607 :       break;
    1163              : 
    1164        52290 :     case BRS_FALSE:
    1165        52290 :       build_le (r, type, op1);
    1166        52290 :       break;
    1167              : 
    1168              :     default:
    1169              :       break;
    1170              :     }
    1171              :   return true;
    1172              : }
    1173              : 
    1174              : relation_kind
    1175       759700 : operator_lt::op1_op2_relation (const irange &lhs, const prange &,
    1176              :                                const prange &) const
    1177              : {
    1178       759700 :   if (lhs.undefined_p ())
    1179              :     return VREL_UNDEFINED;
    1180              : 
    1181              :   // FALSE = op1 < op2 indicates GE_EXPR.
    1182       759700 :   if (lhs.zero_p ())
    1183              :     return VREL_GE;
    1184              : 
    1185              :   // TRUE = op1 < op2 indicates LT_EXPR.
    1186       560489 :   if (!range_includes_zero_p (lhs))
    1187       560485 :     return VREL_LT;
    1188              :   return VREL_VARYING;
    1189              : }
    1190              : 
    1191              : bool
    1192       109631 : operator_le::fold_range (irange &r, tree type,
    1193              :                          const prange &op1,
    1194              :                          const prange &op2,
    1195              :                          relation_trio rel) const
    1196              : {
    1197       109631 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_LE))
    1198              :     return true;
    1199              : 
    1200       109295 :   signop sign = TYPE_SIGN (op1.type ());
    1201       109295 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1202              : 
    1203       109295 :   if (wi::le_p (op1.upper_bound (), op2.lower_bound (), sign))
    1204           17 :     r = range_true (type);
    1205       109278 :   else if (!wi::le_p (op1.lower_bound (), op2.upper_bound (), sign))
    1206            8 :     r = range_false (type);
    1207              :   else
    1208       109270 :     r = range_true_and_false (type);
    1209              : 
    1210              :   //update_known_bitmask (r, LE_EXPR, op1, op2);
    1211              :   return true;
    1212              : }
    1213              : 
    1214              : bool
    1215        75002 : operator_le::op1_range (prange &r, tree type,
    1216              :                         const irange &lhs,
    1217              :                         const prange &op2,
    1218              :                         relation_trio) const
    1219              : {
    1220        75002 :   if (op2.undefined_p ())
    1221              :     return false;
    1222              : 
    1223        75002 :   switch (get_bool_state (r, lhs, type))
    1224              :     {
    1225        53442 :     case BRS_TRUE:
    1226        53442 :       build_le (r, type, op2);
    1227        53442 :       break;
    1228              : 
    1229        21560 :     case BRS_FALSE:
    1230        21560 :       build_gt (r, type, op2);
    1231        21560 :       break;
    1232              : 
    1233              :     default:
    1234              :       break;
    1235              :     }
    1236              :   return true;
    1237              : }
    1238              : 
    1239              : bool
    1240       114628 : operator_le::op2_range (prange &r, tree type,
    1241              :                         const irange &lhs,
    1242              :                         const prange &op1,
    1243              :                         relation_trio) const
    1244              : {
    1245       114628 :   if (op1.undefined_p ())
    1246              :     return false;
    1247              : 
    1248       114628 :   switch (get_bool_state (r, lhs, type))
    1249              :     {
    1250        94267 :     case BRS_TRUE:
    1251        94267 :       build_ge (r, type, op1);
    1252        94267 :       break;
    1253              : 
    1254        20361 :     case BRS_FALSE:
    1255        20361 :       build_lt (r, type, op1);
    1256        20361 :       break;
    1257              : 
    1258              :     default:
    1259              :       break;
    1260              :     }
    1261              :   return true;
    1262              : }
    1263              : 
    1264              : relation_kind
    1265       308623 : operator_le::op1_op2_relation (const irange &lhs, const prange &,
    1266              :                                const prange &) const
    1267              : {
    1268       308623 :   if (lhs.undefined_p ())
    1269              :     return VREL_UNDEFINED;
    1270              : 
    1271              :   // FALSE = op1 <= op2 indicates GT_EXPR.
    1272       308623 :   if (lhs.zero_p ())
    1273              :     return VREL_GT;
    1274              : 
    1275              :   // TRUE = op1 <= op2 indicates LE_EXPR.
    1276       224341 :   if (!range_includes_zero_p (lhs))
    1277       224341 :     return VREL_LE;
    1278              :   return VREL_VARYING;
    1279              : }
    1280              : 
    1281              : bool
    1282       352025 : operator_gt::fold_range (irange &r, tree type,
    1283              :                          const prange &op1, const prange &op2,
    1284              :                          relation_trio rel) const
    1285              : {
    1286       352025 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_GT))
    1287              :     return true;
    1288              : 
    1289       351101 :   signop sign = TYPE_SIGN (op1.type ());
    1290       351101 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1291              : 
    1292       351101 :   if (wi::gt_p (op1.lower_bound (), op2.upper_bound (), sign))
    1293            2 :     r = range_true (type);
    1294       351099 :   else if (!wi::gt_p (op1.upper_bound (), op2.lower_bound (), sign))
    1295            7 :     r = range_false (type);
    1296              :   else
    1297       351092 :     r = range_true_and_false (type);
    1298              : 
    1299              :   //update_known_bitmask (r, GT_EXPR, op1, op2);
    1300              :   return true;
    1301              : }
    1302              : 
    1303              : bool
    1304       245894 : operator_gt::op1_range (prange &r, tree type,
    1305              :                         const irange &lhs, const prange &op2,
    1306              :                         relation_trio) const
    1307              : {
    1308       245894 :   if (op2.undefined_p ())
    1309              :     return false;
    1310              : 
    1311       245894 :   switch (get_bool_state (r, lhs, type))
    1312              :     {
    1313       159628 :     case BRS_TRUE:
    1314       159628 :       build_gt (r, type, op2);
    1315       159628 :       break;
    1316              : 
    1317        86266 :     case BRS_FALSE:
    1318        86266 :       build_le (r, type, op2);
    1319        86266 :       break;
    1320              : 
    1321              :     default:
    1322              :       break;
    1323              :     }
    1324              :   return true;
    1325              : }
    1326              : 
    1327              : bool
    1328       231050 : operator_gt::op2_range (prange &r, tree type,
    1329              :                         const irange &lhs,
    1330              :                         const prange &op1,
    1331              :                         relation_trio) const
    1332              : {
    1333       231050 :   if (op1.undefined_p ())
    1334              :     return false;
    1335              : 
    1336       231050 :   switch (get_bool_state (r, lhs, type))
    1337              :     {
    1338       180001 :     case BRS_TRUE:
    1339       180001 :       build_lt (r, type, op1);
    1340       180001 :       break;
    1341              : 
    1342        51049 :     case BRS_FALSE:
    1343        51049 :       build_ge (r, type, op1);
    1344        51049 :       break;
    1345              : 
    1346              :     default:
    1347              :       break;
    1348              :     }
    1349              :   return true;
    1350              : }
    1351              : 
    1352              : relation_kind
    1353       782172 : operator_gt::op1_op2_relation (const irange &lhs, const prange &,
    1354              :                                const prange &) const
    1355              : {
    1356       782172 :   if (lhs.undefined_p ())
    1357              :     return VREL_UNDEFINED;
    1358              : 
    1359              :   // FALSE = op1 > op2 indicates LE_EXPR.
    1360       782172 :   if (lhs.zero_p ())
    1361              :     return VREL_LE;
    1362              : 
    1363              :   // TRUE = op1 > op2 indicates GT_EXPR.
    1364       541253 :   if (!range_includes_zero_p (lhs))
    1365       541253 :     return VREL_GT;
    1366              :   return VREL_VARYING;
    1367              : }
    1368              : 
    1369              : bool
    1370       183236 : operator_ge::fold_range (irange &r, tree type,
    1371              :                          const prange &op1,
    1372              :                          const prange &op2,
    1373              :                          relation_trio rel) const
    1374              : {
    1375       183236 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_GE))
    1376              :     return true;
    1377              : 
    1378       182986 :   signop sign = TYPE_SIGN (op1.type ());
    1379       182986 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1380              : 
    1381       182986 :   if (wi::ge_p (op1.lower_bound (), op2.upper_bound (), sign))
    1382           63 :     r = range_true (type);
    1383       182923 :   else if (!wi::ge_p (op1.upper_bound (), op2.lower_bound (), sign))
    1384            0 :     r = range_false (type);
    1385              :   else
    1386       182923 :     r = range_true_and_false (type);
    1387              : 
    1388              :   //update_known_bitmask (r, GE_EXPR, op1, op2);
    1389              :   return true;
    1390              : }
    1391              : 
    1392              : bool
    1393       181008 : operator_ge::op1_range (prange &r, tree type,
    1394              :                         const irange &lhs,
    1395              :                         const prange &op2,
    1396              :                         relation_trio) const
    1397              : {
    1398       181008 :   if (op2.undefined_p ())
    1399              :     return false;
    1400              : 
    1401       181008 :   switch (get_bool_state (r, lhs, type))
    1402              :     {
    1403       156933 :     case BRS_TRUE:
    1404       156933 :       build_ge (r, type, op2);
    1405       156933 :       break;
    1406              : 
    1407        24075 :     case BRS_FALSE:
    1408        24075 :       build_lt (r, type, op2);
    1409        24075 :       break;
    1410              : 
    1411              :     default:
    1412              :       break;
    1413              :     }
    1414              :   return true;
    1415              : }
    1416              : 
    1417              : bool
    1418        78762 : operator_ge::op2_range (prange &r, tree type,
    1419              :                         const irange &lhs,
    1420              :                         const prange &op1,
    1421              :                         relation_trio) const
    1422              : {
    1423        78762 :   if (op1.undefined_p ())
    1424              :     return false;
    1425              : 
    1426        78762 :   switch (get_bool_state (r, lhs, type))
    1427              :     {
    1428        53864 :     case BRS_TRUE:
    1429        53864 :       build_le (r, type, op1);
    1430        53864 :       break;
    1431              : 
    1432        24898 :     case BRS_FALSE:
    1433        24898 :       build_gt (r, type, op1);
    1434        24898 :       break;
    1435              : 
    1436              :     default:
    1437              :       break;
    1438              :     }
    1439              :   return true;
    1440              : }
    1441              : 
    1442              : relation_kind
    1443       452502 : operator_ge::op1_op2_relation (const irange &lhs, const prange &,
    1444              :                                const prange &) const
    1445              : {
    1446       452502 :   if (lhs.undefined_p ())
    1447              :     return VREL_UNDEFINED;
    1448              : 
    1449              :   // FALSE = op1 >= op2 indicates LT_EXPR.
    1450       452502 :   if (lhs.zero_p ())
    1451              :     return VREL_LT;
    1452              : 
    1453              :   // TRUE = op1 >= op2 indicates GE_EXPR.
    1454       337863 :   if (!range_includes_zero_p (lhs))
    1455       337863 :     return VREL_GE;
    1456              :   return VREL_VARYING;
    1457              : }
    1458              : 
    1459              : // Initialize any pointer operators to the primary table
    1460              : 
    1461              : void
    1462       297658 : range_op_table::initialize_pointer_ops ()
    1463              : {
    1464       297658 :   set (POINTER_PLUS_EXPR, op_pointer_plus);
    1465       297658 :   set (POINTER_DIFF_EXPR, op_pointer_diff);
    1466       297658 : }
        

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.