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? :) -Dave
On Sep 9, 2010, at 1:48 PM, David Greene wrote:> 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? :)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 at 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? :) > > 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. :) -Dave
Reasonably Related Threads
- [LLVMdev] SCEV Question
- [LLVMdev] [RFC] SCEV Enhancements
- LoopVectorize fails to vectorize loops with induction variables with PtrToInt/IntToPtr conversions
- [LLVMdev] [RFC] SCEV Enhancements
- LoopVectorize fails to vectorize loops with induction variables with PtrToInt/IntToPtr conversions