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

Reply via email to