Skip to content

Commit 51b1ce6

Browse files
authored
Fix incorrect optimization in i64.mul_wide_s translation (#1545)
fix incorrect optimization in i64.mul_wide_s translation
1 parent 1a43c8e commit 51b1ce6

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

crates/wasmi/src/engine/translator/func/mod.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2408,20 +2408,21 @@ impl FuncTranslator {
24082408
&mut self,
24092409
make_instr: fn(results: FixedRegSpan<2>, lhs: Reg, rhs: Reg) -> Instruction,
24102410
const_eval: fn(lhs: i64, rhs: i64) -> (i64, i64),
2411+
signed: bool,
24112412
) -> Result<(), Error> {
24122413
bail_unreachable!(self);
24132414
let (lhs, rhs) = self.stack.pop2();
24142415
let (lhs, rhs) = match (lhs, rhs) {
24152416
(Provider::Register(lhs), Provider::Register(rhs)) => (lhs, rhs),
24162417
(Provider::Register(lhs), Provider::Const(rhs)) => {
2417-
if self.try_opt_i64_mul_wide_sx(lhs, rhs)? {
2418+
if self.try_opt_i64_mul_wide_sx(lhs, rhs, signed)? {
24182419
return Ok(());
24192420
}
24202421
let rhs = self.stack.alloc_const(rhs)?;
24212422
(lhs, rhs)
24222423
}
24232424
(Provider::Const(lhs), Provider::Register(rhs)) => {
2424-
if self.try_opt_i64_mul_wide_sx(rhs, lhs)? {
2425+
if self.try_opt_i64_mul_wide_sx(rhs, lhs, signed)? {
24252426
return Ok(());
24262427
}
24272428
let lhs = self.stack.alloc_const(lhs)?;
@@ -2446,16 +2447,22 @@ impl FuncTranslator {
24462447
///
24472448
/// - Returns `Ok(true)` if the optimiation was applied successfully.
24482449
/// - Returns `Ok(false)` if no optimization was applied.
2449-
fn try_opt_i64_mul_wide_sx(&mut self, reg_in: Reg, imm_in: TypedVal) -> Result<bool, Error> {
2450+
fn try_opt_i64_mul_wide_sx(
2451+
&mut self,
2452+
reg_in: Reg,
2453+
imm_in: TypedVal,
2454+
signed: bool,
2455+
) -> Result<bool, Error> {
24502456
let imm_in = i64::from(imm_in);
24512457
if imm_in == 0 {
24522458
// Case: `mul(x, 0)` or `mul(0, x)` always evaluates to 0.
24532459
self.stack.push_const(0_i64); // lo-bits
24542460
self.stack.push_const(0_i64); // hi-bits
24552461
return Ok(true);
24562462
}
2457-
if imm_in == 1 {
2458-
// Case: `mul(x, 1)` or `mul(0, x)` always evaluates to just `x`.
2463+
if imm_in == 1 && !signed {
2464+
// Case: `mul(x, 1)` or `mul(1, x)` always evaluates to just `x`.
2465+
// This is only valid if `x` is not a singed (negative) value.
24592466
self.stack.push_register(reg_in)?; // lo-bits
24602467
self.stack.push_const(0_i64); // hi-bits
24612468
return Ok(true);

crates/wasmi/src/engine/translator/func/visit.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3247,10 +3247,10 @@ impl<'a> VisitOperator<'a> for FuncTranslator {
32473247
}
32483248

32493249
fn visit_i64_mul_wide_s(&mut self) -> Self::Output {
3250-
self.translate_i64_mul_wide_sx(Instruction::i64_mul_wide_s, wasm::i64_mul_wide_s)
3250+
self.translate_i64_mul_wide_sx(Instruction::i64_mul_wide_s, wasm::i64_mul_wide_s, true)
32513251
}
32523252

32533253
fn visit_i64_mul_wide_u(&mut self) -> Self::Output {
3254-
self.translate_i64_mul_wide_sx(Instruction::i64_mul_wide_u, wasm::i64_mul_wide_u)
3254+
self.translate_i64_mul_wide_sx(Instruction::i64_mul_wide_u, wasm::i64_mul_wide_u, false)
32553255
}
32563256
}

0 commit comments

Comments
 (0)