[Bug tree-optimization/83073] Range for VR_VARYING | [1, 1]
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Nov 29 15:15:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83073
--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
So for VARYING | 1 we go using the may_be_nonzero stuff in
else if (code == BIT_IOR_EXPR)
{
max = wide_int_to_tree (expr_type,
may_be_nonzero0 | may_be_nonzero1);
wide_int wmin = must_be_nonzero0 | must_be_nonzero1;
/* If the input ranges contain only positive values we can
truncate the minimum of the result range to the maximum
of the input range minima. */
if (int_cst_range0 && int_cst_range1
&& tree_int_cst_sgn (vr0.min) >= 0
&& tree_int_cst_sgn (vr1.min) >= 0)
{
wmin = wi::max (wmin, wi::to_wide (vr0.min),
TYPE_SIGN (expr_type));
wmin = wi::max (wmin, wi::to_wide (vr1.min),
TYPE_SIGN (expr_type));
}
/* If either input range contains only negative values
we can truncate the minimum of the result range to the
respective minimum range. */
if (int_cst_range0 && tree_int_cst_sgn (vr0.max) < 0)
wmin = wi::max (wmin, wi::to_wide (vr0.min),
TYPE_SIGN (expr_type));
if (int_cst_range1 && tree_int_cst_sgn (vr1.max) < 0)
wmin = wi::max (wmin, wi::to_wide (vr1.min),
TYPE_SIGN (expr_type));
min = wide_int_to_tree (expr_type, wmin);
but for [MIN, MAX] we go
/* For op & or | attempt to optimize:
[x, y] op z into [x op z, y op z]
if z is a constant which (for op | its bitwise not) has n
consecutive least significant bits cleared followed by m 1
consecutive bits set immediately above it and either
m + n == precision, or (x >> (m + n)) == (y >> (m + n)).
The least significant n bits of all the values in the range are
cleared or set, the m bits above it are preserved and any bits
above these are required to be the same for all values in the
range. */
if (vr0p && range_int_cst_p (vr0p))
{
wide_int w = wi::to_wide (vr1p->min);
int m = 0, n = 0;
if (code == BIT_IOR_EXPR)
w = ~w;
if (wi::eq_p (w, 0))
...
and both cases produce a different outcome (as we see).
I don't see how we can do better. Well, we can choose to handle
| CST with least significant bit set as ~[0, 0] consistently. Or
we can add a predicate effectively_varying_p () and guard the 2nd case
above with it.
The "proper" result for [MIN,MAX] | 1 is of course a set of every odd number...
More information about the Gcc-bugs
mailing list