From 3454d8c7fc1ee1a1a64f61b3b7df27d1b922b922 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 4 Jan 2023 10:39:29 +0100 Subject: [PATCH] [wasm] Add ConditionalSelect SIMD intrinsics (#80145) 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] ... --- src/mono/mono/mini/mini-llvm.c | 4 +++- src/mono/mono/mini/mini-ops.h | 5 ++++- src/mono/mono/mini/simd-intrinsics.c | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c index dc678c6eba444..ee1578d9318b9 100644 --- a/src/mono/mono/mini/mini-llvm.c +++ b/src/mono/mono/mini/mini-llvm.c @@ -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); @@ -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; diff --git a/src/mono/mono/mini/mini-ops.h b/src/mono/mono/mini/mini-ops.h index 9e8320306e358..7db9500b41bae 100644 --- a/src/mono/mono/mini/mini-ops.h +++ b/src/mono/mono/mini/mini-ops.h @@ -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) @@ -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 diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index ddbffd8898784..1ed5b6f52e319 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -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);