-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
ConstProp
misoptimises pointer-typed enum field
#118328
Comments
That seems undesirable. Is there a surface Rust program that can produce this MIR? Asking primarily for prioritization purposes. |
WG-prioritization assigning priority (Zulip discussion). @rustbot label -I-prioritize +P-medium |
Minimized test case: #![feature(custom_mir, core_intrinsics, inline_const)]
extern crate core;
use core::intrinsics::mir::*;
#[custom_mir(dialect = "runtime", phase = "initial")]
fn size_of<T>() -> usize {
mir! {
let a : usize;
{
a = 0;
a = const { std::mem::size_of::<T>() };
RET = a;
Return()
}
}
}
fn main() {
assert_eq!(size_of::<u32>(), std::mem::size_of::<u32>());
} $ rustc a.rs && ./a
$ rustc -O a.rs && ./a
thread 'main' panicked at a.rs:19:5:
assertion `left == right` failed
left: 0
right: 4
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace |
Here's an example using stable surface syntax (playground). #![allow(unused_assignments)]
struct SizeOfConst<T>(std::marker::PhantomData<T>);
impl<T> SizeOfConst<T> {
const SIZE: usize = std::mem::size_of::<T>();
}
fn size_of<T>() -> usize {
let mut a = 0;
a = SizeOfConst::<T>::SIZE;
a
}
fn main() {
assert_eq!(size_of::<u32>(), std::mem::size_of::<u32>());
} Seems to have been introduced in 1.70, with #108872 in particular. |
Nevermind seems like I was wrong. define noundef i64 @src() {
%a = alloca i64, align 8
store i64 0, ptr %a, align 8
store i64 4, ptr %a, align 8
%_0 = load i64, ptr %a, align 8
ret i64 %_0
}
define noundef i64 @tgt() {
ret i64 0
} |
It's not an LLVM miscompilation, the code is already With --- ./mir_dump/lol.size_of.005-015.ConstProp.before.mir 2023-11-28 14:38:07.519258465 +0000
+++ ./mir_dump/lol.size_of.005-015.ConstProp.after.mir 2023-11-28 14:38:07.519258465 +0000
@@ -1,4 +1,4 @@
-// MIR for `size_of` before ConstProp
+// MIR for `size_of` after ConstProp
fn size_of() -> usize {
let mut _0: usize;
@@ -11,7 +11,7 @@
StorageLive(_1);
_1 = const 0_usize;
_1 = const _;
- _0 = _1;
+ _0 = const 0_usize;
StorageDead(_1);
return;
} So it's defiantly happening in MIR ConstProp |
The problem seems to be that when running on the statement
(full log) |
@rustbot claim |
Rollup merge of rust-lang#118426 - aDotInTheVoid:const-wat, r=compiler-errors,cjgillot ConstProp: Correctly remove const if unknown value assigned to it. Closes rust-lang#118328 The problematic sequence of MIR is: ```rust _1 = const 0_usize; _1 = const _; // This is an associated constant we can't know before monomorphization. _0 = _1; ``` 1. When `ConstProp::visit_assign` happens on `_1 = const 0_usize;`, it records that `0x0usize` is the value for `_1`. 2. Next `visit_assign` happens on `_1 = const _;`. Because the rvalue `.has_param()`, it can't be const evaled. 3. Finaly, `visit_assign` happens on `_0 = _1;`. Here it would think the value of `_1` was `0x0usize` from step 1. The solution is to remove consts when checking the RValue fails, as they may have contained values that should now be invalidated, as that local was overwritten. This should probably be back-ported to beta. Stable is more iffy, as it's gone unidentified since 1.70, so I only think it's worthwhile if there's another reason for a 1.74.1 release anyway.
(cherry picked from commit b1a6cf4)
Cc @cjgillot |
Fuzzer generated MIR, reduced, and UB-free under Miri (for real this time 😅)
Segfaults with
ConstProp
enabled:Field::<*mut isize>(Variant(_12, 0), 0))
, which is a valid pointer, somehow got propagated as 0:The text was updated successfully, but these errors were encountered: