-
Notifications
You must be signed in to change notification settings - Fork 12.3k
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
[Mem2Reg] Incorrect poison propagation #97702
Comments
It looks like just mem2reg is sufficient for this. |
Looks like mem2reg calls InstSimplify on phi nodes here:
So it looks like we have found the first real-world instance of the #96631 miscompile. |
After looking a bit closer, my guess in the previous comment wasn't right. The actual root cause is the "single store" optimization in mem2reg, which is not correct if the stored value may be poison. |
Adding a isGuaranteedNotToBePoison() check to rewriteSingleStoreAlloca() does fix the issue. |
…value If there is a single store, then loads must either load the stored value or uninitialized memory (undef). If the stored value may be poison, then replacing an uninitialized memory load with it would be incorrect. Fall back to the generic code in that case. This PR only fixes the case where there is a literal poison store -- the case where the value is non-trivially poison will be miscompiled by phi simplification later, see llvm#96631. Fixes llvm#97702.
…#25) Currently some casts from byte primitives to two element tuple lead to miscompilation on **release** builds on Rust `>=1.70.0`: - `castaway::cast!(123_u8, (u8, u8))` unexpectedly returns `Ok(...)` that leads to **UB**. - `castaway::cast!(false, (bool, u16))` leads to `SIGILL: illegal instruction` runtime error. Upstream issues: - Rust: rust-lang/rust#127286 - LLVM: llvm/llvm-project#97702 I suggest considering adding a safe "workaround" to fix the issue in this crate without having to wait for the upstream fixes. This way we will have this fixed in older Rust versions as well. This PR adds size eq `assert` to `transmute_unchecked`. This workaround was found while preparing an MRE for an upstream issue. Checked locally with `cargo test --release` for Rust `1.38`, `1.68.0`, `1.69.0`, `1.70.0`, `1.71.0`, `1.72.0`, `stable`, `beta`, `nightly`. Generated assembly for other tests cases for the release build seems the same (checks and casts are optimized away). Btw: it might also be a good idea to run tests in `--release` mode as well since the crate relies heavily on optimizing the casts to zero-cost.
For llvm#97702. (cherry picked from commit e7bfd4d)
…value (llvm#97711) If there is a single store, then loads must either load the stored value or uninitialized memory (undef). If the stored value may be poison, then replacing an uninitialized memory load with it would be incorrect. Fall back to the generic code in that case. This PR only fixes the case where there is a literal poison store -- the case where the value is non-trivially poison will still get miscompiled by phi simplification later, see llvm#96631. Fixes llvm#97702. (cherry picked from commit f58930f)
For llvm#97702. (cherry picked from commit e7bfd4d)
…value (llvm#97711) If there is a single store, then loads must either load the stored value or uninitialized memory (undef). If the stored value may be poison, then replacing an uninitialized memory load with it would be incorrect. Fall back to the generic code in that case. This PR only fixes the case where there is a literal poison store -- the case where the value is non-trivially poison will still get miscompiled by phi simplification later, see llvm#96631. Fixes llvm#97702. (cherry picked from commit f58930f)
…value (llvm#97711) If there is a single store, then loads must either load the stored value or uninitialized memory (undef). If the stored value may be poison, then replacing an uninitialized memory load with it would be incorrect. Fall back to the generic code in that case. This PR only fixes the case where there is a literal poison store -- the case where the value is non-trivially poison will still get miscompiled by phi simplification later, see llvm#96631. Fixes llvm#97702.
Results in:
This is incorrect. If
%cond
is false, then the result must be undef, not poison.The original test case is more along these lines (not sure yet whether the root cause is always the same):
The text was updated successfully, but these errors were encountered: