<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>313005</bug_id>
          
          <creation_ts>2026-04-22 10:27:25 -0700</creation_ts>
          <short_desc>[JSC] ASSERTION FAILED: a.tmp1.tmpIndex(bank) != b.tmp1.tmpIndex(bank) in AirAllocateRegistersByGreedy.cpp buildCoalescingGroups</short_desc>
          <delta_ts>2026-04-23 11:12:44 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>JavaScriptCore</component>
          <version>WebKit Nightly Build</version>
          <rep_platform>Mac (Intel)</rep_platform>
          <op_sys>macOS 14</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>InRadar</keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter>2576361468</reporter>
          <assigned_to name="Dan Hecht">dan.hecht</assigned_to>
          <cc>2576361468</cc>
    
    <cc>syg</cc>
    
    <cc>webkit-bug-importer</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>2203214</commentid>
    <comment_count>0</comment_count>
      <attachid>479243</attachid>
    <who name="">2576361468</who>
    <bug_when>2026-04-22 10:27:25 -0700</bug_when>
    <thetext>Created attachment 479243
test js file

**Summary**

The Greedy register allocator&apos;s `buildCoalescingGroups` function crashes with an assertion failure due to duplicate Move entries sharing the same (cost, tmp0, tmp1) triple.

**Steps to Reproduce**

Save the following as `test.js` and run with a debug or ASan-enabled JSC:

```
let buf = new ArrayBuffer(64);
let ta = new Float64Array(buf);
for (let i = 0; i &lt; 8; i++) ta[i] = i + 0.5;

function iterateTA(a) {
    let sum = 0;
    for (let v of a) sum += v;
    return sum;
}

for (let i = 0; i &lt; 1e4; i++) iterateTA(ta);

let newBuf = buf.transfer();
try { iterateTA(ta); } catch(e) { print(e); }
```

Command:

```
jsc test.js
```

No special flags needed — the function gets FTL-compiled through the warmup loop.

**Expected Result**

The program prints a TypeError (from iterating a detached TypedArray) and exits normally.

**Actual Result**

Assertion failure in `AirAllocateRegistersByGreedy.cpp` line 1843, followed by SIGILL (exit code 132):

```
ASSERTION FAILED: a.tmp1.tmpIndex(bank) != b.tmp1.tmpIndex(bank)
AirAllocateRegistersByGreedy.cpp(1843) : auto JSC::B3::Air::Greedy::GreedyAllocator::buildCoalescingGroups(...)
```

**Analysis**

In `buildCoalescingGroups&lt;bank&gt;()` (lines 1838-1845), the sort comparator for Move objects assumes no two Move entries share the same (cost, tmp0, tmp1) triple:

```cpp
std::ranges::sort(moves, [](auto&amp; a, auto&amp; b) {
    if (a.cost != b.cost) return a.cost &gt; b.cost;
    if (a.tmp0.tmpIndex(bank) != b.tmp0.tmpIndex(bank))
        return a.tmp0.tmpIndex(bank) &lt; b.tmp0.tmpIndex(bank);
    ASSERT(a.tmp1.tmpIndex(bank) != b.tmp1.tmpIndex(bank)); // FAILS
    return a.tmp1.tmpIndex(bank) &lt; b.tmp1.tmpIndex(bank);
});
```

The Move list is built at lines 1828-1835 by iterating each Tmp&apos;s `coalescables` list. The deduplication filter (`tmp &lt; with.tmp` at line 1833) prevents reversed pairs but does not prevent the same (tmp0, tmp1) pair from appearing multiple times when they share the same coalescing cost from multiple coalescing opportunities.

I note that the coalescing loop at lines 1847-1855 has an &quot;Already grouped&quot; check that safely skips duplicate entries, so in Release builds (where the ASSERT is compiled out) the duplicates are harmless — the comparator returns `false` for equal elements which satisfies strict weak ordering. The impact is limited to debug/ASan assertion crashes.

Multiple JS patterns trigger this — TypedArray for-of + detach (above), Proxy iteration, Map.forEach with clear — suggesting it is a general issue in the Move list construction, not specific to any particular JS construct.

**Introduced By**

I believe this was introduced by commit f8b9ab1a0bf (2026-03-17): &quot;[JSC] Rewrite of the greedy register allocator&apos;s coalescing strategy&quot; (Bug 309992 / rdar://172621751).

**Suggested Fix**

Either remove the ASSERT (the comparator is already correct for equal elements), or deduplicate the `moves` vector before sorting.

**Environment**

- WebKit main branch @ HEAD (tested 2026-04-22)
- macOS 14, x86_64
- ASan build (JSCOnly/Release with -fsanitize=address)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2203447</commentid>
    <comment_count>1</comment_count>
    <who name="Radar WebKit Bug Importer">webkit-bug-importer</who>
    <bug_when>2026-04-22 17:11:23 -0700</bug_when>
    <thetext>&lt;rdar://problem/175382009&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2203481</commentid>
    <comment_count>2</comment_count>
    <who name="Shu-yu Guo">syg</who>
    <bug_when>2026-04-22 17:51:28 -0700</bug_when>
    <thetext>I&apos;m having trouble reproducing this on Apple Silicon at 311814@main. What commit did you test? Could you provide your exact build configuration?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2203484</commentid>
    <comment_count>3</comment_count>
    <who name="Shu-yu Guo">syg</who>
    <bug_when>2026-04-22 18:06:04 -0700</bug_when>
    <thetext>I also can&apos;t reproduce on x64 using Rosetta.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2203508</commentid>
    <comment_count>4</comment_count>
    <who name="">2576361468</who>
    <bug_when>2026-04-22 20:11:50 -0700</bug_when>
    <thetext>Thank you for looking into this, and sorry for the trouble reproducing.

https://drive.google.com/file/d/1mPMCG0sAmEm29ivc9emYhMQoGRTcDecr/view?usp=drive_link

## Exact build info

**Source:** WebKit main @ **311660@main** (commit `2fa13e45b258`)

**Host:** macOS 14.1.1 (23B81), native Intel x86_64 (Core i5-1038NG7) — *not* Apple Silicon, *not* Rosetta.

**Toolchain:**

- Apple clang 15.0.0 (clang-1500.0.40.1) from CommandLineTools (no Xcode.app)
- CMake 3.23.3 (MacPorts), Ninja 1.11.0

**Build steps:**

```bash
# 1. Enable ASan configuration
Tools/Scripts/set-webkit-configuration --asan --release

# 2. Build
Tools/Scripts/build-webkit --jsc-only --release
```

This produces a JSCOnly Release build with ASan and assertions enabled. The relevant CMake cache values:

```
CMAKE_BUILD_TYPE            = Release
PORT                        = JSCOnly
DEVELOPER_MODE              = ON
ENABLE_ADDRESS_SANITIZER    = ON  (via set-webkit-configuration --asan)
ENABLE_ASSERTS              = AUTO (resolves to ON for ASan/developer builds)
ENABLE_JIT / DFG / FTL      = ON
ENABLE_C_LOOP               = OFF
USE_SYSTEM_MALLOC            = OFF
CMAKE_CXX_FLAGS_RELEASE     = -O1 -g -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls
CMAKE_EXE_LINKER_FLAGS      = -Wl,-no_compact_unwind -fsanitize=address
CMAKE_OSX_SYSROOT            = MacOSX14.0.sdk
```

I can attach the full CMakeCache.txt (1614 lines) if that would help.

**Run command:**

```bash
DYLD_FRAMEWORK_PATH=jsc-asan-x86_64-311660/lib jsc-asan-x86_64-311660/bin/jsc test.js
```

No special env vars or JSC flags needed beyond the framework path. The test case is the 14-line reproducer from the original report.

**Output (deterministic, 5/5 runs):**

```
ASSERTION FAILED: a.tmp1.tmpIndex(bank) != b.tmp1.tmpIndex(bank)
AirAllocateRegistersByGreedy.cpp(1843) : ...buildCoalescingGroups(...)
```

Exit code 132 (SIGILL from CRASH() after assertion failure).

## Why it likely doesn&apos;t reproduce on Apple Silicon or Rosetta

I think this is a **native x86_64-only** issue, for two related reasons:

1. **ARM64 vs x86_64 register sets produce different B3 IR.** x86_64 has fewer general-purpose registers (16 vs 31), creating more register pressure. This means more spills, more moves, and more coalescing opportunities in Air — increasing the chance that two Move entries end up with identical `(cost, tmp0, tmp1)` triples, which is what triggers the assertion. On ARM64 the same JS function may simply never produce a duplicate triple because there&apos;s less coalescing pressure.

2. **Rosetta alters tier-up behavior.** Even with an x86_64 binary, Rosetta&apos;s translation overhead changes execution timing, GC behavior, and profiling heuristics. This can shift when (or whether) FTL compilation fires, and with what profiling data — producing different B3 IR that doesn&apos;t hit the duplicate condition. In some cases Rosetta may cause FTL to not fire at all for this function, in which case `buildCoalescingGroups` is never reached.

To reproduce, I believe you would need a **native x86_64** build on an actual Intel Mac (or an x86_64 CI bot), built with `set-webkit-configuration --asan &amp;&amp; build-webkit --jsc-only --release`.

If that&apos;s not practical, I completely understand and am happy to close this. The issue is assertion-only (the comparator is correct for equal elements under strict weak ordering), so it does not affect Release builds without assertions. Let me know how you&apos;d like to proceed.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2203712</commentid>
    <comment_count>5</comment_count>
    <who name="Dan Hecht">dan.hecht</who>
    <bug_when>2026-04-23 08:56:08 -0700</bug_when>
    <thetext>Pull request: https://github.com/WebKit/WebKit/pull/63431</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2203714</commentid>
    <comment_count>6</comment_count>
    <who name="Dan Hecht">dan.hecht</who>
    <bug_when>2026-04-23 09:11:41 -0700</bug_when>
    <thetext>&gt;  but does not prevent the same (tmp0, tmp1) pair from appearing multiple times when they share the same coalescing cost from multiple coalescing opportunities.

The coalescables lists never have duplicates to begin with, see Coalescables::add(). So this is not a valid explanation.

See the pull request for a possible explanation.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2203775</commentid>
    <comment_count>7</comment_count>
    <who name="EWS">ews-feeder</who>
    <bug_when>2026-04-23 11:12:42 -0700</bug_when>
    <thetext>Committed 311871@main (51024b1e8ca6): &lt;https://commits.webkit.org/311871@main&gt;

Reviewed commits have been landed. Closing PR #63431 and removing active labels.</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="0"
              isprivate="0"
          >
            <attachid>479243</attachid>
            <date>2026-04-22 10:27:25 -0700</date>
            <delta_ts>2026-04-22 10:27:25 -0700</delta_ts>
            <desc>test js file</desc>
            <filename>test.js</filename>
            <type>application/x-javascript</type>
            <size>3405</size>
            <attacher>2576361468</attacher>
            
              <data encoding="base64">Ly8gQjMgQWlyIEdyZWVkeSBSZWdpc3RlciBBbGxvY2F0b3I6IGJ1aWxkQ29hbGVzY2luZ0dyb3Vw
cyBhc3NlcnRpb24gZmFpbHVyZQovLyBBaXJBbGxvY2F0ZVJlZ2lzdGVyc0J5R3JlZWR5LmNwcDox
ODQzIEFTU0VSVChhLnRtcDEudG1wSW5kZXgoYmFuaykgIT0gYi50bXAxLnRtcEluZGV4KGJhbmsp
KQovLwovLyBUaGUgc29ydCBjb21wYXJhdG9yIGZvciBNb3ZlIG9iamVjdHMgYXNzdW1lcyBubyB0
d28gbW92ZXMgc2hhcmUgdGhlIHNhbWUKLy8gKGNvc3QsIHRtcDAsIHRtcDEpIHRyaXBsZS4gV2hl
biBkdXBsaWNhdGUgbW92ZXMgZXhpc3QsIHRoZSBBU1NFUlQgZmlyZXMuCi8vIEluIFJlbGVhc2Ug
YnVpbGRzLCBkdXBsaWNhdGVzIGNhdXNlIGluY29ycmVjdCBjb2FsZXNjaW5nIGRlY2lzaW9ucy4K
Ly8KLy8gUm9vdCBjYXVzZTogdGhlIGxvb3AgYXQgbGluZXMgMTgyOC0xODM1IGNhbiBnZW5lcmF0
ZSBkdXBsaWNhdGUgTW92ZSBlbnRyaWVzCi8vIHdoZW4gdGhlIHNhbWUgcGFpciBvZiB0ZW1wb3Jh
cmllcyBoYXMgbXVsdGlwbGUgY29hbGVzY2luZyBvcHBvcnR1bml0aWVzCi8vIChlLmcuLCBmcm9t
IG11bHRpcGxlIG1vdmUgaW5zdHJ1Y3Rpb25zIGJldHdlZW4gdGhlIHNhbWUgVG1wcykuCi8vCi8v
IFRyaWdnZXI6IEZUTCBjb21waWxhdGlvbiBvZiBUeXBlZEFycmF5IGZvci1vZiArIGRldGFjaCwg
b3IgdmFyaW91cwovLyBjYWxsYmFjayBwYXR0ZXJucyB0aGF0IGdlbmVyYXRlIGNvbXBsZXggQjMg
SVIgd2l0aCByZWR1bmRhbnQgbW92ZXMuCgovLyBNaW5pbWFsIHRyaWdnZXIgKFR5cGVkQXJyYXkg
Zm9yLW9mICsgZGV0YWNoKQpsZXQgYnVmID0gbmV3IEFycmF5QnVmZmVyKDY0KTsKbGV0IHRhID0g
bmV3IEZsb2F0NjRBcnJheShidWYpOwpmb3IgKGxldCBpID0gMDsgaSA8IDg7IGkrKykgdGFbaV0g
PSBpICsgMC41OwoKZnVuY3Rpb24gaXRlcmF0ZVRBKGEpIHsKICAgIGxldCBzdW0gPSAwOwogICAg
Zm9yIChsZXQgdiBvZiBhKSBzdW0gKz0gdjsKICAgIHJldHVybiBzdW07Cn0KCi8vIFdhcm11cCB0
byBGVEwKZm9yIChsZXQgaSA9IDA7IGkgPCAxZTQ7IGkrKykgaXRlcmF0ZVRBKHRhKTsKCi8vIERl
dGFjaCBhbmQgaXRlcmF0ZSAodHJpZ2dlcnMgVHlwZUVycm9yIGJ1dCB0aGUgY3Jhc2ggaXMgaW4g
RlRMIGNvbXBpbGF0aW9uKQpsZXQgbmV3QnVmID0gYnVmLnRyYW5zZmVyKCk7CnRyeSB7IGl0ZXJh
dGVUQSh0YSk7IH0gY2F0Y2goZSkgeyBwcmludChlKTsgfQoKLy8gVmFyaWFudCAyOiB0cnkgdG8g
Z2V0IG1pc2NvbXBpbGVkIGNvZGUgdG8gcHJvZHVjZSB3cm9uZyByZXN1bHRzCi8vIElmIGNvYWxl
c2NpbmcgaW5jb3JyZWN0bHkgbWVyZ2VzIHR3byBUbXBzLCBhIHZhbHVlIGZyb20gb25lIG1heSBs
ZWFrIHRvIHRoZSBvdGhlcgpsZXQgYnVmMiA9IG5ldyBBcnJheUJ1ZmZlcigxMjgpOwpsZXQgdGEy
ID0gbmV3IEZsb2F0NjRBcnJheShidWYyKTsKZm9yIChsZXQgaSA9IDA7IGkgPCAxNjsgaSsrKSB0
YTJbaV0gPSBpICogMS41ICsgMC4xOwoKZnVuY3Rpb24gY29tcGxleEl0ZXJhdGUoYSkgewogICAg
bGV0IHN1bSA9IDA7CiAgICBsZXQgcHJvZHVjdCA9IDE7CiAgICBsZXQgY291bnQgPSAwOwogICAg
Zm9yIChsZXQgdiBvZiBhKSB7CiAgICAgICAgc3VtICs9IHY7CiAgICAgICAgaWYgKHYgPiA1KSBw
cm9kdWN0ICo9IHY7CiAgICAgICAgY291bnQrKzsKICAgIH0KICAgIHJldHVybiBbc3VtLCBwcm9k
dWN0LCBjb3VudF07Cn0KCmZvciAobGV0IGkgPSAwOyBpIDwgMWU0OyBpKyspIGNvbXBsZXhJdGVy
YXRlKHRhMik7CgpsZXQgW3MsIHAsIGNdID0gY29tcGxleEl0ZXJhdGUodGEyKTsKbGV0IGV4cGVj
dGVkU3VtID0gMDsKZm9yIChsZXQgaSA9IDA7IGkgPCAxNjsgaSsrKSBleHBlY3RlZFN1bSArPSBp
ICogMS41ICsgMC4xOwpsZXQgZXhwZWN0ZWRQcm9kdWN0ID0gMTsKZm9yIChsZXQgaSA9IDA7IGkg
PCAxNjsgaSsrKSB7IGxldCB2ID0gaSAqIDEuNSArIDAuMTsgaWYgKHYgPiA1KSBleHBlY3RlZFBy
b2R1Y3QgKj0gdjsgfQoKaWYgKE1hdGguYWJzKHMgLSBleHBlY3RlZFN1bSkgPiAwLjAxKSB7CiAg
ICBwcmludCgiW1ZVTE5dIFdyb25nIHN1bTogIiArIHMgKyAiIGV4cGVjdGVkICIgKyBleHBlY3Rl
ZFN1bSk7Cn0gZWxzZSB7CiAgICBwcmludCgiW09LXSBTdW0gY29ycmVjdDogIiArIHMpOwp9Cmlm
IChNYXRoLmFicyhwIC0gZXhwZWN0ZWRQcm9kdWN0KSA+IDAuMDEpIHsKICAgIHByaW50KCJbVlVM
Tl0gV3JvbmcgcHJvZHVjdDogIiArIHAgKyAiIGV4cGVjdGVkICIgKyBleHBlY3RlZFByb2R1Y3Qp
Owp9IGVsc2UgewogICAgcHJpbnQoIltPS10gUHJvZHVjdCBjb3JyZWN0OiAiICsgcCk7Cn0KCi8v
IFZhcmlhbnQgMzogaGlnaCByZWdpc3RlciBwcmVzc3VyZSB0byBzdHJlc3MgdGhlIGFsbG9jYXRv
cgpmdW5jdGlvbiBoaWdoUHJlc3N1cmUoYSkgewogICAgbGV0IHYwID0gMCwgdjEgPSAwLCB2MiA9
IDAsIHYzID0gMDsKICAgIGxldCB2NCA9IDAsIHY1ID0gMCwgdjYgPSAwLCB2NyA9IDA7CiAgICBs
ZXQgaWR4ID0gMDsKICAgIGZvciAobGV0IHYgb2YgYSkgewogICAgICAgIHN3aXRjaCAoaWR4ICYg
NykgewogICAgICAgICAgICBjYXNlIDA6IHYwICs9IHY7IGJyZWFrOwogICAgICAgICAgICBjYXNl
IDE6IHYxICs9IHY7IGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6IHYyICs9IHY7IGJyZWFrOwog
ICAgICAgICAgICBjYXNlIDM6IHYzICs9IHY7IGJyZWFrOwogICAgICAgICAgICBjYXNlIDQ6IHY0
ICs9IHY7IGJyZWFrOwogICAgICAgICAgICBjYXNlIDU6IHY1ICs9IHY7IGJyZWFrOwogICAgICAg
ICAgICBjYXNlIDY6IHY2ICs9IHY7IGJyZWFrOwogICAgICAgICAgICBjYXNlIDc6IHY3ICs9IHY7
IGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZHgrKzsKICAgIH0KICAgIHJldHVybiB2MCArIHYx
ICsgdjIgKyB2MyArIHY0ICsgdjUgKyB2NiArIHY3Owp9CgpsZXQgYnVmMyA9IG5ldyBBcnJheUJ1
ZmZlcigyNTYpOwpsZXQgdGEzID0gbmV3IEZsb2F0NjRBcnJheShidWYzKTsKZm9yIChsZXQgaSA9
IDA7IGkgPCAzMjsgaSsrKSB0YTNbaV0gPSBpICsgMC4xOwoKZm9yIChsZXQgaSA9IDA7IGkgPCAx
ZTQ7IGkrKykgaGlnaFByZXNzdXJlKHRhMyk7CmxldCBocCA9IGhpZ2hQcmVzc3VyZSh0YTMpOwps
ZXQgZXhwZWN0ZWRIUCA9IDA7CmZvciAobGV0IGkgPSAwOyBpIDwgMzI7IGkrKykgZXhwZWN0ZWRI
UCArPSBpICsgMC4xOwppZiAoTWF0aC5hYnMoaHAgLSBleHBlY3RlZEhQKSA+IDAuMDEpIHsKICAg
IHByaW50KCJbVlVMTl0gSGlnaCBwcmVzc3VyZSB3cm9uZzogIiArIGhwICsgIiBleHBlY3RlZCAi
ICsgZXhwZWN0ZWRIUCk7Cn0gZWxzZSB7CiAgICBwcmludCgiW09LXSBIaWdoIHByZXNzdXJlIGNv
cnJlY3Q6ICIgKyBocCk7Cn0KCnByaW50KCI9PT0gRG9uZSA9PT0iKTsK
</data>

          </attachment>
      

    </bug>

</bugzilla>