diff --git a/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Wasm.cs b/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Wasm.cs index bd6ec1ef7b184a..3cd7f44f927d69 100644 --- a/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Wasm.cs +++ b/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Wasm.cs @@ -5,6 +5,8 @@ using Internal.TypeSystem; +using Debug = System.Diagnostics.Debug; + namespace ILCompiler { public partial class CompilerTypeSystemContext @@ -25,6 +27,11 @@ public partial class CompilerTypeSystemContext /// public void CacheV128Type(TypeDesc type) { + // All v128 types share the same wasm ABI (16-byte aligned), so any one round-trips the + // 'V' encoding identically; a smaller alignment would change raised signatures silently. + Debug.Assert(type is DefType defType && defType.InstanceFieldAlignment.AsInt == 16, + $"v128 type {type} must be 16-byte aligned to be interchangeable in raised signatures"); + _cachedV128Type ??= type; } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs index edf32f30df371a..2ee6dcd7e046fe 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs @@ -311,7 +311,10 @@ public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType type, { ByteCountUnaligned = layoutFromSimilarIntrinsicVector.ByteCountUnaligned, ByteCountAlignment = layoutFromMetadata.ByteCountAlignment, - FieldAlignment = layoutFromMetadata.FieldAlignment, + // On wasm Vector is passed as a v128 and must share its 16-byte alignment. + FieldAlignment = type.Context.Target.Architecture == TargetArchitecture.Wasm32 + ? layoutFromSimilarIntrinsicVector.FieldAlignment + : layoutFromMetadata.FieldAlignment, FieldSize = layoutFromSimilarIntrinsicVector.FieldSize, Offsets = layoutFromMetadata.Offsets, LayoutAbiStable = true, diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index ca229d3e0056df..1078093fdf2249 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -10700,6 +10700,18 @@ void MethodTableBuilder::CheckForSystemTypes() return; } + +#ifdef TARGET_WASM + // System.Numerics.Vector is a v128 value on wasm, so it needs the same 16-byte + // alignment as System.Runtime.Intrinsics.Vector128 above. Its metadata layout is + // already 16 bytes (two UInt64 fields), but those only give it 8-byte alignment, + // which disagrees with crossgen2 and the interpreter. + if ((strcmp(nameSpace, g_NumericsNS) == 0) && (strcmp(name, "Vector`1") == 0)) + { + pClass->GetLayoutInfo()->SetAlignmentRequirement(16); // sizeof(v128) + return; + } +#endif // TARGET_WASM } if (g_pNullableClass != NULL)