Skip to content
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

Work around bad ptr::with_addr codegen in core::ptr #96538

Closed

Conversation

thomcc
Copy link
Member

@thomcc thomcc commented Apr 29, 2022

Fixes #96152.

Probably not really the ideal way to fix this, but the ideal way is an LLVM patch (or to make it an intrinsic), and I'm not a compiler person.

@rust-highfive
Copy link
Collaborator

Hey! It looks like you've submitted a new PR for the library teams!

If this PR contains changes to any rust-lang/rust public library APIs then please comment with r? rust-lang/libs-api @rustbot label +T-libs-api -T-libs to request review from a libs-api team reviewer. If you're unsure where your change falls no worries, just leave it as is and the reviewer will take a look and make a decision to forward on if necessary.

Examples of T-libs-api changes:

  • Stabilizing library features
  • Introducing insta-stable changes such as new implementations of existing stable traits on existing stable types
  • Introducing new or changing existing unstable library APIs (excluding permanently unstable features / features without a tracking issue)
  • Changing public documentation in ways that create new stability guarantees
  • Changing observable runtime behavior of library APIs

@rustbot rustbot added the T-libs Relevant to the library team, which will review and decide on the PR/issue. label Apr 29, 2022
@rust-highfive
Copy link
Collaborator

r? @joshtriplett

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 29, 2022
@thomcc thomcc added the A-strict-provenance Area: Strict provenance for raw pointers label Apr 29, 2022
@thomcc
Copy link
Member Author

thomcc commented Apr 29, 2022

Oof, hm. Well, I wonder if it's even worth keeping the old code given that all current platforms actually support the current way of doing this.

I got rid of it for now. It seems unfortunate, but I don't think we should penalize real current targets for this at the moment. That is, IMO code shouldn't have to pay a performance cost to switch to be compatible with strict provenance, even if the cost is fairly small.

@rust-log-analyzer

This comment has been minimized.

@thomcc
Copy link
Member Author

thomcc commented Apr 29, 2022

Hm, those are some downright spooky failures.

@thomcc thomcc force-pushed the workaround-bad-withaddr-codegen branch from 310fc75 to 35f28d8 Compare April 29, 2022 02:39
@thomcc thomcc closed this Apr 29, 2022
@rust-log-analyzer

This comment has been minimized.

@thomcc thomcc reopened this Apr 29, 2022
@thomcc thomcc force-pushed the workaround-bad-withaddr-codegen branch from 7253736 to 9a902b1 Compare April 29, 2022 03:19
@thomcc
Copy link
Member Author

thomcc commented Apr 29, 2022

Okay, the fact that this fails for self.cast::<u8>().wrapping_sub(self as usize).wrapping_add(addr) and not for self.cast::<u8>().wrapping_add(addr).wrapping_sub(self as usize) is highly spooky, but this seems... fine?

@saethlin
Copy link
Member

saethlin commented Apr 29, 2022

I don't know what's going on here. I did the wrapping_sub then wrapping_add version and all the tests pass locally. I'm on x86_64 Linux too and using CI LLVM so I truly don't know why the tests would be failing in CI for this formulation and not locally.

        self.cast::<u8>().wrapping_sub(self_addr).wrapping_add(addr).cast::<T>()

@thomcc is speculating that this formulation looks to LLVM like ptr::null().wrapping_add(addr).cast::<T>(), which if true would be extremely concerning.

@thomcc
Copy link
Member Author

thomcc commented Apr 29, 2022

Yeah, it's also possible that there's some bug I'm just not seeing in 35f28d8.

@nikic
Copy link
Contributor

nikic commented Apr 29, 2022

It does get miscompiled for constant pointers: https://llvm.godbolt.org/z/chr3v7r9z

I thought we had fixed this one already...

@nikic
Copy link
Contributor

nikic commented Apr 29, 2022

getelementptr (i8, ptr @g, i64 sub (i64 0, i64 ptrtoint (ptr @g to i64))) gets folded to inttoptr (i64 sub (i64 ptrtoint (ptr @g to i64), i64 ptrtoint (ptr @g to i64)) to ptr) by https://github.com/llvm/llvm-project/blob/371412e065a63107d5d79330da6757ff693d91cc/llvm/lib/Analysis/ConstantFolding.cpp#L869-L882. And then that gets folded to inttoptr (i64 0 to ptr) by https://github.com/llvm/llvm-project/blob/371412e065a63107d5d79330da6757ff693d91cc/llvm/lib/Analysis/ConstantFolding.cpp#L778-L787. Which then gets folded to null.

Strictly speaking, the actual bug here is in the last step, but that's a well known issue. From a pragmatic point of view, we'd probably want to prevent the first fold, as it's generally not a good idea to convert a getelementptr into inttoptr and ptrtoint.

@thomcc
Copy link
Member Author

thomcc commented Apr 29, 2022

@nikic what's your advice for this issue? Should we keep it as-is and close the PR? Does the code as-is (with the switched add/sub ordering) avoid this LLVM bug, or would it still be subject to it.

@nikic
Copy link
Contributor

nikic commented Apr 29, 2022

@thomcc The switched order mostly avoids this, but I'm afraid the issue can still be hit: https://llvm.godbolt.org/z/eG4PMcbhb In this case the two GEPs will be interchanged to move one of them loop invariant, at which point we'd back to the same issue.

@thomcc
Copy link
Member Author

thomcc commented Apr 29, 2022

Hm, I see. That's unfortunate. Probably enough to not want this change.

@nikic
Copy link
Contributor

nikic commented Apr 29, 2022

I've put up https://reviews.llvm.org/D124677 to fix the miscompile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-strict-provenance Area: Strict provenance for raw pointers S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CHERI-valid pointer stuffing produces worse codegen than an implementation which does huge wrapping offsets
7 participants