-
Notifications
You must be signed in to change notification settings - Fork 5.3k
[mono][jit] Adding compare all/any intrinsics. #83515
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
7575d26
f317b0a
3354214
4896355
c239967
6234ae4
3b75c85
cc0e097
149a797
21a1850
8a7fb04
56aa1ad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1190,18 +1190,18 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi | |
| return NULL; | ||
| #endif | ||
| // FIXME: This limitation could be removed once everything here are supported by mini JIT on arm64 | ||
| #ifdef TARGET_ARM64 | ||
| if (!(cfg->compile_aot && cfg->full_aot && !cfg->interp)) | ||
| return NULL; | ||
| #endif | ||
| //#ifdef TARGET_ARM64 | ||
|
||
| // if (!(cfg->compile_aot && cfg->full_aot && !cfg->interp)) | ||
| // return NULL; | ||
| //#endif | ||
|
|
||
| int id = lookup_intrins (sri_vector_methods, sizeof (sri_vector_methods), cmethod); | ||
| if (id == -1) { | ||
| //check_no_intrinsic_cattr (cmethod); | ||
| return NULL; | ||
| } | ||
|
|
||
| if (!strcmp (m_class_get_name (cfg->method->klass), "Vector256")) | ||
| if (!strcmp (m_class_get_name (cfg->method->klass), "Vector256") || !strcmp (m_class_get_name (cfg->method->klass), "Vector512")) | ||
| return NULL; // TODO: Fix Vector256.WithUpper/WithLower | ||
|
||
|
|
||
| // FIXME: This limitation could be removed once everything here are supported by mini JIT on arm64 | ||
|
|
@@ -1216,6 +1216,16 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi | |
| case SN_LessThanOrEqual: | ||
| case SN_Negate: | ||
| case SN_OnesComplement: | ||
| case SN_EqualsAny: | ||
| case SN_GreaterThanAny: | ||
| case SN_GreaterThanOrEqualAny: | ||
| case SN_LessThanAny: | ||
| case SN_LessThanOrEqualAny: | ||
| case SN_EqualsAll: | ||
| case SN_GreaterThanAll: | ||
| case SN_GreaterThanOrEqualAll: | ||
| case SN_LessThanAll: | ||
| case SN_LessThanOrEqualAll: | ||
| case SN_Subtract: | ||
| case SN_BitwiseAnd: | ||
| case SN_BitwiseOr: | ||
|
|
@@ -1475,18 +1485,26 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi | |
| if (!is_element_type_primitive (fsig->params [0])) | ||
| return NULL; | ||
| MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); | ||
| switch (id) { | ||
| case SN_Equals: | ||
| return emit_xcompare (cfg, klass, arg0_type, args [0], args [1]); | ||
| case SN_EqualsAll: | ||
| return emit_xequal (cfg, arg_class, 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); | ||
| if (id == SN_Equals) | ||
| return emit_xcompare (cfg, klass, arg0_type, args [0], args [1]); | ||
|
|
||
| if (COMPILE_LLVM (cfg)) { | ||
fanyang-mono marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| switch (id) { | ||
| case SN_EqualsAll: | ||
| return emit_xequal (cfg, arg_class, 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); | ||
| } | ||
| } | ||
| default: g_assert_not_reached (); | ||
| } else { | ||
| MonoInst* cmp = emit_xcompare (cfg, arg_class, arg0_type, args [0], args [1]); | ||
| MonoInst* ret = emit_simd_ins (cfg, mono_defaults.boolean_class, OP_XEXTRACT, cmp->dreg, -1); | ||
| ret->inst_c0 = (id == SN_EqualsAll) ? SIMD_EXTR_MIN8 : SIMD_EXTR_MAX8; | ||
| return ret; | ||
| } | ||
| g_assert_not_reached (); | ||
| } | ||
| case SN_ExtractMostSignificantBits: { | ||
| if (!is_element_type_primitive (fsig->params [0]) || type_enum_is_float (arg0_type)) | ||
|
|
@@ -1554,34 +1572,39 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi | |
| fsig->ret->type == MONO_TYPE_BOOLEAN && | ||
| mono_metadata_type_equal (fsig->params [0], fsig->params [1])); | ||
|
|
||
| MonoInst *cmp = emit_xcompare_for_intrinsic (cfg, klass, id, arg0_type, args [0], args [1]); | ||
| MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); | ||
|
|
||
| gboolean is_all = FALSE; | ||
| switch (id) { | ||
| case SN_GreaterThanAll: | ||
| case SN_GreaterThanOrEqualAll: | ||
| case SN_LessThanAll: | ||
| case SN_LessThanOrEqualAll: { | ||
| // for floating point numbers all ones is NaN and so | ||
| // they must be treated differently than integer types | ||
| if (type_enum_is_float (arg0_type)) { | ||
| case SN_LessThanOrEqualAll: | ||
| is_all = TRUE; | ||
| break; | ||
| } | ||
|
|
||
| MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); | ||
| if (COMPILE_LLVM (cfg)) { | ||
| MonoInst *cmp = emit_xcompare_for_intrinsic (cfg, klass, id, arg0_type, args [0], args [1]); | ||
| if (is_all) { | ||
| // for floating point numbers all ones is NaN and so | ||
| // they must be treated differently than integer types | ||
| 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); | ||
| } | ||
|
|
||
| MonoInst *ones = emit_xones (cfg, arg_class); | ||
| return emit_xequal (cfg, arg_class, cmp, ones); | ||
| } else { | ||
| 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_not_xequal (cfg, arg_class, cmp, zero); | ||
| } | ||
|
|
||
| MonoInst *ones = emit_xones (cfg, arg_class); | ||
| return emit_xequal (cfg, arg_class, cmp, ones); | ||
| } | ||
| case SN_GreaterThanAny: | ||
| case SN_GreaterThanOrEqualAny: | ||
| case SN_LessThanAny: | ||
| case SN_LessThanOrEqualAny: { | ||
| MonoInst *zero = emit_xzero (cfg, arg_class); | ||
| return emit_not_xequal (cfg, arg_class, cmp, zero); | ||
| } | ||
| default: | ||
| g_assert_not_reached (); | ||
| } else { | ||
| MonoInst *cmp = emit_xcompare_for_intrinsic (cfg, arg_class, id, arg0_type, args [0], args [1]); | ||
| MonoInst* ret = emit_simd_ins (cfg, mono_defaults.boolean_class, OP_XEXTRACT, cmp->dreg, -1); | ||
| ret->inst_c0 = is_all ? SIMD_EXTR_MIN8 : SIMD_EXTR_MAX8; | ||
| return ret; | ||
| } | ||
| } | ||
| case SN_Narrow: { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to not hardcode the length of the vector to
VREG_FULL. I am thinking of reusing for vector64 in the future.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, there is a 64-bit variant of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OP_XEXTRACTnow carries vector width (8 or 16) inins->inst_c1.