Commit ff67aff4 by Richard Sandiford Committed by Jeff Law

re PR tree-optimization/84321 (ice in intersect_range_with_nonzero_bits, at tree-vrp.c:213)

2018-02-12  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	PR tree-optimization/84321
	* tree-vrp.c (intersect_range_with_nonzero_bits): Fix VR_ANTI_RANGE
	handling.  Also check whether the anti-range contains any values
	that satisfy the mask; switch to a VR_RANGE if not.

gcc/testsuite/
	PR tree-optimization/84321
	* gcc.dg/pr84321.c: New test.

From-SVN: r257629
parent 62e12268
2018-02-13 Richard Sandiford <richard.sandiford@linaro.org>
PR tree-optimization/84321
* tree-vrp.c (intersect_range_with_nonzero_bits): Fix VR_ANTI_RANGE
handling. Also check whether the anti-range contains any values
that satisfy the mask; switch to a VR_RANGE if not.
2018-02-13 Paolo Bonzini <bonzini@gnu.org>
PR sanitizer/84340
......
2018-02-12 Richard Sandiford <richard.sandiford@linaro.org>
PR tree-optimization/84321
* gcc.dg/pr84321.c: New test.
2018-02-13 Vladimir Makarov <vmakarov@redhat.com>
PR target/84359
......
/* { dg-do compile } */
/* { dg-options "-O3 -fwrapv" } */
int c;
void
foo (int *a, int b)
{
int e;
if (b == 1)
return;
for (e = 0; e < (b & ~7); e += 8)
;
for (++e; e < b;)
c = a[e];
}
......@@ -184,37 +184,61 @@ intersect_range_with_nonzero_bits (enum value_range_type vr_type,
const wide_int &nonzero_bits,
signop sgn)
{
if (vr_type == VR_RANGE)
{
*max = wi::round_down_for_mask (*max, nonzero_bits);
/* Check that the range contains at least one valid value. */
if (wi::gt_p (*min, *max, sgn))
return VR_UNDEFINED;
*min = wi::round_up_for_mask (*min, nonzero_bits);
gcc_checking_assert (wi::le_p (*min, *max, sgn));
}
if (vr_type == VR_ANTI_RANGE)
{
*max = wi::round_up_for_mask (*max, nonzero_bits);
/* The VR_ANTI_RANGE is equivalent to the union of the ranges
A: [-INF, *MIN) and B: (*MAX, +INF]. First use NONZERO_BITS
to create an inclusive upper bound for A and an inclusive lower
bound for B. */
wide_int a_max = wi::round_down_for_mask (*min - 1, nonzero_bits);
wide_int b_min = wi::round_up_for_mask (*max + 1, nonzero_bits);
/* If the calculation of A_MAX wrapped, A is effectively empty
and A_MAX is the highest value that satisfies NONZERO_BITS.
Likewise if the calculation of B_MIN wrapped, B is effectively
empty and B_MIN is the lowest value that satisfies NONZERO_BITS. */
bool a_empty = wi::ge_p (a_max, *min, sgn);
bool b_empty = wi::le_p (b_min, *max, sgn);
/* If both A and B are empty, there are no valid values. */
if (a_empty && b_empty)
return VR_UNDEFINED;
/* If the calculation wrapped, we now have a VR_RANGE whose
lower bound is *MAX and whose upper bound is *MIN. */
if (wi::gt_p (*min, *max, sgn))
/* If exactly one of A or B is empty, return a VR_RANGE for the
other one. */
if (a_empty || b_empty)
{
std::swap (*min, *max);
*max = wi::round_down_for_mask (*max, nonzero_bits);
*min = b_min;
*max = a_max;
gcc_checking_assert (wi::le_p (*min, *max, sgn));
return VR_RANGE;
}
*min = wi::round_down_for_mask (*min, nonzero_bits);
/* Update the VR_ANTI_RANGE bounds. */
*min = a_max + 1;
*max = b_min - 1;
gcc_checking_assert (wi::le_p (*min, *max, sgn));
/* Check whether we now have an empty set of values. */
if (*min - 1 == *max)
/* Now check whether the excluded range includes any values that
satisfy NONZERO_BITS. If not, switch to a full VR_RANGE. */
if (wi::round_up_for_mask (*min, nonzero_bits) == b_min)
{
unsigned int precision = min->get_precision ();
*min = wi::min_value (precision, sgn);
*max = wi::max_value (precision, sgn);
vr_type = VR_RANGE;
}
}
if (vr_type == VR_RANGE)
{
*max = wi::round_down_for_mask (*max, nonzero_bits);
/* Check that the range contains at least one valid value. */
if (wi::gt_p (*min, *max, sgn))
return VR_UNDEFINED;
*min = wi::round_up_for_mask (*min, nonzero_bits);
gcc_checking_assert (wi::le_p (*min, *max, sgn));
}
return vr_type;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment