aboutsummaryrefslogtreecommitdiff
path: root/gcc/value-range.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/value-range.h')
-rw-r--r--gcc/value-range.h79
1 files changed, 49 insertions, 30 deletions
diff --git a/gcc/value-range.h b/gcc/value-range.h
index d166362..484f911 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -215,7 +215,7 @@ private:
bool intersect (const wide_int& lb, const wide_int& ub);
unsigned char m_num_ranges;
unsigned char m_max_ranges;
- wide_int m_nonzero_mask;
+ tree m_nonzero_mask;
tree *m_base;
};
@@ -683,11 +683,11 @@ irange::varying_compatible_p () const
if (INTEGRAL_TYPE_P (t))
return (wi::to_wide (l) == wi::min_value (prec, sign)
&& wi::to_wide (u) == wi::max_value (prec, sign)
- && m_nonzero_mask == -1);
+ && (!m_nonzero_mask || wi::to_wide (m_nonzero_mask) == -1));
if (POINTER_TYPE_P (t))
return (wi::to_wide (l) == 0
&& wi::to_wide (u) == wi::max_value (prec, sign)
- && m_nonzero_mask == -1);
+ && (!m_nonzero_mask || wi::to_wide (m_nonzero_mask) == -1));
return true;
}
@@ -754,6 +754,8 @@ gt_ggc_mx (irange *x)
gt_ggc_mx (x->m_base[i * 2]);
gt_ggc_mx (x->m_base[i * 2 + 1]);
}
+ if (x->m_nonzero_mask)
+ gt_ggc_mx (x->m_nonzero_mask);
}
inline void
@@ -764,6 +766,8 @@ gt_pch_nx (irange *x)
gt_pch_nx (x->m_base[i * 2]);
gt_pch_nx (x->m_base[i * 2 + 1]);
}
+ if (x->m_nonzero_mask)
+ gt_pch_nx (x->m_nonzero_mask);
}
inline void
@@ -774,6 +778,8 @@ gt_pch_nx (irange *x, gt_pointer_operator op, void *cookie)
op (&x->m_base[i * 2], NULL, cookie);
op (&x->m_base[i * 2 + 1], NULL, cookie);
}
+ if (x->m_nonzero_mask)
+ op (&x->m_nonzero_mask, NULL, cookie);
}
template<unsigned N>
@@ -868,6 +874,7 @@ irange::set_undefined ()
{
m_kind = VR_UNDEFINED;
m_num_ranges = 0;
+ m_nonzero_mask = NULL;
}
inline void
@@ -875,11 +882,7 @@ irange::set_varying (tree type)
{
m_kind = VR_VARYING;
m_num_ranges = 1;
-
- if (type == error_mark_node)
- m_nonzero_mask = wi::shwi (-1, 1);
- else
- m_nonzero_mask = wi::shwi (-1, TYPE_PRECISION (type));
+ m_nonzero_mask = NULL;
if (INTEGRAL_TYPE_P (type))
{
@@ -1111,11 +1114,14 @@ inline void
frange::update_nan ()
{
gcc_checking_assert (!undefined_p ());
- m_pos_nan = true;
- m_neg_nan = true;
- normalize_kind ();
- if (flag_checking)
- verify_range ();
+ if (HONOR_NANS (m_type))
+ {
+ m_pos_nan = true;
+ m_neg_nan = true;
+ normalize_kind ();
+ if (flag_checking)
+ verify_range ();
+ }
}
// Like above, but set the sign of the NAN.
@@ -1124,11 +1130,14 @@ inline void
frange::update_nan (bool sign)
{
gcc_checking_assert (!undefined_p ());
- m_pos_nan = !sign;
- m_neg_nan = sign;
- normalize_kind ();
- if (flag_checking)
- verify_range ();
+ if (HONOR_NANS (m_type))
+ {
+ m_pos_nan = !sign;
+ m_neg_nan = sign;
+ normalize_kind ();
+ if (flag_checking)
+ verify_range ();
+ }
}
// Clear the NAN bit and adjust the range.
@@ -1213,12 +1222,17 @@ frange_val_is_max (const REAL_VALUE_TYPE &r, const_tree type)
inline void
frange::set_nan (tree type)
{
- m_kind = VR_NAN;
- m_type = type;
- m_pos_nan = true;
- m_neg_nan = true;
- if (flag_checking)
- verify_range ();
+ if (HONOR_NANS (type))
+ {
+ m_kind = VR_NAN;
+ m_type = type;
+ m_pos_nan = true;
+ m_neg_nan = true;
+ if (flag_checking)
+ verify_range ();
+ }
+ else
+ set_undefined ();
}
// Build a NAN of type TYPE with SIGN.
@@ -1226,12 +1240,17 @@ frange::set_nan (tree type)
inline void
frange::set_nan (tree type, bool sign)
{
- m_kind = VR_NAN;
- m_type = type;
- m_neg_nan = sign;
- m_pos_nan = !sign;
- if (flag_checking)
- verify_range ();
+ if (HONOR_NANS (type))
+ {
+ m_kind = VR_NAN;
+ m_type = type;
+ m_neg_nan = sign;
+ m_pos_nan = !sign;
+ if (flag_checking)
+ verify_range ();
+ }
+ else
+ set_undefined ();
}
// Return TRUE if range is known to be finite.