hi rust twitter: ptr:add (doc.rust-lang.org/std/primitive.) points to wrapping_add (doc.rust-lang.org/std/primitive.) as an alternative if safety requirements are difficult to uphold, but says that wrapping_add disallows some "aggressive compiler optimizations"
anyone know what those are?
Conversation
Replying to
It has a list of the guarantees provided to the compiler by ptr::add at doc.rust-lang.org/std/primitive..
It maps to an LLVM inbounds GEP rather than GEP. There's documentation on this at llvm.org/docs/LangRef.h. Guarantees result will be within the bounds of the object without wrapping.
1
2
It can't cheat by wrapping all the around and back into the same object. It's a bit silly that the safe one is called wrapping_add because allowing wrapping is only one of the things it allows.
Note that ptr::wrapping_add is safe and ptr::add is unsafe due to the UB.
1
1
It's UB to deference a pointer outside the bounds of the object it was derived from regardless of which one you use. The purpose of ptr::add is that it's also undefined to create the pointer outside bounds of the object which enables optimizations even if load isn't right there.
1
Replying to
i need you to realize you linked me at the exact same part of rust docs that i, myself, linked. i was not asking why one is safe and the other is not, i was asking what optimization differences there are
2
llvm.org/docs/GetElemen is informative in a subtle way: because an inbounds gep cannot overflow, the compiler can make assumptions about ordering of pointers, among other things
1
Replying to
Main guarantees is that it's in-bound. ptr::wrapping_add method is poorly named. The main difference is that it permits the result to not be within the bounds of the object. Disallowing wrapping as part of inbounds is a bonus thing.
1
So, among many other things, it's guaranteed to not be a null pointer and null checks can be eliminated. A negative offset will go backwards within the object, a positive offset will go forwards within the object (up to one byte past the end) and a zero offset will stay the same.
2
Replying to
"a `negative offset` will go backwards within the object" is not necessarily true, and the entire reason i'm looking closely at these functions
2
Replying to
It's a promise you make by using inbounds GEP since it's not allowed to wrap around back into the object. I'm listing some of the useful optimization guarantees provided by inbounds GEP. It improves the answers to a lot of different queries in a lot of optimization passes.

