LCOV - code coverage report
Current view: top level - gcc - range-op-ptr.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.2 % 500 426
Test Date: 2026-07-11 15:47:05 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       845573 : range_operator::op1_range (prange &, tree,
     143              :                            const irange &lhs ATTRIBUTE_UNUSED,
     144              :                            const prange &op2 ATTRIBUTE_UNUSED,
     145              :                            relation_trio) const
     146              : {
     147       845573 :   return false;
     148              : }
     149              : 
     150              : bool
     151       411215 : range_operator::op1_range (prange &, tree,
     152              :                            const prange &lhs ATTRIBUTE_UNUSED,
     153              :                            const irange &op2 ATTRIBUTE_UNUSED,
     154              :                            relation_trio) const
     155              : {
     156       411215 :   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      1225007 : range_operator::op2_range (prange &, tree,
     170              :                            const irange &lhs ATTRIBUTE_UNUSED,
     171              :                            const prange &op1 ATTRIBUTE_UNUSED,
     172              :                            relation_trio) const
     173              : {
     174      1225007 :   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      1994539 : 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      1994539 :   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      4079079 : 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      4079079 :   return VREL_VARYING;
     210              : }
     211              : 
     212              : relation_kind
     213        80427 : 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        80427 :   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       686728 : max_limit (const_tree type)
     241              : {
     242       686728 :   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       722051 : min_limit (const_tree type)
     249              : {
     250       722051 :   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       467344 : build_lt (prange &r, tree type, const prange &val)
     257              : {
     258       467344 :   wi::overflow_type ov;
     259       467344 :   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       467344 :   if (ov)
     263            0 :     r.set_undefined ();
     264              :   else
     265       467344 :     r.set (type, min_limit (type), lim);
     266       467344 : }
     267              : 
     268              : // Build a range that is <= VAL and store it in R.
     269              : 
     270              : static void
     271       254707 : build_le (prange &r, tree type, const prange &val)
     272              : {
     273       254707 :   r.set (type, min_limit (type), val.upper_bound ());
     274       254707 : }
     275              : 
     276              : // Build a range that is > VAL and store it in R.
     277              : 
     278              : static void
     279       330597 : build_gt (prange &r, tree type, const prange &val)
     280              : {
     281       330597 :   wi::overflow_type ov;
     282       330597 :   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       330597 :   if (ov)
     286            0 :     r.set_undefined ();
     287              :   else
     288       330597 :     r.set (type, lim, max_limit (type));
     289              : 
     290       330597 : }
     291              : 
     292              : // Build a range that is >= VAL and store it in R.
     293              : 
     294              : static void
     295       356131 : build_ge (prange &r, tree type, const prange &val)
     296              : {
     297       356131 :   r.set (type, val.lower_bound (), max_limit (type));
     298       356131 : }
     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      9011807 : pointer_plus_operator::fold_range (prange &r, tree type,
     326              :                                    const prange &op1,
     327              :                                    const irange &op2,
     328              :                                    relation_trio) const
     329              : {
     330      9011807 :   if (empty_range_varying (r, type, op1, op2))
     331         5551 :     return true;
     332              : 
     333      9006256 :   const wide_int lh_lb = op1.lower_bound ();
     334      9006256 :   const wide_int lh_ub = op1.upper_bound ();
     335      9006256 :   const wide_int rh_lb = op2.lower_bound ();
     336      9006256 :   const wide_int rh_ub = op2.upper_bound ();
     337              : 
     338              :   // Check for [0,0] + const, and simply return the const.
     339      9013895 :   if (lh_lb == 0 && lh_ub == 0 && rh_lb == rh_ub)
     340              :     {
     341          513 :       r.set (type, rh_lb, rh_lb);
     342          513 :       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      9005743 :   if ((!wi_includes_zero_p (type, lh_lb, lh_ub)
     362      5429435 :        || !wi_includes_zero_p (type, rh_lb, rh_ub))
     363      5836386 :       && !TYPE_OVERFLOW_WRAPS (type)
     364     14841614 :       && (flag_delete_null_pointer_checks
     365         1035 :           || !wi::sign_mask (rh_ub)))
     366      5835457 :     r.set_nonzero (type);
     367      3176637 :   else if (lh_lb == lh_ub && lh_lb == 0
     368      3176637 :            && rh_lb == rh_ub && rh_lb == 0)
     369            0 :     r.set_zero (type);
     370              :   else
     371      3170286 :    r.set_varying (type);
     372              : 
     373              :   // If op1 refers to an object, op1 + 0 will also refer to the object.
     374      9005743 :   if (rh_lb == rh_ub && rh_lb == 0)
     375        18417 :     r.set_pt (op1);
     376              : 
     377      9005743 :   update_known_bitmask (r, POINTER_PLUS_EXPR, op1, op2);
     378      9005743 :   return true;
     379      9006256 : }
     380              : 
     381              : bool
     382       229158 : pointer_plus_operator::op2_range (irange &r, tree type,
     383              :                                   const prange &lhs,
     384              :                                   const prange &op1,
     385              :                                   relation_trio trio) const
     386              : {
     387       229158 :   relation_kind rel = trio.lhs_op1 ();
     388       229158 :   r.set_varying (type);
     389              : 
     390              :   // If the LHS and OP1 are equal, the op2 must be zero.
     391       229158 :   if (rel == VREL_EQ || lhs.pt_invariant_p (op1))
     392        11436 :     r.set_zero (type);
     393              :   // If the LHS and OP1 are not equal, the offset must be non-zero.
     394              :   // AWM: Check if aliasing may mean we can't do the not_equal check.
     395       217722 :   else if (rel == VREL_NE || lhs.pt_inverted_p (op1))
     396        17049 :     r.set_nonzero (type);
     397              :   else
     398              :     return false;
     399              :   return true;
     400              : }
     401              : 
     402              : // Return the relation between the LHS and OP1 based on the value of the
     403              : // operand being added.  Pointer_plus is define to have a size_type for
     404              : // operand 2 which can be interpreted as negative, so always used SIGNED.
     405              : // Any overflow is considered UB and thus ignored.
     406              : 
     407              : relation_kind
     408      7724524 : pointer_plus_operator::lhs_op1_relation (const prange &lhs,
     409              :                                          const prange &op1,
     410              :                                          const irange &op2,
     411              :                                          relation_kind) const
     412              : {
     413      7724524 :   if (lhs.undefined_p () || op1.undefined_p () || op2.undefined_p ())
     414              :     return VREL_VARYING;
     415              : 
     416      7719360 :   unsigned prec = TYPE_PRECISION (op2.type ());
     417              : 
     418              :   // LHS = OP1 + 0  indicates LHS == OP1.
     419      7719360 :   if (op2.zero_p ())
     420              :     return VREL_EQ;
     421              : 
     422      7703239 :   tree val;
     423              :   // Only deal with singletons for now.
     424      7703239 :   if (TYPE_OVERFLOW_UNDEFINED (lhs.type ()) && op2.singleton_p (&val))
     425              :     {
     426              :       // Always interpret VALUE as a signed value.  Positive will increase
     427              :       // the pointer value, and negative will decrease the poiinter value.
     428              :       // It cannot be zero or the earlier zero_p () condition will catch it.
     429      3661944 :       wide_int value = wi::to_wide (val);
     430              : 
     431              :       // Positive op2 means lhs > op1.
     432      3661944 :       if (wi::gt_p (value, wi::zero (prec), SIGNED))
     433              :         return VREL_GT;
     434              : 
     435              :       // Negative op2 means lhs < op1.
     436       410947 :       if (wi::lt_p (value, wi::zero (prec), SIGNED))
     437              :         return VREL_LT;
     438      3661944 :     }
     439              : 
     440              :   // If op2 does not contain 0, then LHS and OP1 can never be equal.
     441      4041295 :   if (!range_includes_zero_p (op2))
     442              :     return VREL_NE;
     443              : 
     444              :   return VREL_VARYING;
     445              : }
     446              : 
     447              : bool
     448            0 : operator_bitwise_or::fold_range (prange &r, tree type,
     449              :                                  const prange &op1,
     450              :                                  const prange &op2,
     451              :                                  relation_trio) const
     452              : {
     453              :   // For pointer types, we are really only interested in asserting
     454              :   // whether the expression evaluates to non-NULL.
     455            0 :   if (!range_includes_zero_p (op1) || !range_includes_zero_p (op2))
     456            0 :     r.set_nonzero (type);
     457            0 :   else if (op1.zero_p () && op2.zero_p ())
     458            0 :     r.set_zero (type);
     459              :   else
     460            0 :     r.set_varying (type);
     461              : 
     462            0 :   update_known_bitmask (r, BIT_IOR_EXPR, op1, op2);
     463            0 :   return true;
     464              : }
     465              : 
     466              : 
     467              : class operator_pointer_diff : public range_operator
     468              : {
     469              :   using range_operator::fold_range;
     470              :   using range_operator::update_bitmask;
     471              :   using range_operator::op1_op2_relation_effect;
     472              :   virtual bool fold_range (irange &r, tree type,
     473              :                            const prange &op1,
     474              :                            const prange &op2,
     475              :                            relation_trio trio) const final override;
     476              :   virtual bool op1_op2_relation_effect (irange &lhs_range,
     477              :                                         tree type,
     478              :                                         const prange &op1_range,
     479              :                                         const prange &op2_range,
     480              :                                         relation_kind rel) const final override;
     481      2735999 :   void update_bitmask (irange &r,
     482              :                        const prange &lh, const prange &rh) const final override
     483            0 :   { update_known_bitmask (r, POINTER_DIFF_EXPR, lh, rh); }
     484              : };
     485              : static const operator_pointer_diff op_pointer_diff;
     486              : 
     487              : bool
     488      2735999 : operator_pointer_diff::fold_range (irange &r, tree type,
     489              :                                    const prange &op1,
     490              :                                    const prange &op2,
     491              :                                    relation_trio trio) const
     492              : {
     493      2735999 :   gcc_checking_assert (r.supports_type_p (type));
     494              : 
     495      2735999 :   r.set_varying (type);
     496      2735999 :   relation_kind rel = trio.op1_op2 ();
     497      2735999 :   op1_op2_relation_effect (r, type, op1, op2, rel);
     498              :   // if op1 and op2 point to the same object, the diff is 0.
     499      2735999 :   if (op1.pt_invariant_p (op2))
     500          119 :     r.set_zero (type);
     501      2735999 :   update_bitmask (r, op1, op2);
     502      2735999 :   return true;
     503              : }
     504              : 
     505              : bool
     506      2735999 : operator_pointer_diff::op1_op2_relation_effect (irange &lhs_range, tree type,
     507              :                                                 const prange &op1_range,
     508              :                                                 const prange &op2_range,
     509              :                                                 relation_kind rel) const
     510              : {
     511      2735999 :   int_range<2> op1, op2, tmp;
     512      2735999 :   range_op_handler cast (CONVERT_EXPR);
     513              : 
     514      2735999 :   if (!cast.fold_range (op1, type, op1_range, tmp)
     515      2735999 :       || !cast.fold_range (op2, type, op2_range, tmp))
     516            0 :     return false;
     517              : 
     518      2735999 :   return minus_op1_op2_relation_effect (lhs_range, type, op1, op2, rel);
     519      2735999 : }
     520              : 
     521              : bool
     522      1386266 : operator_identity::fold_range (prange &r, tree type ATTRIBUTE_UNUSED,
     523              :                                const prange &lh ATTRIBUTE_UNUSED,
     524              :                                const prange &rh ATTRIBUTE_UNUSED,
     525              :                                relation_trio) const
     526              : {
     527      1386266 :   r = lh;
     528      1386266 :   return true;
     529              : }
     530              : 
     531              : relation_kind
     532      1224431 : operator_identity::lhs_op1_relation (const prange &lhs,
     533              :                                      const prange &op1 ATTRIBUTE_UNUSED,
     534              :                                      const prange &op2 ATTRIBUTE_UNUSED,
     535              :                                      relation_kind) const
     536              : {
     537      1224431 :   if (lhs.undefined_p ())
     538          366 :     return VREL_VARYING;
     539              :   // Simply a copy, so they are equivalent.
     540              :   return VREL_EQ;
     541              : }
     542              : 
     543              : bool
     544       199128 : operator_identity::op1_range (prange &r, tree type ATTRIBUTE_UNUSED,
     545              :                               const prange &lhs,
     546              :                               const prange &op2 ATTRIBUTE_UNUSED,
     547              :                               relation_trio) const
     548              : {
     549       199128 :   r = lhs;
     550       199128 :   return true;
     551              : }
     552              : 
     553              : bool
     554        18785 : operator_cst::fold_range (prange &r, tree type ATTRIBUTE_UNUSED,
     555              :                           const prange &lh,
     556              :                           const prange & ATTRIBUTE_UNUSED,
     557              :                           relation_trio) const
     558              : {
     559        18785 :   r = lh;
     560        18785 :   return true;
     561              : }
     562              : 
     563              : // Cast between pointers.
     564              : 
     565              : bool
     566     17433687 : operator_cast::fold_range (prange &r, tree type,
     567              :                            const prange &inner,
     568              :                            const prange &outer,
     569              :                            relation_trio) const
     570              : {
     571     17433687 :   if (empty_range_varying (r, type, inner, outer))
     572          540 :     return true;
     573              : 
     574     17433147 :   r.set (type, inner.lower_bound (), inner.upper_bound ());
     575              : 
     576              :   // The resulting pointer still points to the same object.
     577     17433147 :   r.set_pt (inner);
     578              : 
     579     17433147 :   r.update_bitmask (inner.get_bitmask ());
     580     17433147 :   return true;
     581              : }
     582              : 
     583              : // Cast a pointer to an integer.
     584              : 
     585              : bool
     586     11129525 : operator_cast::fold_range (irange &r, tree type,
     587              :                            const prange &inner,
     588              :                            const irange &outer,
     589              :                            relation_trio) const
     590              : {
     591     11129525 :   if (empty_range_varying (r, type, inner, outer))
     592      5473268 :     return true;
     593              : 
     594              :   // Represent INNER as an integer of the same size, and then cast it
     595              :   // to the resulting integer type.
     596      5656257 :   tree pointer_uint_type = make_unsigned_type (TYPE_PRECISION (inner.type ()));
     597      5656257 :   r.set (pointer_uint_type, inner.lower_bound (), inner.upper_bound ());
     598      5656257 :   r.update_bitmask (inner.get_bitmask ());
     599      5656257 :   range_cast (r, type);
     600      5656257 :   return true;
     601              : }
     602              : 
     603              : // Cast an integer to a pointer.
     604              : 
     605              : bool
     606      1995402 : operator_cast::fold_range (prange &r, tree type,
     607              :                            const irange &inner,
     608              :                            const prange &outer,
     609              :                            relation_trio) const
     610              : {
     611      1995402 :   if (empty_range_varying (r, type, inner, outer))
     612         1766 :     return true;
     613              : 
     614              :   // Cast INNER to an integer of the same size as the pointer we want,
     615              :   // and then copy the bounds to the resulting pointer range.
     616      1993636 :   int_range<2> tmp = inner;
     617      1993636 :   tree pointer_uint_type = make_unsigned_type (TYPE_PRECISION (type));
     618      1993636 :   range_cast (tmp, pointer_uint_type);
     619              :   // Casts may cause ranges to become UNDEFINED based on bitmasks.
     620      1993636 :   if (tmp.undefined_p ())
     621            0 :     r.set_varying (type);
     622              :   else
     623              :     {
     624      1993636 :       r.set (type, tmp.lower_bound (), tmp.upper_bound ());
     625      1993636 :       r.update_bitmask (tmp.get_bitmask ());
     626              :     }
     627      1993636 :   return true;
     628      1993636 : }
     629              : 
     630              : bool
     631           69 : operator_cast::op1_range (prange &r, tree type,
     632              :                           const prange &lhs,
     633              :                           const prange &op2,
     634              :                           relation_trio trio) const
     635              : {
     636           69 :   if (lhs.undefined_p ())
     637              :     return false;
     638           69 :   gcc_checking_assert (types_compatible_p (op2.type(), type));
     639              : 
     640              :   // Conversion from other pointers or a constant (including 0/NULL)
     641              :   // are straightforward.
     642           69 :   if (POINTER_TYPE_P (lhs.type ())
     643           69 :       || (lhs.singleton_p ()
     644            0 :           && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
     645           69 :     fold_range (r, type, lhs, op2, trio);
     646              :   else
     647              :     {
     648              :       // If the LHS is not a pointer nor a singleton, then it is
     649              :       // either VARYING or non-zero.
     650            0 :       if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
     651            0 :         r.set_nonzero (type);
     652              :       else
     653            0 :         r.set_varying (type);
     654              :     }
     655           69 :   r.intersect (op2);
     656           69 :   return true;
     657              : }
     658              : 
     659              : bool
     660       238119 : operator_cast::op1_range (irange &r, tree type,
     661              :                           const prange &lhs,
     662              :                           const irange &op2,
     663              :                           relation_trio trio) const
     664              : {
     665       238119 :   if (lhs.undefined_p ())
     666              :     return false;
     667       238119 :   gcc_checking_assert (types_compatible_p (op2.type(), type));
     668              : 
     669              :   // Conversion from other pointers or a constant (including 0/NULL)
     670              :   // are straightforward.
     671       238119 :   if (POINTER_TYPE_P (lhs.type ())
     672       238119 :       || (lhs.singleton_p ()
     673            0 :           && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
     674       238119 :     fold_range (r, type, lhs, op2, trio);
     675              :   else
     676              :     {
     677              :       // If the LHS is not a pointer nor a singleton, then it is
     678              :       // either VARYING or non-zero.
     679            0 :       if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
     680            0 :         r.set_nonzero (type);
     681              :       else
     682            0 :         r.set_varying (type);
     683              :     }
     684       238119 :   r.intersect (op2);
     685       238119 :   return true;
     686              : }
     687              : 
     688              : bool
     689       529469 : operator_cast::op1_range (prange &r, tree type,
     690              :                           const irange &lhs,
     691              :                           const prange &op2,
     692              :                           relation_trio trio) const
     693              : {
     694       529469 :   if (lhs.undefined_p ())
     695              :     return false;
     696       529469 :   gcc_checking_assert (types_compatible_p (op2.type(), type));
     697              : 
     698              :   // Conversion from other pointers or a constant (including 0/NULL)
     699              :   // are straightforward.
     700      1058938 :   if (POINTER_TYPE_P (lhs.type ())
     701      1058938 :       || (lhs.singleton_p ()
     702         1316 :           && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type)))
     703         1310 :     fold_range (r, type, lhs, op2, trio);
     704              :   else
     705              :     {
     706              :       // If the LHS is not a pointer nor a singleton, then it is
     707              :       // either VARYING or non-zero.
     708       528159 :       if (!lhs.undefined_p () && !range_includes_zero_p (lhs))
     709       236958 :         r.set_nonzero (type);
     710              :       else
     711       291201 :         r.set_varying (type);
     712              :     }
     713       529469 :   r.intersect (op2);
     714       529469 :   return true;
     715              : }
     716              : 
     717              : relation_kind
     718       137430 : operator_cast::lhs_op1_relation (const prange &lhs,
     719              :                                  const prange &op1,
     720              :                                  const prange &op2 ATTRIBUTE_UNUSED,
     721              :                                  relation_kind) const
     722              : {
     723       137430 :   if (lhs.undefined_p () || op1.undefined_p ())
     724              :     return VREL_VARYING;
     725       137430 :   unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
     726       137430 :   unsigned op1_prec = TYPE_PRECISION (op1.type ());
     727              :   // If the result gets sign extended into a larger type check first if this
     728              :   // qualifies as a partial equivalence.
     729       137430 :   if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
     730              :     {
     731              :       // If the result is sign extended, and the LHS is larger than op1,
     732              :       // check if op1's range can be negative as the sign extension will
     733              :       // cause the upper bits to be 1 instead of 0, invalidating the PE.
     734            0 :       int_range<3> negs = range_negatives (op1.type ());
     735            0 :       negs.intersect (op1);
     736            0 :       if (!negs.undefined_p ())
     737            0 :         return VREL_VARYING;
     738            0 :     }
     739              : 
     740              :   // If the pointer precisions are the same, check for equality and
     741              :   // inequality in the points to fields.
     742       137430 :   if (lhs_prec == op1_prec)
     743              :     {
     744       137430 :       if (lhs.pt_invariant_p (op1))
     745              :         return VREL_EQ;
     746       137309 :       if (lhs.pt_inverted_p (op1))
     747              :         return VREL_NE;
     748              :     }
     749       137309 :   unsigned prec = MIN (lhs_prec, op1_prec);
     750       137309 :   return bits_to_pe (prec);
     751              : }
     752              : 
     753              : relation_kind
     754      1482292 : operator_cast::lhs_op1_relation (const prange &lhs,
     755              :                                  const irange &op1,
     756              :                                  const irange &op2 ATTRIBUTE_UNUSED,
     757              :                                  relation_kind) const
     758              : {
     759      1482292 :   if (lhs.undefined_p () || op1.undefined_p ())
     760              :     return VREL_VARYING;
     761      1480540 :   unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
     762      1480540 :   unsigned op1_prec = TYPE_PRECISION (op1.type ());
     763              :   // If the result gets sign extended into a larger type check first if this
     764              :   // qualifies as a partial equivalence.
     765      1480540 :   if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
     766              :     {
     767              :       // If the result is sign extended, and the LHS is larger than op1,
     768              :       // check if op1's range can be negative as the sign extension will
     769              :       // cause the upper bits to be 1 instead of 0, invalidating the PE.
     770          284 :       int_range<3> negs = range_negatives (op1.type ());
     771          284 :       negs.intersect (op1);
     772          284 :       if (!negs.undefined_p ())
     773          276 :         return VREL_VARYING;
     774          284 :     }
     775              : 
     776      1480264 :   unsigned prec = MIN (lhs_prec, op1_prec);
     777      1480264 :   return bits_to_pe (prec);
     778              : }
     779              : 
     780              : relation_kind
     781      2195201 : operator_cast::lhs_op1_relation (const irange &lhs,
     782              :                                  const prange &op1,
     783              :                                  const prange &op2 ATTRIBUTE_UNUSED,
     784              :                                  relation_kind) const
     785              : {
     786      2195201 :   if (lhs.undefined_p () || op1.undefined_p ())
     787              :     return VREL_VARYING;
     788      2194388 :   unsigned lhs_prec = TYPE_PRECISION (lhs.type ());
     789      2194388 :   unsigned op1_prec = TYPE_PRECISION (op1.type ());
     790              :   // If the result gets sign extended into a larger type check first if this
     791              :   // qualifies as a partial equivalence.
     792      2194388 :   if (TYPE_SIGN (op1.type ()) == SIGNED && lhs_prec > op1_prec)
     793              :     {
     794              :       // If the result is sign extended, and the LHS is larger than op1,
     795              :       // check if op1's range can be negative as the sign extension will
     796              :       // cause the upper bits to be 1 instead of 0, invalidating the PE.
     797            0 :       int_range<3> negs = range_negatives (op1.type ());
     798            0 :       negs.intersect (op1);
     799            0 :       if (!negs.undefined_p ())
     800            0 :         return VREL_VARYING;
     801            0 :     }
     802              : 
     803      2194388 :   unsigned prec = MIN (lhs_prec, op1_prec);
     804      2194388 :   return bits_to_pe (prec);
     805              : }
     806              : 
     807              : bool
     808         1291 : operator_min::fold_range (prange &r, tree type,
     809              :                           const prange &op1,
     810              :                           const prange &op2,
     811              :                           relation_trio) const
     812              : {
     813              :   // For MIN/MAX expressions with pointers, we only care about
     814              :   // nullness.  If both are non null, then the result is nonnull.
     815              :   // If both are null, then the result is null.  Otherwise they
     816              :   // are varying.
     817         1291 :   if (!range_includes_zero_p (op1)
     818         1291 :       && !range_includes_zero_p (op2))
     819          144 :     r.set_nonzero (type);
     820         1147 :   else if (op1.zero_p () && op2.zero_p ())
     821            0 :     r.set_zero (type);
     822              :   else
     823         1147 :     r.set_varying (type);
     824              : 
     825         1291 :   update_known_bitmask (r, MIN_EXPR, op1, op2);
     826         1291 :   return true;
     827              : }
     828              : 
     829              : bool
     830         1306 : operator_max::fold_range (prange &r, tree type,
     831              :                           const prange &op1,
     832              :                           const prange &op2,
     833              :                           relation_trio) const
     834              : {
     835              :   // For MIN/MAX expressions with pointers, we only care about
     836              :   // nullness.  If both are non null, then the result is nonnull.
     837              :   // If both are null, then the result is null.  Otherwise they
     838              :   // are varying.
     839         1306 :   if (!range_includes_zero_p (op1)
     840         1306 :       && !range_includes_zero_p (op2))
     841          113 :     r.set_nonzero (type);
     842         1193 :   else if (op1.zero_p () && op2.zero_p ())
     843            0 :     r.set_zero (type);
     844              :   else
     845         1193 :     r.set_varying (type);
     846              : 
     847         1306 :   update_known_bitmask (r, MAX_EXPR, op1, op2);
     848         1306 :   return true;
     849              : }
     850              : 
     851              : bool
     852       658760 : operator_addr_expr::op1_range (prange &r, tree type,
     853              :                                const prange &lhs,
     854              :                                const prange &op2,
     855              :                                relation_trio) const
     856              : {
     857       658760 :   if (empty_range_varying (r, type, lhs, op2))
     858            0 :     return true;
     859              : 
     860              :   // Return a non-null pointer of the LHS type (passed in op2), but only
     861              :   // if we cant overflow, eitherwise a no-zero offset could wrap to zero.
     862              :   // See PR 111009.
     863       658760 :   if (!lhs.undefined_p ()
     864       658760 :       && !range_includes_zero_p (lhs)
     865       651986 :       && TYPE_OVERFLOW_UNDEFINED (type))
     866       651973 :     r.set_nonzero (type);
     867              :   else
     868         6787 :     r.set_varying (type);
     869              :   return true;
     870              : }
     871              : 
     872              : bool
     873          787 : operator_bitwise_and::fold_range (prange &r, tree type,
     874              :                                   const prange &op1,
     875              :                                   const prange &op2 ATTRIBUTE_UNUSED,
     876              :                                   relation_trio) const
     877              : {
     878              :   // For pointer types, we are really only interested in asserting
     879              :   // whether the expression evaluates to non-NULL.
     880          787 :   if (op1.zero_p () || op2.zero_p ())
     881            0 :     r.set_zero (type);
     882              :   else
     883          787 :     r.set_varying (type);
     884              : 
     885          787 :   update_known_bitmask (r, BIT_AND_EXPR, op1, op2);
     886          787 :   return true;
     887              : }
     888              : 
     889              : bool
     890      6973323 : operator_equal::fold_range (irange &r, tree type,
     891              :                             const prange &op1,
     892              :                             const prange &op2,
     893              :                             relation_trio rel) const
     894              : {
     895      6973323 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_EQ))
     896              :     return true;
     897              : 
     898              :   // We can be sure the values are always equal or not if both ranges
     899              :   // consist of a single value, and then compare them.
     900      6952749 :   bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ());
     901      6952749 :   bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ());
     902              :   // Check for points to equality and inequality first.
     903      6952749 :   if (op1.pt_invariant_p (op2))
     904        13377 :     r = range_true (type);
     905      6939372 :   else if (op1.pt_inverted_p (op2))
     906            0 :     r = range_false (type);
     907      6939372 :   else if (op1_const && op2_const)
     908              :     {
     909        23290 :       if (wi::eq_p (op1.lower_bound (), op2.upper_bound()))
     910        23129 :         r = range_true (type);
     911              :       else
     912          161 :         r = range_false (type);
     913              :     }
     914              :   else
     915              :     {
     916              :       // If ranges do not intersect, we know the range is not equal,
     917              :       // otherwise we don't know anything for sure.
     918      6916082 :       prange tmp = op1;
     919      6916082 :       tmp.intersect (op2);
     920      6916082 :       if (tmp.undefined_p ())
     921       164075 :         r = range_false (type);
     922              :       // Check if a constant cannot satisfy the bitmask requirements.
     923     11948811 :       else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ()))
     924            0 :          r = range_false (type);
     925      6761131 :       else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ()))
     926            0 :          r = range_false (type);
     927              :       else
     928      6752007 :         r = range_true_and_false (type);
     929      6916082 :     }
     930              : 
     931              :   //update_known_bitmask (r, EQ_EXPR, op1, op2);
     932              :   return true;
     933              : }
     934              : 
     935              : bool
     936      4425089 : operator_equal::op1_range (prange &r, tree type,
     937              :                            const irange &lhs,
     938              :                            const prange &op2,
     939              :                            relation_trio) const
     940              : {
     941      4425089 :   switch (get_bool_state (r, lhs, type))
     942              :     {
     943      1223719 :     case BRS_TRUE:
     944              :       // If it's true, the result is the same as OP2.
     945      1223719 :       r = op2;
     946      1223719 :       break;
     947              : 
     948      3193839 :     case BRS_FALSE:
     949              :       // If the result is false, the only time we know anything is
     950              :       // if OP2 is a constant.
     951      3193839 :       if (!op2.undefined_p ()
     952      9581517 :           && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
     953              :         {
     954      1043738 :           r = op2;
     955      1043738 :           r.invert ();
     956              :         }
     957              :       else
     958      2150101 :         r.set_varying (type);
     959              :       break;
     960              : 
     961              :     default:
     962              :       break;
     963              :     }
     964      4425089 :   return true;
     965              : }
     966              : 
     967              : bool
     968      1511981 : operator_equal::op2_range (prange &r, tree type,
     969              :                            const irange &lhs,
     970              :                            const prange &op1,
     971              :                            relation_trio rel) const
     972              : {
     973      1511981 :   return operator_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
     974              : }
     975              : 
     976              : relation_kind
     977      5618910 : operator_equal::op1_op2_relation (const irange &lhs, const prange &,
     978              :                                   const prange &) const
     979              : {
     980      5618910 :   if (lhs.undefined_p ())
     981              :     return VREL_UNDEFINED;
     982              : 
     983              :   // FALSE = op1 == op2 indicates NE_EXPR.
     984      5618910 :   if (lhs.zero_p ())
     985              :     return VREL_NE;
     986              : 
     987              :   // TRUE = op1 == op2 indicates EQ_EXPR.
     988      2569106 :   if (!range_includes_zero_p (lhs))
     989      2569023 :     return VREL_EQ;
     990              :   return VREL_VARYING;
     991              : }
     992              : 
     993              : bool
     994      7912860 : operator_not_equal::fold_range (irange &r, tree type,
     995              :                                 const prange &op1,
     996              :                                 const prange &op2,
     997              :                                 relation_trio rel) const
     998              : {
     999      7912860 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_NE))
    1000              :     return true;
    1001              : 
    1002              :   // We can be sure the values are always equal or not if both ranges
    1003              :   // consist of a single value, and then compare them.
    1004      7896827 :   bool op1_const = wi::eq_p (op1.lower_bound (), op1.upper_bound ());
    1005      7896827 :   bool op2_const = wi::eq_p (op2.lower_bound (), op2.upper_bound ());
    1006              :   // Check for points to equality and inequality first.
    1007      7896827 :   if (op1.pt_inverted_p (op2))
    1008            0 :     r = range_true (type);
    1009      7896827 :   else if (op1.pt_invariant_p (op2))
    1010         1180 :     r = range_false (type);
    1011      7895647 :   else if (op1_const && op2_const)
    1012              :     {
    1013        47842 :       if (wi::ne_p (op1.lower_bound (), op2.upper_bound()))
    1014          174 :         r = range_true (type);
    1015              :       else
    1016        47668 :         r = range_false (type);
    1017              :     }
    1018              :   else
    1019              :     {
    1020              :       // If ranges do not intersect, we know the range is not equal,
    1021              :       // otherwise we don't know anything for sure.
    1022      7847805 :       prange tmp = op1;
    1023      7847805 :       tmp.intersect (op2);
    1024      7847805 :       if (tmp.undefined_p ())
    1025       200807 :         r = range_true (type);
    1026              :       // Check if a constant cannot satisfy the bitmask requirements.
    1027     16458458 :       else if (op2_const && !op1.get_bitmask ().member_p (op2.lower_bound ()))
    1028            0 :          r = range_true (type);
    1029      7649660 :       else if (op1_const && !op2.get_bitmask ().member_p (op1.lower_bound ()))
    1030            0 :          r = range_true (type);
    1031              :       else
    1032      7646998 :         r = range_true_and_false (type);
    1033      7847805 :     }
    1034              : 
    1035              :   //update_known_bitmask (r, NE_EXPR, op1, op2);
    1036              :   return true;
    1037              : }
    1038              : 
    1039              : bool
    1040      5192174 : operator_not_equal::op1_range (prange &r, tree type,
    1041              :                                const irange &lhs,
    1042              :                                const prange &op2,
    1043              :                                relation_trio) const
    1044              : {
    1045      5192174 :   switch (get_bool_state (r, lhs, type))
    1046              :     {
    1047      4074942 :     case BRS_TRUE:
    1048              :       // If the result is true, the only time we know anything is if
    1049              :       // OP2 is a constant.
    1050      4074942 :       if (!op2.undefined_p ()
    1051     12224826 :           && wi::eq_p (op2.lower_bound(), op2.upper_bound()))
    1052              :         {
    1053      1650597 :           r = op2;
    1054      1650597 :           r.invert ();
    1055              :         }
    1056              :       else
    1057      2424345 :         r.set_varying (type);
    1058              :       break;
    1059              : 
    1060      1093302 :     case BRS_FALSE:
    1061              :       // If it's false, the result is the same as OP2.
    1062      1093302 :       r = op2;
    1063      1093302 :       break;
    1064              : 
    1065              :     default:
    1066              :       break;
    1067              :     }
    1068      5192174 :   return true;
    1069              : }
    1070              : 
    1071              : 
    1072              : bool
    1073      1553728 : operator_not_equal::op2_range (prange &r, tree type,
    1074              :                                const irange &lhs,
    1075              :                                const prange &op1,
    1076              :                                relation_trio rel) const
    1077              : {
    1078      1553728 :   return operator_not_equal::op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
    1079              : }
    1080              : 
    1081              : relation_kind
    1082      5557214 : operator_not_equal::op1_op2_relation (const irange &lhs, const prange &,
    1083              :                                       const prange &) const
    1084              : {
    1085      5557214 :   if (lhs.undefined_p ())
    1086              :     return VREL_UNDEFINED;
    1087              : 
    1088              :   // FALSE = op1 != op2  indicates EQ_EXPR.
    1089      5557214 :   if (lhs.zero_p ())
    1090              :     return VREL_EQ;
    1091              : 
    1092              :   // TRUE = op1 != op2  indicates NE_EXPR.
    1093      3674319 :   if (!range_includes_zero_p (lhs))
    1094      3670937 :     return VREL_NE;
    1095              :   return VREL_VARYING;
    1096              : }
    1097              : 
    1098              : bool
    1099       367839 : operator_lt::fold_range (irange &r, tree type,
    1100              :                          const prange &op1,
    1101              :                          const prange &op2,
    1102              :                          relation_trio rel) const
    1103              : {
    1104       367839 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_LT))
    1105              :     return true;
    1106              : 
    1107       367082 :   signop sign = TYPE_SIGN (op1.type ());
    1108       367082 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1109              : 
    1110       367082 :   if (wi::lt_p (op1.upper_bound (), op2.lower_bound (), sign))
    1111            2 :     r = range_true (type);
    1112       367080 :   else if (!wi::lt_p (op1.lower_bound (), op2.upper_bound (), sign))
    1113           28 :     r = range_false (type);
    1114              :   // Use nonzero bits to determine if < 0 is false.
    1115       367052 :   else if (op2.zero_p () && !wi::neg_p (op1.get_nonzero_bits (), sign))
    1116            0 :     r = range_false (type);
    1117              :   else
    1118       367052 :     r = range_true_and_false (type);
    1119              : 
    1120              :   //update_known_bitmask (r, LT_EXPR, op1, op2);
    1121              :   return true;
    1122              : }
    1123              : 
    1124              : bool
    1125       281952 : operator_lt::op1_range (prange &r, tree type,
    1126              :                         const irange &lhs,
    1127              :                         const prange &op2,
    1128              :                         relation_trio) const
    1129              : {
    1130       281952 :   if (op2.undefined_p ())
    1131              :     return false;
    1132              : 
    1133       281952 :   switch (get_bool_state (r, lhs, type))
    1134              :     {
    1135       239100 :     case BRS_TRUE:
    1136       239100 :       build_lt (r, type, op2);
    1137       239100 :       break;
    1138              : 
    1139        42852 :     case BRS_FALSE:
    1140        42852 :       build_ge (r, type, op2);
    1141        42852 :       break;
    1142              : 
    1143              :     default:
    1144              :       break;
    1145              :     }
    1146              :   return true;
    1147              : }
    1148              : 
    1149              : bool
    1150       175144 : operator_lt::op2_range (prange &r, tree type,
    1151              :                         const irange &lhs,
    1152              :                         const prange &op1,
    1153              :                         relation_trio) const
    1154              : {
    1155       175144 :   if (op1.undefined_p ())
    1156              :     return false;
    1157              : 
    1158       175144 :   switch (get_bool_state (r, lhs, type))
    1159              :     {
    1160       121369 :     case BRS_TRUE:
    1161       121369 :       build_gt (r, type, op1);
    1162       121369 :       break;
    1163              : 
    1164        53771 :     case BRS_FALSE:
    1165        53771 :       build_le (r, type, op1);
    1166        53771 :       break;
    1167              : 
    1168              :     default:
    1169              :       break;
    1170              :     }
    1171              :   return true;
    1172              : }
    1173              : 
    1174              : relation_kind
    1175       775050 : operator_lt::op1_op2_relation (const irange &lhs, const prange &,
    1176              :                                const prange &) const
    1177              : {
    1178       775050 :   if (lhs.undefined_p ())
    1179              :     return VREL_UNDEFINED;
    1180              : 
    1181              :   // FALSE = op1 < op2 indicates GE_EXPR.
    1182       775050 :   if (lhs.zero_p ())
    1183              :     return VREL_GE;
    1184              : 
    1185              :   // TRUE = op1 < op2 indicates LT_EXPR.
    1186       571567 :   if (!range_includes_zero_p (lhs))
    1187       571563 :     return VREL_LT;
    1188              :   return VREL_VARYING;
    1189              : }
    1190              : 
    1191              : bool
    1192       113299 : operator_le::fold_range (irange &r, tree type,
    1193              :                          const prange &op1,
    1194              :                          const prange &op2,
    1195              :                          relation_trio rel) const
    1196              : {
    1197       113299 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_LE))
    1198              :     return true;
    1199              : 
    1200       112955 :   signop sign = TYPE_SIGN (op1.type ());
    1201       112955 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1202              : 
    1203       112955 :   if (wi::le_p (op1.upper_bound (), op2.lower_bound (), sign))
    1204           17 :     r = range_true (type);
    1205       112938 :   else if (!wi::le_p (op1.lower_bound (), op2.upper_bound (), sign))
    1206            7 :     r = range_false (type);
    1207              :   else
    1208       112931 :     r = range_true_and_false (type);
    1209              : 
    1210              :   //update_known_bitmask (r, LE_EXPR, op1, op2);
    1211              :   return true;
    1212              : }
    1213              : 
    1214              : bool
    1215        77357 : operator_le::op1_range (prange &r, tree type,
    1216              :                         const irange &lhs,
    1217              :                         const prange &op2,
    1218              :                         relation_trio) const
    1219              : {
    1220        77357 :   if (op2.undefined_p ())
    1221              :     return false;
    1222              : 
    1223        77357 :   switch (get_bool_state (r, lhs, type))
    1224              :     {
    1225        55022 :     case BRS_TRUE:
    1226        55022 :       build_le (r, type, op2);
    1227        55022 :       break;
    1228              : 
    1229        22335 :     case BRS_FALSE:
    1230        22335 :       build_gt (r, type, op2);
    1231        22335 :       break;
    1232              : 
    1233              :     default:
    1234              :       break;
    1235              :     }
    1236              :   return true;
    1237              : }
    1238              : 
    1239              : bool
    1240       117872 : operator_le::op2_range (prange &r, tree type,
    1241              :                         const irange &lhs,
    1242              :                         const prange &op1,
    1243              :                         relation_trio) const
    1244              : {
    1245       117872 :   if (op1.undefined_p ())
    1246              :     return false;
    1247              : 
    1248       117872 :   switch (get_bool_state (r, lhs, type))
    1249              :     {
    1250        96575 :     case BRS_TRUE:
    1251        96575 :       build_ge (r, type, op1);
    1252        96575 :       break;
    1253              : 
    1254        21297 :     case BRS_FALSE:
    1255        21297 :       build_lt (r, type, op1);
    1256        21297 :       break;
    1257              : 
    1258              :     default:
    1259              :       break;
    1260              :     }
    1261              :   return true;
    1262              : }
    1263              : 
    1264              : relation_kind
    1265       317624 : operator_le::op1_op2_relation (const irange &lhs, const prange &,
    1266              :                                const prange &) const
    1267              : {
    1268       317624 :   if (lhs.undefined_p ())
    1269              :     return VREL_UNDEFINED;
    1270              : 
    1271              :   // FALSE = op1 <= op2 indicates GT_EXPR.
    1272       317624 :   if (lhs.zero_p ())
    1273              :     return VREL_GT;
    1274              : 
    1275              :   // TRUE = op1 <= op2 indicates LE_EXPR.
    1276       230753 :   if (!range_includes_zero_p (lhs))
    1277       230753 :     return VREL_LE;
    1278              :   return VREL_VARYING;
    1279              : }
    1280              : 
    1281              : bool
    1282       362159 : operator_gt::fold_range (irange &r, tree type,
    1283              :                          const prange &op1, const prange &op2,
    1284              :                          relation_trio rel) const
    1285              : {
    1286       362159 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_GT))
    1287              :     return true;
    1288              : 
    1289       361230 :   signop sign = TYPE_SIGN (op1.type ());
    1290       361230 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1291              : 
    1292       361230 :   if (wi::gt_p (op1.lower_bound (), op2.upper_bound (), sign))
    1293            2 :     r = range_true (type);
    1294       361228 :   else if (!wi::gt_p (op1.upper_bound (), op2.lower_bound (), sign))
    1295            7 :     r = range_false (type);
    1296              :   else
    1297       361221 :     r = range_true_and_false (type);
    1298              : 
    1299              :   //update_known_bitmask (r, GT_EXPR, op1, op2);
    1300              :   return true;
    1301              : }
    1302              : 
    1303              : bool
    1304       251556 : operator_gt::op1_range (prange &r, tree type,
    1305              :                         const irange &lhs, const prange &op2,
    1306              :                         relation_trio) const
    1307              : {
    1308       251556 :   if (op2.undefined_p ())
    1309              :     return false;
    1310              : 
    1311       251556 :   switch (get_bool_state (r, lhs, type))
    1312              :     {
    1313       161987 :     case BRS_TRUE:
    1314       161987 :       build_gt (r, type, op2);
    1315       161987 :       break;
    1316              : 
    1317        89569 :     case BRS_FALSE:
    1318        89569 :       build_le (r, type, op2);
    1319        89569 :       break;
    1320              : 
    1321              :     default:
    1322              :       break;
    1323              :     }
    1324              :   return true;
    1325              : }
    1326              : 
    1327              : bool
    1328       236943 : operator_gt::op2_range (prange &r, tree type,
    1329              :                         const irange &lhs,
    1330              :                         const prange &op1,
    1331              :                         relation_trio) const
    1332              : {
    1333       236943 :   if (op1.undefined_p ())
    1334              :     return false;
    1335              : 
    1336       236943 :   switch (get_bool_state (r, lhs, type))
    1337              :     {
    1338       183007 :     case BRS_TRUE:
    1339       183007 :       build_lt (r, type, op1);
    1340       183007 :       break;
    1341              : 
    1342        53936 :     case BRS_FALSE:
    1343        53936 :       build_ge (r, type, op1);
    1344        53936 :       break;
    1345              : 
    1346              :     default:
    1347              :       break;
    1348              :     }
    1349              :   return true;
    1350              : }
    1351              : 
    1352              : relation_kind
    1353       801585 : operator_gt::op1_op2_relation (const irange &lhs, const prange &,
    1354              :                                const prange &) const
    1355              : {
    1356       801585 :   if (lhs.undefined_p ())
    1357              :     return VREL_UNDEFINED;
    1358              : 
    1359              :   // FALSE = op1 > op2 indicates LE_EXPR.
    1360       801585 :   if (lhs.zero_p ())
    1361              :     return VREL_LE;
    1362              : 
    1363              :   // TRUE = op1 > op2 indicates GT_EXPR.
    1364       551756 :   if (!range_includes_zero_p (lhs))
    1365       551756 :     return VREL_GT;
    1366              :   return VREL_VARYING;
    1367              : }
    1368              : 
    1369              : bool
    1370       188838 : operator_ge::fold_range (irange &r, tree type,
    1371              :                          const prange &op1,
    1372              :                          const prange &op2,
    1373              :                          relation_trio rel) const
    1374              : {
    1375       188838 :   if (relop_early_resolve (r, type, op1, op2, rel, VREL_GE))
    1376              :     return true;
    1377              : 
    1378       188592 :   signop sign = TYPE_SIGN (op1.type ());
    1379       188592 :   gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
    1380              : 
    1381       188592 :   if (wi::ge_p (op1.lower_bound (), op2.upper_bound (), sign))
    1382           63 :     r = range_true (type);
    1383       188529 :   else if (!wi::ge_p (op1.upper_bound (), op2.lower_bound (), sign))
    1384            0 :     r = range_false (type);
    1385              :   else
    1386       188529 :     r = range_true_and_false (type);
    1387              : 
    1388              :   //update_known_bitmask (r, GE_EXPR, op1, op2);
    1389              :   return true;
    1390              : }
    1391              : 
    1392              : bool
    1393       186708 : operator_ge::op1_range (prange &r, tree type,
    1394              :                         const irange &lhs,
    1395              :                         const prange &op2,
    1396              :                         relation_trio) const
    1397              : {
    1398       186708 :   if (op2.undefined_p ())
    1399              :     return false;
    1400              : 
    1401       186708 :   switch (get_bool_state (r, lhs, type))
    1402              :     {
    1403       162768 :     case BRS_TRUE:
    1404       162768 :       build_ge (r, type, op2);
    1405       162768 :       break;
    1406              : 
    1407        23940 :     case BRS_FALSE:
    1408        23940 :       build_lt (r, type, op2);
    1409        23940 :       break;
    1410              : 
    1411              :     default:
    1412              :       break;
    1413              :     }
    1414              :   return true;
    1415              : }
    1416              : 
    1417              : bool
    1418        81251 : operator_ge::op2_range (prange &r, tree type,
    1419              :                         const irange &lhs,
    1420              :                         const prange &op1,
    1421              :                         relation_trio) const
    1422              : {
    1423        81251 :   if (op1.undefined_p ())
    1424              :     return false;
    1425              : 
    1426        81251 :   switch (get_bool_state (r, lhs, type))
    1427              :     {
    1428        56345 :     case BRS_TRUE:
    1429        56345 :       build_le (r, type, op1);
    1430        56345 :       break;
    1431              : 
    1432        24906 :     case BRS_FALSE:
    1433        24906 :       build_gt (r, type, op1);
    1434        24906 :       break;
    1435              : 
    1436              :     default:
    1437              :       break;
    1438              :     }
    1439              :   return true;
    1440              : }
    1441              : 
    1442              : relation_kind
    1443       469240 : operator_ge::op1_op2_relation (const irange &lhs, const prange &,
    1444              :                                const prange &) const
    1445              : {
    1446       469240 :   if (lhs.undefined_p ())
    1447              :     return VREL_UNDEFINED;
    1448              : 
    1449              :   // FALSE = op1 >= op2 indicates LT_EXPR.
    1450       469240 :   if (lhs.zero_p ())
    1451              :     return VREL_LT;
    1452              : 
    1453              :   // TRUE = op1 >= op2 indicates GE_EXPR.
    1454       353562 :   if (!range_includes_zero_p (lhs))
    1455       353562 :     return VREL_GE;
    1456              :   return VREL_VARYING;
    1457              : }
    1458              : 
    1459              : // Initialize any pointer operators to the primary table
    1460              : 
    1461              : void
    1462       291201 : range_op_table::initialize_pointer_ops ()
    1463              : {
    1464       291201 :   set (POINTER_PLUS_EXPR, op_pointer_plus);
    1465       291201 :   set (POINTER_DIFF_EXPR, op_pointer_diff);
    1466       291201 : }
        

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.