Skip to content

Make wasm 'V' signature raising deterministic and add a regression test - #131429

Merged
tannergooding merged 1 commit into
dotnet:mainfrom
tannergooding:tannergooding-wasm-v128-raising-determinism
Jul 27, 2026
Merged

Make wasm 'V' signature raising deterministic and add a regression test#131429
tannergooding merged 1 commit into
dotnet:mainfrom
tannergooding:tannergooding-wasm-v128-raising-determinism

Conversation

@tannergooding

@tannergooding tannergooding commented Jul 27, 2026

Copy link
Copy Markdown
Member

Fixes #131339 -- though not in the way the issue proposed; see the note at the bottom.

RaiseSignature resolved the 'V' (v128) signature char to CompilerTypeSystemContext.CachedV128Type, i.e. literally whichever v128 type lowering happened to encounter first, written racily from parallel compilation. 'V' is fully determined by the wasm ABI (16 bytes, 16-byte aligned), so raising now resolves a fixed canonical Vector128<byte> instead. Any v128 type round-trips 'V' identically, so RaiseSignature's own round-trip assert still holds, and the raised signature no longer depends on compilation order.

The 16-byte alignment Debug.Assert that guarded this invariant moved from CacheV128Type into IsWasmV128Type. CacheV128Type only ever saw the first cached type, where-as IsWasmV128Type has three call sites and so covers every v128 type.

This also drops the ?? throw new InvalidOperationException(...) on the 'V' path -- that failure mode is simply gone, since raising no longer needs lowering to have run first.


ILCompiler.ReadyToRun.Tests gains WasmArgumentLayoutTests: 20 cases driving crossgen2's type system and GCRefMapBuilder.BuildArgIterator directly, so they need neither a wasm JIT nor a runtime to execute against.

  • WasmV128TypesAre16ByteAligned -- 12 cases over Vector128<T>/Vector<T> x 6 element types.
  • WasmV128ArgumentsStartOn16ByteBoundaries -- static void M(long, TVector, ref int) must lay out as [0, 16, 32].
  • OtherSimdWidthsAreNotV128 -- Vector64/256/512<T> must fall back to the generic struct ABI.
  • RaisingV128SignatureIsIndependentOfLoweringOrder -- lowers a different vector type first, then asserts the raised 'V' is unchanged and that its offsets match the original signature's.

These also cover the Vector<T> alignment fix from #131328, and I verified they bite: with that fix reverted, 7 cases fail -- the six Vector<T> alignment cases report 8 instead of 16, and WasmV128ArgumentsStartOn16ByteBoundaries for Vector<T> reports [0, 8, 24] instead of [0, 16, 32].


On #131339 itself. The issue asks for a test asserting Vector128<T> is 16-byte aligned, on the premise that this is what #131328 fixed. That is not correct -- Vector128<T> gets alignment 16 from VectorFieldLayoutAlgorithm on every architecture except ARM and was untouched by that fix. I confirmed empirically that the proposed test passes unchanged against a compiler with #131328 reverted, so it would have been a no-op. The actual regression was System.Numerics.Vector<T>, which kept the 8-byte alignment from its metadata layout. The tests here cover both.

The issue also says the test was deferred for lack of a CI-runnable home. That premise is stale: #130866 added the WasmSimdModule wasm crossgen2 suite to ILCompiler.ReadyToRun.Tests three days before the issue was filed, and that is where these tests live.


Also hoisted the System.Private.CoreLib.dll resolution out of R2RTestRunner into TestPaths.SystemPrivateCoreLibPath so the new tests share the existing runtime-pack to CoreCLR-artifacts fallback. Without it they would hard-fail in partial builds that skip libs.pretest, e.g. a bare clr.toolstests.

Out of scope, to be filed separately: CacheStructBySize/GetCachedStructOfSize has the same first-wins-cache shape for the 'S<N>' encoding, and there it is a live miscompile rather than a latent hazard. Guid and Int128 are both 16 bytes and both encode S16, but their clamped alignments are 8 and 16, so the shared thunk signature vlS16ip gets two different frame layouts. Fixing that means changing the on-disk encoding across crossgen2, src/coreclr/vm/wasm/helpers.cpp, WasmAppBuilder, and the R2R format doc, so it does not belong here.

Local test run: ILCompiler.ReadyToRun.Tests is 58 total / 1 failed. The failure is CompositeManifestAssemblyMvidsArePaddedWhenPdbPresent, an ArgumentNullException out of the native PDB COM writer in my Debug layout. Confirmed pre-existing -- it reproduces identically with this branch's changes stashed.

CC. @lewing @adamperlin -- ready for review.

Note

This PR description was drafted by Copilot.

RaiseSignature resolved 'V' to whichever v128 type lowering happened to see
first, cached racily from parallel compilation. 'V' is fully determined by the
ABI, so resolve a fixed Vector128<byte> instead, and move the 16-byte alignment
assert into IsWasmV128Type so it covers every v128 type rather than just the
first one cached.

The test also covers the Vector<T> alignment fix from dotnet#131328; issue dotnet#131339
proposed testing Vector128<T>, which was never under-aligned.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 27, 2026 17:28
@github-actions github-actions Bot added the area-crossgen2-coreclr only use for closed issues label Jul 27, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI 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.

Pull request overview

This PR makes wasm signature raising for the 'V' (v128) encoding deterministic by resolving it to a fixed canonical type (Vector128<byte>) rather than relying on whichever v128 type happened to be cached first during lowering. It also adds targeted regression tests in ILCompiler.ReadyToRun.Tests to validate v128 alignment and argument layout invariants for the wasm ABI, and refactors test infrastructure to share a consistent System.Private.CoreLib.dll resolution path.

Changes:

  • Make RaiseSignature map 'V' to CompilerTypeSystemContext.WasmV128Type (canonical Vector128<byte>) and move the 16-byte alignment invariant assertion into IsWasmV128Type.
  • Add WasmArgumentLayoutTests covering v128 type alignment, argument offsets, non-v128 SIMD widths, and raising independence from lowering order.
  • Hoist System.Private.CoreLib.dll path resolution into TestPaths.SystemPrivateCoreLibPath and reuse it from R2RTestRunner and the new tests.
Show a summary per file
File Description
src/coreclr/tools/Common/JitInterface/WasmLowering.cs Removes order-dependent v128 caching during lowering, asserts v128 alignment via IsWasmV128Type, and raises 'V' via a canonical type.
src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Wasm.cs Replaces the “first-seen” v128 cache with a lazy canonical Vector128<byte> (WasmV128Type).
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj Adds InternalsVisibleTo to allow the test project to access internal crossgen2 APIs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/ILCompiler.ReadyToRun.Tests.csproj Adds an aliased reference to ILCompiler.ReadyToRun for internal API access without namespace/type collisions.
src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/WasmArgumentLayoutTests.cs New regression tests validating wasm v128 alignment and argument layout behavior, including raising determinism.
src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/TestPaths.cs Adds SystemPrivateCoreLibPath with runtime-pack → CoreCLR-artifacts fallback.
src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RTestRunner.cs Switches SPCL resolution to the shared TestPaths.SystemPrivateCoreLibPath.

Copilot's findings

  • Files reviewed: 7/7 changed files
  • Comments generated: 0

@davidwrighton davidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I like the compiler changes, but please get Jackson to take a look at the test changes.

@tannergooding
tannergooding requested a review from jtschuster July 27, 2026 17:53
@tannergooding
tannergooding enabled auto-merge (squash) July 27, 2026 19:00
@tannergooding
tannergooding merged commit 79a5a09 into dotnet:main Jul 27, 2026
114 checks passed
@tannergooding
tannergooding deleted the tannergooding-wasm-v128-raising-determinism branch July 27, 2026 20:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-crossgen2-coreclr only use for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add crossgen ArgIterator unit test for wasm Vector128 argument 16-byte alignment

6 participants