This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: anti-ranges of signed variables


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]