anti-ranges of signed variables
Martin Sebor
msebor@gmail.com
Fri Nov 11 19:30:00 GMT 2016
On 11/11/2016 12:12 PM, Andrew Pinski wrote:
> On Fri, Nov 11, 2016 at 10:51 AM, Martin Sebor <msebor@gmail.com> wrote:
>> On 11/11/2016 10:53 AM, Richard Biener wrote:
>>>
>>> On November 11, 2016 6:34:37 PM GMT+01:00, Martin Sebor <msebor@gmail.com>
>>> wrote:
>>>>
>>>> I noticed that variables of signed integer types that are constrained
>>>> to a specific subrange of values of the type like so:
>>>>
>>>> [-TYPE_MAX + N, N]
>>>>
>>>> are reported by get_range_info as the anti-range
>>>>
>>>> [-TYPE_MAX, TYPE_MIN - 1]
>>>>
>>>> for all positive N of the type regardless of the variable's actual
>>>> range. Basically, such variables are treated the same as variables
>>>> of the same type that have no range info associated with them at all
>>>> (such as function arguments or global variables).
>>>>
>>>> For example, while a signed char variable between -1 and 126 is
>>>> represented by
>>>>
>>>> VR_ANTI_RANGE [127, -2]
>>>
>>>
>>> ? I'd expect [-1, 126]. And certainly never range-min > range-max
>>
>>
>> Okay. With this code:
>>
>> void f (void *d, const void *s, signed char i)
>> {
>> if (i < -1 || 126 < i) i = -1;
>> __builtin_memcpy (d, s, i);
>> }
>>
>> I see the following in the output of -fdump-tree-vrp:
>>
>> prephitmp_11: ~[127, 18446744073709551614]
>
>
> prephitmp_11 is an unsigned type as the last argument to memcpy is
> size_t which is an unsigned type. We had this discussion in bugzilla
> about this same thing when we were talking about pointer plus.
Right. But that wasn't my question (the reported range above
correctly reflects the variable's range in the code).
My question is: why is the range for i in
if (i < -3 || 124 < i) i = -1;
the same as in
if (i < -4 || 123 < i) i = -1;
In both cases it's represented as
prephitmp_12: ~[128, 18446744073709551487]
which is unrelated to i's actual range. This seems to be true
for all signed types in the range [-TYPE_MAX + N, N].
Martin
>
> Thanks,
> Andrew
>
>> ...
>> # prephitmp_11 = PHI <_12(3), 18446744073709551615(2)>
>> __builtin_memcpy (d_8(D), s_9(D), prephitmp_11);
>>
>> and this in GDB:
>>
>> Breakpoint 1, determine_block_size (len=0x7ffff0daacf0,
>> ...
>> 2913 else if (range_type == VR_ANTI_RANGE)
>> (gdb) s
>> 2916 if (min == 0)
>> (gdb) p range_type
>> $1 = VR_ANTI_RANGE
>> (gdb) p min
>> $2 = {<wide_int_storage> = {val = {127, 18136432, 140737235550272}, len =
>> 1,
>> precision = 64}, static is_sign_extended = <optimized out>}
>> (gdb) p max
>> $3 = {<wide_int_storage> = {val = {-2, 18136478, 140737235550272}, len =
>> 1,
>> precision = 64}, static is_sign_extended = <optimized out>}
>>
>>>
>>>> as one would expect, when the same variable is between -4 and 123
>>>> it's represented by
>>>>
>>>> VR_ANTI_RANGE [128, -129]
>>>>
>>>> rather than the expected
>>>>
>>>> VR_ANTI_RANGE [124, -5]
>>>>
>>>> I'd like to know if this is a deliberate feature or a bug.
>>>
>>>
>>> It must be a misinterpretation on your side. Or an implementation bug.
>>
>>
>> Given the above, which does it look like it is?
>>
>> Thanks
>> Martin
More information about the Gcc
mailing list