LCOV - code coverage report
Current view: top level - gcc - value-range.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.5 % 561 530
Test Date: 2026-05-11 19:44:49 Functions: 79.1 % 129 102
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Support routines for value ranges.
       2              :    Copyright (C) 2019-2026 Free Software Foundation, Inc.
       3              :    Contributed by Aldy Hernandez <aldyh@redhat.com> and
       4              :    Andrew Macleod <amacleod@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              : #ifndef GCC_VALUE_RANGE_H
      23              : #define GCC_VALUE_RANGE_H
      24              : 
      25              : class irange;
      26              : 
      27              : // Types of value ranges.
      28              : enum value_range_kind
      29              : {
      30              :   /* Empty range.  */
      31              :   VR_UNDEFINED,
      32              :   /* Range spans the entire domain.  */
      33              :   VR_VARYING,
      34              :   /* Range is [MIN, MAX].  */
      35              :   VR_RANGE,
      36              :   /* Range is ~[MIN, MAX].  */
      37              :   VR_ANTI_RANGE,
      38              :   /* Range is a NAN.  */
      39              :   VR_NAN,
      40              :   /* Range is a nice guy.  */
      41              :   VR_LAST
      42              : };
      43              : 
      44              : // Discriminator between different vrange types.
      45              : 
      46              : enum value_range_discriminator
      47              : {
      48              :   // Range holds an integer or pointer.
      49              :   VR_IRANGE,
      50              :   // Pointer range.
      51              :   VR_PRANGE,
      52              :   // Floating point range.
      53              :   VR_FRANGE,
      54              :   // Range holds an unsupported type.
      55              :   VR_UNKNOWN
      56              : };
      57              : 
      58              : // Abstract class for representing subsets of values for various
      59              : // supported types, such as the possible values of a variable.
      60              : //
      61              : // There are subclasses for each of integer, floating point, and pointer
      62              : // types, each with their own strategies for efficiently representing
      63              : // subsets of values.
      64              : //
      65              : // For efficiency, we can't precisely represent any arbitrary subset
      66              : // of values of a type (which could require 2^N bits for a type of size N)
      67              : // Hence operations on the subclasses may introduce imprecision
      68              : // due to over-approximating the possible subsets.
      69              : //
      70              : // To query what types ranger and the entire ecosystem can support,
      71              : // use value_range::supports_type_p(tree type).  This is a static
      72              : // method available independently of any vrange object.
      73              : //
      74              : // To query what a given vrange variant can support, use:
      75              : //    irange::supports_p ()
      76              : //    frange::supports_p ()
      77              : //    etc
      78              : //
      79              : // To query what a range object can support, use:
      80              : //    void foo (vrange &v, irange &i, frange &f)
      81              : //    {
      82              : //      if (v.supports_type_p (type)) ...
      83              : //      if (i.supports_type_p (type)) ...
      84              : //      if (f.supports_type_p (type)) ...
      85              : //    }
      86              : 
      87              : class vrange
      88              : {
      89              :   template <typename T> friend bool is_a (vrange &);
      90              :   friend class value_range;
      91              :   friend void streamer_write_vrange (struct output_block *, const vrange &);
      92              :   friend class range_op_handler;
      93              : public:
      94              :   virtual void accept (const class vrange_visitor &v) const = 0;
      95              :   virtual void set (tree, tree, value_range_kind = VR_RANGE) = 0;
      96              :   virtual tree type () const = 0;
      97              :   virtual bool supports_type_p (const_tree type) const = 0;
      98              :   virtual void set_varying (tree type) = 0;
      99              :   virtual void set_undefined () = 0;
     100              :   virtual bool union_ (const vrange &) = 0;
     101              :   virtual bool intersect (const vrange &) = 0;
     102              :   virtual bool singleton_p (tree *result = NULL) const = 0;
     103              :   virtual bool contains_p (tree cst) const = 0;
     104              :   virtual bool zero_p () const = 0;
     105              :   virtual bool nonzero_p () const = 0;
     106              :   virtual void set_nonzero (tree type) = 0;
     107              :   virtual void set_zero (tree type) = 0;
     108              :   virtual void set_nonnegative (tree type) = 0;
     109              :   virtual bool fits_p (const vrange &r) const = 0;
     110   5053430720 :   virtual ~vrange () { }
     111              :   virtual tree lbound () const = 0;
     112              :   virtual tree ubound () const = 0;
     113              :   virtual void update_bitmask (const class irange_bitmask &);
     114              :   virtual irange_bitmask get_bitmask () const;
     115              :   wide_int get_nonzero_bits () const;
     116              :   void set_nonzero_bits (const wide_int &bits);
     117              : 
     118              :   bool varying_p () const;
     119              :   bool undefined_p () const;
     120              :   vrange& operator= (const vrange &);
     121              :   bool operator== (const vrange &) const;
     122     14001904 :   bool operator!= (const vrange &r) const { return !(*this == r); }
     123              :   void dump (FILE *) const;
     124            0 :   virtual void verify_range () const { }
     125              : protected:
     126   6372637055 :   vrange (enum value_range_discriminator d) : m_discriminator (d) { }
     127              :   ENUM_BITFIELD(value_range_kind) m_kind : 8;
     128              :   const ENUM_BITFIELD(value_range_discriminator) m_discriminator : 4;
     129              : };
     130              : 
     131              : namespace inchash
     132              : {
     133              :   extern void add_vrange (const vrange &, hash &, unsigned flags = 0);
     134              : }
     135              : 
     136              : // A pair of values representing the known bits of a value.  Zero bits
     137              : // in MASK cover constant values.  Set bits in MASK cover unknown
     138              : // values.  VALUE are the known bits for the bits where MASK is zero,
     139              : // and must be zero for the unknown bits where MASK is set (needed as an
     140              : // optimization of union and intersect)
     141              : // For example:
     142              : // VALUE: [..., 0, 1, 0]
     143              : // MASK:  [..., 1, 0, 0]
     144              : //              ^  ^  ^
     145              : //              |  |  known bit: {0}
     146              : //              |  known bit: {1}
     147              : //              unknown bit: {0, 1}
     148              : 
     149              : class irange_bitmask
     150              : {
     151              : public:
     152   6136671010 :   irange_bitmask () { /* uninitialized */ }
     153            0 :   irange_bitmask (unsigned prec) { set_unknown (prec); }
     154              :   irange_bitmask (const wide_int &value, const wide_int &mask);
     155              :   irange_bitmask (tree type, const wide_int &min, const wide_int &max);
     156              : 
     157   1480202614 :   wide_int value () const { return m_value; }
     158   1789356281 :   wide_int mask () const { return m_mask; }
     159              :   void set_unknown (unsigned prec);
     160              :   bool unknown_p () const;
     161              :   unsigned get_precision () const;
     162              :   void union_ (const irange_bitmask &src);
     163              :   bool intersect (const irange_bitmask &src);
     164              :   bool operator== (const irange_bitmask &src) const;
     165              :   bool operator!= (const irange_bitmask &src) const { return !(*this == src); }
     166              :   void verify_mask () const;
     167              :   void dump (FILE *) const;
     168              :   bool range_from_mask (irange &r, tree type) const;
     169              : 
     170              :   bool member_p (const wide_int &val) const;
     171              : 
     172              :   // Convenience functions for nonzero bitmask compatibility.
     173              :   wide_int get_nonzero_bits () const;
     174              :   void set_nonzero_bits (const wide_int &bits);
     175              : private:
     176              :   wide_int m_value;
     177              :   wide_int m_mask;
     178              : };
     179              : 
     180              : inline void
     181   3347023510 : irange_bitmask::set_unknown (unsigned prec)
     182              : {
     183   3347023510 :   m_value = wi::zero (prec);
     184   3347023510 :   m_mask = wi::minus_one (prec);
     185   3347023510 :   if (flag_checking)
     186   3347010248 :     verify_mask ();
     187   3347023510 : }
     188              : 
     189              : // Return TRUE if THIS does not have any meaningful information.
     190              : 
     191              : inline bool
     192   4786170243 : irange_bitmask::unknown_p () const
     193              : {
     194   2213592385 :   return m_mask == -1;
     195              : }
     196              : 
     197              : inline
     198   1090749711 : irange_bitmask::irange_bitmask (const wide_int &value, const wide_int &mask)
     199              : {
     200   1090749711 :   m_value = value;
     201   1090749711 :   m_mask = mask;
     202   1090749711 :   if (flag_checking)
     203   1090745973 :     verify_mask ();
     204   1090749711 : }
     205              : 
     206              : inline unsigned
     207              : irange_bitmask::get_precision () const
     208              : {
     209              :   return m_mask.get_precision ();
     210              : }
     211              : 
     212              : // The following two functions are meant for backwards compatability
     213              : // with the nonzero bitmask.  A cleared bit means the value must be 0.
     214              : // A set bit means we have no information for the bit.
     215              : 
     216              : // Return the nonzero bits.
     217              : inline wide_int
     218         4013 : irange_bitmask::get_nonzero_bits () const
     219              : {
     220         4013 :   return m_value | m_mask;
     221              : }
     222              : 
     223              : // Set the bitmask to the nonzero bits in BITS.
     224              : inline void
     225              : irange_bitmask::set_nonzero_bits (const wide_int &bits)
     226              : {
     227              :   m_value = wi::zero (bits.get_precision ());
     228              :   m_mask = bits;
     229              :   if (flag_checking)
     230              :     verify_mask ();
     231              : }
     232              : 
     233              : // Return TRUE if val could be a valid value with this bitmask.
     234              : 
     235              : inline bool
     236    246865989 : irange_bitmask::member_p (const wide_int &val) const
     237              : {
     238    246865989 :   if (unknown_p ())
     239              :     return true;
     240     29392924 :   wide_int res = m_mask & val;
     241     29392924 :   if (m_value != 0)
     242       821292 :     res |= ~m_mask & m_value;
     243     29392924 :   return res == val;
     244     29392924 : }
     245              : 
     246              : inline bool
     247   1168421245 : irange_bitmask::operator== (const irange_bitmask &src) const
     248              : {
     249   1168421245 :   bool unknown1 = unknown_p ();
     250   1168421245 :   bool unknown2 = src.unknown_p ();
     251   1168421245 :   if (unknown1 || unknown2)
     252    890996867 :     return unknown1 == unknown2;
     253    277424378 :   return m_value == src.m_value && m_mask == src.m_mask;
     254              : }
     255              : 
     256              : inline void
     257     18552670 : irange_bitmask::union_ (const irange_bitmask &src)
     258              : {
     259     18552726 :   m_mask = (m_mask | src.m_mask) | (m_value ^ src.m_value);
     260     18552670 :   m_value = m_value & src.m_value;
     261     18552670 :   if (flag_checking)
     262     18552670 :     verify_mask ();
     263     18552670 : }
     264              : 
     265              : // Return FALSE if the bitmask intersection is undefined.
     266              : 
     267              : inline bool
     268    783299604 : irange_bitmask::intersect (const irange_bitmask &src)
     269              : {
     270              :   // If we have two known bits that are incompatible, the resulting
     271              :   // bit and therefore entire range is undefined.  Return FALSE.
     272   1566603426 :   if (wi::bit_and (~(m_mask | src.m_mask),
     273   2349898812 :                    m_value ^ src.m_value) != 0)
     274              :     return false;
     275              :   else
     276              :     {
     277    783255726 :       m_mask = m_mask & src.m_mask;
     278    783255726 :       m_value = m_value | src.m_value;
     279              :     }
     280    783255726 :   if (flag_checking)
     281    783253189 :     verify_mask ();
     282              :   return true;
     283              : }
     284              : 
     285              : // A subset of possible values for an integer type, leaving
     286              : // allocation of storage to subclasses.
     287              : 
     288  10000162064 : class irange : public vrange
     289              : {
     290              :   friend class irange_storage;
     291              :   friend class vrange_printer;
     292              : public:
     293              :   // In-place setters.
     294              :   void set (tree type, const wide_int &, const wide_int &,
     295              :             value_range_kind = VR_RANGE);
     296              :   virtual void set_nonzero (tree type) override;
     297              :   virtual void set_zero (tree type) override;
     298              :   virtual void set_nonnegative (tree type) override;
     299              :   virtual void set_varying (tree type) override;
     300              :   virtual void set_undefined () override;
     301              : 
     302              :   // Range types.
     303              :   static bool supports_p (const_tree type);
     304              :   virtual bool supports_type_p (const_tree type) const override;
     305              :   virtual tree type () const override;
     306              : 
     307              :   // Iteration over sub-ranges.
     308              :   unsigned num_pairs () const;
     309              :   wide_int lower_bound (unsigned = 0) const;
     310              :   wide_int upper_bound (unsigned) const;
     311              :   wide_int upper_bound () const;
     312              :   virtual tree lbound () const override;
     313              :   virtual tree ubound () const override;
     314              : 
     315              :   // Predicates.
     316              :   virtual bool zero_p () const override;
     317              :   virtual bool nonzero_p () const override;
     318              :   virtual bool singleton_p (tree *result = NULL) const override;
     319              :   bool singleton_p (wide_int &) const;
     320              :   bool contains_p (const wide_int &) const;
     321              :   bool nonnegative_p () const;
     322              :   bool nonpositive_p () const;
     323              : 
     324              :   // In-place operators.
     325              :   virtual bool union_ (const vrange &) override;
     326              :   virtual bool intersect (const vrange &) override;
     327              :   void invert ();
     328              : 
     329              :   // Operator overloads.
     330              :   irange& operator= (const irange &);
     331              :   bool operator== (const irange &) const;
     332              :   bool operator!= (const irange &r) const { return !(*this == r); }
     333              : 
     334              :   // Misc methods.
     335              :   virtual bool fits_p (const vrange &r) const override;
     336              :   virtual void accept (const vrange_visitor &v) const override;
     337              : 
     338              :   virtual void update_bitmask (const class irange_bitmask &) override;
     339              :   virtual irange_bitmask get_bitmask () const override;
     340              : 
     341              :   virtual void verify_range () const override;
     342              : protected:
     343              :   void maybe_resize (int needed);
     344              :   virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
     345              :   virtual bool contains_p (tree cst) const override;
     346              :   irange (wide_int *, unsigned nranges, bool resizable);
     347              : 
     348              :    // In-place operators.
     349              :   bool irange_contains_p (const irange &) const;
     350              :   bool irange_single_pair_union (const irange &r);
     351              : 
     352              :   void normalize_kind ();
     353              : 
     354              : 
     355              :   // Hard limit on max ranges allowed.
     356              :   static const int HARD_MAX_RANGES = 255;
     357              : private:
     358              :   bool varying_compatible_p () const;
     359              :   bool intersect_bitmask (const irange &r);
     360              :   bool union_bitmask (const irange &r);
     361              :   bool set_range_from_bitmask ();
     362              :   bool snap_subranges ();
     363              :   bool snap (const wide_int &, const wide_int &, wide_int &, wide_int &,
     364              :              bool &);
     365              : 
     366              :   bool intersect (const wide_int& lb, const wide_int& ub);
     367              :   bool union_append (const irange &r);
     368              :   unsigned char m_num_ranges;
     369              :   bool m_resizable;
     370              :   unsigned char m_max_ranges;
     371              :   tree m_type;
     372              :   irange_bitmask m_bitmask;
     373              : protected:
     374              :   wide_int *m_base;
     375              : };
     376              : 
     377              : // Here we describe an irange with N pairs of ranges.  The storage for
     378              : // the pairs is embedded in the class as an array.
     379              : //
     380              : // If RESIZABLE is true, the storage will be resized on the heap when
     381              : // the number of ranges needed goes past N up to a max of
     382              : // HARD_MAX_RANGES.  This new storage is freed upon destruction.
     383              : 
     384              : template<unsigned N, bool RESIZABLE = false>
     385              : class int_range final : public irange
     386              : {
     387              : public:
     388              :   int_range ();
     389              :   int_range (tree type, const wide_int &, const wide_int &,
     390              :              value_range_kind = VR_RANGE);
     391              :   int_range (tree type);
     392              :   int_range (const int_range &);
     393              :   int_range (const irange &);
     394              :   ~int_range () final override;
     395              :   int_range& operator= (const int_range &);
     396              : protected:
     397              :   int_range (tree, tree, value_range_kind = VR_RANGE);
     398              : private:
     399              :   wide_int m_ranges[N*2];
     400              : };
     401              : 
     402              : class prange final : public vrange
     403              : {
     404              :   friend class prange_storage;
     405              :   friend class vrange_printer;
     406              : public:
     407              :   prange ();
     408              :   prange (const prange &);
     409              :   prange (tree type);
     410              :   prange (tree type, const wide_int &, const wide_int &,
     411              :           value_range_kind = VR_RANGE);
     412              :   static bool supports_p (const_tree type);
     413              :   virtual bool supports_type_p (const_tree type) const final override;
     414              :   virtual void accept (const vrange_visitor &v) const final override;
     415              :   virtual void set_undefined () final override;
     416              :   virtual void set_varying (tree type) final override;
     417              :   virtual void set_nonzero (tree type) final override;
     418              :   virtual void set_zero (tree type) final override;
     419              :   virtual void set_nonnegative (tree type) final override;
     420              :   virtual bool contains_p (tree cst) const final override;
     421              :   virtual bool fits_p (const vrange &v) const final override;
     422              :   virtual bool singleton_p (tree *result = NULL) const final override;
     423              :   virtual bool zero_p () const final override;
     424              :   virtual bool nonzero_p () const final override;
     425              :   virtual void set (tree, tree, value_range_kind = VR_RANGE) final override;
     426              :   virtual tree type () const final override;
     427              :   virtual bool union_ (const vrange &v) final override;
     428              :   virtual bool intersect (const vrange &v) final override;
     429              :   virtual tree lbound () const final override;
     430              :   virtual tree ubound () const final override;
     431              : 
     432              :   prange& operator= (const prange &);
     433              :   bool operator== (const prange &) const;
     434              :   void set (tree type, const wide_int &, const wide_int &,
     435              :             value_range_kind = VR_RANGE);
     436              :   void invert ();
     437              :   bool contains_p (const wide_int &) const;
     438              :   wide_int lower_bound () const;
     439              :   wide_int upper_bound () const;
     440              :   virtual void verify_range () const final override;
     441              :   irange_bitmask get_bitmask () const final override;
     442              :   void update_bitmask (const irange_bitmask &) final override;
     443              : protected:
     444              :   bool varying_compatible_p () const;
     445              : 
     446              :   tree m_type;
     447              :   wide_int m_min;
     448              :   wide_int m_max;
     449              :   irange_bitmask m_bitmask;
     450              : };
     451              : 
     452              : // Unsupported temporaries may be created by ranger before it's known
     453              : // they're unsupported, or by vr_values::get_value_range.
     454              : 
     455            0 : class unsupported_range : public vrange
     456              : {
     457              : public:
     458     70913662 :   unsupported_range ()
     459     70913662 :     : vrange (VR_UNKNOWN)
     460              :   {
     461     70913662 :     set_undefined ();
     462              :   }
     463       662641 :   unsupported_range (const unsupported_range &src)
     464       662641 :     : vrange (VR_UNKNOWN)
     465              :   {
     466       662641 :     unsupported_range::operator= (src);
     467              :   }
     468              :   void set (tree min, tree, value_range_kind = VR_RANGE) final override;
     469              :   tree type () const final override;
     470              :   bool supports_type_p (const_tree) const final override;
     471              :   void set_varying (tree) final override;
     472              :   void set_undefined () final override;
     473              :   void accept (const vrange_visitor &v) const final override;
     474              :   bool union_ (const vrange &r) final override;
     475              :   bool intersect (const vrange &r) final override;
     476              :   bool singleton_p (tree * = NULL) const final override;
     477              :   bool contains_p (tree) const final override;
     478              :   bool zero_p () const final override;
     479              :   bool nonzero_p () const final override;
     480              :   void set_nonzero (tree type) final override;
     481              :   void set_zero (tree type) final override;
     482              :   void set_nonnegative (tree type) final override;
     483              :   bool fits_p (const vrange &) const final override;
     484              :   unsupported_range& operator= (const unsupported_range &r);
     485              :   tree lbound () const final override;
     486              :   tree ubound () const final override;
     487              : };
     488              : 
     489              : // The possible NAN state of a floating point value as an opaque object.
     490              : // This represents one of the four subsets of { -NaN, +NaN },
     491              : // i.e. one of {}, { -NaN }, { +NaN}, or { -NaN, +NaN }.
     492              : 
     493              : class nan_state
     494              : {
     495              : public:
     496              :   nan_state (bool);
     497              :   nan_state (bool pos_nan, bool neg_nan);
     498              :   bool neg_p () const;
     499              :   bool pos_p () const;
     500              : private:
     501              :   bool m_pos_nan;
     502              :   bool m_neg_nan;
     503              : };
     504              : 
     505              : // Set NAN state to +-NAN if NAN_P is true.  Otherwise set NAN state
     506              : // to false.
     507              : 
     508              : inline
     509     65773041 : nan_state::nan_state (bool nan_p)
     510              : {
     511     65773041 :   m_pos_nan = nan_p;
     512     61390329 :   m_neg_nan = nan_p;
     513              : }
     514              : 
     515              : // Constructor initializing the object to +NAN if POS_NAN is set, -NAN
     516              : // if NEG_NAN is set, or +-NAN if both are set.  Otherwise POS_NAN and
     517              : // NEG_NAN are clear, and the object cannot be a NAN.
     518              : 
     519              : inline
     520      3930566 : nan_state::nan_state (bool pos_nan, bool neg_nan)
     521              : {
     522      3930566 :   m_pos_nan = pos_nan;
     523      3920801 :   m_neg_nan = neg_nan;
     524              : }
     525              : 
     526              : // Return if +NAN is possible.
     527              : 
     528              : inline bool
     529     36393082 : nan_state::pos_p () const
     530              : {
     531     36393058 :   return m_pos_nan;
     532              : }
     533              : 
     534              : // Return if -NAN is possible.
     535              : 
     536              : inline bool
     537     36224438 : nan_state::neg_p () const
     538              : {
     539     36224414 :   return m_neg_nan;
     540              : }
     541              : 
     542              : // A subset of possible values for a floating point type.
     543              : //
     544              : // The representation is a type with a couple of endpoints, unioned
     545              : // with a subset of { -NaN, +NaN }.
     546              : 
     547     51291971 : class frange final : public vrange
     548              : {
     549              :   friend class frange_storage;
     550              :   friend class vrange_printer;
     551              : public:
     552              :   frange ();
     553              :   frange (const frange &);
     554              :   frange (tree, tree, value_range_kind = VR_RANGE);
     555              :   frange (tree type);
     556              :   frange (tree type, const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
     557              :           value_range_kind = VR_RANGE);
     558    622634607 :   static bool supports_p (const_tree type)
     559              :   {
     560              :     // ?? Decimal floats can have multiple representations for the
     561              :     // same number.  Supporting them may be as simple as just
     562              :     // disabling them in singleton_p.  No clue.
     563    622634607 :     return SCALAR_FLOAT_TYPE_P (type) && !DECIMAL_FLOAT_TYPE_P (type);
     564              :   }
     565              :   virtual tree type () const override;
     566              :   void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
     567              :             value_range_kind = VR_RANGE);
     568              :   void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
     569              :             const nan_state &, value_range_kind = VR_RANGE);
     570              :   void set_nan (tree type);
     571              :   void set_nan (tree type, bool sign);
     572              :   void set_nan (tree type, const nan_state &);
     573              :   virtual void set_varying (tree type) override;
     574              :   virtual void set_undefined () override;
     575              :   virtual bool union_ (const vrange &) override;
     576              :   virtual bool intersect (const vrange &) override;
     577              :   bool contains_p (const REAL_VALUE_TYPE &) const;
     578              :   virtual bool singleton_p (tree *result = NULL) const override;
     579              :   bool singleton_p (REAL_VALUE_TYPE &r) const;
     580              :   virtual bool supports_type_p (const_tree type) const override;
     581              :   virtual void accept (const vrange_visitor &v) const override;
     582              :   virtual bool zero_p () const override;
     583              :   virtual bool nonzero_p () const override;
     584              :   virtual void set_nonzero (tree type) override;
     585              :   virtual void set_zero (tree type) override;
     586              :   virtual void set_nonnegative (tree type) override;
     587              :   virtual bool fits_p (const vrange &) const override;
     588              :   frange& operator= (const frange &);
     589              :   bool operator== (const frange &) const;
     590           12 :   bool operator!= (const frange &r) const { return !(*this == r); }
     591              :   const REAL_VALUE_TYPE &lower_bound () const;
     592              :   const REAL_VALUE_TYPE &upper_bound () const;
     593              :   virtual tree lbound () const override;
     594              :   virtual tree ubound () const override;
     595              :   nan_state get_nan_state () const;
     596              :   void update_nan ();
     597              :   void update_nan (bool sign);
     598              :   void update_nan (tree) = delete; // Disallow silent conversion to bool.
     599              :   void update_nan (const nan_state &);
     600              :   void clear_nan ();
     601              :   void flush_denormals_to_zero ();
     602              : 
     603              :   // fpclassify like API
     604              :   bool known_isfinite () const;
     605              :   bool known_isnan () const;
     606              :   bool known_isinf () const;
     607              :   bool maybe_isnan () const;
     608              :   bool maybe_isnan (bool sign) const;
     609              :   bool maybe_isinf () const;
     610              :   bool signbit_p (bool &signbit) const;
     611              :   bool nan_signbit_p (bool &signbit) const;
     612              :   bool known_isnormal () const;
     613              :   bool known_isdenormal_or_zero () const;
     614              :   virtual void verify_range () const override;
     615              : protected:
     616              :   virtual bool contains_p (tree cst) const override;
     617              :   virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
     618              : 
     619              : private:
     620              :   bool internal_singleton_p (REAL_VALUE_TYPE * = NULL) const;
     621              :   bool normalize_kind ();
     622              :   bool union_nans (const frange &);
     623              :   bool intersect_nans (const frange &);
     624              :   bool combine_zeros (const frange &, bool union_p);
     625              : 
     626              :   tree m_type;
     627              :   REAL_VALUE_TYPE m_min;
     628              :   REAL_VALUE_TYPE m_max;
     629              :   bool m_pos_nan;
     630              :   bool m_neg_nan;
     631              : };
     632              : 
     633              : inline const REAL_VALUE_TYPE &
     634     21147451 : frange::lower_bound () const
     635              : {
     636     21147451 :   gcc_checking_assert (!undefined_p () && !known_isnan ());
     637     21147451 :   return m_min;
     638              : }
     639              : 
     640              : inline const REAL_VALUE_TYPE &
     641     19732188 : frange::upper_bound () const
     642              : {
     643     19732188 :   gcc_checking_assert (!undefined_p () && !known_isnan ());
     644     19732188 :   return m_max;
     645              : }
     646              : 
     647              : // Return the NAN state.
     648              : 
     649              : inline nan_state
     650      1793077 : frange::get_nan_state () const
     651              : {
     652      1793077 :   return nan_state (m_pos_nan, m_neg_nan);
     653              : }
     654              : 
     655              : // is_a<> and as_a<> implementation for vrange.
     656              : 
     657              : // Anything we haven't specialized is a hard fail.
     658              : template <typename T>
     659              : inline bool
     660              : is_a (vrange &)
     661              : {
     662              :   gcc_unreachable ();
     663              :   return false;
     664              : }
     665              : 
     666              : template <typename T>
     667              : inline bool
     668   4185160757 : is_a (const vrange &v)
     669              : {
     670              :   // Reuse is_a <vrange> to implement the const version.
     671   4359469190 :   const T &derived = static_cast<const T &> (v);
     672   1896241580 :   return is_a <T> (const_cast<T &> (derived));
     673              : }
     674              : 
     675              : template <typename T>
     676              : inline T &
     677   2277110390 : as_a (vrange &v)
     678              : {
     679            0 :   gcc_checking_assert (is_a <T> (v));
     680   2277110390 :   return static_cast <T &> (v);
     681              : }
     682              : 
     683              : template <typename T>
     684              : inline const T &
     685   3593173047 : as_a (const vrange &v)
     686              : {
     687            0 :   gcc_checking_assert (is_a <T> (v));
     688   3593173047 :   return static_cast <const T &> (v);
     689              : }
     690              : 
     691              : // Specializations for the different range types.
     692              : 
     693              : template <>
     694              : inline bool
     695   7023696293 : is_a <irange> (vrange &v)
     696              : {
     697   6900530314 :   return v.m_discriminator == VR_IRANGE;
     698              : }
     699              : 
     700              : template <>
     701              : inline bool
     702    922189386 : is_a <prange> (vrange &v)
     703              : {
     704    922189386 :   return v.m_discriminator == VR_PRANGE;
     705              : }
     706              : 
     707              : template <>
     708              : inline bool
     709    192618231 : is_a <frange> (vrange &v)
     710              : {
     711    192618231 :   return v.m_discriminator == VR_FRANGE;
     712              : }
     713              : 
     714              : template <>
     715              : inline bool
     716       662641 : is_a <unsupported_range> (vrange &v)
     717              : {
     718       662641 :   return v.m_discriminator == VR_UNKNOWN;
     719              : }
     720              : 
     721              : // For resizable ranges, resize the range up to HARD_MAX_RANGES if the
     722              : // NEEDED pairs is greater than the current capacity of the range.
     723              : 
     724              : inline void
     725   1301523847 : irange::maybe_resize (int needed)
     726              : {
     727   1301523847 :   if (!m_resizable || m_max_ranges == HARD_MAX_RANGES)
     728              :     return;
     729              : 
     730    845013267 :   if (needed > m_max_ranges)
     731              :     {
     732     61760330 :       m_max_ranges = HARD_MAX_RANGES;
     733  31559528630 :       wide_int *newmem = new wide_int[m_max_ranges * 2];
     734     61760330 :       unsigned n = num_pairs () * 2;
     735    352194262 :       for (unsigned i = 0; i < n; ++i)
     736    290433932 :         newmem[i] = m_base[i];
     737     61760330 :       m_base = newmem;
     738              :     }
     739              : }
     740              : 
     741              : template<unsigned N, bool RESIZABLE>
     742              : inline
     743   5000081032 : int_range<N, RESIZABLE>::~int_range ()
     744              : {
     745   3732490571 :   if (RESIZABLE && m_base != m_ranges)
     746  31559528630 :     delete[] m_base;
     747  31083452078 : }
     748              : 
     749              : // This is an "infinite" precision irange for use in temporary
     750              : // calculations.  It starts with a sensible default covering 99% of
     751              : // uses, and goes up to HARD_MAX_RANGES when needed.  Any allocated
     752              : // storage is freed upon destruction.
     753              : typedef int_range<3, /*RESIZABLE=*/true> int_range_max;
     754              : 
     755        40296 : class vrange_visitor
     756              : {
     757              : public:
     758            0 :   virtual void visit (const irange &) const { }
     759            0 :   virtual void visit (const prange &) const { }
     760            0 :   virtual void visit (const frange &) const { }
     761            0 :   virtual void visit (const unsupported_range &) const { }
     762              : };
     763              : 
     764              : // This is an "infinite" precision range object for use in temporary
     765              : // calculations for any of the handled types.  The object can be
     766              : // transparently used as a vrange.
     767              : //
     768              : // Using any of the various constructors initializes the object
     769              : // appropriately, but the default constructor is uninitialized and
     770              : // must be initialized either with set_range_class() or by assigning into it.
     771              : //
     772              : // Assigning between incompatible types is allowed.  For example if a
     773              : // temporary holds an irange, you can assign an frange into it, and
     774              : // all the right things will happen.  However, before passing this
     775              : // object to a function accepting a vrange, the correct type must be
     776              : // set.  If it isn't, you can do so with set_range_class().
     777              : 
     778              : class value_range
     779              : {
     780              : public:
     781              :   value_range ();
     782              :   value_range (const vrange &r);
     783              :   value_range (tree type);
     784              :   value_range (tree, tree, value_range_kind kind = VR_RANGE);
     785              :   value_range (const value_range &);
     786              :   ~value_range ();
     787              :   void set_range_class (tree type);
     788              :   vrange& operator= (const vrange &);
     789              :   value_range& operator= (const value_range &);
     790              :   bool operator== (const value_range &r) const;
     791              :   bool operator!= (const value_range &r) const;
     792              :   operator vrange &();
     793              :   operator const vrange &() const;
     794              :   void dump (FILE *) const;
     795              :   void print (pretty_printer *) const;
     796              :   static bool supports_type_p (const_tree type);
     797              : 
     798      2941210 :   tree type () { return m_vrange->type (); }
     799    153121321 :   bool varying_p () const { return m_vrange->varying_p (); }
     800    244142575 :   bool undefined_p () const { return m_vrange->undefined_p (); }
     801    302219545 :   void set_varying (tree type) { init (type); m_vrange->set_varying (type); }
     802     22867693 :   void set_undefined () { m_vrange->set_undefined (); }
     803     18769274 :   bool union_ (const vrange &r) { return m_vrange->union_ (r); }
     804     95558368 :   bool intersect (const vrange &r) { return m_vrange->intersect (r); }
     805      1422994 :   bool contains_p (tree cst) const { return m_vrange->contains_p (cst); }
     806    308037113 :   bool singleton_p (tree *result = NULL) const
     807    308037113 :     { return m_vrange->singleton_p (result); }
     808              :   void set_zero (tree type) { init (type); return m_vrange->set_zero (type); }
     809            0 :   void set_nonzero (tree type)
     810            0 :     { init (type); return m_vrange->set_nonzero (type); }
     811       260849 :   bool nonzero_p () const { return m_vrange->nonzero_p (); }
     812         4452 :   bool zero_p () const { return m_vrange->zero_p (); }
     813     10788976 :   tree lbound () const { return m_vrange->lbound (); }
     814       341141 :   tree ubound () const { return m_vrange->ubound (); }
     815       510938 :   irange_bitmask get_bitmask () const { return m_vrange->get_bitmask (); }
     816      1365470 :   void update_bitmask (const class irange_bitmask &bm)
     817      1365470 :   { return m_vrange->update_bitmask (bm); }
     818         2813 :   void accept (const vrange_visitor &v) const { m_vrange->accept (v); }
     819              :   void verify_range () const { m_vrange->verify_range (); }
     820              : private:
     821              :   void init (tree type);
     822              :   void init (const vrange &);
     823              : 
     824              :   vrange *m_vrange;
     825              :   union buffer_type {
     826              :     int_range_max ints;
     827              :     frange floats;
     828              :     unsupported_range unsupported;
     829              :     prange pointers;
     830   6574912779 :     buffer_type () { }
     831   6694235860 :     ~buffer_type () { }
     832              :   } m_buffer;
     833              : };
     834              : 
     835              : // The default constructor is uninitialized and must be initialized
     836              : // with either set_range_class() or with an assignment into it.
     837              : 
     838              : inline
     839   3710007776 : value_range::value_range ()
     840   3710007776 :   : m_buffer ()
     841              : {
     842   3710007776 :   m_vrange = NULL;
     843              : }
     844              : 
     845              : // Copy constructor.
     846              : 
     847              : inline
     848     11611572 : value_range::value_range (const value_range &r)
     849              : {
     850     11611572 :   init (*r.m_vrange);
     851              : }
     852              : 
     853              : // Copy constructor from a vrange.
     854              : 
     855              : inline
     856     77879518 : value_range::value_range (const vrange &r)
     857              : {
     858     77879518 :   init (r);
     859              : }
     860              : 
     861              : // Construct an UNDEFINED range that can hold ranges of TYPE.  If TYPE
     862              : // is not supported, default to unsupported_range.
     863              : 
     864              : inline
     865   2775361325 : value_range::value_range (tree type)
     866              : {
     867   2605627641 :   init (type);
     868      5798192 : }
     869              : 
     870              : // Construct a range that can hold a range of [MIN, MAX], where MIN
     871              : // and MAX are trees.
     872              : 
     873              : inline
     874        52588 : value_range::value_range (tree min, tree max, value_range_kind kind)
     875              : {
     876        52588 :   init (TREE_TYPE (min));
     877        52588 :   m_vrange->set (min, max, kind);
     878        52588 : }
     879              : 
     880              : inline
     881   6694235860 : value_range::~value_range ()
     882              : {
     883   6694235860 :   if (m_vrange)
     884   3116796963 :     m_vrange->~vrange ();
     885   6694235860 : }
     886              : 
     887              : // Initialize object to an UNDEFINED range that can hold ranges of
     888              : // TYPE.  Clean-up memory if there was a previous object.
     889              : // Note that this does *not* set the type of the underlying vrange.
     890              : 
     891              : inline void
     892     91997243 : value_range::set_range_class (tree type)
     893              : {
     894     91997243 :   if (m_vrange)
     895      8597821 :     m_vrange->~vrange ();
     896     91997243 :   init (type);
     897     91997243 : }
     898              : 
     899              : // Initialize object to an UNDEFINED range that can hold ranges of
     900              : // TYPE.
     901              : // Note that this does *not* set the type of the underlying vrange.
     902              : 
     903              : inline void
     904   3169630701 : value_range::init (tree type)
     905              : {
     906   3169630701 :   gcc_checking_assert (TYPE_P (type));
     907              : 
     908   3169630701 :   if (irange::supports_p (type))
     909   2253111207 :     m_vrange = new (&m_buffer.ints) int_range_max ();
     910    916519494 :   else if (prange::supports_p (type))
     911    735072298 :     m_vrange = new (&m_buffer.pointers) prange ();
     912    181447196 :   else if (frange::supports_p (type))
     913    110533534 :     m_vrange = new (&m_buffer.floats) frange ();
     914              :   else
     915     70913662 :     m_vrange = new (&m_buffer.unsupported) unsupported_range ();
     916   3169630701 : }
     917              : 
     918              : // Initialize object with a copy of R.
     919              : 
     920              : inline void
     921    122727983 : value_range::init (const vrange &r)
     922              : {
     923    122727983 :   if (is_a <irange> (r))
     924     72002210 :     m_vrange = new (&m_buffer.ints) int_range_max (as_a <irange> (r));
     925     50725773 :   else if (is_a <prange> (r))
     926     99756022 :     m_vrange = new (&m_buffer.pointers) prange (as_a <prange> (r));
     927       847762 :   else if (is_a <frange> (r))
     928       370242 :     m_vrange = new (&m_buffer.floats) frange (as_a <frange> (r));
     929              :   else
     930      1325282 :     m_vrange = new (&m_buffer.unsupported)
     931       662641 :       unsupported_range (as_a <unsupported_range> (r));
     932    122727983 : }
     933              : 
     934              : // Assignment operator.  Copying incompatible types is allowed.  That
     935              : // is, assigning an frange to an object holding an irange does the
     936              : // right thing.
     937              : 
     938              : inline vrange &
     939     33236893 : value_range::operator= (const vrange &r)
     940              : {
     941     33236893 :   if (m_vrange)
     942      9405206 :     m_vrange->~vrange ();
     943     33236893 :   init (r);
     944     33236893 :   return *m_vrange;
     945              : }
     946              : 
     947              : inline value_range &
     948      9457766 : value_range::operator= (const value_range &r)
     949              : {
     950              :   // No need to call the m_vrange destructor here, as we will do so in
     951              :   // the assignment below.
     952      1104829 :   *this = *r.m_vrange;
     953      9457766 :   return *this;
     954              : }
     955              : 
     956              : inline bool
     957     24154886 : value_range::operator== (const value_range &r) const
     958              : {
     959     24154886 :   return *m_vrange == *r.m_vrange;
     960              : }
     961              : 
     962              : inline bool
     963     13507246 : value_range::operator!= (const value_range &r) const
     964              : {
     965     13507246 :   return *m_vrange != *r.m_vrange;
     966              : }
     967              : 
     968              : inline
     969   4443225394 : value_range::operator vrange &()
     970              : {
     971   4152110341 :   return *m_vrange;
     972              : }
     973              : 
     974              : inline
     975     43664222 : value_range::operator const vrange &() const
     976              : {
     977     43664222 :   return *m_vrange;
     978              : }
     979              : 
     980              : // Return TRUE if TYPE is supported by the vrange infrastructure.
     981              : 
     982              : inline bool
     983   5832759657 : value_range::supports_type_p (const_tree type)
     984              : {
     985   5832759657 :   return irange::supports_p (type)
     986   1479208076 :     || prange::supports_p (type)
     987    233745257 :     || frange::supports_p (type);
     988              : }
     989              : 
     990              : extern value_range_kind get_legacy_range (const vrange &, tree &min, tree &max);
     991              : extern void dump_value_range (FILE *, const vrange *);
     992              : extern bool vrp_operand_equal_p (const_tree, const_tree);
     993              : inline REAL_VALUE_TYPE frange_val_min (const_tree type);
     994              : inline REAL_VALUE_TYPE frange_val_max (const_tree type);
     995              : 
     996              : // Number of sub-ranges in a range.
     997              : 
     998              : inline unsigned
     999  32782917383 : irange::num_pairs () const
    1000              : {
    1001  10039150799 :   return m_num_ranges;
    1002              : }
    1003              : 
    1004              : inline tree
    1005  11443289970 : irange::type () const
    1006              : {
    1007  11443289970 :   gcc_checking_assert (m_num_ranges > 0);
    1008  11443289970 :   return m_type;
    1009              : }
    1010              : 
    1011              : inline bool
    1012   4950319040 : irange::varying_compatible_p () const
    1013              : {
    1014   4950319040 :   if (m_num_ranges != 1)
    1015              :     return false;
    1016              : 
    1017   3701433587 :   const wide_int &l = m_base[0];
    1018   3701433587 :   const wide_int &u = m_base[1];
    1019   3701433587 :   tree t = m_type;
    1020              : 
    1021   3701433587 :   if (m_kind == VR_VARYING)
    1022              :     return true;
    1023              : 
    1024   3417164677 :   unsigned prec = TYPE_PRECISION (t);
    1025   3417164677 :   signop sign = TYPE_SIGN (t);
    1026   3417164677 :   if (INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
    1027   6834329354 :     return (l == wi::min_value (prec, sign)
    1028   4456867851 :             && u == wi::max_value (prec, sign)
    1029   3423831198 :             && m_bitmask.unknown_p ());
    1030              :   return true;
    1031              : }
    1032              : 
    1033              : inline bool
    1034   1257605593 : vrange::varying_p () const
    1035              : {
    1036   1254341951 :   return m_kind == VR_VARYING;
    1037              : }
    1038              : 
    1039              : inline bool
    1040  18969347556 : vrange::undefined_p () const
    1041              : {
    1042  11195382327 :   return m_kind == VR_UNDEFINED;
    1043              : }
    1044              : 
    1045              : inline bool
    1046    209456994 : irange::zero_p () const
    1047              : {
    1048    197719016 :   return (m_kind == VR_RANGE && m_num_ranges == 1
    1049    384024034 :           && lower_bound (0) == 0
    1050    407176029 :           && upper_bound (0) == 0);
    1051              : }
    1052              : 
    1053              : inline bool
    1054        45016 : irange::nonzero_p () const
    1055              : {
    1056        45016 :   if (undefined_p ())
    1057              :     return false;
    1058              : 
    1059        45016 :   wide_int zero = wi::zero (TYPE_PRECISION (type ()));
    1060        45016 :   return *this == int_range<2> (type (), zero, zero, VR_ANTI_RANGE);
    1061        45016 : }
    1062              : 
    1063              : inline bool
    1064  14887426421 : irange::supports_p (const_tree type)
    1065              : {
    1066  14082081051 :   return INTEGRAL_TYPE_P (type);
    1067              : }
    1068              : 
    1069              : inline bool
    1070     67782746 : irange::contains_p (tree cst) const
    1071              : {
    1072     67782746 :   return contains_p (wi::to_wide (cst));
    1073              : }
    1074              : 
    1075              : inline bool
    1076     35278604 : range_includes_zero_p (const vrange &vr)
    1077              : {
    1078     35278604 :   if (vr.undefined_p ())
    1079              :     return false;
    1080              : 
    1081     35278604 :   if (vr.varying_p ())
    1082              :     return true;
    1083              : 
    1084     26483157 :   return vr.contains_p (build_zero_cst (vr.type ()));
    1085              : }
    1086              : 
    1087              : // Constructors for irange
    1088              : 
    1089              : inline
    1090   5111806029 : irange::irange (wide_int *base, unsigned nranges, bool resizable)
    1091              :   : vrange (VR_IRANGE),
    1092   5111806029 :     m_resizable (resizable),
    1093   5111806029 :     m_max_ranges (nranges)
    1094              : {
    1095   5111806029 :   m_base = base;
    1096   5111806029 :   set_undefined ();
    1097              : }
    1098              : 
    1099              : // Constructors for int_range<>.
    1100              : 
    1101              : template<unsigned N, bool RESIZABLE>
    1102              : inline
    1103   3837377548 : int_range<N, RESIZABLE>::int_range ()
    1104  26191638808 :   : irange (m_ranges, N, RESIZABLE)
    1105              : {
    1106   3837377548 : }
    1107              : 
    1108              : template<unsigned N, bool RESIZABLE>
    1109       411046 : int_range<N, RESIZABLE>::int_range (const int_range &other)
    1110      2877314 :   : irange (m_ranges, N, RESIZABLE)
    1111              : {
    1112       411046 :   irange::operator= (other);
    1113       411046 : }
    1114              : 
    1115              : template<unsigned N, bool RESIZABLE>
    1116              : int_range<N, RESIZABLE>::int_range (tree min, tree max, value_range_kind kind)
    1117              :   : irange (m_ranges, N, RESIZABLE)
    1118              : {
    1119              :   irange::set (min, max, kind);
    1120              : }
    1121              : 
    1122              : template<unsigned N, bool RESIZABLE>
    1123    151583530 : int_range<N, RESIZABLE>::int_range (tree type)
    1124    595367694 :   : irange (m_ranges, N, RESIZABLE)
    1125              : {
    1126    151583530 :   set_varying (type);
    1127    151583530 : }
    1128              : 
    1129              : template<unsigned N, bool RESIZABLE>
    1130    748892634 : int_range<N, RESIZABLE>::int_range (tree type, const wide_int &wmin, const wide_int &wmax,
    1131              :                          value_range_kind kind)
    1132   2611861682 :   : irange (m_ranges, N, RESIZABLE)
    1133              : {
    1134    748892634 :   set (type, wmin, wmax, kind);
    1135    748892634 : }
    1136              : 
    1137              : template<unsigned N, bool RESIZABLE>
    1138    373541271 : int_range<N, RESIZABLE>::int_range (const irange &other)
    1139   2402021225 :   : irange (m_ranges, N, RESIZABLE)
    1140              : {
    1141    373541271 :   irange::operator= (other);
    1142    373541271 : }
    1143              : 
    1144              : template<unsigned N, bool RESIZABLE>
    1145              : int_range<N, RESIZABLE>&
    1146     63504897 : int_range<N, RESIZABLE>::operator= (const int_range &src)
    1147              : {
    1148     63497289 :   irange::operator= (src);
    1149          357 :   return *this;
    1150              : }
    1151              : 
    1152              : inline void
    1153   5470569206 : irange::set_undefined ()
    1154              : {
    1155   5470569206 :   m_kind = VR_UNDEFINED;
    1156   5116530232 :   m_num_ranges = 0;
    1157    358763173 : }
    1158              : 
    1159              : inline void
    1160   1168231030 : irange::set_varying (tree type)
    1161              : {
    1162   1168231030 :   m_kind = VR_VARYING;
    1163   1168231030 :   m_num_ranges = 1;
    1164   1168231030 :   m_bitmask.set_unknown (TYPE_PRECISION (type));
    1165              : 
    1166   1168231030 :   if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
    1167              :     {
    1168   1168231030 :       m_type = type;
    1169              :       // Strict enum's require varying to be not TYPE_MIN/MAX, but rather
    1170              :       // min_value and max_value.
    1171   1168231030 :       m_base[0] = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
    1172   1168243888 :       m_base[1] = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
    1173              :     }
    1174              :   else
    1175            0 :     m_type = error_mark_node;
    1176   1168231030 : }
    1177              : 
    1178              : // Return the lower bound of a sub-range.  PAIR is the sub-range in
    1179              : // question.
    1180              : 
    1181              : inline wide_int
    1182  11290696574 : irange::lower_bound (unsigned pair) const
    1183              : {
    1184  11290696574 :   gcc_checking_assert (m_num_ranges > 0);
    1185  11290696574 :   gcc_checking_assert (pair + 1 <= num_pairs ());
    1186  11290696574 :   return m_base[pair * 2];
    1187              : }
    1188              : 
    1189              : // Return the upper bound of a sub-range.  PAIR is the sub-range in
    1190              : // question.
    1191              : 
    1192              : inline wide_int
    1193  12891072826 : irange::upper_bound (unsigned pair) const
    1194              : {
    1195  12891072826 :   gcc_checking_assert (m_num_ranges > 0);
    1196  12891072826 :   gcc_checking_assert (pair + 1 <= num_pairs ());
    1197  12891072826 :   return m_base[pair * 2 + 1];
    1198              : }
    1199              : 
    1200              : // Return the highest bound of a range.
    1201              : 
    1202              : inline wide_int
    1203   3514417724 : irange::upper_bound () const
    1204              : {
    1205   3514417724 :   unsigned pairs = num_pairs ();
    1206   3514417724 :   gcc_checking_assert (pairs > 0);
    1207   3514417724 :   return upper_bound (pairs - 1);
    1208              : }
    1209              : 
    1210              : // Set value range VR to a nonzero range of type TYPE.
    1211              : 
    1212              : inline void
    1213      3556318 : irange::set_nonzero (tree type)
    1214              : {
    1215      3556318 :   unsigned prec = TYPE_PRECISION (type);
    1216              : 
    1217      3556318 :   if (TYPE_UNSIGNED (type))
    1218              :     {
    1219      3160533 :       m_type = type;
    1220      3160533 :       m_kind = VR_RANGE;
    1221      3160533 :       m_base[0] = wi::one (prec);
    1222      3160533 :       m_base[1] = wi::minus_one (prec);
    1223      3160533 :       m_bitmask.set_unknown (prec);
    1224      3160533 :       m_num_ranges = 1;
    1225              : 
    1226      3160533 :       if (flag_checking)
    1227      3160533 :         verify_range ();
    1228              :     }
    1229              :   else
    1230              :     {
    1231       395785 :       wide_int zero = wi::zero (prec);
    1232       395785 :       set (type, zero, zero, VR_ANTI_RANGE);
    1233       395785 :     }
    1234      3556318 : }
    1235              : 
    1236              : // Set value range VR to a ZERO range of type TYPE.
    1237              : 
    1238              : inline void
    1239      3390284 : irange::set_zero (tree type)
    1240              : {
    1241      3390284 :   wide_int zero = wi::zero (TYPE_PRECISION (type));
    1242      3390284 :   set (type, zero, zero);
    1243      3390284 : }
    1244              : 
    1245              : // Normalize a range to VARYING or UNDEFINED if possible.
    1246              : 
    1247              : inline void
    1248    550184428 : irange::normalize_kind ()
    1249              : {
    1250    550184428 :   if (m_num_ranges == 0)
    1251        18868 :     set_undefined ();
    1252    550165560 :   else if (varying_compatible_p ())
    1253              :     {
    1254     26787635 :       if (m_kind == VR_RANGE)
    1255      6517364 :         m_kind = VR_VARYING;
    1256     20270271 :       else if (m_kind == VR_ANTI_RANGE)
    1257            0 :         set_undefined ();
    1258              :     }
    1259    550184428 :   if (flag_checking)
    1260    550183632 :     verify_range ();
    1261    550184428 : }
    1262              : 
    1263              : inline bool
    1264     25863924 : contains_zero_p (const irange &r)
    1265              : {
    1266     25863924 :   if (r.undefined_p ())
    1267              :     return false;
    1268              : 
    1269     25863924 :   wide_int zero = wi::zero (TYPE_PRECISION (r.type ()));
    1270     25863924 :   return r.contains_p (zero);
    1271     25863924 : }
    1272              : 
    1273              : inline wide_int
    1274     87804162 : irange_val_min (const_tree type)
    1275              : {
    1276     87804162 :   gcc_checking_assert (irange::supports_p (type));
    1277     87804162 :   return wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
    1278              : }
    1279              : 
    1280              : inline wide_int
    1281     85361406 : irange_val_max (const_tree type)
    1282              : {
    1283     85361406 :   gcc_checking_assert (irange::supports_p (type));
    1284     85361406 :   return wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
    1285              : }
    1286              : 
    1287              : inline
    1288    889348777 : prange::prange ()
    1289    889348777 :   : vrange (VR_PRANGE)
    1290              : {
    1291    889348777 :   set_undefined ();
    1292              : }
    1293              : 
    1294              : inline
    1295    120118064 : prange::prange (const prange &r)
    1296    120118064 :   : vrange (VR_PRANGE)
    1297              : {
    1298    120118064 :   *this = r;
    1299              : }
    1300              : 
    1301              : inline
    1302     12250216 : prange::prange (tree type)
    1303     12250216 :   : vrange (VR_PRANGE)
    1304              : {
    1305     12250216 :   set_varying (type);
    1306              : }
    1307              : 
    1308              : inline
    1309      3064025 : prange::prange (tree type, const wide_int &lb, const wide_int &ub,
    1310      3064025 :                 value_range_kind kind)
    1311      3064025 :   : vrange (VR_PRANGE)
    1312              : {
    1313      3064025 :   set (type, lb, ub, kind);
    1314              : }
    1315              : 
    1316              : inline bool
    1317   3584264326 : prange::supports_p (const_tree type)
    1318              : {
    1319   3584264326 :   return POINTER_TYPE_P (type);
    1320              : }
    1321              : 
    1322              : inline bool
    1323    434246854 : prange::supports_type_p (const_tree type) const
    1324              : {
    1325    434246854 :   return POINTER_TYPE_P (type);
    1326              : }
    1327              : 
    1328              : inline void
    1329   1016033035 : prange::set_undefined ()
    1330              : {
    1331   1016033019 :   m_kind = VR_UNDEFINED;
    1332    126282658 : }
    1333              : 
    1334              : inline void
    1335    426377868 : prange::set_varying (tree type)
    1336              : {
    1337    426377868 :   m_kind = VR_VARYING;
    1338    426377868 :   m_type = type;
    1339    426377868 :   m_min = wi::zero (TYPE_PRECISION (type));
    1340    426377868 :   m_max = wi::max_value (TYPE_PRECISION (type), UNSIGNED);
    1341    426377868 :   m_bitmask.set_unknown (TYPE_PRECISION (type));
    1342              : 
    1343    426377868 :   if (flag_checking)
    1344    426377844 :     verify_range ();
    1345    426377868 : }
    1346              : 
    1347              : inline void
    1348    209265813 : prange::set_nonzero (tree type)
    1349              : {
    1350    209265813 :   m_kind = VR_RANGE;
    1351    209265813 :   m_type = type;
    1352    209265813 :   m_min = wi::one (TYPE_PRECISION (type));
    1353    209265813 :   m_max = wi::max_value (TYPE_PRECISION (type), UNSIGNED);
    1354    209265813 :   m_bitmask.set_unknown (TYPE_PRECISION (type));
    1355              : 
    1356    209265813 :   if (flag_checking)
    1357    209265552 :     verify_range ();
    1358    209265813 : }
    1359              : 
    1360              : inline void
    1361      1459901 : prange::set_zero (tree type)
    1362              : {
    1363      1459901 :   m_kind = VR_RANGE;
    1364      1459901 :   m_type = type;
    1365      1459901 :   wide_int zero = wi::zero (TYPE_PRECISION (type));
    1366      1459901 :   m_min = m_max = zero;
    1367      1459901 :   m_bitmask = irange_bitmask (zero, zero);
    1368              : 
    1369      1459901 :   if (flag_checking)
    1370      1459901 :     verify_range ();
    1371      1459901 : }
    1372              : 
    1373              : inline bool
    1374       593412 : prange::contains_p (tree cst) const
    1375              : {
    1376       593412 :   return contains_p (wi::to_wide (cst));
    1377              : }
    1378              : 
    1379              : inline bool
    1380    121982864 : prange::zero_p () const
    1381              : {
    1382    121982864 :   return m_kind == VR_RANGE && m_min == 0 && m_max == 0;
    1383              : }
    1384              : 
    1385              : inline bool
    1386    168009695 : prange::nonzero_p () const
    1387              : {
    1388    168009695 :   return m_kind == VR_RANGE && m_min == 1 && m_max == -1;
    1389              : }
    1390              : 
    1391              : inline tree
    1392   1939709432 : prange::type () const
    1393              : {
    1394   1939709432 :   gcc_checking_assert (!undefined_p ());
    1395   1939709432 :   return m_type;
    1396              : }
    1397              : 
    1398              : inline wide_int
    1399    301832706 : prange::lower_bound () const
    1400              : {
    1401    301832706 :   gcc_checking_assert (!undefined_p ());
    1402    301832706 :   return m_min;
    1403              : }
    1404              : 
    1405              : inline wide_int
    1406    289712427 : prange::upper_bound () const
    1407              : {
    1408    289712427 :   gcc_checking_assert (!undefined_p ());
    1409    289712427 :   return m_max;
    1410              : }
    1411              : 
    1412              : inline bool
    1413   1191155134 : prange::varying_compatible_p () const
    1414              : {
    1415   1191155134 :   return (!undefined_p ()
    1416   1665557643 :           && m_min == 0 && m_max == -1 && get_bitmask ().unknown_p ());
    1417              : }
    1418              : 
    1419              : inline irange_bitmask
    1420    642610553 : prange::get_bitmask () const
    1421              : {
    1422    642610553 :   return m_bitmask;
    1423              : }
    1424              : 
    1425              : inline bool
    1426            0 : prange::fits_p (const vrange &) const
    1427              : {
    1428            0 :   return true;
    1429              : }
    1430              : 
    1431              : 
    1432              : inline
    1433    113188904 : frange::frange ()
    1434    113188904 :   : vrange (VR_FRANGE)
    1435              : {
    1436    113188868 :   set_undefined ();
    1437              : }
    1438              : 
    1439              : inline
    1440      2857481 : frange::frange (const frange &src)
    1441      2857481 :   : vrange (VR_FRANGE)
    1442              : {
    1443      2452223 :   *this = src;
    1444              : }
    1445              : 
    1446              : inline
    1447       769398 : frange::frange (tree type)
    1448       769398 :   : vrange (VR_FRANGE)
    1449              : {
    1450       769398 :   set_varying (type);
    1451              : }
    1452              : 
    1453              : // frange constructor from REAL_VALUE_TYPE endpoints.
    1454              : 
    1455              : inline
    1456     47657858 : frange::frange (tree type,
    1457              :                 const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
    1458     47657350 :                 value_range_kind kind)
    1459     47657858 :   : vrange (VR_FRANGE)
    1460              : {
    1461     47657858 :   set (type, min, max, kind);
    1462              : }
    1463              : 
    1464              : // frange constructor from trees.
    1465              : 
    1466              : inline
    1467              : frange::frange (tree min, tree max, value_range_kind kind)
    1468              :   : vrange (VR_FRANGE)
    1469              : {
    1470              :   set (min, max, kind);
    1471              : }
    1472              : 
    1473              : inline tree
    1474     74010319 : frange::type () const
    1475              : {
    1476     74010319 :   gcc_checking_assert (!undefined_p ());
    1477     74010319 :   return m_type;
    1478              : }
    1479              : 
    1480              : inline void
    1481     68979767 : frange::set_varying (tree type)
    1482              : {
    1483     68979767 :   m_kind = VR_VARYING;
    1484     68979767 :   m_type = type;
    1485     68979767 :   m_min = frange_val_min (type);
    1486     68979767 :   m_max = frange_val_max (type);
    1487     68979767 :   if (HONOR_NANS (m_type))
    1488              :     {
    1489     65022601 :       m_pos_nan = true;
    1490     65022601 :       m_neg_nan = true;
    1491              :     }
    1492              :   else
    1493              :     {
    1494      3957166 :       m_pos_nan = false;
    1495      3957166 :       m_neg_nan = false;
    1496              :     }
    1497     68979767 : }
    1498              : 
    1499              : inline void
    1500    130932508 : frange::set_undefined ()
    1501              : {
    1502    130932508 :   m_kind = VR_UNDEFINED;
    1503    130932508 :   m_type = NULL;
    1504    130932508 :   m_pos_nan = false;
    1505    130932508 :   m_neg_nan = false;
    1506              :   // m_min and m_min are uninitialized as they are REAL_VALUE_TYPE ??.
    1507    130932508 :   if (flag_checking)
    1508    130932508 :     verify_range ();
    1509    130932508 : }
    1510              : 
    1511              : // Set the NAN bits to NAN and adjust the range.
    1512              : 
    1513              : inline void
    1514      6294235 : frange::update_nan (const nan_state &nan)
    1515              : {
    1516      6294235 :   gcc_checking_assert (!undefined_p ());
    1517      6294235 :   if (HONOR_NANS (m_type))
    1518              :     {
    1519      6293726 :       m_pos_nan = nan.pos_p ();
    1520      6293726 :       m_neg_nan = nan.neg_p ();
    1521      6293726 :       normalize_kind ();
    1522      6293726 :       if (flag_checking)
    1523      6293726 :         verify_range ();
    1524              :     }
    1525      6294235 : }
    1526              : 
    1527              : // Set the NAN bit to +-NAN.
    1528              : 
    1529              : inline void
    1530      4335841 : frange::update_nan ()
    1531              : {
    1532      4335841 :   gcc_checking_assert (!undefined_p ());
    1533      4335841 :   nan_state nan (true);
    1534      4335841 :   update_nan (nan);
    1535      4335841 : }
    1536              : 
    1537              : // Like above, but set the sign of the NAN.
    1538              : 
    1539              : inline void
    1540      1958394 : frange::update_nan (bool sign)
    1541              : {
    1542      1958394 :   gcc_checking_assert (!undefined_p ());
    1543      1958394 :   nan_state nan (/*pos=*/!sign, /*neg=*/sign);
    1544      1958394 :   update_nan (nan);
    1545      1958394 : }
    1546              : 
    1547              : inline bool
    1548            0 : frange::contains_p (tree cst) const
    1549              : {
    1550            0 :   return contains_p (*TREE_REAL_CST_PTR (cst));
    1551              : }
    1552              : 
    1553              : // Clear the NAN bit and adjust the range.
    1554              : 
    1555              : inline void
    1556     14544394 : frange::clear_nan ()
    1557              : {
    1558     14544394 :   gcc_checking_assert (!undefined_p ());
    1559     14544394 :   m_pos_nan = false;
    1560     14544394 :   m_neg_nan = false;
    1561     14544394 :   normalize_kind ();
    1562     14544394 :   if (flag_checking)
    1563     14544394 :     verify_range ();
    1564     14544394 : }
    1565              : 
    1566              : // Set R to maximum representable value for TYPE.
    1567              : 
    1568              : inline REAL_VALUE_TYPE
    1569     23379478 : real_max_representable (const_tree type)
    1570              : {
    1571     23379478 :   REAL_VALUE_TYPE r;
    1572     23379478 :   char buf[128];
    1573     23379478 :   get_max_float (REAL_MODE_FORMAT (TYPE_MODE (type)),
    1574              :                  buf, sizeof (buf), false);
    1575     23379478 :   int res = real_from_string (&r, buf);
    1576     23379478 :   gcc_checking_assert (!res);
    1577     23379478 :   return r;
    1578              : }
    1579              : 
    1580              : // Return the minimum representable value for TYPE.
    1581              : 
    1582              : inline REAL_VALUE_TYPE
    1583     12083553 : real_min_representable (const_tree type)
    1584              : {
    1585     12083553 :   REAL_VALUE_TYPE r = real_max_representable (type);
    1586     12083553 :   r = real_value_negate (&r);
    1587     12083553 :   return r;
    1588              : }
    1589              : 
    1590              : // Return the minimum value for TYPE.
    1591              : 
    1592              : inline REAL_VALUE_TYPE
    1593    179866299 : frange_val_min (const_tree type)
    1594              : {
    1595    179866299 :   if (HONOR_INFINITIES (type))
    1596    169178416 :     return dconstninf;
    1597              :   else
    1598     10687883 :     return real_min_representable (type);
    1599              : }
    1600              : 
    1601              : // Return the maximum value for TYPE.
    1602              : 
    1603              : inline REAL_VALUE_TYPE
    1604    127327019 : frange_val_max (const_tree type)
    1605              : {
    1606    127327019 :   if (HONOR_INFINITIES (type))
    1607    117508839 :     return dconstinf;
    1608              :   else
    1609      9818180 :     return real_max_representable (type);
    1610              : }
    1611              : 
    1612              : // Return TRUE if R is the minimum value for TYPE.
    1613              : 
    1614              : inline bool
    1615    107458641 : frange_val_is_min (const REAL_VALUE_TYPE &r, const_tree type)
    1616              : {
    1617    107458641 :   REAL_VALUE_TYPE min = frange_val_min (type);
    1618    107458641 :   return real_identical (&min, &r);
    1619              : }
    1620              : 
    1621              : // Return TRUE if R is the max value for TYPE.
    1622              : 
    1623              : inline bool
    1624     54536123 : frange_val_is_max (const REAL_VALUE_TYPE &r, const_tree type)
    1625              : {
    1626     54536123 :   REAL_VALUE_TYPE max = frange_val_max (type);
    1627     54536123 :   return real_identical (&max, &r);
    1628              : }
    1629              : 
    1630              : // Build a NAN with a state of NAN.
    1631              : 
    1632              : inline void
    1633       324325 : frange::set_nan (tree type, const nan_state &nan)
    1634              : {
    1635       324325 :   gcc_checking_assert (nan.pos_p () || nan.neg_p ());
    1636       324325 :   if (HONOR_NANS (type))
    1637              :     {
    1638       324324 :       m_kind = VR_NAN;
    1639       324324 :       m_type = type;
    1640       324324 :       m_neg_nan = nan.neg_p ();
    1641       324324 :       m_pos_nan = nan.pos_p ();
    1642       324324 :       if (flag_checking)
    1643       324324 :         verify_range ();
    1644              :     }
    1645              :   else
    1646            1 :     set_undefined ();
    1647       324325 : }
    1648              : 
    1649              : // Build a signless NAN of type TYPE.
    1650              : 
    1651              : inline void
    1652       147017 : frange::set_nan (tree type)
    1653              : {
    1654       147017 :   nan_state nan (true);
    1655       147005 :   set_nan (type, nan);
    1656       125029 : }
    1657              : 
    1658              : // Build a NAN of type TYPE with SIGN.
    1659              : 
    1660              : inline void
    1661       177305 : frange::set_nan (tree type, bool sign)
    1662              : {
    1663       177305 :   nan_state nan (/*pos=*/!sign, /*neg=*/sign);
    1664       177301 :   set_nan (type, nan);
    1665        21657 : }
    1666              : 
    1667              : // Return TRUE if range is known to be finite.
    1668              : 
    1669              : inline bool
    1670            0 : frange::known_isfinite () const
    1671              : {
    1672            0 :   if (undefined_p () || varying_p () || m_kind == VR_ANTI_RANGE)
    1673              :     return false;
    1674            0 :   return (!maybe_isnan () && !real_isinf (&m_min) && !real_isinf (&m_max));
    1675              : }
    1676              : 
    1677              : // Return TRUE if range is known to be normal.
    1678              : 
    1679              : inline bool
    1680            0 : frange::known_isnormal () const
    1681              : {
    1682            0 :   if (!known_isfinite ())
    1683              :     return false;
    1684              : 
    1685            0 :   machine_mode mode = TYPE_MODE (type ());
    1686            0 :   return (!real_isdenormal (&m_min, mode) && !real_isdenormal (&m_max, mode)
    1687            0 :           && !real_iszero (&m_min) && !real_iszero (&m_max)
    1688            0 :           && (!real_isneg (&m_min) || real_isneg (&m_max)));
    1689              : }
    1690              : 
    1691              : // Return TRUE if range is known to be denormal.
    1692              : 
    1693              : inline bool
    1694            0 : frange::known_isdenormal_or_zero () const
    1695              : {
    1696            0 :   if (!known_isfinite ())
    1697              :     return false;
    1698              : 
    1699            0 :   machine_mode mode = TYPE_MODE (type ());
    1700            0 :   return ((real_isdenormal (&m_min, mode) || real_iszero (&m_min))
    1701            0 :           && (real_isdenormal (&m_max, mode) || real_iszero (&m_max)));
    1702              : }
    1703              : 
    1704              : // Return TRUE if range may be infinite.
    1705              : 
    1706              : inline bool
    1707        34061 : frange::maybe_isinf () const
    1708              : {
    1709        34061 :   if (undefined_p () || m_kind == VR_ANTI_RANGE || m_kind == VR_NAN)
    1710              :     return false;
    1711        34061 :   if (varying_p ())
    1712              :     return true;
    1713        31999 :   return real_isinf (&m_min) || real_isinf (&m_max);
    1714              : }
    1715              : 
    1716              : // Return TRUE if range is known to be the [-INF,-INF] or [+INF,+INF].
    1717              : 
    1718              : inline bool
    1719      6050269 : frange::known_isinf () const
    1720              : {
    1721      6050269 :   return (m_kind == VR_RANGE
    1722      8513621 :           && !maybe_isnan ()
    1723      1231667 :           && real_identical (&m_min, &m_max)
    1724      6068022 :           && real_isinf (&m_min));
    1725              : }
    1726              : 
    1727              : // Return TRUE if range is possibly a NAN.
    1728              : 
    1729              : inline bool
    1730     23164715 : frange::maybe_isnan () const
    1731              : {
    1732     21478363 :   if (undefined_p ())
    1733              :     return false;
    1734     23160913 :   return m_pos_nan || m_neg_nan;
    1735              : }
    1736              : 
    1737              : // Return TRUE if range is possibly a NAN with SIGN.
    1738              : 
    1739              : inline bool
    1740       157193 : frange::maybe_isnan (bool sign) const
    1741              : {
    1742       157193 :   if (undefined_p ())
    1743              :     return false;
    1744       157193 :   if (sign)
    1745       157193 :     return m_neg_nan;
    1746              :   return m_pos_nan;
    1747              : }
    1748              : 
    1749              : // Return TRUE if range is a +NAN or -NAN.
    1750              : 
    1751              : inline bool
    1752     17193382 : frange::known_isnan () const
    1753              : {
    1754     13227022 :   return m_kind == VR_NAN;
    1755              : }
    1756              : 
    1757              : // If the signbit for the range is known, set it in SIGNBIT and return
    1758              : // TRUE.
    1759              : 
    1760              : inline bool
    1761      1824195 : frange::signbit_p (bool &signbit) const
    1762              : {
    1763      1824195 :   if (undefined_p ())
    1764              :     return false;
    1765              : 
    1766              :   // NAN with unknown sign.
    1767      1824177 :   if (m_pos_nan && m_neg_nan)
    1768              :     return false;
    1769              :   // No NAN.
    1770       129796 :   if (!m_pos_nan && !m_neg_nan)
    1771              :     {
    1772       108836 :       if (m_min.sign == m_max.sign)
    1773              :         {
    1774        12783 :           signbit = m_min.sign;
    1775        12783 :           return true;
    1776              :         }
    1777              :       return false;
    1778              :     }
    1779              :   // NAN with known sign.
    1780        20960 :   bool nan_sign = m_neg_nan;
    1781        20960 :   if (known_isnan ()
    1782        20960 :       || (nan_sign == m_min.sign && nan_sign == m_max.sign))
    1783              :     {
    1784        19594 :       signbit = nan_sign;
    1785        19594 :       return true;
    1786              :     }
    1787              :   return false;
    1788              : }
    1789              : 
    1790              : // If range has a NAN with a known sign, set it in SIGNBIT and return
    1791              : // TRUE.
    1792              : 
    1793              : inline bool
    1794        51230 : frange::nan_signbit_p (bool &signbit) const
    1795              : {
    1796        51230 :   if (undefined_p ())
    1797              :     return false;
    1798              : 
    1799        51230 :   if (m_pos_nan == m_neg_nan)
    1800              :     return false;
    1801              : 
    1802         2410 :   signbit = m_neg_nan;
    1803         2410 :   return true;
    1804              : }
    1805              : 
    1806              : void frange_nextafter (enum machine_mode, REAL_VALUE_TYPE &,
    1807              :                        const REAL_VALUE_TYPE &);
    1808              : void frange_arithmetic (enum tree_code, tree, REAL_VALUE_TYPE &,
    1809              :                         const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
    1810              :                         const REAL_VALUE_TYPE &);
    1811              : 
    1812              : // Return true if TYPE1 and TYPE2 are compatible range types.
    1813              : 
    1814              : inline bool
    1815   1581479556 : range_compatible_p (tree type1, tree type2)
    1816              : {
    1817              :   // types_compatible_p requires conversion in both directions to be useless.
    1818              :   // GIMPLE only requires a cast one way in order to be compatible.
    1819              :   // Ranges really only need the sign and precision to be the same.
    1820   1581479556 :   return (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
    1821   1581479556 :           && TYPE_SIGN (type1) == TYPE_SIGN (type2));
    1822              : }
    1823              : #endif // GCC_VALUE_RANGE_H
        

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.