SCEV Question

LLVM 2.7's ScalarEvolution.cpp has this scary comment:

  // It's tempting to handle inttoptr and ptrtoint as no-ops, however this can
  // lead to pointer expressions which cannot safely be expanded to GEPs,
  // because ScalarEvolution doesn't respect the GEP aliasing rules when
  // simplifying integer expressions.

I think I understand what the comment is saying. If a GEP has inbounds
or other properties, that information will be lost when casting to an
integer and back to a pointer.

Unfortunately, (as Dan G. well knows), our compiler does a lot of this
ptrtoint->arithmetic->inttoptr kind of thing. I would like to clean
that up at some point but right now I'm trying to track down some
regressions in SCEV when we updated to 2.7.

With previous LLVM versions, we have been handling inttoptr as a no-op
cast and created a special SCEV expression type for ptrtoint.

For 2.7, I created a new inttoptr SCEV expression type and turn inttoptr
instructions into that.

Really all I need to get to work is add recurrences being recognized in
the face of these ptr->int->ptr conversions. I don't really care if
they get turned into GEPs later.

My assumption is that while an inttoptr SCEV expression may be overkill
for this case (I can treat inttoptr as a no-op if I don't care about
conversion back to GEP) it shouldn't really hurt anything if I create an
inttoptr SCEV as long as the support for analysis (loop invariance,
etc.) is all there.

Basically, I want to make sure I'm not going to trip over any gotchas.
Are my assumptions reasonable?

Comments, warnings or flames? :slight_smile:

                           -Dave

LLVM 2.7's ScalarEvolution.cpp has this scary comment:

// It's tempting to handle inttoptr and ptrtoint as no-ops, however this can
// lead to pointer expressions which cannot safely be expanded to GEPs,
// because ScalarEvolution doesn't respect the GEP aliasing rules when
// simplifying integer expressions.

I think I understand what the comment is saying. If a GEP has inbounds
or other properties, that information will be lost when casting to an
integer and back to a pointer.

It's the reverse. If the code does ptrtoint+arithmetic+inttoptr,
it may not uphold the GEP guarantees (even without inbounds), so
converting it to GEP is not safe unless you can prove things about
its operands which ScalarEvolution doesn't currently know how to do.

See http://llvm.org/docs/GetElementPtr.html#int for details (which
was written quite a while after the code you're talking about was
written :-)).

Unfortunately, (as Dan G. well knows), our compiler does a lot of this
ptrtoint->arithmetic->inttoptr kind of thing. I would like to clean
that up at some point but right now I'm trying to track down some
regressions in SCEV when we updated to 2.7.

With previous LLVM versions, we have been handling inttoptr as a no-op
cast and created a special SCEV expression type for ptrtoint.

For 2.7, I created a new inttoptr SCEV expression type and turn inttoptr
instructions into that.

Really all I need to get to work is add recurrences being recognized in
the face of these ptr->int->ptr conversions. I don't really care if
they get turned into GEPs later.

My assumption is that while an inttoptr SCEV expression may be overkill
for this case (I can treat inttoptr as a no-op if I don't care about
conversion back to GEP) it shouldn't really hurt anything if I create an
inttoptr SCEV as long as the support for analysis (loop invariance,
etc.) is all there.

Basically, I want to make sure I'm not going to trip over any gotchas.
Are my assumptions reasonable?

Comments, warnings or flames? :slight_smile:

It sounds like it'll probably work. I wonder if it's more work than
just converting the producer to use bitcast+i8* gep+bitcast when it
can though.

Dan

Dan Gohman <gohman@apple.com> writes:

I think I understand what the comment is saying. If a GEP has inbounds
or other properties, that information will be lost when casting to an
integer and back to a pointer.

It's the reverse. If the code does ptrtoint+arithmetic+inttoptr,
it may not uphold the GEP guarantees (even without inbounds), so
converting it to GEP is not safe unless you can prove things about
its operands which ScalarEvolution doesn't currently know how to do.

See http://llvm.org/docs/GetElementPtr.html#int for details (which
was written quite a while after the code you're talking about was
written :-)).

Ok, cool. That's helpful.

My assumption is that while an inttoptr SCEV expression may be overkill
for this case (I can treat inttoptr as a no-op if I don't care about
conversion back to GEP) it shouldn't really hurt anything if I create an
inttoptr SCEV as long as the support for analysis (loop invariance,
etc.) is all there.

Basically, I want to make sure I'm not going to trip over any gotchas.
Are my assumptions reasonable?

Comments, warnings or flames? :slight_smile:

It sounds like it'll probably work. I wonder if it's more work than
just converting the producer to use bitcast+i8* gep+bitcast when it
can though.

Well, I got everything to work again. The bitcast idea is interesting.
I may look at that in the future.

In the absence of abominations like overindexing, I think I should be
able to convert most of this stuff back into GEPs safely. But that's an
experiment for another day. :slight_smile:

                              -Dave