On 9/3/21 5:41 PM, Jakub Jelinek wrote:
On Fri, Sep 03, 2021 at 09:09:59AM -0600, Jeff Law via Gcc-patches wrote:
On 9/3/2021 9:05 AM, Andrew MacLeod via Gcc-patches wrote:
On 9/3/21 10:41 AM, Aldy Hernandez wrote:
[Andrew, do you see any problem with using the minus relational code
here? It seems like everything matches up.]
I've seen cases in the upcoming jump threader enhancements where we see
a difference of two pointers that are known to be equivalent, and yet we
fail to return 0 for the range. This is because we have no working
range-op entry for POINTER_DIFF_EXPR. The entry we currently have is
a mere placeholder to avoid ignoring POINTER_DIFF_EXPR's so
adjust_pointer_diff_expr() could get a whack at it here:
// def = __builtin_memchr (arg, 0, sz)
// n = def - arg
//
// The range for N can be narrowed to [0, PTRDIFF_MAX - 1].
In theory... but do the non-equality relations make sense? ie ptr1 <
ptr2 ? Perhaps there is no harm in those.. Probably undefined
behaviour if they are not related so we can do whatever...
I'm pretty sure they're in the realm of undefined behavior if the pointers
point to different objects. There was some code that would have cared about
this, but I think it mostly got cleaned up in response to Martin S's
diagnostic work over the last couple years.
Yeah. Just note, [0, PTRDIFF_MAX - 1] range will be only for builtins
like memchr/strchr/mempcpy etc. that return either the passed argument or that
pointer
incremented some number of times. Generally pointer arith can go in both
directions, so POINTER_DIFF_EXPR can be negative too.
If one of the pointers points into some VAR_DECL object, the range could be
narrowed from the size of that object though.
The [0, PTRDIFF_MAX - 1] stuff I spoke of, is the code in
adjust_pointer_diff_expr(). It is meant to be used when chasing the
defining statement of a POINTER_DIFF_EXPR is in a specific form.
Currently it only applies to __builtin_memchr. I believe the code came
from vr-values (or tree-vrp) at some point ??.
Do you think the code there should be ehanced to include other built-ins
other than __builtin_memchr? Patches welcome :)).
BTW, my proposed patch only deals with relations between the operands.
It has nothing to do with builtins or other such uses. For example, if
both operands to a POINTER_DIFF_EXPR are equal, we can deduce that the
result will be 0. I frankly only care about the == and != relationship
presently, but it was easy enough to hijack the MINUS_EXPR relation code.
Thanks.
Aldy
char a[26];
long
foo (long i, char *q)
{
char *p = &a[0] + i;
return q - p;
}
The minimum result will be if q points to &a[0] and p to &a[26], i.e.
-26, maximum the other way, so [-26, 26] range.
Jakub