Skip to content

Commit

Permalink
[wasm] Add ConditionalSelect SIMD intrinsics (dotnet#80145)
Browse files Browse the repository at this point in the history
It uses existing `OP_BSL`, which does And, Not, And and Or operations.
llvm emits it as `v128.bitselect` for us. So I think we don't need
to use the `llvm.wasm.bitselect.*` intrinsics.

This should help in few areas, SpanHelper.ReplaceValueType and
IndexOfAnyAsciiSearcher.IndexOfAnyLookup'1.

It improves the Json deserialization a bit:

| measurement | before | after |
|-:|-:|-:|
|       Json, non-ASCII text deserialize |     0.4343ms |     0.4275ms |
|                Json, small deserialize |     0.0517ms |     0.0497ms |
|                Json, large deserialize |    14.3995ms |    13.8217ms |

Example of emitted code:

    > wa-info -d -f SpanHelper.*ReplaceValueType src\mono\sample\wasm\browser-bench\bin\Release\AppBundle\dotnet.wasm
    (func corlib_System_SpanHelpers_ReplaceValueType_uint16_uint16__uint16__uint16_uint16_uintptr(param $0 i32, $1 i32, $2 i32, $3 i32, $4 i32, $5 i32))
    ...
        i16x8.eq    [SIMD]
        v128.bitselect    [SIMD]
        v128.store    [SIMD]
    ...
  • Loading branch information
radekdoulik committed Jan 4, 2023
1 parent 7690b0a commit 3454d8c
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 3 deletions.
4 changes: 3 additions & 1 deletion src/mono/mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -11305,7 +11305,7 @@ MONO_RESTORE_WARNING
break;
}
#endif
#if defined(TARGET_ARM64) || defined(TARGET_AMD64)
#if defined(TARGET_ARM64) || defined(TARGET_AMD64) || defined(TARGET_WASM)
case OP_BSL: {
LLVMTypeRef ret_t = LLVMTypeOf (rhs);
LLVMValueRef select = bitcast_to_integral (ctx, lhs);
Expand All @@ -11318,6 +11318,8 @@ MONO_RESTORE_WARNING
values [ins->dreg] = result;
break;
}
#endif
#if defined(TARGET_ARM64) || defined(TARGET_AMD64)
case OP_NEGATION:
case OP_NEGATION_SCALAR: {
gboolean scalar = ins->opcode == OP_NEGATION_SCALAR;
Expand Down
5 changes: 4 additions & 1 deletion src/mono/mono/mini/mini-ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -1767,7 +1767,6 @@ MINI_OP(OP_WASM_ONESCOMPLEMENT, "wasm_onescomplement", XREG, XREG, NONE)
#endif

#if defined(TARGET_ARM64) || defined(TARGET_AMD64)
MINI_OP3(OP_BSL, "bitwise_select", XREG, XREG, XREG, XREG)
MINI_OP(OP_NEGATION, "negate", XREG, XREG, NONE)
MINI_OP(OP_NEGATION_SCALAR, "negate_scalar", XREG, XREG, NONE)
MINI_OP(OP_ONES_COMPLEMENT, "ones_complement", XREG, XREG, NONE)
Expand All @@ -1782,3 +1781,7 @@ MINI_OP(OP_CVT_SI_FP, "convert_si_to_fp", XREG, XREG, NONE)
MINI_OP(OP_CVT_UI_FP_SCALAR, "convert_ui_to_fp_scalar", XREG, XREG, NONE)
MINI_OP(OP_CVT_SI_FP_SCALAR, "convert_si_to_fp_scalar", XREG, XREG, NONE)
#endif // TARGET_ARM64 || TARGET_AMD64

#if defined(TARGET_ARM64) || defined(TARGET_AMD64) || defined(TARGET_WASM)
MINI_OP3(OP_BSL, "bitwise_select", XREG, XREG, XREG, XREG)
#endif // TARGET_ARM64 || TARGET_AMD64 || TARGET_WASM
2 changes: 1 addition & 1 deletion src/mono/mono/mini/simd-intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -1253,7 +1253,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
#endif
}
case SN_ConditionalSelect: {
#if defined(TARGET_ARM64) || defined(TARGET_AMD64)
#if defined(TARGET_ARM64) || defined(TARGET_AMD64) || defined(TARGET_WASM)
if (!is_element_type_primitive (fsig->params [0]))
return NULL;
return emit_simd_ins_for_sig (cfg, klass, OP_BSL, -1, arg0_type, fsig, args);
Expand Down

0 comments on commit 3454d8c

Please sign in to comment.