Skip to content

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
Contributor

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
Contributor

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