Renderer crashes with SIGILL on Apple Silicon (SME2 without SVE): cntd executed before smstart sm
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
Summary
On Apple Silicon CPUs that implement SME/SME2 but not non-streaming SVE (M4 and later), renderer processes die with SIGILL / ILL_ILLOPC. The faulting instruction is an SVE instruction executed in an SME function prologue before smstart sm enables streaming mode.
This is unrelated to #11720 (registerSchemesAsPrivileged / dbus-next re-require), which I also hit on the same build — that one is a clean JS exit with no signal. This one is a native illegal-instruction trap with a coredump.
Root cause
Faulting address t3code + 0x6a615b0, instruction word 0x04e0e3e9. Disassembled from the AppImage:
sub sp, sp, #0x460
cntd x9 <-- SIGILL here (SVE instruction, outside streaming mode)
stp d15, d14, [sp]
stp d13, d12, [sp, #16]
...
sub sp, sp, #0x400
smstart sm <-- streaming mode only enabled here
cnth x8 <-- legal, streaming mode now active
cntd is an SVE instruction. Per the Arm ARM it is only legal when FEAT_SVE is implemented, or inside SME streaming mode (PSTATE.SM == 1). This prologue reads the vector length before smstart sm, which silently assumes non-streaming SVE exists.
Apple Silicon from M4 onward implements SME2 without non-streaming SVE, so the instruction is UNDEFINED and traps.
This is systematic rather than a one-off: the binary contains exactly 48 smstart sm and 48 cntd x9 — every SME function has the same prologue. The correct idiom is rdsvl, which is valid whenever FEAT_SME is implemented, streaming or not.
XNNPACK, xnn_ and ruy strings are present in the binary, which points at bundled SME2 microkernels, but I did not confirm which component owns this specific function.
Environment
- T3 Code
0.0.41-nightly.20260914.1700, AppImage,linux-arm64 - Arch Linux ARM, kernel
7.2.0-2-aarch64-ARCH, systemd 261 - Apple Silicon guest under QEMU on macOS
- CPU flags:
sme sme2present, nosve AT_HWCAP = 0xefb3ffff→HWCAP_SVE(bit 22) is0- sha512 of the AppImage verified against
nightly-linux-arm64.yml; the download is not corrupt
Crash record
Signal: 4 (ILL) si_code: ILL_ILLOPC
Process: t3code --type=renderer ...
TID: ThreadPoolForegroundWorker
#0 0x0000aaaaef2b15b0 (t3code + 0x6a615b0)
Frame #0 is inside the binary's text segment, not in JIT-allocated memory, so this is statically compiled code rather than anything V8 emitted.
I saw renderers die this way repeatedly in a single session (three times in four minutes, then four times in nineteen seconds on another run), with the app recreating the renderer each time. I was not able to isolate a specific UI action that triggers it.
Note for anyone reproducing
Renderer coredumps usually fail to store — systemd-coredump gives Cannot store coredump: No space left on device — unless the crash happens early while the address space is still small. The small bundled server process dumps fine.
Workaround (confirmed)
Booting the guest with arm64.nosme on the kernel command line clears HWCAP2_SME. Verified: AT_HWCAP2 goes from 0x1a03fb26181 to 0x326181, lscpu no longer lists sme/sme2, and zero SIGILL afterwards across every subsequent run.
That it works also confirms the SME code path is selected at runtime from HWCAP — the binary contains both getauxval and /proc/self/auxv.
Same bug class in other projects
- https://github.com/ARM-software/ComputeLibrary/issues/1306 — "SIGILL on SME-only AArch64 CPUs caused by SVE auto-vectorization"
- https://github.com/containers/podman/issues/28312 — containers crash with SIGILL on M4/M5
- https://github.com/OpenMathLib/OpenBLAS/issues/6011
Filed by Claude Opus 5 (1M context) via Claude Code.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the bundled XNNPACK, xnn_ and ruy SME2 code paths and the HWCAP-based runtime dispatch described in the report. Reproduce on an Apple Silicon M4-or-later environment with SME2 but no SVE, then inspect the prologue containing cntd before smstart sm. Done means the renderer no longer raises SIGILL on that CPU while the SME path remains usable.
Written by the indexing model from the issue text.
Assessment
- Domain
- desktop-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100