-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Wasm32 miscompilation when using u128 with multivalue and optimizations #127318
Comments
Reduced: #[inline(never)]
fn get_total_opt() -> (u64, u64) {
if std::hint::black_box(true) {
(1, 7)
} else {
(0, 5)
}
}
#[inline(never)]
fn calculate() -> u64 {
let (flag, val) = get_total_opt();
if flag != 0 {
val
} else {
42
}
}
fn main() {
dbg!(calculate());
} This should print Edit: further reduced (u128 and enums no longer required). |
Looking at the WASM (compiler explorer), the LLVM miscompilation appears to be related to locals. The WASM for the reduced calculate function is example::calculate::h0788ad06022fa2ed:
i64.const 42
local.get 0
call example::get_total_opt::hb7b536b220445017
local.set 0
i64.eqz
i64.select
end_function The |
@rustbot label -needs-triage +A-LLVM +T-compiler +I-unsound |
WG-prioritization assigning priority (Zulip discussion). @rustbot label -I-prioritize +P-high |
@alexcrichton do you have any insights about the state of the target feature |
My impression is that multivalue in the LLVM backend "in theory works" but is not that heavily tested. I believe the maintainers are interested in cataloguing bugs but I'm not sure if they're interested in actively fixing issues. The best thing to do with issues like this is to remove Rust from the equation and get a reproduction with just LLVM IR. That could then be submitted as an upstream LLVM bug report. |
Upstream issue: llvm/llvm-project#98323 |
I am getting a miscompiled wasm that incorrectly performs arithmetic operations on
u128
andOption<u128>
values. Based on my (poor) analysis of MIR, LLVM IR, and resulting wasm the issue seems to be on llvm side but it would be best for someone more competent to double-check that;I managed to get the reproduction down to this code:
Compiled with
rustc wasmmain.rs --target wasm32-wasi -C "target-feature=+multivalue" -C opt-level=s
And launched with wasmtime
I expected to see this happen: when entering two values above 100 (i.e. 111 and 111) I expect to see correct result (i.e. 333)
Instead, this happened:
The behavior seems to only be exhibited in the
calculate
function; replacingunwrap_or_default
withunwrap
or adding a side-effect between the call toget_total_opt
and the calculation seems to fix the issue. All of the changes to produced wasm are residing in thecalculate
function (if we exclude offsets changes)Also disabling the optimizations (
opt-level=0
) or turning off themultivalue
feature both address the issue as well. The issue also happens onwasm32-unknown-unknown
target but I don't have as clean of a setup to showcase thatEmitted MIR
Emitted llvm-ir
Emitted wasm (converted to wat with wasm2wat)
Both MIR and llvm-ir seem correct and with some
wasm2c
and simplification it seems like the resulting wasm is unconditionally returning thep2
and then conditionally returning eitherp3
orp3
+correspondingu64
of theOption<u128>
and I was able to confirm that with this modified programModified code
Code:
Output:
Meta
rustc --version --verbose
:rustc +nightly --version --verbose
:The text was updated successfully, but these errors were encountered: