aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2019-08-16 06:54:23 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2019-08-16 06:54:23 +0000
commit97ecc8d5769e947e8659d32be51846d40c90f50c (patch)
tree7451af2bf9f9c04582fba7f75cfc275b2619ddbb /gcc/tree-vrp.c
parente3cfbeaf6b655b9c00d77efb8220a8a16341cb2e (diff)
downloadgcc-97ecc8d5769e947e8659d32be51846d40c90f50c.zip
gcc-97ecc8d5769e947e8659d32be51846d40c90f50c.tar.gz
gcc-97ecc8d5769e947e8659d32be51846d40c90f50c.tar.bz2
Add type to VR_VARYING.
From-SVN: r274561
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c142
1 files changed, 93 insertions, 49 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 77e7594..8067f85 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -186,9 +186,11 @@ value_range_base::check ()
break;
}
case VR_UNDEFINED:
- case VR_VARYING:
gcc_assert (!min () && !max ());
break;
+ case VR_VARYING:
+ gcc_assert (m_min && m_max);
+ break;
default:
gcc_unreachable ();
}
@@ -214,6 +216,10 @@ value_range::check ()
bool
value_range_base::equal_p (const value_range_base &other) const
{
+ /* Ignore types for undefined. All undefines are equal. */
+ if (undefined_p ())
+ return m_kind == other.m_kind;
+
return (m_kind == other.m_kind
&& vrp_operand_equal_p (m_min, other.m_min)
&& vrp_operand_equal_p (m_max, other.m_max));
@@ -269,16 +275,24 @@ value_range::set_undefined ()
}
void
-value_range_base::set_varying ()
+value_range_base::set_varying (tree type)
{
m_kind = VR_VARYING;
- m_min = m_max = NULL;
+ if (supports_type_p (type))
+ {
+ m_min = vrp_val_min (type, true);
+ m_max = vrp_val_max (type, true);
+ }
+ else
+ /* We can't do anything range-wise with these types. */
+ m_min = m_max = error_mark_node;
}
void
-value_range::set_varying ()
+value_range::set_varying (tree type)
{
- set (VR_VARYING, NULL, NULL, NULL);
+ value_range_base::set_varying (type);
+ equiv_clear ();
}
/* Return TRUE if it is possible that range contains VAL. */
@@ -355,9 +369,7 @@ value_range_base::singleton_p (tree *result) const
tree
value_range_base::type () const
{
- /* Types are only valid for VR_RANGE and VR_ANTI_RANGE, which are
- known to have non-zero min/max. */
- gcc_assert (min ());
+ gcc_assert (m_min || undefined_p ());
return TREE_TYPE (min ());
}
@@ -395,12 +407,21 @@ value_range_base::dump (FILE *file) const
fprintf (file, "]");
}
else if (varying_p ())
- fprintf (file, "VARYING");
+ {
+ print_generic_expr (file, type ());
+ fprintf (file, " VARYING");
+ }
else
gcc_unreachable ();
}
void
+value_range_base::dump () const
+{
+ dump (stderr);
+}
+
+void
value_range::dump (FILE *file) const
{
value_range_base::dump (file);
@@ -424,6 +445,12 @@ value_range::dump (FILE *file) const
}
void
+value_range::dump () const
+{
+ dump (stderr);
+}
+
+void
dump_value_range (FILE *file, const value_range *vr)
{
if (!vr)
@@ -658,7 +685,14 @@ value_range_base::set (enum value_range_kind kind, tree min, tree max)
}
else if (kind == VR_VARYING)
{
- set_varying ();
+ gcc_assert (TREE_TYPE (min) == TREE_TYPE (max));
+ tree typ = TREE_TYPE (min);
+ if (supports_type_p (typ))
+ {
+ gcc_assert (vrp_val_min (typ, true));
+ gcc_assert (vrp_val_max (typ, true));
+ }
+ set_varying (typ);
return;
}
@@ -683,7 +717,7 @@ value_range_base::set (enum value_range_kind kind, tree min, tree max)
for VR_ANTI_RANGE empty range, so drop to varying as well. */
if (TYPE_PRECISION (TREE_TYPE (min)) == 1)
{
- set_varying ();
+ set_varying (TREE_TYPE (min));
return;
}
@@ -697,7 +731,7 @@ value_range_base::set (enum value_range_kind kind, tree min, tree max)
to varying in this case. */
if (tree_int_cst_lt (max, min))
{
- set_varying ();
+ set_varying (TREE_TYPE (min));
return;
}
@@ -720,7 +754,7 @@ value_range_base::set (enum value_range_kind kind, tree min, tree max)
{
/* We cannot deal with empty ranges, drop to varying.
??? This could be VR_UNDEFINED instead. */
- set_varying ();
+ set_varying (type);
return;
}
else if (TYPE_PRECISION (TREE_TYPE (min)) == 1
@@ -767,7 +801,7 @@ value_range_base::set (enum value_range_kind kind, tree min, tree max)
&& wi::eq_p (wi::to_wide (max), wi::max_value (prec, sign)))
{
if (kind == VR_RANGE)
- set_varying ();
+ set_varying (type);
else if (kind == VR_ANTI_RANGE)
set_undefined ();
else
@@ -1297,7 +1331,7 @@ extract_range_from_multiplicative_op (value_range_base *vr,
|| code == LSHIFT_EXPR);
if (!range_int_cst_p (vr1))
{
- vr->set_varying ();
+ vr->set_varying (type);
return;
}
@@ -1332,7 +1366,7 @@ extract_range_from_multiplicative_op (value_range_base *vr,
vr->set (VR_RANGE, wide_int_to_tree (type, res_lb),
wide_int_to_tree (type, res_ub));
else
- vr->set_varying ();
+ vr->set_varying (type);
}
/* If BOUND will include a symbolic bound, adjust it accordingly,
@@ -1541,7 +1575,7 @@ extract_range_from_binary_expr (value_range_base *vr,
if (!INTEGRAL_TYPE_P (expr_type)
&& !POINTER_TYPE_P (expr_type))
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -1565,7 +1599,7 @@ extract_range_from_binary_expr (value_range_base *vr,
&& code != BIT_IOR_EXPR
&& code != BIT_XOR_EXPR)
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -1580,9 +1614,9 @@ extract_range_from_binary_expr (value_range_base *vr,
have UNDEFINED result for all or some value-ranges of the not UNDEFINED
operand. */
else if (vr0.undefined_p ())
- vr0.set_varying ();
+ vr0.set_varying (expr_type);
else if (vr1.undefined_p ())
- vr1.set_varying ();
+ vr1.set_varying (expr_type);
/* We get imprecise results from ranges_from_anti_range when
code is EXACT_DIV_EXPR. We could mask out bits in the resulting
@@ -1654,7 +1688,7 @@ extract_range_from_binary_expr (value_range_base *vr,
|| vr0.symbolic_p ()
|| vr1.symbolic_p ()))
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -1672,7 +1706,7 @@ extract_range_from_binary_expr (value_range_base *vr,
else if (vr0.zero_p () && vr1.zero_p ())
vr->set_zero (expr_type);
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
}
else if (code == POINTER_PLUS_EXPR)
{
@@ -1701,7 +1735,7 @@ extract_range_from_binary_expr (value_range_base *vr,
else if (vr0.zero_p () && vr1.zero_p ())
vr->set_zero (expr_type);
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
}
else if (code == BIT_AND_EXPR)
{
@@ -1712,10 +1746,10 @@ extract_range_from_binary_expr (value_range_base *vr,
else if (vr0.zero_p () || vr1.zero_p ())
vr->set_zero (expr_type);
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
}
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -1793,7 +1827,7 @@ extract_range_from_binary_expr (value_range_base *vr,
if (((bool)min_ovf && sym_min_op0 != sym_min_op1)
|| ((bool)max_ovf && sym_max_op0 != sym_max_op1))
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -1804,7 +1838,7 @@ extract_range_from_binary_expr (value_range_base *vr,
wmin, wmax, min_ovf, max_ovf);
if (type == VR_VARYING)
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -1830,7 +1864,7 @@ extract_range_from_binary_expr (value_range_base *vr,
a single range or anti-range as the above is
[-INF+1, +INF(OVF)] intersected with ~[5, 5]
but one could use a scheme similar to equivalences for this. */
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
}
@@ -1847,7 +1881,7 @@ extract_range_from_binary_expr (value_range_base *vr,
vr->set (VR_RANGE, wide_int_to_tree (expr_type, wmin),
wide_int_to_tree (expr_type, wmax));
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
else if (code == MULT_EXPR)
@@ -1855,7 +1889,7 @@ extract_range_from_binary_expr (value_range_base *vr,
if (!range_int_cst_p (&vr0)
|| !range_int_cst_p (&vr1))
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
extract_range_from_multiplicative_op (vr, code, expr_type, &vr0, &vr1);
@@ -1895,7 +1929,7 @@ extract_range_from_binary_expr (value_range_base *vr,
}
}
}
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
else if (code == TRUNC_DIV_EXPR
@@ -1932,7 +1966,7 @@ extract_range_from_binary_expr (value_range_base *vr,
TYPE_OVERFLOW_UNDEFINED (expr_type),
extra_range_p, extra_min, extra_max))
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
vr->set (VR_RANGE, wide_int_to_tree (expr_type, wmin),
@@ -1991,7 +2025,7 @@ extract_range_from_binary_expr (value_range_base *vr,
vr->set (VR_RANGE, min, max);
}
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
else if (code == BIT_IOR_EXPR)
@@ -2009,7 +2043,7 @@ extract_range_from_binary_expr (value_range_base *vr,
vr->set (VR_RANGE, min, max);
}
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
else if (code == BIT_XOR_EXPR)
@@ -2025,7 +2059,7 @@ extract_range_from_binary_expr (value_range_base *vr,
vr->set (VR_RANGE, min, max);
}
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
}
@@ -2039,7 +2073,7 @@ extract_range_from_binary_expr (value_range_base *vr,
|| max == NULL_TREE
|| TREE_OVERFLOW_P (max))
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -2048,7 +2082,7 @@ extract_range_from_binary_expr (value_range_base *vr,
Note that we do accept [-INF, -INF] and [+INF, +INF]. */
if (vrp_val_is_min (min) && vrp_val_is_max (max))
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -2058,7 +2092,7 @@ extract_range_from_binary_expr (value_range_base *vr,
/* If the new range has its limits swapped around (MIN > MAX),
then the operation caused one of them to wrap around, mark
the new range VARYING. */
- vr->set_varying ();
+ vr->set_varying (expr_type);
}
else
vr->set (type, min, max);
@@ -2084,7 +2118,7 @@ extract_range_from_unary_expr (value_range_base *vr,
|| !(INTEGRAL_TYPE_P (type)
|| POINTER_TYPE_P (type)))
{
- vr->set_varying ();
+ vr->set_varying (type);
return;
}
@@ -2156,7 +2190,7 @@ extract_range_from_unary_expr (value_range_base *vr,
else if (vr0.zero_p ())
vr->set_zero (type);
else
- vr->set_varying ();
+ vr->set_varying (type);
return;
}
@@ -2190,7 +2224,7 @@ extract_range_from_unary_expr (value_range_base *vr,
vr->set (VR_RANGE, min, max);
}
else
- vr->set_varying ();
+ vr->set_varying (outer_type);
return;
}
else if (code == ABS_EXPR)
@@ -2203,7 +2237,7 @@ extract_range_from_unary_expr (value_range_base *vr,
vr->set (VR_RANGE, wide_int_to_tree (type, wmin),
wide_int_to_tree (type, wmax));
else
- vr->set_varying ();
+ vr->set_varying (type);
return;
}
else if (code == ABSU_EXPR)
@@ -2219,7 +2253,7 @@ extract_range_from_unary_expr (value_range_base *vr,
}
/* For unhandled operations fall back to varying. */
- vr->set_varying ();
+ vr->set_varying (type);
return;
}
@@ -6100,7 +6134,12 @@ value_range_base::intersect_helper (const value_range_base *vr0,
VR_RANGE can still be a VR_RANGE. Work on a temporary so we can
fall back to vr0 when this turns things to varying. */
value_range_base tem;
- tem.set (vr0type, vr0min, vr0max);
+ if (vr0type == VR_UNDEFINED)
+ tem.set_undefined ();
+ else if (vr0type == VR_VARYING)
+ tem.set_varying (vr0->type ());
+ else
+ tem.set (vr0type, vr0min, vr0max);
/* If that failed, use the saved original VR0. */
if (tem.varying_p ())
return *vr0;
@@ -6205,7 +6244,12 @@ value_range_base::union_helper (const value_range_base *vr0,
/* Work on a temporary so we can still use vr0 when union returns varying. */
value_range_base tem;
- tem.set (vr0type, vr0min, vr0max);
+ if (vr0type == VR_UNDEFINED)
+ tem.set_undefined ();
+ else if (vr0type == VR_VARYING)
+ tem.set_varying (vr0->type ());
+ else
+ tem.set (vr0type, vr0min, vr0max);
/* Failed to find an efficient meet. Before giving up and setting
the result to VARYING, see if we can at least derive a useful
@@ -6302,7 +6346,7 @@ value_range_base::normalize_symbolics () const
if (min_symbolic && max_symbolic)
{
value_range_base var;
- var.set_varying ();
+ var.set_varying (ttype);
return var;
}
if (kind () == VR_RANGE)
@@ -6323,7 +6367,7 @@ value_range_base::normalize_symbolics () const
return value_range_base (VR_RANGE, n, vrp_val_max (ttype));
}
value_range_base var;
- var.set_varying ();
+ var.set_varying (ttype);
return var;
}
// ~[NUM, SYM] -> [-MIN, NUM - 1]
@@ -6333,7 +6377,7 @@ value_range_base::normalize_symbolics () const
return value_range_base (VR_RANGE, vrp_val_min (ttype), n);
}
value_range_base var;
- var.set_varying ();
+ var.set_varying (ttype);
return var;
}
@@ -7010,7 +7054,7 @@ determine_value_range_1 (value_range_base *vr, tree expr)
vr->set (kind, wide_int_to_tree (TREE_TYPE (expr), min),
wide_int_to_tree (TREE_TYPE (expr), max));
else
- vr->set_varying ();
+ vr->set_varying (TREE_TYPE (expr));
}
}