Wasmer with llvm compiler gives wrong execution result for extmul instructions. The PoC code is as the following:
use wasmer::sys::{EngineBuilder, Features};
use wasmer::{imports, Cranelift, CraneliftOptLevel, Instance, Memory, MemoryType, Module, Store, CompilerConfig};
use wasmer_compiler_llvm::{LLVM, LLVMOptLevel};
use anyhow::Error;
fn main() -> Result<(), Error> {
let diff = 0; // CHANGE HERE!!! (0 and 1)
let mut features = Features::new();
features.multi_value(true);
features.simd(true);
features.threads(true);
let engine = if diff == 0 {
let mut compiler = Cranelift::default();
compiler.canonicalize_nans(true);
compiler.opt_level(CraneliftOptLevel::None);
let engine = EngineBuilder::new(compiler).set_features(Some(features));
engine
} else {
let mut compiler = LLVM::default();
compiler.canonicalize_nans(true);
compiler.opt_level(LLVMOptLevel::None);
let engine = EngineBuilder::new(compiler).set_features(Some(features));
engine
};
let module_wat = r#"
(module
(type (;0;) (func (result v128)))
(import "mem" "mem" (memory (;0;) 1))
(func (;0;) (type 0)
v128.const i32x4 0x40404040 0x40404040 0x40404040 0x40404040
v128.const i32x4 0x00010203 0x807f7e7d 0xcccdcecf 0xfffefdfc
i16x8.extmul_low_i8x16_s)
(export "main" (func 0)))
"#;
let mut store = Store::new(engine);
let module = Module::new(&store, &module_wat)?;
let memory_ty = MemoryType::new(1, None, false);
let memory = Memory::new(&mut store, memory_ty)?;
let imports = imports!{
"mem" => {
"mem" => memory.clone()
}
};
let instance = Instance::new(&mut store, &module, &imports)?;
let main = instance.exports.get_function("main")
.expect("`main` was not an exported function");
let result = main.call(&mut store, vec![].as_slice());
println!("{:?}", result);
Ok(())
}
[package]
name = "wasmer-wrapper"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
wasmer = { version = "4.2.8", features = ["cranelift", "singlepass", "compiler"] }
wasmer-compiler-llvm = "4.2.8"
anyhow = "1.0"
Steps to reproduce
You can change the value of the variable diff on line 7. (with 0 and 1) It will choose the compiler between Cranelift and llvm.
cargo run --release
Expected behavior
The output should be the one below as Cranelift gives. (0xe0001fc0_1f801f40_00000040_008000c0) This value is checked to be correct with the WebAssembly interpreter.
Describe the bug
Wasmer with llvm compiler gives wrong execution result for
extmul
instructions. The PoC code is as the following:Steps to reproduce
You can change the value of the variable
diff
on line 7. (with 0 and 1) It will choose the compiler between Cranelift and llvm.Expected behavior
The output should be the one below as Cranelift gives. (
0xe0001fc0_1f801f40_00000040_008000c0
) This value is checked to be correct with the WebAssembly interpreter.Actual behavior
Execution with the llvm compiler gives the following result: (
0xff80ff00_f340f3c0_1fc01f40_004000c0
)Additional context