darmie opened PR #14054 from darmie:aarch64-usdot-i8mm to bytecodealliance:main:
Implements the proposal from #14050 (a maintainer confirmed CI can validate this).
What
aarch64folds the signed i8 dot-product tree intoSDOTunderhas_dotprod, but the mixed unsigned x signed form had no equivalent, so on a FEAT_I8MM part it kept theumull/smull+saddlpwidening fallback even thoughUSDOTcomputes it in a single instruction. x64 already lowers this form toVPDPBUSDon a VNNI host; aarch64 covered only the signed case.That mixed shape is what quantized inference produces — unsigned activations against signed weights — which is the reason
USDOTandVPDPBUSDexist at all.How
Mirrors the existing
SDOTsupport:
has_i8mmsetting inmeta/src/isa/arm64.rs, with host detection incranelift-nativeand ause_i8mmextractor.USDOTinVecALUModOp+ its encoding (same shape asSDOT, differing only in the opcode field).- A lowering rule beside the
SDOTrule. The matched tree is identical except that one operand widens unsigned.Testing
filetests/isa/aarch64/usdot.clif— precise-output, asserts the tree lowers to a singleusdot v0.4s, v1.16b, v2.16b.filetests/runtests/usdot.clif— execution, on the interpreter and every native target, plus anaarch64 has_i8mmtarget so the fused path itself is exercised where the feature is present. Includes lanes above 127 to pin the unsigned widening, which is what distinguishes this from a signed dot.- The existing
isa/aarch64filetests pass unchanged (118), so the new rule does not disturb theSDOTpath.What I could not verify locally
My machine is an M1, where
hw.optional.arm.FEAT_I8MM = 0, soUSDOTnever executes here. What I did verify locally:
- the rule fires and emits the expected instruction (precise-output filetest);
- the tree semantics are right — the runtest's expected values are confirmed by the interpreter and by the native fallback path.
What remains for CI on I8MM hardware is that
USDOTitself produces those same values. Flagging it plainly since a wrong dot-product rule is a silent miscompile rather than a crash.One open question from #14050, in case it matters: I derived the mixed-tree pattern from the fallback lowering rather than from a mid-end dump, so if the mid-end normalises the mixed form differently than the signed one, the rule may need its shape adjusted.
darmie requested alexcrichton for a review on PR #14054.
darmie requested wasmtime-compiler-reviewers for a review on PR #14054.
darmie edited PR #14054:
Implements #14050.
aarch64folds the signed i8 dot tree intoSDOTunderhas_dotprod; the mixed unsigned-by-signed form had no equivalent and kept theumull/smull+saddlpfallback. x64 already lowers that form toVPDPBUSD.Mirrors the
SDOTsupport:has_i8mmsetting + host detection +use_i8mmextractor, theUSDOTencoding, and a rule beside theSDOTone — same tree, one operand widening unsigned.Tests: precise-output filetest for the lowering, plus a runtest (interpreter + native targets, and an
aarch64 has_i8mmtarget) with lanes above 127 to pin the unsigned widening. Existingisa/aarch64filetests pass unchanged.
FEAT_I8MM = 0on my machine, soUSDOTdoesn't execute locally — selection and tree semantics are verified, thatUSDOTitself matches is for CI.
darmie converted PR #14054 aarch64: lower mixed unsigned-by-signed i8 dot to USDOT (FEAT_I8MM) to a draft
darmie commented on PR #14054:
Moving to draft — CI is red on Linux arm64, which is the first host where this rule actually fires (my machine has
FEAT_I8MM = 0, so locally it only ever took the fallback path). So this is exactly the case I flagged as unverifiable, and CI caught it.Not yet diagnosed. My leading suspicion is the rule matching too broadly: it sits at priority 9, above the
SDOTrule, and if the mid-end emitsuwidenfor the i7 operand ofi32x4.relaxed_dot_i8x16_i7x16_add_sthen this rule would hijack that tree — whereUSDOT's unsigned operand is the first source, so the operands would be the wrong way round. Will confirm against the failing test before pushing anything further.
darmie updated PR #14054.
darmie has marked PR #14054 as ready for review.
darmie requested wasmtime-core-reviewers for a review on PR #14054.
darmie updated PR #14054.
darmie updated PR #14054.
darmie updated PR #14054.
github-actions[bot] added the label cranelift:area:aarch64 on PR #14054.
github-actions[bot] added the label cranelift on PR #14054.
github-actions[bot] added the label cranelift:meta on PR #14054.
github-actions[bot] added the label wasmtime:api on PR #14054.
github-actions[bot] added the label isle on PR #14054.
github-actions[bot] added the label wasmtime:config on PR #14054.
github-actions[bot] commented on PR #14054:
Subscribe to Label Action
cc @cfallin, @fitzgen
<details>
This issue or pull request has been labeled: "cranelift", "cranelift:area:aarch64", "cranelift:meta", "isle", "wasmtime:api", "wasmtime:config"Thus the following users have been cc'd because of the following labels:
- cfallin: isle
- fitzgen: isle
To subscribe or unsubscribe from this label, edit the <code>.github/subscribe-to-label.json</code> configuration file.
Learn more.
</details>
github-actions[bot] commented on PR #14054:
Label Messager: wasmtime:config
It looks like you are changing Wasmtime's configuration options. Make sure to
complete this check list:
[ ] If you added a new
Configmethod, you wrote extensive documentation for
it.<details>
Our documentation should be of the following form:
```text
Short, simple summary sentence.More details. These details can be multiple paragraphs. There should be
information about not just the method, but its parameters and results as
well.Is this method fallible? If so, when can it return an error?
Can this method panic? If so, when does it panic?
Example
Optional example here.
```</details>
[ ] If you added a new
Configmethod, or modified an existing one, you
ensured that this configuration is exercised by the fuzz targets.<details>
For example, if you expose a new strategy for allocating the next instance
slot inside the pooling allocator, you should ensure that at least one of our
fuzz targets exercises that new strategy.Often, all that is required of you is to ensure that there is a knob for this
configuration option in [wasmtime_fuzzing::Config][fuzzing-config] (or one
of its nestedstructs).Rarely, this may require authoring a new fuzz target to specifically test this
configuration. See [our docs on fuzzing][fuzzing-docs] for more details.</details>
[ ] If you are enabling a configuration option by default, make sure that it
has been fuzzed for at least two weeks before turning it on by default.[fuzzing-config]: https://github.com/bytecodealliance/wasmtime/blob/ca0e8d0a1d8cefc0496dba2f77a670571d8fdcab/crates/fuzzing/src/generators.rs#L182-L194
[fuzzing-docs]: https://docs.wasmtime.dev/contributing-fuzzing.html
<details>
To modify this label's message, edit the <code>.github/label-messager/wasmtime-config.md</code> file.
To add new label messages or remove existing label messages, edit the
<code>.github/label-messager.json</code> configuration file.</details>
:thumbs_up: alexcrichton submitted PR review:
Thanks!
alexcrichton added PR #14054 aarch64: lower mixed unsigned-by-signed i8 dot to USDOT (FEAT_I8MM) to the merge queue
:check: alexcrichton merged PR #14054.
alexcrichton removed PR #14054 aarch64: lower mixed unsigned-by-signed i8 dot to USDOT (FEAT_I8MM) from the merge queue
Last updated: Aug 30 2026 at 09:07 UTC