From fb9e3c2ae9fcf908fb194e3668035126b0d9af84 Mon Sep 17 00:00:00 2001 From: Sebastian Nickolls Date: Fri, 3 Oct 2025 12:38:18 +0000 Subject: [PATCH] Remove 128-bit limit on Vector size for ARM64 If InstructionSet_VectorT is available, set the class instance size to the process SVE vector length. Increase the maximum bound in structMightRepresentSIMDType to allow the JIT to detect this when the ISA is present. --- src/coreclr/jit/compiler.h | 7 ++++++- src/coreclr/jit/targetarm64.h | 3 +++ src/coreclr/vm/codeman.cpp | 10 ++++++---- src/coreclr/vm/methodtablebuilder.cpp | 15 +++++++++++++-- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 15161eacd678d8..b9f41aaada5068 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -10599,7 +10599,12 @@ class Compiler bool structSizeMightRepresentSIMDType(size_t structSize) { #ifdef FEATURE_SIMD - return (structSize >= getMinVectorByteLength()) && (structSize <= getMaxVectorByteLength()); +#ifdef TARGET_ARM64 + const uint32_t max = compExactlyDependsOn(InstructionSet_VectorT) ? MAX_SVE_REGSIZE_BYTES : FP_REGSIZE_BYTES; +#else + const uint32_t max = getMaxVectorByteLength(); +#endif // TARGET_ARM64 + return (structSize >= getMinVectorByteLength()) && (structSize <= max); #else return false; #endif // FEATURE_SIMD diff --git a/src/coreclr/jit/targetarm64.h b/src/coreclr/jit/targetarm64.h index 1dea19fa87c0b9..bea112f319f5d6 100644 --- a/src/coreclr/jit/targetarm64.h +++ b/src/coreclr/jit/targetarm64.h @@ -370,4 +370,7 @@ #define REG_UNKBASE REG_R19 #define RBM_UNKBASE RBM_R19 + +#define MAX_SVE_REGSIZE_BYTES 256 + // clang-format on diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index 438b513b3aaf4b..254007dce44d19 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -1720,10 +1720,12 @@ void EEJitManager::SetCpuInfo() uint32_t maxVectorTLength = (maxVectorTBitWidth / 8); uint64_t sveLengthFromOS = GetSveLengthFromOS(); - // For now, enable SVE only when the system vector length is 16 bytes (128-bits) - // TODO: https://github.com/dotnet/runtime/issues/101477 - if (sveLengthFromOS == 16) - // if ((maxVectorTLength >= sveLengthFromOS) || (maxVectorTBitWidth == 0)) + if (sveLengthFromOS == 16 +#ifdef _DEBUG + || (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitUseScalableVectorT) + && ((maxVectorTLength >= sveLengthFromOS) || (maxVectorTBitWidth == 0))) +#endif + ) { CPUCompileFlags.Set(InstructionSet_Sve); diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index fb16290b29e561..c9984deef79a1b 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -1174,6 +1174,10 @@ MethodTableBuilder::CopyParentVtable() } } +#ifdef TARGET_ARM64 +extern "C" uint64_t GetSveLengthFromOS(); +#endif + //******************************************************************************* // Determine if this is the special SIMD type System.Numerics.Vector, whose // size is determined dynamically based on the hardware and the presence of JIT @@ -1186,7 +1190,7 @@ BOOL MethodTableBuilder::CheckIfSIMDAndUpdateSize() { STANDARD_VM_CONTRACT; -#if defined(TARGET_X86) || defined(TARGET_AMD64) +#if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) if (!bmtProp->fIsIntrinsicType) return false; @@ -1205,6 +1209,7 @@ BOOL MethodTableBuilder::CheckIfSIMDAndUpdateSize() CORJIT_FLAGS CPUCompileFlags = ExecutionManager::GetEEJitManager()->GetCPUCompileFlags(); uint32_t numInstanceFieldBytes = 16; +#if defined(TARGET_X86) || defined(TARGET_AMD64) if (CPUCompileFlags.IsSet(InstructionSet_VectorT512)) { numInstanceFieldBytes = 64; @@ -1213,13 +1218,19 @@ BOOL MethodTableBuilder::CheckIfSIMDAndUpdateSize() { numInstanceFieldBytes = 32; } +#elif defined(TARGET_ARM64) + if (CPUCompileFlags.IsSet(InstructionSet_VectorT)) + { + numInstanceFieldBytes = (uint32_t) GetSveLengthFromOS(); + } +#endif if (numInstanceFieldBytes != 16) { bmtFP->NumInstanceFieldBytes = numInstanceFieldBytes; return true; } -#endif // TARGET_X86 || TARGET_AMD64 +#endif // TARGET_X86 || TARGET_AMD64 || TARGET_ARM64 return false; }