This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] Fix PR 22493
Diego Novillo <dnovillo@redhat.com> writes:
> On Sun, Jul 24, 2005 at 03:16:14AM -0400, James A. Morrison wrote:
>
>> * tree-vrp.c (extract_range_from_unary_expr): Deal with -fwrapv and
>> VR_ANTI_RANGEs properly for NEGATE_EXPRs and ABS_EXPRs.
>>
> Thanks. It needs a few changes before it can go in:
>
>> @@ -1353,27 +1356,64 @@ extract_range_from_unary_expr (value_ran
>> if (code == NEGATE_EXPR
>> && !TYPE_UNSIGNED (TREE_TYPE (expr)))
>> {
>> - /* Negating an anti-range doesn't really do anything to it. The
>> - new range will also not take on the same range of values
>> - excluded by the original anti-range. */
>> + /* Negating an anti-range doesn't really do anything to it if the max
>> + value is equal to the min value. Then the new range will also not
>> + take on the same range of values excluded by the original
>> + anti-range. */
>> if (vr0.type == VR_ANTI_RANGE)
>> {
>> - copy_value_range (vr, &vr0);
>> + tree neg_min = fold_unary_to_constant (code, TREE_TYPE (expr),
>> + vr0.min);
>> + if (operand_equal_p (vr0.max, neg_min, 0))
>> + copy_value_range (vr, &vr0);
>> + else
>> + set_value_range_to_varying (vr);
>> return;
>> }
>>
> I think both the original code and this fix get it wrong.
> Thinking better about anti-ranges, I don't think there's anything
> special about them wrt NEGATE_EXPR:
>
> a_4 -> ~[1, 9]
> a_5 = -a_4 -> ~[-9, -1]
>
> a_4 -> ~[2, 2]
> a_5 = -a_4 -> ~[-2, -2]
>
> This is exactly what we do for regular ranges. Just flip the
> range around and apply NEGATE_EXPR to each end. I don't know
> what I was thinking when I decided to keep the original
> anti-range, but it couldn't be right.
>
>>
>> - /* NEGATE_EXPR flips the range around. */
>> - min = (vr0.max == TYPE_MAX_VALUE (TREE_TYPE (expr)))
>> - ? TYPE_MIN_VALUE (TREE_TYPE (expr))
>> - : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
>> + if (flag_wrapv && vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr)))
>> + {
>> + tree one = build_int_cst (TREE_TYPE (expr), 1);
>>
> Document the handling of -fwrapv here.
>
>> else if (code == ABS_EXPR
>> - && !TYPE_UNSIGNED (TREE_TYPE (expr)))
>> + && !(TYPE_UNSIGNED (TREE_TYPE (expr))))
>>
> Not needed.
>
>> {
>> + int comp;
>> + /* Deal with VR_ANTI_RANGEs in the same way we do for NEGATE_EXPRs. */
>> + if (vr_type == VR_ANTI_RANGE)
>> + {
>> + tree neg_min = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (expr),
>> + vr0.min);
>> + if (operand_equal_p (vr0.max, neg_min, 0))
>> + copy_value_range (vr, &vr0);
>> + else
>> + set_value_range_to_varying (vr);
>> + return;
>> + }
>> +
> Hmm, no. Just ask if range_includes_zero_p (&vr0). If so, set VR
> to VARYING. We know that ABS_EXPR <~[-N1, -N2]> will be ~[N2, N1].
No, since N1 and N2 are outside the anti-range, so if N1 is positive then
ABS_EXPR<N1> = N1.
> But if the range includes 0, say ~[-3, 1], we would end with ~[1, 3].
> Which would be wrong for input 2.
However, if we have ABS_EXPR<~[-N, N]> then we know that the range is still
~[-N, N], actually ~[TYPE_MIN_VALUE, N].
> If the range does not include zero, handle it as a regular range.
>
>> @@ -1382,12 +1422,22 @@ extract_range_from_unary_expr (value_ran
>>
>> max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
>>
>> - /* If the range was reversed, swap MIN and MAX. */
>> - if (compare_values (min, max) == 1)
>> + comp = compare_values (min, max);
>> + if (tree_int_cst_sgn (vr0.min) == tree_int_cst_sgn (vr0.max))
>>
> Why do you need this?
Take the range [-15, 12], the signs are different, so the range contains zero
and we have to be careful. I.e. the new range is [0, 15]. However, for
[-15, -12] or [12, 15] the ranges don't contain zero, so we do want to swap min
and max if the ABS_EXPR did make min > max. I think using
range_contains_zero_p is what I wanted here.
--
Thanks,
Jim
http://www.csclub.uwaterloo.ca/~ja2morri/
http://phython.blogspot.com
http://open.nit.ca/wiki/?page=jim