Skip to content

Rewrite pointer::with_addr implementation #110318

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions library/core/src/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,15 @@ impl<T: ?Sized> *const T {
// FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
//
// In the mean-time, this operation is defined to be "as if" it was
// a wrapping_offset, so we can emulate it as such. This should properly
// two `wrapping_offset`s, so we can emulate it as such. This should properly
// restore pointer provenance even under today's compiler.
let self_addr = self.addr() as isize;
let dest_addr = addr as isize;
let offset = dest_addr.wrapping_sub(self_addr);

// This is the canonical desugarring of this operation
self.wrapping_byte_offset(offset)
//
// This is the canonical desugaring of this operation.
//
// Note that we are using two offsets, instead of precomputing offset
// with `addr - self.addr()`. This is because it is easier for LLVM to
// optimize such code.
self.wrapping_byte_sub(self.addr()).wrapping_byte_add(addr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I was playing yesterday, I noticed another possible implementation:

Suggested change
self.wrapping_byte_sub(self.addr()).wrapping_byte_add(addr)
self.mask(0).wrapping_byte_add(addr)

That's again just two IR instructions (https://rust.godbolt.org/z/EeraoxKnh), and it has the bonus of never doing a ptrtoint.

Any thoughts on whether that's reasonable or horrible, @nikic?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's very horrible. ptrmask has about zero optimization support.

}

/// Creates a new pointer by mapping `self`'s address to a new one.
Expand Down
15 changes: 8 additions & 7 deletions library/core/src/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,14 +264,15 @@ impl<T: ?Sized> *mut T {
// FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
//
// In the mean-time, this operation is defined to be "as if" it was
// a wrapping_offset, so we can emulate it as such. This should properly
// two `wrapping_offset`s, so we can emulate it as such. This should properly
// restore pointer provenance even under today's compiler.
let self_addr = self.addr() as isize;
let dest_addr = addr as isize;
let offset = dest_addr.wrapping_sub(self_addr);

// This is the canonical desugarring of this operation
self.wrapping_byte_offset(offset)
//
// This is the canonical desugaring of this operation.
//
// Note that we are using two offsets, instead of precomputing offset
// with `addr - self.addr()`. This is because it is easier for LLVM to
// optimize such code.
self.wrapping_byte_sub(self.addr()).wrapping_byte_add(addr)
}

/// Creates a new pointer by mapping `self`'s address to a new one.
Expand Down