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. 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