Skip to content

Commit 23ddef3

Browse files
authored
[wasm] Enable v128 and PackedSimd in the interpreter (#85920)
Fix the create scalar intrinsics in the jiterpreter Fix trimming removing SIMD even if SIMD was enabled Add wasm opcode mapping for extract msb Fix some SN_ lists in transform-simd being ordered incorrectly Due to mixed mode it is not possible to control interp SIMD with a runtime option, so remove the options Disable linker substitutions for SIMD unless AOT is active, so the interp is responsible for the properties Generate a MINT_NIY for unimplemented PackedSimd methods
1 parent 309ffc8 commit 23ddef3

File tree

8 files changed

+86
-59
lines changed

8 files changed

+86
-59
lines changed

eng/testing/tests.wasm.targets

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
So, set those parameters explicitly here.
6262
-->
6363
<_ExtraTrimmerArgs Condition="'$(WasmEnableSIMD)' == 'true' and '$(RunAOTCompilation)' == 'true'">$(_ExtraTrimmerArgs) --substitutions &quot;$(MonoProjectRoot)\wasm\build\ILLink.Substitutions.WasmIntrinsics.xml&quot;</_ExtraTrimmerArgs>
64-
<_ExtraTrimmerArgs Condition="'$(WasmEnableSIMD)' != 'true' or '$(RunAOTCompilation)' != 'true'">$(_ExtraTrimmerArgs) --substitutions &quot;$(MonoProjectRoot)\wasm\build\ILLink.Substitutions.NoWasmIntrinsics.xml&quot;</_ExtraTrimmerArgs>
64+
<_ExtraTrimmerArgs Condition="'$(WasmEnableSIMD)' != 'true'">$(_ExtraTrimmerArgs) --substitutions &quot;$(MonoProjectRoot)\wasm\build\ILLink.Substitutions.NoWasmIntrinsics.xml&quot;</_ExtraTrimmerArgs>
6565
</PropertyGroup>
6666

6767
<ItemGroup>

src/mono/mono/mini/interp/interp.c

+4
Original file line numberDiff line numberDiff line change
@@ -3802,6 +3802,10 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
38023802
memset (locals + ip [1], 0, ip [2]);
38033803
ip += 3;
38043804
MINT_IN_BREAK;
3805+
MINT_IN_CASE(MINT_NIY)
3806+
g_printf ("MONO interpreter: NIY encountered in method %s\n", frame->imethod->method->name);
3807+
g_assert_not_reached ();
3808+
MINT_IN_BREAK;
38053809
MINT_IN_CASE(MINT_BREAK)
38063810
++ip;
38073811
SAVE_INTERP_STATE (frame);

src/mono/mono/mini/interp/mintops.def

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#define IROPDEF(opsymbol, opstring, oplength, num_dregs, num_sregs, optype) OPDEF(opsymbol, opstring, oplength, num_dregs, num_sregs, optype)
2727
#endif // IROPDEF
2828

29+
OPDEF(MINT_NIY, "niy", 1, 0, 0, MintOpNoArgs)
2930
OPDEF(MINT_BREAK, "break", 1, 0, 0, MintOpNoArgs)
3031
OPDEF(MINT_BREAKPOINT, "breakpoint", 1, 0, 0, MintOpNoArgs)
3132

@@ -843,7 +844,6 @@ OPDEF(MINT_TIER_MONITOR_JITERPRETER, "tier_monitor_jiterpreter", 3, 0, 0, MintOp
843844
#endif // HOST_BROWSER
844845

845846
IROPDEF(MINT_NOP, "nop", 1, 0, 0, MintOpNoArgs)
846-
IROPDEF(MINT_NIY, "niy", 1, 0, 0, MintOpNoArgs)
847847
IROPDEF(MINT_DEF, "def", 2, 1, 0, MintOpNoArgs)
848848
IROPDEF(MINT_IL_SEQ_POINT, "il_seq_point", 1, 0, 0, MintOpNoArgs)
849849
IROPDEF(MINT_DUMMY_USE, "dummy_use", 2, 0, 1, MintOpNoArgs)

src/mono/mono/mini/interp/transform-simd.c

+41-18
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,6 @@ static guint16 sri_vector128_methods [] = {
6767
};
6868

6969
static guint16 sri_vector128_t_methods [] = {
70-
SN_get_AllBitsSet,
71-
SN_get_Count,
72-
SN_get_One,
73-
SN_get_Zero,
7470
SN_op_Addition,
7571
SN_op_BitwiseAnd,
7672
SN_op_BitwiseOr,
@@ -84,12 +80,29 @@ static guint16 sri_vector128_t_methods [] = {
8480
SN_op_RightShift,
8581
SN_op_Subtraction,
8682
SN_op_UnaryNegation,
87-
SN_op_UnsignedRightShift
83+
SN_op_UnsignedRightShift,
84+
SN_get_AllBitsSet,
85+
SN_get_Count,
86+
SN_get_One,
87+
SN_get_Zero,
8888
};
8989

9090
static guint16 sri_packedsimd_methods [] = {
91+
SN_Add,
92+
SN_And,
93+
SN_Bitmask,
94+
SN_CompareEqual,
95+
SN_CompareNotEqual,
9196
SN_ConvertNarrowingSignedSaturate,
9297
SN_ConvertNarrowingUnsignedSaturate,
98+
SN_Dot,
99+
SN_Multiply,
100+
SN_Negate,
101+
SN_ShiftLeft,
102+
SN_ShiftRightArithmetic,
103+
SN_ShiftRightLogical,
104+
SN_Splat,
105+
SN_Subtract,
93106
SN_Swizzle,
94107
SN_get_IsHardwareAccelerated,
95108
SN_get_IsSupported,
@@ -534,12 +547,12 @@ static gboolean
534547
emit_sri_packedsimd (TransformData *td, MonoMethod *cmethod, MonoMethodSignature *csignature)
535548
{
536549
int id = lookup_intrins (sri_packedsimd_methods, sizeof (sri_packedsimd_methods), cmethod);
537-
if (id == -1)
538-
return FALSE;
550+
// We don't early-out for an unrecognized method, we will generate an NIY later
539551

540552
MonoClass *vector_klass = mono_class_from_mono_type_internal (csignature->ret);
541553
int vector_size = -1;
542554

555+
// NOTE: Linker substitutions (used in AOT) will prevent this from running.
543556
if ((id == SN_get_IsSupported) || (id == SN_get_IsHardwareAccelerated)) {
544557
#if HOST_BROWSER
545558
interp_add_ins (td, MINT_LDC_I4_1);
@@ -550,6 +563,23 @@ emit_sri_packedsimd (TransformData *td, MonoMethod *cmethod, MonoMethodSignature
550563
}
551564

552565
#if HOST_BROWSER
566+
if (id < 0) {
567+
g_print ("MONO interpreter: Unimplemented method: System.Runtime.Intrinsics.Wasm.PackedSimd.%s\n", cmethod->name);
568+
569+
// If we're missing a packedsimd method but the packedsimd method was AOT'd, we can
570+
// just let the interpreter generate a native call to the AOT method instead of
571+
// generating an NIY that will halt execution
572+
ERROR_DECL (error);
573+
gpointer addr = mono_aot_get_method (cmethod, error);
574+
if (addr)
575+
return FALSE;
576+
577+
// The packedsimd method implementations recurse infinitely and cause a stack overflow,
578+
// so replace them with a NIY opcode instead that will assert
579+
interp_add_ins (td, MINT_NIY);
580+
goto opcode_added;
581+
}
582+
553583
gint16 simd_opcode = -1;
554584
gint16 simd_intrins = -1;
555585
if (!m_class_is_simd_type (vector_klass))
@@ -705,21 +735,14 @@ interp_emit_simd_intrinsics (TransformData *td, MonoMethod *cmethod, MonoMethodS
705735
class_ns = m_class_get_name_space (cmethod->klass);
706736
class_name = m_class_get_name (cmethod->klass);
707737

708-
if (mono_opt_interp_simd_v128 && !strcmp (class_ns, "System.Runtime.Intrinsics")) {
738+
if (!strcmp (class_ns, "System.Runtime.Intrinsics")) {
709739
if (!strcmp (class_name, "Vector128"))
710740
return emit_sri_vector128 (td, cmethod, csignature);
711741
else if (!strcmp (class_name, "Vector128`1"))
712742
return emit_sri_vector128_t (td, cmethod, csignature);
713-
} else if (mono_opt_interp_simd_packedsimd && !strcmp (class_ns, "System.Runtime.Intrinsics.Wasm")) {
714-
if (!strcmp (class_name, "PackedSimd")) {
715-
gboolean res = emit_sri_packedsimd (td, cmethod, csignature);
716-
#if HOST_BROWSER
717-
if (!res)
718-
g_print ("MONO interpreter: Unsupported method: System.Runtime.Intrinsics.Wasm.PackedSimd.%s\n", cmethod->name);
719-
g_assert (res);
720-
#endif
721-
return res;
722-
}
743+
} else if (!strcmp (class_ns, "System.Runtime.Intrinsics.Wasm")) {
744+
if (!strcmp (class_name, "PackedSimd"))
745+
return emit_sri_packedsimd (td, cmethod, csignature);
723746
}
724747
return FALSE;
725748
}

src/mono/mono/utils/options-def.h

-6
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,6 @@ DEFINE_BOOL_READONLY(readonly_flag, "readonly-flag", FALSE, "Example")
6060
DEFINE_BOOL(wasm_exceptions, "wasm-exceptions", FALSE, "Enable codegen for WASM exceptions")
6161
DEFINE_BOOL(wasm_gc_safepoints, "wasm-gc-safepoints", FALSE, "Use GC safepoints on WASM")
6262
DEFINE_BOOL(aot_lazy_assembly_load, "aot-lazy-assembly-load", FALSE, "Load assemblies referenced by AOT images lazily")
63-
#if HOST_BROWSER
64-
DEFINE_BOOL(interp_simd_v128, "interp-simd-v128", FALSE, "Enable interpreter Vector128 support")
65-
#else
66-
DEFINE_BOOL(interp_simd_v128, "interp-simd-v128", TRUE, "Enable interpreter Vector128 support")
67-
#endif
68-
DEFINE_BOOL(interp_simd_packedsimd, "interp-simd-packedsimd", FALSE, "Enable interpreter WASM PackedSimd support")
6963

7064
#if HOST_BROWSER
7165

src/mono/wasm/build/WasmApp.targets

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
<UseAppHost>false</UseAppHost>
125125
<TrimMode Condition="'$(TrimMode)' == ''">full</TrimMode>
126126
<_ExtraTrimmerArgs Condition="'$(WasmEnableSIMD)' == 'true' and '$(RunAOTCompilation)' == 'true'">$(_ExtraTrimmerArgs) --substitutions &quot;$(MSBuildThisFileDirectory)ILLink.Substitutions.WasmIntrinsics.xml&quot;</_ExtraTrimmerArgs>
127-
<_ExtraTrimmerArgs Condition="'$(WasmEnableSIMD)' != 'true' or '$(RunAOTCompilation)' != 'true'">$(_ExtraTrimmerArgs) --substitutions &quot;$(MSBuildThisFileDirectory)ILLink.Substitutions.NoWasmIntrinsics.xml&quot;</_ExtraTrimmerArgs>
127+
<_ExtraTrimmerArgs Condition="'$(WasmEnableSIMD)' != 'true'">$(_ExtraTrimmerArgs) --substitutions &quot;$(MSBuildThisFileDirectory)ILLink.Substitutions.NoWasmIntrinsics.xml&quot;</_ExtraTrimmerArgs>
128128
<_ExtraTrimmerArgs Condition="'$(WasmEnableLegacyJsInterop)' == 'false'">$(_ExtraTrimmerArgs) --substitutions &quot;$(MSBuildThisFileDirectory)ILLink.Substitutions.LegacyJsInterop.xml&quot;</_ExtraTrimmerArgs>
129129

130130
<!-- Temporarily `false`, till sdk gets a fix for supporting the new file -->

src/mono/wasm/runtime/jiterpreter-tables.ts

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import {
2-
WasmOpcode, JiterpSpecialOpcode
2+
WasmOpcode, WasmSimdOpcode, JiterpSpecialOpcode
33
} from "./jiterpreter-opcodes";
44
import {
5-
MintOpcode, SimdIntrinsic3
5+
MintOpcode, SimdIntrinsic2, SimdIntrinsic3
66
} from "./mintops";
77

88
export const ldcTable: { [opcode: number]: [WasmOpcode, number] } = {
@@ -356,3 +356,17 @@ export const simdShiftTable = new Set<SimdIntrinsic3>([
356356
SimdIntrinsic3.V128_I4_URIGHT_SHIFT,
357357
SimdIntrinsic3.V128_I8_URIGHT_SHIFT,
358358
]);
359+
360+
export const bitmaskTable : { [intrinsic: number]: WasmSimdOpcode } = {
361+
[SimdIntrinsic2.V128_I1_EXTRACT_MSB]: WasmSimdOpcode.i8x16_bitmask,
362+
[SimdIntrinsic2.V128_I2_EXTRACT_MSB]: WasmSimdOpcode.i16x8_bitmask,
363+
[SimdIntrinsic2.V128_I4_EXTRACT_MSB]: WasmSimdOpcode.i32x4_bitmask,
364+
[SimdIntrinsic2.V128_I8_EXTRACT_MSB]: WasmSimdOpcode.i64x2_bitmask,
365+
};
366+
367+
export const createScalarTable : { [intrinsic: number]: [WasmOpcode, WasmSimdOpcode] } = {
368+
[SimdIntrinsic2.V128_I1_CREATE_SCALAR]: [WasmOpcode.i32_load8_s, WasmSimdOpcode.i8x16_replace_lane],
369+
[SimdIntrinsic2.V128_I2_CREATE_SCALAR]: [WasmOpcode.i32_load16_s, WasmSimdOpcode.i16x8_replace_lane],
370+
[SimdIntrinsic2.V128_I4_CREATE_SCALAR]: [WasmOpcode.i32_load, WasmSimdOpcode.i32x4_replace_lane],
371+
[SimdIntrinsic2.V128_I8_CREATE_SCALAR]: [WasmOpcode.i64_load, WasmSimdOpcode.i64x2_replace_lane],
372+
};

src/mono/wasm/runtime/jiterpreter-trace-generator.ts

+22-30
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import {
4848
relopbranchTable, mathIntrinsicTable,
4949
simdCreateLoadOps, simdCreateSizes,
5050
simdCreateStoreOps, simdShiftTable,
51+
bitmaskTable, createScalarTable,
5152
} from "./jiterpreter-tables";
5253
import { mono_log_error, mono_log_info } from "./logging";
5354

@@ -3156,13 +3157,6 @@ function append_simd_4_load(builder: WasmBuilder, ip: MintOpcodePtr) {
31563157
append_ldloc(builder, getArgU16(ip, 4), WasmOpcode.PREFIX_simd, WasmSimdOpcode.v128_load);
31573158
}
31583159

3159-
function append_stloc_simd_zero(builder: WasmBuilder, offset: number) {
3160-
builder.local("pLocals");
3161-
builder.appendSimd(WasmSimdOpcode.v128_const);
3162-
builder.appendBytes(new Uint8Array(sizeOfV128));
3163-
append_stloc_tail(builder, offset, WasmOpcode.PREFIX_simd, WasmSimdOpcode.v128_store);
3164-
}
3165-
31663160
function emit_simd_2(builder: WasmBuilder, ip: MintOpcodePtr, index: SimdIntrinsic2): boolean {
31673161
const simple = <WasmSimdOpcode>cwraps.mono_jiterp_get_simd_opcode(1, index);
31683162
if (simple) {
@@ -3172,35 +3166,33 @@ function emit_simd_2(builder: WasmBuilder, ip: MintOpcodePtr, index: SimdIntrins
31723166
return true;
31733167
}
31743168

3169+
const bitmask = bitmaskTable[index];
3170+
if (bitmask) {
3171+
append_simd_2_load(builder, ip);
3172+
builder.appendSimd(bitmask);
3173+
append_stloc_tail(builder, getArgU16(ip, 1), WasmOpcode.i32_store);
3174+
return true;
3175+
}
3176+
31753177
switch (index) {
31763178
case SimdIntrinsic2.V128_I1_CREATE_SCALAR:
3177-
// Zero then write scalar component
3178-
builder.local("pLocals");
3179-
append_stloc_simd_zero(builder, getArgU16(ip, 1));
3180-
append_ldloc(builder, getArgU16(ip, 2), WasmOpcode.i32_load8_s);
3181-
append_stloc_tail(builder, getArgU16(ip, 1), WasmOpcode.i32_store8);
3182-
return true;
31833179
case SimdIntrinsic2.V128_I2_CREATE_SCALAR:
3184-
// Zero then write scalar component
3185-
builder.local("pLocals");
3186-
append_stloc_simd_zero(builder, getArgU16(ip, 1));
3187-
append_ldloc(builder, getArgU16(ip, 2), WasmOpcode.i32_load16_s);
3188-
append_stloc_tail(builder, getArgU16(ip, 1), WasmOpcode.i32_store16);
3189-
return true;
31903180
case SimdIntrinsic2.V128_I4_CREATE_SCALAR:
3191-
// Zero then write scalar component
3181+
case SimdIntrinsic2.V128_I8_CREATE_SCALAR: {
3182+
const tableEntry = createScalarTable[index];
31923183
builder.local("pLocals");
3193-
append_stloc_simd_zero(builder, getArgU16(ip, 1));
3194-
append_ldloc(builder, getArgU16(ip, 2), WasmOpcode.i32_load);
3195-
append_stloc_tail(builder, getArgU16(ip, 1), WasmOpcode.i32_store);
3196-
return true;
3197-
case SimdIntrinsic2.V128_I8_CREATE_SCALAR:
3198-
// Zero then write scalar component
3199-
builder.local("pLocals");
3200-
append_stloc_simd_zero(builder, getArgU16(ip, 1));
3201-
append_ldloc(builder, getArgU16(ip, 2), WasmOpcode.i64_load);
3202-
append_stloc_tail(builder, getArgU16(ip, 1), WasmOpcode.i64_store);
3184+
// Make a zero vector
3185+
builder.i52_const(0);
3186+
builder.appendSimd(WasmSimdOpcode.i64x2_splat);
3187+
// Load the scalar value
3188+
append_ldloc(builder, getArgU16(ip, 2), tableEntry[0]);
3189+
// Replace the first lane
3190+
builder.appendSimd(tableEntry[1]);
3191+
builder.appendU8(0);
3192+
// Store result
3193+
append_stloc_tail(builder, getArgU16(ip, 1), WasmOpcode.PREFIX_simd, WasmSimdOpcode.v128_store);
32033194
return true;
3195+
}
32043196

32053197
case SimdIntrinsic2.V128_I1_CREATE:
32063198
append_simd_2_load(builder, ip, WasmSimdOpcode.v128_load8_splat);

0 commit comments

Comments
 (0)