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-05-11 19:44:49 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       754445 : range_operator::op1_range (prange &, tree,
     143              :                            const irange &lhs ATTRIBUTE_UNUSED,
     144              :                            const prange &op2 ATTRIBUTE_UNUSED,
     145              :                            relation_trio) const
     146              : {
     147       754445 :   return false;
     148              : }
     149              : 
     150              : bool
     151       388809 : range_operator::op1_range (prange &, tree,
     152              :                            const prange &lhs ATTRIBUTE_UNUSED,
     153              :                            const irange &op2 ATTRIBUTE_UNUSED,
     154              :                            relation_trio) const
     155              : {
     156       388809 :   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      1168248 : range_operator::op2_range (prange &, tree,
     170              :                            const irange &lhs ATTRIBUTE_UNUSED,
     171              :                            const prange &op1 ATTRIBUTE_UNUSED,
     172              :                            relation_trio) const
     173              : {
     174      1168248 :   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      1855638 : 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      1855638 :   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      3813991 : 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      3813991 :   return VREL_VARYING;
     210              : }
     211              : 
     212              : relation_kind
     213        78825 : 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        78825 :   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       656722 : max_limit (const_tree type)
     241              : {
     242       656722 :   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       689398 : min_limit (const_tree type)
     249              : {
     250       689398 :   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       447974 : build_lt (prange &r, tree type, const prange &val)
     257              : {
     258       447974 :   wi::overflow_type ov;
     259       447974 :   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       447974 :   if (ov)
     263            0 :     r.set_undefined ();
     264              :   else
     265       447974 :     r.set (type, min_limit (type), lim);
     266       447974 : }
     267              : 
     268              : // Build a range that is <= VAL and store it in R.
     269              : 
     270              : static void
     271       241424 : build_le (prange &r, tree type, const prange &val)
     272              : {
     273       241424 :   r.set (type, min_limit (type), val.upper_bound ());
     274       241424 : }
     275              : 
     276              : // Build a range that is > VAL and store it in R.
     277              : 
     278              : static void
     279       321918 : build_gt (prange &r, tree type, const prange &val)
     280              : {
     281       321918 :   wi::overflow_type ov;
     282       321918 :   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       321918 :   if (ov)
     286            0 :     r.set_undefined ();
     287              :   else
     288       321918 :     r.set (type, lim, max_limit (type));
     289              : 
     290       321918 : }
     291              : 
     292              : // Build a range that is >= VAL and store it in R.
     293              : 
     294              : static void
     295       334804 : build_ge (prange &r, tree type, const prange &val)
     296              : {
     297       334804 :   r.set (type, val.lower_bound (), max_limit (type));
     298       334804 : }
     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      9116356 : pointer_plus_operator::fold_range (prange &r, tree type,
     326              :                                    const prange &op1,
     327              :                                    const irange &op2,
     328              :                                    relation_trio) const
     329              : {
     330      9116356 :   if (empty_range_varying (r, type, op1, op2))
     331         5968 :     return true;
     332              : 
     333      9110388 :   const wide_int lh_lb = op1.lower_bound ();
     334      9110388 :   const wide_int lh_ub = op1.upper_bound ();
     335      9110388 :   const wide_int rh_lb = op2.lower_bound ();
     336      9110388 :   const wide_int rh_ub = op2.upper_bound ();
     337              : 
     338              :   // Check for [0,0] + const, and simply return the const.
     339      9117959 :   if (lh_lb == 0 && lh_ub == 0 && rh_lb == rh_ub)
     340              :     {
     341          835 :       r.set (type, rh_lb, rh_lb);
     342          835 :       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      9109553 :   if ((!wi_includes_zero_p (type, lh_lb, lh_ub)
     362      5434997 :        || !wi_includes_zero_p (type, rh_lb, rh_ub))
     363      5948491 :       && !TYPE_OVERFLOW_WRAPS (type)
     364     15057407 :       && (flag_delete_null_pointer_checks
     365         1293 :           || !wi::sign_mask (rh_ub)))
     366      5947439 :     r.set_nonzero (type);
     367      3167821 :   else if (lh_lb == lh_ub && lh_lb == 0
     368      3167821 :            && rh_lb == rh_ub && rh_lb == 0)
     369            0 :     r.set_zero (type);
     370              :   else
     371      3162114 :    r.set_varying (type);
     372              : 
     373      9109553 :   update_known_bitmask (r, POINTER_PLUS_EXPR, op1, op2);
     374      9109553 :   return true;
     375      9110388 : }
     376              : 
     377              : bool
     378       211207 : pointer_plus_operator::op2_range (irange &r, tree type,
     379              :                                   const prange &lhs ATTRIBUTE_UNUSED,
     380              :                                   const prange &op1 ATTRIBUTE_UNUSED,
     381              :                                   relation_trio trio) const
     382              : {
     383       211207 :   relation_kind rel = trio.lhs_op1 ();
     384       211207 :   r.set_varying (type);
     385              : 
     386              :   // If the LHS and OP1 are equal, the op2 must be zero.
     387       211207 :   if (rel == VREL_EQ)
     388         9737 :     r.set_zero (type);
     389              :   // If the LHS and OP1 are not equal, the offset must be non-zero.
     390       201470 :   else if (rel == VREL_NE)
     391        14355 :     r.set_nonzero (type);
     392              :   else
     393              :     return false;
     394              :   return true;
     395              : }
     396              : 
     397              : // Return the relation between the LHS and OP1 based on the value of the
     398              : // operand being added.  Pointer_plus is define to have a size_type for
     399              : // operand 2 which can be interpreted as negative, so always used SIGNED.
     400              : // Any overflow is considered UB and thus ignored.
     401              : 
     402              : relation_kind
     403      7875723 : pointer_plus_operator::lhs_op1_relation (const prange &lhs,
     404              :                                          const prange &op1,
     405              :                                          const irange &op2,
     406              :                                          relation_kind) const
     407              : {
     408      7875723 :   if (lhs.undefined_p () || op1.undefined_p () || op2.undefined_p ())
     409              :     return VREL_VARYING;
     410              : 
     411      7870132 :   unsigned prec = TYPE_PRECISION (op2.type ());
     412              : 
     413              :   // LHS = OP1 + 0  indicates LHS == OP1.
     414      7870132 :   if (op2.zero_p ())
     415              :     return VREL_EQ;
     416              : 
     417      7853073 :   tree val;
     418              :   // Only deal with singletons for now.
     419      7853073 :   if (TYPE_OVERFLOW_UNDEFINED (lhs.type ()) && op2.singleton_p (&val))
     420              :     {
     421              :       // Always interpret VALUE as a signed value.  Positive will increase
     422              :       // the pointer value, and negative will decrease the poiinter value.
     423              :       // It cannot be zero or the earlier zero_p () condition will catch it.
     424      3785201 :       wide_int value = wi::to_wide (val);
     425              : 
     426              :       // Positive op2 means lhs > op1.
     427      3785201 :       if (wi::gt_p (value, wi::zero (prec), SIGNED))
     428              :         return VREL_GT;
     429              : 
     430              :       // Negative op2 means lhs < op1.
     431       416442 :       if (wi::lt_p (value, wi::zero (prec), SIGNED))
     432              :         return VREL_LT;
     433      3785201 :     }
     434              : 
     435              :   // If op2 does not contain 0, then LHS and OP1 can never be equal.
     436      4067872 :   if (!range_includes_zero_p (op2))
     437              :     return VREL_NE;
     438              : 
     439              :   return VREL_VARYING;
     440              : }
     441              : 
     442              : bool
     443            0 : operator_bitwise_or::fold_range (prange &r, tree type,
     444              :                                  const prange &op1,
     445              :                                  const prange &op2,
     446              :                                  relation_trio) const
     447              : {
     448              :   // For pointer types, we are really only interested in asserting
     449              :   // whether the expression evaluates to non-NULL.
     450            0 :   if (!range_includes_zero_p (op1) || !range_includes_zero_p (op2))
     451            0 :     r.set_nonzero (type);
     452            0 :   else if (op1.zero_p () && op2.zero_p ())
     453            0 :     r.set_zero (type);
     454              :   else
     455            0 :     r.set_varying (type);
     456              : 
     457            0 :   update_known_bitmask (r, BIT_IOR_EXPR, op1, op2);
     458            0 :   return true;
     459              : }
     460              : 
     461              : 
     462              : class operator_pointer_diff : public range_operator
     463              : {
     464              :   using range_operator::fold_range;
     465              :   using range_operator::update_bitmask;
     466              :   using range_operator::op1_op2_relation_effect;
     467              :   virtual bool fold_range (irange &r, tree type,
     468              :                            const prange &op1,
     469              :                            const prange &op2,
     470              :                            relation_trio trio) const final override;
     471              :   virtual bool op1_op2_relation_effect (irange &lhs_range,
     472              :                                         tree type,
     473              :                                         const prange &op1_range,
     474              :                                         const prange &op2_range,
     475              :                                         relation_kind rel) const final override;
     476      2537519 :   void update_bitmask (irange &r,
     477              :                        const prange &lh, const prange &rh) const final override
     478            0 :   { update_known_bitmask (r, POINTER_DIFF_EXPR, lh, rh); }
     479              : };
     480              : static const operator_pointer_diff op_pointer_diff;
     481              : 
     482              : bool
     483      2537519 : operator_pointer_diff::fold_range (irange &r, tree type,
     484              :                                    const prange &op1,
     485              :                                    const prange &op2,
     486              :                                    relation_trio trio) const
     487              : {
     488      2537519 :   gcc_checking_assert (r.supports_type_p (type));
     489              : 
     490      2537519 :   r.set_varying (type);
     491      2537519 :   relation_kind rel = trio.op1_op2 ();
     492      2537519 :   op1_op2_relation_effect (r, type, op1, op2, rel);
     493      2537519 :   update_bitmask (r, op1, op2);
     494      2537519 :   return true;
     495              : }
     496              : 
     497              : bool
     498      2537519 : operator_pointer_diff::op1_op2_relation_effect (irange &lhs_range, tree type,
     499              :                                                 const prange &op1_range,
     500              :                                                 const prange &op2_range,
     501              :                                                 relation_kind rel) const
     502              : {
     503      2537519 :   int_range<2> op1, op2, tmp;
     504      2537519 :   range_op_handler cast (CONVERT_EXPR);
     505              : 
     506      2537519 :   if (!cast.fold_range (op1, type, op1_range, tmp)
     507      2537519 :       || !cast.fold_range (op2, type, op2_range, tmp))
     508            0 :     return false;
     509              : 
     510      2537519 :   return minus_op1_op2_relation_effect (lhs_range, type, op1, op2, rel);
     511      2537519 : }
     512              : 
     513              : bool
     514      1293141 : operator_identity::fold_range (prange &r, tree type ATTRIBUTE_UNUSED,
     515              :                                const prange &lh ATTRIBUTE_UNUSED,
     516              :                                const prange &rh ATTRIBUTE_UNUSED,
     517              :                                relation_trio) const
     518              : {
     519      1293141 :   r = lh;
     520      1293141 :   return true;
     521              : }
     522              : 
     523              : relation_kind
     524      1140139 : operator_identity::lhs_op1_relation (const prange &lhs,
     525              :                                      const prange &op1 ATTRIBUTE_UNUSED,
     526              :                                      const prange &op2 ATTRIBUTE_UNUSED,
     527              :                                      relation_kind) const
     528              : {
     529      1140139 :   if (lhs.undefined_p ())
     530          389 :     return VREL_VARYING;
     531              :   // Simply a copy, so they are equivalent.
     532              :   return VREL_EQ;
     533              : }
     534              : 
     535              : bool
     536       179605 : operator_identity::op1_range (prange &r, tree type ATTRIBUTE_UNUSED,
     537              :                               const prange &lhs,
     538              :                               const prange &op2 ATTRIBUTE_UNUSED,
     539              :                               relation_trio) const
     540              : {
     541       179605 :   r = lhs;
     542       179605 :   return true;
     543              : }
     544              : 
     545              : bool
     546        18266 : operator_cst::fold_range (prange &r, tree type ATTRIBUTE_UNUSED,
     547              :                           const prange &lh,
     548              :                           const prange & ATTRIBUTE_UNUSED,
     549              :                           relation_trio) const
     550              : {
     551        18266 :   r = lh;
     552        18266 :   return true;
     553              : }
     554              : 
     555              : // Cast between pointers.
     556              : 
     557              : bool
     558     16899747 : operator_cast::fold_range (prange &r, tree type,
     559              :                            const prange &inner,
     560              :                            const prange &outer,
     561              :                            relation_trio) const
     562              : {
     563     16899747 :   if (empty_range_varying (r, type, inner, outer))
     564          452 :     return true;
     565              : 
     566     16899295 :   r.set (type, inner.lower_bound (), inner.upper_bound ());
     567     16899295 :   r.update_bitmask (inner.get_bitmask ());
     568     16899295 :   return true;
     569              : }
     570              : 
     571              : // Cast a pointer to an integer.
     572              : 
     573              : bool
     574     10524259 : operator_cast::fold_range (irange &r, tree type,
     575              :                            const prange &inner,
     576              :                            const irange &outer,
     577              :                            relation_trio) const
     578              : {
     579     10524259 :   if (empty_range_varying (r, type, inner, outer))
     580      5076175 :     return true;
     581              : 
     582              :   // Represent INNER as an integer of the same size, and then cast it
     583              :   // to the resulting integer type.
     584      5448084 :   tree pointer_uint_type = make_unsigned_type (TYPE_PRECISION (inner.type ()));
     585      5448084 :   r.set (pointer_uint_type, inner.lower_bound (), inner.upper_bound ());
     586      5448084 :   r.update_bitmask (inner.get_bitmask ());
     587      5448084 :   range_cast (r, type);
     588      5448084 :   return true;
     589              : }
     590              : 
     591              : // Cast an integer to a pointer.
     592              : 
     593              : bool
     594      1875226 : operator_cast::fold_range (prange &r, tree type,
     595              :                            const irange &inner,
     596              :                            const prange &outer,
     597              :                            relation_trio) const
     598              : {
     599      1875226 :   if (empty_range_varying (r, type, inner, outer))
     600         1776 :     return true;
     601              : 
     602              :   // Cast INNER to an integer of the same size as the pointer we want,
     603              :   // and then copy the bounds to the resulting pointer range.
     604      1873450 :   int_range<2> tmp = inner;
     605      1873450 :   tree pointer_uint_type = make_unsigned_type (TYPE_PRECISION (type));
     606      1873450 :   range_cast (tmp, pointer_uint_type);
     607              :   // Casts may cause ranges to become UNDEFINED based on bitmasks.
     608      1873450 :   if (tmp.undefined_p ())
     609            0 :     r.set_varying (type);
     610              :   else
     611              :     {
     612      1873450 :       r.set (type, tmp.lower_bound (), tmp.upper_bound ());
     613      1873450 :       r.update_bitmask (tmp.get_bitmask ());
     614              :     }
     615      1873450 :   return true;
     616      1873450 : }
     617              : 
     618              : bool
     619           69 : operator_cast::op1_range (prange &r, tree type,
     620              :                           const prange &lhs,
     621              :                           const prange &op2,
     622              :                           relation_trio trio) const
     623              : {
     624           69 :   if (lhs.undefined_p ())
     625              :     return false;
     626           69 :   gcc_checking_assert (types_compatible_p (op2.type(), type));
     627              : 
     628              :   // Conversion from other pointers or a constant (including 0/NULL)
     629              :   // are straightforward.
     630           69 :   if (POINTER_TYPE_P (lhs.type ())
     631           69 :       || (lhs.singleton_p ()
     632            0 :           && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
     633           69 :     fold_range (r, type, lhs, op2, trio);
     634              :   else
     635              :     {
     636              :       // If the LHS is not a pointer nor a singleton, then it is
     637              :       // either VARYING or non-zero.
     638            0 :       if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
     639            0 :         r.set_nonzero (type);
     640              :       else
     641            0 :         r.set_varying (type);
     642              :     }
     643           69 :   r.intersect (op2);
     644           69 :   return true;
     645              : }
     646              : 
     647              : bool
     648       229137 : operator_cast::op1_range (irange &r, tree type,
     649              :                           const prange &lhs,
     650              :                           const irange &op2,
     651              :                           relation_trio trio) const
     652              : {
     653       229137 :   if (lhs.undefined_p ())
     654              :     return false;
     655       229137 :   gcc_checking_assert (types_compatible_p (op2.type(), type));
     656              : 
     657              :   // Conversion from other pointers or a constant (including 0/NULL)
     658              :   // are straightforward.
     659       229137 :   if (POINTER_TYPE_P (lhs.type ())
     660       229137 :       || (lhs.singleton_p ()
     661            0 :           && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
     662       229137 :     fold_range (r, type, lhs, op2, trio);
     663              :   else
     664              :     {
     665              :       // If the LHS is not a pointer nor a singleton, then it is
     666              :       // either VARYING or non-zero.
     667            0 :       if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
     668            0 :         r.set_nonzero (type);
     669              :       else
     670            0 :         r.set_varying (type);
     671              :     }
     672       229137 :   r.intersect (op2);
     673       229137 :   return true;
     674              : }
     675              : 
     676              : bool
     677       494013 : operator_cast::op1_range (prange &r, tree type,
     678              :                           const irange &lhs,
     679              :                           const prange &op2,
     680              :                           relation_trio trio) const
     681              : {
     682       494013 :   if (lhs.undefined_p ())
     683              :     return false;
     684       494013 :   gcc_checking_assert (types_compatible_p (op2.type(), type));
     685              : 
     686              :   // Conversion from other pointers or a constant (including 0/NULL)
     687              :   // are straightforward.
     688       988026 :   if (POINTER_TYPE_P (lhs.type ())
     689       988026 :       || (lhs.singleton_p ()
     690         1245 :           && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
     691         1239 :     fold_range (r, type, lhs, op2, trio);
     692              :   else
     693              :     {
     694              :       // If the LHS is not a pointer nor a singleton, then it is
     695              :       // either VARYING or non-zero.
     696       492774 :       if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
     697       223411 :         r.set_nonzero (type);
     698              :       else
     699       269363 :         r.set_varying (type);
     700              :     }
     701       494013 :   r.intersect (op2);
     702       494013 :   return true;
     703              : }
     704              : 
     705              : relation_kind
     706       137484 : operator_cast::lhs_op1_relation (const prange &lhs,
     707              :                                  const prange &op1,
     708              :                                  const prange &op2 ATTRIBUTE_UNUSED,
     709              :                                  relation_kind) const
     710              : {
     711       137484 :   if (lhs.undefined_p () || op1.undefined_p ())
     712              :     return VREL_VARYING;
     713       137484 :   unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
     714       137484 :   unsigned op1_prec = TYPE_PRECISION (op1.type ());
     715              :   // If the result gets sign extended into a larger type check first if this
     716              :   // qualifies as a partial equivalence.
     717       137484 :   if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
     718              :     {
     719              :       // If the result is sign extended, and the LHS is larger than op1,
     720              :       // check if op1's range can be negative as the sign extension will
     721              :       // cause the upper bits to be 1 instead of 0, invalidating the PE.
     722            0 :       int_range<3> negs = range_negatives (op1.type ());
     723            0 :       negs.intersect (op1);
     724            0 :       if (!negs.undefined_p ())
     725            0 :         return VREL_VARYING;
     726            0 :     }
     727              : 
     728       137484 :   unsigned prec = MIN (lhs_prec, op1_prec);
     729       137484 :   return bits_to_pe (prec);
     730              : }
     731              : 
     732              : relation_kind
     733      1401067 : operator_cast::lhs_op1_relation (const prange &lhs,
     734              :                                  const irange &op1,
     735              :                                  const irange &op2 ATTRIBUTE_UNUSED,
     736              :                                  relation_kind) const
     737              : {
     738      1401067 :   if (lhs.undefined_p () || op1.undefined_p ())
     739              :     return VREL_VARYING;
     740      1399297 :   unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
     741      1399297 :   unsigned op1_prec = TYPE_PRECISION (op1.type ());
     742              :   // If the result gets sign extended into a larger type check first if this
     743              :   // qualifies as a partial equivalence.
     744      1399297 :   if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
     745              :     {
     746              :       // If the result is sign extended, and the LHS is larger than op1,
     747              :       // check if op1's range can be negative as the sign extension will
     748              :       // cause the upper bits to be 1 instead of 0, invalidating the PE.
     749          284 :       int_range<3> negs = range_negatives (op1.type ());
     750          284 :       negs.intersect (op1);
     751          284 :       if (!negs.undefined_p ())
     752          276 :         return VREL_VARYING;
     753          284 :     }
     754              : 
     755      1399021 :   unsigned prec = MIN (lhs_prec, op1_prec);
     756      1399021 :   return bits_to_pe (prec);
     757              : }
     758              : 
     759              : relation_kind
     760      2151712 : operator_cast::lhs_op1_relation (const irange &lhs,
     761              :                                  const prange &op1,
     762              :                                  const prange &op2 ATTRIBUTE_UNUSED,
     763              :                                  relation_kind) const
     764              : {
     765      2151712 :   if (lhs.undefined_p () || op1.undefined_p ())
     766              :     return VREL_VARYING;
     767      2150966 :   unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
     768      2150966 :   unsigned op1_prec = TYPE_PRECISION (op1.type ());
     769              :   // If the result gets sign extended into a larger type check first if this
     770              :   // qualifies as a partial equivalence.
     771      2150966 :   if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
     772              :     {
     773              :       // If the result is sign extended, and the LHS is larger than op1,
     774              :       // check if op1's range can be negative as the sign extension will
     775              :       // cause the upper bits to be 1 instead of 0, invalidating the PE.
     776            0 :       int_range<3> negs = range_negatives (op1.type ());
     777            0 :       negs.intersect (op1);
     778            0 :       if (!negs.undefined_p ())
     779            0 :         return VREL_VARYING;
     780            0 :     }
     781              : 
     782      2150966 :   unsigned prec = MIN (lhs_prec, op1_prec);
     783      2150966 :   return bits_to_pe (prec);
     784              : }
     785              : 
     786              : bool
     787         1098 : operator_min::fold_range (prange &r, tree type,
     788              :                           const prange &op1,
     789              :                           const prange &op2,
     790              :                           relation_trio) const
     791              : {
     792              :   // For MIN/MAX expressions with pointers, we only care about
     793              :   // nullness.  If both are non null, then the result is nonnull.
     794              :   // If both are null, then the result is null.  Otherwise they
     795              :   // are varying.
     796         1098 :   if (!range_includes_zero_p (op1)
     797         1098 :       && !range_includes_zero_p (op2))
     798          144 :     r.set_nonzero (type);
     799          954 :   else if (op1.zero_p () && op2.zero_p ())
     800            0 :     r.set_zero (type);
     801              :   else
     802          954 :     r.set_varying (type);
     803              : 
     804         1098 :   update_known_bitmask (r, MIN_EXPR, op1, op2);
     805         1098 :   return true;
     806              : }
     807              : 
     808              : bool
     809         1588 : operator_max::fold_range (prange &r, tree type,
     810              :                           const prange &op1,
     811              :                           const prange &op2,
     812              :                           relation_trio) const
     813              : {
     814              :   // For MIN/MAX expressions with pointers, we only care about
     815              :   // nullness.  If both are non null, then the result is nonnull.
     816              :   // If both are null, then the result is null.  Otherwise they
     817              :   // are varying.
     818         1588 :   if (!range_includes_zero_p (op1)
     819         1588 :       && !range_includes_zero_p (op2))
     820          110 :     r.set_nonzero (type);
     821         1478 :   else if (op1.zero_p () && op2.zero_p ())
     822            0 :     r.set_zero (type);
     823              :   else
     824         1478 :     r.set_varying (type);
     825              : 
     826         1588 :   update_known_bitmask (r, MAX_EXPR, op1, op2);
     827         1588 :   return true;
     828              : }
     829              : 
     830              : bool
     831       596750 : operator_addr_expr::op1_range (prange &r, tree type,
     832              :                                const prange &lhs,
     833              :                                const prange &op2,
     834              :                                relation_trio) const
     835              : {
     836       596750 :   if (empty_range_varying (r, type, lhs, op2))
     837            0 :     return true;
     838              : 
     839              :   // Return a non-null pointer of the LHS type (passed in op2), but only
     840              :   // if we cant overflow, eitherwise a no-zero offset could wrap to zero.
     841              :   // See PR 111009.
     842       596750 :   if (!lhs.undefined_p ()
     843       596750 :       && !range_includes_zero_p (lhs)
     844       590071 :       && TYPE_OVERFLOW_UNDEFINED (type))
     845       590058 :     r.set_nonzero (type);
     846              :   else
     847         6692 :     r.set_varying (type);
     848              :   return true;
     849              : }
     850              : 
     851              : bool
     852          766 : operator_bitwise_and::fold_range (prange &r, tree type,
     853              :                                   const prange &op1,
     854              :                                   const prange &op2 ATTRIBUTE_UNUSED,
     855              :                                   relation_trio) const
     856              : {
     857              :   // For pointer types, we are really only interested in asserting
     858              :   // whether the expression evaluates to non-NULL.
     859          766 :   if (op1.zero_p () || op2.zero_p ())
     860            0 :     r.set_zero (type);
     861              :   else
     862          766 :     r.set_varying (type);
     863              : 
     864          766 :   update_known_bitmask (r, BIT_AND_EXPR, op1, op2);
     865          766 :   return true;
     866              : }
     867              : 
     868              : bool
     869      6701267 : operator_equal::fold_range (irange &r, tree type,
     870              :                             const prange &op1,
     871              :                             const prange &op2,
     872              :                             relation_trio rel) const
     873              : {
     874      6701267 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_EQ))
     875              :     return true;
     876              : 
     877              :   // We can be sure the values are always equal or not if both ranges
     878              :   // consist of a single value, and then compare them.
     879      6679095 :   bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ());
     880      6679095 :   bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ());
     881      6679095 :   if (op1_const && op2_const)
     882              :     {
     883        22849 :       if (wi::eq_p (op1.lower_bound (), op2.upper_bound()))
     884        22688 :         r = range_true (type);
     885              :       else
     886          161 :         r = range_false (type);
     887              :     }
     888              :   else
     889              :     {
     890              :       // If ranges do not intersect, we know the range is not equal,
     891              :       // otherwise we don't know anything for sure.
     892      6656246 :       prange tmp = op1;
     893      6656246 :       tmp.intersect (op2);
     894      6656246 :       if (tmp.undefined_p ())
     895       162641 :         r = range_false (type);
     896              :       // Check if a constant cannot satisfy the bitmask requirements.
     897     11567659 :       else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ()))
     898            0 :          r = range_false (type);
     899      6502085 :       else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ()))
     900            0 :          r = range_false (type);
     901              :       else
     902      6493605 :         r = range_true_and_false (type);
     903      6656246 :     }
     904              : 
     905              :   //update_known_bitmask (r, EQ_EXPR, op1, op2);
     906              :   return true;
     907              : }
     908              : 
     909              : bool
     910      4211538 : operator_equal::op1_range (prange &r, tree type,
     911              :                            const irange &lhs,
     912              :                            const prange &op2,
     913              :                            relation_trio) const
     914              : {
     915      4211538 :   switch (get_bool_state (r, lhs, type))
     916              :     {
     917      1165710 :     case BRS_TRUE:
     918              :       // If it's true, the result is the same as OP2.
     919      1165710 :       r = op2;
     920      1165710 :       break;
     921              : 
     922      3038575 :     case BRS_FALSE:
     923              :       // If the result is false, the only time we know anything is
     924              :       // if OP2 is a constant.
     925      3038575 :       if (!op2.undefined_p ()
     926      9115725 :           && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
     927              :         {
     928      1008614 :           r = op2;
     929      1008614 :           r.invert ();
     930              :         }
     931              :       else
     932      2029961 :         r.set_varying (type);
     933              :       break;
     934              : 
     935              :     default:
     936              :       break;
     937              :     }
     938      4211538 :   return true;
     939              : }
     940              : 
     941              : bool
     942      1409966 : operator_equal::op2_range (prange &r, tree type,
     943              :                            const irange &lhs,
     944              :                            const prange &op1,
     945              :                            relation_trio rel) const
     946              : {
     947      1409966 :   return operator_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
     948              : }
     949              : 
     950              : relation_kind
     951      5294697 : operator_equal::op1_op2_relation (const irange &lhs, const prange &,
     952              :                                   const prange &) const
     953              : {
     954      5294697 :   if (lhs.undefined_p ())
     955              :     return VREL_UNDEFINED;
     956              : 
     957              :   // FALSE = op1 == op2 indicates NE_EXPR.
     958      5294697 :   if (lhs.zero_p ())
     959              :     return VREL_NE;
     960              : 
     961              :   // TRUE = op1 == op2 indicates EQ_EXPR.
     962      2407914 :   if (!range_includes_zero_p (lhs))
     963      2407832 :     return VREL_EQ;
     964              :   return VREL_VARYING;
     965              : }
     966              : 
     967              : bool
     968      7641983 : operator_not_equal::fold_range (irange &r, tree type,
     969              :                                 const prange &op1,
     970              :                                 const prange &op2,
     971              :                                 relation_trio rel) const
     972              : {
     973      7641983 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_NE))
     974              :     return true;
     975              : 
     976              :   // We can be sure the values are always equal or not if both ranges
     977              :   // consist of a single value, and then compare them.
     978      7626197 :   bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ());
     979      7626197 :   bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ());
     980      7626197 :   if (op1_const && op2_const)
     981              :     {
     982        47191 :       if (wi::ne_p (op1.lower_bound (), op2.upper_bound()))
     983          175 :         r = range_true (type);
     984              :       else
     985        47016 :         r = range_false (type);
     986              :     }
     987              :   else
     988              :     {
     989              :       // If ranges do not intersect, we know the range is not equal,
     990              :       // otherwise we don't know anything for sure.
     991      7579006 :       prange tmp = op1;
     992      7579006 :       tmp.intersect (op2);
     993      7579006 :       if (tmp.undefined_p ())
     994       199832 :         r = range_true (type);
     995              :       // Check if a constant cannot satisfy the bitmask requirements.
     996     15978492 :       else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ()))
     997            0 :          r = range_true (type);
     998      7381834 :       else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ()))
     999            0 :          r = range_true (type);
    1000              :       else
    1001      7379174 :         r = range_true_and_false (type);
    1002      7579006 :     }
    1003              : 
    1004              :   //update_known_bitmask (r, NE_EXPR, op1, op2);
    1005              :   return true;
    1006              : }
    1007              : 
    1008              : bool
    1009      5011707 : operator_not_equal::op1_range (prange &r, tree type,
    1010              :                                const irange &lhs,
    1011              :                                const prange &op2,
    1012              :                                relation_trio) const
    1013              : {
    1014      5011707 :   switch (get_bool_state (r, lhs, type))
    1015              :     {
    1016      3912573 :     case BRS_TRUE:
    1017              :       // If the result is true, the only time we know anything is if
    1018              :       // OP2 is a constant.
    1019      3912573 :       if (!op2.undefined_p ()
    1020     11737719 :           && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
    1021              :         {
    1022      1604772 :           r = op2;
    1023      1604772 :           r.invert ();
    1024              :         }
    1025              :       else
    1026      2307801 :         r.set_varying (type);
    1027              :       break;
    1028              : 
    1029      1075884 :     case BRS_FALSE:
    1030              :       // If it's false, the result is the same as OP2.
    1031      1075884 :       r = op2;
    1032      1075884 :       break;
    1033              : 
    1034              :     default:
    1035              :       break;
    1036              :     }
    1037      5011707 :   return true;
    1038              : }
    1039              : 
    1040              : 
    1041              : bool
    1042      1487447 : operator_not_equal::op2_range (prange &r, tree type,
    1043              :                                const irange &lhs,
    1044              :                                const prange &op1,
    1045              :                                relation_trio rel) const
    1046              : {
    1047      1487447 :   return operator_not_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
    1048              : }
    1049              : 
    1050              : relation_kind
    1051      5298877 : operator_not_equal::op1_op2_relation (const irange &lhs, const prange &,
    1052              :                                       const prange &) const
    1053              : {
    1054      5298877 :   if (lhs.undefined_p ())
    1055              :     return VREL_UNDEFINED;
    1056              : 
    1057              :   // FALSE = op1 != op2  indicates EQ_EXPR.
    1058      5298877 :   if (lhs.zero_p ())
    1059              :     return VREL_EQ;
    1060              : 
    1061              :   // TRUE = op1 != op2  indicates NE_EXPR.
    1062      3474565 :   if (!range_includes_zero_p (lhs))
    1063      3471098 :     return VREL_NE;
    1064              :   return VREL_VARYING;
    1065              : }
    1066              : 
    1067              : bool
    1068       361288 : operator_lt::fold_range (irange &r, tree type,
    1069              :                          const prange &op1,
    1070              :                          const prange &op2,
    1071              :                          relation_trio rel) const
    1072              : {
    1073       361288 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_LT))
    1074              :     return true;
    1075              : 
    1076       360528 :   signop sign = TYPE_SIGN (op1.type ());
    1077       360528 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1078              : 
    1079       360528 :   if (wi::lt_p (op1.upper_bound (), op2.lower_bound (), sign))
    1080            0 :     r = range_true (type);
    1081       360528 :   else if (!wi::lt_p (op1.lower_bound (), op2.upper_bound (), sign))
    1082           28 :     r = range_false (type);
    1083              :   // Use nonzero bits to determine if < 0 is false.
    1084       360500 :   else if (op2.zero_p () && !wi::neg_p (op1.get_nonzero_bits (), sign))
    1085            0 :     r = range_false (type);
    1086              :   else
    1087       360500 :     r = range_true_and_false (type);
    1088              : 
    1089              :   //update_known_bitmask (r, LT_EXPR, op1, op2);
    1090              :   return true;
    1091              : }
    1092              : 
    1093              : bool
    1094       273854 : operator_lt::op1_range (prange &r, tree type,
    1095              :                         const irange &lhs,
    1096              :                         const prange &op2,
    1097              :                         relation_trio) const
    1098              : {
    1099       273854 :   if (op2.undefined_p ())
    1100              :     return false;
    1101              : 
    1102       273854 :   switch (get_bool_state (r, lhs, type))
    1103              :     {
    1104       231380 :     case BRS_TRUE:
    1105       231380 :       build_lt (r, type, op2);
    1106       231380 :       break;
    1107              : 
    1108        42474 :     case BRS_FALSE:
    1109        42474 :       build_ge (r, type, op2);
    1110        42474 :       break;
    1111              : 
    1112              :     default:
    1113              :       break;
    1114              :     }
    1115              :   return true;
    1116              : }
    1117              : 
    1118              : bool
    1119       169054 : operator_lt::op2_range (prange &r, tree type,
    1120              :                         const irange &lhs,
    1121              :                         const prange &op1,
    1122              :                         relation_trio) const
    1123              : {
    1124       169054 :   if (op1.undefined_p ())
    1125              :     return false;
    1126              : 
    1127       169054 :   switch (get_bool_state (r, lhs, type))
    1128              :     {
    1129       118903 :     case BRS_TRUE:
    1130       118903 :       build_gt (r, type, op1);
    1131       118903 :       break;
    1132              : 
    1133        50147 :     case BRS_FALSE:
    1134        50147 :       build_le (r, type, op1);
    1135        50147 :       break;
    1136              : 
    1137              :     default:
    1138              :       break;
    1139              :     }
    1140              :   return true;
    1141              : }
    1142              : 
    1143              : relation_kind
    1144       760690 : operator_lt::op1_op2_relation (const irange &lhs, const prange &,
    1145              :                                const prange &) const
    1146              : {
    1147       760690 :   if (lhs.undefined_p ())
    1148              :     return VREL_UNDEFINED;
    1149              : 
    1150              :   // FALSE = op1 < op2 indicates GE_EXPR.
    1151       760690 :   if (lhs.zero_p ())
    1152              :     return VREL_GE;
    1153              : 
    1154              :   // TRUE = op1 < op2 indicates LT_EXPR.
    1155       561944 :   if (!range_includes_zero_p (lhs))
    1156       561940 :     return VREL_LT;
    1157              :   return VREL_VARYING;
    1158              : }
    1159              : 
    1160              : bool
    1161       107569 : operator_le::fold_range (irange &r, tree type,
    1162              :                          const prange &op1,
    1163              :                          const prange &op2,
    1164              :                          relation_trio rel) const
    1165              : {
    1166       107569 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_LE))
    1167              :     return true;
    1168              : 
    1169       107259 :   signop sign = TYPE_SIGN (op1.type ());
    1170       107259 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1171              : 
    1172       107259 :   if (wi::le_p (op1.upper_bound (), op2.lower_bound (), sign))
    1173           17 :     r = range_true (type);
    1174       107242 :   else if (!wi::le_p (op1.lower_bound (), op2.upper_bound (), sign))
    1175            8 :     r = range_false (type);
    1176              :   else
    1177       107234 :     r = range_true_and_false (type);
    1178              : 
    1179              :   //update_known_bitmask (r, LE_EXPR, op1, op2);
    1180              :   return true;
    1181              : }
    1182              : 
    1183              : bool
    1184        75043 : operator_le::op1_range (prange &r, tree type,
    1185              :                         const irange &lhs,
    1186              :                         const prange &op2,
    1187              :                         relation_trio) const
    1188              : {
    1189        75043 :   if (op2.undefined_p ())
    1190              :     return false;
    1191              : 
    1192        75043 :   switch (get_bool_state (r, lhs, type))
    1193              :     {
    1194        52916 :     case BRS_TRUE:
    1195        52916 :       build_le (r, type, op2);
    1196        52916 :       break;
    1197              : 
    1198        22127 :     case BRS_FALSE:
    1199        22127 :       build_gt (r, type, op2);
    1200        22127 :       break;
    1201              : 
    1202              :     default:
    1203              :       break;
    1204              :     }
    1205              :   return true;
    1206              : }
    1207              : 
    1208              : bool
    1209       111601 : operator_le::op2_range (prange &r, tree type,
    1210              :                         const irange &lhs,
    1211              :                         const prange &op1,
    1212              :                         relation_trio) const
    1213              : {
    1214       111601 :   if (op1.undefined_p ())
    1215              :     return false;
    1216              : 
    1217       111601 :   switch (get_bool_state (r, lhs, type))
    1218              :     {
    1219        90809 :     case BRS_TRUE:
    1220        90809 :       build_ge (r, type, op1);
    1221        90809 :       break;
    1222              : 
    1223        20792 :     case BRS_FALSE:
    1224        20792 :       build_lt (r, type, op1);
    1225        20792 :       break;
    1226              : 
    1227              :     default:
    1228              :       break;
    1229              :     }
    1230              :   return true;
    1231              : }
    1232              : 
    1233              : relation_kind
    1234       302579 : operator_le::op1_op2_relation (const irange &lhs, const prange &,
    1235              :                                const prange &) const
    1236              : {
    1237       302579 :   if (lhs.undefined_p ())
    1238              :     return VREL_UNDEFINED;
    1239              : 
    1240              :   // FALSE = op1 <= op2 indicates GT_EXPR.
    1241       302579 :   if (lhs.zero_p ())
    1242              :     return VREL_GT;
    1243              : 
    1244              :   // TRUE = op1 <= op2 indicates LE_EXPR.
    1245       217745 :   if (!range_includes_zero_p (lhs))
    1246       217745 :     return VREL_LE;
    1247              :   return VREL_VARYING;
    1248              : }
    1249              : 
    1250              : bool
    1251       349432 : operator_gt::fold_range (irange &r, tree type,
    1252              :                          const prange &op1, const prange &op2,
    1253              :                          relation_trio rel) const
    1254              : {
    1255       349432 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_GT))
    1256              :     return true;
    1257              : 
    1258       348495 :   signop sign = TYPE_SIGN (op1.type ());
    1259       348495 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1260              : 
    1261       348495 :   if (wi::gt_p (op1.lower_bound (), op2.upper_bound (), sign))
    1262            2 :     r = range_true (type);
    1263       348493 :   else if (!wi::gt_p (op1.upper_bound (), op2.lower_bound (), sign))
    1264            7 :     r = range_false (type);
    1265              :   else
    1266       348486 :     r = range_true_and_false (type);
    1267              : 
    1268              :   //update_known_bitmask (r, GT_EXPR, op1, op2);
    1269              :   return true;
    1270              : }
    1271              : 
    1272              : bool
    1273       243365 : operator_gt::op1_range (prange &r, tree type,
    1274              :                         const irange &lhs, const prange &op2,
    1275              :                         relation_trio) const
    1276              : {
    1277       243365 :   if (op2.undefined_p ())
    1278              :     return false;
    1279              : 
    1280       243365 :   switch (get_bool_state (r, lhs, type))
    1281              :     {
    1282       157777 :     case BRS_TRUE:
    1283       157777 :       build_gt (r, type, op2);
    1284       157777 :       break;
    1285              : 
    1286        85588 :     case BRS_FALSE:
    1287        85588 :       build_le (r, type, op2);
    1288        85588 :       break;
    1289              : 
    1290              :     default:
    1291              :       break;
    1292              :     }
    1293              :   return true;
    1294              : }
    1295              : 
    1296              : bool
    1297       220529 : operator_gt::op2_range (prange &r, tree type,
    1298              :                         const irange &lhs,
    1299              :                         const prange &op1,
    1300              :                         relation_trio) const
    1301              : {
    1302       220529 :   if (op1.undefined_p ())
    1303              :     return false;
    1304              : 
    1305       220529 :   switch (get_bool_state (r, lhs, type))
    1306              :     {
    1307       172863 :     case BRS_TRUE:
    1308       172863 :       build_lt (r, type, op1);
    1309       172863 :       break;
    1310              : 
    1311        47666 :     case BRS_FALSE:
    1312        47666 :       build_ge (r, type, op1);
    1313        47666 :       break;
    1314              : 
    1315              :     default:
    1316              :       break;
    1317              :     }
    1318              :   return true;
    1319              : }
    1320              : 
    1321              : relation_kind
    1322       762499 : operator_gt::op1_op2_relation (const irange &lhs, const prange &,
    1323              :                                const prange &) const
    1324              : {
    1325       762499 :   if (lhs.undefined_p ())
    1326              :     return VREL_UNDEFINED;
    1327              : 
    1328              :   // FALSE = op1 > op2 indicates LE_EXPR.
    1329       762499 :   if (lhs.zero_p ())
    1330              :     return VREL_LE;
    1331              : 
    1332              :   // TRUE = op1 > op2 indicates GT_EXPR.
    1333       527104 :   if (!range_includes_zero_p (lhs))
    1334       527104 :     return VREL_GT;
    1335              :   return VREL_VARYING;
    1336              : }
    1337              : 
    1338              : bool
    1339       181025 : operator_ge::fold_range (irange &r, tree type,
    1340              :                          const prange &op1,
    1341              :                          const prange &op2,
    1342              :                          relation_trio rel) const
    1343              : {
    1344       181025 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_GE))
    1345              :     return true;
    1346              : 
    1347       180779 :   signop sign = TYPE_SIGN (op1.type ());
    1348       180779 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1349              : 
    1350       180779 :   if (wi::ge_p (op1.lower_bound (), op2.upper_bound (), sign))
    1351           67 :     r = range_true (type);
    1352       180712 :   else if (!wi::ge_p (op1.upper_bound (), op2.lower_bound (), sign))
    1353            0 :     r = range_false (type);
    1354              :   else
    1355       180712 :     r = range_true_and_false (type);
    1356              : 
    1357              :   //update_known_bitmask (r, GE_EXPR, op1, op2);
    1358              :   return true;
    1359              : }
    1360              : 
    1361              : bool
    1362       176794 : operator_ge::op1_range (prange &r, tree type,
    1363              :                         const irange &lhs,
    1364              :                         const prange &op2,
    1365              :                         relation_trio) const
    1366              : {
    1367       176794 :   if (op2.undefined_p ())
    1368              :     return false;
    1369              : 
    1370       176794 :   switch (get_bool_state (r, lhs, type))
    1371              :     {
    1372       153855 :     case BRS_TRUE:
    1373       153855 :       build_ge (r, type, op2);
    1374       153855 :       break;
    1375              : 
    1376        22939 :     case BRS_FALSE:
    1377        22939 :       build_lt (r, type, op2);
    1378        22939 :       break;
    1379              : 
    1380              :     default:
    1381              :       break;
    1382              :     }
    1383              :   return true;
    1384              : }
    1385              : 
    1386              : bool
    1387        75884 : operator_ge::op2_range (prange &r, tree type,
    1388              :                         const irange &lhs,
    1389              :                         const prange &op1,
    1390              :                         relation_trio) const
    1391              : {
    1392        75884 :   if (op1.undefined_p ())
    1393              :     return false;
    1394              : 
    1395        75884 :   switch (get_bool_state (r, lhs, type))
    1396              :     {
    1397        52773 :     case BRS_TRUE:
    1398        52773 :       build_le (r, type, op1);
    1399        52773 :       break;
    1400              : 
    1401        23111 :     case BRS_FALSE:
    1402        23111 :       build_gt (r, type, op1);
    1403        23111 :       break;
    1404              : 
    1405              :     default:
    1406              :       break;
    1407              :     }
    1408              :   return true;
    1409              : }
    1410              : 
    1411              : relation_kind
    1412       444341 : operator_ge::op1_op2_relation (const irange &lhs, const prange &,
    1413              :                                const prange &) const
    1414              : {
    1415       444341 :   if (lhs.undefined_p ())
    1416              :     return VREL_UNDEFINED;
    1417              : 
    1418              :   // FALSE = op1 >= op2 indicates LT_EXPR.
    1419       444341 :   if (lhs.zero_p ())
    1420              :     return VREL_LT;
    1421              : 
    1422              :   // TRUE = op1 >= op2 indicates GE_EXPR.
    1423       332795 :   if (!range_includes_zero_p (lhs))
    1424       332795 :     return VREL_GE;
    1425              :   return VREL_VARYING;
    1426              : }
    1427              : 
    1428              : // Initialize any pointer operators to the primary table
    1429              : 
    1430              : void
    1431       286916 : range_op_table::initialize_pointer_ops ()
    1432              : {
    1433       286916 :   set (POINTER_PLUS_EXPR, op_pointer_plus);
    1434       286916 :   set (POINTER_DIFF_EXPR, op_pointer_diff);
    1435       286916 : }
        

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.