From a20847d0f90291d800b1ed28e18d1d645a16012f Mon Sep 17 00:00:00 2001 From: Radek Zikmund <32671551+rzikm@users.noreply.github.com> Date: Mon, 15 Jul 2024 15:13:42 +0200 Subject: [PATCH 01/30] Make ActivityRecorder more threadsafe (#104888) --- .../tests/System/Net/ActivityRecorder.cs | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/ActivityRecorder.cs b/src/libraries/Common/tests/System/Net/ActivityRecorder.cs index 6647076d4bac53..ebeef8b4bc4e38 100644 --- a/src/libraries/Common/tests/System/Net/ActivityRecorder.cs +++ b/src/libraries/Common/tests/System/Net/ActivityRecorder.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Linq; using System.Text; +using System.Threading; using Xunit; namespace System.Net.Test.Common @@ -17,12 +18,16 @@ internal class ActivityRecorder : IDisposable private readonly ActivityListener _listener; private List _finishedActivities = new(); + private int _started; + private int _stopped; + + public int Started => _started; + public int Stopped => _stopped; + public Predicate Filter { get; set; } = _ => true; public bool VerifyParent { get; set; } = true; public Activity ExpectedParent { get; set; } - public int Started { get; private set; } - public int Stopped { get; private set; } public Activity LastStartedActivity { get; private set; } public Activity LastFinishedActivity { get; private set; } public IEnumerable FinishedActivities => _finishedActivities; @@ -35,7 +40,8 @@ public ActivityRecorder(string activitySourceName, string activityName) { ShouldListenTo = (activitySource) => activitySource.Name == _activitySourceName, Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllData, - ActivityStarted = (activity) => { + ActivityStarted = (activity) => + { if (activity.OperationName == _activityName && Filter(activity)) { if (VerifyParent) @@ -43,11 +49,13 @@ public ActivityRecorder(string activitySourceName, string activityName) Assert.Same(ExpectedParent, activity.Parent); } - Started++; + Interlocked.Increment(ref _started); + LastStartedActivity = activity; } }, - ActivityStopped = (activity) => { + ActivityStopped = (activity) => + { if (activity.OperationName == _activityName && Filter(activity)) { if (VerifyParent) @@ -55,14 +63,18 @@ public ActivityRecorder(string activitySourceName, string activityName) Assert.Same(ExpectedParent, activity.Parent); } - Stopped++; - LastFinishedActivity = activity; - _finishedActivities.Add(activity); + Interlocked.Increment(ref _stopped); + + lock (_finishedActivities) + { + LastFinishedActivity = activity; + _finishedActivities.Add(activity); + } } } }; - ActivitySource.AddActivityListener(_listener); + ActivitySource.AddActivityListener(_listener); } public void Dispose() => _listener.Dispose(); From 9d24b13dadf84de72bce61ab50909fed5331cbd5 Mon Sep 17 00:00:00 2001 From: Jeremi Kurdek <59935235+jkurdek@users.noreply.github.com> Date: Mon, 15 Jul 2024 15:40:23 +0200 Subject: [PATCH 02/30] [Mono] [swift-interop] Add support for reverse pinvoke argument lowering (#104437) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add support for reverse pinvoke argument lowering * Fix ILGeneration tests errors * Fix build errors * Reworked structure reassemble algorithm to work on sig * Fix x64 test errors * Add support for SwiftIndirectResult * Remove duplicate call to lowering algorithm * Refactor emitting swift lowered struct * Fix formatting * Remove extra newline * Fix SwiftIndirectResult errors * Address review comments * Fix loop indent * Update src/mono/mono/metadata/marshal-lightweight.c Co-authored-by: Aleksey Kliger (λgeek) * Remove passing MonoImage * Fix formatting around conditional blocks * Fix missing whitespace --------- Co-authored-by: Aleksey Kliger (λgeek) --- src/mono/mono/metadata/marshal-lightweight.c | 65 ++++++++++++++++--- src/mono/mono/metadata/marshal.c | 57 ++++++++++++++-- src/mono/mono/metadata/marshal.h | 22 ++++--- .../SwiftCallbackAbiStress.cs | 57 ++++++++++++++++ src/tests/issues.targets | 3 - 5 files changed, 176 insertions(+), 28 deletions(-) diff --git a/src/mono/mono/metadata/marshal-lightweight.c b/src/mono/mono/metadata/marshal-lightweight.c index 24aaeebc33ba47..9829c95232baef 100644 --- a/src/mono/mono/metadata/marshal-lightweight.c +++ b/src/mono/mono/metadata/marshal-lightweight.c @@ -2715,6 +2715,39 @@ emit_managed_wrapper_validate_signature (MonoMethodSignature* sig, MonoMarshalSp return TRUE; } +static void +emit_swift_lowered_struct_load (MonoMethodBuilder *mb, MonoMethodSignature *csig, SwiftPhysicalLowering swift_lowering, int tmp_local, uint32_t csig_argnum) +{ + guint8 stind_op; + uint32_t offset = 0; + + for (uint32_t idx_lowered = 0; idx_lowered < swift_lowering.num_lowered_elements; idx_lowered++) { + offset = swift_lowering.offsets [idx_lowered]; + mono_mb_emit_ldloc_addr (mb, tmp_local); + mono_mb_emit_icon (mb, offset); + mono_mb_emit_byte (mb, CEE_ADD); + + mono_mb_emit_ldarg (mb, csig_argnum + idx_lowered); + stind_op = mono_type_to_stind (csig->params [csig_argnum + idx_lowered]); + mono_mb_emit_byte (mb, stind_op); + } +} + +/* Swift struct lowering handling causes csig to have additional arguments. + * This function returns the index of the argument in the csig that corresponds to the argument in the original signature. + */ +static int +get_csig_argnum (int i, EmitMarshalContext* m) +{ + if (m->swift_sig_to_csig_mp) { + g_assert (i < m->sig->param_count); + int csig_argnum = m->swift_sig_to_csig_mp [i]; + g_assert (csig_argnum >= 0 && csig_argnum < m->csig->param_count); + return csig_argnum; + } + return i; +} + static void emit_managed_wrapper_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoGCHandle target_handle, gboolean runtime_init_callback, MonoError *error) { @@ -2722,6 +2755,7 @@ emit_managed_wrapper_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *invoke_s int i, *tmp_locals; gboolean closed = FALSE; GCUnsafeTransitionBuilder gc_unsafe_builder = {0,}; + SwiftPhysicalLowering *swift_lowering = m->swift_lowering; sig = m->sig; csig = m->csig; @@ -2798,19 +2832,31 @@ emit_managed_wrapper_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *invoke_s for (i = 0; i < sig->param_count; i ++) { MonoType *t = sig->params [i]; MonoMarshalSpec *spec = mspecs [i + 1]; + int csig_argnum = get_csig_argnum (i, m); if (spec && spec->native == MONO_NATIVE_CUSTOM) { - tmp_locals [i] = mono_emit_marshal (m, i, t, mspecs [i + 1], 0, &csig->params [i], MARSHAL_ACTION_MANAGED_CONV_IN); + tmp_locals [i] = mono_emit_marshal (m, csig_argnum, t, mspecs [i + 1], 0, &csig->params [csig_argnum], MARSHAL_ACTION_MANAGED_CONV_IN); } else { switch (t->type) { + case MONO_TYPE_VALUETYPE: + if (mono_method_signature_has_ext_callconv (csig, MONO_EXT_CALLCONV_SWIFTCALL)) { + if (swift_lowering [i].num_lowered_elements > 0) { + tmp_locals [i] = mono_mb_add_local (mb, sig->params [i]); + emit_swift_lowered_struct_load (mb, csig, swift_lowering [i], tmp_locals [i], csig_argnum); + break; + } else if (swift_lowering [i].by_reference) { + /* Structs passed by reference are handled during arg loading emission */ + tmp_locals [i] = 0; + break; + } + } /* else fallthru */ case MONO_TYPE_OBJECT: case MONO_TYPE_CLASS: - case MONO_TYPE_VALUETYPE: case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: case MONO_TYPE_STRING: case MONO_TYPE_BOOLEAN: - tmp_locals [i] = mono_emit_marshal (m, i, t, mspecs [i + 1], 0, &csig->params [i], MARSHAL_ACTION_MANAGED_CONV_IN); + tmp_locals [i] = mono_emit_marshal (m, csig_argnum, t, mspecs [i + 1], 0, &csig->params [csig_argnum], MARSHAL_ACTION_MANAGED_CONV_IN); break; default: tmp_locals [i] = 0; @@ -2836,15 +2882,18 @@ emit_managed_wrapper_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *invoke_s for (i = 0; i < sig->param_count; i++) { MonoType *t = sig->params [i]; - - if (tmp_locals [i]) { + int csig_argnum = get_csig_argnum (i, m); + if (mono_method_signature_has_ext_callconv (csig, MONO_EXT_CALLCONV_SWIFTCALL) && swift_lowering [i].by_reference) { + mono_mb_emit_ldarg (mb, csig_argnum); + MonoClass* klass = mono_class_from_mono_type_internal (sig->params [i]); + mono_mb_emit_op (mb, CEE_LDOBJ, klass); + } else if (tmp_locals [i]) { if (m_type_is_byref (t)) mono_mb_emit_ldloc_addr (mb, tmp_locals [i]); else mono_mb_emit_ldloc (mb, tmp_locals [i]); - } - else - mono_mb_emit_ldarg (mb, i); + } else + mono_mb_emit_ldarg (mb, csig_argnum); } /* ret = method (...) */ diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 2bf9621294f5c2..bff7eb1d3e3ad4 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -4103,6 +4103,8 @@ marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, Mono int i; EmitMarshalContext m; gboolean marshalling_enabled = FALSE; + int *swift_sig_to_csig_mp = NULL; + SwiftPhysicalLowering *swift_lowering = NULL; g_assert (method != NULL); error_init (error); @@ -4183,6 +4185,50 @@ marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, Mono csig->hasthis = 0; csig->pinvoke = 1; + if (invoke) + mono_marshal_set_callconv_from_modopt (invoke, csig, TRUE); + else + mono_marshal_set_callconv_from_unmanaged_callers_only_attribute (method, csig); + + if (mono_method_signature_has_ext_callconv (csig, MONO_EXT_CALLCONV_SWIFTCALL)) { + MonoClass *swift_self = mono_class_try_get_swift_self_class (); + MonoClass *swift_error = mono_class_try_get_swift_error_class (); + MonoClass *swift_indirect_result = mono_class_try_get_swift_indirect_result_class (); + swift_lowering = g_newa (SwiftPhysicalLowering, sig->param_count); + swift_sig_to_csig_mp = g_newa (int, sig->param_count); + GArray *new_params = g_array_sized_new (FALSE, FALSE, sizeof (MonoType*), csig->param_count); + int new_param_count = 0; + + + for (i = 0; i < csig->param_count; i++) { + swift_lowering [i] = (SwiftPhysicalLowering){0}; + swift_sig_to_csig_mp [i] = new_param_count; + MonoType *ptype = csig->params [i]; + MonoClass *klass = mono_class_from_mono_type_internal (ptype); + + if (mono_type_is_struct (ptype) && !(klass == swift_self || klass == swift_error || klass == swift_indirect_result)) { + SwiftPhysicalLowering lowered_swift_struct = mono_marshal_get_swift_physical_lowering (ptype, FALSE); + swift_lowering [i] = lowered_swift_struct; + if (!lowered_swift_struct.by_reference) { + for (uint32_t idx_lowered = 0; idx_lowered < lowered_swift_struct.num_lowered_elements; idx_lowered++) { + g_array_append_val (new_params, lowered_swift_struct.lowered_elements [idx_lowered]); + new_param_count++; + } + } else { + ptype = mono_class_get_byref_type (klass); + g_array_append_val (new_params, ptype); + new_param_count++; + } + } else { + g_array_append_val (new_params, ptype); + new_param_count++; + } + } + + csig = mono_metadata_signature_dup_new_params (NULL, m_method_get_mem_manager (method), csig, new_param_count, (MonoType**)new_params->data); + g_array_free (new_params, TRUE); + } + if (!marshalling_enabled) csig->marshalling_disabled = 1; @@ -4194,11 +4240,8 @@ marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, Mono m.csig = csig; m.image = get_method_image (method); m.runtime_marshalling_enabled = marshalling_enabled; - - if (invoke) - mono_marshal_set_callconv_from_modopt (invoke, csig, TRUE); - else - mono_marshal_set_callconv_from_unmanaged_callers_only_attribute(method, csig); + m.swift_lowering = swift_lowering; + m.swift_sig_to_csig_mp = swift_sig_to_csig_mp; /* The attribute is only available in Net 2.0 */ if (delegate_klass && mono_class_try_get_unmanaged_function_pointer_attribute_class ()) { @@ -4274,10 +4317,10 @@ marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, Mono info->d.native_to_managed.klass = delegate_klass; res = mono_mb_create_and_cache_full (cache, method, - mb, csig, sig->param_count + 16, + mb, csig, csig->param_count + 16, info, NULL); } else { - res = mono_mb_create (mb, csig, sig->param_count + 16, NULL); + res = mono_mb_create (mb, csig, csig->param_count + 16, NULL); } } diff --git a/src/mono/mono/metadata/marshal.h b/src/mono/mono/metadata/marshal.h index d6ca2bdf0915ce..a682f4dc2b5101 100644 --- a/src/mono/mono/metadata/marshal.h +++ b/src/mono/mono/metadata/marshal.h @@ -37,6 +37,16 @@ typedef const gunichar2 *mono_bstr_const; GENERATE_TRY_GET_CLASS_WITH_CACHE_DECL(stringbuilder) +typedef struct { + gboolean by_reference; + uint32_t num_lowered_elements; + MonoType *lowered_elements[4]; + uint32_t offsets[4]; +} SwiftPhysicalLowering; + +SwiftPhysicalLowering +mono_marshal_get_swift_physical_lowering (MonoType *type, gboolean native_layout); + /* * This structure holds the state kept by the emit_ marshalling functions. @@ -53,6 +63,8 @@ typedef struct { MonoMethodSignature *csig; /* Might need to be changed due to MarshalAs directives */ MonoImage *image; /* The image to use for looking up custom marshallers */ gboolean runtime_marshalling_enabled; + SwiftPhysicalLowering *swift_lowering; + int *swift_sig_to_csig_mp; } EmitMarshalContext; typedef enum { @@ -744,14 +756,4 @@ GENERATE_TRY_GET_CLASS_WITH_CACHE_DECL (swift_self) GENERATE_TRY_GET_CLASS_WITH_CACHE_DECL (swift_error) GENERATE_TRY_GET_CLASS_WITH_CACHE_DECL (swift_indirect_result) -typedef struct { - gboolean by_reference; - uint32_t num_lowered_elements; - MonoType *lowered_elements[4]; - uint32_t offsets[4]; -} SwiftPhysicalLowering; - -SwiftPhysicalLowering -mono_marshal_get_swift_physical_lowering (MonoType *type, gboolean native_layout); - #endif /* __MONO_MARSHAL_H__ */ diff --git a/src/tests/Interop/Swift/SwiftCallbackAbiStress/SwiftCallbackAbiStress.cs b/src/tests/Interop/Swift/SwiftCallbackAbiStress/SwiftCallbackAbiStress.cs index cd00caec4667f4..e94c5c37570c4f 100644 --- a/src/tests/Interop/Swift/SwiftCallbackAbiStress/SwiftCallbackAbiStress.cs +++ b/src/tests/Interop/Swift/SwiftCallbackAbiStress/SwiftCallbackAbiStress.cs @@ -375,6 +375,7 @@ private static F3_Ret SwiftCallbackFunc3Callback(F3_S0 a0, float a1, ushort a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc3() { Console.Write("Running SwiftCallbackFunc3: "); @@ -460,6 +461,7 @@ private static F4_Ret SwiftCallbackFunc4Callback(double a0, F4_S0 a1, byte a2, i } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc4() { Console.Write("Running SwiftCallbackFunc4: "); @@ -588,6 +590,7 @@ private static F5_Ret SwiftCallbackFunc5Callback(byte a0, short a1, ulong a2, nu } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc5() { Console.Write("Running SwiftCallbackFunc5: "); @@ -712,6 +715,7 @@ private static F6_Ret SwiftCallbackFunc6Callback(float a0, F6_S0 a1, long a2, sb } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc6() { Console.Write("Running SwiftCallbackFunc6: "); @@ -866,6 +870,7 @@ private static F8_Ret SwiftCallbackFunc8Callback(F8_S0 a0, F8_S1 a1, SwiftSelf s } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc8() { Console.Write("Running SwiftCallbackFunc8: "); @@ -1061,6 +1066,7 @@ private static F10_Ret SwiftCallbackFunc10Callback(short a0, SwiftSelf self) } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc10() { Console.Write("Running SwiftCallbackFunc10: "); @@ -1169,6 +1175,7 @@ private static F11_Ret SwiftCallbackFunc11Callback(uint a0, nuint a1, ulong a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc11() { Console.Write("Running SwiftCallbackFunc11: "); @@ -1251,6 +1258,7 @@ private static F12_Ret SwiftCallbackFunc12Callback(F12_S0 a0, short a1, ulong a2 } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc12() { Console.Write("Running SwiftCallbackFunc12: "); @@ -1742,6 +1750,7 @@ private static F18_Ret SwiftCallbackFunc18Callback(F18_S0 a0, F18_S1 a1, F18_S2 } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc18() { Console.Write("Running SwiftCallbackFunc18: "); @@ -1855,6 +1864,7 @@ private static F19_Ret SwiftCallbackFunc19Callback(long a0, byte a1, F19_S0 a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc19() { Console.Write("Running SwiftCallbackFunc19: "); @@ -1960,6 +1970,7 @@ private static F20_Ret SwiftCallbackFunc20Callback(F20_S0 a0, F20_S1 a1, float a } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc20() { Console.Write("Running SwiftCallbackFunc20: "); @@ -2034,6 +2045,7 @@ private static F21_Ret SwiftCallbackFunc21Callback(int a0, short a1, F21_S0 a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc21() { Console.Write("Running SwiftCallbackFunc21: "); @@ -2157,6 +2169,7 @@ private static F22_Ret SwiftCallbackFunc22Callback(int a0, F22_S0 a1, F22_S1 a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc22() { Console.Write("Running SwiftCallbackFunc22: "); @@ -2415,6 +2428,7 @@ private static F25_Ret SwiftCallbackFunc25Callback(F25_S0 a0, ushort a1, nuint a } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc25() { Console.Write("Running SwiftCallbackFunc25: "); @@ -2511,6 +2525,7 @@ private static F26_Ret SwiftCallbackFunc26Callback(sbyte a0, byte a1, uint a2, F } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc26() { Console.Write("Running SwiftCallbackFunc26: "); @@ -2701,6 +2716,7 @@ private static F28_Ret SwiftCallbackFunc28Callback(uint a0, ushort a1, sbyte a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc28() { Console.Write("Running SwiftCallbackFunc28: "); @@ -2828,6 +2844,7 @@ private static F29_Ret SwiftCallbackFunc29Callback(F29_S0 a0, nint a1, ulong a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc29() { Console.Write("Running SwiftCallbackFunc29: "); @@ -2981,6 +2998,7 @@ private static F31_Ret SwiftCallbackFunc31Callback(F31_S0 a0, double a1, SwiftSe } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc31() { Console.Write("Running SwiftCallbackFunc31: "); @@ -3034,6 +3052,7 @@ private static F32_Ret SwiftCallbackFunc32Callback(ushort a0, short a1, SwiftSel } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc32() { Console.Write("Running SwiftCallbackFunc32: "); @@ -3413,6 +3432,7 @@ private static F37_Ret SwiftCallbackFunc37Callback(ulong a0, F37_S0 a1, double a } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc37() { Console.Write("Running SwiftCallbackFunc37: "); @@ -3730,6 +3750,7 @@ private static F41_Ret SwiftCallbackFunc41Callback(F41_S0 a0, SwiftSelf self) } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc41() { Console.Write("Running SwiftCallbackFunc41: "); @@ -3848,6 +3869,7 @@ private static F43_Ret SwiftCallbackFunc43Callback(F43_S0 a0, F43_S1 a1, SwiftSe } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc43() { Console.Write("Running SwiftCallbackFunc43: "); @@ -3952,6 +3974,7 @@ private static F44_Ret SwiftCallbackFunc44Callback(double a0, F44_S0 a1, F44_S1 } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc44() { Console.Write("Running SwiftCallbackFunc44: "); @@ -4036,6 +4059,7 @@ private static F45_Ret SwiftCallbackFunc45Callback(F45_S0 a0, F45_S1 a1, byte a2 } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc45() { Console.Write("Running SwiftCallbackFunc45: "); @@ -4095,6 +4119,7 @@ private static F46_Ret SwiftCallbackFunc46Callback(nint a0, nuint a1, ushort a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc46() { Console.Write("Running SwiftCallbackFunc46: "); @@ -4211,6 +4236,7 @@ private static F47_Ret SwiftCallbackFunc47Callback(nint a0, float a1, uint a2, F } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc47() { Console.Write("Running SwiftCallbackFunc47: "); @@ -4354,6 +4380,7 @@ private static F49_Ret SwiftCallbackFunc49Callback(F49_S0 a0, long a1, SwiftSelf } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc49() { Console.Write("Running SwiftCallbackFunc49: "); @@ -4531,6 +4558,7 @@ private static F51_Ret SwiftCallbackFunc51Callback(short a0, nuint a1, F51_S0 a2 } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc51() { Console.Write("Running SwiftCallbackFunc51: "); @@ -4604,6 +4632,7 @@ private static F52_Ret SwiftCallbackFunc52Callback(nint a0, F52_S0 a1, short a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc52() { Console.Write("Running SwiftCallbackFunc52: "); @@ -4763,6 +4792,7 @@ private static F53_Ret SwiftCallbackFunc53Callback(F53_S0 a0, byte a1, long a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc53() { Console.Write("Running SwiftCallbackFunc53: "); @@ -4882,6 +4912,7 @@ private static F54_Ret SwiftCallbackFunc54Callback(ushort a0, F54_S0 a1, float a } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc54() { Console.Write("Running SwiftCallbackFunc54: "); @@ -4980,6 +5011,7 @@ private static F55_Ret SwiftCallbackFunc55Callback(F55_S0 a0, long a1, F55_S1 a2 } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc55() { Console.Write("Running SwiftCallbackFunc55: "); @@ -5114,6 +5146,7 @@ private static F57_Ret SwiftCallbackFunc57Callback(sbyte a0, nuint a1, uint a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc57() { Console.Write("Running SwiftCallbackFunc57: "); @@ -5434,6 +5467,7 @@ private static F62_Ret SwiftCallbackFunc62Callback(F62_S0 a0, SwiftSelf self) } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc62() { Console.Write("Running SwiftCallbackFunc62: "); @@ -5560,6 +5594,7 @@ private static F64_Ret SwiftCallbackFunc64Callback(sbyte a0, F64_S0 a1, F64_S1 a } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc64() { Console.Write("Running SwiftCallbackFunc64: "); @@ -5659,6 +5694,7 @@ private static F65_Ret SwiftCallbackFunc65Callback(F65_S0 a0, short a1, double a } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc65() { Console.Write("Running SwiftCallbackFunc65: "); @@ -5726,6 +5762,7 @@ private static F66_Ret SwiftCallbackFunc66Callback(long a0, SwiftSelf self) } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc66() { Console.Write("Running SwiftCallbackFunc66: "); @@ -5933,6 +5970,7 @@ private static F68_Ret SwiftCallbackFunc68Callback(byte a0, float a1, int a2, ni } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc68() { Console.Write("Running SwiftCallbackFunc68: "); @@ -6032,6 +6070,7 @@ private static F69_Ret SwiftCallbackFunc69Callback(F69_S0 a0, nint a1, int a2, F } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc69() { Console.Write("Running SwiftCallbackFunc69: "); @@ -6148,6 +6187,7 @@ private static F70_Ret SwiftCallbackFunc70Callback(short a0, byte a1, nint a2, u } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc70() { Console.Write("Running SwiftCallbackFunc70: "); @@ -6260,6 +6300,7 @@ private static F72_Ret SwiftCallbackFunc72Callback(F72_S0 a0, long a1, sbyte a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc72() { Console.Write("Running SwiftCallbackFunc72: "); @@ -6511,6 +6552,7 @@ private static F75_Ret SwiftCallbackFunc75Callback(sbyte a0, sbyte a1, sbyte a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc75() { Console.Write("Running SwiftCallbackFunc75: "); @@ -6709,6 +6751,7 @@ private static F77_Ret SwiftCallbackFunc77Callback(double a0, F77_S0 a1, F77_S1 } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc77() { Console.Write("Running SwiftCallbackFunc77: "); @@ -6867,6 +6910,7 @@ private static F79_Ret SwiftCallbackFunc79Callback(F79_S0 a0, float a1, SwiftSel } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc79() { Console.Write("Running SwiftCallbackFunc79: "); @@ -7007,6 +7051,7 @@ private static F81_Ret SwiftCallbackFunc81Callback(byte a0, uint a1, byte a2, F8 } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc81() { Console.Write("Running SwiftCallbackFunc81: "); @@ -7156,6 +7201,7 @@ private static F83_Ret SwiftCallbackFunc83Callback(sbyte a0, F83_S0 a1, short a2 } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc83() { Console.Write("Running SwiftCallbackFunc83: "); @@ -7382,6 +7428,7 @@ private static F85_Ret SwiftCallbackFunc85Callback(F85_S0 a0, F85_S1 a1, uint a2 } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc85() { Console.Write("Running SwiftCallbackFunc85: "); @@ -7486,6 +7533,7 @@ private static F86_Ret SwiftCallbackFunc86Callback(float a0, short a1, nint a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc86() { Console.Write("Running SwiftCallbackFunc86: "); @@ -7634,6 +7682,7 @@ private static F88_Ret SwiftCallbackFunc88Callback(F88_S0 a0, F88_S1 a1, float a } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc88() { Console.Write("Running SwiftCallbackFunc88: "); @@ -7703,6 +7752,7 @@ private static F89_Ret SwiftCallbackFunc89Callback(F89_S0 a0, SwiftSelf self) } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc89() { Console.Write("Running SwiftCallbackFunc89: "); @@ -7811,6 +7861,7 @@ private static F90_Ret SwiftCallbackFunc90Callback(long a0, float a1, F90_S0 a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc90() { Console.Write("Running SwiftCallbackFunc90: "); @@ -7931,6 +7982,7 @@ private static F91_Ret SwiftCallbackFunc91Callback(F91_S0 a0, short a1, uint a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc91() { Console.Write("Running SwiftCallbackFunc91: "); @@ -8024,6 +8076,7 @@ private static F92_Ret SwiftCallbackFunc92Callback(uint a0, long a1, F92_S0 a2, } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc92() { Console.Write("Running SwiftCallbackFunc92: "); @@ -8087,6 +8140,7 @@ private static F93_Ret SwiftCallbackFunc93Callback(nuint a0, ushort a1, double a } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc93() { Console.Write("Running SwiftCallbackFunc93: "); @@ -8196,6 +8250,7 @@ private static F94_Ret SwiftCallbackFunc94Callback(F94_S0 a0, short a1, F94_S1 a } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc94() { Console.Write("Running SwiftCallbackFunc94: "); @@ -8285,6 +8340,7 @@ private static F95_Ret SwiftCallbackFunc95Callback(F95_S0 a0, nuint a1, F95_S1 a } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc95() { Console.Write("Running SwiftCallbackFunc95: "); @@ -8448,6 +8504,7 @@ private static F97_Ret SwiftCallbackFunc97Callback(F97_S0 a0, F97_S1 a1, F97_S2 } [Fact] + [SkipOnMono("Struct lowering for reverse pinvokes returns not supported on Mono")] public static void TestSwiftCallbackFunc97() { Console.Write("Running SwiftCallbackFunc97: "); diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 793ac714bc17b0..1ceab90a73d64d 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -1908,9 +1908,6 @@ https://github.com/dotnet/runtime/issues/98628 - - https://github.com/dotnet/runtime/issues/93631: Swift reverse pinvokes are not implemented on Mono yet - From 99ec785804219bc5b509f95a97133a849ceaa24a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 15 Jul 2024 15:46:58 +0200 Subject: [PATCH 03/30] Speed up native AOT test build (#104880) Same as #82080, but this time we have #104763 Fixes #94102. --- src/tests/Directory.Build.targets | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tests/Directory.Build.targets b/src/tests/Directory.Build.targets index 29668c966d6f35..89db34123535b7 100644 --- a/src/tests/Directory.Build.targets +++ b/src/tests/Directory.Build.targets @@ -541,6 +541,11 @@ + + true + @executable_path/.. From 51306837c5f43cd1a34084d1b42ae9d4f812d82f Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 15 Jul 2024 16:38:09 +0200 Subject: [PATCH 04/30] JIT: Avoid boxing ArgumentNullException.ThrowIfNull arguments in Tier-0 (#104815) Co-authored-by: Jakob Botsch Nielsen --- src/coreclr/jit/compiler.h | 2 + src/coreclr/jit/gentree.h | 8 +- src/coreclr/jit/importercalls.cpp | 109 ++++++++++++++++++ src/coreclr/jit/namedintrinsiclist.h | 2 + .../src/System/ArgumentNullException.cs | 2 + 5 files changed, 122 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index efd73852b1a1c1..2f9abcb00703ad 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -4541,6 +4541,8 @@ class Compiler GenTree* impDuplicateWithProfiledArg(GenTreeCall* call, IL_OFFSET ilOffset); + GenTree* impThrowIfNull(GenTreeCall* call); + #ifdef DEBUG var_types impImportJitTestLabelMark(int numArgs); #endif // DEBUG diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 5b7bc8278cab7e..c2b186e691e89a 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -2265,6 +2265,7 @@ struct GenTree return OperGet() == GT_CALL; } inline bool IsHelperCall(); + inline bool IsHelperCall(Compiler* compiler, unsigned helper); bool gtOverflow() const; bool gtOverflowEx() const; @@ -10500,7 +10501,12 @@ inline bool GenTree::IsCnsVec() const inline bool GenTree::IsHelperCall() { - return OperGet() == GT_CALL && AsCall()->IsHelperCall(); + return IsCall() && AsCall()->IsHelperCall(); +} + +inline bool GenTree::IsHelperCall(Compiler* compiler, unsigned helper) +{ + return IsCall() && AsCall()->IsHelperCall(compiler, helper); } inline var_types GenTree::CastFromType() diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index dc205c60c2fd0c..0d2045d553c826 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -1330,6 +1330,10 @@ var_types Compiler::impImportCall(OPCODE opcode, } else { + if (call->IsCall() && call->AsCall()->IsSpecialIntrinsic(this, NI_System_ArgumentNullException_ThrowIfNull)) + { + call = impThrowIfNull(call->AsCall()); + } impAppendTree(call, CHECK_SPILL_ALL, impCurStmtDI); } } @@ -1528,6 +1532,97 @@ var_types Compiler::impImportCall(OPCODE opcode, #pragma warning(pop) #endif +//------------------------------------------------------------------------ +// impThrowIfNull: Remove redundandant boxing from ArgumentNullException_ThrowIfNull +// it is done for Tier0 where we can't remove it without inlining otherwise. +// +// Arguments: +// call -- call representing ArgumentNullException_ThrowIfNull +// +// Return Value: +// Optimized tree (or the original call tree if we can't optimize it). +// +GenTree* Compiler::impThrowIfNull(GenTreeCall* call) +{ + // We have two overloads: + // + // void ThrowIfNull(object argument, string paramName = null) + // void ThrowIfNull(object argument, ExceptionArgument paramName) + // + assert(call->IsSpecialIntrinsic(this, NI_System_ArgumentNullException_ThrowIfNull)); + assert(call->gtArgs.CountUserArgs() == 2); + assert(call->TypeIs(TYP_VOID)); + + if (opts.compDbgCode || opts.jitFlags->IsSet(JitFlags::JIT_FLAG_MIN_OPT)) + { + // Don't fold it for debug code or forced MinOpts + return call; + } + + GenTree* value = call->gtArgs.GetUserArgByIndex(0)->GetNode(); + GenTree* valueName = call->gtArgs.GetUserArgByIndex(1)->GetNode(); + + // Case 1: value-type (non-nullable): + // + // ArgumentNullException_ThrowIfNull(GT_BOX(value), valueName) + // -> + // NOP (with side-effects if any) + // + if (value->OperIs(GT_BOX)) + { + // Now we need to spill the addr and argName arguments in the correct order + // to preserve possible side effects. + unsigned boxedValTmp = lvaGrabTemp(true DEBUGARG("boxedVal spilled")); + unsigned boxedArgNameTmp = lvaGrabTemp(true DEBUGARG("boxedArg spilled")); + impStoreToTemp(boxedValTmp, value, CHECK_SPILL_ALL); + impStoreToTemp(boxedArgNameTmp, valueName, CHECK_SPILL_ALL); + gtTryRemoveBoxUpstreamEffects(value, BR_REMOVE_AND_NARROW); + return gtNewNothingNode(); + } + + // Case 2: nullable: + // + // ArgumentNullException.ThrowIfNull(CORINFO_HELP_BOX_NULLABLE(classHandle, addr), valueName); + // -> + // addr->hasValue != 0 ? NOP : ArgumentNullException.ThrowIfNull(null, valueNameTmp) + // + if (opts.OptimizationEnabled() || !value->IsHelperCall(this, CORINFO_HELP_BOX_NULLABLE)) + { + // We're not boxing - bail out. + // NOTE: when opts are enabled, we remove the box as is (with better CQ) + return call; + } + + GenTree* boxHelperClsArg = value->AsCall()->gtArgs.GetUserArgByIndex(0)->GetNode(); + GenTree* boxHelperAddrArg = value->AsCall()->gtArgs.GetUserArgByIndex(1)->GetNode(); + + if ((boxHelperClsArg->gtFlags & GTF_SIDE_EFFECT) != 0) + { + // boxHelperClsArg is always just a class handle constant, so we don't bother spilling it. + return call; + } + + // Now we need to spill the addr and argName arguments in the correct order + // to preserve possible side effects. + unsigned boxedValTmp = lvaGrabTemp(true DEBUGARG("boxedVal spilled")); + unsigned boxedArgNameTmp = lvaGrabTemp(true DEBUGARG("boxedArg spilled")); + impStoreToTemp(boxedValTmp, boxHelperAddrArg, CHECK_SPILL_ALL); + impStoreToTemp(boxedArgNameTmp, valueName, CHECK_SPILL_ALL); + + // Change arguments to 'ThrowIfNull(null, valueNameTmp)' + call->gtArgs.GetUserArgByIndex(0)->SetEarlyNode(gtNewNull()); + call->gtArgs.GetUserArgByIndex(1)->SetEarlyNode(gtNewLclvNode(boxedArgNameTmp, valueName->TypeGet())); + + // This is Tier0 specific, so we create a raw indir node to access Nullable.hasValue field + // which is the first field of Nullable struct and is of type 'bool'. + // + static_assert_no_msg(OFFSETOF__CORINFO_NullableOfT__hasValue == 0); + GenTree* hasValueField = gtNewIndir(TYP_UBYTE, gtNewLclvNode(boxedValTmp, boxHelperAddrArg->TypeGet())); + GenTreeOp* cond = gtNewOperNode(GT_NE, TYP_INT, hasValueField, gtNewIconNode(0)); + + return gtNewQmarkNode(TYP_VOID, cond, gtNewColonNode(TYP_VOID, gtNewNothingNode(), call)); +} + //------------------------------------------------------------------------ // impDuplicateWithProfiledArg: duplicates a call with a profiled argument, e.g.: // Given `Buffer.Memmove(dst, src, len)` call, @@ -3257,6 +3352,9 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd, // to avoid some unnecessary boxing case NI_System_Enum_HasFlag: + // This one is made intrinsic specifically to avoid boxing in Tier0 + case NI_System_ArgumentNullException_ThrowIfNull: + // Most atomics are compiled to single instructions case NI_System_Threading_Interlocked_And: case NI_System_Threading_Interlocked_Or: @@ -3787,6 +3885,10 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd, break; } + case NI_System_ArgumentNullException_ThrowIfNull: + isSpecial = true; + break; + case NI_System_Enum_HasFlag: { GenTree* thisOp = impStackTop(1).val; @@ -9826,6 +9928,13 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) result = NI_System_Activator_DefaultConstructorOf; } } + else if (strcmp(className, "ArgumentNullException") == 0) + { + if (strcmp(methodName, "ThrowIfNull") == 0) + { + result = NI_System_ArgumentNullException_ThrowIfNull; + } + } else if (strcmp(className, "Array") == 0) { if (strcmp(methodName, "Clone") == 0) diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h index 0ec8fd2496ba38..93e4ce7893f98b 100644 --- a/src/coreclr/jit/namedintrinsiclist.h +++ b/src/coreclr/jit/namedintrinsiclist.h @@ -13,6 +13,8 @@ enum NamedIntrinsic : unsigned short { NI_Illegal = 0, + NI_System_ArgumentNullException_ThrowIfNull, + NI_System_Enum_HasFlag, NI_System_BitConverter_DoubleToInt64Bits, diff --git a/src/libraries/System.Private.CoreLib/src/System/ArgumentNullException.cs b/src/libraries/System.Private.CoreLib/src/System/ArgumentNullException.cs index b563c12dfa3567..8094b882ef5486 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ArgumentNullException.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ArgumentNullException.cs @@ -51,6 +51,7 @@ protected ArgumentNullException(SerializationInfo info, StreamingContext context /// Throws an if is null. /// The reference type argument to validate as non-null. /// The name of the parameter with which corresponds. + [Intrinsic] // Tier0 intrinsic to avoid redundant boxing in generics public static void ThrowIfNull([NotNull] object? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null) { if (argument is null) @@ -59,6 +60,7 @@ public static void ThrowIfNull([NotNull] object? argument, [CallerArgumentExpres } } + [Intrinsic] // Tier0 intrinsic to avoid redundant boxing in generics internal static void ThrowIfNull([NotNull] object? argument, ExceptionArgument paramName) { if (argument is null) From 9bc738db42602629daba6463a9eb80bf5370854d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Mon, 15 Jul 2024 16:38:51 +0200 Subject: [PATCH 05/30] Don't use SyncTextWriter on WASI either (#104798) Follow-up to https://github.com/dotnet/runtime/pull/101221 so we match behavior between single-threaded Browser and WASI. --- src/libraries/System.Console/tests/ReadAndWrite.cs | 6 ++++-- src/libraries/System.Console/tests/SyncTextWriter.cs | 2 +- .../src/System.Private.CoreLib.Shared.projitems | 2 -- .../System.Private.CoreLib/src/System/IO/TextWriter.cs | 2 +- .../tests/System.IO.Tests/StreamReader/StreamReader.cs | 2 +- .../tests/System.IO.Tests/StreamWriter/StreamWriter.cs | 2 +- .../tests/System.IO.Tests/TextWriter/TextWriterTests.cs | 2 +- .../System.Private.CoreLib/System.Private.CoreLib.csproj | 2 -- 8 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/libraries/System.Console/tests/ReadAndWrite.cs b/src/libraries/System.Console/tests/ReadAndWrite.cs index 913d85835dbb18..3e165d38263926 100644 --- a/src/libraries/System.Console/tests/ReadAndWrite.cs +++ b/src/libraries/System.Console/tests/ReadAndWrite.cs @@ -158,9 +158,11 @@ public static async Task OutWriteAndWriteLineOverloads() Console.SetOut(sw); TextWriter writer = Console.Out; Assert.NotNull(writer); - // Browser bypasses SyncTextWriter for faster startup - if (!OperatingSystem.IsBrowser()) + // single-threaded WASM bypasses SyncTextWriter for faster startup + if (PlatformDetection.IsThreadingSupported) Assert.NotEqual(writer, sw); // the writer we provide gets wrapped + else + Assert.Equal(writer, sw); // the writer we provide does not get wrapped // We just want to ensure none of these throw exceptions, we don't actually validate // what was written. diff --git a/src/libraries/System.Console/tests/SyncTextWriter.cs b/src/libraries/System.Console/tests/SyncTextWriter.cs index 772e1e2b44a915..bcd0b12ddb426d 100644 --- a/src/libraries/System.Console/tests/SyncTextWriter.cs +++ b/src/libraries/System.Console/tests/SyncTextWriter.cs @@ -12,7 +12,7 @@ public class SyncTextWriter { - // Browser bypasses SyncTextWriter for faster startup + // single-threaded WASM bypasses SyncTextWriter for faster startup [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public void SyncTextWriterLockedOnThis() { diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 406f3caecba30e..9045c03a920b96 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -22,8 +22,6 @@ true true true - true - $(DefineConstants);FEATURE_WASM_MANAGED_THREADS $(DefineConstants);BIGENDIAN diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs b/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs index d949017809f825..c328f858f1edca 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs @@ -759,7 +759,7 @@ public static TextWriter Synchronized(TextWriter writer) { ArgumentNullException.ThrowIfNull(writer); -#if !TARGET_BROWSER || FEATURE_WASM_MANAGED_THREADS +#if (!TARGET_BROWSER && !TARGET_WASI) || FEATURE_WASM_MANAGED_THREADS return writer is SyncTextWriter ? writer : new SyncTextWriter(writer); #else return writer; diff --git a/src/libraries/System.Runtime/tests/System.IO.Tests/StreamReader/StreamReader.cs b/src/libraries/System.Runtime/tests/System.IO.Tests/StreamReader/StreamReader.cs index 29677f512d9f73..efdf66257c31c7 100644 --- a/src/libraries/System.Runtime/tests/System.IO.Tests/StreamReader/StreamReader.cs +++ b/src/libraries/System.Runtime/tests/System.IO.Tests/StreamReader/StreamReader.cs @@ -29,7 +29,7 @@ public void ObjectClosedReadLineBaseStream() Assert.Throws(() => sr.ReadLine()); } - // Browser bypasses SyncTextWriter for faster startup + // single-threaded WASM bypasses SyncTextWriter for faster startup [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public void Synchronized_NewObject() { diff --git a/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.cs b/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.cs index cc09f1c0d2032c..0abbc4d6add34d 100644 --- a/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.cs +++ b/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.cs @@ -7,7 +7,7 @@ namespace System.IO.Tests { public partial class WriteTests { - // Browser bypasses SyncTextWriter for faster startup + // single-threaded WASM bypasses SyncTextWriter for faster startup [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public void Synchronized_NewObject() { diff --git a/src/libraries/System.Runtime/tests/System.IO.Tests/TextWriter/TextWriterTests.cs b/src/libraries/System.Runtime/tests/System.IO.Tests/TextWriter/TextWriterTests.cs index 47541635c8eef6..08dc045e4a5b5b 100644 --- a/src/libraries/System.Runtime/tests/System.IO.Tests/TextWriter/TextWriterTests.cs +++ b/src/libraries/System.Runtime/tests/System.IO.Tests/TextWriter/TextWriterTests.cs @@ -690,7 +690,7 @@ public void DisposeAsync_ExceptionReturnedInTask() Assert.Same(e, vt.AsTask().Exception.InnerException); } - // Browser bypasses SyncTextWriter for faster startup + // single-threaded WASM bypasses SyncTextWriter for faster startup [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task FlushAsync_Precanceled() { diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index 9137c694aa4ab8..ed02811e9b39a2 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -13,8 +13,6 @@ x64;x86;arm;armv6;arm64;riscv64;s390x;wasm;ppc64le true - true - $(DefineConstants);FEATURE_WASM_MANAGED_THREADS From 72026ca448d2c5a4cbc5b028fa27e9f66e289bbc Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 16:44:19 +0200 Subject: [PATCH 06/30] [main] Update dependencies from dotnet/arcade (#104730) * Update dependencies from https://github.com/dotnet/arcade build 20240710.4 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XliffTasks , Microsoft.DotNet.XUnitAssert , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.24360.1 -> To Version 9.0.0-beta.24360.4 * Update dependencies from https://github.com/dotnet/arcade build 20240710.4 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XliffTasks , Microsoft.DotNet.XUnitAssert , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.24360.1 -> To Version 9.0.0-beta.24360.4 * Update dependencies from https://github.com/dotnet/arcade build 20240710.4 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XliffTasks , Microsoft.DotNet.XUnitAssert , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.24360.1 -> To Version 9.0.0-beta.24360.4 * Update dependencies from https://github.com/dotnet/arcade build 20240710.4 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XliffTasks , Microsoft.DotNet.XUnitAssert , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.24360.1 -> To Version 9.0.0-beta.24360.4 * Update dependencies from https://github.com/dotnet/arcade build 20240710.4 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XliffTasks , Microsoft.DotNet.XUnitAssert , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.24360.1 -> To Version 9.0.0-beta.24360.4 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 84 ++++++++++++++++---------------- eng/Versions.props | 32 ++++++------ eng/common/cross/build-rootfs.sh | 2 +- global.json | 6 +-- 4 files changed, 62 insertions(+), 62 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4a3c73c10190f2..32b119ad8b537e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -92,87 +92,87 @@ - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b https://github.com/dotnet/runtime-assets @@ -332,9 +332,9 @@ https://github.com/dotnet/xharness 65d0584b517952962b7a79195b5d7606b52fcbfe - + https://github.com/dotnet/arcade - f20056daa31b4a08f2ce379cfe4610042c3bc26c + 731d793be2d0a66bafc96b1a79dc96b4d1f0301b https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index 75599d7c272da7..8b19e3de2d1290 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -83,22 +83,22 @@ 9.0.100-preview.7.24358.3 - 9.0.0-beta.24360.1 - 9.0.0-beta.24360.1 - 9.0.0-beta.24360.1 - 9.0.0-beta.24360.1 - 2.8.1-beta.24360.1 - 9.0.0-beta.24360.1 - 2.8.1-beta.24360.1 - 9.0.0-beta.24360.1 - 9.0.0-beta.24360.1 - 9.0.0-beta.24360.1 - 9.0.0-beta.24360.1 - 9.0.0-beta.24360.1 - 9.0.0-beta.24360.1 - 9.0.0-beta.24360.1 - 9.0.0-beta.24360.1 - 9.0.0-beta.24360.1 + 9.0.0-beta.24360.4 + 9.0.0-beta.24360.4 + 9.0.0-beta.24360.4 + 9.0.0-beta.24360.4 + 2.8.1-beta.24360.4 + 9.0.0-beta.24360.4 + 2.8.1-beta.24360.4 + 9.0.0-beta.24360.4 + 9.0.0-beta.24360.4 + 9.0.0-beta.24360.4 + 9.0.0-beta.24360.4 + 9.0.0-beta.24360.4 + 9.0.0-beta.24360.4 + 9.0.0-beta.24360.4 + 9.0.0-beta.24360.4 + 9.0.0-beta.24360.4 1.4.0 diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh index eb1a908046483f..6d99d1263c0be6 100755 --- a/eng/common/cross/build-rootfs.sh +++ b/eng/common/cross/build-rootfs.sh @@ -72,7 +72,7 @@ __AlpinePackages+=" krb5-dev" __AlpinePackages+=" openssl-dev" __AlpinePackages+=" zlib-dev" -__FreeBSDBase="13.2-RELEASE" +__FreeBSDBase="13.3-RELEASE" __FreeBSDPkg="1.17.0" __FreeBSDABI="13" __FreeBSDPackages="libunwind" diff --git a/global.json b/global.json index 0fad9fb50a2a2f..1ce506fa636f8a 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "9.0.100-preview.5.24307.3" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24360.1", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24360.1", - "Microsoft.DotNet.SharedFramework.Sdk": "9.0.0-beta.24360.1", + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24360.4", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24360.4", + "Microsoft.DotNet.SharedFramework.Sdk": "9.0.0-beta.24360.4", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "9.0.0-preview.7.24357.2" From 9600a8c7b2ac760beb0e973d12df419baee7a13d Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 15 Jul 2024 17:38:36 +0200 Subject: [PATCH 07/30] Update PackageOverrides.txt (#104638) * Update PackageOverrides.txt Update PackageOverrides.txt which ships inside the Microsoft.NETCore.App.Ref targeting pack with the latest state for .NET 9. This improves build perf as assembly version checks are avoided for the packages listed with a version lower or equal. * Update packages which will ship again Update packages that aren't produced from runtime/main anymore but from other branches or from the maintenance-packages repository. --- .../PackageOverrides.txt | 206 ++++++++++-------- 1 file changed, 117 insertions(+), 89 deletions(-) diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/PackageOverrides.txt b/src/installer/pkg/sfx/Microsoft.NETCore.App/PackageOverrides.txt index c4c594f90f86d7..6fff123a00f419 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/PackageOverrides.txt +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/PackageOverrides.txt @@ -1,83 +1,86 @@ -Microsoft.CSharp|4.4.0 +Microsoft.CSharp|4.7.0 +Microsoft.VisualBasic|10.4.0 Microsoft.Win32.Primitives|4.3.0 -Microsoft.Win32.Registry|4.4.0 -runtime.debian.8-x64.runtime.native.System|4.3.0 -runtime.debian.8-x64.runtime.native.System.IO.Compression|4.3.0 -runtime.debian.8-x64.runtime.native.System.Net.Http|4.3.0 -runtime.debian.8-x64.runtime.native.System.Net.Security|4.3.0 -runtime.debian.8-x64.runtime.native.System.Security.Cryptography|4.3.0 -runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.0 -runtime.fedora.23-x64.runtime.native.System|4.3.0 -runtime.fedora.23-x64.runtime.native.System.IO.Compression|4.3.0 -runtime.fedora.23-x64.runtime.native.System.Net.Http|4.3.0 -runtime.fedora.23-x64.runtime.native.System.Net.Security|4.3.0 -runtime.fedora.23-x64.runtime.native.System.Security.Cryptography|4.3.0 -runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.0 -runtime.fedora.24-x64.runtime.native.System|4.3.0 -runtime.fedora.24-x64.runtime.native.System.IO.Compression|4.3.0 -runtime.fedora.24-x64.runtime.native.System.Net.Http|4.3.0 -runtime.fedora.24-x64.runtime.native.System.Net.Security|4.3.0 -runtime.fedora.24-x64.runtime.native.System.Security.Cryptography|4.3.0 -runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.0 -runtime.opensuse.13.2-x64.runtime.native.System|4.3.0 -runtime.opensuse.13.2-x64.runtime.native.System.IO.Compression|4.3.0 -runtime.opensuse.13.2-x64.runtime.native.System.Net.Http|4.3.0 -runtime.opensuse.13.2-x64.runtime.native.System.Net.Security|4.3.0 -runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography|4.3.0 -runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.0 -runtime.opensuse.42.1-x64.runtime.native.System|4.3.0 -runtime.opensuse.42.1-x64.runtime.native.System.IO.Compression|4.3.0 -runtime.opensuse.42.1-x64.runtime.native.System.Net.Http|4.3.0 -runtime.opensuse.42.1-x64.runtime.native.System.Net.Security|4.3.0 -runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography|4.3.0 -runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.0 -runtime.osx.10.10-x64.runtime.native.System|4.3.0 -runtime.osx.10.10-x64.runtime.native.System.IO.Compression|4.3.0 -runtime.osx.10.10-x64.runtime.native.System.Net.Http|4.3.0 -runtime.osx.10.10-x64.runtime.native.System.Net.Security|4.3.0 -runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography|4.3.0 -runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple|4.3.0 -runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.0 -runtime.rhel.7-x64.runtime.native.System|4.3.0 -runtime.rhel.7-x64.runtime.native.System.IO.Compression|4.3.0 -runtime.rhel.7-x64.runtime.native.System.Net.Http|4.3.0 -runtime.rhel.7-x64.runtime.native.System.Net.Security|4.3.0 -runtime.rhel.7-x64.runtime.native.System.Security.Cryptography|4.3.0 -runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.0 -runtime.ubuntu.14.04-x64.runtime.native.System|4.3.0 -runtime.ubuntu.14.04-x64.runtime.native.System.IO.Compression|4.3.0 -runtime.ubuntu.14.04-x64.runtime.native.System.Net.Http|4.3.0 -runtime.ubuntu.14.04-x64.runtime.native.System.Net.Security|4.3.0 -runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography|4.3.0 -runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.0 -runtime.ubuntu.16.04-x64.runtime.native.System|4.3.0 -runtime.ubuntu.16.04-x64.runtime.native.System.IO.Compression|4.3.0 -runtime.ubuntu.16.04-x64.runtime.native.System.Net.Http|4.3.0 -runtime.ubuntu.16.04-x64.runtime.native.System.Net.Security|4.3.0 -runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography|4.3.0 -runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.0 -runtime.ubuntu.16.10-x64.runtime.native.System|4.3.0 -runtime.ubuntu.16.10-x64.runtime.native.System.IO.Compression|4.3.0 -runtime.ubuntu.16.10-x64.runtime.native.System.Net.Http|4.3.0 -runtime.ubuntu.16.10-x64.runtime.native.System.Net.Security|4.3.0 -runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography|4.3.0 -runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.0 +Microsoft.Win32.Registry|5.0.0 +runtime.debian.8-x64.runtime.native.System|4.3.1 +runtime.debian.8-x64.runtime.native.System.IO.Compression|4.3.2 +runtime.debian.8-x64.runtime.native.System.Net.Http|4.3.1 +runtime.debian.8-x64.runtime.native.System.Net.Security|4.3.1 +runtime.debian.8-x64.runtime.native.System.Security.Cryptography|4.3.4 +runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.3 +runtime.fedora.23-x64.runtime.native.System|4.3.1 +runtime.fedora.23-x64.runtime.native.System.IO.Compression|4.3.2 +runtime.fedora.23-x64.runtime.native.System.Net.Http|4.3.1 +runtime.fedora.23-x64.runtime.native.System.Net.Security|4.3.1 +runtime.fedora.23-x64.runtime.native.System.Security.Cryptography|4.3.4 +runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.3 +runtime.fedora.24-x64.runtime.native.System|4.3.1 +runtime.fedora.24-x64.runtime.native.System.IO.Compression|4.3.2 +runtime.fedora.24-x64.runtime.native.System.Net.Http|4.3.1 +runtime.fedora.24-x64.runtime.native.System.Net.Security|4.3.1 +runtime.fedora.24-x64.runtime.native.System.Security.Cryptography|4.3.4 +runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.3 +runtime.opensuse.13.2-x64.runtime.native.System|4.3.1 +runtime.opensuse.13.2-x64.runtime.native.System.IO.Compression|4.3.2 +runtime.opensuse.13.2-x64.runtime.native.System.Net.Http|4.3.1 +runtime.opensuse.13.2-x64.runtime.native.System.Net.Security|4.3.1 +runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography|4.3.4 +runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.3 +runtime.opensuse.42.1-x64.runtime.native.System|4.3.1 +runtime.opensuse.42.1-x64.runtime.native.System.IO.Compression|4.3.2 +runtime.opensuse.42.1-x64.runtime.native.System.Net.Http|4.3.1 +runtime.opensuse.42.1-x64.runtime.native.System.Net.Security|4.3.1 +runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography|4.3.4 +runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.3 +runtime.osx.10.10-x64.runtime.native.System|4.3.1 +runtime.osx.10.10-x64.runtime.native.System.IO.Compression|4.3.2 +runtime.osx.10.10-x64.runtime.native.System.Net.Http|4.3.1 +runtime.osx.10.10-x64.runtime.native.System.Net.Security|4.3.1 +runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography|4.3.4 +runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple|4.3.1 +runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.3 +runtime.rhel.7-x64.runtime.native.System|4.3.1 +runtime.rhel.7-x64.runtime.native.System.IO.Compression|4.3.2 +runtime.rhel.7-x64.runtime.native.System.Net.Http|4.3.1 +runtime.rhel.7-x64.runtime.native.System.Net.Security|4.3.1 +runtime.rhel.7-x64.runtime.native.System.Security.Cryptography|4.3.4 +runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.3 +runtime.ubuntu.14.04-x64.runtime.native.System|4.3.1 +runtime.ubuntu.14.04-x64.runtime.native.System.IO.Compression|4.3.2 +runtime.ubuntu.14.04-x64.runtime.native.System.Net.Http|4.3.1 +runtime.ubuntu.14.04-x64.runtime.native.System.Net.Security|4.3.1 +runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography|4.3.4 +runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.3 +runtime.ubuntu.16.04-x64.runtime.native.System|4.3.1 +runtime.ubuntu.16.04-x64.runtime.native.System.IO.Compression|4.3.2 +runtime.ubuntu.16.04-x64.runtime.native.System.Net.Http|4.3.1 +runtime.ubuntu.16.04-x64.runtime.native.System.Net.Security|4.3.1 +runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography|4.3.4 +runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.3 +runtime.ubuntu.16.10-x64.runtime.native.System|4.3.1 +runtime.ubuntu.16.10-x64.runtime.native.System.IO.Compression|4.3.2 +runtime.ubuntu.16.10-x64.runtime.native.System.Net.Http|4.3.1 +runtime.ubuntu.16.10-x64.runtime.native.System.Net.Security|4.3.1 +runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography|4.3.4 +runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl|4.3.3 System.AppContext|4.3.0 -System.Buffers|4.4.0 +System.Buffers|5.0.0 System.Collections|4.3.0 System.Collections.Concurrent|4.3.0 -System.Collections.Immutable|1.4.0 +System.Collections.Immutable|9.0.0 System.Collections.NonGeneric|4.3.0 System.Collections.Specialized|4.3.0 System.ComponentModel|4.3.0 +System.ComponentModel.Annotations|4.3.0 System.ComponentModel.EventBasedAsync|4.3.0 System.ComponentModel.Primitives|4.3.0 System.ComponentModel.TypeConverter|4.3.0 -System.Console|4.3.0 +System.Console|4.3.1 System.Data.Common|4.3.0 +System.Data.DataSetExtensions|4.4.0 System.Diagnostics.Contracts|4.3.0 System.Diagnostics.Debug|4.3.0 -System.Diagnostics.DiagnosticSource|4.4.0 +System.Diagnostics.DiagnosticSource|9.0.0 System.Diagnostics.FileVersionInfo|4.3.0 System.Diagnostics.Process|4.3.0 System.Diagnostics.StackTrace|4.3.0 @@ -85,7 +88,10 @@ System.Diagnostics.TextWriterTraceListener|4.3.0 System.Diagnostics.Tools|4.3.0 System.Diagnostics.TraceSource|4.3.0 System.Diagnostics.Tracing|4.3.0 +System.Drawing.Primitives|4.3.0 System.Dynamic.Runtime|4.3.0 +System.Formats.Asn1|9.0.0 +System.Formats.Tar|9.0.0 System.Globalization|4.3.0 System.Globalization.Calendars|4.3.0 System.Globalization.Extensions|4.3.0 @@ -94,36 +100,52 @@ System.IO.Compression|4.3.0 System.IO.Compression.ZipFile|4.3.0 System.IO.FileSystem|4.3.0 System.IO.FileSystem.AccessControl|4.4.0 -System.IO.FileSystem.DriveInfo|4.3.0 +System.IO.FileSystem.DriveInfo|4.3.1 System.IO.FileSystem.Primitives|4.3.0 System.IO.FileSystem.Watcher|4.3.0 System.IO.IsolatedStorage|4.3.0 System.IO.MemoryMappedFiles|4.3.0 System.IO.Pipes|4.3.0 +System.IO.Pipes.AccessControl|5.0.0 +System.IO.Pipelines|9.0.0 System.IO.UnmanagedMemoryStream|4.3.0 System.Linq|4.3.0 System.Linq.Expressions|4.3.0 +System.Linq.Parallel|4.3.0 System.Linq.Queryable|4.3.0 -System.Net.Http|4.3.0 +System.Memory|5.0.0 +System.Net.Http|4.3.4 +System.Net.Http.Json|9.0.0 System.Net.NameResolution|4.3.0 -System.Net.Primitives|4.3.0 +System.Net.NetworkInformation|4.3.0 +System.Net.Ping|4.3.0 +System.Net.Primitives|4.3.1 System.Net.Requests|4.3.0 -System.Net.Security|4.3.0 +System.Net.Security|4.3.2 System.Net.Sockets|4.3.0 System.Net.WebHeaderCollection|4.3.0 +System.Net.WebSockets|4.3.0 +System.Net.WebSockets.Client|4.3.2 +System.Numerics.Vectors|5.0.0 System.ObjectModel|4.3.0 System.Private.DataContractSerialization|4.3.0 +System.Private.Uri|4.3.2 System.Reflection|4.3.0 -System.Reflection.Emit|4.3.0 -System.Reflection.Emit.ILGeneration|4.3.0 -System.Reflection.Emit.Lightweight|4.3.0 +System.Reflection.DispatchProxy|6.0.0 +System.Reflection.Emit|4.7.0 +System.Reflection.Emit.ILGeneration|4.7.0 +System.Reflection.Emit.Lightweight|4.7.0 System.Reflection.Extensions|4.3.0 -System.Reflection.Metadata|1.5.0 +System.Reflection.Metadata|9.0.0 System.Reflection.Primitives|4.3.0 System.Reflection.TypeExtensions|4.3.0 +System.Resources.Reader|4.3.0 System.Resources.ResourceManager|4.3.0 -System.Runtime|4.3.0 -System.Runtime.Extensions|4.3.0 +System.Resources.Writer|4.3.0 +System.Runtime|4.3.1 +System.Runtime.CompilerServices.Unsafe|7.0.0 +System.Runtime.CompilerServices.VisualC|4.3.0 +System.Runtime.Extensions|4.3.1 System.Runtime.Handles|4.3.0 System.Runtime.InteropServices|4.3.0 System.Runtime.InteropServices.RuntimeInformation|4.3.0 @@ -132,33 +154,39 @@ System.Runtime.Numerics|4.3.0 System.Runtime.Serialization.Formatters|4.3.0 System.Runtime.Serialization.Json|4.3.0 System.Runtime.Serialization.Primitives|4.3.0 -System.Security.AccessControl|4.4.0 +System.Runtime.Serialization.Xml|4.3.0 +System.Security.AccessControl|6.0.1 System.Security.Claims|4.3.0 -System.Security.Cryptography.Algorithms|4.3.0 -System.Security.Cryptography.Cng|4.4.0 +System.Security.Cryptography.Algorithms|4.3.1 +System.Security.Cryptography.Cng|5.0.0 System.Security.Cryptography.Csp|4.3.0 System.Security.Cryptography.Encoding|4.3.0 -System.Security.Cryptography.OpenSsl|4.4.0 +System.Security.Cryptography.OpenSsl|5.0.0 System.Security.Cryptography.Primitives|4.3.0 -System.Security.Cryptography.X509Certificates|4.3.0 -System.Security.Cryptography.Xml|4.4.0 +System.Security.Cryptography.X509Certificates|4.3.2 System.Security.Principal|4.3.0 -System.Security.Principal.Windows|4.4.0 +System.Security.Principal.Windows|5.0.0 +System.Security.SecureString|4.3.0 System.Text.Encoding|4.3.0 +System.Text.Encoding.CodePages|9.0.0 System.Text.Encoding.Extensions|4.3.0 -System.Text.RegularExpressions|4.3.0 +System.Text.Encodings.Web|9.0.0 +System.Text.Json|9.0.0 +System.Text.RegularExpressions|4.3.1 System.Threading|4.3.0 +System.Threading.Channels|9.0.0 System.Threading.Overlapped|4.3.0 System.Threading.Tasks|4.3.0 -System.Threading.Tasks.Extensions|4.3.0 +System.Threading.Tasks.Dataflow|9.0.0 +System.Threading.Tasks.Extensions|5.0.0 System.Threading.Tasks.Parallel|4.3.0 System.Threading.Thread|4.3.0 System.Threading.ThreadPool|4.3.0 System.Threading.Timer|4.3.0 -System.ValueTuple|4.3.0 -System.Xml.ReaderWriter|4.3.0 +System.ValueTuple|4.5.0 +System.Xml.ReaderWriter|4.3.1 System.Xml.XDocument|4.3.0 System.Xml.XmlDocument|4.3.0 System.Xml.XmlSerializer|4.3.0 System.Xml.XPath|4.3.0 -System.Xml.XPath.XDocument|4.3.0 +System.Xml.XPath.XDocument|5.0.0 From ad25cd0126a8d4a060f2039f987bd58e7ca56a1d Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 15 Jul 2024 09:17:02 -0700 Subject: [PATCH 08/30] ILLink: Fix order dependent logic for DAM on types (#104701) When applying DynamicallyAccessedMembers annotations to a type, we need to ensure that the base annotations are also applied to the base type. Previously this logic was determining which annotations to apply to the base type (with the warning originating from the derived type) based on whether the base annotations were already applied. This is incorrect as it introduces an order dependence. Instead the base annotations should use the base type as the origin. --- ...DynamicallyAccessedMembersTypeHierarchy.cs | 50 +++++------ .../ReflectionTests.cs | 4 +- .../TypeHierarchyReflectionWarnings.cs | 85 +++++++++++++++++-- 3 files changed, 107 insertions(+), 32 deletions(-) diff --git a/src/tools/illink/src/linker/Linker.Dataflow/DynamicallyAccessedMembersTypeHierarchy.cs b/src/tools/illink/src/linker/Linker.Dataflow/DynamicallyAccessedMembersTypeHierarchy.cs index 014d42cd884e94..943030c7f35061 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/DynamicallyAccessedMembersTypeHierarchy.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/DynamicallyAccessedMembersTypeHierarchy.cs @@ -14,6 +14,7 @@ sealed class DynamicallyAccessedMembersTypeHierarchy { readonly LinkContext _context; readonly MarkStep _markStep; + readonly ReflectionMarker _reflectionMarker; // Cache of DynamicallyAccessedMembers annotations applied to types and their hierarchies // Values @@ -43,6 +44,7 @@ public DynamicallyAccessedMembersTypeHierarchy (LinkContext context, MarkStep ma _context = context; _markStep = markStep; _typesInDynamicallyAccessedMembersHierarchy = new Dictionary (); + _reflectionMarker = new ReflectionMarker (_context, _markStep, enabled: true); } public (DynamicallyAccessedMemberTypes annotation, bool applied) ProcessMarkedTypeForDynamicallyAccessedMembersHierarchy (TypeDefinition type) @@ -107,10 +109,8 @@ public DynamicallyAccessedMembersTypeHierarchy (LinkContext context, MarkStep ma if (apply) { // One of the base/interface types is already marked as having the annotation applied // so we need to apply the annotation to this type as well - var origin = new MessageOrigin (type); - var reflectionMarker = new ReflectionMarker (_context, _markStep, enabled: true); // Report warnings on access to annotated members, with the annotated type as the origin. - ApplyDynamicallyAccessedMembersToType (reflectionMarker, origin, type, annotation); + ApplyDynamicallyAccessedMembersToType (type, annotation); } return (annotation, apply); @@ -126,10 +126,8 @@ public DynamicallyAccessedMemberTypes ApplyDynamicallyAccessedMembersToTypeHiera return annotation; // Apply the effective annotation for the type - var origin = new MessageOrigin (type); - var reflectionMarker = new ReflectionMarker (_context, _markStep, enabled: true); // Report warnings on access to annotated members, with the annotated type as the origin. - ApplyDynamicallyAccessedMembersToType (reflectionMarker, origin, type, annotation); + ApplyDynamicallyAccessedMembersToType (type, annotation); // Mark it as applied in the cache _typesInDynamicallyAccessedMembersHierarchy[type] = (annotation, true); @@ -161,16 +159,14 @@ public DynamicallyAccessedMemberTypes ApplyDynamicallyAccessedMembersToTypeHiera break; foreach (var candidateType in candidateTypes) { - ApplyDynamicallyAccessedMembersToTypeHierarchyInner (reflectionMarker, candidateType); + ApplyDynamicallyAccessedMembersToTypeHierarchyInner (candidateType); } } return annotation; } - bool ApplyDynamicallyAccessedMembersToTypeHierarchyInner ( - in ReflectionMarker reflectionMarker, - TypeDefinition type) + bool ApplyDynamicallyAccessedMembersToTypeHierarchyInner (TypeDefinition type) { (var annotation, var applied) = GetCachedInfoForTypeInHierarchy (type); @@ -182,13 +178,13 @@ bool ApplyDynamicallyAccessedMembersToTypeHierarchyInner ( TypeDefinition? baseType = _context.TryResolve (type.BaseType); if (baseType != null) - applied = ApplyDynamicallyAccessedMembersToTypeHierarchyInner (reflectionMarker, baseType); + applied = ApplyDynamicallyAccessedMembersToTypeHierarchyInner (baseType); if (!applied && type.HasInterfaces) { foreach (InterfaceImplementation iface in type.Interfaces) { var interfaceType = _context.TryResolve (iface.InterfaceType); if (interfaceType != null) { - if (ApplyDynamicallyAccessedMembersToTypeHierarchyInner (reflectionMarker, interfaceType)) { + if (ApplyDynamicallyAccessedMembersToTypeHierarchyInner (interfaceType)) { applied = true; break; } @@ -197,31 +193,33 @@ bool ApplyDynamicallyAccessedMembersToTypeHierarchyInner ( } if (applied) { - var origin = new MessageOrigin (type); // Report warnings on access to annotated members, with the annotated type as the origin. - ApplyDynamicallyAccessedMembersToType (reflectionMarker, origin, type, annotation); + ApplyDynamicallyAccessedMembersToType (type, annotation); _typesInDynamicallyAccessedMembersHierarchy[type] = (annotation, true); } return applied; } - void ApplyDynamicallyAccessedMembersToType (in ReflectionMarker reflectionMarker, in MessageOrigin origin, TypeDefinition type, DynamicallyAccessedMemberTypes annotation) + void ApplyDynamicallyAccessedMembersToType (TypeDefinition type, DynamicallyAccessedMemberTypes annotation) { + var origin = new MessageOrigin (type); Debug.Assert (annotation != DynamicallyAccessedMemberTypes.None); // We need to apply annotations to this type, and its base/interface types (recursively) - // But the annotations on base/interfaces are already applied so we don't need to apply those + // But the annotations on base will be applied so we don't need to apply those // again (and should avoid doing so as it would produce extra warnings). var baseType = _context.TryResolve (type.BaseType); if (baseType != null) { var baseAnnotation = GetCachedInfoForTypeInHierarchy (baseType); - var annotationToApplyToBase = baseAnnotation.applied ? Annotations.GetMissingMemberTypes (annotation, baseAnnotation.annotation) : annotation; + if (!baseAnnotation.applied && baseAnnotation.annotation != DynamicallyAccessedMemberTypes.None) + ApplyDynamicallyAccessedMembersToType (baseType, baseAnnotation.annotation); + var annotationToApplyToBase = Annotations.GetMissingMemberTypes (annotation, baseAnnotation.annotation); // Apply any annotations that didn't exist on the base type to the base type. // This may produce redundant warnings when the annotation is DAMT.All or DAMT.PublicConstructors and the base already has a // subset of those annotations. - reflectionMarker.MarkTypeForDynamicallyAccessedMembers (origin, baseType, annotationToApplyToBase, DependencyKind.DynamicallyAccessedMemberOnType, declaredOnly: false); + _reflectionMarker.MarkTypeForDynamicallyAccessedMembers (origin, baseType, annotationToApplyToBase, DependencyKind.DynamicallyAccessedMemberOnType, declaredOnly: false); } // Most of the DynamicallyAccessedMemberTypes don't select members on interfaces. We only need to apply @@ -234,19 +232,21 @@ void ApplyDynamicallyAccessedMembersToType (in ReflectionMarker reflectionMarker continue; var interfaceAnnotation = GetCachedInfoForTypeInHierarchy (interfaceType); - if (interfaceAnnotation.applied && interfaceAnnotation.annotation.HasFlag (annotationToApplyToInterfaces)) - continue; - - // Apply All or Interfaces to the interface type. - // DAMT.All may produce redundant warnings from implementing types, when the interface type already had some annotations. - reflectionMarker.MarkTypeForDynamicallyAccessedMembers (origin, interfaceType, annotationToApplyToInterfaces, DependencyKind.DynamicallyAccessedMemberOnType, declaredOnly: false); + if (interfaceAnnotation.annotation.HasFlag (annotationToApplyToInterfaces)) { + if (!interfaceAnnotation.applied) + ApplyDynamicallyAccessedMembersToType (interfaceType, interfaceAnnotation.annotation); + } else { + // Apply All or Interfaces to the interface type. + // DAMT.All may produce redundant warnings from implementing types, when the interface type already had some annotations. + _reflectionMarker.MarkTypeForDynamicallyAccessedMembers (origin, interfaceType, annotationToApplyToInterfaces, DependencyKind.DynamicallyAccessedMemberOnType, declaredOnly: false); + } } } // The annotations this type inherited from its base types or interfaces should not produce // warnings on the respective base/interface members, since those are already covered by applying // the annotations to those types. So we only need to handle the members directly declared on this type. - reflectionMarker.MarkTypeForDynamicallyAccessedMembers (origin, type, annotation, DependencyKind.DynamicallyAccessedMemberOnType, declaredOnly: true); + _reflectionMarker.MarkTypeForDynamicallyAccessedMembers (origin, type, annotation, DependencyKind.DynamicallyAccessedMemberOnType, declaredOnly: true); } (DynamicallyAccessedMemberTypes annotation, bool applied) GetCachedInfoForTypeInHierarchy (TypeDefinition type) diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReflectionTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReflectionTests.cs index 5799627098f509..c3cae702e3e929 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReflectionTests.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReflectionTests.cs @@ -181,14 +181,14 @@ public Task TypeDelegator () [Fact] public Task TypeHierarchyReflectionWarnings () { - // https://github.com/dotnet/linker/issues/2578 + // https://github.com/dotnet/runtime/issues/104742 return RunTest (allowMissingWarnings: true); } [Fact] public Task TypeHierarchySuppressions () { - // https://github.com/dotnet/linker/issues/2578 + // https://github.com/dotnet/runtime/issues/104742 return RunTest (allowMissingWarnings: true); } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs index cd3ae16955e94d..75ebd5d6edf7a3 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs @@ -58,6 +58,8 @@ public static void Main () RUCOnVirtualOnAnnotatedBase.Test (); RUCOnVirtualOnAnnotatedBaseUsedByDerived.Test (); + RUCOnVirtualOnAnnotatedInterface.Test (); + RucOnVirtualOnAnnotatedInterfaceUsedByImplementation.Test (); UseByDerived.Test (); CompilerGeneratedCodeRUC.Test (null); @@ -699,16 +701,13 @@ public class Base [Kept] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] [RequiresUnreferencedCode ("--RUCOnVirtualMethodDerivedAnnotated.Base.RUCVirtualMethod--")] - // Compare to the case above - the only difference is the type of the field - // and it causes different warnings to be produced. - [ExpectedWarning ("IL2112", "--RUCOnVirtualMethodDerivedAnnotated.Base.RUCVirtualMethod--", Tool.None, "https://github.com/dotnet/runtime/issues/86580")] + [ExpectedWarning ("IL2112", "--RUCOnVirtualMethodDerivedAnnotated.Base.RUCVirtualMethod--", Tool.Trimmer, "https://github.com/dotnet/runtime/issues/104740")] public virtual void RUCVirtualMethod () { } } [Kept] [KeptMember (".ctor()")] [KeptBaseType (typeof (Base))] - [UnexpectedWarning ("IL2113", "--RUCOnVirtualMethodDerivedAnnotated.Base.RUCVirtualMethod--", Tool.Trimmer, "https://github.com/dotnet/runtime/issues/86580")] public class Derived : Base { [Kept] @@ -729,6 +728,82 @@ public static void Test () } } + [Kept] + class RUCOnVirtualOnAnnotatedInterface + { + [Kept] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] + public interface Interface + { + [Kept] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode ("--RUCOnVirtualOnAnnotatedInterface.Interface.RUCVirtualMethod--")] + [ExpectedWarning ("IL2112", "--RUCOnVirtualOnAnnotatedInterface.Interface.RUCVirtualMethod--", Tool.Trimmer, "https://github.com/dotnet/runtime/issues/104740")] + void RUCVirtualMethod () { } + } + + [Kept] + [KeptMember (".ctor()")] + [KeptInterface (typeof (Interface))] + public class Implementation : Interface + { + [Kept] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode ("--RUCOnVirtualOnAnnotatedInterface.Implementation.RUCVirtualMethod--")] + [ExpectedWarning ("IL2112", "--RUCOnVirtualOnAnnotatedInterface.Implementation.RUCVirtualMethod--")] + public void RUCVirtualMethod () { } + } + + [Kept] + static Interface _interfaceInstance; + + [Kept] + public static void Test () + { + _interfaceInstance = new Implementation (); + _interfaceInstance.GetType ().RequiresAll (); + } + } + + [Kept] + class RucOnVirtualOnAnnotatedInterfaceUsedByImplementation + { + [Kept] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] + public interface Interface + { + [Kept] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode ("--RucOnVirtualOnAnnotatedInterfaceUsedByImplementation.Interface.RUCVirtualMethod--")] + [ExpectedWarning ("IL2112", "--RucOnVirtualOnAnnotatedInterfaceUsedByImplementation.Interface.RUCVirtualMethod--", Tool.Trimmer, "https://github.com/dotnet/runtime/issues/104740")] + void RUCVirtualMethod () { } + } + + [Kept] + [KeptMember (".ctor()")] + [KeptInterface (typeof (Interface))] + public class Implementation : Interface + { + [Kept] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode ("--RucOnVirtualOnAnnotatedInterfaceUsedByImplementation.Implementation.RUCVirtualMethod--")] + [ExpectedWarning ("IL2112", "--RucOnVirtualOnAnnotatedInterfaceUsedByImplementation.Implementation.RUCVirtualMethod--")] + public void RUCVirtualMethod () { } + } + + [Kept] + static Implementation _implementationInstance; + + [Kept] + public static void Test () + { + _implementationInstance = new Implementation (); + _implementationInstance.GetType ().RequiresAll (); + } + } + [Kept] class UseByDerived { @@ -745,13 +820,13 @@ class AnnotatedBase [RequiresUnreferencedCode ("--AnnotatedBase.VirtualMethodWithRequires--")] [RequiresDynamicCode ("--AnnotatedBase.VirtualMethodWithRequires--")] [RequiresAssemblyFiles ("--AnnotatedBase.VirtualMethodWithRequires--")] + [ExpectedWarning ("IL2112", "--AnnotatedBase.VirtualMethodWithRequires--", Tool.Trimmer, "https://github.com/dotnet/runtime/issues/104740")] public virtual void VirtualMethodWithRequires () { } } [Kept] [KeptBaseType (typeof (AnnotatedBase))] [KeptMember (".ctor()")] - [UnexpectedWarning ("IL2113", "--AnnotatedBase.VirtualMethodWithRequires--", Tool.Trimmer, "https://github.com/dotnet/runtime/issues/86580")] class Derived : AnnotatedBase { [Kept] From 5354e0f6e5baffa22fd52f3797ecd43711041c5c Mon Sep 17 00:00:00 2001 From: Aman Khalid Date: Mon, 15 Jul 2024 16:57:15 +0000 Subject: [PATCH 09/30] ARM64-SVE: Add `TrigonometricMultiplyAddCoefficient` (#104697) --- src/coreclr/jit/hwintrinsicarm64.cpp | 5 ++ src/coreclr/jit/hwintrinsiccodegenarm64.cpp | 20 +++++++ src/coreclr/jit/hwintrinsiclistarm64sve.h | 1 + src/coreclr/jit/lowerarmarch.cpp | 1 + src/coreclr/jit/lsraarm64.cpp | 1 + .../Arm/Sve.PlatformNotSupported.cs | 15 ++++++ .../src/System/Runtime/Intrinsics/Arm/Sve.cs | 15 ++++++ .../ref/System.Runtime.Intrinsics.cs | 2 + .../GenerateHWIntrinsicTests_Arm.cs | 13 ++++- .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 54 +++++++++++++++++++ .../_SveImmBinaryOpTestTemplate.template | 32 ++++++++++- 11 files changed, 155 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index a3fed94ee71a89..91b053a49163e2 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -504,6 +504,11 @@ void HWIntrinsicInfo::lookupImmBounds( immUpperBound = (int)SVE_PRFOP_CONST15; break; + case NI_Sve_TrigonometricMultiplyAddCoefficient: + immLowerBound = 0; + immUpperBound = 7; + break; + default: unreached(); } diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index bb9e340d03d377..6f519c2094805f 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -2330,6 +2330,26 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) break; } + case NI_Sve_TrigonometricMultiplyAddCoefficient: + { + assert(isRMW); + + if (targetReg != op1Reg) + { + assert(targetReg != op2Reg); + + GetEmitter()->emitInsSve_R_R(INS_sve_movprfx, EA_SCALABLE, targetReg, op1Reg); + } + + HWIntrinsicImmOpHelper helper(this, intrin.op3, node); + + for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) + { + GetEmitter()->emitInsSve_R_R_I(ins, emitSize, targetReg, op2Reg, helper.ImmValue(), opt); + } + break; + } + default: unreached(); } diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index ab78d2f0f1af60..d4ec166ba3f792 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -246,6 +246,7 @@ HARDWARE_INTRINSIC(Sve, TestFirstTrue, HARDWARE_INTRINSIC(Sve, TestLastTrue, -1, 2, true, {INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, TransposeEven, -1, 2, true, {INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, TransposeOdd, -1, 2, true, {INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Sve, TrigonometricMultiplyAddCoefficient, -1, 3, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ftmad, INS_sve_ftmad}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, TrigonometricSelectCoefficient, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ftssel, INS_sve_ftssel}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Sve, TrigonometricStartingValue, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ftsmul, INS_sve_ftsmul}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Sve, UnzipEven, -1, 2, true, {INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index b04e97844f1f27..3ecc41f20d99f7 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -3434,6 +3434,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_PrefetchInt32: case NI_Sve_PrefetchInt64: case NI_Sve_ExtractVector: + case NI_Sve_TrigonometricMultiplyAddCoefficient: assert(hasImmediateOperand); assert(varTypeIsIntegral(intrin.op3)); if (intrin.op3->IsCnsIntOrI()) diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index d1fb48fc16d939..9cd5dd0f3ec035 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -1450,6 +1450,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou case NI_Sve_PrefetchInt32: case NI_Sve_PrefetchInt64: case NI_Sve_ExtractVector: + case NI_Sve_TrigonometricMultiplyAddCoefficient: needBranchTargetReg = !intrin.op3->isContainedIntOrIImmed(); break; diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs index bfb5314bb97a7e..d5e569439dafe1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs @@ -8631,6 +8631,21 @@ internal Arm64() { } public static unsafe Vector TransposeOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + /// Trigonometric multiply-add coefficient + + /// + /// svfloat64_t svtmad[_f64](svfloat64_t op1, svfloat64_t op2, uint64_t imm3) + /// FTMAD Ztied1.D, Ztied1.D, Zop2.D, #imm3 + /// + public static unsafe Vector TrigonometricMultiplyAddCoefficient(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(7))] byte control) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svtmad[_f32](svfloat32_t op1, svfloat32_t op2, uint64_t imm3) + /// FTMAD Ztied1.S, Ztied1.S, Zop2.S, #imm3 + /// + public static unsafe Vector TrigonometricMultiplyAddCoefficient(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(7))] byte control) { throw new PlatformNotSupportedException(); } + + /// Trigonometric select coefficient /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs index a0b8086b679921..e87e90fc92e47f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs @@ -8676,6 +8676,21 @@ internal Arm64() { } public static unsafe Vector TransposeOdd(Vector left, Vector right) => TransposeOdd(left, right); + /// Trigonometric multiply-add coefficient + + /// + /// svfloat64_t svtmad[_f64](svfloat64_t op1, svfloat64_t op2, uint64_t imm3) + /// FTMAD Ztied1.D, Ztied1.D, Zop2.D, #imm3 + /// + public static unsafe Vector TrigonometricMultiplyAddCoefficient(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(7))] byte control) => TrigonometricMultiplyAddCoefficient(left, right, control); + + /// + /// svfloat32_t svtmad[_f32](svfloat32_t op1, svfloat32_t op2, uint64_t imm3) + /// FTMAD Ztied1.S, Ztied1.S, Zop2.S, #imm3 + /// + public static unsafe Vector TrigonometricMultiplyAddCoefficient(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(7))] byte control) => TrigonometricMultiplyAddCoefficient(left, right, control); + + /// Trigonometric select coefficient /// diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 1afa8c2c7f7506..fbe30cad8fdafc 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -5603,6 +5603,8 @@ internal Arm64() { } public static System.Numerics.Vector TransposeOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector TransposeOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector TrigonometricMultiplyAddCoefficient(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(7))] byte control) { throw null; } + public static System.Numerics.Vector TrigonometricMultiplyAddCoefficient(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(7))] byte control) { throw null; } public static System.Numerics.Vector TrigonometricSelectCoefficient(System.Numerics.Vector value, System.Numerics.Vector selector) { throw null; } public static System.Numerics.Vector TrigonometricSelectCoefficient(System.Numerics.Vector value, System.Numerics.Vector selector) { throw null; } public static System.Numerics.Vector TrigonometricStartingValue(System.Numerics.Vector value, System.Numerics.Vector sign) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 6e548bd1926db6..75efaa708a3157 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -3850,8 +3850,8 @@ ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "0", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyExtended_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.MultiplyExtended(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyExtended(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyExtended_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.MultiplyExtended(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyExtended(left[i], right[i])"}), @@ -4107,6 +4107,15 @@ ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Sqrt_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.Sqrt(firstOp[i])", ["GetIterResult"] = "Helpers.Sqrt(leftOp[i])"}), ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Sqrt_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.Sqrt(firstOp[i])", ["GetIterResult"] = "Helpers.Sqrt(leftOp[i])"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "0", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "2", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_4", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "4", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_6", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_5", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_7", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "7", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 95619d36dfe3b9..d143df3432e87f 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -5252,6 +5252,33 @@ public static float MultiplyExtended(float op1, float op2) } } + public static float TrigonometricMultiplyAddCoefficient(float op1, float op2, byte imm) + { + int index = (op2 < 0) ? (imm + 8) : imm; + uint coeff = index switch + { + 0 => 0x3f800000, + 1 => 0xbe2aaaab, + 2 => 0x3c088886, + 3 => 0xb95008b9, + 4 => 0x36369d6d, + 5 => 0x00000000, + 6 => 0x00000000, + 7 => 0x00000000, + 8 => 0x3f800000, + 9 => 0xbf000000, + 10 => 0x3d2aaaa6, + 11 => 0xbab60705, + 12 => 0x37cd37cc, + 13 => 0x00000000, + 14 => 0x00000000, + 15 => 0x00000000, + _ => 0x00000000 + }; + + return MathF.FusedMultiplyAdd(op1, Math.Abs(op2), BitConverter.UInt32BitsToSingle(coeff)); + } + public static float TrigonometricSelectCoefficient(float op1, uint op2) { float result = ((op2 % 2) == 0) ? op1 : (float)1.0; @@ -5402,6 +5429,33 @@ public static double MultiplyExtended(double op1, double op2) } } + public static double TrigonometricMultiplyAddCoefficient(double op1, double op2, byte imm) + { + int index = (op2 < 0) ? (imm + 8) : imm; + ulong coeff = index switch + { + 0 => 0x3ff0000000000000, + 1 => 0xbfc5555555555543, + 2 => 0x3f8111111110f30c, + 3 => 0xbf2a01a019b92fc6, + 4 => 0x3ec71de351f3d22b, + 5 => 0xbe5ae5e2b60f7b91, + 6 => 0x3de5d8408868552f, + 7 => 0x0000000000000000, + 8 => 0x3ff0000000000000, + 9 => 0xbfe0000000000000, + 10 => 0x3fa5555555555536, + 11 => 0xbf56c16c16c13a0b, + 12 => 0x3efa01a019b1e8d8, + 13 => 0xbe927e4f7282f468, + 14 => 0x3e21ee96d2641b13, + 15 => 0xbda8f76380fbb401, + _ => 0x0000000000000000 + }; + + return Math.FusedMultiplyAdd(op1, Math.Abs(op2), BitConverter.UInt64BitsToDouble(coeff)); + } + public static double TrigonometricSelectCoefficient(double op1, ulong op2) { double result = ((op2 % 2) == 0) ? op1 : 1.0; diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template index 33d9c59e8dde18..3132da3fa1fdbf 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template @@ -62,6 +62,9 @@ namespace JIT.HardwareIntrinsics.Arm // Validates executing the test inside conditional, with op3 as zero test.ConditionalSelect_ZeroOp(); + + // Validates basic functionality fails with an invalid imm, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead_InvalidImm(); } else { @@ -209,6 +212,31 @@ namespace JIT.HardwareIntrinsics.Arm ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); } + public void RunBasicScenario_UnsafeRead_InvalidImm() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead_InvalidImm)); + + bool succeeded = false; + try + { + var result = {Isa}.{Method}( + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray2Ptr), + {InvalidImm} + ); + Console.WriteLine(result); + } + catch (ArgumentOutOfRangeException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); @@ -368,7 +396,7 @@ namespace JIT.HardwareIntrinsics.Arm [method: MethodImpl(MethodImplOptions.AggressiveInlining)] private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> op2, {Op1VectorType}<{Op1BaseType}> falseOp) { - var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, Imm), falseOp); + var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, {Imm}), falseOp); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateConditionalSelectResult_TrueValue(mask, op1, op2, falseOp, _dataTable.outArrayPtr); } @@ -376,7 +404,7 @@ namespace JIT.HardwareIntrinsics.Arm [method: MethodImpl(MethodImplOptions.AggressiveInlining)] private void ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> op2, {Op1VectorType}<{Op1BaseType}> trueOp) { - var result = Sve.ConditionalSelect(mask, trueOp, {Isa}.{Method}(op1, op2, Imm)); + var result = Sve.ConditionalSelect(mask, trueOp, {Isa}.{Method}(op1, op2, {Imm})); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateConditionalSelectResult_FalseValue(mask, op1, op2, trueOp, _dataTable.outArrayPtr); } From a86987ccab917433d065fe5dc8870fc261f79d14 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Mon, 15 Jul 2024 18:59:51 +0200 Subject: [PATCH 10/30] JIT: Remove `GTF_IS_IN_CSE` (#104855) This flag is just a convoluted way to pass an argument through to a bunch of methods from inside CSE. That's because CSE tries to reuse `gtExtractSideEffList` even though it needs something more capable that considers CSE defs and CSE uses as well. Remove the flag in favor of an `ignoreCctors` flag in the side effect checking functions; then, additionally add a CSE-specific version of `gtExtractSideEffList` called `optExtractSideEffectsForCSE` which handles side effects and also CSE defs/uses. This does result in a slight amount of duplication, but I think that's beneficial over the convoluted logic before. --- src/coreclr/jit/compiler.h | 5 +- src/coreclr/jit/gentree.cpp | 159 +++++++++++------------------------- src/coreclr/jit/gentree.h | 9 -- src/coreclr/jit/optcse.cpp | 112 ++++++++++++++++++++++++- 4 files changed, 161 insertions(+), 124 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 2f9abcb00703ad..743cd5c4095fda 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -3648,10 +3648,10 @@ class Compiler void gtSetStmtInfo(Statement* stmt); // Returns "true" iff "node" has any of the side effects in "flags". - bool gtNodeHasSideEffects(GenTree* node, GenTreeFlags flags); + bool gtNodeHasSideEffects(GenTree* node, GenTreeFlags flags, bool ignoreCctors = false); // Returns "true" iff "tree" or its (transitive) children have any of the side effects in "flags". - bool gtTreeHasSideEffects(GenTree* tree, GenTreeFlags flags); + bool gtTreeHasSideEffects(GenTree* tree, GenTreeFlags flags, bool ignoreCctors = false); void gtExtractSideEffList(GenTree* expr, GenTree** pList, @@ -7251,6 +7251,7 @@ class Compiler void optValnumCSE_DataFlow(); void optValnumCSE_Availability(); void optValnumCSE_Heuristic(CSE_HeuristicCommon* heuristic); + GenTree* optExtractSideEffectsForCSE(GenTree* tree); bool optDoCSE; // True when we have found a duplicate CSE tree bool optValnumCSE_phase; // True when we are executing the optOptimizeValnumCSEs() phase diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index d47c42a0ade52f..bad626cf155da2 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -16609,7 +16609,7 @@ GenTree* Compiler::gtNewRefCOMfield(GenTree* objPtr, * It may return false even if the node has GTF_SIDE_EFFECT (because of its children). */ -bool Compiler::gtNodeHasSideEffects(GenTree* tree, GenTreeFlags flags) +bool Compiler::gtNodeHasSideEffects(GenTree* tree, GenTreeFlags flags, bool ignoreCctors) { if (flags & GTF_ASG) { @@ -16636,7 +16636,6 @@ bool Compiler::gtNodeHasSideEffects(GenTree* tree, GenTreeFlags flags) { GenTreeCall* const call = potentialCall->AsCall(); const bool ignoreExceptions = (flags & GTF_EXCEPT) == 0; - const bool ignoreCctors = (flags & GTF_IS_IN_CSE) != 0; // We can CSE helpers that run cctors. if (!call->HasSideEffects(this, ignoreExceptions, ignoreCctors)) { // If this call is otherwise side effect free, check its arguments. @@ -16644,12 +16643,13 @@ bool Compiler::gtNodeHasSideEffects(GenTree* tree, GenTreeFlags flags) { // I'm a little worried that args that assign to temps that are late args will look like // side effects...but better to be conservative for now. - if ((arg.GetEarlyNode() != nullptr) && gtTreeHasSideEffects(arg.GetEarlyNode(), flags)) + if ((arg.GetEarlyNode() != nullptr) && + gtTreeHasSideEffects(arg.GetEarlyNode(), flags, ignoreCctors)) { return true; } - if ((arg.GetLateNode() != nullptr) && gtTreeHasSideEffects(arg.GetLateNode(), flags)) + if ((arg.GetLateNode() != nullptr) && gtTreeHasSideEffects(arg.GetLateNode(), flags, ignoreCctors)) { return true; } @@ -16686,7 +16686,7 @@ bool Compiler::gtNodeHasSideEffects(GenTree* tree, GenTreeFlags flags) * Returns true if the expr tree has any side effects. */ -bool Compiler::gtTreeHasSideEffects(GenTree* tree, GenTreeFlags flags /* = GTF_SIDE_EFFECT*/) +bool Compiler::gtTreeHasSideEffects(GenTree* tree, GenTreeFlags flags /* = GTF_SIDE_EFFECT*/, bool ignoreCctors) { // These are the side effect flags that we care about for this tree GenTreeFlags sideEffectFlags = tree->gtFlags & flags; @@ -16709,22 +16709,22 @@ bool Compiler::gtTreeHasSideEffects(GenTree* tree, GenTreeFlags flags /* = GTF_S // If this node is a helper call we may not care about the side-effects. // Note that gtNodeHasSideEffects checks the side effects of the helper itself // as well as the side effects of its arguments. - return gtNodeHasSideEffects(tree, flags); + return gtNodeHasSideEffects(tree, flags, ignoreCctors); } } else if (tree->OperGet() == GT_INTRINSIC) { - if (gtNodeHasSideEffects(tree, flags)) + if (gtNodeHasSideEffects(tree, flags, ignoreCctors)) { return true; } - if (gtNodeHasSideEffects(tree->AsOp()->gtOp1, flags)) + if (gtNodeHasSideEffects(tree->AsOp()->gtOp1, flags, ignoreCctors)) { return true; } - if ((tree->AsOp()->gtOp2 != nullptr) && gtNodeHasSideEffects(tree->AsOp()->gtOp2, flags)) + if ((tree->AsOp()->gtOp2 != nullptr) && gtNodeHasSideEffects(tree->AsOp()->gtOp2, flags, ignoreCctors)) { return true; } @@ -17110,81 +17110,61 @@ void Compiler::gtExtractSideEffList(GenTree* expr, { GenTree* node = *use; - bool treeHasSideEffects = m_compiler->gtTreeHasSideEffects(node, m_flags); + if (!m_compiler->gtTreeHasSideEffects(node, m_flags)) + { + return Compiler::WALK_SKIP_SUBTREES; + } - if (treeHasSideEffects) + if (m_compiler->gtNodeHasSideEffects(node, m_flags)) { - if (m_compiler->gtNodeHasSideEffects(node, m_flags)) + if (node->OperIsBlk() && !node->OperIsStoreBlk()) { - if (node->OperIsBlk() && !node->OperIsStoreBlk()) - { - JITDUMP("Replace an unused BLK node [%06d] with a NULLCHECK\n", dspTreeID(node)); - m_compiler->gtChangeOperToNullCheck(node, m_compiler->compCurBB); - } - - Append(node); - return Compiler::WALK_SKIP_SUBTREES; + JITDUMP("Replace an unused BLK node [%06d] with a NULLCHECK\n", dspTreeID(node)); + m_compiler->gtChangeOperToNullCheck(node, m_compiler->compCurBB); } - if (node->OperIs(GT_QMARK)) - { - GenTree* prevSideEffects = m_result; - // Visit children out of order so we know if we can - // completely remove the qmark. We cannot modify the - // condition if we cannot completely remove the qmark, so - // we cannot visit it first. + Append(node); + return Compiler::WALK_SKIP_SUBTREES; + } - GenTreeQmark* qmark = node->AsQmark(); - GenTreeColon* colon = qmark->gtGetOp2()->AsColon(); + if (node->OperIs(GT_QMARK)) + { + GenTree* prevSideEffects = m_result; + // Visit children out of order so we know if we can + // completely remove the qmark. We cannot modify the + // condition if we cannot completely remove the qmark, so + // we cannot visit it first. - m_result = nullptr; - WalkTree(&colon->gtOp1, colon); - GenTree* thenSideEffects = m_result; + GenTreeQmark* qmark = node->AsQmark(); + GenTreeColon* colon = qmark->gtGetOp2()->AsColon(); - m_result = nullptr; - WalkTree(&colon->gtOp2, colon); - GenTree* elseSideEffects = m_result; + m_result = nullptr; + WalkTree(&colon->gtOp1, colon); + GenTree* thenSideEffects = m_result; - m_result = prevSideEffects; + m_result = nullptr; + WalkTree(&colon->gtOp2, colon); + GenTree* elseSideEffects = m_result; - if ((thenSideEffects == nullptr) && (elseSideEffects == nullptr)) - { - WalkTree(&qmark->gtOp1, qmark); - } - else - { - colon->gtOp1 = (thenSideEffects != nullptr) ? thenSideEffects : m_compiler->gtNewNothingNode(); - colon->gtOp2 = (elseSideEffects != nullptr) ? elseSideEffects : m_compiler->gtNewNothingNode(); - qmark->gtType = TYP_VOID; - colon->gtType = TYP_VOID; - Append(qmark); - } + m_result = prevSideEffects; - return Compiler::WALK_SKIP_SUBTREES; + if ((thenSideEffects == nullptr) && (elseSideEffects == nullptr)) + { + WalkTree(&qmark->gtOp1, qmark); } - - // Generally all GT_CALL nodes are considered to have side-effects. - // So if we get here it must be a helper call that we decided it does - // not have side effects that we needed to keep. - assert(!node->OperIs(GT_CALL) || node->AsCall()->IsHelperCall()); - } - - if ((m_flags & GTF_IS_IN_CSE) != 0) - { - // If we're doing CSE then we also need to unmark CSE nodes. This will fail for CSE defs, - // those need to be extracted as if they're side effects. - if (!UnmarkCSE(node)) + else { - Append(node); - return Compiler::WALK_SKIP_SUBTREES; + colon->gtOp1 = (thenSideEffects != nullptr) ? thenSideEffects : m_compiler->gtNewNothingNode(); + colon->gtOp2 = (elseSideEffects != nullptr) ? elseSideEffects : m_compiler->gtNewNothingNode(); + qmark->gtType = TYP_VOID; + colon->gtType = TYP_VOID; + Append(qmark); } - // The existence of CSE defs and uses is not propagated up the tree like side - // effects are. We need to continue visiting the tree as if it has side effects. - treeHasSideEffects = true; + return Compiler::WALK_SKIP_SUBTREES; } - return treeHasSideEffects ? Compiler::WALK_CONTINUE : Compiler::WALK_SKIP_SUBTREES; + return Compiler::WALK_CONTINUE; } void Append(GenTree* node) @@ -17196,7 +17176,6 @@ void Compiler::gtExtractSideEffList(GenTree* expr, } GenTree* comma = m_compiler->gtNewOperNode(GT_COMMA, TYP_VOID, m_result, node); - comma->gtFlags |= (m_result->gtFlags | node->gtFlags) & GTF_ALL_EFFECT; #ifdef DEBUG if (m_compiler->fgGlobalMorph) @@ -17218,52 +17197,12 @@ void Compiler::gtExtractSideEffList(GenTree* expr, // if ((m_compiler->vnStore != nullptr) && m_result->gtVNPair.BothDefined() && node->gtVNPair.BothDefined()) { - // The result of a GT_COMMA node is op2, the normal value number is op2vnp - // But we also need to include the union of side effects from op1 and op2. - // we compute this value into exceptions_vnp. - ValueNumPair op1vnp; - ValueNumPair op1Xvnp = ValueNumStore::VNPForEmptyExcSet(); - ValueNumPair op2vnp; - ValueNumPair op2Xvnp = ValueNumStore::VNPForEmptyExcSet(); - - m_compiler->vnStore->VNPUnpackExc(node->gtVNPair, &op1vnp, &op1Xvnp); - m_compiler->vnStore->VNPUnpackExc(m_result->gtVNPair, &op2vnp, &op2Xvnp); - - ValueNumPair exceptions_vnp = ValueNumStore::VNPForEmptyExcSet(); - - exceptions_vnp = m_compiler->vnStore->VNPExcSetUnion(exceptions_vnp, op1Xvnp); - exceptions_vnp = m_compiler->vnStore->VNPExcSetUnion(exceptions_vnp, op2Xvnp); - - comma->gtVNPair = m_compiler->vnStore->VNPWithExc(op2vnp, exceptions_vnp); + ValueNumPair op1Exceptions = m_compiler->vnStore->VNPExceptionSet(m_result->gtVNPair); + comma->gtVNPair = m_compiler->vnStore->VNPWithExc(node->gtVNPair, op1Exceptions); } m_result = comma; } - - private: - bool UnmarkCSE(GenTree* node) - { - assert(m_compiler->optValnumCSE_phase); - - if (m_compiler->optUnmarkCSE(node)) - { - // The call to optUnmarkCSE(node) should have cleared any CSE info. - assert(!IS_CSE_INDEX(node->gtCSEnum)); - return true; - } - else - { - assert(IS_CSE_DEF(node->gtCSEnum)); -#ifdef DEBUG - if (m_compiler->verbose) - { - printf("Preserving the CSE def #%02d at ", GET_CSE_INDEX(node->gtCSEnum)); - m_compiler->printTreeID(node); - } -#endif - return false; - } - } }; SideEffectExtractor extractor(this, flags); diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index c2b186e691e89a..9595be490519f4 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -404,15 +404,6 @@ enum GenTreeFlags : unsigned int // With operators: the specified node is an unsigned operator GTF_SPILL = 0x00020000, // Needs to be spilled here -// The extra flag GTF_IS_IN_CSE is used to tell the consumer of the side effect flags -// that we are calling in the context of performing a CSE, thus we -// should allow the run-once side effects of running a class constructor. -// -// The only requirement of this flag is that it not overlap any of the -// side-effect flags. The actual bit used is otherwise arbitrary. - - GTF_IS_IN_CSE = 0x00004000, - GTF_COMMON_MASK = 0x0003FFFF, // mask of all the flags above GTF_REUSE_REG_VAL = 0x00800000, // This is set by the register allocator on nodes whose value already exists in the diff --git a/src/coreclr/jit/optcse.cpp b/src/coreclr/jit/optcse.cpp index b3d8e2610168a1..4bd081e14ad7ef 100644 --- a/src/coreclr/jit/optcse.cpp +++ b/src/coreclr/jit/optcse.cpp @@ -1878,7 +1878,7 @@ bool CSE_HeuristicCommon::CanConsiderTree(GenTree* tree, bool isReturn) // If we have a simple helper call with no other persistent side-effects // then we allow this tree to be a CSE candidate // - if (m_pCompiler->gtTreeHasSideEffects(tree, GTF_PERSISTENT_SIDE_EFFECTS | GTF_IS_IN_CSE)) + if (m_pCompiler->gtTreeHasSideEffects(tree, GTF_PERSISTENT_SIDE_EFFECTS, /* ignoreCctors */ true)) { return false; } @@ -5131,8 +5131,7 @@ void CSE_HeuristicCommon::PerformCSE(CSE_Candidate* successfulCandidate) // exp->gtCSEnum = NO_CSE; // clear the gtCSEnum field - GenTree* sideEffList = nullptr; - m_pCompiler->gtExtractSideEffList(exp, &sideEffList, GTF_PERSISTENT_SIDE_EFFECTS | GTF_IS_IN_CSE); + GenTree* sideEffList = m_pCompiler->optExtractSideEffectsForCSE(exp); // If we have any side effects or extracted CSE defs then we need to create a GT_COMMA tree instead // @@ -5414,6 +5413,113 @@ void CSE_HeuristicCommon::ConsiderCandidates() } } +//------------------------------------------------------------------------ +// optExtractSideEffectsForCSE: Extract side effects from a tree that is going +// to be CSE'd. This requires unmarking CSE uses and preserving CSE defs as if +// they were side effects. +// +// Parameters: +// tree - The tree containing side effects +// +// Return Value: +// Tree of side effects. +// +// Remarks: +// Unlike gtExtractSideEffList, this considers CSE defs to be side effects +// and also unmarks CSE uses as it proceeds. Additionally, for CSE we are ok +// with not treating cctor invocations as side effects because we have +// already handled those specially during CSE. +// +GenTree* Compiler::optExtractSideEffectsForCSE(GenTree* tree) +{ + class Extractor final : public GenTreeVisitor + { + GenTree* m_result = nullptr; + + public: + enum + { + DoPreOrder = true, + UseExecutionOrder = true + }; + + GenTree* GetResult() + { + return m_result; + } + + Extractor(Compiler* compiler) + : GenTreeVisitor(compiler) + { + } + + fgWalkResult PreOrderVisit(GenTree** use, GenTree* user) + { + GenTree* node = *use; + + if (m_compiler->gtTreeHasSideEffects(node, GTF_PERSISTENT_SIDE_EFFECTS, /* ignoreCctors */ true)) + { + if (m_compiler->gtNodeHasSideEffects(node, GTF_PERSISTENT_SIDE_EFFECTS, /* ignoreCctors */ true)) + { + Append(node); + return Compiler::WALK_SKIP_SUBTREES; + } + + // Generally all GT_CALL nodes are considered to have side-effects. + // So if we get here it must be a helper call that we decided it does + // not have side effects that we needed to keep. + assert(!node->OperIs(GT_CALL) || node->AsCall()->IsHelperCall()); + } + + // We also need to unmark CSE nodes. This will fail for CSE defs, + // those need to be extracted as if they're side effects. + if (m_compiler->optUnmarkCSE(node)) + { + // The call to optUnmarkCSE(node) should have cleared any CSE info. + assert(!IS_CSE_INDEX(node->gtCSEnum)); + return Compiler::WALK_CONTINUE; + } + + assert(IS_CSE_DEF(node->gtCSEnum)); +#ifdef DEBUG + if (m_compiler->verbose) + { + printf("Preserving the CSE def #%02d at ", GET_CSE_INDEX(node->gtCSEnum)); + m_compiler->printTreeID(node); + } +#endif + Append(node); + return Compiler::WALK_SKIP_SUBTREES; + } + + void Append(GenTree* node) + { + if (m_result == nullptr) + { + m_result = node; + return; + } + + GenTree* comma = m_compiler->gtNewOperNode(GT_COMMA, TYP_VOID, m_result, node); + + // Set the ValueNumber 'gtVNPair' for the new GT_COMMA node + // + if ((m_compiler->vnStore != nullptr) && m_result->gtVNPair.BothDefined() && node->gtVNPair.BothDefined()) + { + ValueNumPair op1Exceptions = m_compiler->vnStore->VNPExceptionSet(m_result->gtVNPair); + comma->gtVNPair = m_compiler->vnStore->VNPWithExc(node->gtVNPair, op1Exceptions); + } + + m_result = comma; + } + }; + + Extractor extractor(this); + extractor.WalkTree(&tree, nullptr); + + return extractor.GetResult(); +} + //------------------------------------------------------------------------ // optValnumCSE_Heuristic: Perform common sub-expression elimination // based on profitabiliy heuristic From 2268a06871542f070dec7080a1c2602bf04b9de8 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Mon, 15 Jul 2024 14:02:57 -0400 Subject: [PATCH 11/30] Update comment in CreateVersion7 (#104897) --- src/libraries/System.Private.CoreLib/src/System/Guid.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Guid.cs b/src/libraries/System.Private.CoreLib/src/System/Guid.cs index 4d3419236ec5f8..8dea2d581b2b6e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Guid.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Guid.cs @@ -303,9 +303,11 @@ public Guid(string g) /// public static Guid CreateVersion7(DateTimeOffset timestamp) { - // This isn't the most optimal way, but we don't have an easy way to get - // secure random bytes in corelib without doing this since the secure rng - // is in a different layer. + // NewGuid uses CoCreateGuid on Windows and Interop.GetCryptographicallySecureRandomBytes on Unix to get + // cryptographically-secure random bytes. We could use Interop.BCrypt.BCryptGenRandom to generate the random + // bytes on Windows, as is done in RandomNumberGenerator, but that's measurably slower than using CoCreateGuid. + // And while CoCreateGuid only generates 122 bits of randomness, the other 6 bits being for the version / variant + // fields, this method also needs those bits to be non-random, so we can just use NewGuid for efficiency. Guid result = NewGuid(); // 2^48 is roughly 8925.5 years, which from the Unix Epoch means we won't From d4a2691e97b091a2c1b258dc600e16b846450b75 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Mon, 15 Jul 2024 14:09:56 -0400 Subject: [PATCH 12/30] Light up support for OpenSSL ENGINEs only if they are available. Some Linux distributions are phasing out support for OpenSSL 1.x ENGINEs. They are doing this by moving the header, `engine.h`, to a separate package. The actual OpenSSL shared libraries still contain the engine APIs. This makes the change an API, not ABI, break. We react to this by disabling OpenSSL engine support on non-portable builds that are missing the engine header. Portable builds will continue to probe the loaded OpenSSL library for support, and non-portable builds will only support ENGINEs if the header is present. --- .../Interop.EvpPkey.cs | 22 +++++-- .../src/Resources/Strings.resx | 3 + .../configure.cmake | 6 ++ .../opensslshim.h | 37 +++++++++-- .../pal_crypto_config.h.in | 1 + .../pal_evp_pkey.c | 65 ++++++++++++++----- .../pal_evp_pkey.h | 6 +- 7 files changed, 110 insertions(+), 30 deletions(-) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.cs index 77b80634bd0ce1..4e8659b5653b78 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.cs @@ -217,7 +217,8 @@ internal static ArraySegment RentEncodeSubjectPublicKeyInfo(SafeEvpPKeyHan [LibraryImport(Libraries.CryptoNative, StringMarshalling = StringMarshalling.Utf8)] private static partial SafeEvpPKeyHandle CryptoNative_LoadPrivateKeyFromEngine( string engineName, - string keyName); + string keyName, + [MarshalAs(UnmanagedType.Bool)] out bool haveEngine); internal static SafeEvpPKeyHandle LoadPrivateKeyFromEngine( string engineName, @@ -226,7 +227,13 @@ internal static SafeEvpPKeyHandle LoadPrivateKeyFromEngine( Debug.Assert(engineName is not null); Debug.Assert(keyName is not null); - SafeEvpPKeyHandle pkey = CryptoNative_LoadPrivateKeyFromEngine(engineName, keyName); + SafeEvpPKeyHandle pkey = CryptoNative_LoadPrivateKeyFromEngine(engineName, keyName, out bool haveEngine); + + if (!haveEngine) + { + pkey.Dispose(); + throw new CryptographicException(SR.Cryptography_EnginesNotSupported); + } if (pkey.IsInvalid) { @@ -240,7 +247,8 @@ internal static SafeEvpPKeyHandle LoadPrivateKeyFromEngine( [LibraryImport(Libraries.CryptoNative, StringMarshalling = StringMarshalling.Utf8)] private static partial SafeEvpPKeyHandle CryptoNative_LoadPublicKeyFromEngine( string engineName, - string keyName); + string keyName, + [MarshalAs(UnmanagedType.Bool)] out bool haveEngine); internal static SafeEvpPKeyHandle LoadPublicKeyFromEngine( string engineName, @@ -249,7 +257,13 @@ internal static SafeEvpPKeyHandle LoadPublicKeyFromEngine( Debug.Assert(engineName is not null); Debug.Assert(keyName is not null); - SafeEvpPKeyHandle pkey = CryptoNative_LoadPublicKeyFromEngine(engineName, keyName); + SafeEvpPKeyHandle pkey = CryptoNative_LoadPublicKeyFromEngine(engineName, keyName, out bool haveEngine); + + if (!haveEngine) + { + pkey.Dispose(); + throw new CryptographicException(SR.Cryptography_EnginesNotSupported); + } if (pkey.IsInvalid) { diff --git a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx index 62b608677b74fa..630f2f89bc6ff6 100644 --- a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx +++ b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx @@ -327,6 +327,9 @@ {0} unexpectedly produced a ciphertext with the incorrect length. + + OpenSSL ENGINE is not available on this platform. + The total number of bytes extracted cannot exceed UInt32.MaxValue * hash length. diff --git a/src/native/libs/System.Security.Cryptography.Native/configure.cmake b/src/native/libs/System.Security.Cryptography.Native/configure.cmake index ea779318c667ca..d4d9f34be0dc7f 100644 --- a/src/native/libs/System.Security.Cryptography.Native/configure.cmake +++ b/src/native/libs/System.Security.Cryptography.Native/configure.cmake @@ -1,5 +1,6 @@ include(CheckLibraryExists) include(CheckFunctionExists) +include(CheckSourceCompiles) set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY} ${OPENSSL_SSL_LIBRARY}) @@ -27,6 +28,11 @@ check_function_exists( HAVE_OPENSSL_SHA3_SQUEEZE ) +check_source_compiles(C " +#include +int main(void) { ENGINE_init(NULL); return 1; }" +HAVE_OPENSSL_ENGINE) + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/pal_crypto_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/pal_crypto_config.h) diff --git a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h index 74413d2011836d..3541c7558484ea 100644 --- a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h +++ b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -48,6 +47,11 @@ #include #endif +#if HAVE_OPENSSL_ENGINE +// Some Linux distributions build without engine support. +#include +#endif + #if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_1_RTM #define HAVE_OPENSSL_SET_CIPHERSUITES 1 #else @@ -184,6 +188,25 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len); int EVP_DigestSqueeze(EVP_MD_CTX *ctx, unsigned char *out, size_t outlen); #endif +#if !HAVE_OPENSSL_ENGINE +#undef HAVE_OPENSSL_ENGINE +#define HAVE_OPENSSL_ENGINE 1 + +ENGINE *ENGINE_by_id(const char *id); +int ENGINE_init(ENGINE *e); +int ENGINE_finish(ENGINE *e); +ENGINE *ENGINE_new(void); +int ENGINE_free(ENGINE *e); +typedef EVP_PKEY *(*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, + UI_METHOD *ui_method, + void *callback_data); +EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); + +#endif + #define API_EXISTS(fn) (fn != NULL) @@ -319,12 +342,12 @@ extern bool g_libSslUses32BitTime; REQUIRED_FUNCTION(EC_POINT_mul) \ REQUIRED_FUNCTION(EC_POINT_new) \ REQUIRED_FUNCTION(EC_POINT_set_affine_coordinates_GFp) \ - REQUIRED_FUNCTION(ENGINE_by_id) \ - REQUIRED_FUNCTION(ENGINE_finish) \ - REQUIRED_FUNCTION(ENGINE_free) \ - REQUIRED_FUNCTION(ENGINE_init) \ - REQUIRED_FUNCTION(ENGINE_load_public_key) \ - REQUIRED_FUNCTION(ENGINE_load_private_key) \ + LIGHTUP_FUNCTION(ENGINE_by_id) \ + LIGHTUP_FUNCTION(ENGINE_finish) \ + LIGHTUP_FUNCTION(ENGINE_free) \ + LIGHTUP_FUNCTION(ENGINE_init) \ + LIGHTUP_FUNCTION(ENGINE_load_public_key) \ + LIGHTUP_FUNCTION(ENGINE_load_private_key) \ REQUIRED_FUNCTION(ERR_clear_error) \ REQUIRED_FUNCTION(ERR_error_string_n) \ REQUIRED_FUNCTION(ERR_get_error) \ diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_crypto_config.h.in b/src/native/libs/System.Security.Cryptography.Native/pal_crypto_config.h.in index c216e88e272e4a..7ef6127a6faa7e 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_crypto_config.h.in +++ b/src/native/libs/System.Security.Cryptography.Native/pal_crypto_config.h.in @@ -5,3 +5,4 @@ #cmakedefine01 HAVE_OPENSSL_CHACHA20POLY1305 #cmakedefine01 HAVE_OPENSSL_SHA3 #cmakedefine01 HAVE_OPENSSL_SHA3_SQUEEZE +#cmakedefine01 HAVE_OPENSSL_ENGINE diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c index 80183b97a77c90..dea4f277b8969d 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c @@ -511,41 +511,72 @@ int32_t CryptoNative_EncodeSubjectPublicKeyInfo(EVP_PKEY* pkey, uint8_t* buf) return i2d_PUBKEY(pkey, &buf); } +#if HAVE_OPENSSL_ENGINE static EVP_PKEY* LoadKeyFromEngine( const char* engineName, const char* keyName, - ENGINE_LOAD_KEY_PTR load_func) + ENGINE_LOAD_KEY_PTR load_func, + int32_t* haveEngine) { + assert(haveEngine); ERR_clear_error(); - EVP_PKEY* ret = NULL; - ENGINE* engine = NULL; + if (API_EXISTS(ENGINE_by_id) && API_EXISTS(ENGINE_init) && API_EXISTS(ENGINE_finish) && API_EXISTS(ENGINE_free)) + { + *haveEngine = 1; + EVP_PKEY* ret = NULL; + ENGINE* engine = NULL; - // Per https://github.com/openssl/openssl/discussions/21427 - // using EVP_PKEY after freeing ENGINE is correct. - engine = ENGINE_by_id(engineName); + // Per https://github.com/openssl/openssl/discussions/21427 + // using EVP_PKEY after freeing ENGINE is correct. + engine = ENGINE_by_id(engineName); - if (engine != NULL) - { - if (ENGINE_init(engine)) + if (engine != NULL) { - ret = load_func(engine, keyName, NULL, NULL); + if (ENGINE_init(engine)) + { + ret = load_func(engine, keyName, NULL, NULL); + + ENGINE_finish(engine); + } - ENGINE_finish(engine); + ENGINE_free(engine); } - ENGINE_free(engine); + return ret; } - return ret; + *haveEngine = 0; + return NULL; } +#endif -EVP_PKEY* CryptoNative_LoadPrivateKeyFromEngine(const char* engineName, const char* keyName) +EVP_PKEY* CryptoNative_LoadPrivateKeyFromEngine(const char* engineName, const char* keyName, int32_t* haveEngine) { - return LoadKeyFromEngine(engineName, keyName, ENGINE_load_private_key); +#if HAVE_OPENSSL_ENGINE + if (API_EXISTS(ENGINE_load_private_key)) + { + return LoadKeyFromEngine(engineName, keyName, ENGINE_load_private_key, haveEngine); + } +#endif + (void)engineName; + (void)keyName; + (void)haveEngine; + *haveEngine = 0; + return NULL; } -EVP_PKEY* CryptoNative_LoadPublicKeyFromEngine(const char* engineName, const char* keyName) +EVP_PKEY* CryptoNative_LoadPublicKeyFromEngine(const char* engineName, const char* keyName, int32_t* haveEngine) { - return LoadKeyFromEngine(engineName, keyName, ENGINE_load_public_key); +#if HAVE_OPENSSL_ENGINE + if (API_EXISTS(ENGINE_load_private_key)) + { + return LoadKeyFromEngine(engineName, keyName, ENGINE_load_public_key, haveEngine); + } +#endif + (void)engineName; + (void)keyName; + (void)haveEngine; + *haveEngine = 0; + return NULL; } diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.h b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.h index 64d289dc6f4884..e4d5f85d4b9ec3 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.h +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.h @@ -93,12 +93,14 @@ PALEXPORT int32_t CryptoNative_EncodeSubjectPublicKeyInfo(EVP_PKEY* pkey, uint8_ Load a named key, via ENGINE_load_private_key, from the named engine. Returns a valid EVP_PKEY* on success, NULL on failure. +haveEngine is 1 if OpenSSL ENGINE's are supported, otherwise 0. */ -PALEXPORT EVP_PKEY* CryptoNative_LoadPrivateKeyFromEngine(const char* engineName, const char* keyName); +PALEXPORT EVP_PKEY* CryptoNative_LoadPrivateKeyFromEngine(const char* engineName, const char* keyName, int32_t* haveEngine); /* Load a named key, via ENGINE_load_public_key, from the named engine. Returns a valid EVP_PKEY* on success, NULL on failure. +haveEngine is 1 if OpenSSL ENGINE's are supported, otherwise 0. */ -PALEXPORT EVP_PKEY* CryptoNative_LoadPublicKeyFromEngine(const char* engineName, const char* keyName); +PALEXPORT EVP_PKEY* CryptoNative_LoadPublicKeyFromEngine(const char* engineName, const char* keyName, int32_t* haveEngine); From f38e6611f8191800ff223bcd24992a0d2cea9c7b Mon Sep 17 00:00:00 2001 From: Mark Plesko Date: Mon, 15 Jul 2024 11:46:49 -0700 Subject: [PATCH 13/30] [GC] Fix freelist crash - don't modify during check-only operation (#104876) `RegisterForFullGCNotification` sets `gc_heap::fgn_maxgen_percent`, which guards calls to `check_for_full_gc` to determine if a notification should be sent. `gc_heap::generation_to_condemn`. One part of `check_for_full_gc` calls `generation_to_condemn` with the parameter `check_only_p` set to `TRUE`. `generation_to_condemn` calls `try_get_new_free_region`, which ensures that a free region is available. It checks the freelist, but if none are found it creates a new one and adds it to the freelist. `check_for_full_gc` does not (and should not) contain the necessary synchronization to make this safe. This can lead to corruption of the basic region freelist, often ending up with `nullptr` links between nodes. This caused crashed in production and the cause was determined by using a custom GC build with additional runtime checks. The fix is to simply honor the `check_only_p` parameter and not call `try_get_new_free_region` when it is set. The problem can be reproed by changing `try_get_new_free_region` to always create a new region. This fix handles that repro. This fix does not impact normal GC operation. It can cause `check_for_full_gc` to no longer detect that full collection is going to occur, but only if the failure to create or initialize a new region is the only reason why that full collection is going to occur. However, those cases are open to the race condition that can cause the freelist corruption is possible. --- src/coreclr/gc/gc.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 1575dfe4dbe329..7f41750d553366 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -21507,10 +21507,13 @@ int gc_heap::generation_to_condemn (int n_initial, } #ifdef USE_REGIONS - if (!try_get_new_free_region()) + if (!check_only_p) { - dprintf (GTC_LOG, ("can't get an empty region -> full compacting")); - last_gc_before_oom = TRUE; + if (!try_get_new_free_region()) + { + dprintf (GTC_LOG, ("can't get an empty region -> full compacting")); + last_gc_before_oom = TRUE; + } } #endif //USE_REGIONS From 01662463a50508a5bde82de600a898ead6015a5f Mon Sep 17 00:00:00 2001 From: SwapnilGaikwad Date: Mon, 15 Jul 2024 20:43:15 +0100 Subject: [PATCH 14/30] Add Sve.ScatterXBitYNarrowing() on Arm64 (#104720) * Add Sve.ScatterXBitYNarrowing() on Arm64 Includes: - Sve.Scatter16BitNarrowing() - Sve.Scatter8BitNarrowing() - Sve.Scatter32BitNarrowing() - Sve.Scatter16BitWithByteOffsetsNarrowing() - Sve.Scatter8BitWithByteOffsetsNarrowing() - Sve.Scatter32BitWithByteOffsetsNarrowing() * Remove duplicate API calls * Remove duplicate tests --- src/coreclr/jit/gentree.cpp | 8 +- src/coreclr/jit/hwintrinsiccodegenarm64.cpp | 22 +- src/coreclr/jit/hwintrinsiclistarm64sve.h | 6 + .../Arm/Sve.PlatformNotSupported.cs | 202 ++++++++++++++++++ .../src/System/Runtime/Intrinsics/Arm/Sve.cs | 202 ++++++++++++++++++ .../ref/System.Runtime.Intrinsics.cs | 37 ++++ .../GenerateHWIntrinsicTests_Arm.cs | 56 +++-- ...plate => SveScatterVectorOffsets.template} | 8 +- 8 files changed, 517 insertions(+), 24 deletions(-) rename src/tests/JIT/HardwareIntrinsics/Arm/Shared/{SveScatterVectorIndices.template => SveScatterVectorOffsets.template} (98%) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index bad626cf155da2..1022d6a5d4b656 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -26671,6 +26671,7 @@ bool GenTreeHWIntrinsic::OperIsMemoryStore(GenTree** pAddr) const case NI_SSE2_MaskMove: addr = Op(3); break; + #elif defined(TARGET_ARM64) case NI_Sve_StoreAndZip: case NI_Sve_StoreAndZipx2: @@ -26682,9 +26683,14 @@ bool GenTreeHWIntrinsic::OperIsMemoryStore(GenTree** pAddr) const break; case NI_Sve_Scatter: + case NI_Sve_Scatter16BitNarrowing: + case NI_Sve_Scatter16BitWithByteOffsetsNarrowing: + case NI_Sve_Scatter32BitNarrowing: + case NI_Sve_Scatter32BitWithByteOffsetsNarrowing: + case NI_Sve_Scatter8BitNarrowing: + case NI_Sve_Scatter8BitWithByteOffsetsNarrowing: addr = Op(2); break; - #endif // TARGET_ARM64 default: diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index 6f519c2094805f..db33fb25771786 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -2053,27 +2053,35 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) break; case NI_Sve_Scatter: + case NI_Sve_Scatter16BitNarrowing: + case NI_Sve_Scatter16BitWithByteOffsetsNarrowing: + case NI_Sve_Scatter32BitNarrowing: + case NI_Sve_Scatter32BitWithByteOffsetsNarrowing: + case NI_Sve_Scatter8BitNarrowing: + case NI_Sve_Scatter8BitWithByteOffsetsNarrowing: { if (!varTypeIsSIMD(intrin.op2->gtType)) { // Scatter(Vector mask, T1* address, Vector indicies, Vector data) assert(intrin.numOperands == 4); - emitAttr baseSize = emitActualTypeSize(intrin.baseType); + emitAttr baseSize = emitActualTypeSize(intrin.baseType); + insScalableOpts sopt; if (baseSize == EA_8BYTE) { // Index is multiplied by 8 - GetEmitter()->emitIns_R_R_R_R(ins, emitSize, op4Reg, op1Reg, op2Reg, op3Reg, opt, - INS_SCALABLE_OPTS_LSL_N); + sopt = (ins == INS_sve_st1b) ? INS_SCALABLE_OPTS_NONE : INS_SCALABLE_OPTS_LSL_N; + GetEmitter()->emitIns_R_R_R_R(ins, emitSize, op4Reg, op1Reg, op2Reg, op3Reg, opt, sopt); } else { // Index is sign or zero extended to 64bits, then multiplied by 4 assert(baseSize == EA_4BYTE); - opt = varTypeIsUnsigned(node->GetAuxiliaryType()) ? INS_OPTS_SCALABLE_S_UXTW - : INS_OPTS_SCALABLE_S_SXTW; - GetEmitter()->emitIns_R_R_R_R(ins, emitSize, op4Reg, op1Reg, op2Reg, op3Reg, opt, - INS_SCALABLE_OPTS_MOD_N); + opt = varTypeIsUnsigned(node->GetAuxiliaryType()) ? INS_OPTS_SCALABLE_S_UXTW + : INS_OPTS_SCALABLE_S_SXTW; + sopt = (ins == INS_sve_st1b) ? INS_SCALABLE_OPTS_NONE : INS_SCALABLE_OPTS_MOD_N; + + GetEmitter()->emitIns_R_R_R_R(ins, emitSize, op4Reg, op1Reg, op2Reg, op3Reg, opt, sopt); } } else diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index d4ec166ba3f792..e3a1d979b7fd38 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -225,6 +225,12 @@ HARDWARE_INTRINSIC(Sve, SaturatingIncrementBy8BitElementCount, HARDWARE_INTRINSIC(Sve, SaturatingIncrementByActiveElementCount, -1, 2, true, {INS_invalid, INS_sve_sqincp, INS_sve_sqincp, INS_sve_sqincp, INS_sve_sqincp, INS_sve_sqincp, INS_sve_sqincp, INS_sve_sqincp, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_BaseTypeFromSecondArg|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve, Scale, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fscale, INS_sve_fscale}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve, Scatter, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_st1w, INS_sve_st1w, INS_sve_st1d, INS_sve_st1d, INS_sve_st1w, INS_sve_st1d}, HW_Category_MemoryStore, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, Scatter16BitNarrowing, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_st1h, INS_sve_st1h, INS_sve_st1h, INS_sve_st1h, INS_invalid, INS_invalid}, HW_Category_MemoryStore, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, Scatter16BitWithByteOffsetsNarrowing, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_st1h, INS_sve_st1h, INS_sve_st1h, INS_sve_st1h, INS_invalid, INS_invalid}, HW_Category_MemoryStore, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, Scatter32BitNarrowing, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_st1w, INS_sve_st1w, INS_invalid, INS_invalid}, HW_Category_MemoryStore, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, Scatter32BitWithByteOffsetsNarrowing, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_st1w, INS_sve_st1w, INS_invalid, INS_invalid}, HW_Category_MemoryStore, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, Scatter8BitNarrowing, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_st1b, INS_sve_st1b, INS_sve_st1b, INS_sve_st1b, INS_invalid, INS_invalid}, HW_Category_MemoryStore, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, Scatter8BitWithByteOffsetsNarrowing, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_st1b, INS_sve_st1b, INS_sve_st1b, INS_sve_st1b, INS_invalid, INS_invalid}, HW_Category_MemoryStore, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, ShiftLeftLogical, -1, -1, false, {INS_sve_lsl, INS_sve_lsl, INS_sve_lsl, INS_sve_lsl, INS_sve_lsl, INS_sve_lsl, INS_sve_lsl, INS_sve_lsl, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve, ShiftRightArithmetic, -1, -1, false, {INS_sve_asr, INS_invalid, INS_sve_asr, INS_invalid, INS_sve_asr, INS_invalid, INS_sve_asr, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve, ShiftRightArithmeticForDivide, -1, -1, false, {INS_sve_asrd, INS_invalid, INS_sve_asrd, INS_invalid, INS_sve_asrd, INS_invalid, INS_sve_asrd, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs index d5e569439dafe1..736b3fd1484fd1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs @@ -7287,6 +7287,208 @@ internal Arm64() { } public static unsafe void Scatter(Vector mask, ulong* address, Vector indicies, Vector data) { throw new PlatformNotSupportedException(); } + // Truncate to 16 bits and store + + // + // void svst1h_scatter[_u32base_s32](svbool_t pg, svuint32_t bases, svint32_t data) + // ST1H Zdata.S, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void Scatter16BitNarrowing(Vector mask, Vector addresses, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1h_scatter[_u64base_s64](svbool_t pg, svuint64_t bases, svint64_t data) + // ST1H Zdata.D, Pg, [Zbases.D, #0] + // + public static unsafe void Scatter16BitNarrowing(Vector mask, Vector addresses, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1h_scatter[_u32base_u32](svbool_t pg, svuint32_t bases, svuint32_t data) + // ST1H Zdata.S, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void Scatter16BitNarrowing(Vector mask, Vector addresses, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1h_scatter[_u64base_u64](svbool_t pg, svuint64_t bases, svuint64_t data) + // ST1H Zdata.D, Pg, [Zbases.D, #0] + // + public static unsafe void Scatter16BitNarrowing(Vector mask, Vector addresses, Vector data) { throw new PlatformNotSupportedException(); } + + + // Truncate to 16 bits and store + + // + // void svst1h_scatter_[s32]offset[_s32](svbool_t pg, int16_t *base, svint32_t offsets, svint32_t data) + // ST1H Zdata.S, Pg, [Xbase, Zoffsets.S, SXTW] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, short* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1h_scatter_[u32]offset[_s32](svbool_t pg, int16_t *base, svuint32_t offsets, svint32_t data) + // ST1H Zdata.S, Pg, [Xbase, Zoffsets.S, UXTW] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, short* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1h_scatter_[s64]offset[_s64](svbool_t pg, int16_t *base, svint64_t offsets, svint64_t data) + // ST1H Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, short* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1h_scatter_[u64]offset[_s64](svbool_t pg, int16_t *base, svuint64_t offsets, svint64_t data) + // ST1H Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, short* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1h_scatter_[s32]offset[_u32](svbool_t pg, uint16_t *base, svint32_t offsets, svuint32_t data) + // ST1H Zdata.S, Pg, [Xbase, Zoffsets.S, SXTW] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, ushort* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1h_scatter_[u32]offset[_u32](svbool_t pg, uint16_t *base, svuint32_t offsets, svuint32_t data) + // ST1H Zdata.S, Pg, [Xbase, Zoffsets.S, UXTW] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, ushort* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1h_scatter_[s64]offset[_u64](svbool_t pg, uint16_t *base, svint64_t offsets, svuint64_t data) + // ST1H Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, ushort* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1h_scatter_[u64]offset[_u64](svbool_t pg, uint16_t *base, svuint64_t offsets, svuint64_t data) + // ST1H Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, ushort* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + + // Truncate to 32 bits and store + + // + // void svst1w_scatter[_u64base_s64](svbool_t pg, svuint64_t bases, svint64_t data) + // ST1W Zdata.D, Pg, [Zbases.D, #0] + // + public static unsafe void Scatter32BitNarrowing(Vector mask, Vector addresses, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1w_scatter[_u64base_u64](svbool_t pg, svuint64_t bases, svuint64_t data) + // ST1W Zdata.D, Pg, [Zbases.D, #0] + // + public static unsafe void Scatter32BitNarrowing(Vector mask, Vector addresses, Vector data) { throw new PlatformNotSupportedException(); } + + + // Truncate to 32 bits and store, non-temporal + + // + // void svstnt1w_scatter_[s64]offset[_s64](svbool_t pg, int32_t *base, svint64_t offsets, svint64_t data) + // STNT1W Zdata.D, Pg, [Zoffsets.D, Xbase] + // + public static unsafe void Scatter32BitWithByteOffsetsNarrowing(Vector mask, int* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svstnt1w_scatter_[u64]offset[_s64](svbool_t pg, int32_t *base, svuint64_t offsets, svint64_t data) + // STNT1W Zdata.D, Pg, [Zoffsets.D, Xbase] + // + public static unsafe void Scatter32BitWithByteOffsetsNarrowing(Vector mask, int* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svstnt1w_scatter_[s64]offset[_u64](svbool_t pg, uint32_t *base, svint64_t offsets, svuint64_t data) + // STNT1W Zdata.D, Pg, [Zoffsets.D, Xbase] + // + public static unsafe void Scatter32BitWithByteOffsetsNarrowing(Vector mask, uint* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svstnt1w_scatter_[u64]offset[_u64](svbool_t pg, uint32_t *base, svuint64_t offsets, svuint64_t data) + // STNT1W Zdata.D, Pg, [Zoffsets.D, Xbase] + // + public static unsafe void Scatter32BitWithByteOffsetsNarrowing(Vector mask, uint* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + + // Truncate to 8 bits and store + + // + // void svst1b_scatter[_u32base_s32](svbool_t pg, svuint32_t bases, svint32_t data) + // ST1B Zdata.S, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void Scatter8BitNarrowing(Vector mask, Vector addresses, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1b_scatter[_u64base_s64](svbool_t pg, svuint64_t bases, svint64_t data) + // ST1B Zdata.D, Pg, [Zbases.D, #0] + // + public static unsafe void Scatter8BitNarrowing(Vector mask, Vector addresses, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1b_scatter[_u32base_u32](svbool_t pg, svuint32_t bases, svuint32_t data) + // ST1B Zdata.S, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void Scatter8BitNarrowing(Vector mask, Vector addresses, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1b_scatter[_u64base_u64](svbool_t pg, svuint64_t bases, svuint64_t data) + // ST1B Zdata.D, Pg, [Zbases.D, #0] + // + public static unsafe void Scatter8BitNarrowing(Vector mask, Vector addresses, Vector data) { throw new PlatformNotSupportedException(); } + + + // Truncate to 8 bits and store + + // + // void svst1b_scatter_[s32]offset[_s32](svbool_t pg, int8_t *base, svint32_t offsets, svint32_t data) + // ST1B Zdata.S, Pg, [Xbase, Zoffsets.S, SXTW] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, sbyte* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1b_scatter_[u32]offset[_s32](svbool_t pg, int8_t *base, svuint32_t offsets, svint32_t data) + // ST1B Zdata.S, Pg, [Xbase, Zoffsets.S, UXTW] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, sbyte* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1b_scatter_[s64]offset[_s64](svbool_t pg, int8_t *base, svint64_t offsets, svint64_t data) + // ST1B Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, sbyte* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1b_scatter_[u64]offset[_s64](svbool_t pg, int8_t *base, svuint64_t offsets, svint64_t data) + // ST1B Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, sbyte* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1b_scatter_[s32]offset[_u32](svbool_t pg, uint8_t *base, svint32_t offsets, svuint32_t data) + // ST1B Zdata.S, Pg, [Xbase, Zoffsets.S, SXTW] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, byte* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1b_scatter_[u32]offset[_u32](svbool_t pg, uint8_t *base, svuint32_t offsets, svuint32_t data) + // ST1B Zdata.S, Pg, [Xbase, Zoffsets.S, UXTW] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, byte* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1b_scatter_[s64]offset[_u64](svbool_t pg, uint8_t *base, svint64_t offsets, svuint64_t data) + // ST1B Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, byte* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // + // void svst1b_scatter_[u64]offset[_u64](svbool_t pg, uint8_t *base, svuint64_t offsets, svuint64_t data) + // ST1B Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, byte* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + /// Logical shift left /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs index e87e90fc92e47f..930ae6afd2bdf0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs @@ -7332,6 +7332,208 @@ internal Arm64() { } public static unsafe void Scatter(Vector mask, ulong* address, Vector indicies, Vector data) => Scatter(mask, address, indicies, data); + // Truncate to 16 bits and store + + // + // void svst1h_scatter[_u32base_s32](svbool_t pg, svuint32_t bases, svint32_t data) + // ST1H Zdata.S, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void Scatter16BitNarrowing(Vector mask, Vector addresses, Vector data) => Scatter16BitNarrowing(mask, addresses, data); + + // + // void svst1h_scatter[_u64base_s64](svbool_t pg, svuint64_t bases, svint64_t data) + // ST1H Zdata.D, Pg, [Zbases.D, #0] + // + public static unsafe void Scatter16BitNarrowing(Vector mask, Vector addresses, Vector data) => Scatter16BitNarrowing(mask, addresses, data); + + // + // void svst1h_scatter[_u32base_u32](svbool_t pg, svuint32_t bases, svuint32_t data) + // ST1H Zdata.S, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void Scatter16BitNarrowing(Vector mask, Vector addresses, Vector data) => Scatter16BitNarrowing(mask, addresses, data); + + // + // void svst1h_scatter[_u64base_u64](svbool_t pg, svuint64_t bases, svuint64_t data) + // ST1H Zdata.D, Pg, [Zbases.D, #0] + // + public static unsafe void Scatter16BitNarrowing(Vector mask, Vector addresses, Vector data) => Scatter16BitNarrowing(mask, addresses, data); + + + // Truncate to 16 bits and store + + // + // void svst1h_scatter_[s32]offset[_s32](svbool_t pg, int16_t *base, svint32_t offsets, svint32_t data) + // ST1H Zdata.S, Pg, [Xbase, Zoffsets.S, SXTW] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, short* address, Vector offsets, Vector data) => Scatter16BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1h_scatter_[u32]offset[_s32](svbool_t pg, int16_t *base, svuint32_t offsets, svint32_t data) + // ST1H Zdata.S, Pg, [Xbase, Zoffsets.S, UXTW] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, short* address, Vector offsets, Vector data) => Scatter16BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1h_scatter_[s64]offset[_s64](svbool_t pg, int16_t *base, svint64_t offsets, svint64_t data) + // ST1H Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, short* address, Vector offsets, Vector data) => Scatter16BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1h_scatter_[u64]offset[_s64](svbool_t pg, int16_t *base, svuint64_t offsets, svint64_t data) + // ST1H Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, short* address, Vector offsets, Vector data) => Scatter16BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1h_scatter_[s32]offset[_u32](svbool_t pg, uint16_t *base, svint32_t offsets, svuint32_t data) + // ST1H Zdata.S, Pg, [Xbase, Zoffsets.S, SXTW] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, ushort* address, Vector offsets, Vector data) => Scatter16BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1h_scatter_[u32]offset[_u32](svbool_t pg, uint16_t *base, svuint32_t offsets, svuint32_t data) + // ST1H Zdata.S, Pg, [Xbase, Zoffsets.S, UXTW] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, ushort* address, Vector offsets, Vector data) => Scatter16BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1h_scatter_[s64]offset[_u64](svbool_t pg, uint16_t *base, svint64_t offsets, svuint64_t data) + // ST1H Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, ushort* address, Vector offsets, Vector data) => Scatter16BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1h_scatter_[u64]offset[_u64](svbool_t pg, uint16_t *base, svuint64_t offsets, svuint64_t data) + // ST1H Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(Vector mask, ushort* address, Vector offsets, Vector data) => Scatter16BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + + // Truncate to 32 bits and store + + // + // void svst1w_scatter[_u64base_s64](svbool_t pg, svuint64_t bases, svint64_t data) + // ST1W Zdata.D, Pg, [Zbases.D, #0] + // + public static unsafe void Scatter32BitNarrowing(Vector mask, Vector addresses, Vector data) => Scatter32BitNarrowing(mask, addresses, data); + + // + // void svst1w_scatter[_u64base_u64](svbool_t pg, svuint64_t bases, svuint64_t data) + // ST1W Zdata.D, Pg, [Zbases.D, #0] + // + public static unsafe void Scatter32BitNarrowing(Vector mask, Vector addresses, Vector data) => Scatter32BitNarrowing(mask, addresses, data); + + + // Truncate to 32 bits and store + + // + // void svst1w_scatter_[s64]offset[_s64](svbool_t pg, int32_t *base, svint64_t offsets, svint64_t data) + // ST1W Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter32BitWithByteOffsetsNarrowing(Vector mask, int* address, Vector offsets, Vector data) => Scatter32BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1w_scatter_[u64]offset[_s64](svbool_t pg, int32_t *base, svuint64_t offsets, svint64_t data) + // ST1W Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter32BitWithByteOffsetsNarrowing(Vector mask, int* address, Vector offsets, Vector data) => Scatter32BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1w_scatter_[s64]offset[_u64](svbool_t pg, uint32_t *base, svint64_t offsets, svuint64_t data) + // ST1W Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter32BitWithByteOffsetsNarrowing(Vector mask, uint* address, Vector offsets, Vector data) => Scatter32BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1w_scatter_[u64]offset[_u64](svbool_t pg, uint32_t *base, svuint64_t offsets, svuint64_t data) + // ST1W Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter32BitWithByteOffsetsNarrowing(Vector mask, uint* address, Vector offsets, Vector data) => Scatter32BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + + // Truncate to 8 bits and store + + // + // void svst1b_scatter[_u32base_s32](svbool_t pg, svuint32_t bases, svint32_t data) + // ST1B Zdata.S, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void Scatter8BitNarrowing(Vector mask, Vector addresses, Vector data) => Scatter8BitNarrowing(mask, addresses, data); + + // + // void svst1b_scatter[_u64base_s64](svbool_t pg, svuint64_t bases, svint64_t data) + // ST1B Zdata.D, Pg, [Zbases.D, #0] + // + public static unsafe void Scatter8BitNarrowing(Vector mask, Vector addresses, Vector data) => Scatter8BitNarrowing(mask, addresses, data); + + // + // void svst1b_scatter[_u32base_u32](svbool_t pg, svuint32_t bases, svuint32_t data) + // ST1B Zdata.S, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void Scatter8BitNarrowing(Vector mask, Vector addresses, Vector data) => Scatter8BitNarrowing(mask, addresses, data); + + // + // void svst1b_scatter[_u64base_u64](svbool_t pg, svuint64_t bases, svuint64_t data) + // ST1B Zdata.D, Pg, [Zbases.D, #0] + // + public static unsafe void Scatter8BitNarrowing(Vector mask, Vector addresses, Vector data) => Scatter8BitNarrowing(mask, addresses, data); + + + // Truncate to 8 bits and store + + // + // void svst1b_scatter_[s32]offset[_s32](svbool_t pg, int8_t *base, svint32_t offsets, svint32_t data) + // ST1B Zdata.S, Pg, [Xbase, Zoffsets.S, SXTW] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, sbyte* address, Vector offsets, Vector data) => Scatter8BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1b_scatter_[u32]offset[_s32](svbool_t pg, int8_t *base, svuint32_t offsets, svint32_t data) + // ST1B Zdata.S, Pg, [Xbase, Zoffsets.S, UXTW] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, sbyte* address, Vector offsets, Vector data) => Scatter8BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1b_scatter_[s64]offset[_s64](svbool_t pg, int8_t *base, svint64_t offsets, svint64_t data) + // ST1B Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, sbyte* address, Vector offsets, Vector data) => Scatter8BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1b_scatter_[u64]offset[_s64](svbool_t pg, int8_t *base, svuint64_t offsets, svint64_t data) + // ST1B Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, sbyte* address, Vector offsets, Vector data) => Scatter8BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1b_scatter_[s32]offset[_u32](svbool_t pg, uint8_t *base, svint32_t offsets, svuint32_t data) + // ST1B Zdata.S, Pg, [Xbase, Zoffsets.S, SXTW] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, byte* address, Vector offsets, Vector data) => Scatter8BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1b_scatter_[u32]offset[_u32](svbool_t pg, uint8_t *base, svuint32_t offsets, svuint32_t data) + // ST1B Zdata.S, Pg, [Xbase, Zoffsets.S, UXTW] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, byte* address, Vector offsets, Vector data) => Scatter8BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1b_scatter_[s64]offset[_u64](svbool_t pg, uint8_t *base, svint64_t offsets, svuint64_t data) + // ST1B Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, byte* address, Vector offsets, Vector data) => Scatter8BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + // + // void svst1b_scatter_[u64]offset[_u64](svbool_t pg, uint8_t *base, svuint64_t offsets, svuint64_t data) + // ST1B Zdata.D, Pg, [Xbase, Zoffsets.D] + // + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, byte* address, Vector offsets, Vector data) => Scatter8BitWithByteOffsetsNarrowing(mask, address, offsets, data); + + /// Logical shift left /// diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index fbe30cad8fdafc..13a0b2ee9695f6 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -5411,6 +5411,43 @@ internal Arm64() { } public static unsafe void Scatter(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } public static unsafe void Scatter(System.Numerics.Vector mask, ulong* address, System.Numerics.Vector indicies, System.Numerics.Vector data) { throw null; } + + // public static unsafe void Scatter16BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } + // public static unsafe void Scatter16BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } + + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, short* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, short* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, short* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, short* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, ushort* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, ushort* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, ushort* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, ushort* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + + public static unsafe void Scatter32BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter32BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } + + public static unsafe void Scatter32BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, int* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter32BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, int* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter32BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, uint* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter32BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, uint* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + + // public static unsafe void Scatter8BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter8BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } + // public static unsafe void Scatter8BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter8BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } + + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, sbyte* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, sbyte* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, sbyte* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, sbyte* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, byte* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, byte* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, byte* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter8BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, byte* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static System.Numerics.Vector ShiftLeftLogical(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector ShiftLeftLogical(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector ShiftLeftLogical(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 75efaa708a3157..d02ccf461648b9 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -4038,21 +4038,53 @@ ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Scale_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scale", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != Helpers.Scale(left[i], right[i])"}), ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Scale_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scale", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != Helpers.Scale(left[i], right[i])"}), + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter_bases_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()"}), ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter_bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter_bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveScatterVectorIndices.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetDouble()"}), - ("SveScatterVectorIndices.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetDouble()"}), - ("SveScatterVectorIndices.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), - ("SveScatterVectorIndices.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), - ("SveScatterVectorIndices.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), - ("SveScatterVectorIndices.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), - ("SveScatterVectorIndices.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetSingle()"}), - ("SveScatterVectorIndices.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetSingle()"}), - ("SveScatterVectorIndices.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveScatterVectorIndices.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveScatterVectorIndices.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveScatterVectorIndices.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetDouble()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetDouble()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetSingle()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetSingle()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + + // ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["NarrowingType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + // ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["NarrowingType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitNarrowing_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitNarrowing_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitWithByteOffset_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitWithByteOffset_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitWithByteOffset_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitWithByteOffset_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + // ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitNarrowing_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["NarrowingType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitNarrowing_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + // ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitNarrowing_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["NarrowingType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitNarrowing_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_sbyte_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(sbyte)Helpers.ShiftLeft((byte)left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "(sbyte)Helpers.ShiftLeft((byte)left[i], (ulong)right[i])"}), ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_short_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(short)Helpers.ShiftLeft((ushort)left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "(short)Helpers.ShiftLeft((ushort)left[i], (ulong)right[i])"}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveScatterVectorIndices.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveScatterVectorOffsets.template similarity index 98% rename from src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveScatterVectorIndices.template rename to src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveScatterVectorOffsets.template index 903e79e1f376b1..9b27b962166151 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveScatterVectorIndices.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveScatterVectorOffsets.template @@ -150,7 +150,7 @@ namespace JIT.HardwareIntrinsics.Arm._Sve if(!dict.Add(input[i])) { // value already exist - input[i] += 1; + input[i] = (input[i] + 1) % ({Op3BaseType})OutElementCount; continue; } i++; @@ -421,7 +421,7 @@ private void ValidateResult({Op1BaseType}[] mask, {Op1BaseType}[] data, {Op2Base { bool succeeded = true; - var actualResult = new {Op1BaseType}[DataElementCount]; + var actualResult = new {Op2BaseType}[DataElementCount]; for (var i = 0; i < DataElementCount; i++) { actualResult[i] = *({Op2BaseType}*)(baseAddr + offset[i]); @@ -430,7 +430,7 @@ private void ValidateResult({Op1BaseType}[] mask, {Op1BaseType}[] data, {Op2Base for (var i = 0; i < DataElementCount; i++) { {Op1BaseType} expectedResult = mask[i] == 0 ? 0 : data[i]; - if (actualResult[i] != expectedResult) + if (actualResult[i] != ({Op2BaseType})expectedResult) { succeeded = false; break; @@ -475,7 +475,7 @@ private void ValidateZeroResult(void* data, void* baseAddr, void* offset, [Calle private void ValidateZeroResult({Op1BaseType}[] data, {Op2BaseType}* baseAddr, {Op3BaseType}[] offset, [CallerMemberName] string method = "") { bool succeeded = true; - var actualResult = new {Op1BaseType}[DataElementCount]; + var actualResult = new {Op2BaseType}[DataElementCount]; for (var i = 0; i < DataElementCount; i++) { actualResult[i] = *({Op2BaseType}*)(baseAddr + offset[i]); From e0bb71434f9720c00e54e75d20e9d63f819b26e9 Mon Sep 17 00:00:00 2001 From: Jacob Bundgaard Date: Mon, 15 Jul 2024 22:21:40 +0200 Subject: [PATCH 15/30] Fix incorrect reference to compiler-generated field for primary constructor parameter in LoggerMessageGenerator (#104899) Co-authored-by: Tarek Mahmoud Sayed --- .../gen/LoggerMessageGenerator.Parser.cs | 4 ++++ ...torWithParameterUsedInMethod.generated.txt | 21 +++++++++++++++++++ .../LoggerMessageGeneratedCodeTests.cs | 11 ++++++++++ .../LoggerMessageGeneratorEmitterTests.cs | 20 ++++++++++++++++++ .../LoggerMessageGeneratorParserTests.cs | 19 +++++++++++++++++ .../TestClasses/MiscTestExtensions.cs | 11 ++++++++++ 6 files changed, 86 insertions(+) create mode 100644 src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithLoggerFromPrimaryConstructorWithParameterUsedInMethod.generated.txt diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs index b474c5ea54a150..73e347d067112e 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs @@ -652,6 +652,10 @@ private static string GenerateClassName(TypeDeclarationSyntax typeDeclaration) { continue; } + if (!fs.CanBeReferencedByName) + { + continue; + } if (IsBaseOrIdentity(fs.Type, loggerSymbol)) { if (loggerField == null) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithLoggerFromPrimaryConstructorWithParameterUsedInMethod.generated.txt b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithLoggerFromPrimaryConstructorWithParameterUsedInMethod.generated.txt new file mode 100644 index 00000000000000..4fc0f50d5c735b --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithLoggerFromPrimaryConstructorWithParameterUsedInMethod.generated.txt @@ -0,0 +1,21 @@ +// +#nullable enable + +namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses +{ + partial class TestWithLoggerFromPrimaryConstructorWithParameterUsedInMethod + { + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "%VERSION%")] + private static readonly global::System.Action __M0Callback = + global::Microsoft.Extensions.Logging.LoggerMessage.Define(global::Microsoft.Extensions.Logging.LogLevel.Debug, new global::Microsoft.Extensions.Logging.EventId(0, nameof(M0)), "M0", new global::Microsoft.Extensions.Logging.LogDefineOptions() { SkipEnabledCheck = true }); + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "%VERSION%")] + public partial void M0() + { + if (logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Debug)) + { + __M0Callback(logger, null); + } + } + } +} \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs index 1013af8ae36722..ceac90cc93c3ba 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs @@ -48,6 +48,17 @@ public void FindsLoggerInPrimaryConstructorParameter() Assert.Equal("Test.", logger.LastFormattedString); } + [Fact] + public void FindsLoggerInPrimaryConstructorParameterUsedInMethod() + { + var logger = new MockLogger(); + + logger.Reset(); + + new ClassWithPrimaryConstructorWithParameterUsedInMethod(logger).Test(); + Assert.Equal("Test.", logger.LastFormattedString); + } + [Fact] public void FindsLoggerInPrimaryConstructorParameterInDifferentPartialDeclaration() { diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorEmitterTests.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorEmitterTests.cs index 0952f66a8adabb..5f8dc5f9ca20ed 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorEmitterTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorEmitterTests.cs @@ -203,6 +203,26 @@ internal partial class TestWithLoggerFromPrimaryConstructor(ILogger logger) await VerifyAgainstBaselineUsingFile("TestWithLoggerFromPrimaryConstructor.generated.txt", testSourceCode); } + [Fact] + public async Task TestBaseline_TestWithLoggerFromPrimaryConstructorWithParameterUsedInMethod_Success() + { + string testSourceCode = @" +namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses +{ + internal partial class TestWithLoggerFromPrimaryConstructorWithParameterUsedInMethod(ILogger logger) + { + [LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = ""M0"")] + public partial void M0(); + + private void M1() + { + logger.LogInformation(""M1""); + } + } +}"; + await VerifyAgainstBaselineUsingFile("TestWithLoggerFromPrimaryConstructorWithParameterUsedInMethod.generated.txt", testSourceCode); + } + [Fact] public async Task TestBaseline_TestWithLoggerInFieldAndFromPrimaryConstructor_UsesField() { diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs index 15a4f965074775..7249600f515c43 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs @@ -456,6 +456,25 @@ partial class C(ILogger logger) Assert.Empty(diagnostics); } + [Fact] + public async Task PrimaryConstructorWithParameterUsedInMethodOK() + { + IReadOnlyList diagnostics = await RunGenerator(@" + partial class C(ILogger logger) + { + [LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = ""M1"")] + public partial void M1(); + + private void M2() + { + logger.LogInformation(""M2""); + } + } + "); + + Assert.Empty(diagnostics); + } + [Fact] public async Task PrimaryConstructorOnOtherPartialDeclarationOK() { diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/MiscTestExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/MiscTestExtensions.cs index 5f4fec36ac7b77..09e481f99badad 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/MiscTestExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/MiscTestExtensions.cs @@ -64,6 +64,17 @@ public partial class ClassWithPrimaryConstructor(ILogger logger) public partial void Test(); } +public partial class ClassWithPrimaryConstructorWithParameterUsedInMethod(ILogger logger) +{ + [LoggerMessage(0, LogLevel.Debug, "Test.")] + public partial void Test(); + + private void OtherLoggerUse() + { + logger.LogInformation("Other logger use."); + } +} + public partial class ClassWithPrimaryConstructorInDifferentPartialDeclaration(ILogger logger); public partial class ClassWithPrimaryConstructorInDifferentPartialDeclaration From dcfd52b67f239e38aa99174f5042186e06d13975 Mon Sep 17 00:00:00 2001 From: Austin Wise Date: Mon, 15 Jul 2024 13:22:08 -0700 Subject: [PATCH 16/30] illumos: set default timezone info path (#104533) This is where these files live on OpenIndiana and SmartOS. Co-authored-by: Tarek Mahmoud Sayed --- .../System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs index d0ba5fc6e9316b..4951f7829e7943 100644 --- a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs @@ -16,7 +16,11 @@ namespace System { public sealed partial class TimeZoneInfo { +#if TARGET_ILLUMOS || TARGET_SOLARIS + private const string DefaultTimeZoneDirectory = "/usr/share/lib/zoneinfo/"; +#else private const string DefaultTimeZoneDirectory = "/usr/share/zoneinfo/"; +#endif // Set fallback values using abbreviations, base offset, and id // These are expected in environments without time zone globalization data From ad542b244bea3b453a6bda6b59440182c6c14ef2 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Mon, 15 Jul 2024 23:09:44 +0200 Subject: [PATCH 17/30] [wasm] emscripten bump 3.1.56 (#100334) * [wasm] Bump emscripten to 3.1.56 * Replace Module.asm with Module.wasmExports Module.asm was removed, use wasmExports instead. Context: https://github.com/emscripten-core/emscripten/pull/19816 * Updates for .native.worker.js -> mjs rename Context: https://github.com/emscripten-core/emscripten/pull/21041 * Update deps * Add general testing feed * Update mode deps * Update path * Use current python packages for now, we don't have newer ones The current names 3.1.34 are new enough * Keep using llvm 16 for runtime and aot compiler * Add -Wno-pre-c11-compat only for browser * Temporarily disable version checks to get further * Temporarily disable version checks to get further #2 * Disable -Wunused-command-line-argument * Update emsdk deps * Update icu dependency * Revert "Temporarily disable version checks to get further #2" This reverts commit 3f8834f2a83405bdb46ffe4ae46560ce7c8755e3. * Revert "Temporarily disable version checks to get further" This reverts commit fe1e5c643c6ab4bbfeb1af06f1f13492722825b9. * Fix emsdk check We use system python on osx too * Workaround wasm-opt crash * Workaround wasm-opt crash * Workaround wasm-opt crash * Fix WBT test * Feedback * Update ICU dependency * Update emscripten deps * Revert "Workaround wasm-opt crash" This reverts commit 200cf3b3915d7e308414387628049cc710196992. * Revert "Workaround wasm-opt crash" This reverts commit 4530edfdcc64dd60d16f276a58fb7e3e5ede867d. * Revert "Workaround wasm-opt crash" This reverts commit 3593c41798f6c667a1778859f5576d8cfc723d5d. * Increase tests timeout * Show test progress * Increase MT library tests timeout * Disable WBT tests with SkiaSharp * Increase helix tests timeout on browser * Increase WBT timeout * Increase initial heap sizes * Fix mono_wasm_load_runtime cwrap signature Fixes: `Uncaught ExitStatus: Assertion failed: stringToUTF8Array expects a string (got number)` * Enable XunitShowProgress for threading tasks tests * Try to reduce number of parallel AOT compilations To check whether it will improve memory issues on CI * Use new docker image for helix/windows tests * Revert "Try to reduce number of parallel AOT compilations" This reverts commit 5d9a6d2352e1df268a591320ac36ed62b71f8c91. * Reduce the timeouts * Reduce intitial heap size * use active issues for MT * Remove testing channel from nuget config, update deps * Update emsdk and icu dependencies --------- Co-authored-by: Larry Ewing Co-authored-by: pavelsavara --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- eng/liveBuilds.targets | 4 ++-- eng/pipelines/libraries/helix-queues-setup.yml | 2 +- .../Microsoft.NETCore.App/Directory.Build.props | 2 +- .../System.Buffers.Tests.csproj | 1 + .../System.Threading.Tasks.Tests.csproj | 1 + src/libraries/sendtohelixhelp.proj | 1 + src/mono/browser/browser.proj | 11 +++++++---- src/mono/browser/build/BrowserWasmApp.targets | 6 +++--- src/mono/browser/emscripten-version.txt | 2 +- src/mono/browser/runtime/CMakeLists.txt | 2 +- src/mono/browser/runtime/cwraps.ts | 6 +++--- src/mono/browser/runtime/es6/dotnet.es6.pre.js | 2 +- src/mono/browser/runtime/jiterpreter-jit-call.ts | 2 +- src/mono/browser/runtime/jiterpreter-support.ts | 4 ++-- src/mono/browser/runtime/loader/assets.ts | 1 + src/mono/browser/runtime/pthreads/ui-thread.ts | 1 + src/mono/browser/runtime/types/internal.ts | 2 +- .../wasm/Wasm.Build.Tests/Blazor/MiscTests.cs | 1 + src/mono/wasm/Wasm.Build.Tests/BuildTestBase.cs | 2 +- .../Wasm.Build.Tests/Common/BuildEnvironment.cs | 2 +- .../wasm/Wasm.Build.Tests/NativeLibraryTests.cs | 1 + .../TestMainJsProjectProvider.cs | 6 +++--- .../WasmSdkBasedProjectProvider.cs | 8 ++++---- src/mono/wasm/build/WasmApp.Common.targets | 2 +- ...ntsWebAssemblyApplicationBuilderExtensions.cs | 1 + .../WasmOnAspNetCore/AspNetCoreServer/Program.cs | 1 + src/native/libs/CMakeLists.txt | 4 ++++ .../AssetsComputingHelper.cs | 3 ++- .../BootJsonBuilderHelper.cs | 2 +- .../ComputeWasmBuildAssets.cs | 5 +++-- .../ComputeWasmPublishAssets.cs | 16 +++++++++------- src/tasks/WasmAppBuilder/WasmAppBuilder.cs | 2 +- 34 files changed, 72 insertions(+), 52 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 32b119ad8b537e..8229ab31c89688 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/icu - 42787a07ecba682549f520293bb5a6941bdccb50 + c8db7547bc0a021ffd262b3449f5b0343894b32b https://github.com/dotnet/msquic @@ -68,14 +68,14 @@ 7e4af02521473d89d6144b3da58fef253e498974 - + https://github.com/dotnet/emsdk - d3583522209829d1ed0440662ba136c7b7700b16 + 99ea0c06b84d3084d090da537080dd35d2a193cf - + https://github.com/dotnet/emsdk - d3583522209829d1ed0440662ba136c7b7700b16 + 99ea0c06b84d3084d090da537080dd35d2a193cf diff --git a/eng/Versions.props b/eng/Versions.props index 8b19e3de2d1290..b9b6c8e08186d5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -216,7 +216,7 @@ 9.0.0-preview.7.24357.2 - 9.0.0-preview.7.24358.1 + 9.0.0-preview.7.24365.2 2.3.5 9.0.0-alpha.1.24167.3 @@ -239,7 +239,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-9_0_100_Transport --> - 9.0.0-preview.7.24352.2 + 9.0.0-preview.7.24365.1 $(MicrosoftNETWorkloadEmscriptenCurrentManifest90100TransportVersion) 9.0.0-preview.7.24352.2 @@ -262,6 +262,6 @@ 9.0.0-alpha.1.24175.1 $(MicrosoftNETRuntimeEmscriptenVersion) $(runtimewinx64MicrosoftNETCoreRuntimeWasmNodeTransportPackageVersion) - 3.1.34 + 3.1.56 diff --git a/eng/liveBuilds.targets b/eng/liveBuilds.targets index fce021e7b99702..db8aee3799b440 100644 --- a/eng/liveBuilds.targets +++ b/eng/liveBuilds.targets @@ -215,9 +215,9 @@ $(LibrariesNativeArtifactsPath)segmentation-rules.json;" IsNative="true" /> - - + diff --git a/src/libraries/System.Runtime/tests/System.Buffers.Tests/System.Buffers.Tests.csproj b/src/libraries/System.Runtime/tests/System.Buffers.Tests/System.Buffers.Tests.csproj index 66ae6833a50eb5..113d56e6f43635 100644 --- a/src/libraries/System.Runtime/tests/System.Buffers.Tests/System.Buffers.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Buffers.Tests/System.Buffers.Tests.csproj @@ -6,6 +6,7 @@ $(NetCoreAppCurrent) + true 1 diff --git a/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/System.Threading.Tasks.Tests.csproj b/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/System.Threading.Tasks.Tests.csproj index 4b916c09bb4b35..2f832312d7e2df 100644 --- a/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/System.Threading.Tasks.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/System.Threading.Tasks.Tests.csproj @@ -6,6 +6,7 @@ <_WasmPThreadPoolUnusedSize>10 + true diff --git a/src/libraries/sendtohelixhelp.proj b/src/libraries/sendtohelixhelp.proj index 3608f1cae63d0d..81a3ac4d710978 100644 --- a/src/libraries/sendtohelixhelp.proj +++ b/src/libraries/sendtohelixhelp.proj @@ -39,6 +39,7 @@ '$(Scenario)' == 'gcstress0xc_jitminopts_heapverify1'">06:00:00 <_workItemTimeout Condition="'$(_workItemTimeout)' == '' and '$(TargetsAppleMobile)' == 'true'">01:15:00 <_workItemTimeout Condition="'$(_workItemTimeout)' == '' and '$(TargetOS)' == 'android'">00:30:00 + <_workItemTimeout Condition="'$(_workItemTimeout)' == '' and '$(TargetOS)' == 'browser'">00:30:00 <_workItemTimeout Condition="'$(Scenario)' == '' and '$(_workItemTimeout)' == '' and ('$(TargetArchitecture)' == 'arm64' or '$(TargetArchitecture)' == 'arm')">00:45:00 <_workItemTimeout Condition="'$(Scenario)' != '' and '$(_workItemTimeout)' == '' and ('$(TargetArchitecture)' == 'arm64' or '$(TargetArchitecture)' == 'arm')">01:00:00 <_workItemTimeout Condition="'$(Scenario)' == '' and '$(_workItemTimeout)' == '' and ('$(TestScope)' == 'outerloop' or '$(TestScope)' == 'all')">00:20:00 diff --git a/src/mono/browser/browser.proj b/src/mono/browser/browser.proj index 47a351fb53b415..e9923f10d4831a 100644 --- a/src/mono/browser/browser.proj +++ b/src/mono/browser/browser.proj @@ -217,6 +217,8 @@ + + @@ -277,6 +279,7 @@ 5MB + <_EmccLinkFlags Include="-Wno-unused-command-line-argument" /> <_EmccLinkFlags Include="-s INITIAL_MEMORY=$(EmccInitialHeapSize)" /> <_EmccLinkFlags Include="-s STACK_SIZE=$(EmccStackSize)" /> <_EmccCommonFlags Condition="'$(WasmEnableThreads)' == 'true'" Include="-s USE_PTHREADS=1" /> @@ -294,7 +297,7 @@ <_EmccLinkFlags Include="--source-map-base http://example.com" /> <_EmccLinkFlags Include="-s WASM_BIGINT=1" /> <_EmccLinkFlags Include="-s EXPORT_NAME="'createDotnetRuntime'"" /> - <_EmccLinkFlags Include="-s MODULARIZE=1"/> + <_EmccLinkFlags Include="-s MODULARIZE=1" /> <_EmccLinkFlags Include="-s ENVIRONMENT="web,webview,worker,node,shell"" /> - + https://github.com/dotnet/roslyn - 19b5e961ecb97b008106f1b646c077e0bffde4a7 + cada394f99c521861c39e2a5334678e6aba1ac62 diff --git a/eng/Versions.props b/eng/Versions.props index b9b6c8e08186d5..526206c9b3c20a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -42,9 +42,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.12.0-1.24355.3 - 4.12.0-1.24355.3 - 4.12.0-1.24355.3 + 4.12.0-1.24362.11 + 4.12.0-1.24362.11 + 4.12.0-1.24362.11 reg3 - // reg1 = reg3 + (reg1 * reg2) // swap reg1 <--> reg2 - // reg1 = (reg1 * reg2) + reg3 // rearrange to get FMAD format - // - // Case# 3: Result is stored in the operand `op3` that held the "multiplier" - // targetReg == reg3 - // - // So we basically have an operation: - // reg3 = reg1 + (reg2 * reg3) - // Since, the result will be stored in the "multiplier", we again pick format `FMAD`. - // Then, we rearrange the operands to ensure that the operation is done correctly. - // reg3 = reg1 + (reg2 * reg3) // to start with - // reg1 = reg3 + (reg2 * reg1) // swap reg1 <--> reg3 - // reg1 = (reg1 * reg2) + reg3 // rearrange to get FMAD format - - bool useAddend = true; - if (targetReg == embMaskOp2Reg) - { - // Case# 2 - useAddend = false; - std::swap(embMaskOp1Reg, embMaskOp3Reg); - std::swap(embMaskOp1Reg, embMaskOp2Reg); - } - else if (targetReg == embMaskOp3Reg) - { - // Case# 3 - useAddend = false; - std::swap(embMaskOp1Reg, embMaskOp3Reg); - } - else + if (HWIntrinsicInfo::IsFmaIntrinsic(intrinEmbMask.id)) { - // Case# 1 - } + assert(falseReg != embMaskOp3Reg); + // For FMA, the operation we are trying to perform is: + // result = op1 + (op2 * op3) + // + // There are two instructions that can be used depending on which operand's register, + // optionally, will store the final result. + // + // 1. If the result is stored in the operand that was used as an "addend" in the operation, + // then we use `FMLA` format: + // reg1 = reg1 + (reg2 * reg3) + // + // 2. If the result is stored in the operand that was used as a "multiplicand" in the operation, + // then we use `FMAD` format: + // reg1 = (reg1 * reg2) + reg3 + // + // Check if the result's register is same as that of one of the operand's register and + // accordingly pick the appropriate format. Suppose `targetReg` holds the result, then we have + // following cases: + // + // Case# 1: Result is stored in the operand that held the "addend" + // targetReg == reg1 + // + // We generate the FMLA instruction format and no further changes are needed. + // + // Case# 2: Result is stored in the operand `op2` that held the "multiplicand" + // targetReg == reg2 + // + // So we basically have an operation: + // reg2 = reg1 + (reg2 * reg3) + // + // Since, the result will be stored in the "multiplicand", we pick format `FMAD`. + // Then, we rearrange the operands to ensure that the operation is done correctly. + // reg2 = reg1 + (reg2 * reg3) // to start with + // reg2 = reg3 + (reg2 * reg1) // swap reg1 <--> reg3 + // reg1 = reg3 + (reg1 * reg2) // swap reg1 <--> reg2 + // reg1 = (reg1 * reg2) + reg3 // rearrange to get FMAD format + // + // Case# 3: Result is stored in the operand `op3` that held the "multiplier" + // targetReg == reg3 + // + // So we basically have an operation: + // reg3 = reg1 + (reg2 * reg3) + // Since, the result will be stored in the "multiplier", we again pick format `FMAD`. + // Then, we rearrange the operands to ensure that the operation is done correctly. + // reg3 = reg1 + (reg2 * reg3) // to start with + // reg1 = reg3 + (reg2 * reg1) // swap reg1 <--> reg3 + // reg1 = (reg1 * reg2) + reg3 // rearrange to get FMAD format + + bool useAddend = true; + if (targetReg == embMaskOp2Reg) + { + // Case# 2 + useAddend = false; + std::swap(embMaskOp1Reg, embMaskOp3Reg); + std::swap(embMaskOp1Reg, embMaskOp2Reg); + } + else if (targetReg == embMaskOp3Reg) + { + // Case# 3 + useAddend = false; + std::swap(embMaskOp1Reg, embMaskOp3Reg); + } + else + { + // Case# 1 + } - switch (intrinEmbMask.id) - { - case NI_Sve_FusedMultiplyAdd: - insEmbMask = useAddend ? INS_sve_fmla : INS_sve_fmad; - break; + switch (intrinEmbMask.id) + { + case NI_Sve_FusedMultiplyAdd: + insEmbMask = useAddend ? INS_sve_fmla : INS_sve_fmad; + break; - case NI_Sve_FusedMultiplyAddNegated: - insEmbMask = useAddend ? INS_sve_fnmla : INS_sve_fnmad; - break; + case NI_Sve_FusedMultiplyAddNegated: + insEmbMask = useAddend ? INS_sve_fnmla : INS_sve_fnmad; + break; - case NI_Sve_FusedMultiplySubtract: - insEmbMask = useAddend ? INS_sve_fmls : INS_sve_fmsb; - break; + case NI_Sve_FusedMultiplySubtract: + insEmbMask = useAddend ? INS_sve_fmls : INS_sve_fmsb; + break; - case NI_Sve_FusedMultiplySubtractNegated: - insEmbMask = useAddend ? INS_sve_fnmls : INS_sve_fnmsb; - break; + case NI_Sve_FusedMultiplySubtractNegated: + insEmbMask = useAddend ? INS_sve_fnmls : INS_sve_fnmsb; + break; - case NI_Sve_MultiplyAdd: - insEmbMask = useAddend ? INS_sve_mla : INS_sve_mad; - break; + case NI_Sve_MultiplyAdd: + insEmbMask = useAddend ? INS_sve_mla : INS_sve_mad; + break; - case NI_Sve_MultiplySubtract: - insEmbMask = useAddend ? INS_sve_mls : INS_sve_msb; - break; + case NI_Sve_MultiplySubtract: + insEmbMask = useAddend ? INS_sve_mls : INS_sve_msb; + break; - default: - unreached(); + default: + unreached(); + } } - if (intrin.op3->IsVectorZero()) - { - // If `falseReg` is zero, then move the first operand of `intrinEmbMask` in the - // destination using /Z. + emitEmbeddedMaskSetup(); - assert(targetReg != embMaskOp2Reg); - assert(intrin.op3->isContained() || !intrin.op1->IsMaskAllBitsSet()); - GetEmitter()->emitIns_R_R_R(INS_sve_movprfx, emitSize, targetReg, maskReg, embMaskOp1Reg, opt); + // Finally, perform the desired operation. + if (HWIntrinsicInfo::HasImmediateOperand(intrinEmbMask.id)) + { + HWIntrinsicImmOpHelper helper(this, intrinEmbMask.op3, op2->AsHWIntrinsic()); + for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) + { + GetEmitter()->emitInsSve_R_R_R_I(insEmbMask, emitSize, targetReg, maskReg, embMaskOp2Reg, + helper.ImmValue(), opt); + } } else { - // Below are the considerations we need to handle: - // - // targetReg == falseReg && targetReg == embMaskOp1Reg - // fmla Zd, P/m, Zn, Zm - // - // targetReg == falseReg && targetReg != embMaskOp1Reg - // movprfx target, P/m, embMaskOp1Reg - // fmla target, P/m, embMaskOp2Reg, embMaskOp3Reg - // - // targetReg != falseReg && targetReg == embMaskOp1Reg - // sel target, P/m, embMaskOp1Reg, falseReg - // fmla target, P/m, embMaskOp2Reg, embMaskOp3Reg - // - // targetReg != falseReg && targetReg != embMaskOp1Reg - // sel target, P/m, embMaskOp1Reg, falseReg - // fmla target, P/m, embMaskOp2Reg, embMaskOp3Reg - // - // Note that, we just check if the targetReg/falseReg or targetReg/embMaskOp1Reg - // coincides or not. + assert(HWIntrinsicInfo::IsFmaIntrinsic(intrinEmbMask.id)); + GetEmitter()->emitInsSve_R_R_R_R(insEmbMask, emitSize, targetReg, maskReg, embMaskOp2Reg, + embMaskOp3Reg, opt); + } - if (targetReg != falseReg) - { - if (falseReg == embMaskOp1Reg) - { - // If falseReg value and embMaskOp1Reg value are same, then just mov the value - // to the target. + break; + } - GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, embMaskOp1Reg, - /* canSkip */ true); - } - else - { - // If falseReg value is not present in targetReg yet, move the inactive lanes - // into the targetReg using `sel`. Since this is RMW, the active lanes should - // have the value from embMaskOp1Reg + case 4: + { + assert(instrIsRMW); + assert(intrinEmbMask.op4->isContained() == (embMaskOp4Reg == REG_NA)); + assert(HWIntrinsicInfo::HasImmediateOperand(intrinEmbMask.id)); - GetEmitter()->emitIns_R_R_R_R(INS_sve_sel, emitSize, targetReg, maskReg, embMaskOp1Reg, - falseReg, opt); - } - } - else if (targetReg != embMaskOp1Reg) - { - // If target already contains the values of `falseReg`, just merge the lanes from - // `embMaskOp1Reg`, again because this is RMW semantics. + emitEmbeddedMaskSetup(); - GetEmitter()->emitIns_R_R_R(INS_sve_movprfx, emitSize, targetReg, maskReg, embMaskOp1Reg, - opt, INS_SCALABLE_OPTS_PREDICATE_MERGE); - } + HWIntrinsicImmOpHelper helper(this, intrinEmbMask.op4, op2->AsHWIntrinsic()); + for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) + { + GetEmitter()->emitInsSve_R_R_R_R_I(insEmbMask, emitSize, targetReg, maskReg, embMaskOp2Reg, + embMaskOp3Reg, helper.ImmValue(), opt); } - // Finally, perform the desired operation. - GetEmitter()->emitIns_R_R_R_R(insEmbMask, emitSize, targetReg, maskReg, embMaskOp2Reg, - embMaskOp3Reg, opt); - break; } + default: unreached(); } diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index e3a1d979b7fd38..c7df23557516e7 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -24,6 +24,7 @@ HARDWARE_INTRINSIC(Sve, AbsoluteCompareLessThanOrEqual, HARDWARE_INTRINSIC(Sve, AbsoluteDifference, -1, -1, false, {INS_sve_sabd, INS_sve_uabd, INS_sve_sabd, INS_sve_uabd, INS_sve_sabd, INS_sve_uabd, INS_sve_sabd, INS_sve_uabd, INS_sve_fabd, INS_sve_fabd}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Add, -1, -1, false, {INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_fadd, INS_sve_fadd}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, AddAcross, -1, 1, true, {INS_sve_saddv, INS_sve_uaddv, INS_sve_saddv, INS_sve_uaddv, INS_sve_saddv, INS_sve_uaddv, INS_sve_uaddv, INS_sve_uaddv, INS_sve_faddv, INS_sve_faddv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, AddRotateComplex, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcadd, INS_sve_fcadd}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand) HARDWARE_INTRINSIC(Sve, AddSaturate, -1, 2, true, {INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, AddSequentialAcross, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fadda, INS_sve_fadda}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve, And, -1, -1, false, {INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) @@ -186,6 +187,7 @@ HARDWARE_INTRINSIC(Sve, MinNumber, HARDWARE_INTRINSIC(Sve, MinNumberAcross, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fminnmv, INS_sve_fminnmv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Multiply, -1, 2, true, {INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_fmul, INS_sve_fmul}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, MultiplyAdd, -1, -1, false, {INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation|HW_Flag_FmaIntrinsic|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Sve, MultiplyAddRotateComplex, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcmla, INS_sve_fcmla}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand) HARDWARE_INTRINSIC(Sve, MultiplyBySelectedScalar, -1, 3, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmul, INS_sve_fmul}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) HARDWARE_INTRINSIC(Sve, MultiplyExtended, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmulx, INS_sve_fmulx}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, MultiplySubtract, -1, -1, false, {INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation|HW_Flag_FmaIntrinsic|HW_Flag_SpecialCodeGen) diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 3ecc41f20d99f7..2ae67d5899b97d 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -3434,6 +3434,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_PrefetchInt32: case NI_Sve_PrefetchInt64: case NI_Sve_ExtractVector: + case NI_Sve_AddRotateComplex: case NI_Sve_TrigonometricMultiplyAddCoefficient: assert(hasImmediateOperand); assert(varTypeIsIntegral(intrin.op3)); @@ -3638,6 +3639,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_FusedMultiplyAddBySelectedScalar: case NI_Sve_FusedMultiplySubtractBySelectedScalar: + case NI_Sve_MultiplyAddRotateComplex: assert(hasImmediateOperand); assert(varTypeIsIntegral(intrin.op4)); if (intrin.op4->IsCnsIntOrI()) diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index 7a02286440df26..266cb47537d50a 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -1943,18 +1943,44 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou } else { - assert((numArgs == 1) || (numArgs == 2) || (numArgs == 3)); + const bool embHasImmediateOperand = HWIntrinsicInfo::HasImmediateOperand(intrinEmb.id); + assert((numArgs == 1) || (numArgs == 2) || (numArgs == 3) || (embHasImmediateOperand && (numArgs == 4))); - // Special handling for ShiftRightArithmeticForDivide: + // Special handling for embedded intrinsics with immediates: // We might need an additional register to hold branch targets into the switch table // that encodes the immediate - if (intrinEmb.id == NI_Sve_ShiftRightArithmeticForDivide) + switch (intrinEmb.id) { - assert(embOp2Node->GetOperandCount() == 2); - if (!embOp2Node->Op(2)->isContainedIntOrIImmed()) - { - buildInternalIntRegisterDefForNode(embOp2Node); - } + case NI_Sve_ShiftRightArithmeticForDivide: + assert(embHasImmediateOperand); + assert(numArgs == 2); + if (!embOp2Node->Op(2)->isContainedIntOrIImmed()) + { + buildInternalIntRegisterDefForNode(embOp2Node); + } + break; + + case NI_Sve_AddRotateComplex: + assert(embHasImmediateOperand); + assert(numArgs == 3); + if (!embOp2Node->Op(3)->isContainedIntOrIImmed()) + { + buildInternalIntRegisterDefForNode(embOp2Node); + } + break; + + case NI_Sve_MultiplyAddRotateComplex: + assert(embHasImmediateOperand); + assert(numArgs == 4); + if (!embOp2Node->Op(4)->isContainedIntOrIImmed()) + { + buildInternalIntRegisterDefForNode(embOp2Node); + } + break; + + default: + assert(!embHasImmediateOperand); + break; } tgtPrefUse = BuildUse(embOp2Node->Op(1)); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs index 736b3fd1484fd1..81863a057638d5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs @@ -347,6 +347,26 @@ internal Arm64() { } /// public static unsafe Vector AddAcross(Vector value) { throw new PlatformNotSupportedException(); } + /// Complex add with rotate + + /// + /// svfloat64_t svcadd[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D, #imm_rotation + /// svfloat64_t svcadd[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D, #imm_rotation + /// svfloat64_t svcadd[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2, uint64_t imm_rotation) + /// + public static unsafe Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svcadd[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S, #imm_rotation + /// svfloat32_t svcadd[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S, #imm_rotation + /// svfloat32_t svcadd[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2, uint64_t imm_rotation) + /// + public static unsafe Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw new PlatformNotSupportedException(); } + /// AddSaturate : Saturating add /// @@ -5717,6 +5737,26 @@ internal Arm64() { } /// public static unsafe Vector MultiplyAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + /// Complex multiply-add with rotate + + /// + /// svfloat64_t svcmla[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.D, Pg/M, Zop2.D, Zop3.D, #imm_rotation + /// svfloat64_t svcmla[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.D, Pg/M, Zop2.D, Zop3.D, #imm_rotation + /// svfloat64_t svcmla[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3, uint64_t imm_rotation) + /// + public static unsafe Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svcmla[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.S, Pg/M, Zop2.S, Zop3.S, #imm_rotation + /// svfloat32_t svcmla[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.S, Pg/M, Zop2.S, Zop3.S, #imm_rotation + /// svfloat32_t svcmla[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3, uint64_t imm_rotation) + /// + public static unsafe Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + /// MultiplyBySelectedScalar : Multiply /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs index 930ae6afd2bdf0..73d4c556249fb6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs @@ -377,6 +377,26 @@ internal Arm64() { } /// public static unsafe Vector AddAcross(Vector value) => AddAcross(value); + /// Complex add with rotate + + /// + /// svfloat64_t svcadd[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D, #imm_rotation + /// svfloat64_t svcadd[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D, #imm_rotation + /// svfloat64_t svcadd[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2, uint64_t imm_rotation) + /// + public static unsafe Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddRotateComplex(left, right, rotation); + + /// + /// svfloat32_t svcadd[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S, #imm_rotation + /// svfloat32_t svcadd[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S, #imm_rotation + /// svfloat32_t svcadd[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2, uint64_t imm_rotation) + /// + public static unsafe Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddRotateComplex(left, right, rotation); + /// AddSaturate : Saturating add /// @@ -5773,6 +5793,26 @@ internal Arm64() { } /// public static unsafe Vector MultiplyAdd(Vector addend, Vector left, Vector right) => MultiplyAdd(addend, left, right); + /// Complex multiply-add with rotate + + /// + /// svfloat64_t svcmla[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.D, Pg/M, Zop2.D, Zop3.D, #imm_rotation + /// svfloat64_t svcmla[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.D, Pg/M, Zop2.D, Zop3.D, #imm_rotation + /// svfloat64_t svcmla[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3, uint64_t imm_rotation) + /// + public static unsafe Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplex(addend, left, right, rotation); + + /// + /// svfloat32_t svcmla[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.S, Pg/M, Zop2.S, Zop3.S, #imm_rotation + /// svfloat32_t svcmla[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.S, Pg/M, Zop2.S, Zop3.S, #imm_rotation + /// svfloat32_t svcmla[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3, uint64_t imm_rotation) + /// + public static unsafe Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplex(addend, left, right, rotation); + /// MultiplyBySelectedScalar : Multiply /// diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 13a0b2ee9695f6..419dee05737bd6 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4364,6 +4364,9 @@ internal Arm64() { } public static System.Numerics.Vector AddAcross(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector AddAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AddRotateComplex(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw null; } + public static System.Numerics.Vector AddRotateComplex(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw null; } + public static System.Numerics.Vector AddSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AddSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AddSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -5178,6 +5181,9 @@ internal Arm64() { } public static System.Numerics.Vector MultiplyAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector MultiplyAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyAddRotateComplex(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRotateComplex(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index d02ccf461648b9..2abaf62dcd680f 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -280,11 +280,13 @@ ("_SveBinaryOpDifferentTypesTestTemplate.template", "SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveBinaryMaskOpTestTemplate.template", "SveMaskVecBinOpConvertTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveImmBinaryOpTestTemplate.template", "SveVecImmBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveImmBinaryOpTestTemplate.template", "SveVecImmBinOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), ("_SveImmUnaryOpTestTemplate.template", "SveVecImmUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveTernOpTestTemplate.template", "SveVecTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveTernOpTestTemplate.template", "SveVecTernOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), ("_SveTernOpFirstArgTestTemplate.template", "SveVecTernOpFirstArgTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveImmTernOpTestTemplate.template", "SveVecImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveImmTernOpTestTemplate.template", "SveVecImmTernOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), ("_SveTernOpMaskedOpTestTemplate.template", "SveVecTernOpMaskedTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveImmTernOpFirstArgTestTemplate.template", "SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveScalarTernOpTestTemplate.template", "SveScalarTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleScalarOpTest_ValidationLogic }), @@ -3113,6 +3115,11 @@ ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_float_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_float_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_double_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), @@ -3364,8 +3371,8 @@ ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplyAdd_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplyAdd_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "0", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddNegated_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddNegated_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), @@ -3373,8 +3380,8 @@ ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplySubtract_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplySubtract_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "0", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractNegated_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractNegated_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), @@ -3850,8 +3857,17 @@ ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyExtended_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.MultiplyExtended(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyExtended(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyExtended_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.MultiplyExtended(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyExtended(left[i], right[i])"}), @@ -4139,14 +4155,14 @@ ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Sqrt_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.Sqrt(firstOp[i])", ["GetIterResult"] = "Helpers.Sqrt(leftOp[i])"}), ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Sqrt_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.Sqrt(firstOp[i])", ["GetIterResult"] = "Helpers.Sqrt(leftOp[i])"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "0", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "2", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_4", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "4", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_6", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_5", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_7", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "7", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "0", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "2", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_4", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "4", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_6", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "1", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_5", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_7", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "7", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index d143df3432e87f..54ddade391f939 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -5234,6 +5234,28 @@ private static (ulong val, bool ovf) ShiftOvf(ulong value, int shift) public static float MinNumberPairwise(float[] op1, float[] op2, int i) => Pairwise(MinNumber, op1, op2, i); + public static float[] MultiplyAddRotateComplex(float[] op1, float[] op2, float[] op3, byte imm) + { + for (int i = 0; i < op1.Length; i += 2) + { + int real = i; + int img = i + 1; + (float ans1, float ans2) = imm switch + { + 0 => (FusedMultiplyAdd(op1[real], op2[real], op3[real]), FusedMultiplyAdd(op1[img], op2[real], op3[img])), + 1 => (FusedMultiplySubtract(op1[real], op2[img], op3[img]), FusedMultiplyAdd(op1[img], op2[img], op3[i])), + 2 => (FusedMultiplySubtract(op1[real], op2[real], op3[real]), FusedMultiplySubtract(op1[img], op2[real], op3[img])), + 3 => (FusedMultiplyAdd(op1[real], op2[img], op3[img]), FusedMultiplySubtract(op1[img], op2[img], op3[real])), + _ => (0.0f, 0.0f) + }; + + op1[real] = ans1; + op1[img] = ans2; + } + + return op1; + } + public static float MultiplyExtended(float op1, float op2) { bool inf1 = float.IsInfinity(op1); @@ -5411,6 +5433,28 @@ public static float FPExponentialAccelerator(uint op1) public static double MinNumberPairwise(double[] op1, double[] op2, int i) => Pairwise(MinNumber, op1, op2, i); + public static double[] MultiplyAddRotateComplex(double[] op1, double[] op2, double[] op3, byte imm) + { + for (int i = 0; i < op1.Length; i += 2) + { + int real = i; + int img = i + 1; + (double ans1, double ans2) = imm switch + { + 0 => (FusedMultiplyAdd(op1[real], op2[real], op3[real]), FusedMultiplyAdd(op1[img], op2[real], op3[img])), + 1 => (FusedMultiplySubtract(op1[real], op2[img], op3[img]), FusedMultiplyAdd(op1[img], op2[img], op3[i])), + 2 => (FusedMultiplySubtract(op1[real], op2[real], op3[real]), FusedMultiplySubtract(op1[img], op2[real], op3[img])), + 3 => (FusedMultiplyAdd(op1[real], op2[img], op3[img]), FusedMultiplySubtract(op1[img], op2[img], op3[real])), + _ => (0.0, 0.0) + }; + + op1[real] = ans1; + op1[img] = ans2; + } + + return op1; + } + public static double MultiplyExtended(double op1, double op2) { bool inf1 = double.IsInfinity(op1); @@ -6084,6 +6128,28 @@ private static ulong Pairwise(Func pairOp, ulong[] op1, ulo public static float AddPairwise(float[] op1, float[] op2, int i) => Pairwise(Add, op1, op2, i); + public static float[] AddRotateComplex(float[] op1, float[] op2, byte rot) + { + for (int i = 0; i < op1.Length; i += 2) + { + int real = i; + int img = i + 1; + + if (rot == 0) + { + op1[real] -= op2[img]; + op1[img] += op2[real]; + } + else + { + op1[real] += op2[img]; + op1[img] -= op2[real]; + } + } + + return op1; + } + public static float Max(float op1, float op2) => Math.Max(op1, op2); public static float MaxPairwise(float[] op1, int i) => Pairwise(Max, op1, i); @@ -6134,6 +6200,28 @@ private static float Pairwise(Func pairOp, float[] op1, flo public static double AddPairwise(double[] op1, double[] op2, int i) => Pairwise(Add, op1, op2, i); + public static double[] AddRotateComplex(double[] op1, double[] op2, byte rot) + { + for (int i = 0; i < op1.Length; i += 2) + { + int real = i; + int img = i + 1; + + if (rot == 0) + { + op1[real] -= op2[img]; + op1[img] += op2[real]; + } + else + { + op1[real] += op2[img]; + op1[img] -= op2[real]; + } + } + + return op1; + } + public static double Max(double op1, double op2) => Math.Max(op1, op2); public static double MaxPairwise(double[] op1, int i) => Pairwise(Max, op1, i); diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template index 3132da3fa1fdbf..e3c3957aa01fd6 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template @@ -9,6 +9,7 @@ ******************************************************************************/ using System; +using System.Linq; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -145,7 +146,7 @@ namespace JIT.HardwareIntrinsics.Arm for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp1}; } + for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp2}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); return testStruct; @@ -173,7 +174,7 @@ namespace JIT.HardwareIntrinsics.Arm private {Op1VectorType}<{Op1BaseType}> _mask; private {Op1VectorType}<{Op1BaseType}> _fld1; private {Op1VectorType}<{Op1BaseType}> _fld2; - private {Op1VectorType}<{Op1BaseType}> _falseFld; + private {Op1VectorType}<{Op1BaseType}> _falseFld; private DataTable _dataTable; @@ -181,16 +182,16 @@ namespace JIT.HardwareIntrinsics.Arm { Succeeded = true; - for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueOp1} % 2); } + for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueMask} % 2); } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _mask), ref Unsafe.As<{Op1BaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp1}; } + for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp2}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp1}; } + for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp2}; } _dataTable = new DataTable(_data1, _data2, new {RetBaseType}[RetElementCount], LargestVectorSize); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template index c1bcca1eb32c65..9ce3a334f7d7ad 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template @@ -9,6 +9,7 @@ ******************************************************************************/ using System; +using System.Linq; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -65,6 +66,9 @@ namespace JIT.HardwareIntrinsics.Arm // Validates executing the test inside conditional, with op3 as zero test.ConditionalSelect_ZeroOp(); + + // Validates basic functionality fails with an invalid imm, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead_InvalidImm(); } else { @@ -194,7 +198,7 @@ namespace JIT.HardwareIntrinsics.Arm { Succeeded = true; - for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueOp1} % 2); } + for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueMask} % 2); } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _mask), ref Unsafe.As<{Op1BaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); @@ -229,6 +233,32 @@ namespace JIT.HardwareIntrinsics.Arm ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); } + public void RunBasicScenario_UnsafeRead_InvalidImm() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead_InvalidImm)); + + bool succeeded = false; + try + { + var result = {Isa}.{Method}( + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray3Ptr), + {InvalidImm} + ); + Console.WriteLine(result); + } + catch (ArgumentOutOfRangeException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); From 20f11b0505d018c345446d06e6aeaeb64befb1e5 Mon Sep 17 00:00:00 2001 From: Aman Khalid Date: Tue, 16 Jul 2024 13:26:48 +0000 Subject: [PATCH 30/30] ARM64-SVE: Add `ConvertToSingle`, `ConvertToDouble`; fix `CovertTo*` tests (#104478) --- src/coreclr/jit/hwintrinsic.cpp | 4 +- src/coreclr/jit/hwintrinsiccodegenarm64.cpp | 2 + src/coreclr/jit/hwintrinsiclistarm64sve.h | 2 + src/coreclr/jit/lowerarmarch.cpp | 6 +- .../Arm/Sve.PlatformNotSupported.cs | 97 +++++++++++ .../src/System/Runtime/Intrinsics/Arm/Sve.cs | 96 +++++++++++ .../ref/System.Runtime.Intrinsics.cs | 10 ++ .../GenerateHWIntrinsicTests_Arm.cs | 47 ++++-- .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 154 ++++++++++++++++-- ...aryOpDifferentRetTypeTestTemplate.template | 33 ++-- 10 files changed, 406 insertions(+), 45 deletions(-) diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index f1b05fb9197984..4d31cebad96b38 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -2088,9 +2088,11 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, #elif defined(TARGET_ARM64) switch (intrinsic) { + case NI_Sve_ConvertToDouble: case NI_Sve_ConvertToInt32: - case NI_Sve_ConvertToUInt32: case NI_Sve_ConvertToInt64: + case NI_Sve_ConvertToSingle: + case NI_Sve_ConvertToUInt32: case NI_Sve_ConvertToUInt64: // Save the base type of return SIMD. It is used to contain this intrinsic inside // ConditionalSelect. diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index 17f929fef2bb7a..f8e77197916df8 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -586,6 +586,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) { case NI_Sve_ConvertToInt32: case NI_Sve_ConvertToUInt32: + case NI_Sve_ConvertToSingle: { embOpt = emitTypeSize(intrinEmbMask.baseType) == EA_8BYTE ? INS_OPTS_D_TO_S : INS_OPTS_SCALABLE_S; @@ -594,6 +595,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_ConvertToInt64: case NI_Sve_ConvertToUInt64: + case NI_Sve_ConvertToDouble: { embOpt = emitTypeSize(intrinEmbMask.baseType) == EA_4BYTE ? INS_OPTS_S_TO_D : INS_OPTS_SCALABLE_D; diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index c7df23557516e7..961076326818a3 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -48,8 +48,10 @@ HARDWARE_INTRINSIC(Sve, ConditionalExtractAfterLastActiveElementAndRep HARDWARE_INTRINSIC(Sve, ConditionalExtractLastActiveElement, -1, 3, true, {INS_sve_clastb, INS_sve_clastb, INS_sve_clastb, INS_sve_clastb, INS_sve_clastb, INS_sve_clastb, INS_sve_clastb, INS_sve_clastb, INS_sve_clastb, INS_sve_clastb}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_HasScalarInputVariant|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, ConditionalExtractLastActiveElementAndReplicate, -1, 3, true, {INS_sve_clastb, INS_sve_clastb, INS_sve_clastb, INS_sve_clastb, INS_sve_clastb, INS_sve_clastb, INS_sve_clastb, INS_sve_clastb, INS_sve_clastb, INS_sve_clastb}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve, ConditionalSelect, -1, 3, true, {INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_SupportsContainment) +HARDWARE_INTRINSIC(Sve, ConvertToDouble, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_scvtf, INS_sve_ucvtf, INS_sve_scvtf, INS_sve_ucvtf, INS_sve_fcvt, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, ConvertToInt32, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcvtzs, INS_sve_fcvtzs}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, ConvertToInt64, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcvtzs, INS_sve_fcvtzs}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, ConvertToSingle, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_scvtf, INS_sve_ucvtf, INS_sve_scvtf, INS_sve_ucvtf, INS_invalid, INS_sve_fcvt}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, ConvertToUInt32, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcvtzu, INS_sve_fcvtzu}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, ConvertToUInt64, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcvtzu, INS_sve_fcvtzu}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Count16BitElements, 0, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cnth, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_NoFloatingPointUsed) diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 2ae67d5899b97d..e64b134192ae28 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -3599,9 +3599,11 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) // For now, make sure that we get here only for intrinsics that we are // sure about to rely on auxiliary type's size. - assert((embOp->GetHWIntrinsicId() == NI_Sve_ConvertToInt32) || - (embOp->GetHWIntrinsicId() == NI_Sve_ConvertToUInt32) || + assert((embOp->GetHWIntrinsicId() == NI_Sve_ConvertToDouble) || + (embOp->GetHWIntrinsicId() == NI_Sve_ConvertToInt32) || (embOp->GetHWIntrinsicId() == NI_Sve_ConvertToInt64) || + (embOp->GetHWIntrinsicId() == NI_Sve_ConvertToSingle) || + (embOp->GetHWIntrinsicId() == NI_Sve_ConvertToUInt32) || (embOp->GetHWIntrinsicId() == NI_Sve_ConvertToUInt64)); uint32_t auxSize = genTypeSize(embOp->GetAuxiliaryType()); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs index 81863a057638d5..3d52204ba67f2f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs @@ -1879,6 +1879,54 @@ internal Arm64() { } public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + /// ConvertToDouble : Floating-point convert + + /// + /// svfloat64_t svcvt_f64[_s32]_m(svfloat64_t inactive, svbool_t pg, svint32_t op) + /// SCVTF Ztied.D, Pg/M, Zop.S + /// svfloat64_t svcvt_f64[_s32]_x(svbool_t pg, svint32_t op) + /// SCVTF Ztied.D, Pg/M, Ztied.S + /// svfloat64_t svcvt_f64[_s32]_z(svbool_t pg, svint32_t op) + /// + public static unsafe Vector ConvertToDouble(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svcvt_f64[_s64]_m(svfloat64_t inactive, svbool_t pg, svint64_t op) + /// SCVTF Ztied.D, Pg/M, Zop.D + /// svfloat64_t svcvt_f64[_s64]_x(svbool_t pg, svint64_t op) + /// SCVTF Ztied.D, Pg/M, Ztied.D + /// svfloat64_t svcvt_f64[_s64]_z(svbool_t pg, svint64_t op) + /// + public static unsafe Vector ConvertToDouble(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svcvt_f64[_f32]_m(svfloat64_t inactive, svbool_t pg, svfloat32_t op) + /// FCVT Ztied.D, Pg/M, Zop.S + /// svfloat64_t svcvt_f64[_f32]_x(svbool_t pg, svfloat32_t op) + /// FCVT Ztied.D, Pg/M, Ztied.S + /// svfloat64_t svcvt_f64[_f32]_z(svbool_t pg, svfloat32_t op) + /// + public static unsafe Vector ConvertToDouble(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svcvt_f64[_u32]_m(svfloat64_t inactive, svbool_t pg, svuint32_t op) + /// UCVTF Ztied.D, Pg/M, Zop.S + /// svfloat64_t svcvt_f64[_u32]_x(svbool_t pg, svuint32_t op) + /// UCVTF Ztied.D, Pg/M, Ztied.S + /// svfloat64_t svcvt_f64[_u32]_z(svbool_t pg, svuint32_t op) + /// + public static unsafe Vector ConvertToDouble(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svcvt_f64[_u64]_m(svfloat64_t inactive, svbool_t pg, svuint64_t op) + /// UCVTF Ztied.D, Pg/M, Zop.D + /// svfloat64_t svcvt_f64[_u64]_x(svbool_t pg, svuint64_t op) + /// UCVTF Ztied.D, Pg/M, Ztied.D + /// svfloat64_t svcvt_f64[_u64]_z(svbool_t pg, svuint64_t op) + /// + public static unsafe Vector ConvertToDouble(Vector value) { throw new PlatformNotSupportedException(); } + + /// ConvertToInt32 : Floating-point convert /// @@ -1920,6 +1968,55 @@ internal Arm64() { } /// public static unsafe Vector ConvertToInt64(Vector value) { throw new PlatformNotSupportedException(); } + + /// ConvertToSingle : Floating-point convert + + /// + /// svfloat32_t svcvt_f32[_f64]_m(svfloat32_t inactive, svbool_t pg, svfloat64_t op) + /// FCVT Ztied.S, Pg/M, Zop.D + /// svfloat32_t svcvt_f32[_f64]_x(svbool_t pg, svfloat64_t op) + /// FCVT Ztied.S, Pg/M, Ztied.D + /// svfloat32_t svcvt_f32[_f64]_z(svbool_t pg, svfloat64_t op) + /// + public static unsafe Vector ConvertToSingle(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svcvt_f32[_s32]_m(svfloat32_t inactive, svbool_t pg, svint32_t op) + /// SCVTF Ztied.S, Pg/M, Zop.S + /// svfloat32_t svcvt_f32[_s32]_x(svbool_t pg, svint32_t op) + /// SCVTF Ztied.S, Pg/M, Ztied.S + /// svfloat32_t svcvt_f32[_s32]_z(svbool_t pg, svint32_t op) + /// + public static unsafe Vector ConvertToSingle(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svcvt_f32[_s64]_m(svfloat32_t inactive, svbool_t pg, svint64_t op) + /// SCVTF Ztied.S, Pg/M, Zop.D + /// svfloat32_t svcvt_f32[_s64]_x(svbool_t pg, svint64_t op) + /// SCVTF Ztied.S, Pg/M, Ztied.D + /// svfloat32_t svcvt_f32[_s64]_z(svbool_t pg, svint64_t op) + /// + public static unsafe Vector ConvertToSingle(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svcvt_f32[_u32]_m(svfloat32_t inactive, svbool_t pg, svuint32_t op) + /// UCVTF Ztied.S, Pg/M, Zop.S + /// svfloat32_t svcvt_f32[_u32]_x(svbool_t pg, svuint32_t op) + /// UCVTF Ztied.S, Pg/M, Ztied.S + /// svfloat32_t svcvt_f32[_u32]_z(svbool_t pg, svuint32_t op) + /// + public static unsafe Vector ConvertToSingle(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svcvt_f32[_u64]_m(svfloat32_t inactive, svbool_t pg, svuint64_t op) + /// UCVTF Ztied.S, Pg/M, Zop.D + /// svfloat32_t svcvt_f32[_u64]_x(svbool_t pg, svuint64_t op) + /// UCVTF Ztied.S, Pg/M, Ztied.D + /// svfloat32_t svcvt_f32[_u64]_z(svbool_t pg, svuint64_t op) + /// + public static unsafe Vector ConvertToSingle(Vector value) { throw new PlatformNotSupportedException(); } + + /// ConvertToUInt32 : Floating-point convert /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs index 73d4c556249fb6..e7dc14f3a3f2cd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs @@ -1937,6 +1937,54 @@ internal Arm64() { } public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) => ConditionalSelect(mask, left, right); + /// ConvertToDouble : Floating-point convert + + /// + /// svfloat64_t svcvt_f64[_s32]_m(svfloat64_t inactive, svbool_t pg, svint32_t op) + /// SCVTF Ztied.D, Pg/M, Zop.S + /// svfloat64_t svcvt_f64[_s32]_x(svbool_t pg, svint32_t op) + /// SCVTF Ztied.D, Pg/M, Ztied.S + /// svfloat64_t svcvt_f64[_s32]_z(svbool_t pg, svint32_t op) + /// + public static unsafe Vector ConvertToDouble(Vector value) => ConvertToDouble(value); + + /// + /// svfloat64_t svcvt_f64[_s64]_m(svfloat64_t inactive, svbool_t pg, svint64_t op) + /// SCVTF Ztied.D, Pg/M, Zop.D + /// svfloat64_t svcvt_f64[_s64]_x(svbool_t pg, svint64_t op) + /// SCVTF Ztied.D, Pg/M, Ztied.D + /// svfloat64_t svcvt_f64[_s64]_z(svbool_t pg, svint64_t op) + /// + public static unsafe Vector ConvertToDouble(Vector value) => ConvertToDouble(value); + + /// + /// svfloat64_t svcvt_f64[_f32]_m(svfloat64_t inactive, svbool_t pg, svfloat32_t op) + /// FCVT Ztied.D, Pg/M, Zop.S + /// svfloat64_t svcvt_f64[_f32]_x(svbool_t pg, svfloat32_t op) + /// FCVT Ztied.D, Pg/M, Ztied.S + /// svfloat64_t svcvt_f64[_f32]_z(svbool_t pg, svfloat32_t op) + /// + public static unsafe Vector ConvertToDouble(Vector value) => ConvertToDouble(value); + + /// + /// svfloat64_t svcvt_f64[_u32]_m(svfloat64_t inactive, svbool_t pg, svuint32_t op) + /// UCVTF Ztied.D, Pg/M, Zop.S + /// svfloat64_t svcvt_f64[_u32]_x(svbool_t pg, svuint32_t op) + /// UCVTF Ztied.D, Pg/M, Ztied.S + /// svfloat64_t svcvt_f64[_u32]_z(svbool_t pg, svuint32_t op) + /// + public static unsafe Vector ConvertToDouble(Vector value) => ConvertToDouble(value); + + /// + /// svfloat64_t svcvt_f64[_u64]_m(svfloat64_t inactive, svbool_t pg, svuint64_t op) + /// UCVTF Ztied.D, Pg/M, Zop.D + /// svfloat64_t svcvt_f64[_u64]_x(svbool_t pg, svuint64_t op) + /// UCVTF Ztied.D, Pg/M, Ztied.D + /// svfloat64_t svcvt_f64[_u64]_z(svbool_t pg, svuint64_t op) + /// + public static unsafe Vector ConvertToDouble(Vector value) => ConvertToDouble(value); + + /// ConvertToInt32 : Floating-point convert /// @@ -1979,6 +2027,54 @@ internal Arm64() { } public static unsafe Vector ConvertToInt64(Vector value) => ConvertToInt64(value); + /// ConvertToSingle : Floating-point convert + + /// + /// svfloat32_t svcvt_f32[_f64]_m(svfloat32_t inactive, svbool_t pg, svfloat64_t op) + /// FCVT Ztied.S, Pg/M, Zop.D + /// svfloat32_t svcvt_f32[_f64]_x(svbool_t pg, svfloat64_t op) + /// FCVT Ztied.S, Pg/M, Ztied.D + /// svfloat32_t svcvt_f32[_f64]_z(svbool_t pg, svfloat64_t op) + /// + public static unsafe Vector ConvertToSingle(Vector value) => ConvertToSingle(value); + + /// + /// svfloat32_t svcvt_f32[_s32]_m(svfloat32_t inactive, svbool_t pg, svint32_t op) + /// SCVTF Ztied.S, Pg/M, Zop.S + /// svfloat32_t svcvt_f32[_s32]_x(svbool_t pg, svint32_t op) + /// SCVTF Ztied.S, Pg/M, Ztied.S + /// svfloat32_t svcvt_f32[_s32]_z(svbool_t pg, svint32_t op) + /// + public static unsafe Vector ConvertToSingle(Vector value) => ConvertToSingle(value); + + /// + /// svfloat32_t svcvt_f32[_s64]_m(svfloat32_t inactive, svbool_t pg, svint64_t op) + /// SCVTF Ztied.S, Pg/M, Zop.D + /// svfloat32_t svcvt_f32[_s64]_x(svbool_t pg, svint64_t op) + /// SCVTF Ztied.S, Pg/M, Ztied.D + /// svfloat32_t svcvt_f32[_s64]_z(svbool_t pg, svint64_t op) + /// + public static unsafe Vector ConvertToSingle(Vector value) => ConvertToSingle(value); + + /// + /// svfloat32_t svcvt_f32[_u32]_m(svfloat32_t inactive, svbool_t pg, svuint32_t op) + /// UCVTF Ztied.S, Pg/M, Zop.S + /// svfloat32_t svcvt_f32[_u32]_x(svbool_t pg, svuint32_t op) + /// UCVTF Ztied.S, Pg/M, Ztied.S + /// svfloat32_t svcvt_f32[_u32]_z(svbool_t pg, svuint32_t op) + /// + public static unsafe Vector ConvertToSingle(Vector value) => ConvertToSingle(value); + + /// + /// svfloat32_t svcvt_f32[_u64]_m(svfloat32_t inactive, svbool_t pg, svuint64_t op) + /// UCVTF Ztied.S, Pg/M, Zop.D + /// svfloat32_t svcvt_f32[_u64]_x(svbool_t pg, svuint64_t op) + /// UCVTF Ztied.S, Pg/M, Ztied.D + /// svfloat32_t svcvt_f32[_u64]_z(svbool_t pg, svuint64_t op) + /// + public static unsafe Vector ConvertToSingle(Vector value) => ConvertToSingle(value); + + /// ConvertToUInt32 : Floating-point convert /// diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 419dee05737bd6..fc632d99b3387d 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4610,10 +4610,20 @@ internal Arm64() { } public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector mask, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector mask, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ConvertToDouble(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToDouble(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToDouble(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToDouble(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToDouble(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ConvertToInt32(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ConvertToInt32(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ConvertToInt64(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ConvertToInt64(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToSingle(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToSingle(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToSingle(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToSingle(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToSingle(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ConvertToUInt32(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ConvertToUInt32(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ConvertToUInt64(System.Numerics.Vector value) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 2abaf62dcd680f..c20d6c8dd1bf55 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -139,9 +139,9 @@ }"; const string SimpleVecOpTest_VectorValidationLogicForCndSel = @" - { - {Op1BaseType}[] vectorResult = {GetVectorResult}; - {Op1BaseType}[] maskedVectorResult = new {RetBaseType}[vectorResult.Length]; + + {RetBaseType}[] vectorResult = {GetVectorResult}; + {RetBaseType}[] maskedVectorResult = new {RetBaseType}[vectorResult.Length]; for (var i = 0; i < vectorResult.Length; i++) { @@ -152,16 +152,16 @@ { succeeded = false; } - }"; + "; const string SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue = @" { - {Op1BaseType}[] vectorResult = {GetVectorResult}; - {Op1BaseType}[] maskedVectorResult = new {RetBaseType}[vectorResult.Length]; + {RetBaseType}[] vectorResult = {GetVectorResult}; + {RetBaseType}[] maskedVectorResult = new {RetBaseType}[vectorResult.Length]; for (var i = 0; i < vectorResult.Length; i++) { - {Op1BaseType} iterResult = (mask[i] != 0) ? trueVal[i] : vectorResult[i]; + {RetBaseType} iterResult = (mask[i] != 0) ? trueVal[i] : vectorResult[i]; if (mask[i] != 0) { // Pick the trueValue @@ -271,7 +271,8 @@ ("_BinaryOpTestTemplate.template", "SecureHashBinOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }), ("_TernaryOpTestTemplate.template", "SecureHashTernOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }), ("_SveUnaryOpTestTemplate.template", "SveSimpleVecOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), - ("_SveUnaryOpDifferentRetTypeTestTemplate.template", "SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogicForNarrowing, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSelForNarrowing, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSelForNarrowing_FalseValue }), + ("_SveUnaryOpDifferentRetTypeTestTemplate.template", "SveSimpleVecOpDiffRetTypeTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogicForNarrowing, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSelForNarrowing, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSelForNarrowing_FalseValue }), + ("_SveUnaryOpDifferentRetTypeTestTemplate.template", "SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), ("_SveBinaryOpTestTemplate.template", "SveVecBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveBinaryOpTestTemplate.template", "SveVecBinOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), ("_SveBinaryOpTestTemplate.template", "SveVecBinOpConvertTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), @@ -3272,14 +3273,24 @@ ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), - ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt32_int_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertToInt32(leftOp[i])", ["ConvertFunc"] = ""}), - ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt32_int_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertDoubleToInt32(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertDoubleToInt32(leftOp[i])", ["ConvertFunc"] = ""}), - ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt64_long_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertFloatToInt64(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertFloatToInt64(leftOp[i])", ["ConvertFunc"] = ""}), - ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt64_long_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToInt64(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertToInt64(leftOp[i])", ["ConvertFunc"] = ""}), - ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt32_uint_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertToUInt32(leftOp[i])", ["ConvertFunc"] = ""}), - ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt32_uint_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertDoubleToUInt32(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertDoubleToUInt32(leftOp[i])", ["ConvertFunc"] = ""}), - ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt64_ulong_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertFloatToUInt64(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertFloatToUInt64(leftOp[i])", ["ConvertFunc"] = ""}), - ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt64_ulong_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToUInt64(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.ConvertToUInt64(leftOp[i])", ["ConvertFunc"] = ""}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToDouble_double_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToDouble(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToDouble(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToDouble_double_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToDouble(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToDouble(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToDouble_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToDouble(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToDouble(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToDouble_double_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToDouble(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToDouble(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToDouble_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToDouble(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToDouble(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt32_int_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToInt32(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToInt32(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt32_int_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToInt32(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToInt32(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt64_long_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToInt64(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToInt64(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt64_long_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToInt64(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToInt64(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToSingle_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToSingle(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToSingle(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToSingle_float_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToSingle(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToSingle(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToSingle_float_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToSingle(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToSingle(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToSingle_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToSingle(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToSingle(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToSingle_float_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToSingle(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToSingle(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt32_uint_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToUInt32(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToUInt32(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt32_uint_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToUInt32(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToUInt32(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt64_ulong_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToUInt64(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToUInt64(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt64_ulong_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToUInt64(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToUInt64(left)"}), ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count16BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count16BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Int16)));",}), ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count32BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count32BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Int32)));",}), @@ -3481,8 +3492,8 @@ ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForNextActiveElement_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForNextActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForNextActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForNextActiveElement(left, right)"}), ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForNextActiveElement_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForNextActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForNextActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForNextActiveElement(left, right)"}), - ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary {["TestName"] = "Sve_FloatingPointExponentialAccelerator_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FloatingPointExponentialAccelerator", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPExponentialAccelerator(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FPExponentialAccelerator(leftOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveSimpleVecOpDifferentRetTypeTest.template", new Dictionary {["TestName"] = "Sve_FloatingPointExponentialAccelerator_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FloatingPointExponentialAccelerator", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPExponentialAccelerator(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FPExponentialAccelerator(leftOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveSimpleVecOpDiffRetTypeTest.template", new Dictionary {["TestName"] = "Sve_FloatingPointExponentialAccelerator_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FloatingPointExponentialAccelerator", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPExponentialAccelerator(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FPExponentialAccelerator(leftOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveSimpleVecOpDiffRetTypeTest.template", new Dictionary {["TestName"] = "Sve_FloatingPointExponentialAccelerator_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FloatingPointExponentialAccelerator", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPExponentialAccelerator(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FPExponentialAccelerator(leftOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "SveExtractVector_Byte_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "SveExtractVector_Double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 54ddade391f939..1e3b4c342b1a3e 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -7081,21 +7081,75 @@ public static ulong ShiftRightAndInsert(ulong left, ulong right, byte shift) public static float RoundToZero(float op1) => MathF.Round(op1, MidpointRounding.ToZero); - public static int ConvertDoubleToInt32(double op1) => (int)Math.Clamp(op1, long.MinValue, long.MaxValue); + private static int ConvertToInt32(double op1) => (int)Math.Clamp(op1, int.MinValue, int.MaxValue); - public static int ConvertToInt32(float op1) => (int)Math.Clamp(op1, int.MinValue, int.MaxValue); + public static int[] ConvertToInt32(double[] op1) + { + int[] result = new int[op1.Length * 2]; + + for (int i = 0; i < op1.Length; i++) + { + int index = i * 2; + result[index] = ConvertToInt32(op1[i]); + if (op1[i] < 0) + { + // Sign-extend next lane with all ones + result[index + 1] = -1; + } + } + + return result; + } + + public static int[] ConvertToInt32(float[] op1) => Array.ConvertAll(op1, num => ConvertToInt32(num)); + + private static long ConvertToInt64(double op1) => (long)Math.Clamp(op1, long.MinValue, long.MaxValue); - public static long ConvertToInt64(double op1) => (long)Math.Clamp(op1, long.MinValue, long.MaxValue); + public static long[] ConvertToInt64(double[] op1) => Array.ConvertAll(op1, num => ConvertToInt64(num)); + + public static long[] ConvertToInt64(float[] op1) + { + long[] result = new long[op1.Length / 2]; + + for (int i = 0; i < result.Length; i++) + { + result[i] = ConvertToInt64(op1[i * 2]); + } + + return result; + } + + private static uint ConvertToUInt32(double op1) => (uint)Math.Clamp(op1, uint.MinValue, uint.MaxValue); + + public static uint[] ConvertToUInt32(double[] op1) + { + uint[] result = new uint[op1.Length * 2]; + + for (int i = 0; i < op1.Length; i++) + { + result[i * 2] = ConvertToUInt32(op1[i]); + } + + return result; + } - public static long ConvertFloatToInt64(float op1) => (long)Math.Clamp(op1, int.MinValue, int.MaxValue); + public static uint[] ConvertToUInt32(float[] op1) => Array.ConvertAll(op1, num => ConvertToUInt32(num)); - public static uint ConvertDoubleToUInt32(double op1) => (uint)Math.Clamp(op1, ulong.MinValue, ulong.MaxValue); + private static ulong ConvertToUInt64(double op1) => (ulong)Math.Clamp(op1, ulong.MinValue, ulong.MaxValue); - public static uint ConvertToUInt32(float op1) => (uint)Math.Clamp(op1, uint.MinValue, uint.MaxValue); + public static ulong[] ConvertToUInt64(double[] op1) => Array.ConvertAll(op1, num => ConvertToUInt64(num)); - public static ulong ConvertToUInt64(double op1) => (ulong)Math.Clamp(op1, ulong.MinValue, ulong.MaxValue); + public static ulong[] ConvertToUInt64(float[] op1) + { + ulong[] result = new ulong[op1.Length / 2]; + + for (int i = 0; i < result.Length; i++) + { + result[i] = ConvertToUInt64(op1[i * 2]); + } - public static ulong ConvertFloatToUInt64(float op1) => (ulong)Math.Clamp(op1, uint.MinValue, uint.MaxValue); + return result; + } public static Int32 ConvertToInt32RoundAwayFromZero(float op1) => ConvertToInt32(RoundAwayFromZero(op1)); @@ -7143,16 +7197,96 @@ public static ulong ShiftRightAndInsert(ulong left, ulong right, byte shift) public static float ConvertToSingle(double op1) => (float)op1; + public static float[] ConvertToSingle(double[] op1) + { + float[] result = new float[op1.Length * 2]; + + for (int i = 0; i < op1.Length; i++) + { + result[i * 2] = (float)op1[i]; + } + + return result; + } + + public static float[] ConvertToSingle(int[] op1) => Array.ConvertAll(op1, num => (float)num); + + public static float[] ConvertToSingle(long[] op1) + { + float[] result = new float[op1.Length * 2]; + + for (int i = 0; i < op1.Length; i++) + { + result[i * 2] = (float)op1[i]; + } + + return result; + } + + public static float[] ConvertToSingle(uint[] op1) => Array.ConvertAll(op1, num => (float)num); + + public static float[] ConvertToSingle(ulong[] op1) + { + float[] result = new float[op1.Length * 2]; + + for (int i = 0; i < op1.Length; i++) + { + result[i * 2] = (float)op1[i]; + } + + return result; + } + public static float ConvertToSingleUpper(float[] op1, double[] op2, int i) => i < op1.Length ? op1[i] : ConvertToSingle(op2[i - op1.Length]); public static double ConvertToDouble(float op1) => op1; - public static double ConvertToDoubleUpper(float[] op1, int i) => ConvertToDouble(op1[i + op1.Length / 2]); - public static double ConvertToDouble(long op1) => op1; public static double ConvertToDouble(ulong op1) => op1; + public static double[] ConvertToDouble(float[] op1) + { + double[] result = new double[op1.Length / 2]; + + for (int i = 0; i < result.Length; i++) + { + result[i] = op1[i * 2]; + } + + return result; + } + + public static double[] ConvertToDouble(int[] op1) + { + double[] result = new double[op1.Length / 2]; + + for (int i = 0; i < result.Length; i++) + { + result[i] = op1[i * 2]; + } + + return result; + } + + public static double[] ConvertToDouble(long[] op1) => Array.ConvertAll(op1, num => (double)num); + + public static double[] ConvertToDouble(uint[] op1) + { + double[] result = new double[op1.Length / 2]; + + for (int i = 0; i < result.Length; i++) + { + result[i] = op1[i * 2]; + } + + return result; + } + + public static double[] ConvertToDouble(ulong[] op1) => Array.ConvertAll(op1, num => (double)num); + + public static double ConvertToDoubleUpper(float[] op1, int i) => ConvertToDouble(op1[i + op1.Length / 2]); + public static short ReverseElement8(short val) { ulong result = 0UL; diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveUnaryOpDifferentRetTypeTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveUnaryOpDifferentRetTypeTestTemplate.template index e08a215ae18f04..56a0d8bfb3a2fc 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveUnaryOpDifferentRetTypeTestTemplate.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveUnaryOpDifferentRetTypeTestTemplate.template @@ -9,6 +9,7 @@ ******************************************************************************/ using System; +using System.Linq; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -51,11 +52,14 @@ namespace JIT.HardwareIntrinsics.Arm // Validates passing an instance member of a struct works test.RunStructFldScenario(); - // Validates executing the test inside conditional, with op3 as falseValue - test.ConditionalSelect_FalseOp(); + if (sizeof({Op1BaseType}) == sizeof({RetBaseType})) + { + // Validates executing the test inside conditional, with op3 as falseValue + test.ConditionalSelect_FalseOp(); - // Validates executing the test inside conditional, with op3 as zero - test.ConditionalSelect_ZeroOp(); + // Validates executing the test inside conditional, with op3 as zero + test.ConditionalSelect_ZeroOp(); + } } else { @@ -143,6 +147,7 @@ namespace JIT.HardwareIntrinsics.Arm private static readonly int LargestVectorSize = {LargestVectorSize}; private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; private static {RetBaseType}[] _data2 = new {RetBaseType}[Op1ElementCount]; @@ -165,7 +170,7 @@ namespace JIT.HardwareIntrinsics.Arm Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _falseFld), ref Unsafe.As<{RetBaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - _dataTable = new DataTable(_data1, new {RetBaseType}[Op1ElementCount], LargestVectorSize); + _dataTable = new DataTable(_data1, new {RetBaseType}[RetElementCount], LargestVectorSize); } public bool IsSupported => {Isa}.IsSupported; @@ -334,10 +339,10 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateConditionalSelectResult_TrueValue({Op1VectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> leftOp, {Op1VectorType}<{RetBaseType}> falseOp, void* output, [CallerMemberName] string method = "") { - {RetBaseType}[] mask = new {RetBaseType}[Op1ElementCount]; + {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; {Op1BaseType}[] left = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] falseVal = new {RetBaseType}[Op1ElementCount]; - {RetBaseType}[] result = new {RetBaseType}[Op1ElementCount]; + {RetBaseType}[] falseVal = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref left[0]), leftOp); @@ -350,7 +355,7 @@ namespace JIT.HardwareIntrinsics.Arm if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>): {method} failed:"); TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" falseOp: ({string.Join(", ", falseVal)})"); @@ -363,10 +368,10 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateConditionalSelectResult_FalseValue({Op1VectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> leftOp, {Op1VectorType}<{RetBaseType}> trueOp, void* output, [CallerMemberName] string method = "") { - {RetBaseType}[] mask = new {RetBaseType}[Op1ElementCount]; + {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; {Op1BaseType}[] left = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] trueVal = new {RetBaseType}[Op1ElementCount]; - {RetBaseType}[] result = new {RetBaseType}[Op1ElementCount]; + {RetBaseType}[] trueVal = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref left[0]), leftOp); @@ -393,7 +398,7 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[Op1ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); @@ -404,7 +409,7 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[Op1ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>());