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] 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. If it's a feature, can and should it be relied on for all signed variables? Or if it need not always hold, under what conditions, if any, might it not hold? I'm also curious why get_range_info returns VR_ANTI_RANGE for signed variables with bounds of opposite signedness, and if it's something that can be relied on. I.e., does an anti-range always imply that the original variable (before being cast to an unsigned type as often happens) is signed and its lower bound is negative? I've gone through tree-ssa-vrp.[hc] to try to tease out answers to these questions from the code but it looks too involved for me to be confident that I haven't overlooked something. Thanks Martin PS I came across this while stepping through the code below in the determine_block_size function in builtins.c: void f (void *d, void *s, signed char n) { if (n < -4 || 123 < n) return; memcpy (d, s, n); } The function tries to estimate the likely maximum block size for the memcpy call and determines it to be 127 (i.e., SCHAR_MAX) in this case. When the if statement is changed to this: if (n < -4 || 122 < n) return; it determines the likely maximum size to be 122 as I would expect.