LCOV - code coverage report
Current view: top level - gcc - range-op-ptr.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 84.9 % 484 411
Test Date: 2026-02-28 14:20:25 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          162 : range_operator::op1_range (prange &, tree,
     134              :                            const prange &lhs ATTRIBUTE_UNUSED,
     135              :                            const prange &op2 ATTRIBUTE_UNUSED,
     136              :                            relation_trio) const
     137              : {
     138          162 :   return false;
     139              : }
     140              : 
     141              : bool
     142       733704 : range_operator::op1_range (prange &, tree,
     143              :                            const irange &lhs ATTRIBUTE_UNUSED,
     144              :                            const prange &op2 ATTRIBUTE_UNUSED,
     145              :                            relation_trio) const
     146              : {
     147       733704 :   return false;
     148              : }
     149              : 
     150              : bool
     151       489352 : range_operator::op1_range (prange &, tree,
     152              :                            const prange &lhs ATTRIBUTE_UNUSED,
     153              :                            const irange &op2 ATTRIBUTE_UNUSED,
     154              :                            relation_trio) const
     155              : {
     156       489352 :   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      1150164 : range_operator::op2_range (prange &, tree,
     170              :                            const irange &lhs ATTRIBUTE_UNUSED,
     171              :                            const prange &op1 ATTRIBUTE_UNUSED,
     172              :                            relation_trio) const
     173              : {
     174      1150164 :   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      1835227 : 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      1835227 :   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      3940204 : 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      3940204 :   return VREL_VARYING;
     210              : }
     211              : 
     212              : relation_kind
     213        78686 : 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        78686 :   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       666314 : max_limit (const_tree type)
     241              : {
     242       666314 :   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       730956 : min_limit (const_tree type)
     249              : {
     250       730956 :   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       495661 : build_lt (prange &r, tree type, const prange &val)
     257              : {
     258       495661 :   wi::overflow_type ov;
     259       495661 :   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       495661 :   if (ov)
     263            0 :     r.set_undefined ();
     264              :   else
     265       495661 :     r.set (type, min_limit (type), lim);
     266       495661 : }
     267              : 
     268              : // Build a range that is <= VAL and store it in R.
     269              : 
     270              : static void
     271       235295 : build_le (prange &r, tree type, const prange &val)
     272              : {
     273       235295 :   r.set (type, min_limit (type), val.upper_bound ());
     274       235295 : }
     275              : 
     276              : // Build a range that is > VAL and store it in R.
     277              : 
     278              : static void
     279       337695 : build_gt (prange &r, tree type, const prange &val)
     280              : {
     281       337695 :   wi::overflow_type ov;
     282       337695 :   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       337695 :   if (ov)
     286            0 :     r.set_undefined ();
     287              :   else
     288       337695 :     r.set (type, lim, max_limit (type));
     289              : 
     290       337695 : }
     291              : 
     292              : // Build a range that is >= VAL and store it in R.
     293              : 
     294              : static void
     295       328619 : build_ge (prange &r, tree type, const prange &val)
     296              : {
     297       328619 :   r.set (type, val.lower_bound (), max_limit (type));
     298       328619 : }
     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              : } op_pointer_plus;
     322              : 
     323              : bool
     324      9673438 : pointer_plus_operator::fold_range (prange &r, tree type,
     325              :                                    const prange &op1,
     326              :                                    const irange &op2,
     327              :                                    relation_trio) const
     328              : {
     329      9673438 :   if (empty_range_varying (r, type, op1, op2))
     330         6002 :     return true;
     331              : 
     332      9667436 :   const wide_int lh_lb = op1.lower_bound ();
     333      9667436 :   const wide_int lh_ub = op1.upper_bound ();
     334      9667436 :   const wide_int rh_lb = op2.lower_bound ();
     335      9667436 :   const wide_int rh_ub = op2.upper_bound ();
     336              : 
     337              :   // Check for [0,0] + const, and simply return the const.
     338      9675140 :   if (lh_lb == 0 && lh_ub == 0 && rh_lb == rh_ub)
     339              :     {
     340          831 :       r.set (type, rh_lb, rh_lb);
     341          831 :       return true;
     342              :     }
     343              : 
     344              :   // For pointer types, we are really only interested in asserting
     345              :   // whether the expression evaluates to non-NULL.
     346              :   //
     347              :   // With -fno-delete-null-pointer-checks we need to be more
     348              :   // conservative.  As some object might reside at address 0,
     349              :   // then some offset could be added to it and the same offset
     350              :   // subtracted again and the result would be NULL.
     351              :   // E.g.
     352              :   // static int a[12]; where &a[0] is NULL and
     353              :   // ptr = &a[6];
     354              :   // ptr -= 6;
     355              :   // ptr will be NULL here, even when there is POINTER_PLUS_EXPR
     356              :   // where the first range doesn't include zero and the second one
     357              :   // doesn't either.  As the second operand is sizetype (unsigned),
     358              :   // consider all ranges where the MSB could be set as possible
     359              :   // subtractions where the result might be NULL.
     360      9666605 :   if ((!wi_includes_zero_p (type, lh_lb, lh_ub)
     361      5697153 :        || !wi_includes_zero_p (type, rh_lb, rh_ub))
     362      6409265 :       && !TYPE_OVERFLOW_WRAPS (type)
     363     16075170 :       && (flag_delete_null_pointer_checks
     364         1265 :           || !wi::sign_mask (rh_ub)))
     365      6408150 :     r.set_nonzero (type);
     366      3264299 :   else if (lh_lb == lh_ub && lh_lb == 0
     367      3264299 :            && rh_lb == rh_ub && rh_lb == 0)
     368            0 :     r.set_zero (type);
     369              :   else
     370      3258455 :    r.set_varying (type);
     371              : 
     372      9666605 :   update_known_bitmask (r, POINTER_PLUS_EXPR, op1, op2);
     373      9666605 :   return true;
     374      9667436 : }
     375              : 
     376              : bool
     377       216584 : pointer_plus_operator::op2_range (irange &r, tree type,
     378              :                                   const prange &lhs ATTRIBUTE_UNUSED,
     379              :                                   const prange &op1 ATTRIBUTE_UNUSED,
     380              :                                   relation_trio trio) const
     381              : {
     382       216584 :   relation_kind rel = trio.lhs_op1 ();
     383       216584 :   r.set_varying (type);
     384              : 
     385              :   // If the LHS and OP1 are equal, the op2 must be zero.
     386       216584 :   if (rel == VREL_EQ)
     387         8998 :     r.set_zero (type);
     388              :   // If the LHS and OP1 are not equal, the offset must be non-zero.
     389       207586 :   else if (rel == VREL_NE)
     390        13331 :     r.set_nonzero (type);
     391              :   else
     392              :     return false;
     393              :   return true;
     394              : }
     395              : 
     396              : // Return the relation between the LHS and OP1 based on the value of the
     397              : // operand being added.  Pointer_plus is define to have a size_type for
     398              : // operand 2 which can be interpreted as negative, so always used SIGNED.
     399              : // Any overflow is considered UB and thus ignored.
     400              : 
     401              : relation_kind
     402      8414161 : pointer_plus_operator::lhs_op1_relation (const prange &lhs,
     403              :                                          const prange &op1,
     404              :                                          const irange &op2,
     405              :                                          relation_kind) const
     406              : {
     407      8414161 :   if (lhs.undefined_p () || op1.undefined_p () || op2.undefined_p ())
     408              :     return VREL_VARYING;
     409              : 
     410      8408545 :   unsigned prec = TYPE_PRECISION (op2.type ());
     411              : 
     412              :   // LHS = OP1 + 0  indicates LHS == OP1.
     413      8408545 :   if (op2.zero_p ())
     414              :     return VREL_EQ;
     415              : 
     416      8391560 :   tree val;
     417              :   // Only deal with singletons for now.
     418      8391560 :   if (TYPE_OVERFLOW_UNDEFINED (lhs.type ()) && op2.singleton_p (&val))
     419              :     {
     420              :       // Always interpret VALUE as a signed value.  Positive will increase
     421              :       // the pointer value, and negative will decrease the poiinter value.
     422              :       // It cannot be zero or the earlier zero_p () condition will catch it.
     423      4197224 :       wide_int value = wi::to_wide (val);
     424              : 
     425              :       // Positive op2 means lhs > op1.
     426      4197224 :       if (wi::gt_p (value, wi::zero (prec), SIGNED))
     427              :         return VREL_GT;
     428              : 
     429              :       // Negative op2 means lhs < op1.
     430       440352 :       if (wi::lt_p (value, wi::zero (prec), SIGNED))
     431              :         return VREL_LT;
     432      4197224 :     }
     433              : 
     434              :   // If op2 does not contain 0, then LHS and OP1 can never be equal.
     435      4194336 :   if (!range_includes_zero_p (op2))
     436              :     return VREL_NE;
     437              : 
     438              :   return VREL_VARYING;
     439              : }
     440              : 
     441              : bool
     442            0 : operator_bitwise_or::fold_range (prange &r, tree type,
     443              :                                  const prange &op1,
     444              :                                  const prange &op2,
     445              :                                  relation_trio) const
     446              : {
     447              :   // For pointer types, we are really only interested in asserting
     448              :   // whether the expression evaluates to non-NULL.
     449            0 :   if (!range_includes_zero_p (op1) || !range_includes_zero_p (op2))
     450            0 :     r.set_nonzero (type);
     451            0 :   else if (op1.zero_p () && op2.zero_p ())
     452            0 :     r.set_zero (type);
     453              :   else
     454            0 :     r.set_varying (type);
     455              : 
     456            0 :   update_known_bitmask (r, BIT_IOR_EXPR, op1, op2);
     457            0 :   return true;
     458              : }
     459              : 
     460              : 
     461              : class operator_pointer_diff : public range_operator
     462              : {
     463              :   using range_operator::fold_range;
     464              :   using range_operator::update_bitmask;
     465              :   using range_operator::op1_op2_relation_effect;
     466              :   virtual bool fold_range (irange &r, tree type,
     467              :                            const prange &op1,
     468              :                            const prange &op2,
     469              :                            relation_trio trio) const final override;
     470              :   virtual bool op1_op2_relation_effect (irange &lhs_range,
     471              :                                         tree type,
     472              :                                         const prange &op1_range,
     473              :                                         const prange &op2_range,
     474              :                                         relation_kind rel) const final override;
     475      2628503 :   void update_bitmask (irange &r,
     476              :                        const prange &lh, const prange &rh) const final override
     477            0 :   { update_known_bitmask (r, POINTER_DIFF_EXPR, lh, rh); }
     478              : } op_pointer_diff;
     479              : 
     480              : bool
     481      2628503 : operator_pointer_diff::fold_range (irange &r, tree type,
     482              :                                    const prange &op1,
     483              :                                    const prange &op2,
     484              :                                    relation_trio trio) const
     485              : {
     486      2628503 :   gcc_checking_assert (r.supports_type_p (type));
     487              : 
     488      2628503 :   r.set_varying (type);
     489      2628503 :   relation_kind rel = trio.op1_op2 ();
     490      2628503 :   op1_op2_relation_effect (r, type, op1, op2, rel);
     491      2628503 :   update_bitmask (r, op1, op2);
     492      2628503 :   return true;
     493              : }
     494              : 
     495              : bool
     496      2628503 : operator_pointer_diff::op1_op2_relation_effect (irange &lhs_range, tree type,
     497              :                                                 const prange &op1_range,
     498              :                                                 const prange &op2_range,
     499              :                                                 relation_kind rel) const
     500              : {
     501      2628503 :   int_range<2> op1, op2, tmp;
     502      2628503 :   range_op_handler cast (CONVERT_EXPR);
     503              : 
     504      2628503 :   if (!cast.fold_range (op1, type, op1_range, tmp)
     505      2628503 :       || !cast.fold_range (op2, type, op2_range, tmp))
     506            0 :     return false;
     507              : 
     508      2628503 :   return minus_op1_op2_relation_effect (lhs_range, type, op1, op2, rel);
     509      2628503 : }
     510              : 
     511              : bool
     512      1382739 : operator_identity::fold_range (prange &r, tree type ATTRIBUTE_UNUSED,
     513              :                                const prange &lh ATTRIBUTE_UNUSED,
     514              :                                const prange &rh ATTRIBUTE_UNUSED,
     515              :                                relation_trio) const
     516              : {
     517      1382739 :   r = lh;
     518      1382739 :   return true;
     519              : }
     520              : 
     521              : relation_kind
     522      1231903 : operator_identity::lhs_op1_relation (const prange &lhs,
     523              :                                      const prange &op1 ATTRIBUTE_UNUSED,
     524              :                                      const prange &op2 ATTRIBUTE_UNUSED,
     525              :                                      relation_kind) const
     526              : {
     527      1231903 :   if (lhs.undefined_p ())
     528          375 :     return VREL_VARYING;
     529              :   // Simply a copy, so they are equivalent.
     530              :   return VREL_EQ;
     531              : }
     532              : 
     533              : bool
     534       205425 : operator_identity::op1_range (prange &r, tree type ATTRIBUTE_UNUSED,
     535              :                               const prange &lhs,
     536              :                               const prange &op2 ATTRIBUTE_UNUSED,
     537              :                               relation_trio) const
     538              : {
     539       205425 :   r = lhs;
     540       205425 :   return true;
     541              : }
     542              : 
     543              : bool
     544        21462 : operator_cst::fold_range (prange &r, tree type ATTRIBUTE_UNUSED,
     545              :                           const prange &lh,
     546              :                           const prange & ATTRIBUTE_UNUSED,
     547              :                           relation_trio) const
     548              : {
     549        21462 :   r = lh;
     550        21462 :   return true;
     551              : }
     552              : 
     553              : // Cast between pointers.
     554              : 
     555              : bool
     556     16449717 : operator_cast::fold_range (prange &r, tree type,
     557              :                            const prange &inner,
     558              :                            const prange &outer,
     559              :                            relation_trio) const
     560              : {
     561     16449717 :   if (empty_range_varying (r, type, inner, outer))
     562          445 :     return true;
     563              : 
     564     16449272 :   r.set (type, inner.lower_bound (), inner.upper_bound ());
     565     16449272 :   r.update_bitmask (inner.get_bitmask ());
     566     16449272 :   return true;
     567              : }
     568              : 
     569              : // Cast a pointer to an integer.
     570              : 
     571              : bool
     572     10809285 : operator_cast::fold_range (irange &r, tree type,
     573              :                            const prange &inner,
     574              :                            const irange &outer,
     575              :                            relation_trio) const
     576              : {
     577     10809285 :   if (empty_range_varying (r, type, inner, outer))
     578      5258158 :     return true;
     579              : 
     580              :   // Represent INNER as an integer of the same size, and then cast it
     581              :   // to the resulting integer type.
     582      5551127 :   tree pointer_uint_type = make_unsigned_type (TYPE_PRECISION (inner.type ()));
     583      5551127 :   r.set (pointer_uint_type, inner.lower_bound (), inner.upper_bound ());
     584      5551127 :   r.update_bitmask (inner.get_bitmask ());
     585      5551127 :   range_cast (r, type);
     586      5551127 :   return true;
     587              : }
     588              : 
     589              : // Cast an integer to a pointer.
     590              : 
     591              : bool
     592      1931619 : operator_cast::fold_range (prange &r, tree type,
     593              :                            const irange &inner,
     594              :                            const prange &outer,
     595              :                            relation_trio) const
     596              : {
     597      1931619 :   if (empty_range_varying (r, type, inner, outer))
     598         1789 :     return true;
     599              : 
     600              :   // Cast INNER to an integer of the same size as the pointer we want,
     601              :   // and then copy the bounds to the resulting pointer range.
     602      1929830 :   int_range<2> tmp = inner;
     603      1929830 :   tree pointer_uint_type = make_unsigned_type (TYPE_PRECISION (type));
     604      1929830 :   range_cast (tmp, pointer_uint_type);
     605              :   // Casts may cause ranges to become UNDEFINED based on bitmasks.
     606      1929830 :   if (tmp.undefined_p ())
     607            0 :     r.set_varying (type);
     608              :   else
     609              :     {
     610      1929830 :       r.set (type, tmp.lower_bound (), tmp.upper_bound ());
     611      1929830 :       r.update_bitmask (tmp.get_bitmask ());
     612              :     }
     613      1929830 :   return true;
     614      1929830 : }
     615              : 
     616              : bool
     617           69 : operator_cast::op1_range (prange &r, tree type,
     618              :                           const prange &lhs,
     619              :                           const prange &op2,
     620              :                           relation_trio trio) const
     621              : {
     622           69 :   if (lhs.undefined_p ())
     623              :     return false;
     624           69 :   gcc_checking_assert (types_compatible_p (op2.type(), type));
     625              : 
     626              :   // Conversion from other pointers or a constant (including 0/NULL)
     627              :   // are straightforward.
     628           69 :   if (POINTER_TYPE_P (lhs.type ())
     629           69 :       || (lhs.singleton_p ()
     630            0 :           && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
     631           69 :     fold_range (r, type, lhs, op2, trio);
     632              :   else
     633              :     {
     634              :       // If the LHS is not a pointer nor a singleton, then it is
     635              :       // either VARYING or non-zero.
     636            0 :       if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
     637            0 :         r.set_nonzero (type);
     638              :       else
     639            0 :         r.set_varying (type);
     640              :     }
     641           69 :   r.intersect (op2);
     642           69 :   return true;
     643              : }
     644              : 
     645              : bool
     646       247092 : operator_cast::op1_range (irange &r, tree type,
     647              :                           const prange &lhs,
     648              :                           const irange &op2,
     649              :                           relation_trio trio) const
     650              : {
     651       247092 :   if (lhs.undefined_p ())
     652              :     return false;
     653       247092 :   gcc_checking_assert (types_compatible_p (op2.type(), type));
     654              : 
     655              :   // Conversion from other pointers or a constant (including 0/NULL)
     656              :   // are straightforward.
     657       247092 :   if (POINTER_TYPE_P (lhs.type ())
     658       247092 :       || (lhs.singleton_p ()
     659            0 :           && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
     660       247092 :     fold_range (r, type, lhs, op2, trio);
     661              :   else
     662              :     {
     663              :       // If the LHS is not a pointer nor a singleton, then it is
     664              :       // either VARYING or non-zero.
     665            0 :       if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
     666            0 :         r.set_nonzero (type);
     667              :       else
     668            0 :         r.set_varying (type);
     669              :     }
     670       247092 :   r.intersect (op2);
     671       247092 :   return true;
     672              : }
     673              : 
     674              : bool
     675       479331 : operator_cast::op1_range (prange &r, tree type,
     676              :                           const irange &lhs,
     677              :                           const prange &op2,
     678              :                           relation_trio trio) const
     679              : {
     680       479331 :   if (lhs.undefined_p ())
     681              :     return false;
     682       479331 :   gcc_checking_assert (types_compatible_p (op2.type(), type));
     683              : 
     684              :   // Conversion from other pointers or a constant (including 0/NULL)
     685              :   // are straightforward.
     686       958662 :   if (POINTER_TYPE_P (lhs.type ())
     687       958662 :       || (lhs.singleton_p ()
     688         1199 :           && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
     689         1189 :     fold_range (r, type, lhs, op2, trio);
     690              :   else
     691              :     {
     692              :       // If the LHS is not a pointer nor a singleton, then it is
     693              :       // either VARYING or non-zero.
     694       478142 :       if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
     695       210790 :         r.set_nonzero (type);
     696              :       else
     697       267352 :         r.set_varying (type);
     698              :     }
     699       479331 :   r.intersect (op2);
     700       479331 :   return true;
     701              : }
     702              : 
     703              : relation_kind
     704       137472 : operator_cast::lhs_op1_relation (const prange &lhs,
     705              :                                  const prange &op1,
     706              :                                  const prange &op2 ATTRIBUTE_UNUSED,
     707              :                                  relation_kind) const
     708              : {
     709       137472 :   if (lhs.undefined_p () || op1.undefined_p ())
     710              :     return VREL_VARYING;
     711       137472 :   unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
     712       137472 :   unsigned op1_prec = TYPE_PRECISION (op1.type ());
     713              :   // If the result gets sign extended into a larger type check first if this
     714              :   // qualifies as a partial equivalence.
     715       137472 :   if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
     716              :     {
     717              :       // If the result is sign extended, and the LHS is larger than op1,
     718              :       // check if op1's range can be negative as the sign extension will
     719              :       // cause the upper bits to be 1 instead of 0, invalidating the PE.
     720            0 :       int_range<3> negs = range_negatives (op1.type ());
     721            0 :       negs.intersect (op1);
     722            0 :       if (!negs.undefined_p ())
     723            0 :         return VREL_VARYING;
     724            0 :     }
     725              : 
     726       137472 :   unsigned prec = MIN (lhs_prec, op1_prec);
     727       137472 :   return bits_to_pe (prec);
     728              : }
     729              : 
     730              : relation_kind
     731      1442620 : operator_cast::lhs_op1_relation (const prange &lhs,
     732              :                                  const irange &op1,
     733              :                                  const irange &op2 ATTRIBUTE_UNUSED,
     734              :                                  relation_kind) const
     735              : {
     736      1442620 :   if (lhs.undefined_p () || op1.undefined_p ())
     737              :     return VREL_VARYING;
     738      1440848 :   unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
     739      1440848 :   unsigned op1_prec = TYPE_PRECISION (op1.type ());
     740              :   // If the result gets sign extended into a larger type check first if this
     741              :   // qualifies as a partial equivalence.
     742      1440848 :   if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
     743              :     {
     744              :       // If the result is sign extended, and the LHS is larger than op1,
     745              :       // check if op1's range can be negative as the sign extension will
     746              :       // cause the upper bits to be 1 instead of 0, invalidating the PE.
     747          284 :       int_range<3> negs = range_negatives (op1.type ());
     748          284 :       negs.intersect (op1);
     749          284 :       if (!negs.undefined_p ())
     750          276 :         return VREL_VARYING;
     751          284 :     }
     752              : 
     753      1440572 :   unsigned prec = MIN (lhs_prec, op1_prec);
     754      1440572 :   return bits_to_pe (prec);
     755              : }
     756              : 
     757              : relation_kind
     758      2182861 : operator_cast::lhs_op1_relation (const irange &lhs,
     759              :                                  const prange &op1,
     760              :                                  const prange &op2 ATTRIBUTE_UNUSED,
     761              :                                  relation_kind) const
     762              : {
     763      2182861 :   if (lhs.undefined_p () || op1.undefined_p ())
     764              :     return VREL_VARYING;
     765      2182094 :   unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
     766      2182094 :   unsigned op1_prec = TYPE_PRECISION (op1.type ());
     767              :   // If the result gets sign extended into a larger type check first if this
     768              :   // qualifies as a partial equivalence.
     769      2182094 :   if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
     770              :     {
     771              :       // If the result is sign extended, and the LHS is larger than op1,
     772              :       // check if op1's range can be negative as the sign extension will
     773              :       // cause the upper bits to be 1 instead of 0, invalidating the PE.
     774            0 :       int_range<3> negs = range_negatives (op1.type ());
     775            0 :       negs.intersect (op1);
     776            0 :       if (!negs.undefined_p ())
     777            0 :         return VREL_VARYING;
     778            0 :     }
     779              : 
     780      2182094 :   unsigned prec = MIN (lhs_prec, op1_prec);
     781      2182094 :   return bits_to_pe (prec);
     782              : }
     783              : 
     784              : bool
     785         1131 : operator_min::fold_range (prange &r, tree type,
     786              :                           const prange &op1,
     787              :                           const prange &op2,
     788              :                           relation_trio) const
     789              : {
     790              :   // For MIN/MAX expressions with pointers, we only care about
     791              :   // nullness.  If both are non null, then the result is nonnull.
     792              :   // If both are null, then the result is null.  Otherwise they
     793              :   // are varying.
     794         1131 :   if (!range_includes_zero_p (op1)
     795         1131 :       && !range_includes_zero_p (op2))
     796          144 :     r.set_nonzero (type);
     797          987 :   else if (op1.zero_p () && op2.zero_p ())
     798            0 :     r.set_zero (type);
     799              :   else
     800          987 :     r.set_varying (type);
     801              : 
     802         1131 :   update_known_bitmask (r, MIN_EXPR, op1, op2);
     803         1131 :   return true;
     804              : }
     805              : 
     806              : bool
     807         1588 : operator_max::fold_range (prange &r, tree type,
     808              :                           const prange &op1,
     809              :                           const prange &op2,
     810              :                           relation_trio) const
     811              : {
     812              :   // For MIN/MAX expressions with pointers, we only care about
     813              :   // nullness.  If both are non null, then the result is nonnull.
     814              :   // If both are null, then the result is null.  Otherwise they
     815              :   // are varying.
     816         1588 :   if (!range_includes_zero_p (op1)
     817         1588 :       && !range_includes_zero_p (op2))
     818          110 :     r.set_nonzero (type);
     819         1478 :   else if (op1.zero_p () && op2.zero_p ())
     820            0 :     r.set_zero (type);
     821              :   else
     822         1478 :     r.set_varying (type);
     823              : 
     824         1588 :   update_known_bitmask (r, MAX_EXPR, op1, op2);
     825         1588 :   return true;
     826              : }
     827              : 
     828              : bool
     829       616766 : operator_addr_expr::op1_range (prange &r, tree type,
     830              :                                const prange &lhs,
     831              :                                const prange &op2,
     832              :                                relation_trio) const
     833              : {
     834       616766 :   if (empty_range_varying (r, type, lhs, op2))
     835            0 :     return true;
     836              : 
     837              :   // Return a non-null pointer of the LHS type (passed in op2), but only
     838              :   // if we cant overflow, eitherwise a no-zero offset could wrap to zero.
     839              :   // See PR 111009.
     840       616766 :   if (!lhs.undefined_p ()
     841       616766 :       && !range_includes_zero_p (lhs)
     842       609819 :       && TYPE_OVERFLOW_UNDEFINED (type))
     843       609806 :     r.set_nonzero (type);
     844              :   else
     845         6960 :     r.set_varying (type);
     846              :   return true;
     847              : }
     848              : 
     849              : bool
     850          768 : operator_bitwise_and::fold_range (prange &r, tree type,
     851              :                                   const prange &op1,
     852              :                                   const prange &op2 ATTRIBUTE_UNUSED,
     853              :                                   relation_trio) const
     854              : {
     855              :   // For pointer types, we are really only interested in asserting
     856              :   // whether the expression evaluates to non-NULL.
     857          768 :   if (op1.zero_p () || op2.zero_p ())
     858            0 :     r.set_zero (type);
     859              :   else
     860          768 :     r.set_varying (type);
     861              : 
     862          768 :   update_known_bitmask (r, BIT_AND_EXPR, op1, op2);
     863          768 :   return true;
     864              : }
     865              : 
     866              : bool
     867      6844407 : operator_equal::fold_range (irange &r, tree type,
     868              :                             const prange &op1,
     869              :                             const prange &op2,
     870              :                             relation_trio rel) const
     871              : {
     872      6844407 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_EQ))
     873              :     return true;
     874              : 
     875              :   // We can be sure the values are always equal or not if both ranges
     876              :   // consist of a single value, and then compare them.
     877      6824376 :   bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ());
     878      6824376 :   bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ());
     879      6824376 :   if (op1_const && op2_const)
     880              :     {
     881        23448 :       if (wi::eq_p (op1.lower_bound (), op2.upper_bound()))
     882        23287 :         r = range_true (type);
     883              :       else
     884          161 :         r = range_false (type);
     885              :     }
     886              :   else
     887              :     {
     888              :       // If ranges do not intersect, we know the range is not equal,
     889              :       // otherwise we don't know anything for sure.
     890      6800928 :       prange tmp = op1;
     891      6800928 :       tmp.intersect (op2);
     892      6800928 :       if (tmp.undefined_p ())
     893       163877 :         r = range_false (type);
     894              :       // Check if a constant cannot satisfy the bitmask requirements.
     895     11689889 :       else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ()))
     896            0 :          r = range_false (type);
     897      6645501 :       else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ()))
     898            0 :          r = range_false (type);
     899              :       else
     900      6637051 :         r = range_true_and_false (type);
     901      6800928 :     }
     902              : 
     903              :   //update_known_bitmask (r, EQ_EXPR, op1, op2);
     904              :   return true;
     905              : }
     906              : 
     907              : bool
     908      4430519 : operator_equal::op1_range (prange &r, tree type,
     909              :                            const irange &lhs,
     910              :                            const prange &op2,
     911              :                            relation_trio) const
     912              : {
     913      4430519 :   switch (get_bool_state (r, lhs, type))
     914              :     {
     915      1220999 :     case BRS_TRUE:
     916              :       // If it's true, the result is the same as OP2.
     917      1220999 :       r = op2;
     918      1220999 :       break;
     919              : 
     920      3202212 :     case BRS_FALSE:
     921              :       // If the result is false, the only time we know anything is
     922              :       // if OP2 is a constant.
     923      3202212 :       if (!op2.undefined_p ()
     924      9606636 :           && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
     925              :         {
     926      1009241 :           r = op2;
     927      1009241 :           r.invert ();
     928              :         }
     929              :       else
     930      2192971 :         r.set_varying (type);
     931              :       break;
     932              : 
     933              :     default:
     934              :       break;
     935              :     }
     936      4430519 :   return true;
     937              : }
     938              : 
     939              : bool
     940      1527415 : operator_equal::op2_range (prange &r, tree type,
     941              :                            const irange &lhs,
     942              :                            const prange &op1,
     943              :                            relation_trio rel) const
     944              : {
     945      1527415 :   return operator_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
     946              : }
     947              : 
     948              : relation_kind
     949      5674422 : operator_equal::op1_op2_relation (const irange &lhs, const prange &,
     950              :                                   const prange &) const
     951              : {
     952      5674422 :   if (lhs.undefined_p ())
     953              :     return VREL_UNDEFINED;
     954              : 
     955              :   // FALSE = op1 == op2 indicates NE_EXPR.
     956      5674422 :   if (lhs.zero_p ())
     957              :     return VREL_NE;
     958              : 
     959              :   // TRUE = op1 == op2 indicates EQ_EXPR.
     960      2493147 :   if (!range_includes_zero_p (lhs))
     961      2493065 :     return VREL_EQ;
     962              :   return VREL_VARYING;
     963              : }
     964              : 
     965              : bool
     966      7897879 : operator_not_equal::fold_range (irange &r, tree type,
     967              :                                 const prange &op1,
     968              :                                 const prange &op2,
     969              :                                 relation_trio rel) const
     970              : {
     971      7897879 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_NE))
     972              :     return true;
     973              : 
     974              :   // We can be sure the values are always equal or not if both ranges
     975              :   // consist of a single value, and then compare them.
     976      7881006 :   bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ());
     977      7881006 :   bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ());
     978      7881006 :   if (op1_const && op2_const)
     979              :     {
     980        47028 :       if (wi::ne_p (op1.lower_bound (), op2.upper_bound()))
     981          175 :         r = range_true (type);
     982              :       else
     983        46853 :         r = range_false (type);
     984              :     }
     985              :   else
     986              :     {
     987              :       // If ranges do not intersect, we know the range is not equal,
     988              :       // otherwise we don't know anything for sure.
     989      7833978 :       prange tmp = op1;
     990      7833978 :       tmp.intersect (op2);
     991      7833978 :       if (tmp.undefined_p ())
     992       197636 :         r = range_true (type);
     993              :       // Check if a constant cannot satisfy the bitmask requirements.
     994     16333160 :       else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ()))
     995            0 :          r = range_true (type);
     996      7639016 :       else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ()))
     997            0 :          r = range_true (type);
     998              :       else
     999      7636342 :         r = range_true_and_false (type);
    1000      7833978 :     }
    1001              : 
    1002              :   //update_known_bitmask (r, NE_EXPR, op1, op2);
    1003              :   return true;
    1004              : }
    1005              : 
    1006              : bool
    1007      5462987 : operator_not_equal::op1_range (prange &r, tree type,
    1008              :                                const irange &lhs,
    1009              :                                const prange &op2,
    1010              :                                relation_trio) const
    1011              : {
    1012      5462987 :   switch (get_bool_state (r, lhs, type))
    1013              :     {
    1014      4313767 :     case BRS_TRUE:
    1015              :       // If the result is true, the only time we know anything is if
    1016              :       // OP2 is a constant.
    1017      4313767 :       if (!op2.undefined_p ()
    1018     12941301 :           && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
    1019              :         {
    1020      1623201 :           r = op2;
    1021      1623201 :           r.invert ();
    1022              :         }
    1023              :       else
    1024      2690566 :         r.set_varying (type);
    1025              :       break;
    1026              : 
    1027      1125675 :     case BRS_FALSE:
    1028              :       // If it's false, the result is the same as OP2.
    1029      1125675 :       r = op2;
    1030      1125675 :       break;
    1031              : 
    1032              :     default:
    1033              :       break;
    1034              :     }
    1035      5462987 :   return true;
    1036              : }
    1037              : 
    1038              : 
    1039              : bool
    1040      1714519 : operator_not_equal::op2_range (prange &r, tree type,
    1041              :                                const irange &lhs,
    1042              :                                const prange &op1,
    1043              :                                relation_trio rel) const
    1044              : {
    1045      1714519 :   return operator_not_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
    1046              : }
    1047              : 
    1048              : relation_kind
    1049      5973194 : operator_not_equal::op1_op2_relation (const irange &lhs, const prange &,
    1050              :                                       const prange &) const
    1051              : {
    1052      5973194 :   if (lhs.undefined_p ())
    1053              :     return VREL_UNDEFINED;
    1054              : 
    1055              :   // FALSE = op1 != op2  indicates EQ_EXPR.
    1056      5973194 :   if (lhs.zero_p ())
    1057              :     return VREL_EQ;
    1058              : 
    1059              :   // TRUE = op1 != op2  indicates NE_EXPR.
    1060      4024126 :   if (!range_includes_zero_p (lhs))
    1061      4020609 :     return VREL_NE;
    1062              :   return VREL_VARYING;
    1063              : }
    1064              : 
    1065              : bool
    1066       357941 : operator_lt::fold_range (irange &r, tree type,
    1067              :                          const prange &op1,
    1068              :                          const prange &op2,
    1069              :                          relation_trio rel) const
    1070              : {
    1071       357941 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_LT))
    1072              :     return true;
    1073              : 
    1074       357143 :   signop sign = TYPE_SIGN (op1.type ());
    1075       357143 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1076              : 
    1077       357143 :   if (wi::lt_p (op1.upper_bound (), op2.lower_bound (), sign))
    1078            0 :     r = range_true (type);
    1079       357143 :   else if (!wi::lt_p (op1.lower_bound (), op2.upper_bound (), sign))
    1080           28 :     r = range_false (type);
    1081              :   // Use nonzero bits to determine if < 0 is false.
    1082       357115 :   else if (op2.zero_p () && !wi::neg_p (op1.get_nonzero_bits (), sign))
    1083            0 :     r = range_false (type);
    1084              :   else
    1085       357115 :     r = range_true_and_false (type);
    1086              : 
    1087              :   //update_known_bitmask (r, LT_EXPR, op1, op2);
    1088              :   return true;
    1089              : }
    1090              : 
    1091              : bool
    1092       282693 : operator_lt::op1_range (prange &r, tree type,
    1093              :                         const irange &lhs,
    1094              :                         const prange &op2,
    1095              :                         relation_trio) const
    1096              : {
    1097       282693 :   if (op2.undefined_p ())
    1098              :     return false;
    1099              : 
    1100       282693 :   switch (get_bool_state (r, lhs, type))
    1101              :     {
    1102       239697 :     case BRS_TRUE:
    1103       239697 :       build_lt (r, type, op2);
    1104       239697 :       break;
    1105              : 
    1106        42996 :     case BRS_FALSE:
    1107        42996 :       build_ge (r, type, op2);
    1108        42996 :       break;
    1109              : 
    1110              :     default:
    1111              :       break;
    1112              :     }
    1113              :   return true;
    1114              : }
    1115              : 
    1116              : bool
    1117       172321 : operator_lt::op2_range (prange &r, tree type,
    1118              :                         const irange &lhs,
    1119              :                         const prange &op1,
    1120              :                         relation_trio) const
    1121              : {
    1122       172321 :   if (op1.undefined_p ())
    1123              :     return false;
    1124              : 
    1125       172321 :   switch (get_bool_state (r, lhs, type))
    1126              :     {
    1127       121567 :     case BRS_TRUE:
    1128       121567 :       build_gt (r, type, op1);
    1129       121567 :       break;
    1130              : 
    1131        50750 :     case BRS_FALSE:
    1132        50750 :       build_le (r, type, op1);
    1133        50750 :       break;
    1134              : 
    1135              :     default:
    1136              :       break;
    1137              :     }
    1138              :   return true;
    1139              : }
    1140              : 
    1141              : relation_kind
    1142       764046 : operator_lt::op1_op2_relation (const irange &lhs, const prange &,
    1143              :                                const prange &) const
    1144              : {
    1145       764046 :   if (lhs.undefined_p ())
    1146              :     return VREL_UNDEFINED;
    1147              : 
    1148              :   // FALSE = op1 < op2 indicates GE_EXPR.
    1149       764046 :   if (lhs.zero_p ())
    1150              :     return VREL_GE;
    1151              : 
    1152              :   // TRUE = op1 < op2 indicates LT_EXPR.
    1153       567177 :   if (!range_includes_zero_p (lhs))
    1154       567173 :     return VREL_LT;
    1155              :   return VREL_VARYING;
    1156              : }
    1157              : 
    1158              : bool
    1159       105313 : operator_le::fold_range (irange &r, tree type,
    1160              :                          const prange &op1,
    1161              :                          const prange &op2,
    1162              :                          relation_trio rel) const
    1163              : {
    1164       105313 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_LE))
    1165              :     return true;
    1166              : 
    1167       105007 :   signop sign = TYPE_SIGN (op1.type ());
    1168       105007 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1169              : 
    1170       105007 :   if (wi::le_p (op1.upper_bound (), op2.lower_bound (), sign))
    1171           17 :     r = range_true (type);
    1172       104990 :   else if (!wi::le_p (op1.lower_bound (), op2.upper_bound (), sign))
    1173           10 :     r = range_false (type);
    1174              :   else
    1175       104980 :     r = range_true_and_false (type);
    1176              : 
    1177              :   //update_known_bitmask (r, LE_EXPR, op1, op2);
    1178              :   return true;
    1179              : }
    1180              : 
    1181              : bool
    1182        74461 : operator_le::op1_range (prange &r, tree type,
    1183              :                         const irange &lhs,
    1184              :                         const prange &op2,
    1185              :                         relation_trio) const
    1186              : {
    1187        74461 :   if (op2.undefined_p ())
    1188              :     return false;
    1189              : 
    1190        74461 :   switch (get_bool_state (r, lhs, type))
    1191              :     {
    1192        53216 :     case BRS_TRUE:
    1193        53216 :       build_le (r, type, op2);
    1194        53216 :       break;
    1195              : 
    1196        21245 :     case BRS_FALSE:
    1197        21245 :       build_gt (r, type, op2);
    1198        21245 :       break;
    1199              : 
    1200              :     default:
    1201              :       break;
    1202              :     }
    1203              :   return true;
    1204              : }
    1205              : 
    1206              : bool
    1207       110547 : operator_le::op2_range (prange &r, tree type,
    1208              :                         const irange &lhs,
    1209              :                         const prange &op1,
    1210              :                         relation_trio) const
    1211              : {
    1212       110547 :   if (op1.undefined_p ())
    1213              :     return false;
    1214              : 
    1215       110547 :   switch (get_bool_state (r, lhs, type))
    1216              :     {
    1217        90683 :     case BRS_TRUE:
    1218        90683 :       build_ge (r, type, op1);
    1219        90683 :       break;
    1220              : 
    1221        19864 :     case BRS_FALSE:
    1222        19864 :       build_lt (r, type, op1);
    1223        19864 :       break;
    1224              : 
    1225              :     default:
    1226              :       break;
    1227              :     }
    1228              :   return true;
    1229              : }
    1230              : 
    1231              : relation_kind
    1232       298933 : operator_le::op1_op2_relation (const irange &lhs, const prange &,
    1233              :                                const prange &) const
    1234              : {
    1235       298933 :   if (lhs.undefined_p ())
    1236              :     return VREL_UNDEFINED;
    1237              : 
    1238              :   // FALSE = op1 <= op2 indicates GT_EXPR.
    1239       298933 :   if (lhs.zero_p ())
    1240              :     return VREL_GT;
    1241              : 
    1242              :   // TRUE = op1 <= op2 indicates LE_EXPR.
    1243       218280 :   if (!range_includes_zero_p (lhs))
    1244       218280 :     return VREL_LE;
    1245              :   return VREL_VARYING;
    1246              : }
    1247              : 
    1248              : bool
    1249       352412 : operator_gt::fold_range (irange &r, tree type,
    1250              :                          const prange &op1, const prange &op2,
    1251              :                          relation_trio rel) const
    1252              : {
    1253       352412 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_GT))
    1254              :     return true;
    1255              : 
    1256       351469 :   signop sign = TYPE_SIGN (op1.type ());
    1257       351469 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1258              : 
    1259       351469 :   if (wi::gt_p (op1.lower_bound (), op2.upper_bound (), sign))
    1260            2 :     r = range_true (type);
    1261       351467 :   else if (!wi::gt_p (op1.upper_bound (), op2.lower_bound (), sign))
    1262            7 :     r = range_false (type);
    1263              :   else
    1264       351460 :     r = range_true_and_false (type);
    1265              : 
    1266              :   //update_known_bitmask (r, GT_EXPR, op1, op2);
    1267              :   return true;
    1268              : }
    1269              : 
    1270              : bool
    1271       245903 : operator_gt::op1_range (prange &r, tree type,
    1272              :                         const irange &lhs, const prange &op2,
    1273              :                         relation_trio) const
    1274              : {
    1275       245903 :   if (op2.undefined_p ())
    1276              :     return false;
    1277              : 
    1278       245903 :   switch (get_bool_state (r, lhs, type))
    1279              :     {
    1280       167435 :     case BRS_TRUE:
    1281       167435 :       build_gt (r, type, op2);
    1282       167435 :       break;
    1283              : 
    1284        78468 :     case BRS_FALSE:
    1285        78468 :       build_le (r, type, op2);
    1286        78468 :       break;
    1287              : 
    1288              :     default:
    1289              :       break;
    1290              :     }
    1291              :   return true;
    1292              : }
    1293              : 
    1294              : bool
    1295       251274 : operator_gt::op2_range (prange &r, tree type,
    1296              :                         const irange &lhs,
    1297              :                         const prange &op1,
    1298              :                         relation_trio) const
    1299              : {
    1300       251274 :   if (op1.undefined_p ())
    1301              :     return false;
    1302              : 
    1303       251274 :   switch (get_bool_state (r, lhs, type))
    1304              :     {
    1305       210041 :     case BRS_TRUE:
    1306       210041 :       build_lt (r, type, op1);
    1307       210041 :       break;
    1308              : 
    1309        41233 :     case BRS_FALSE:
    1310        41233 :       build_ge (r, type, op1);
    1311        41233 :       break;
    1312              : 
    1313              :     default:
    1314              :       break;
    1315              :     }
    1316              :   return true;
    1317              : }
    1318              : 
    1319              : relation_kind
    1320       823780 : operator_gt::op1_op2_relation (const irange &lhs, const prange &,
    1321              :                                const prange &) const
    1322              : {
    1323       823780 :   if (lhs.undefined_p ())
    1324              :     return VREL_UNDEFINED;
    1325              : 
    1326              :   // FALSE = op1 > op2 indicates LE_EXPR.
    1327       823780 :   if (lhs.zero_p ())
    1328              :     return VREL_LE;
    1329              : 
    1330              :   // TRUE = op1 > op2 indicates GT_EXPR.
    1331       599844 :   if (!range_includes_zero_p (lhs))
    1332       599844 :     return VREL_GT;
    1333              :   return VREL_VARYING;
    1334              : }
    1335              : 
    1336              : bool
    1337       184671 : operator_ge::fold_range (irange &r, tree type,
    1338              :                          const prange &op1,
    1339              :                          const prange &op2,
    1340              :                          relation_trio rel) const
    1341              : {
    1342       184671 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_GE))
    1343              :     return true;
    1344              : 
    1345       184425 :   signop sign = TYPE_SIGN (op1.type ());
    1346       184425 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1347              : 
    1348       184425 :   if (wi::ge_p (op1.lower_bound (), op2.upper_bound (), sign))
    1349           67 :     r = range_true (type);
    1350       184358 :   else if (!wi::ge_p (op1.upper_bound (), op2.lower_bound (), sign))
    1351            0 :     r = range_false (type);
    1352              :   else
    1353       184358 :     r = range_true_and_false (type);
    1354              : 
    1355              :   //update_known_bitmask (r, GE_EXPR, op1, op2);
    1356              :   return true;
    1357              : }
    1358              : 
    1359              : bool
    1360       179766 : operator_ge::op1_range (prange &r, tree type,
    1361              :                         const irange &lhs,
    1362              :                         const prange &op2,
    1363              :                         relation_trio) const
    1364              : {
    1365       179766 :   if (op2.undefined_p ())
    1366              :     return false;
    1367              : 
    1368       179766 :   switch (get_bool_state (r, lhs, type))
    1369              :     {
    1370       153707 :     case BRS_TRUE:
    1371       153707 :       build_ge (r, type, op2);
    1372       153707 :       break;
    1373              : 
    1374        26059 :     case BRS_FALSE:
    1375        26059 :       build_lt (r, type, op2);
    1376        26059 :       break;
    1377              : 
    1378              :     default:
    1379              :       break;
    1380              :     }
    1381              :   return true;
    1382              : }
    1383              : 
    1384              : bool
    1385        80309 : operator_ge::op2_range (prange &r, tree type,
    1386              :                         const irange &lhs,
    1387              :                         const prange &op1,
    1388              :                         relation_trio) const
    1389              : {
    1390        80309 :   if (op1.undefined_p ())
    1391              :     return false;
    1392              : 
    1393        80309 :   switch (get_bool_state (r, lhs, type))
    1394              :     {
    1395        52861 :     case BRS_TRUE:
    1396        52861 :       build_le (r, type, op1);
    1397        52861 :       break;
    1398              : 
    1399        27448 :     case BRS_FALSE:
    1400        27448 :       build_gt (r, type, op1);
    1401        27448 :       break;
    1402              : 
    1403              :     default:
    1404              :       break;
    1405              :     }
    1406              :   return true;
    1407              : }
    1408              : 
    1409              : relation_kind
    1410       454211 : operator_ge::op1_op2_relation (const irange &lhs, const prange &,
    1411              :                                const prange &) const
    1412              : {
    1413       454211 :   if (lhs.undefined_p ())
    1414              :     return VREL_UNDEFINED;
    1415              : 
    1416              :   // FALSE = op1 >= op2 indicates LT_EXPR.
    1417       454211 :   if (lhs.zero_p ())
    1418              :     return VREL_LT;
    1419              : 
    1420              :   // TRUE = op1 >= op2 indicates GE_EXPR.
    1421       332066 :   if (!range_includes_zero_p (lhs))
    1422       332066 :     return VREL_GE;
    1423              :   return VREL_VARYING;
    1424              : }
    1425              : 
    1426              : // Initialize any pointer operators to the primary table
    1427              : 
    1428              : void
    1429       284591 : range_op_table::initialize_pointer_ops ()
    1430              : {
    1431       284591 :   set (POINTER_PLUS_EXPR, op_pointer_plus);
    1432       284591 :   set (POINTER_DIFF_EXPR, op_pointer_diff);
    1433       284591 : }
        

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.