This is the mail archive of the gcc-patches@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: [PTR-PLUS] Add/fix documentation for POINTER_PLUS_EXPR


Hello,

> >  I figured as much that I needed to update the documentation for the
> >addition of POINTER_PLUS_EXPR.  This patch does that and fixes one small
> >documentation in tree.def about the second operand.
> 
> The "small fix", documenting the 2nd operand of POINTER_PLUS_EXPR
> to be always unsigned instead of signed makes me curious.  This effectively
> means that POINTER_PLUS_EXPR overflow is defined as wrapping, which
> will make some transformations we do now invalid and complicates
> re-construction of array accesses &a p+ CST to &a[CST/element_size]
> where this division needs to be done as signed.
> 
> So I would have thought an always signed representation of the
> 2nd operand would have been a more natural choice.
> 
> Any clarifications on why you came to this conclusion?

actually, I have tried also using ssizetype, which indeed appears more
natural.  I run into problems in scev, though.  The serious one is the
following: consider architecture where both pointers and ints are 32
bit, and the following loop:

int *p;

for (unsigned i = 0; ; i++)
  {
    t1 = (ssizetype) i;
    t2 = 4 * t1;
    t3 = p (pplus) t2;
    use (*t3);
  }

the evolution of i is [0,+,1].  The problem is that it is somewhat hard to
derive that the evolution of t1 is also [0,+,1] (in ssizetype) -- in
ssizetype the overflow is undefined, so we may do that only in case when
we are sure the loop iterates less than 2^31 times.

Of course, the way the pointer arithmetics in the loop is done ensures
that the loop iterates less than 2^29 times, but to derive this, we would
need to know the evolution of t2, and for that we need to know the
evolution of t1, at which point we are stuck.  There are various ways
out of this chicken-and-egg loop, but I do not see an easy and reliable
one (if someone did, I would be very grateful).

One option I have considered is going one step further with the
POINTER_PLUS idea, and let POINTER_PLUS have three arguments -- pointer,
multiplier and offset (where type of multiplier would be ssize_int, and
offset could be an arbitrary integer type).  The code above would then
translate to

for (unsigned i = 0; ; i++)
  {
    t3 = POINTER_PLUS (p, 4, i);
    use (*t3);
  }

and the problems with the casts would be eliminated.  Needless to say,
this is much more intrusive change, and it probably would have many side
effects that I do not consider now.

Zdenek


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