Handle non constant ranges in irange pretty printer.

Technically iranges only exist in constant form, but we allow symbolic
ones before arriving in the ranger, so legacy VRP can work.  This fixes the
ICE when attempting to print symbolic iranges in the pretty printer.

For consistency's sake, I have made sure irange::get_nonzero_bits does
not similarly ICE on a symbolic range, even though no one should be
querying nonzero bits on such a range.  This should all melt away
when legacy disappears, because all these methods are slated for
removal (min, max, kind, symbolic_p, constant_p, etc).

Finally, Richi suggested using pp_wide_int in the pretty printer
instead of going through trees.  I've adapted a test, since
dump_generic_node seems to work slightly different.

	PR tree-optimization/106444

gcc/ChangeLog:

	* value-range-pretty-print.cc (vrange_printer::visit): Handle
	legacy ranges.
	(vrange_printer::print_irange_bound): Work on wide_int's.
	* value-range-pretty-print.h (print_irange_bound): Same.
	* value-range.cc (irange::get_nonzero_bits): Handle legacy ranges.

gcc/testsuite/ChangeLog:

	* gcc.dg/tree-ssa/evrp4.c: Adjust.
This commit is contained in:
Aldy Hernandez 2022-07-26 11:03:17 +02:00
parent 67248ad043
commit 2615502971
4 changed files with 30 additions and 15 deletions

View File

@ -17,4 +17,4 @@ int bar (struct st *s)
foo (&s->a);
}
/* { dg-final { scan-tree-dump "\\\[1B, \\+INF\\\]" "evrp" } } */
/* { dg-final { scan-tree-dump "\\\[1, \\+INF\\\]" "evrp" } } */

View File

@ -63,38 +63,45 @@ vrange_printer::visit (const irange &r) const
pp_string (pp, "VARYING");
return;
}
for (unsigned i = 0; i < r.num_pairs (); ++i)
// Handle legacy symbolics.
if (!r.constant_p ())
{
tree lb = wide_int_to_tree (r.type (), r.lower_bound (i));
tree ub = wide_int_to_tree (r.type (), r.upper_bound (i));
if (r.kind () == VR_ANTI_RANGE)
pp_character (pp, '~');
pp_character (pp, '[');
print_irange_bound (lb);
dump_generic_node (pp, r.min (), 0, TDF_NONE, false);
pp_string (pp, ", ");
print_irange_bound (ub);
dump_generic_node (pp, r.max (), 0, TDF_NONE, false);
pp_character (pp, ']');
print_irange_bitmasks (r);
return;
}
for (unsigned i = 0; i < r.num_pairs (); ++i)
{
pp_character (pp, '[');
print_irange_bound (r.lower_bound (i), r.type ());
pp_string (pp, ", ");
print_irange_bound (r.upper_bound (i), r.type ());
pp_character (pp, ']');
}
print_irange_bitmasks (r);
}
void
vrange_printer::print_irange_bound (tree bound) const
vrange_printer::print_irange_bound (const wide_int &bound, tree type) const
{
tree type = TREE_TYPE (bound);
wide_int type_min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
wide_int type_max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
if (INTEGRAL_TYPE_P (type)
&& !TYPE_UNSIGNED (type)
&& TREE_CODE (bound) == INTEGER_CST
&& wi::to_wide (bound) == type_min
&& bound == type_min
&& TYPE_PRECISION (type) != 1)
pp_string (pp, "-INF");
else if (TREE_CODE (bound) == INTEGER_CST
&& wi::to_wide (bound) == type_max
&& TYPE_PRECISION (type) != 1)
else if (bound == type_max && TYPE_PRECISION (type) != 1)
pp_string (pp, "+INF");
else
dump_generic_node (pp, bound, 0, TDF_NONE, false);
pp_wide_int (pp, bound, TYPE_SIGN (type));
}
void

View File

@ -29,7 +29,7 @@ public:
void visit (const irange &) const override;
void visit (const frange &) const override;
private:
void print_irange_bound (tree bound) const;
void print_irange_bound (const wide_int &w, tree type) const;
void print_irange_bitmasks (const irange &) const;
void print_frange_prop (const char *str, const fp_prop &) const;

View File

@ -2593,6 +2593,14 @@ irange::get_nonzero_bits () const
{
gcc_checking_assert (!undefined_p ());
// In case anyone in the legacy world queries us.
if (!constant_p ())
{
if (m_nonzero_mask)
return wi::to_wide (m_nonzero_mask);
return wi::shwi (-1, TYPE_PRECISION (type ()));
}
// Calculate the nonzero bits inherent in the range.
wide_int min = lower_bound ();
wide_int max = upper_bound ();