From 74a8b8a6aa84081211c9cf9416c6e51446324437 Mon Sep 17 00:00:00 2001 From: Vlad - Alexandru Ionescu Date: Fri, 14 Jul 2023 16:08:04 +0200 Subject: [PATCH 1/4] Enabled more intrinsics for V4 Signed-off-by: Vlad - Alexandru Ionescu --- src/mono/mono/mini/simd-intrinsics.c | 61 ++++++++++------------------ 1 file changed, 21 insertions(+), 40 deletions(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 8df9cd7885347c..8d2347f58baff7 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -548,12 +548,11 @@ emit_xcompare_for_intrinsic (MonoCompile *cfg, MonoClass *klass, int intrinsic_i } static MonoInst* -emit_xequal (MonoCompile *cfg, MonoClass *klass, MonoInst *arg1, MonoInst *arg2) +emit_xequal (MonoCompile *cfg, MonoClass *klass, MonoTypeEnum element_type, MonoInst *arg1, MonoInst *arg2) { #ifdef TARGET_ARM64 if (!COMPILE_LLVM (cfg)) { - MonoTypeEnum elemt = get_underlying_type (m_class_get_this_arg (arg1->klass)); - MonoInst* cmp = emit_xcompare (cfg, arg1->klass, elemt, arg1, arg2); + MonoInst* cmp = emit_xcompare (cfg, klass, element_type, arg1, arg2); MonoInst* ret = emit_simd_ins (cfg, mono_defaults.boolean_class, OP_XEXTRACT, cmp->dreg, -1); ret->inst_c0 = SIMD_EXTR_ARE_ALL_SET; ret->inst_c1 = mono_class_value_size (klass, NULL); @@ -572,9 +571,9 @@ emit_xequal (MonoCompile *cfg, MonoClass *klass, MonoInst *arg1, MonoInst *arg2) } static MonoInst* -emit_not_xequal (MonoCompile *cfg, MonoClass *klass, MonoInst *arg1, MonoInst *arg2) +emit_not_xequal (MonoCompile *cfg, MonoClass *klass, MonoTypeEnum element_type, MonoInst *arg1, MonoInst *arg2) { - MonoInst *ins = emit_xequal (cfg, klass, arg1, arg2); + MonoInst *ins = emit_xequal (cfg, klass, element_type, arg1, arg2); int sreg = ins->dreg; int dreg = alloc_ireg (cfg); MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, sreg, 0); @@ -1784,11 +1783,11 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi if (COMPILE_LLVM (cfg)) { switch (id) { case SN_EqualsAll: - return emit_xequal (cfg, arg_class, args [0], args [1]); + return emit_xequal (cfg, arg_class, arg0_type, args [0], args [1]); case SN_EqualsAny: { MonoInst *cmp_eq = emit_xcompare (cfg, arg_class, arg0_type, args [0], args [1]); MonoInst *zero = emit_xzero (cfg, arg_class); - return emit_not_xequal (cfg, arg_class, cmp_eq, zero); + return emit_not_xequal (cfg, arg_class, arg0_type, cmp_eq, zero); } } } else { @@ -1979,14 +1978,14 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi if (type_enum_is_float (arg0_type)) { MonoInst *zero = emit_xzero (cfg, arg_class); MonoInst *inverted_cmp = emit_xcompare (cfg, klass, arg0_type, cmp, zero); - return emit_xequal (cfg, arg_class, inverted_cmp, zero); + return emit_xequal (cfg, arg_class, arg0_type, inverted_cmp, zero); } MonoInst *ones = emit_xones (cfg, arg_class); - return emit_xequal (cfg, arg_class, cmp, ones); + return emit_xequal (cfg, arg_class, arg0_type, cmp, ones); } else { MonoInst *zero = emit_xzero (cfg, arg_class); - return emit_not_xequal (cfg, arg_class, cmp, zero); + return emit_not_xequal (cfg, arg_class, arg0_type, cmp, zero); } } else { MonoInst* cmp = emit_xcompare_for_intrinsic (cfg, arg_class, id, arg0_type, args [0], args [1]); @@ -2516,8 +2515,8 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign return NULL; MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); switch (id) { - case SN_op_Equality: return emit_xequal (cfg, arg_class, args [0], args [1]); - case SN_op_Inequality: return emit_not_xequal (cfg, arg_class, args [0], args [1]); + case SN_op_Equality: return emit_xequal (cfg, arg_class, arg0_type, args [0], args [1]); + case SN_op_Inequality: return emit_not_xequal (cfg, arg_class, arg0_type, args [0], args [1]); default: g_assert_not_reached (); } } @@ -2600,28 +2599,7 @@ emit_vector_2_3_4 (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f // when a method gets enabled should be removed from here switch (id) { case SN_ctor: - case SN_Clamp: - case SN_Conjugate: - case SN_CopyTo: - case SN_Distance: - case SN_DistanceSquared: - case SN_Dot: - case SN_Length: - case SN_LengthSquared: - case SN_Lerp: - case SN_Negate: - case SN_Normalize: - case SN_get_Identity: case SN_get_Item: - case SN_get_One: - case SN_get_UnitW: - case SN_get_UnitX: - case SN_get_UnitY: - case SN_get_UnitZ: - case SN_get_Zero: - case SN_op_Equality: - case SN_op_Inequality: - case SN_op_UnaryNegation: case SN_set_Item: return NULL; default: @@ -2789,8 +2767,7 @@ emit_vector_2_3_4 (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f } case SN_Dot: { #if defined(TARGET_ARM64) || defined(TARGET_WASM) - int instc0 = OP_FMUL; - MonoInst *pairwise_multiply = emit_simd_ins_for_sig (cfg, klass, OP_XBINOP, instc0, MONO_TYPE_R4, fsig, args); + MonoInst *pairwise_multiply = emit_simd_ins_for_sig (cfg, klass, OP_XBINOP, OP_FMUL, MONO_TYPE_R4, fsig, args); return emit_sum_vector (cfg, fsig->params [0], MONO_TYPE_R4, pairwise_multiply); #elif defined(TARGET_AMD64) if (!(mini_get_cpu_features (cfg) & MONO_CPU_X86_SSE41)) @@ -2815,7 +2792,11 @@ emit_vector_2_3_4 (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f case SN_Negate: case SN_op_UnaryNegation: { #if defined(TARGET_ARM64) || defined(TARGET_AMD64) - return emit_simd_ins (cfg, klass, OP_NEGATION, args [0]->dreg, -1); + if (!COMPILE_LLVM(cfg)) { + return emit_simd_ins_for_unary_op (cfg, klass, fsig, args, MONO_TYPE_R4, id); + } else { + return emit_simd_ins (cfg, klass, OP_NEGATION, args [0]->dreg, -1); + } #else return NULL; #endif @@ -2840,13 +2821,13 @@ emit_vector_2_3_4 (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f if (!(fsig->param_count == 2 && mono_metadata_type_equal (fsig->params [0], type) && mono_metadata_type_equal (fsig->params [1], type))) return NULL; MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); - return emit_xequal (cfg, arg_class, args [0], args [1]); + return emit_xequal (cfg, arg_class, MONO_TYPE_R4, args [0], args [1]); } case SN_op_Inequality: { if (!(fsig->param_count == 2 && mono_metadata_type_equal (fsig->params [0], type) && mono_metadata_type_equal (fsig->params [1], type))) return NULL; MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); - return emit_not_xequal (cfg, arg_class, args [0], args [1]); + return emit_not_xequal (cfg, arg_class, MONO_TYPE_R4, args [0], args [1]); } case SN_SquareRoot: { #ifdef TARGET_ARM64 @@ -3207,8 +3188,8 @@ emit_sys_numerics_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSig mono_metadata_type_equal (fsig->params [0], type) && mono_metadata_type_equal (fsig->params [1], type)); switch (id) { - case SN_op_Equality: return emit_xequal (cfg, klass, args [0], args [1]); - case SN_op_Inequality: return emit_not_xequal (cfg, klass, args [0], args [1]); + case SN_op_Equality: return emit_xequal (cfg, klass, arg0_type, args [0], args [1]); + case SN_op_Inequality: return emit_not_xequal (cfg, klass, arg0_type, args [0], args [1]); default: g_assert_not_reached (); } case SN_GreaterThan: From 11867b9008648e0a71a1e209f38984f0749293b2 Mon Sep 17 00:00:00 2001 From: Vlad - Alexandru Ionescu Date: Mon, 17 Jul 2023 10:01:53 +0200 Subject: [PATCH 2/4] Passing etype->type instead of arg0_type Signed-off-by: Vlad - Alexandru Ionescu --- src/mono/mono/mini/simd-intrinsics.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 8d2347f58baff7..d0e2115c3c32d1 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -3188,8 +3188,8 @@ emit_sys_numerics_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSig mono_metadata_type_equal (fsig->params [0], type) && mono_metadata_type_equal (fsig->params [1], type)); switch (id) { - case SN_op_Equality: return emit_xequal (cfg, klass, arg0_type, args [0], args [1]); - case SN_op_Inequality: return emit_not_xequal (cfg, klass, arg0_type, args [0], args [1]); + case SN_op_Equality: return emit_xequal (cfg, klass, etype->type, args [0], args [1]); + case SN_op_Inequality: return emit_not_xequal (cfg, klass, etype->type, args [0], args [1]); default: g_assert_not_reached (); } case SN_GreaterThan: From 545b0eb82109c98554f33956c431dd727817fb42 Mon Sep 17 00:00:00 2001 From: Vlad - Alexandru Ionescu Date: Thu, 20 Jul 2023 19:02:17 +0200 Subject: [PATCH 3/4] Specify arg type to instruction Signed-off-by: Vlad - Alexandru Ionescu --- src/mono/mono/mini/simd-intrinsics.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 68061803cc4f52..c6ba61e76221eb 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -2792,11 +2792,9 @@ emit_vector_2_3_4 (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f case SN_Negate: case SN_op_UnaryNegation: { #if defined(TARGET_ARM64) || defined(TARGET_AMD64) - if (!COMPILE_LLVM(cfg)) { - return emit_simd_ins_for_unary_op (cfg, klass, fsig, args, MONO_TYPE_R4, id); - } else { - return emit_simd_ins (cfg, klass, OP_NEGATION, args [0]->dreg, -1); - } + MonoInst *ins = emit_simd_ins (cfg, klass, OP_NEGATION, args [0]->dreg, -1); + ins->inst_c1 = MONO_TYPE_R4; + return ins; #else return NULL; #endif From a522264b8f29387be3882643760cf0251d488b5b Mon Sep 17 00:00:00 2001 From: Vlad - Alexandru Ionescu Date: Fri, 21 Jul 2023 15:26:13 +0200 Subject: [PATCH 4/4] Use already declared variable Signed-off-by: Vlad - Alexandru Ionescu --- src/mono/mono/mini/simd-intrinsics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index c6ba61e76221eb..536e0e135d8c1a 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -2792,7 +2792,7 @@ emit_vector_2_3_4 (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f case SN_Negate: case SN_op_UnaryNegation: { #if defined(TARGET_ARM64) || defined(TARGET_AMD64) - MonoInst *ins = emit_simd_ins (cfg, klass, OP_NEGATION, args [0]->dreg, -1); + ins = emit_simd_ins (cfg, klass, OP_NEGATION, args [0]->dreg, -1); ins->inst_c1 = MONO_TYPE_R4; return ins; #else