Skip to content

[wasm] Decide Vector256/Vector512 field alignment on wasm before layout is locked in #135483

Description

@lewing

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-unknown and wasm32-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 multiple v128s.

  • In [wasm] Use ordinary struct alignment for Int128/UInt128 on wasm #131421, the expected model was that Vector256<T> is struct { Vector128 lower, upper; } and Vector512<T> is struct { 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.

Activity

  1. added this to the 12.0.0 milestone on Oct 9, 2026
  2. dotnet-policy-service commented on Oct 9, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
    See info in area-owners.md if you want to be subscribed.

  3. dotnet-policy-service commented on Oct 9, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to this area: @agocke
    See info in area-owners.md if you want to be subscribed.

  4. lewing commented on Oct 9, 2026

    @lewing
    MemberAuthor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    • Status
      No status

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions