-
Notifications
You must be signed in to change notification settings - Fork 5.2k
[Mono] Add arm64 SIMD intrinsic for Vector64/128 Abs #65086
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 arm64 SIMD intrinsic for Vector64/128 Abs #65086
Conversation
src/mono/mono/mini/simd-intrinsics.c
Outdated
| case SN_Abs: { | ||
| #ifdef TARGET_ARM64 | ||
| MonoType *arg_type = get_vector_t_elem_type (fsig->params [0]); | ||
| if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type)) |
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 am not sure if this check is necessary. What would happen if you don't have 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.
I wanted to check if type is numeric but I see now that it doesn't check that. Do we have some function to understand if type is numeric?
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 had the impression that it is guaranteed that it should be numeric type, cause the other cases wasn't checking 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.
It validates that T is actually a supported type for Vector64/128/256 as not every primitive type is supported.
Notably, it can be relaxed from
runtime/src/mono/mono/mini/simd-intrinsics.c
Line 599 in 04bb6eb
| #define MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE(t) ((MONO_TYPE_IS_VECTOR_PRIMITIVE(t)) && ((t)->type != MONO_TYPE_I) && ((t)->type != MONO_TYPE_U)) |
To just:
- #define MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE(t) ((MONO_TYPE_IS_VECTOR_PRIMITIVE(t)) && ((t)->type != MONO_TYPE_I) && ((t)->type != MONO_TYPE_U))
+ #define MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE(t) MONO_TYPE_IS_VECTOR_PRIMITIVE(t)Where MONO_TYPE_IS_VECTOR_PRIMITIVE is:
runtime/src/mono/mono/mini/mini.h
Line 142 in 6c72db8
| #define MONO_TYPE_IS_VECTOR_PRIMITIVE(t) ((!m_type_is_byref ((t)) && ((((t)->type >= MONO_TYPE_I1 && (t)->type <= MONO_TYPE_R8) || ((t)->type >= MONO_TYPE_I && (t)->type <= MONO_TYPE_U))))) |
For reference; in .NET 6 Vector64/128/256<T> only support:
byteandsbyteshortandushortintanduintlongandulongfloatanddouble
While Vector<T> supports those plus nint and nuint.
In .NET 7, Vector64/128/256<T> also support nint and nuint bringing them inline.
We do not support bool, char, decimal, or half today (or any of the other types that may be built-in or specially recognized).
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 see, thanks for the detailed explanation.
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.
@tannergooding So it is not guaranteed that runtime would only be given the supported types?
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.
Right. A user can go declare Vector<bool> just fine, nothing prevents that. Same with Vector<Guid>, etc
Attempting to use any of the methods/members on Vector<bool> is expected to fail however. So the JIT shouldn't intrinsify them and should let the managed type checks throw the relevant exception
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.
Gotcha!
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.
Created an issue #65318 to track the cleanup work.
src/mono/mono/mini/simd-intrinsics.c
Outdated
| switch (id) { | ||
| case SN_Abs: { | ||
| #ifdef TARGET_ARM64 | ||
| MonoType *arg_type = get_vector_t_elem_type (fsig->params [0]); |
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.
Fix indentation.
src/mono/mono/mini/simd-intrinsics.c
Outdated
| MonoType *arg_type = get_vector_t_elem_type (fsig->params [0]); | ||
| if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type)) | ||
| return NULL; | ||
| gboolean is_float = type_is_float (fsig->params [0]); |
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.
It is faster to make type comparison directly here, since you have arg0_type already. If you look at the content of type_is_float, that's exactly what it does but with more calls to get arg0_type.
| gboolean is_float = type_is_float (fsig->params [0]); | |
| gboolean is_float = arg0_type == MONO_TYPE_R4 || arg0_type == MONO_TYPE_R8; |
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.
Changed.
This PR contributes to #64072
Add intrinsics for Vector64/128 Abs.