Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 83895848013f99c39586e536b8ea0d25b7ad7b31
https://github.com/WebKit/WebKit/commit/83895848013f99c39586e536b8ea0d25b7ad7b31
Author: Sosuke Suzuki <[email protected]>
Date: 2026-04-06 (Mon, 06 Apr 2026)
Changed paths:
A JSTests/stress/dfg-arith-mul-bitand-negative-mask-unchecked.js
M Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp
Log Message:
-----------
[JSC] `isWithinPowerOfTwo` is unsound for BitAnd with negative mask in DFG
BackwardsPropagation
https://bugs.webkit.org/show_bug.cgi?id=311505
Reviewed by Justin Michaud.
isWithinPowerOfTwo<power>() returned true for `x & c` whenever |c| < 2^power,
but this bound only holds when c is non-negative. A negative mask preserves
the sign bit, so `x & -4` can span the full int32 range. This caused ArithMul
to drop NodeBytecodeUsesAsNumber and become Arith::Unchecked, producing the
low 32 bits of the exact product instead of the spec-mandated double-rounded
result.
function f(a, b) { return ((a & -4) * b) | 0; }
f(0x7ffffffc, 0x7ffffffc) // LLInt: 0, DFG/FTL: 16
Fix by requiring the BitAnd constant operand to be non-negative. Also remove
isWithinPowerOfTwoNonRecursive() which is now unused.
Test: JSTests/stress/dfg-arith-mul-bitand-negative-mask-unchecked.js
* JSTests/stress/dfg-arith-mul-bitand-negative-mask-unchecked.js: Added.
(testMaskRight):
(testMaskLeft):
(testMaskRightSwappedMul):
* Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp:
(JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwo):
(JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwoNonRecursive): Deleted.
Canonical link: https://commits.webkit.org/310678@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications