LibJS: Optimize x >> 0 to ToInt32 in bytecode codegen

x >> 0 is a common JS idiom equivalent to ToInt32(x). We already had
this optimization for x | 0, now do it for right shift by zero as well.

This allows the asmint handler for ToInt32 to run instead of the more
expensive RightShift handler, which wastes time loading and checking the
rhs operand and performing a shift by zero.
This commit is contained in:
Andreas Kling 2026-03-18 15:30:34 -05:00 committed by Andreas Kling
parent 02b0746676
commit bb0acb54ae
3 changed files with 52 additions and 5 deletions

View file

@ -2077,11 +2077,29 @@ fn emit_binary_op(
lhs: lhs_op,
rhs: rhs_op,
}),
BinaryOp::RightShift => generator.emit(Instruction::RightShift {
dst: dst_op,
lhs: lhs_op,
rhs: rhs_op,
}),
BinaryOp::RightShift => {
// OPTIMIZATION: x >> 0 == ToInt32(x) (matches C++)
if let Some(ConstantValue::Number(n)) = generator.get_constant(rhs) {
if *n == 0.0 && n.is_sign_positive() {
generator.emit(Instruction::ToInt32 {
dst: dst_op,
value: lhs_op,
});
} else {
generator.emit(Instruction::RightShift {
dst: dst_op,
lhs: lhs_op,
rhs: rhs_op,
});
}
} else {
generator.emit(Instruction::RightShift {
dst: dst_op,
lhs: lhs_op,
rhs: rhs_op,
});
}
}
BinaryOp::UnsignedRightShift => generator.emit(Instruction::UnsignedRightShift {
dst: dst_op,
lhs: lhs_op,

View file

@ -0,0 +1,24 @@
$a08063d8 right-shift-by-zero.js:5:1
Registers: 7
Blocks: 1
Constants:
[0] = Undefined
[1] = Double(1.5)
block0:
[ 0] GetLexicalEnvironment dst:reg4
[ 8] GetGlobal dst:reg6, `foo`
[ 20] Call dst:reg5, callee:reg6, this_value:Undefined, foo, arguments:[Double(1.5)]
[ 48] End value:reg5
foo$197906fe right-shift-by-zero.js:2:5
Registers: 6
Blocks: 1
Constants:
[0] = Int32(0)
block0:
[ 0] GetLexicalEnvironment dst:reg4
[ 8] ToInt32 dst:reg5, value:arg0
[ 18] Return value:reg5

View file

@ -0,0 +1,5 @@
function foo(x) {
return x >> 0;
}
foo(1.5);