Skip to content

build: keep Highway's x64 target set at clang 23 (no AVX10_2) - #44004

Open
robobun wants to merge 1 commit into
mainfrom
robobun/a4a490b1/highway-x64-targets
Open

robobun wants to merge 1 commit into
mainfrom
robobun/a4a490b1/highway-x64-targets

Conversation

@robobun

@robobun robobun commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

  • Since the LLVM 23 upgrade (Upgrade LLVM 21.1.8 → 23.1.1 and Rust nightly to 2026-09-15 #42851), Highway compiles every kernel for one more x64 target, AVX10_2. Highway enables it from clang 23 (hwy/detect_targets.h:198). HWY_TARGETS went from 7120 to 7128.
  • The 60 new kernels are duplicates: 57 are instruction-identical to the AVX3_SPR copy, 3 to the AVX3_DL copy. The linker cannot fold them, because the dispatch tables hold their addresses.

Fix

  • Add HWY_AVX10_2 to HWY_DISABLED_TARGETS in scripts/build/deps/highway.ts, beside the SVE targets from build: pin Highway's aarch64 target set (no scalable SVE/SVE2 with clang ≥ 22) #40921. HWY_TARGETS is 7120 again.
  • Remove the 56 N_AVX10_2 entries from each x64 baseline allowlist. The static scan fails if that code comes back.
  • Correct because Highway sets AVX3_SPR for every CPU it sets AVX10_2 for (hwy/targets.cc:336). Such a CPU dispatches to AVX3_SPR.
  • Verified: test/js/bun/util/highway-strings.test.ts on debug and release builds. Also escapeHTML.test.js and stringWidth.test.ts.

Background

  • Highway compiles each kernel once per SIMD target and picks one copy at run time from CPUID. HWY_DISABLED_TARGETS removes targets at compile time.
  • The baseline allowlists name the functions that may use instructions newer than Nehalem behind a CPUID check.
  • Considered: also dropping AVX3_SPR (89% identical to other copies). Left out: it changes what runs on Sapphire Rapids today.

Downsides

  • A later kernel that wants an AVX10.2-only instruction needs the target enabled again. No kernel uses one today.
  • On a CPU with AVX10.2, JsonIndexImpl, XmlIndexImpl and XmlIndex16Impl run a different copy than before. Not measured: no such hardware was available.
  • Size, linux-x64 release, stripped: 80,995,912 to 80,934,472 bytes (-61,440). No per-call cost: dispatch is unchanged.
Notes

Section deltas of the size line above: .text -46,080, .rodata -16,384.

Stripped size per target, CI release builds of this branch against main at c86bd18 (3 commits after the merge base of this branch):

target this branch main delta
bun-linux-x64 77.18 MB 77.24 MB -60.0 KB
bun-linux-x64-musl 71.15 MB 71.21 MB -56.0 KB
bun-linux-x64-android 86.37 MB 86.42 MB -56.0 KB
bun-freebsd-x64 85.06 MB 85.12 MB -60.0 KB
bun-darwin-x64 66.56 MB 66.63 MB -64.1 KB
bun-windows-x64 83.86 MB 83.92 MB -58.5 KB
bun-windows-aarch64 72.70 MB 72.70 MB +1.5 KB
the 5 other aarch64 targets +0.0 KB

How the copies were compared: llvm-objdump -d of every N_<target> kernel in the CI canary build of f063852, with branch targets made function-relative, callee names stripped of their target namespace, and RIP-relative and jump-table addresses masked. After that, all 50,417 bytes of AVX10_2 kernels equal another target's copy. No instruction mnemonic appears in an N_AVX10_2 function that does not also appear in an N_AVX3* function.

Per-target kernel bytes (symbol sizes, 60 kernels each):

target before after
SSSE3 38,596 38,596
SSE4 38,627 38,627
AVX2 52,629 52,629
AVX3 48,357 48,357
AVX3_DL 50,400 50,400
AVX3_ZEN4 50,922 50,922
AVX3_SPR 50,939 50,939
AVX10_2 50,417 0

HWY_TARGETS from the preprocessor, clang 23.1.2, vendored Highway:

target flags before after
--target=x86_64-linux-gnu -march=nehalem 7128 7120
--target=x86_64-pc-windows-msvc -march=nehalem 7128 7120
--target=aarch64-linux-gnu -march=armv8-a+crc unchanged unchanged
--target=arm64-apple-macos13 -mcpu=apple-m1 unchanged unchanged

x86 target bits are 0 to 14 and Arm target bits are 15 to 29, so the x86 bit has no effect on Arm. The define uses + and not |, because the bits are disjoint and | needs quoting under cmd.exe.

History: the allowlists already had N_AVX10_2 entries before #42851, and #42851 added more. The 1.4.2 release binary (clang 21) has no N_AVX10_2 symbol, so those older entries matched nothing at that time.

Debug build: indexOfAny / lastIndexOfAny: 2, 3 and 16-byte sets in highway-strings.test.ts takes 9 to 13 s under debug with ASAN on the build host and passes the 5 s default timeout neither with nor without this change. It passes with --timeout 60000 (11 pass, 56,393 expect() calls). The debug binary has 774 N_AVX10_2 symbols before and 0 after.


[policy-decision:dep] gate passed · iteration 0 · 3 files touched

passes on PR (with fix)
Dependency/toolchain change; no test proof to run.
diff hotspot
scripts/build/deps/highway.ts                      |  7 ++-
 .../allowlist-x64-windows.txt                      | 64 ++--------------------
 scripts/verify-baseline-static/allowlist-x64.txt   | 64 ++--------------------
 3 files changed, 14 insertions(+), 121 deletions(-)

gate history · 1 passed · 0 rejected · iteration 0

evidence per changed file
file                                                      reads  edits  tests
scripts/build/deps/highway.ts                                 1      2      1
scripts/verify-baseline-static/allowlist-x64-windows.txt      0      0      1
scripts/verify-baseline-static/allowlist-x64.txt              0      0      1

Highway enables its AVX10_2 target when the compiler is clang 23 or newer
(hwy/detect_targets.h, HWY_BROKEN_AVX10_2). The LLVM 23 upgrade therefore
added an eighth copy of every dispatched kernel on x64: HWY_TARGETS went
from 7120 to 7128.

Each of the 60 AVX10_2 kernels compiles to the same instructions as its
AVX3_SPR copy (57) or its AVX3_DL copy (3). Highway's detection sets
AVX3_SPR for every CPU it sets AVX10_2 for, so such a CPU dispatches to
AVX3_SPR when AVX10_2 is not compiled.

Add HWY_AVX10_2 to HWY_DISABLED_TARGETS, next to the SVE targets that are
off since clang 22, and remove the AVX10_2 entries from the x64 baseline
allowlists. linux-x64 release, stripped: 80,995,912 -> 80,934,472 bytes.
@robobun

robobun commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator Author

Status: ready for review.

How this was checked, on linux-x64 at f063852:

  1. bun run build:release before and after the change. Stripped bun: 80,995,912 and 80,934,472 bytes.
  2. llvm-nm on bun-profile: 60 N_AVX10_2 kernels before, 0 after. The other seven targets keep the same 60 kernels and the same sizes.
  3. clang++ -E on hwy/detect_targets.h with the build's flags: HWY_TARGETS is 7128 before and 7120 after, for the Linux and the Windows x64 triples.
  4. bun bd test --timeout 60000 test/js/bun/util/highway-strings.test.ts: 11 pass. Without --timeout, one test of that file passes the 5 s default neither with nor without this change on the debug build of this host (it takes 9 to 13 s there).
  5. The same file, escapeHTML.test.js, stringWidth.test.ts and index-of-line.test.ts pass on the release build.

@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: oven-sh/bun/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Essentials

Run ID: 7b768117-36d4-43f2-9773-639df4f1709f

📥 Commits

Reviewing files that changed from the base of the PR and between c86bd18 and a5790f8.

📒 Files selected for processing (3)
  • scripts/build/deps/highway.ts
  • scripts/verify-baseline-static/allowlist-x64-windows.txt
  • scripts/verify-baseline-static/allowlist-x64.txt

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.


Walkthrough

The Highway build configuration disables the AVX10_2 target. The x64 and Windows x64 static-baseline allowlists remove AVX10_2 symbols and update the corresponding section counts.

Changes

AVX10_2 target and baseline symbols

Layer / File(s) Summary
Disable the AVX10_2 target
scripts/build/deps/highway.ts
The Highway target configuration disables AVX10_2. Comments describe the AVX3-equivalent kernels and CPU feature reporting used for dispatch.
Update x64 baseline allowlists
scripts/verify-baseline-static/allowlist-x64.txt, scripts/verify-baseline-static/allowlist-x64-windows.txt
Both allowlists remove AVX10_2 symbols from Highway, source-map VLQ, xxHash3, and Bun.Image sections. Their section counts are updated.

Suggested reviewers: jarred-sumner

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to a5790

Disabling AVX10_2 preserves dispatch coverage through AVX3_SPR without an identified current-head regression.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: keeping Highway's x64 target set unchanged at clang 23 by excluding AVX10_2.
Description check ✅ Passed The description explains the problem, fix, verification steps, impact, trade-offs, and build-size results. It provides the information requested by the template, although it uses Problem and Fix headi…

Comment @coderabbitai help to get the list of available commands.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — a one-token build-flag change plus the matching allowlist pruning.

What was reviewed:

  • disabledTargets in scripts/build/deps/highway.ts flows unquoted into -D... for both Highway's own sources and bun's compile (scripts/build/bun.ts:250), so +/- in the value need no shell escaping on any platform.
  • Both x64 allowlists: every N_AVX10_2 entry is gone, no other entries changed, and the updated section counts (234/10/5/45) match the actual entry counts; aarch64 allowlist untouched, as expected for an x86-only bit.
  • Could not fetch the pinned Highway commit here to read HWY_AVX10_2 directly; the pre-existing N_AVX10_2 allowlist entries and the 7128-to-7120 (=1<<3) delta both point to the macro existing, and a wrong name would fail every CI build at the first Highway include rather than silently.
Extended reasoning...

The change touches only the Highway dependency build script (one string constant and a comment) and two x64 baseline-ISA allowlists, removing 56 AVX10_2 kernel entries; no runtime source, tests, or security-sensitive surface is involved. The define is consumed verbatim as a -D flag by both the Highway direct build and bun's compile, so the added +HWY_AVX10_2 reaches every Highway-including TU. Allowlist edits are purely subtractive and internally consistent with their section counts, and the static scan would flag any AVX10_2 code that reappeared. The runtime effect is confined to CPUs with AVX10.2, which Highway also flags as AVX3_SPR-capable, so dispatch falls to an existing kernel copy; the changed files have no CODEOWNER and there are no outstanding reviewer objections.

@robobun

robobun commented Sep 28, 2026

Copy link
Copy Markdown
Collaborator Author

@robobun wake up!!

@Jarred-Sumner

Copy link
Copy Markdown
Collaborator

@robobun wake up!!

@robobun

robobun commented Sep 28, 2026

Copy link
Copy Markdown
Collaborator Author

I am here. This is the state of the PR at a5790f8. Nothing is pending from my side.

CI

  • Buildkite build 120717 passed, 181 of 181 jobs.
  • verify-baseline passed on linux-x64, linux-x64-musl and windows-x64. Those steps scan the CI binaries against the pruned allowlists.
  • The red claude-find-issues check does not come from this diff. That workflow passed on none of its last 100 runs across all pull requests (89 failed, 11 wait for approval).

Size, from the binary-size step of that build

target delta
bun-linux-x64 -60.0 KB
bun-linux-x64-musl -56.0 KB
bun-linux-x64-android -56.0 KB
bun-freebsd-x64 -60.0 KB
bun-darwin-x64 -64.1 KB
bun-windows-x64 -58.5 KB
bun-windows-aarch64 +1.5 KB
the 5 other aarch64 targets +0.0 KB

The baseline of that step is main at c86bd18, which is 3 commits after the merge base of this branch. The linux-x64 number agrees with my local measurement (-61,440 bytes). I added the table to the Notes of the description.

Against main today (a4f1429)

  • The branch merges without conflict.
  • I checked the merged result. The define is in highway.ts, and the two x64 allowlists have no N_AVX10_2 entry.
  • Main did not change the Highway pin or add a Highway kernel since this branch started.

What it needs

  • A review from a maintainer.
  • Tell me if you want a rebase for a fresh CI run, a change, or if this PR must close.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants