diff options
Diffstat (limited to 'gcc/value-range.h')
-rw-r--r-- | gcc/value-range.h | 51 |
1 files changed, 23 insertions, 28 deletions
diff --git a/gcc/value-range.h b/gcc/value-range.h index 760ee77..7428c91 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -111,8 +111,7 @@ protected: void irange_set (tree, tree); void irange_set_anti_range (tree, tree); - bool swap_out_of_order_endpoints (tree &min, tree &max, value_range_kind &); - bool normalize_min_max (tree type, tree min, tree max, value_range_kind); + void normalize_min_max (); bool legacy_mode_p () const; bool legacy_equal_p (const irange &) const; @@ -281,12 +280,14 @@ irange::varying_p () const tree l = m_base[0]; tree u = m_base[1]; tree t = TREE_TYPE (l); + unsigned prec = TYPE_PRECISION (t); + signop sign = TYPE_SIGN (t); if (INTEGRAL_TYPE_P (t)) - return l == TYPE_MIN_VALUE (t) && u == TYPE_MAX_VALUE (t); + return (wi::to_wide (l) == wi::min_value (prec, sign) + && wi::to_wide (u) == wi::max_value (prec, sign)); if (POINTER_TYPE_P (t)) - return wi::to_wide (l) == 0 - && wi::to_wide (u) == wi::max_value (TYPE_PRECISION (t), - TYPE_SIGN (t)); + return (wi::to_wide (l) == 0 + && wi::to_wide (u) == wi::max_value (prec, sign)); return true; } @@ -470,8 +471,10 @@ irange::set_varying (tree type) m_num_ranges = 1; if (INTEGRAL_TYPE_P (type)) { - m_base[0] = TYPE_MIN_VALUE (type); - m_base[1] = TYPE_MAX_VALUE (type); + wide_int min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type)); + wide_int max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type)); + m_base[0] = wide_int_to_tree (type, min); + m_base[1] = wide_int_to_tree (type, max); } else if (POINTER_TYPE_P (type)) { @@ -566,33 +569,25 @@ irange::set_zero (tree type) irange_set (z, z); } -// Normalize [MIN, MAX] into VARYING and ~[MIN, MAX] into UNDEFINED. -// -// Avoid using TYPE_{MIN,MAX}_VALUE because -fstrict-enums can -// restrict those to a subset of what actually fits in the type. -// Instead use the extremes of the type precision which will allow -// compare_range_with_value() to check if a value is inside a range, -// whereas if we used TYPE_*_VAL, said function would just punt upon -// seeing a VARYING. +// Normalize a range to VARYING or UNDEFINED if possible. -inline bool -irange::normalize_min_max (tree type, tree min, tree max, - value_range_kind kind) +inline void +irange::normalize_min_max () { - unsigned prec = TYPE_PRECISION (type); - signop sign = TYPE_SIGN (type); - if (wi::eq_p (wi::to_wide (min), wi::min_value (prec, sign)) - && wi::eq_p (wi::to_wide (max), wi::max_value (prec, sign))) + gcc_checking_assert (legacy_mode_p ()); + gcc_checking_assert (!undefined_p ()); + unsigned prec = TYPE_PRECISION (type ()); + signop sign = TYPE_SIGN (type ()); + if (wi::eq_p (wi::to_wide (min ()), wi::min_value (prec, sign)) + && wi::eq_p (wi::to_wide (max ()), wi::max_value (prec, sign))) { - if (kind == VR_RANGE) - set_varying (type); - else if (kind == VR_ANTI_RANGE) + if (m_kind == VR_RANGE) + set_varying (type ()); + else if (m_kind == VR_ANTI_RANGE) set_undefined (); else gcc_unreachable (); - return true; } - return false; } // Return the maximum value for TYPE. |