1 /* Support routines for value ranges.
2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
3 Contributed by Aldy Hernandez <aldyh@redhat.com> and
4 Andrew Macleod <amacleod@redhat.com>.
6 This file is part of GCC.
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)
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.
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/>. */
22 #ifndef GCC_VALUE_RANGE_H
23 #define GCC_VALUE_RANGE_H
27 // Types of value ranges.
32 /* Range spans the entire domain. */
34 /* Range is [MIN, MAX]. */
36 /* Range is ~[MIN, MAX]. */
40 /* Range is a nice guy. */
44 // Discriminator between different vrange types.
46 enum value_range_discriminator
48 // Range holds an integer or pointer.
50 // Floating point range.
52 // Range holds an unsupported type.
56 // Abstract class for ranges of any of the supported types.
58 // To query what types ranger and the entire ecosystem can support,
59 // use Value_Range::supports_type_p(tree type). This is a static
60 // method available independently of any vrange object.
62 // To query what a given vrange variant can support, use:
63 // irange::supports_p ()
64 // frange::supports_p ()
67 // To query what a range object can support, use:
68 // void foo (vrange &v, irange &i, frange &f)
70 // if (v.supports_type_p (type)) ...
71 // if (i.supports_type_p (type)) ...
72 // if (f.supports_type_p (type)) ...
75 class GTY((user
)) vrange
77 template <typename T
> friend bool is_a (vrange
&);
78 friend class Value_Range
;
80 virtual void accept (const class vrange_visitor
&v
) const = 0;
81 virtual void set (tree
, tree
, value_range_kind
= VR_RANGE
);
82 virtual tree
type () const;
83 virtual bool supports_type_p (const_tree type
) const;
84 virtual void set_varying (tree type
);
85 virtual void set_undefined ();
86 virtual bool union_ (const vrange
&);
87 virtual bool intersect (const vrange
&);
88 virtual bool singleton_p (tree
*result
= NULL
) const;
89 virtual bool contains_p (tree cst
) const;
90 virtual bool zero_p () const;
91 virtual bool nonzero_p () const;
92 virtual void set_nonzero (tree type
);
93 virtual void set_zero (tree type
);
94 virtual void set_nonnegative (tree type
);
95 virtual bool fits_p (const vrange
&r
) const;
97 bool varying_p () const;
98 bool undefined_p () const;
99 vrange
& operator= (const vrange
&);
100 bool operator== (const vrange
&) const;
101 bool operator!= (const vrange
&r
) const { return !(*this == r
); }
102 void dump (FILE *) const;
104 enum value_range_kind
kind () const; // DEPRECATED
107 vrange (enum value_range_discriminator d
) : m_discriminator (d
) { }
108 ENUM_BITFIELD(value_range_kind
) m_kind
: 8;
109 const ENUM_BITFIELD(value_range_discriminator
) m_discriminator
: 4;
114 extern void add_vrange (const vrange
&, hash
&, unsigned flags
= 0);
117 // An integer range without any storage.
119 class GTY((user
)) irange
: public vrange
121 friend value_range_kind
get_legacy_range (const irange
&, tree
&, tree
&);
122 friend class irange_storage
;
125 void set (tree type
, const wide_int
&, const wide_int
&,
126 value_range_kind
= VR_RANGE
);
127 virtual void set_nonzero (tree type
) override
;
128 virtual void set_zero (tree type
) override
;
129 virtual void set_nonnegative (tree type
) override
;
130 virtual void set_varying (tree type
) override
;
131 virtual void set_undefined () override
;
134 static bool supports_p (const_tree type
);
135 virtual bool supports_type_p (const_tree type
) const override
;
136 virtual tree
type () const override
;
138 // Iteration over sub-ranges.
139 unsigned num_pairs () const;
140 wide_int
lower_bound (unsigned = 0) const;
141 wide_int
upper_bound (unsigned) const;
142 wide_int
upper_bound () const;
145 virtual bool zero_p () const override
;
146 virtual bool nonzero_p () const override
;
147 virtual bool singleton_p (tree
*result
= NULL
) const override
;
148 bool singleton_p (wide_int
&) const;
149 bool contains_p (const wide_int
&) const;
151 // In-place operators.
152 virtual bool union_ (const vrange
&) override
;
153 virtual bool intersect (const vrange
&) override
;
156 // Operator overloads.
157 irange
& operator= (const irange
&);
158 bool operator== (const irange
&) const;
159 bool operator!= (const irange
&r
) const { return !(*this == r
); }
162 virtual bool fits_p (const vrange
&r
) const override
;
163 virtual void accept (const vrange_visitor
&v
) const override
;
166 wide_int
get_nonzero_bits () const;
167 void set_nonzero_bits (const wide_int
&bits
);
170 void maybe_resize (int needed
);
171 virtual void set (tree
, tree
, value_range_kind
= VR_RANGE
) override
;
172 virtual bool contains_p (tree cst
) const override
;
173 irange (wide_int
*, unsigned nranges
, bool resizable
);
175 // In-place operators.
176 bool irange_contains_p (const irange
&) const;
177 bool irange_single_pair_union (const irange
&r
);
179 void normalize_kind ();
181 void verify_range ();
183 // Hard limit on max ranges allowed.
184 static const int HARD_MAX_RANGES
= 255;
186 friend void gt_ggc_mx (irange
*);
187 friend void gt_pch_nx (irange
*);
188 friend void gt_pch_nx (irange
*, gt_pointer_operator
, void *);
190 bool varying_compatible_p () const;
191 bool intersect_nonzero_bits (const irange
&r
);
192 bool union_nonzero_bits (const irange
&r
);
193 wide_int
get_nonzero_bits_from_range () const;
194 bool set_range_from_nonzero_bits ();
196 bool intersect (const wide_int
& lb
, const wide_int
& ub
);
197 unsigned char m_num_ranges
;
199 unsigned char m_max_ranges
;
201 wide_int m_nonzero_mask
;
206 // Here we describe an irange with N pairs of ranges. The storage for
207 // the pairs is embedded in the class as an array.
209 // If RESIZABLE is true, the storage will be resized on the heap when
210 // the number of ranges needed goes past N up to a max of
211 // HARD_MAX_RANGES. This new storage is freed upon destruction.
213 template<unsigned N
, bool RESIZABLE
= false>
214 class GTY((user
)) int_range
: public irange
218 int_range (tree type
, const wide_int
&, const wide_int
&,
219 value_range_kind
= VR_RANGE
);
220 int_range (tree type
);
221 int_range (const int_range
&);
222 int_range (const irange
&);
223 virtual ~int_range ();
224 int_range
& operator= (const int_range
&);
226 int_range (tree
, tree
, value_range_kind
= VR_RANGE
);
228 wide_int m_ranges
[N
*2];
231 // Unsupported temporaries may be created by ranger before it's known
232 // they're unsupported, or by vr_values::get_value_range.
234 class unsupported_range
: public vrange
238 : vrange (VR_UNKNOWN
)
242 virtual void set_undefined () final override
244 m_kind
= VR_UNDEFINED
;
246 virtual void accept (const vrange_visitor
&v
) const override
;
249 // The NAN state as an opaque object.
255 nan_state (bool pos_nan
, bool neg_nan
);
263 // Set NAN state to +-NAN if NAN_P is true. Otherwise set NAN state
267 nan_state::nan_state (bool nan_p
)
273 // Constructor initializing the object to +NAN if POS_NAN is set, -NAN
274 // if NEG_NAN is set, or +-NAN if both are set. Otherwise POS_NAN and
275 // NEG_NAN are clear, and the object cannot be a NAN.
278 nan_state::nan_state (bool pos_nan
, bool neg_nan
)
284 // Return if +NAN is possible.
287 nan_state::pos_p () const
292 // Return if -NAN is possible.
295 nan_state::neg_p () const
300 // A floating point range.
302 // The representation is a type with a couple of endpoints, unioned
303 // with the set of { -NAN, +Nan }.
305 class GTY((user
)) frange
: public vrange
307 friend class frange_storage
;
308 friend class vrange_printer
;
309 friend void gt_ggc_mx (frange
*);
310 friend void gt_pch_nx (frange
*);
311 friend void gt_pch_nx (frange
*, gt_pointer_operator
, void *);
314 frange (const frange
&);
315 frange (tree
, tree
, value_range_kind
= VR_RANGE
);
317 frange (tree type
, const REAL_VALUE_TYPE
&min
, const REAL_VALUE_TYPE
&max
,
318 value_range_kind
= VR_RANGE
);
319 static bool supports_p (const_tree type
)
321 // ?? Decimal floats can have multiple representations for the
322 // same number. Supporting them may be as simple as just
323 // disabling them in singleton_p. No clue.
324 return SCALAR_FLOAT_TYPE_P (type
) && !DECIMAL_FLOAT_TYPE_P (type
);
326 virtual tree
type () const override
;
327 void set (tree type
, const REAL_VALUE_TYPE
&, const REAL_VALUE_TYPE
&,
328 value_range_kind
= VR_RANGE
);
329 void set (tree type
, const REAL_VALUE_TYPE
&, const REAL_VALUE_TYPE
&,
330 const nan_state
&, value_range_kind
= VR_RANGE
);
331 void set_nan (tree type
);
332 void set_nan (tree type
, bool sign
);
333 virtual void set_varying (tree type
) override
;
334 virtual void set_undefined () override
;
335 virtual bool union_ (const vrange
&) override
;
336 virtual bool intersect (const vrange
&) override
;
337 bool contains_p (const REAL_VALUE_TYPE
&) const;
338 virtual bool singleton_p (tree
*result
= NULL
) const override
;
339 bool singleton_p (REAL_VALUE_TYPE
&r
) const;
340 virtual bool supports_type_p (const_tree type
) const override
;
341 virtual void accept (const vrange_visitor
&v
) const override
;
342 virtual bool zero_p () const override
;
343 virtual bool nonzero_p () const override
;
344 virtual void set_nonzero (tree type
) override
;
345 virtual void set_zero (tree type
) override
;
346 virtual void set_nonnegative (tree type
) override
;
347 frange
& operator= (const frange
&);
348 bool operator== (const frange
&) const;
349 bool operator!= (const frange
&r
) const { return !(*this == r
); }
350 const REAL_VALUE_TYPE
&lower_bound () const;
351 const REAL_VALUE_TYPE
&upper_bound () const;
352 nan_state
get_nan_state () const;
354 void update_nan (bool sign
);
355 void update_nan (tree
) = delete; // Disallow silent conversion to bool.
356 void update_nan (const nan_state
&);
358 void flush_denormals_to_zero ();
360 // fpclassify like API
361 bool known_isfinite () const;
362 bool known_isnan () const;
363 bool known_isinf () const;
364 bool maybe_isnan () const;
365 bool maybe_isnan (bool sign
) const;
366 bool maybe_isinf () const;
367 bool signbit_p (bool &signbit
) const;
368 bool nan_signbit_p (bool &signbit
) const;
371 virtual bool contains_p (tree cst
) const override
;
372 virtual void set (tree
, tree
, value_range_kind
= VR_RANGE
) override
;
375 bool internal_singleton_p (REAL_VALUE_TYPE
* = NULL
) const;
376 void verify_range ();
377 bool normalize_kind ();
378 bool union_nans (const frange
&);
379 bool intersect_nans (const frange
&);
380 bool combine_zeros (const frange
&, bool union_p
);
383 REAL_VALUE_TYPE m_min
;
384 REAL_VALUE_TYPE m_max
;
389 inline const REAL_VALUE_TYPE
&
390 frange::lower_bound () const
392 gcc_checking_assert (!undefined_p () && !known_isnan ());
396 inline const REAL_VALUE_TYPE
&
397 frange::upper_bound () const
399 gcc_checking_assert (!undefined_p () && !known_isnan ());
403 // Return the NAN state.
406 frange::get_nan_state () const
408 return nan_state (m_pos_nan
, m_neg_nan
);
411 // is_a<> and as_a<> implementation for vrange.
413 // Anything we haven't specialized is a hard fail.
414 template <typename T
>
422 template <typename T
>
424 is_a (const vrange
&v
)
426 // Reuse is_a <vrange> to implement the const version.
427 const T
&derived
= static_cast<const T
&> (v
);
428 return is_a
<T
> (const_cast<T
&> (derived
));
431 template <typename T
>
435 gcc_checking_assert (is_a
<T
> (v
));
436 return static_cast <T
&> (v
);
439 template <typename T
>
441 as_a (const vrange
&v
)
443 gcc_checking_assert (is_a
<T
> (v
));
444 return static_cast <const T
&> (v
);
447 // Specializations for the different range types.
451 is_a
<irange
> (vrange
&v
)
453 return v
.m_discriminator
== VR_IRANGE
;
458 is_a
<frange
> (vrange
&v
)
460 return v
.m_discriminator
== VR_FRANGE
;
465 is_a
<unsupported_range
> (vrange
&v
)
467 return v
.m_discriminator
== VR_UNKNOWN
;
470 // For resizable ranges, resize the range up to HARD_MAX_RANGES if the
471 // NEEDED pairs is greater than the current capacity of the range.
474 irange::maybe_resize (int needed
)
476 if (!m_resizable
|| m_max_ranges
== HARD_MAX_RANGES
)
479 if (needed
> m_max_ranges
)
481 m_max_ranges
= HARD_MAX_RANGES
;
482 wide_int
*newmem
= new wide_int
[m_max_ranges
* 2];
483 memcpy (newmem
, m_base
, sizeof (wide_int
) * num_pairs () * 2);
488 template<unsigned N
, bool RESIZABLE
>
490 int_range
<N
, RESIZABLE
>::~int_range ()
492 if (RESIZABLE
&& m_base
!= m_ranges
)
496 // This is an "infinite" precision irange for use in temporary
497 // calculations. It starts with a sensible default covering 99% of
498 // uses, and goes up to HARD_MAX_RANGES when needed. Any allocated
499 // storage is freed upon destruction.
500 typedef int_range
<3, /*RESIZABLE=*/true> int_range_max
;
505 virtual void visit (const irange
&) const { }
506 virtual void visit (const frange
&) const { }
507 virtual void visit (const unsupported_range
&) const { }
510 typedef int_range
<2> value_range
;
512 // This is an "infinite" precision range object for use in temporary
513 // calculations for any of the handled types. The object can be
514 // transparently used as a vrange.
520 Value_Range (const vrange
&r
);
521 Value_Range (tree type
);
522 Value_Range (tree
, tree
, value_range_kind kind
= VR_RANGE
);
523 Value_Range (const Value_Range
&);
524 void set_type (tree type
);
525 vrange
& operator= (const vrange
&);
526 Value_Range
& operator= (const Value_Range
&);
527 bool operator== (const Value_Range
&r
) const;
528 bool operator!= (const Value_Range
&r
) const;
530 operator const vrange
&() const;
531 void dump (FILE *) const;
532 static bool supports_type_p (const_tree type
);
534 // Convenience methods for vrange compatibility.
535 tree
type () { return m_vrange
->type (); }
536 bool varying_p () const { return m_vrange
->varying_p (); }
537 bool undefined_p () const { return m_vrange
->undefined_p (); }
538 void set_varying (tree type
) { m_vrange
->set_varying (type
); }
539 void set_undefined () { m_vrange
->set_undefined (); }
540 bool union_ (const vrange
&r
) { return m_vrange
->union_ (r
); }
541 bool intersect (const vrange
&r
) { return m_vrange
->intersect (r
); }
542 bool contains_p (tree cst
) const { return m_vrange
->contains_p (cst
); }
543 bool singleton_p (tree
*result
= NULL
) const
544 { return m_vrange
->singleton_p (result
); }
545 void set_zero (tree type
) { return m_vrange
->set_zero (type
); }
546 void set_nonzero (tree type
) { return m_vrange
->set_nonzero (type
); }
547 bool nonzero_p () const { return m_vrange
->nonzero_p (); }
548 bool zero_p () const { return m_vrange
->zero_p (); }
549 wide_int
lower_bound () const; // For irange/prange comparability.
550 wide_int
upper_bound () const; // For irange/prange comparability.
551 void accept (const vrange_visitor
&v
) const { m_vrange
->accept (v
); }
553 void init (tree type
);
554 unsupported_range m_unsupported
;
556 int_range_max m_irange
;
561 Value_Range::Value_Range ()
563 m_vrange
= &m_unsupported
;
566 // Copy constructor from a vrange.
569 Value_Range::Value_Range (const vrange
&r
)
574 // Copy constructor from a TYPE. The range of the temporary is set to
578 Value_Range::Value_Range (tree type
)
584 Value_Range::Value_Range (tree min
, tree max
, value_range_kind kind
)
586 init (TREE_TYPE (min
));
587 m_vrange
->set (min
, max
, kind
);
591 Value_Range::Value_Range (const Value_Range
&r
)
596 // Initialize object so it is possible to store temporaries of TYPE
600 Value_Range::init (tree type
)
602 gcc_checking_assert (TYPE_P (type
));
604 if (irange::supports_p (type
))
605 m_vrange
= &m_irange
;
606 else if (frange::supports_p (type
))
607 m_vrange
= &m_frange
;
609 m_vrange
= &m_unsupported
;
612 // Set the temporary to allow storing temporaries of TYPE. The range
613 // of the temporary is set to UNDEFINED.
616 Value_Range::set_type (tree type
)
619 m_vrange
->set_undefined ();
622 // Assignment operator for temporaries. Copying incompatible types is
626 Value_Range::operator= (const vrange
&r
)
628 if (is_a
<irange
> (r
))
630 m_irange
= as_a
<irange
> (r
);
631 m_vrange
= &m_irange
;
633 else if (is_a
<frange
> (r
))
635 m_frange
= as_a
<frange
> (r
);
636 m_vrange
= &m_frange
;
638 else if (is_a
<unsupported_range
> (r
))
640 m_unsupported
= as_a
<unsupported_range
> (r
);
641 m_vrange
= &m_unsupported
;
650 Value_Range::operator= (const Value_Range
&r
)
652 if (r
.m_vrange
== &r
.m_irange
)
654 m_irange
= r
.m_irange
;
655 m_vrange
= &m_irange
;
657 else if (r
.m_vrange
== &r
.m_frange
)
659 m_frange
= r
.m_frange
;
660 m_vrange
= &m_frange
;
662 else if (r
.m_vrange
== &r
.m_unsupported
)
664 m_unsupported
= r
.m_unsupported
;
665 m_vrange
= &m_unsupported
;
674 Value_Range::operator== (const Value_Range
&r
) const
676 return *m_vrange
== *r
.m_vrange
;
680 Value_Range::operator!= (const Value_Range
&r
) const
682 return *m_vrange
!= *r
.m_vrange
;
686 Value_Range::operator vrange
&()
692 Value_Range::operator const vrange
&() const
697 // Return TRUE if TYPE is supported by the vrange infrastructure.
700 Value_Range::supports_type_p (const_tree type
)
702 return irange::supports_p (type
) || frange::supports_p (type
);
705 extern value_range_kind
get_legacy_range (const irange
&, tree
&min
, tree
&max
);
706 extern void dump_value_range (FILE *, const vrange
*);
707 extern bool vrp_operand_equal_p (const_tree
, const_tree
);
708 inline REAL_VALUE_TYPE
frange_val_min (const_tree type
);
709 inline REAL_VALUE_TYPE
frange_val_max (const_tree type
);
711 // Number of sub-ranges in a range.
714 irange::num_pairs () const
720 irange::type () const
722 gcc_checking_assert (m_num_ranges
> 0);
727 irange::varying_compatible_p () const
729 if (m_num_ranges
!= 1)
732 const wide_int
&l
= m_base
[0];
733 const wide_int
&u
= m_base
[1];
736 if (m_kind
== VR_VARYING
&& t
== error_mark_node
)
739 unsigned prec
= TYPE_PRECISION (t
);
740 signop sign
= TYPE_SIGN (t
);
741 if (INTEGRAL_TYPE_P (t
) || POINTER_TYPE_P (t
))
742 return (l
== wi::min_value (prec
, sign
)
743 && u
== wi::max_value (prec
, sign
)
744 && m_nonzero_mask
== -1);
749 vrange::varying_p () const
751 return m_kind
== VR_VARYING
;
755 vrange::undefined_p () const
757 return m_kind
== VR_UNDEFINED
;
761 irange::zero_p () const
763 return (m_kind
== VR_RANGE
&& m_num_ranges
== 1
764 && lower_bound (0) == 0
765 && upper_bound (0) == 0);
769 irange::nonzero_p () const
774 wide_int zero
= wi::zero (TYPE_PRECISION (type ()));
775 return *this == int_range
<2> (type (), zero
, zero
, VR_ANTI_RANGE
);
779 irange::supports_p (const_tree type
)
781 return INTEGRAL_TYPE_P (type
) || POINTER_TYPE_P (type
);
785 irange::contains_p (tree cst
) const
787 return contains_p (wi::to_wide (cst
));
791 range_includes_zero_p (const irange
*vr
)
793 if (vr
->undefined_p ())
796 if (vr
->varying_p ())
799 wide_int zero
= wi::zero (TYPE_PRECISION (vr
->type ()));
800 return vr
->contains_p (zero
);
803 extern void gt_ggc_mx (vrange
*);
804 extern void gt_pch_nx (vrange
*);
805 extern void gt_pch_nx (vrange
*, gt_pointer_operator
, void *);
806 extern void gt_ggc_mx (irange
*);
807 extern void gt_pch_nx (irange
*);
808 extern void gt_pch_nx (irange
*, gt_pointer_operator
, void *);
809 extern void gt_ggc_mx (frange
*);
810 extern void gt_pch_nx (frange
*);
811 extern void gt_pch_nx (frange
*, gt_pointer_operator
, void *);
815 gt_ggc_mx (int_range
<N
> *x
)
817 gt_ggc_mx ((irange
*) x
);
822 gt_pch_nx (int_range
<N
> *x
)
824 gt_pch_nx ((irange
*) x
);
829 gt_pch_nx (int_range
<N
> *x
, gt_pointer_operator op
, void *cookie
)
831 gt_pch_nx ((irange
*) x
, op
, cookie
);
834 // Constructors for irange
837 irange::irange (wide_int
*base
, unsigned nranges
, bool resizable
)
838 : vrange (VR_IRANGE
),
839 m_resizable (resizable
),
840 m_max_ranges (nranges
)
846 // Constructors for int_range<>.
848 template<unsigned N
, bool RESIZABLE
>
850 int_range
<N
, RESIZABLE
>::int_range ()
851 : irange (m_ranges
, N
, RESIZABLE
)
855 template<unsigned N
, bool RESIZABLE
>
856 int_range
<N
, RESIZABLE
>::int_range (const int_range
&other
)
857 : irange (m_ranges
, N
, RESIZABLE
)
859 irange::operator= (other
);
862 template<unsigned N
, bool RESIZABLE
>
863 int_range
<N
, RESIZABLE
>::int_range (tree min
, tree max
, value_range_kind kind
)
864 : irange (m_ranges
, N
, RESIZABLE
)
866 irange::set (min
, max
, kind
);
869 template<unsigned N
, bool RESIZABLE
>
870 int_range
<N
, RESIZABLE
>::int_range (tree type
)
871 : irange (m_ranges
, N
, RESIZABLE
)
876 template<unsigned N
, bool RESIZABLE
>
877 int_range
<N
, RESIZABLE
>::int_range (tree type
, const wide_int
&wmin
, const wide_int
&wmax
,
878 value_range_kind kind
)
879 : irange (m_ranges
, N
, RESIZABLE
)
881 set (type
, wmin
, wmax
, kind
);
884 template<unsigned N
, bool RESIZABLE
>
885 int_range
<N
, RESIZABLE
>::int_range (const irange
&other
)
886 : irange (m_ranges
, N
, RESIZABLE
)
888 irange::operator= (other
);
891 template<unsigned N
, bool RESIZABLE
>
892 int_range
<N
, RESIZABLE
>&
893 int_range
<N
, RESIZABLE
>::operator= (const int_range
&src
)
895 irange::operator= (src
);
900 irange::set_undefined ()
902 m_kind
= VR_UNDEFINED
;
907 irange::set_varying (tree type
)
911 m_nonzero_mask
= wi::minus_one (TYPE_PRECISION (type
));
913 if (INTEGRAL_TYPE_P (type
) || POINTER_TYPE_P (type
))
916 // Strict enum's require varying to be not TYPE_MIN/MAX, but rather
917 // min_value and max_value.
918 m_base
[0] = wi::min_value (TYPE_PRECISION (type
), TYPE_SIGN (type
));
919 m_base
[1] = wi::max_value (TYPE_PRECISION (type
), TYPE_SIGN (type
));
922 m_type
= error_mark_node
;
925 // Return the lower bound of a sub-range. PAIR is the sub-range in
929 irange::lower_bound (unsigned pair
) const
931 gcc_checking_assert (m_num_ranges
> 0);
932 gcc_checking_assert (pair
+ 1 <= num_pairs ());
933 return m_base
[pair
* 2];
936 // Return the upper bound of a sub-range. PAIR is the sub-range in
940 irange::upper_bound (unsigned pair
) const
942 gcc_checking_assert (m_num_ranges
> 0);
943 gcc_checking_assert (pair
+ 1 <= num_pairs ());
944 return m_base
[pair
* 2 + 1];
947 // Return the highest bound of a range.
950 irange::upper_bound () const
952 unsigned pairs
= num_pairs ();
953 gcc_checking_assert (pairs
> 0);
954 return upper_bound (pairs
- 1);
957 // Set value range VR to a nonzero range of type TYPE.
960 irange::set_nonzero (tree type
)
962 unsigned prec
= TYPE_PRECISION (type
);
964 if (TYPE_UNSIGNED (type
))
968 m_base
[0] = wi::one (prec
);
969 m_base
[1] = m_nonzero_mask
= wi::minus_one (prec
);
977 wide_int zero
= wi::zero (prec
);
978 set (type
, zero
, zero
, VR_ANTI_RANGE
);
982 // Set value range VR to a ZERO range of type TYPE.
985 irange::set_zero (tree type
)
987 wide_int zero
= wi::zero (TYPE_PRECISION (type
));
988 set (type
, zero
, zero
);
991 // Normalize a range to VARYING or UNDEFINED if possible.
994 irange::normalize_kind ()
996 if (m_num_ranges
== 0)
998 else if (varying_compatible_p ())
1000 if (m_kind
== VR_RANGE
)
1001 m_kind
= VR_VARYING
;
1002 else if (m_kind
== VR_ANTI_RANGE
)
1008 contains_zero_p (const irange
&r
)
1010 if (r
.undefined_p ())
1013 wide_int zero
= wi::zero (TYPE_PRECISION (r
.type ()));
1014 return r
.contains_p (zero
);
1018 irange_val_min (const_tree type
)
1020 gcc_checking_assert (irange::supports_p (type
));
1021 return wi::min_value (TYPE_PRECISION (type
), TYPE_SIGN (type
));
1025 irange_val_max (const_tree type
)
1027 gcc_checking_assert (irange::supports_p (type
));
1028 return wi::max_value (TYPE_PRECISION (type
), TYPE_SIGN (type
));
1033 : vrange (VR_FRANGE
)
1039 frange::frange (const frange
&src
)
1040 : vrange (VR_FRANGE
)
1046 frange::frange (tree type
)
1047 : vrange (VR_FRANGE
)
1052 // frange constructor from REAL_VALUE_TYPE endpoints.
1055 frange::frange (tree type
,
1056 const REAL_VALUE_TYPE
&min
, const REAL_VALUE_TYPE
&max
,
1057 value_range_kind kind
)
1058 : vrange (VR_FRANGE
)
1060 set (type
, min
, max
, kind
);
1063 // frange constructor from trees.
1066 frange::frange (tree min
, tree max
, value_range_kind kind
)
1067 : vrange (VR_FRANGE
)
1069 set (min
, max
, kind
);
1073 frange::type () const
1075 gcc_checking_assert (!undefined_p ());
1080 frange::set_varying (tree type
)
1082 m_kind
= VR_VARYING
;
1084 m_min
= frange_val_min (type
);
1085 m_max
= frange_val_max (type
);
1086 if (HONOR_NANS (m_type
))
1099 frange::set_undefined ()
1101 m_kind
= VR_UNDEFINED
;
1105 // m_min and m_min are uninitialized as they are REAL_VALUE_TYPE ??.
1110 // Set the NAN bit and adjust the range.
1113 frange::update_nan ()
1115 gcc_checking_assert (!undefined_p ());
1116 if (HONOR_NANS (m_type
))
1126 // Like above, but set the sign of the NAN.
1129 frange::update_nan (bool sign
)
1131 gcc_checking_assert (!undefined_p ());
1132 if (HONOR_NANS (m_type
))
1143 frange::contains_p (tree cst
) const
1145 return contains_p (*TREE_REAL_CST_PTR (cst
));
1148 // Clear the NAN bit and adjust the range.
1151 frange::clear_nan ()
1153 gcc_checking_assert (!undefined_p ());
1161 // Set R to maximum representable value for TYPE.
1163 inline REAL_VALUE_TYPE
1164 real_max_representable (const_tree type
)
1168 get_max_float (REAL_MODE_FORMAT (TYPE_MODE (type
)),
1169 buf
, sizeof (buf
), false);
1170 int res
= real_from_string (&r
, buf
);
1171 gcc_checking_assert (!res
);
1175 // Return the minimum representable value for TYPE.
1177 inline REAL_VALUE_TYPE
1178 real_min_representable (const_tree type
)
1180 REAL_VALUE_TYPE r
= real_max_representable (type
);
1181 r
= real_value_negate (&r
);
1185 // Return the minimum value for TYPE.
1187 inline REAL_VALUE_TYPE
1188 frange_val_min (const_tree type
)
1190 if (HONOR_INFINITIES (type
))
1193 return real_min_representable (type
);
1196 // Return the maximum value for TYPE.
1198 inline REAL_VALUE_TYPE
1199 frange_val_max (const_tree type
)
1201 if (HONOR_INFINITIES (type
))
1204 return real_max_representable (type
);
1207 // Return TRUE if R is the minimum value for TYPE.
1210 frange_val_is_min (const REAL_VALUE_TYPE
&r
, const_tree type
)
1212 REAL_VALUE_TYPE min
= frange_val_min (type
);
1213 return real_identical (&min
, &r
);
1216 // Return TRUE if R is the max value for TYPE.
1219 frange_val_is_max (const REAL_VALUE_TYPE
&r
, const_tree type
)
1221 REAL_VALUE_TYPE max
= frange_val_max (type
);
1222 return real_identical (&max
, &r
);
1225 // Build a signless NAN of type TYPE.
1228 frange::set_nan (tree type
)
1230 if (HONOR_NANS (type
))
1243 // Build a NAN of type TYPE with SIGN.
1246 frange::set_nan (tree type
, bool sign
)
1248 if (HONOR_NANS (type
))
1261 // Return TRUE if range is known to be finite.
1264 frange::known_isfinite () const
1266 if (undefined_p () || varying_p () || m_kind
== VR_ANTI_RANGE
)
1268 return (!maybe_isnan () && !real_isinf (&m_min
) && !real_isinf (&m_max
));
1271 // Return TRUE if range may be infinite.
1274 frange::maybe_isinf () const
1276 if (undefined_p () || m_kind
== VR_ANTI_RANGE
|| m_kind
== VR_NAN
)
1280 return real_isinf (&m_min
) || real_isinf (&m_max
);
1283 // Return TRUE if range is known to be the [-INF,-INF] or [+INF,+INF].
1286 frange::known_isinf () const
1288 return (m_kind
== VR_RANGE
1290 && real_identical (&m_min
, &m_max
)
1291 && real_isinf (&m_min
));
1294 // Return TRUE if range is possibly a NAN.
1297 frange::maybe_isnan () const
1301 return m_pos_nan
|| m_neg_nan
;
1304 // Return TRUE if range is possibly a NAN with SIGN.
1307 frange::maybe_isnan (bool sign
) const
1316 // Return TRUE if range is a +NAN or -NAN.
1319 frange::known_isnan () const
1321 return m_kind
== VR_NAN
;
1324 // If the signbit for the range is known, set it in SIGNBIT and return
1328 frange::signbit_p (bool &signbit
) const
1333 // NAN with unknown sign.
1334 if (m_pos_nan
&& m_neg_nan
)
1337 if (!m_pos_nan
&& !m_neg_nan
)
1339 if (m_min
.sign
== m_max
.sign
)
1341 signbit
= m_min
.sign
;
1346 // NAN with known sign.
1347 bool nan_sign
= m_neg_nan
;
1349 || (nan_sign
== m_min
.sign
&& nan_sign
== m_max
.sign
))
1357 // If range has a NAN with a known sign, set it in SIGNBIT and return
1361 frange::nan_signbit_p (bool &signbit
) const
1366 if (m_pos_nan
== m_neg_nan
)
1369 signbit
= m_neg_nan
;
1373 void frange_nextafter (enum machine_mode
, REAL_VALUE_TYPE
&,
1374 const REAL_VALUE_TYPE
&);
1375 void frange_arithmetic (enum tree_code
, tree
, REAL_VALUE_TYPE
&,
1376 const REAL_VALUE_TYPE
&, const REAL_VALUE_TYPE
&,
1377 const REAL_VALUE_TYPE
&);
1379 #endif // GCC_VALUE_RANGE_H