Skip to content

Commit

Permalink
clamp Vector<T> size to largest accelerated fixed-sized vector
Browse files Browse the repository at this point in the history
  • Loading branch information
saucecontrol committed Jan 17, 2025
1 parent 8064d04 commit 94cb2c5
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 14 deletions.
3 changes: 3 additions & 0 deletions src/coreclr/inc/clrconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,9 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_GDBJitEmitDebugFrame, W("GDBJitEmitDebugFrame"
#endif

RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_MaxVectorTBitWidth, W("MaxVectorTBitWidth"), 0, "The maximum decimal width, in bits, that Vector<T> is allowed to be. A value less than 128 is treated as the system default.", CLRConfig::LookupOptions::ParseIntegerAsBase10)
#if defined(TARGET_AMD64) || defined(TARGET_X86)
RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_PreferredVectorBitWidth, W("PreferredVectorBitWidth"), 0, "The maximum decimal width, in bits, of fixed-width vectors that may be considered hardware accelerated. A value less than 128 is treated as the system default.", CLRConfig::LookupOptions::ParseIntegerAsBase10)
#endif // defined(TARGET_AMD64) || defined(TARGET_X86)

//
// Hardware Intrinsic ISAs; keep in sync with jitconfigvalues.h
Expand Down
50 changes: 39 additions & 11 deletions src/coreclr/vm/codeman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1548,17 +1548,6 @@ void EEJitManager::SetCpuInfo()

#if defined(TARGET_X86) || defined(TARGET_AMD64)

// Clean up mutually exclusive ISAs
if (CPUCompileFlags.IsSet(InstructionSet_VectorT512))
{
CPUCompileFlags.Clear(InstructionSet_VectorT256);
CPUCompileFlags.Clear(InstructionSet_VectorT128);
}
else if (CPUCompileFlags.IsSet(InstructionSet_VectorT256))
{
CPUCompileFlags.Clear(InstructionSet_VectorT128);
}

int cpuidInfo[4];

const int CPUID_EAX = 0;
Expand Down Expand Up @@ -1625,6 +1614,45 @@ void EEJitManager::SetCpuInfo()
}
}
}

// JIT maps Vector<T> to Vector128, Vector256, or Vector512 for the purposes of most intrinsic resolution.
// If JIT reports that the corresponding fixed-width vector class is not hardware accelerated, that will
// mean Vector<T> is also reported as not accelerated, so we will limit Vector<T> size using the same rules.
// This logic must be kept in sync with Compiler::compSetProcessor/Compiler::getPreferredVectorByteLength.

uint32_t preferredVectorBitWidth = (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PreferredVectorBitWidth) / 128) * 128;

if ((preferredVectorBitWidth == 0) && CPUCompileFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_VECTOR512_THROTTLING))
{
preferredVectorBitWidth = 256;
}

if (preferredVectorBitWidth != 0)
{
if (CPUCompileFlags.IsSet(InstructionSet_VectorT512) && (preferredVectorBitWidth < 512))
{
CPUCompileFlags.Clear(InstructionSet_VectorT512);
}

if (CPUCompileFlags.IsSet(InstructionSet_VectorT256) && (preferredVectorBitWidth < 256))
{
CPUCompileFlags.Clear(InstructionSet_VectorT256);
}
}

// Only one VectorT ISA can be set, and we have validated that anything left in the flags is supported
// by both the hardware and the config. Remove everything less than the largest supported.

if (CPUCompileFlags.IsSet(InstructionSet_VectorT512))
{
CPUCompileFlags.Clear(InstructionSet_VectorT256);
CPUCompileFlags.Clear(InstructionSet_VectorT128);
}
else if (CPUCompileFlags.IsSet(InstructionSet_VectorT256))
{
CPUCompileFlags.Clear(InstructionSet_VectorT128);
}

#endif // TARGET_X86 || TARGET_AMD64

m_CPUCompileFlags = CPUCompileFlags;
Expand Down
2 changes: 1 addition & 1 deletion src/tests/Common/testenvironment.proj
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
<TestEnvironment Include="jitstress_isas_x86_nosse42" EnableSSE42="0" /> <!-- Depends on SSE41 -->
<TestEnvironment Include="jitstress_isas_x86_nossse3" EnableSSSE3="0" /> <!-- Depends on SSE3 -->
<TestEnvironment Include="jitstress_isas_x86_vectort128" JitStressEvexEncoding="1" MaxVectorTBitWidth="128" />
<TestEnvironment Include="jitstress_isas_x86_vectort512" JitStressEvexEncoding="1" MaxVectorTBitWidth="512" />
<TestEnvironment Include="jitstress_isas_x86_vectort512" JitStressEvexEncoding="1" PreferredVectorBitWidth="512" MaxVectorTBitWidth="512" />
<TestEnvironment Include="jitstress_isas_x86_noavx512_vectort128" EnableAVX512F="0" MaxVectorTBitWidth="128" />
<TestEnvironment Include="jitstress_isas_1_x86_noaes" JitStress="1" EnableAES="0" /> <!-- Depends on SSE2 -->
<TestEnvironment Include="jitstress_isas_1_x86_noavx" JitStress="1" EnableAVX="0" /> <!-- Depends on SSE42 -->
Expand Down
5 changes: 5 additions & 0 deletions src/tests/JIT/HardwareIntrinsics/X86/General/IsSupported.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public static void IsSupported()
if (Sse.IsSupported && int.TryParse(Environment.GetEnvironmentVariable("DOTNET_EnableIncompleteISAClass"), out var enableIncompleteIsa) && (enableIncompleteIsa != 0))
{
// X86 platforms
if (Vector<byte>.Count == 64 && !Avx512F.IsSupported)
{
result = false;
}

if (Vector<byte>.Count == 32 && !Avx2.IsSupported)
{
result = false;
Expand Down
4 changes: 2 additions & 2 deletions src/tests/JIT/HardwareIntrinsics/X86/X86Base/CpuId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -386,11 +386,11 @@ public unsafe static void CpuId()

if ((maxVectorTBitWidth >= 512) && !isAvx512HierarchyDisabled)
{
vectorTByteLength = 64;
vectorTByteLength = int.Min(64, preferredVectorByteLength);
}
else if ((maxVectorTBitWidth is 0 or >= 256) && !isAvx2HierarchyDisabled)
{
vectorTByteLength = 32;
vectorTByteLength = int.Min(32, preferredVectorByteLength);
}

if (Vector<byte>.Count != vectorTByteLength)
Expand Down

0 comments on commit 94cb2c5

Please sign in to comment.