Repository navigation
Description
On wasm, both the VM (MethodTableBuilder::CheckForSystemTypes) and crossgen2 (VectorFieldLayoutAlgorithm) give Vector256<T> and Vector512<T> an alignment of 32 and 64. Neither has a wasm branch, so both fall through to the generic else, which corresponds to x86's __m256/__m512. Since #135481, auto-layout structs that contain these types inherit the same alignment, consistently in the VM and crossgen2.
The VM and crossgen2 agree, so there is no correctness bug today. However, 32/64 is questionable for wasm, and changing it later breaks layout and ReadyToRun compatibility. It should be decided before wasm CoreCLR ships.
Evidence
-
The Wasm Basic C ABI defines nothing wider than
v128. -
clang 22 targeting
wasm32-unknown-unknownandwasm32-unknown-emscripten:type _Alignof__int128,v128(vector_size(16))16 struct { v128 lo, hi; }16 vector_size(32)/vector_size(64)32 / 64 __BIGGEST_ALIGNMENT__16 The data layout's stack alignment is
S128, i.e. 16 bytes. Only clang's generic vector-extension types get 32/64, and those are not part of the ABI; wasm lowers them to multiplev128s. -
In [wasm] Use ordinary struct alignment for Int128/UInt128 on wasm #131421, the expected model was that
Vector256<T>isstruct { Vector128 lower, upper; }andVector512<T>isstruct { Vector256 lower, upper; }, treated like equivalent user-defined structs (as on Arm64). On wasm that gives an alignment of 16. -
The GC heap on wasm only guarantees 8-byte object alignment (
FEATURE_64BIT_ALIGNMENT). Any field alignment above 8 therefore only affects offsets relative to the start of the object, so 32/64 adds padding without giving real alignment. -
[wasm] Use ordinary struct alignment for Int128/UInt128 on wasm #131421 also found that wide vectors were passed through alignment-blind
S<N>signature keys. [wasm] Pass Int128, Decimal128 and wide vectors by value #131492 changed wasm argument passing for these types; that side should be re-checked as part of this decision.
Ask
- Decide between 16 (the 2×/4× V128 model) and the current 32/64 for wasm.
- Change the VM (
CheckForSystemTypes) and crossgen2 (VectorFieldLayoutAlgorithm) together. - Add Wasm32 rows for the vector types to
ArchitectureSpecificFieldLayoutTests. Wasm32 coverage for Int128/UInt128/Decimal128 was added in [wasm] Keep larger field alignment for Align8 auto-layout structs #135481.
Note
This issue was drafted with GitHub Copilot.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
Activity
dotnet-policy-service commentedon Oct 9, 2026
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.
dotnet-policy-service commentedon Oct 9, 2026
Tagging subscribers to this area: @agocke
See info in area-owners.md if you want to be subscribed.
lewing commentedon Oct 9, 2026
cc @tannergooding
[wasm] Keep larger field alignment for Align8 auto-layout structs (#1…
tannergooding commentedon Oct 12, 2026
I'd say defaulting to 16 for them, like Arm64 does, is reasonable.
If WASM does get dedicated support for V256 or similar in the future, we can (and may need to) take a R2R/ABI break then.