-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
[Mono] Add SIMD intrinsic for Vector64/128 comparisons #65128
Merged
simonrozsival
merged 15 commits into
dotnet:main
from
simonrozsival:vector-intrinsics-eq-gt-geq-lt-leq
Feb 25, 2022
+178
−85
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
dd0b05a
Add vector comparison intrinsics
simonrozsival e397416
Add EqualsAll and EqualsAny intrinsics
simonrozsival 7c9dc2a
Merge branch 'main' into vector-intrinsics-eq-gt-geq-lt-leq
simonrozsival 6d01474
Remove broken EqualsAny
simonrozsival 9434cf9
Fix EqualsAny
simonrozsival c6882fe
Merge branch 'main' of https://github.com/dotnet/runtime into vector-…
simonrozsival 9120f8e
Enable xequal also for arm64
simonrozsival ba3b3e2
Fix xzero type
simonrozsival 0cd0a3a
Merge branch 'main' into vector-intrinsics-eq-gt-geq-lt-leq
simonrozsival ed8f56b
Fix bad merge
simonrozsival a35683b
Add guards for invalid types
simonrozsival 82a7672
Revert unrelated change
simonrozsival 862cda9
Extract duplicate code blocks to a new function
simonrozsival 20113c3
Fix EqualsAny
simonrozsival 1c0f52d
Fix typo + code improvements
simonrozsival File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -260,6 +260,29 @@ emit_xcompare (MonoCompile *cfg, MonoClass *klass, MonoTypeEnum etype, MonoInst | |
return ins; | ||
} | ||
|
||
static MonoInst* | ||
emit_xequal (MonoCompile *cfg, MonoClass *klass, MonoInst *arg1, MonoInst *arg2) | ||
{ | ||
return emit_simd_ins (cfg, klass, OP_XEQUAL, arg1->dreg, arg2->dreg); | ||
} | ||
|
||
static MonoInst* | ||
emit_not_xequal (MonoCompile *cfg, MonoClass *klass, MonoInst *arg1, MonoInst *arg2) | ||
{ | ||
MonoInst *ins = emit_simd_ins (cfg, klass, OP_XEQUAL, arg1->dreg, arg2->dreg); | ||
int sreg = ins->dreg; | ||
int dreg = alloc_ireg (cfg); | ||
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, sreg, 0); | ||
EMIT_NEW_UNALU (cfg, ins, OP_CEQ, dreg, -1); | ||
return ins; | ||
} | ||
|
||
static MonoInst* | ||
emit_xzero (MonoCompile *cfg, MonoClass *klass) | ||
{ | ||
return emit_simd_ins (cfg, klass, OP_XZERO, -1, -1); | ||
} | ||
|
||
static gboolean | ||
is_intrinsics_vector_type (MonoType *vector_type) | ||
{ | ||
|
@@ -492,7 +515,7 @@ emit_vector_create_elementwise ( | |
{ | ||
int op = type_to_insert_op (etype); | ||
MonoClass *vklass = mono_class_from_mono_type_internal (vtype); | ||
MonoInst *ins = emit_simd_ins (cfg, vklass, OP_XZERO, -1, -1); | ||
MonoInst *ins = emit_xzero (cfg, vklass); | ||
for (int i = 0; i < fsig->param_count; ++i) { | ||
ins = emit_simd_ins (cfg, vklass, op, ins->dreg, args [i]->dreg); | ||
ins->inst_c0 = i; | ||
|
@@ -590,10 +613,17 @@ static guint16 sri_vector_methods [] = { | |
SN_CreateScalar, | ||
SN_CreateScalarUnsafe, | ||
SN_Divide, | ||
SN_Equals, | ||
SN_EqualsAll, | ||
SN_EqualsAny, | ||
SN_Floor, | ||
SN_GetElement, | ||
SN_GetLower, | ||
SN_GetUpper, | ||
SN_GreaterThan, | ||
SN_GreaterThanOrEqual, | ||
SN_LessThan, | ||
SN_LessThanOrEqual, | ||
SN_Max, | ||
SN_Min, | ||
SN_Multiply, | ||
|
@@ -788,6 +818,27 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi | |
return emit_simd_ins_for_sig (cfg, klass, OP_CREATE_SCALAR, -1, arg0_type, fsig, args); | ||
case SN_CreateScalarUnsafe: | ||
return emit_simd_ins_for_sig (cfg, klass, OP_CREATE_SCALAR_UNSAFE, -1, arg0_type, fsig, args); | ||
case SN_Equals: | ||
case SN_EqualsAll: | ||
case SN_EqualsAny: { | ||
MonoType *arg_type = get_vector_t_elem_type (fsig->params [0]); | ||
if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type)) | ||
return NULL; | ||
|
||
switch (id) { | ||
case SN_Equals: | ||
return emit_xcompare (cfg, klass, arg0_type, args [0], args [1]); | ||
case SN_EqualsAll: | ||
return emit_xequal (cfg, klass, args [0], args [1]); | ||
case SN_EqualsAny: { | ||
MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); | ||
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 (); | ||
} | ||
} | ||
case SN_GetElement: { | ||
MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); | ||
MonoType *etype = mono_class_get_context (arg_class)->class_inst->type_argv [0]; | ||
|
@@ -809,6 +860,34 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi | |
int op = id == SN_GetLower ? OP_XLOWER : OP_XUPPER; | ||
return emit_simd_ins_for_sig (cfg, klass, op, 0, arg0_type, fsig, args); | ||
} | ||
case SN_GreaterThan: | ||
case SN_GreaterThanOrEqual: | ||
case SN_LessThan: | ||
case SN_LessThanOrEqual: { | ||
MonoType *arg_type = get_vector_t_elem_type (fsig->params [0]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto |
||
if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type)) | ||
return NULL; | ||
|
||
gboolean is_unsigned = type_is_unsigned (fsig->params [0]); | ||
MonoInst *ins = emit_xcompare (cfg, klass, arg0_type, args [0], args [1]); | ||
switch (id) { | ||
case SN_GreaterThan: | ||
ins->inst_c0 = is_unsigned ? CMP_GT_UN : CMP_GT; | ||
break; | ||
case SN_GreaterThanOrEqual: | ||
ins->inst_c0 = is_unsigned ? CMP_GE_UN : CMP_GE; | ||
break; | ||
case SN_LessThan: | ||
ins->inst_c0 = is_unsigned ? CMP_LT_UN : CMP_LT; | ||
break; | ||
case SN_LessThanOrEqual: | ||
ins->inst_c0 = is_unsigned ? CMP_LE_UN : CMP_LE; | ||
break; | ||
default: | ||
g_assert_not_reached (); | ||
} | ||
return ins; | ||
} | ||
case SN_Negate: | ||
case SN_OnesComplement: { | ||
#ifdef TARGET_ARM64 | ||
|
@@ -879,6 +958,8 @@ static guint16 vector64_vector128_t_methods [] = { | |
SN_get_Count, | ||
SN_get_IsSupported, | ||
SN_get_Zero, | ||
SN_op_Equality, | ||
SN_op_Inequality, | ||
}; | ||
|
||
static MonoInst* | ||
|
@@ -928,10 +1009,10 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign | |
return ins; | ||
} | ||
case SN_get_Zero: { | ||
return emit_simd_ins (cfg, klass, OP_XZERO, -1, -1); | ||
return emit_xzero (cfg, klass); | ||
} | ||
case SN_get_AllBitsSet: { | ||
MonoInst *ins = emit_simd_ins (cfg, klass, OP_XZERO, -1, -1); | ||
MonoInst *ins = emit_xzero (cfg, klass); | ||
return emit_xcompare (cfg, klass, etype->type, ins, ins); | ||
simonrozsival marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
case SN_Equals: { | ||
|
@@ -941,6 +1022,16 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign | |
} | ||
break; | ||
} | ||
case SN_op_Equality: | ||
case SN_op_Inequality: | ||
g_assert (fsig->param_count == 2 && fsig->ret->type == MONO_TYPE_BOOLEAN && | ||
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]); | ||
default: g_assert_not_reached (); | ||
} | ||
default: | ||
break; | ||
} | ||
|
@@ -1086,7 +1177,7 @@ emit_sys_numerics_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSig | |
return ins; | ||
case SN_get_Zero: | ||
g_assert (fsig->param_count == 0 && mono_metadata_type_equal (fsig->ret, type)); | ||
return emit_simd_ins (cfg, klass, OP_XZERO, -1, -1); | ||
return emit_xzero (cfg, klass); | ||
case SN_get_One: { | ||
g_assert (fsig->param_count == 0 && mono_metadata_type_equal (fsig->ret, type)); | ||
MonoInst *one = NULL; | ||
|
@@ -1115,7 +1206,7 @@ emit_sys_numerics_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSig | |
} | ||
case SN_get_AllBitsSet: { | ||
/* Compare a zero vector with itself */ | ||
ins = emit_simd_ins (cfg, klass, OP_XZERO, -1, -1); | ||
ins = emit_xzero (cfg, klass); | ||
return emit_xcompare (cfg, klass, etype->type, ins, ins); | ||
} | ||
case SN_get_Item: { | ||
|
@@ -1222,14 +1313,11 @@ emit_sys_numerics_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSig | |
g_assert (fsig->param_count == 2 && fsig->ret->type == MONO_TYPE_BOOLEAN && | ||
mono_metadata_type_equal (fsig->params [0], type) && | ||
mono_metadata_type_equal (fsig->params [1], type)); | ||
ins = emit_simd_ins (cfg, klass, OP_XEQUAL, args [0]->dreg, args [1]->dreg); | ||
if (id == SN_op_Inequality) { | ||
int sreg = ins->dreg; | ||
int dreg = alloc_ireg (cfg); | ||
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, sreg, 0); | ||
EMIT_NEW_UNALU (cfg, ins, OP_CEQ, dreg, -1); | ||
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]); | ||
default: g_assert_not_reached (); | ||
} | ||
return ins; | ||
case SN_GreaterThan: | ||
case SN_GreaterThanOrEqual: | ||
case SN_LessThan: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
We should start to add comprehensive vector element type checks for each case. (Both input args and the return.) I have a PR up to refactor the code of type checks for this function. (#65486) You could merge this PR like this and fix it with your next PR.