@@ -2408,20 +2408,21 @@ impl FuncTranslator {
2408
2408
& mut self ,
2409
2409
make_instr : fn ( results : FixedRegSpan < 2 > , lhs : Reg , rhs : Reg ) -> Instruction ,
2410
2410
const_eval : fn ( lhs : i64 , rhs : i64 ) -> ( i64 , i64 ) ,
2411
+ signed : bool ,
2411
2412
) -> Result < ( ) , Error > {
2412
2413
bail_unreachable ! ( self ) ;
2413
2414
let ( lhs, rhs) = self . stack . pop2 ( ) ;
2414
2415
let ( lhs, rhs) = match ( lhs, rhs) {
2415
2416
( Provider :: Register ( lhs) , Provider :: Register ( rhs) ) => ( lhs, rhs) ,
2416
2417
( 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 ) ? {
2418
2419
return Ok ( ( ) ) ;
2419
2420
}
2420
2421
let rhs = self . stack . alloc_const ( rhs) ?;
2421
2422
( lhs, rhs)
2422
2423
}
2423
2424
( 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 ) ? {
2425
2426
return Ok ( ( ) ) ;
2426
2427
}
2427
2428
let lhs = self . stack . alloc_const ( lhs) ?;
@@ -2446,16 +2447,22 @@ impl FuncTranslator {
2446
2447
///
2447
2448
/// - Returns `Ok(true)` if the optimiation was applied successfully.
2448
2449
/// - 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 > {
2450
2456
let imm_in = i64:: from ( imm_in) ;
2451
2457
if imm_in == 0 {
2452
2458
// Case: `mul(x, 0)` or `mul(0, x)` always evaluates to 0.
2453
2459
self . stack . push_const ( 0_i64 ) ; // lo-bits
2454
2460
self . stack . push_const ( 0_i64 ) ; // hi-bits
2455
2461
return Ok ( true ) ;
2456
2462
}
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.
2459
2466
self . stack . push_register ( reg_in) ?; // lo-bits
2460
2467
self . stack . push_const ( 0_i64 ) ; // hi-bits
2461
2468
return Ok ( true ) ;
0 commit comments