anti-ranges of signed variables

kugan kugan.vivekanandarajah@linaro.org
Mon Nov 14 03:15:00 GMT 2016


Hi,

On 12/11/16 06:19, Jakub Jelinek wrote:
> On Fri, Nov 11, 2016 at 11:51:34AM -0700, Martin Sebor 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 = PHI <_12(3), 18446744073709551615(2)>
>>   __builtin_memcpy (d_8(D), s_9(D), prephitmp_11);
>
> At some point get_range_info for anti-ranges has been represented
> by using min larger than max, but later on some extra bit on SSA_NAME has
> been added.  Dunno if the code has been adjusted at that point.

Commit changed that and removed it is.
commit 0c20fe492bc5b8c9259d21dd2dab03ff5155facb
Author: rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Thu Nov 28 16:32:44 2013 +0000

     wide-int version of SSA_NAME_ANTI_ALIAS_P patch.

     git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/wide-int@205491 
138bc75d-0d04-0410-961f-82ee72b054a4


But looking closely:

enum value_range_type { VR_UNDEFINED, VR_RANGE,
			VR_ANTI_RANGE, VR_VARYING, VR_LAST };
in set_range_info, we have:
   SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE);

in get_range_info, we have:
   return SSA_NAME_RANGE_TYPE (name);

I think we should change the get_range_info to:

diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 913d142..f33b9c0 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -371,7 +371,7 @@ get_range_info (const_tree name, wide_int *min, 
wide_int *max)

    *min = ri->get_min ();
    *max = ri->get_max ();
-  return SSA_NAME_RANGE_TYPE (name);
+  return SSA_NAME_RANGE_TYPE (name) ? VR_ANTI_RANGE : VR_RANGE;
  }

Is this OK after testing ?

Thanks,
Kugan



More information about the Gcc mailing list