Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 6dd325c7d06792f0f623a820e643bfd3e3dcde2c
      
https://github.com/WebKit/WebKit/commit/6dd325c7d06792f0f623a820e643bfd3e3dcde2c
  Author: Yusuke Suzuki <[email protected]>
  Date:   2026-09-25 (Fri, 25 Sep 2026)

  Changed paths:
    A JSTests/stress/b3-specialize-select-should-not-clone-phis.js
    M Source/JavaScriptCore/b3/B3SpecializeSelect.cpp
    M Source/JavaScriptCore/b3/testb3.h
    M Source/JavaScriptCore/b3/testb3_1.cpp
    M Source/JavaScriptCore/b3/testb3_6.cpp

  Log Message:
  -----------
  [JSC] B3 specializeSelect must not clone Phis
https://bugs.webkit.org/show_bug.cgi?id=325312
rdar://188290503

Reviewed by Dan Hecht.

B3 specializeSelect's job is like this.

    Turn this:

        @a = Select(@p, @x, 42)
        @b = Add(@a, 35)
        Check(@b)

    into this:

        Branch(@p, #truecase, #falsecase)

      BB#truecase:
        @b_truecase = Add(@x, 35)
        Check(@b_truecase)
        Upsilon(@x, ^a)
        Upsilon(@b_truecase, ^b)
        Jump(#continuation)

      BB#falsecase:
        @b_falsecase = Add(42, 35)
        Check(@b_falsecase)
        Upsilon(42, ^a)
        Upsilon(@b_falsecase, ^b)
        Jump(#continuation)

      BB#continuation:
        @a = Phi()
        @b = Phi()

We need to clone values between Select and Check. But this should not
include `Phi` node. Let's see the example,

    b@63 = Select(b@52, $7, $6)
           Upsilon(b@63, ^11)
    b@11 = Phi()
    b@65 = BitAnd(b@63, $-562949953421310)
    b@66 = NotEqual(b@65, $0)
           Check(b@66, b@63:ColdAny, b@52:ColdAny, b@11:ColdAny)
           Patchpoint(...) / CCall / Oops

gets converted to,

    BB#5:
            Branch(b@52) -> #6, #7
    BB#6:                                          ; true arm
            Upsilon($7, ^63)
            Upsilon($7, ^11)          ; correct: writes 7 into b@11's slot
        b@64 = Phi()                  ; clone of b@11: its slot is never 
written -> garbage
            Upsilon(b@64, ^11)        ; overwrites the 7 with the garbage
        b@81 = BitAnd($7, $-562949953421310)
            Upsilon(b@81, ^65)
        b@85 = NotEqual(b@81, $0)
            Upsilon(b@85, ^66)
            Check(b@85, $7:ColdAny, b@52:ColdAny, b@64:ColdAny)   ; exit state 
for `v` = garbage
            Jump #8
    BB#7:                                          ; false arm, same shape with 
$6 and b@79
            ...
    BB#8:
        b@63 = Phi()
        b@11 = Phi()                  ; receives garbage from both arms
        b@65 = Phi()
        b@66 = Phi()
            Patchpoint(b@63, ...) / Oops

Then b@64 Phi is broken since no value is written into this slot.

This patch fixes this issue by avoiding Phi cloning.

Tests: JSTests/stress/b3-specialize-select-should-not-clone-phis.js
       Source/JavaScriptCore/b3/testb3_1.cpp
       Source/JavaScriptCore/b3/testb3_6.cpp

* JSTests/stress/b3-specialize-select-should-not-clone-phis.js: Added.
(f):
* Source/JavaScriptCore/b3/B3SpecializeSelect.cpp:
* Source/JavaScriptCore/b3/testb3.h:
* Source/JavaScriptCore/b3/testb3_1.cpp:
(run):
* Source/JavaScriptCore/b3/testb3_6.cpp:
(testCheckSelectWithPhiBeforeCheck):
(testCheckSelectWithUpsilonBeforeCheck):

Canonical link: https://commits.webkit.org/321956@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to