-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add sub_ptr
on pointers (the usize
version of offset_from
)
#95837
Conversation
Some changes occured to rustc_codegen_cranelift cc @bjorn3 Some changes occured to the CTFE / Miri engine cc @rust-lang/miri |
r? @kennytm (rust-highfive has picked a reviewer for you, use r? to override) |
5edd31a
to
378bb4a
Compare
Sorry for the drive-by comment (rant?) but just wanted to leave the note somewhere: since i've been poking these APIs, this has been the second-most-brain-melty interface in
Like my guess is that the intent is that This API is (at least in std) pretty universally used for computing array length via pointer distance... and yes you do this with imo things end up a lot clearer if you just make this And then yeah you always want it unsigned so... what you really want is So, just make (I will concede add_to reads funny, because my brain wants to map it to "add x to y" and not "the add to get to y", but I think this is a weird enough name that it will just... be fine in practice and we'll get over it in like a day when all of our code actually makes sense to read again.) Also CC #95643 |
(also yeah byte_unsigned_offset_from is Suffering, byte_add_to is uh, a lot more reasonable lol) |
FWIW I find the naming very intuitive -- I do agree that it should explicitly spell out the I agree |
(I know @Gankra already knows this, but I wanted to state my objection with "add" because it's only a verb, whereas AFAICT Personally something like EDIT: wait I forgot that "addend" is the equivalent noun for "add", so |
I agree with @Gankra's sort of confusion/irritation at Btw I'm just commenting here because I'm trying to patch all the ptr-int-ptr casts out of impl ChunkFooter {
// Returns the start and length of the currently allocated region of this
// chunk.
fn as_raw_parts(&self) -> (*const u8, usize) {
let data = self.data.as_ptr() as usize;
let ptr = self.ptr.get().as_ptr() as usize;
debug_assert!(data <= ptr);
debug_assert!(ptr <= self as *const _ as usize);
let len = self as *const _ as usize - ptr;
(ptr as *const u8, len)
}
} A lot of the |
Just caught up on the Zulip thread for this. @scottmcm you commented:
I think |
Yeah
Regarding |
I opened #95851 to clarify offset_from's docs |
If we want an operation that works in This is also slightly helpful for compiler optimizations, for roughly the same reason -- the optimizer can be sure that passing the result of an |
One thing I'll note is that both In such cases, something like |
You can either recover the sign at runtime or have different return types. The former might be ergonomic and the latter help the compiler. |
I like the
👍 The same as how I started making this thinking of it as "this is the specialized one that
Heh, very much so. Hmm, Maybe we can take advantage of the "UB in the other order (unless they're equal)" to put the directionality more obviously in the name. Would it be clearer with
Can you say more about this, @eternaleye? Notably, every single case in the (Although, thinking about this again, |
I think @eternaleye was arguing that the order-less API is strictly more useful because it works for both the standard "definitely know" and the strange "no idea (yet)". But I think this operation is low-level enough and the "definitely know" case so common, that we should prefer the ordered impl because it's more optimized (saving like 3 instructions or something, I couldn't think of any way to do cute hardware-specific). Also we have usize::abs_diff so if anyone really wants it they can do |
b6d2f47
to
3ca6921
Compare
Thanks, @Gankra; that makes sense. And we definitely need a hyper-optimized version of this operation for use in the bowels of slice iterators, so it might as well be this method. I agree the more unusual cases are best left for something else. I ended up pushing a change to rename to I also added a section like this to the docs to attempt to further emphasize: ptr.sub_ptr(origin) == count
origin.add(count) == ptr
ptr.sub(count) == origin Feedback appreciated on whether this name is good, or whether you're prefer one of the other naming approaches. |
I still think framing it as subtraction is a missed opportunity because subtraction is not what you actually "care" about, but a means to an end (which always stops me in my tracks while I triple check which way I want). But at least it is very compact and appeals directly to subtraction, so it's a strict ergonomics win with the same intuition as the "normal" way. I would happily let this land to nightly and let the name bikeshed later. 😸 |
(disclaimer: I have not reviewed the rest of this in detail, and idk how much the docs want to crib from my other PR) |
💔 Test failed - checks-actions |
faee850
to
e1520f1
Compare
Like we have `add`/`sub` which are the `usize` version of `offset`, this adds the `usize` equivalent of `offset_from`. Like how `.add(d)` replaced a whole bunch of `.offset(d as isize)`, you can see from the changes here that it's fairly common that code actually knows the order between the pointers and *wants* a `usize`, not an `isize`. As a bonus, this can do `sub nuw`+`udiv exact`, rather than `sub`+`sdiv exact`, which can be optimized slightly better because it doesn't have to worry about negatives. That's why the slice iterators weren't using `offset_from`, though I haven't updated that code in this PR because slices are so perf-critical that I'll do it as its own change. This is an intrinsic, like `offset_from`, so that it can eventually be allowed in CTFE. It also allows checking the extra safety condition -- see the test confirming that CTFE catches it if you pass the pointers in the wrong order.
e1520f1
to
003b954
Compare
Rebase from faee850 to e1520f1 is just updating to master. There's an @bors r=oli-obk rollup=iffy (codegen tests are always iffy for me) |
📌 Commit 003b954 has been approved by |
☀️ Test successful - checks-actions |
Finished benchmarking commit (1d2ea98): comparison url. Summary:
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. @rustbot label: -perf-regression Footnotes |
Status: Compilation succeeds but regression fails due to new intrinsic. Relevant changes: - rust-lang/rust#95837 - rust-lang/rust#95562 - rust-lang/rust#96883
* Update rust toolchain to 2022-05-17 Status: Compilation succeeds but regression fails due to new intrinsic. Relevant changes: - rust-lang/rust#95837 - rust-lang/rust#95562 - rust-lang/rust#96883 * Implement new intrinsic ptr_offset_from_unsigned This new intrinsic is used in many different places in the standard library and it was failing some tests for vectors. * Apply suggestions from code review Co-authored-by: Adrian Palacios <73246657+adpaco-aws@users.noreply.github.com> * Address PR comments - Fix order of checks. - Improve error message. - Add comments to the new tests. Co-authored-by: Adrian Palacios <73246657+adpaco-aws@users.noreply.github.com>
…, r=Mark-Simulacrum Add a codegen test for `slice::from_ptr_range` I noticed back in rust-lang#95579 that this didn't optimize as well as it should. It's better now, after rust-lang#95837 changed the code in `from_ptr_range` and llvm/llvm-project#54824 was fixed in LLVM 15. So here's a test to keep it generating the good version.
We have
add
/sub
which are theusize
versions ofoffset
, this adds theusize
equivalent ofoffset_from
. Like how.add(d)
replaced a whole bunch of.offset(d as isize)
, you can see from the changes here that it's fairly common that code actually knows the order between the pointers and wants ausize
, not anisize
.As a bonus, this can do
sub nuw
+udiv exact
, rather thansub
+sdiv exact
, which can be optimized slightly better because it doesn't have to worry about negatives. That's why the slice iterators weren't usingoffset_from
, though I haven't updated that code in this PR because slices are so perf-critical that I'll do it as its own change.This is an intrinsic, like
offset_from
, so that it can eventually be allowed in CTFE. It also allows checking the extra safety condition -- see the test confirming that CTFE catches it if you pass the pointers in the wrong order.