diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Plane.Extensions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Plane.Extensions.cs index c85f47cea68b50..07ea8e13e8ff4f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Plane.Extensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Plane.Extensions.cs @@ -11,13 +11,6 @@ public static partial class Vector /// The plane to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Vector4 AsVector4(this Plane value) - { -#if MONO - return Unsafe.As(ref value); -#else - return Unsafe.BitCast(value); -#endif - } + public static Vector4 AsVector4(this Plane value) => Unsafe.BitCast(value); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.Extensions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.Extensions.cs index e5e402880fb324..02086f9bc1bedb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.Extensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.Extensions.cs @@ -11,13 +11,6 @@ public static partial class Vector /// The quaternion to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Vector4 AsVector4(this Quaternion value) - { -#if MONO - return Unsafe.As(ref value); -#else - return Unsafe.BitCast(value); -#endif - } + public static Vector4 AsVector4(this Quaternion value) => Unsafe.BitCast(value); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs index 32166a6f4ecedd..f80cba2809dc12 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs @@ -149,11 +149,7 @@ public static Vector As(this Vector vector) ThrowHelper.ThrowForUnsupportedNumericsVectorBaseType(); ThrowHelper.ThrowForUnsupportedNumericsVectorBaseType(); -#if MONO - return Unsafe.As, Vector>(ref vector); -#else return Unsafe.BitCast, Vector>(vector); -#endif } /// Reinterprets a as a new . diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs index 6aa93a2d4a47a8..b6d9fa2ef48356 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs @@ -12,26 +12,12 @@ public static unsafe partial class Vector /// Reinterprets a as a new . /// The vector to reinterpret. /// reinterpreted as a new . - public static Plane AsPlane(this Vector4 value) - { -#if MONO - return Unsafe.As(ref value); -#else - return Unsafe.BitCast(value); -#endif - } + public static Plane AsPlane(this Vector4 value) => Unsafe.BitCast(value); /// Reinterprets a as a new . /// The vector to reinterpret. /// reinterpreted as a new . - public static Quaternion AsQuaternion(this Vector4 value) - { -#if MONO - return Unsafe.As(ref value); -#else - return Unsafe.BitCast(value); -#endif - } + public static Quaternion AsQuaternion(this Vector4 value) => Unsafe.BitCast(value); /// Reinterprets a as a new . /// The vector to reinterpret. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.Numerics.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.Numerics.cs index 1cfbc41de7ce22..0ccc17eb0e85c1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.Numerics.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.Numerics.cs @@ -53,53 +53,25 @@ public static partial class Vector128 /// The vector to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Plane AsPlane(this Vector128 value) - { -#if MONO - return Unsafe.As, Plane>(ref value); -#else - return Unsafe.BitCast, Plane>(value); -#endif - } + public static Plane AsPlane(this Vector128 value) => Unsafe.BitCast, Plane>(value); /// Reinterprets a as a new . /// The vector to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Quaternion AsQuaternion(this Vector128 value) - { -#if MONO - return Unsafe.As, Quaternion>(ref value); -#else - return Unsafe.BitCast, Quaternion>(value); -#endif - } + public static Quaternion AsQuaternion(this Vector128 value) => Unsafe.BitCast, Quaternion>(value); /// Reinterprets a as a new . /// The plane to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Vector128 AsVector128(this Plane value) - { -#if MONO - return Unsafe.As>(ref value); -#else - return Unsafe.BitCast>(value); -#endif - } + public static Vector128 AsVector128(this Plane value) => Unsafe.BitCast>(value); /// Reinterprets a as a new . /// The quaternion to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Vector128 AsVector128(this Quaternion value) - { -#if MONO - return Unsafe.As>(ref value); -#else - return Unsafe.BitCast>(value); -#endif - } + public static Vector128 AsVector128(this Quaternion value) => Unsafe.BitCast>(value); /// Reinterprets a as a new with the new elements zeroed. /// The vector to reinterpret. @@ -117,14 +89,7 @@ public static Vector128 AsVector128(this Quaternion value) /// The vector to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Vector128 AsVector128(this Vector4 value) - { -#if MONO - return Unsafe.As>(ref value); -#else - return Unsafe.BitCast>(value); -#endif - } + public static Vector128 AsVector128(this Vector4 value) => Unsafe.BitCast>(value); /// Reinterprets a as a new . /// The type of the elements in the vector. @@ -196,14 +161,7 @@ public static Vector3 AsVector3(this Vector128 value) /// The vector to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Vector4 AsVector4(this Vector128 value) - { -#if MONO - return Unsafe.As, Vector4>(ref value); -#else - return Unsafe.BitCast, Vector4>(value); -#endif - } + public static Vector4 AsVector4(this Vector128 value) => Unsafe.BitCast, Vector4>(value); /// Reinterprets a as a new . /// The type of the elements in the vector. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs index 90d8770baf7309..6aac6ab0314a74 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs @@ -177,11 +177,7 @@ public static Vector128 As(this Vector128 vector) ThrowHelper.ThrowForUnsupportedIntrinsicsVector128BaseType(); ThrowHelper.ThrowForUnsupportedIntrinsicsVector128BaseType(); -#if MONO - return Unsafe.As, Vector128>(ref vector); -#else return Unsafe.BitCast, Vector128>(vector); -#endif } /// Reinterprets a as a new . diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs index 8f8580a1fb11c9..397b6428656ec3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs @@ -171,11 +171,7 @@ public static Vector256 As(this Vector256 vector) ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType(); ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType(); -#if MONO - return Unsafe.As, Vector256>(ref vector); -#else return Unsafe.BitCast, Vector256>(vector); -#endif } /// Reinterprets a as a new . diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs index 29b10dba0310aa..85b780a3271b66 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs @@ -170,11 +170,7 @@ public static Vector512 As(this Vector512 vector) ThrowHelper.ThrowForUnsupportedIntrinsicsVector512BaseType(); ThrowHelper.ThrowForUnsupportedIntrinsicsVector512BaseType(); -#if MONO - return Unsafe.As, Vector512>(ref vector); -#else return Unsafe.BitCast, Vector512>(vector); -#endif } /// Reinterprets a as a new . diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs index 5c49722a1fa36b..b4bf35654517bd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs @@ -170,11 +170,7 @@ public static Vector64 As(this Vector64 vector) ThrowHelper.ThrowForUnsupportedIntrinsicsVector64BaseType(); ThrowHelper.ThrowForUnsupportedIntrinsicsVector64BaseType(); -#if MONO - return Unsafe.As, Vector64>(ref vector); -#else return Unsafe.BitCast, Vector64>(vector); -#endif } /// Reinterprets a as a new . diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index b45b82db4696dc..266c658ba1563b 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -2139,6 +2139,16 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas return TRUE; } } + } else if (in_corlib && !strcmp (klass_name_space, "System") && (!strcmp (klass_name, "BitConverter"))) { + if (!strcmp (tm, "DoubleToInt64Bits") || !strcmp (tm, "DoubleToUInt64Bits")) { + *op = MINT_MOV_8; + } else if (!strcmp (tm, "Int32BitsToSingle") || !strcmp (tm, "UInt32BitsToSingle")) { + *op = MINT_MOV_4; + } else if (!strcmp (tm, "Int64BitsToDouble") || !strcmp (tm, "UInt64BitsToDouble")) { + *op = MINT_MOV_8; + } else if (!strcmp (tm, "SingleToInt32Bits") || !strcmp (tm, "SingleToUInt32Bits")) { + *op = MINT_MOV_4; + } } else if (in_corlib && !strcmp (klass_name_space, "System.Runtime.CompilerServices") && !strcmp (klass_name, "Unsafe")) { if (!strcmp (tm, "AddByteOffset")) #if SIZEOF_VOID_P == 4 @@ -2156,6 +2166,72 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas return TRUE; } else if (!strcmp (tm, "AreSame")) { *op = MINT_CEQ_P; + } else if (!strcmp (tm, "BitCast")) { + MonoGenericContext *ctx = mono_method_get_context (target_method); + g_assert (ctx); + g_assert (ctx->method_inst); + g_assert (ctx->method_inst->type_argc == 2); + g_assert (csignature->param_count == 1); + + // We explicitly do not handle gsharedvt as it is meant as a slow fallback strategy + // instead we fallback to the managed implementation which will do the right things + + MonoType *tfrom = ctx->method_inst->type_argv [0]; + MonoType *tto = ctx->method_inst->type_argv [1]; + tfrom = mini_get_underlying_type (tfrom); + tto = mini_get_underlying_type (tto); + + // The underlying API always throws for reference type inputs, so we + // fallback to the managed implementation to let that handling occur + + if (MONO_TYPE_IS_REFERENCE (tfrom) || MONO_TYPE_IS_REFERENCE (tto)) { + return FALSE; + } + + MonoClass *tto_klass = mono_class_from_mono_type_internal (tto); + + // The same applies for when the type sizes do not match, as this will always throw + // and so its not an expected case and we can fallback to the managed implementation + + int tfrom_align, tto_align; + gint32 size = mono_type_size (tfrom, &tfrom_align); + if (size != mono_type_size (tto, &tto_align)) { + return FALSE; + } + g_assert (size < G_MAXUINT16); + + // We have several different move opcodes to handle the data depending on the + // source and target types, so detect and optimize the most common ones falling + // back to what is effectively `ReadUnaligned(ref As(ref source))` + // for anything that can't be special cased as potentially zero-cost move. + + if (m_class_is_enumtype (tto_klass)) { + tto = mono_class_enum_basetype_internal (tto_klass); + } + + int mov_op = interp_get_mov_for_type (mono_mint_type (tto), TRUE); + + if (mov_op == MINT_MOV_VT ) { + if (size <= 4) { + *op = MINT_MOV_4; + } else if (size <= 8) { + *op = MINT_MOV_8; + } else { + td->sp--; + interp_add_ins (td, MINT_MOV_VT); + interp_ins_set_sreg (td->last_ins, td->sp [0].var); + push_type_vt (td, tto_klass, size); + interp_ins_set_dreg (td->last_ins, td->sp [-1].var); + td->last_ins->data [0] = GINT32_TO_UINT16 (size); + td->ip += 5; + return TRUE; + } + } else { + if (size < 4) + return FALSE; + + *op = mov_op; + } } else if (!strcmp (tm, "ByteOffset")) { #if SIZEOF_VOID_P == 4 interp_add_ins (td, MINT_SUB_I4); diff --git a/src/mono/mono/mini/intrinsics.c b/src/mono/mono/mini/intrinsics.c index f5654ed3b82613..6ec87adc090b77 100644 --- a/src/mono/mono/mini/intrinsics.c +++ b/src/mono/mono/mini/intrinsics.c @@ -750,6 +750,11 @@ MONO_RESTORE_WARNING } } else if (mini_class_is_simd (cfg, tfrom_klass) && mini_class_is_simd (cfg, tto_klass)) { #if TARGET_SIZEOF_VOID_P == 8 || defined(TARGET_WASM) +#if defined(TARGET_WIN32) && defined(TARGET_AMD64) + if (!COMPILE_LLVM (cfg)) + // FIXME: Fix the register allocation for SIMD on Windows x64 + return NULL; +#endif opcode = OP_XCAST; tto_stack = STACK_VTYPE; #else diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Program.Vector128_1.cs b/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Program.Vector128_1.cs index 5bd034ce1e0be5..ce7efa5c7e04a4 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Program.Vector128_1.cs +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Program.Vector128_1.cs @@ -5,8 +5,6 @@ using System.Collections.Generic; using Xunit; -[assembly:ActiveIssue("https://github.com/dotnet/runtime/issues/54122", TestPlatforms.Browser)] - namespace JIT.HardwareIntrinsics.General._Vector128_1 { public static partial class Program diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Program.Vector256_1.cs b/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Program.Vector256_1.cs index bfccc8223160a7..89ee9c201e1641 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Program.Vector256_1.cs +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Program.Vector256_1.cs @@ -5,8 +5,6 @@ using System.Collections.Generic; using Xunit; -[assembly:ActiveIssue("https://github.com/dotnet/runtime/issues/54122", TestPlatforms.Browser)] - namespace JIT.HardwareIntrinsics.General._Vector256_1 { public static partial class Program diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 60a5ee7f2fe967..5d91deeba59eb2 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -2725,16 +2725,6 @@ https://github.com/dotnet/runtime/issues/54867 - - https://github.com/dotnet/runtime/issues/54122 - - - https://github.com/dotnet/runtime/issues/54122 - - - https://github.com/dotnet/runtime/issues/54122 - - Function mismatch