cpufeatures: Enable compile time target features under Miri - #1513
Conversation
ff2d41a to
e00363a
Compare
e00363a to
f8155d1
Compare
f8155d1 to
56ce971
Compare
|
So, while this would be interesting, seems it's a breaking change: RustCrypto/stream-ciphers#579 We can consider it for I went ahead and yanked |
|
As I wrote here, it's probably an issue in the |
|
@newpavlov but code that previously built under miri (because the gated backend was disabled) will now break. That’s a breaking change. I think it should be
|
It breaks build only for people who use Miri, and only old versions of it at that. So IMO the impact is pretty limited, especially considering that the breakage is caused by a genuine UB. So arguably it's not a "breaking change", but a change which has exposed previously existing UB in downstream code, so if anything the breakage speaks in favor of this PR. I am fine with postponing un-yanking until we release a fixed version of |
|
I'm fine with giving it another go after |
|
I don't see how a breaking release of We could've considered it a breaking change if Miri did not support intrinsics for target features enabled by default, but IIUC it's not the case today. I agree that we should decide based on reports, but I don't expect much trouble. |
|
A minor version bump to v0.4 would ensure that all code which builds with I'm worried about things like blocking CI workflows of major downstream crates, such as |
From a downstream crate perspective, I don't see any difference between pinning I opened RustCrypto/stream-ciphers#580 to the fix the root issue, so we should proceed with its release and un-yanking of |
|
I'm not suggesting any "pinning" on the part of the end user. Instead making it a breaking change means we can individually update our crates to the new breaking version after we've confirmed they build under Miri with the various backends, without worrying about it causing downstream breakage in the interim. |
|
chacha20 v0.10.2 with the fix is published, so cpufeatures v0.3.1 can be un-yanked.
You do not work around UB in downstream by demanding upstream dependencies to do breaking releases on each change which potentially breaks incorrect And I don't think we need to check that Miri works with every supported backend, but only those which require enabled by default target features (like SSE2 on x86 targets). |
|
If the code compiled under one version, and you release something that's supposed to be SemVer compatible, and it no longer compiles, that's a breaking change. Period. Note that the previous Miri behavior was to fall back to the pure Rust version, which works. This PR switches Miri to trying to use the SIMD backend which doesn't compile. So it definitely changes things from "working" to "broken" in what's supposed to be a SemVer-compatible update. Despite this being UB, having it cause new compile errors under Miri and only Miri in what's supposed to be a SemVer compatible release doesn't help downstream users. It's breaking under Miri runs for people who are trying to run Miri their own projects and pulling in We should absolutely fix the issues, but in the interim we shouldn't be breaking people's builds. |
Nope. There are various carve outs for this naive rule. For example, if you add In this particular case the change did the intended job. I am fine with taking measures to limit the impact (note that it was already extremely limited), but moving this change into a new breaking release is IMO taking it a bit too far. Instead of yanking |
|
Please note that I went ahead and un-yanked v0.3.1. |
|
@newpavlov in this case, it's changing the backend selected on Miri from a working pure Rust one to a broken one that doesn't even compile on Miri. That's not the kind of breaking change you can defensibly make an exception for. It took a good implementation for that particular target and switched it out for a broken one that doesn't even compile. |
I disagree. We expanded what Miri can check in our crates and it has helped to find UB. Both Miri and this change did their intended job. The broken CI build is not a bad thing, quite an opposite, it did CI's job and notified us about the lurking issue. And a somewhat serious one at that. I believe this firmly falls under the soundness issue exception. With your stance new Miri releases which expand scope of checks (e.g. imagine if runtime target feature detection is added) would be also "breaking". |
|
cc @RalfJung |
|
Alright, it's a reasonable argument that Miri is I still think we could ensure all of our code is tested and working under Miri with this change first before we unleash it on the world. That said, if If more issues pop up, perhaps we should reconsider. |
| //! Minimal miri support. | ||
| //! | ||
| //! Miri is an interpreter, and though it tries to emulate the target CPU | ||
| //! it does not support any target features. |
Sorry, what's the question? |
|
The std macro honors statically enabled target features under Miri so IMO it makes sense for this crate to do the same.
|
|
@RalfJung
|
I think that's up to the crate maintainers. I view it as bringing cpufeatures in line with the std macro, but I can see how it could be annoying for downstream users. std macro consumers had to deal with that already and I think typically crates just carry their own If you want to take a more conservative stance, you could do this change only for x86-32/64 where we have much better intrinsic coverage in Miri. Maybe that's more appropriate for a semver-compatible bump. But given the std macro precedent that could cause its own confusion.
I don't know enough about which target features even exist, let alone which ones are enabled by default where, to provide such a list. Generally we have pretty good support on x86 and barely anything for other targets (though aarch64 has been getting better). But even on x86 I don't know how I'd even figure out whether we support everything that's enabled by default on any (tier 1?) target. And obviously with |
- RustCrypto/stream-ciphers#583 (yank) - RustCrypto/stream-ciphers#580 (UB SSE2 backend) - RustCrypto/utils#1513 (MIRI stuff enabled)
|
So RustCrypto/block-ciphers#585 was exactly the sort of thing I was worried about. I think we really need to roll this change out more gradually in CI instead of using our end users as testers to discover where these gaps exist. I would continue to suggest this change either be made In general with crates like |
|
I fixed |
|
RustCrypto/block-ciphers#588 is another example, and it seems we're going to keep playing whack-a-mole with these for awhile. I think that issue in particular is a good example of why I don't understand the opposition to cc @nazar-pc |
Miri already supports a lot of intrinsics: https://github.com/rust-lang/miri/tree/master/src/intrinsics so I think it make sense to return
truefor compile time enabled features, so if someone runsRUSTFLAGS=+avx2 cargo miri runit will actually enable those features, as the user explicitly asked for themAlso added tests to show that it works outside and inside of miri
tested everything locally too(including loongarch64 via qemu)