diff --git a/crates/wasmi/src/engine/translator/tests/regression/fuzz_2.wat b/crates/wasmi/src/engine/translator/tests/regression/fuzz_2.wat new file mode 100644 index 0000000000..de34d6ecf9 --- /dev/null +++ b/crates/wasmi/src/engine/translator/tests/regression/fuzz_2.wat @@ -0,0 +1,11 @@ +(module + (func (;0;) (param i32) + (local.tee 0 (local.get 0)) + (local.tee 0 (local.get 0)) + (if (param i32) ;; label = @1 + (then (drop)) + (else (drop)) + ) + ) + (export "" (func 0)) +) diff --git a/crates/wasmi/src/engine/translator/tests/regression/mod.rs b/crates/wasmi/src/engine/translator/tests/regression/mod.rs index 19c4494b1e..6d8f1cfdc9 100644 --- a/crates/wasmi/src/engine/translator/tests/regression/mod.rs +++ b/crates/wasmi/src/engine/translator/tests/regression/mod.rs @@ -1,4 +1,5 @@ use super::*; +use crate::engine::bytecode::{BranchOffset, BranchOffset16}; #[test] #[cfg_attr(miri, ignore)] @@ -27,3 +28,17 @@ fn fuzz_regression_1() { ]) .run() } + +#[test] +#[cfg_attr(miri, ignore)] +fn fuzz_regression_2() { + let wat = include_str!("fuzz_2.wat"); + let wasm = wat2wasm(wat); + TranslationTest::new(wasm) + .expect_func_instrs([ + Instruction::branch_i32_eq_imm(Register::from_i16(0), 0, BranchOffset16::from(2)), + Instruction::branch(BranchOffset::from(1)), + Instruction::Return, + ]) + .run() +} diff --git a/crates/wasmi/src/engine/translator/visit.rs b/crates/wasmi/src/engine/translator/visit.rs index 563acc09e7..5890fd1911 100644 --- a/crates/wasmi/src/engine/translator/visit.rs +++ b/crates/wasmi/src/engine/translator/visit.rs @@ -790,6 +790,15 @@ impl<'a> VisitOperator<'a> for FuncTranslator<'a> { bail_unreachable!(self); let value = self.alloc.stack.pop(); let local = Register::try_from(local_index)?; + if let TypedProvider::Register(value) = value { + if value == local { + // Case: `(local.set $n (local.get $n))` is a no-op so we can ignore it. + // + // Note: This does not require any preservation since it won't change + // the value of `local $n`. + return Ok(()); + } + } let preserved = self.alloc.stack.preserve_locals(local_index)?; let fuel_info = self.fuel_info(); self.alloc.instr_encoder.encode_local_set(