-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
[Mono] [Arm64] Add basic Vector3 SIMD intrinsics #97416
Changes from 7 commits
a9918e5
d384ae7
1e30142
dfcbb55
552c019
472cabd
74a2a29
b47cdf9
e672c53
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -554,13 +554,14 @@ static MonoInst* | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
emit_xequal (MonoCompile *cfg, MonoClass *klass, MonoTypeEnum element_type, MonoInst *arg1, MonoInst *arg2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#ifdef TARGET_ARM64 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
gint32 simd_size = mono_class_value_size (klass, NULL); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!COMPILE_LLVM (cfg)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return ret; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else if (mono_class_value_size (klass, NULL) == 16) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else if (simd_size == 16 || simd_size == 12) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
jkurdek marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return emit_simd_ins (cfg, klass, OP_XEQUAL_ARM64_V128_FAST, arg1->dreg, arg2->dreg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return emit_simd_ins (cfg, klass, OP_XEQUAL, arg1->dreg, arg2->dreg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -649,10 +650,15 @@ emit_sum_vector (MonoCompile *cfg, MonoType *vector_type, MonoTypeEnum element_t | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
MonoClass *vector_class = mono_class_from_mono_type_internal (vector_type); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int vector_size = mono_class_value_size (vector_class, NULL); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int element_size; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// FIXME: Support Vector3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
guint32 nelems; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mini_get_simd_type_info (vector_class, &nelems); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mini_get_simd_type_info (vector_class, &nelems); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Override nelems for Vector3, with actual number of elements | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
jkurdek marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const char *klass_name = m_class_get_name (vector_class); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!strcmp (klass_name, "Vector3")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
nelems = 3; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
element_size = vector_size / nelems; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
gboolean has_single_element = vector_size == element_size; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -2721,6 +2727,17 @@ emit_vector_2_3_4 (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for (int i = 1; i < fsig->param_count; ++i) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ins = emit_vector_insert_element (cfg, klass, ins, MONO_TYPE_R4, args [i + 1], i, FALSE); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (len == 3) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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. Does this also handle the Vector3 constructor: runtime/src/mono/mono/mini/simd-intrinsics.c Lines 2734 to 2762 in 93381bf
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. It is not supported yet, I created a new issue for the rest of vector constructors as it seems they don't work out of the box. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
static float r4_0 = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
MonoInst *zero; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int zero_dreg = alloc_freg (cfg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
MONO_INST_NEW (cfg, zero, OP_R4CONST); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
zero->inst_p0 = (void*)&r4_0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
zero->dreg = zero_dreg; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
MONO_ADD_INS (cfg->cbb, zero); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ins = emit_vector_insert_element (cfg, klass, ins, MONO_TYPE_R4, zero, 3, FALSE); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ins->dreg = dreg; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (indirect) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -5923,7 +5940,7 @@ arch_emit_simd_intrinsics (const char *class_ns, const char *class_name, MonoCom | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!strcmp (class_ns, "System.Numerics")) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// FIXME: Support Vector2 https://github.com/dotnet/runtime/issues/81501 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!strcmp (class_name, "Vector2") || !strcmp (class_name, "Vector4") || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!strcmp (class_name, "Vector2") || !strcmp (class_name, "Vector3") || !strcmp (class_name, "Vector4") || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
!strcmp (class_name, "Quaternion") || !strcmp (class_name, "Plane")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return emit_vector_2_3_4 (cfg, cmethod, fsig, args); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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.
Why are we decrementing
len
here?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.
I encountered case that
lhs
would be V3 represented as V4(three elements + zero). And theretval
would be V3.The code tried to extract the fourth value of
lhs
and insert it intoretval
which caused an error, asretval
had only three elements.The change made it only extract and insert the first three elms if V3 was encoutered
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.
I would add comment explaining this special case for easier comprehension.
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.
@jkurdek thank you for the explanation.
Just for my understanding, so it basically means that in such cases
LLVMGetReturnType (ctx->lmethod_type)
andLLVMTypeOf (lhs)
are returning a different type (as we end up having different vector sizes) ?If we have these kind of workarounds across the mini-llvm code, I think it is ok to manually adjust the
len
however to be less cryptic, it might be better to have a comment explaining the special-casing (as @matouskozak suggested) and something like this instead: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.
Yup,
LLVMGetReturnType (ctx->lmethod_type)
is a vector of three elements,whereas LLVMTypeOf (lhs)
is a vector of four elements (three + zero)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.
Since 3 element vectors don't exist in the hardware, it might be easier to use 4 elements ones in return types etc. and only handle 3 element ones in loads/stores etc.