Patches welcome :-). On Fri, Sep 3, 2021, 18:42 Martin Sebor <mse...@gmail.com> wrote:
> On 9/3/21 8:41 AM, Aldy Hernandez via Gcc-patches 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]. > > For the two statements above a tighter bound is possible: [0, sz). > > With no range info, sz can be assumed to be in [0, N], where N > is one less than the smaller of PTRDIFF_MAX and the size of arg. > (With PTRDIFF_MAX being only hypothetical. max_object_size() > should at some return the actual limit for the current target). > > The same (or even tighter) range can be derived from calls to > other functions, including like mempcpy/stpcpy, or strchr, etc. > > Martin > > > > > This patch adds the relational magic to range-op, which we can just > > steal from the minus_expr code. > > > > Testing currently in progress. I will commit pending tests. > > > > gcc/ChangeLog: > > > > * range-op.cc (operator_minus::op1_op2_relation_effect): Abstract > > out to... > > (minus_op1_op2_relation_effect): ...here. > > (class operator_pointer_diff): New. > > (operator_pointer_diff::op1_op2_relation_effect): Call > > minus_op1_op2_relation_effect. > > (integral_table::integral_table): Add entry for POINTER_DIFF_EXPR. > > --- > > gcc/range-op.cc | 45 ++++++++++++++++++++++++++++++++++++++------- > > 1 file changed, 38 insertions(+), 7 deletions(-) > > > > diff --git a/gcc/range-op.cc b/gcc/range-op.cc > > index fee0e834c23..5e37133026d 100644 > > --- a/gcc/range-op.cc > > +++ b/gcc/range-op.cc > > @@ -1372,13 +1372,14 @@ operator_minus::wi_fold (irange &r, tree type, > > } > > > > // Check to see if the relation REL between OP1 and OP2 has any effect > on the > > -// LHS of the expression. If so, apply it to LHS_RANGE. > > +// LHS of the expression. If so, apply it to LHS_RANGE. This is a > helper > > +// function for both MINUS_EXPR and POINTER_DIFF_EXPR. > > > > -bool > > -operator_minus::op1_op2_relation_effect (irange &lhs_range, tree type, > > - const irange &op1_range > ATTRIBUTE_UNUSED, > > - const irange &op2_range > ATTRIBUTE_UNUSED, > > - relation_kind rel) const > > +static bool > > +minus_op1_op2_relation_effect (irange &lhs_range, tree type, > > + const irange &op1_range ATTRIBUTE_UNUSED, > > + const irange &op2_range ATTRIBUTE_UNUSED, > > + relation_kind rel) > > { > > if (rel == VREL_NONE) > > return false; > > @@ -1440,6 +1441,16 @@ operator_minus::op1_op2_relation_effect (irange > &lhs_range, tree type, > > return true; > > } > > > > +bool > > +operator_minus::op1_op2_relation_effect (irange &lhs_range, tree type, > > + const irange &op1_range, > > + const irange &op2_range, > > + relation_kind rel) const > > +{ > > + return minus_op1_op2_relation_effect (lhs_range, type, op1_range, > op2_range, > > + rel); > > +} > > + > > bool > > operator_minus::op1_range (irange &r, tree type, > > const irange &lhs, > > @@ -1459,6 +1470,26 @@ operator_minus::op2_range (irange &r, tree type, > > } > > > > > > +class operator_pointer_diff : public range_operator > > +{ > > + virtual bool op1_op2_relation_effect (irange &lhs_range, > > + tree type, > > + const irange &op1_range, > > + const irange &op2_range, > > + relation_kind rel) const; > > +} op_pointer_diff; > > + > > +bool > > +operator_pointer_diff::op1_op2_relation_effect (irange &lhs_range, tree > type, > > + const irange &op1_range, > > + const irange &op2_range, > > + relation_kind rel) const > > +{ > > + return minus_op1_op2_relation_effect (lhs_range, type, op1_range, > op2_range, > > + rel); > > +} > > + > > + > > class operator_min : public range_operator > > { > > public: > > @@ -4018,7 +4049,7 @@ integral_table::integral_table () > > set (OBJ_TYPE_REF, op_identity); > > set (IMAGPART_EXPR, op_unknown); > > set (REALPART_EXPR, op_unknown); > > - set (POINTER_DIFF_EXPR, op_unknown); > > + set (POINTER_DIFF_EXPR, op_pointer_diff); > > set (ABS_EXPR, op_abs); > > set (ABSU_EXPR, op_absu); > > set (NEGATE_EXPR, op_negate); > > > >