Skip to content

Commit

Permalink
Ensure that InstructionSetFlags are correctly fixed up for unmatched …
Browse files Browse the repository at this point in the history
…VM (#64158)

* Ensure that InstructionSetFlags are correctly fixed up for unmatched VM

* Applying formatting patch
  • Loading branch information
tannergooding committed May 3, 2022
1 parent 6f563b3 commit a29f51a
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/coreclr/inc/clrconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_GDBJitEmitDebugFrame, W("GDBJitEmitDebugFrame"
#endif

//
// Hardware Intrinsic ISAs
// Hardware Intrinsic ISAs; keep in sync with jitconfigvalues.h
//
#if defined(TARGET_LOONGARCH64)
//TODO: should implement LoongArch64's features.
Expand Down
163 changes: 151 additions & 12 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5585,24 +5585,163 @@ int Compiler::compCompile(CORINFO_MODULE_HANDLE classPtr,

if (!info.compMatchedVM)
{
#if defined(TARGET_ARM)
CORINFO_InstructionSetFlags instructionSetFlags;

// Currently nothing needs to be done. There are no ARM flags that conflict with other flags.
// We need to assume, by default, that all flags coming from the VM are invalid.
instructionSetFlags.Reset();

#endif // defined(TARGET_ARM)
// We then add each available instruction set for the target architecture provided
// that the corresponding JitConfig switch hasn't explicitly asked for it to be
// disabled. This allows us to default to "everything" supported for altjit scenarios
// while also still allowing instruction set opt-out providing users with the ability
// to, for example, see and debug ARM64 codegen for any desired CPU configuration without
// needing to have the hardware in question.

#if defined(TARGET_ARM64)
if (JitConfig.EnableHWIntrinsic() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_ArmBase);
}

// The x86/x64 architecture capabilities flags overlap with the ARM64 ones. Set a reasonable architecture
// target default. Currently this is disabling all ARM64 architecture features except FP and SIMD, but this
// should be altered to possibly enable all of them, when they are known to all work.
if (JitConfig.EnableArm64AdvSimd() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_AdvSimd);
}

CORINFO_InstructionSetFlags defaultArm64Flags;
defaultArm64Flags.AddInstructionSet(InstructionSet_ArmBase);
defaultArm64Flags.AddInstructionSet(InstructionSet_AdvSimd);
defaultArm64Flags.Set64BitInstructionSetVariants();
compileFlags->SetInstructionSetFlags(defaultArm64Flags);
#endif // defined(TARGET_ARM64)
if (JitConfig.EnableArm64Aes() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_Aes);
}

if (JitConfig.EnableArm64Crc32() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_Crc32);
}

if (JitConfig.EnableArm64Dp() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_Dp);
}

if (JitConfig.EnableArm64Rdm() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_Rdm);
}

if (JitConfig.EnableArm64Sha1() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_Sha1);
}

if (JitConfig.EnableArm64Sha256() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_Sha256);
}

if (JitConfig.EnableArm64Atomics() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_Atomics);
}

if (JitConfig.EnableArm64Dczva() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_Dczva);
}
#elif defined(TARGET_XARCH)
if (JitConfig.EnableHWIntrinsic() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_X86Base);
}

if (JitConfig.EnableSSE() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_SSE);
}

if (JitConfig.EnableSSE2() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_SSE2);
}

if ((JitConfig.EnableSSE3() != 0) && (JitConfig.EnableSSE3_4() != 0))
{
instructionSetFlags.AddInstructionSet(InstructionSet_SSE3);
}

if (JitConfig.EnableSSSE3() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_SSSE3);
}

if (JitConfig.EnableSSE41() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_SSE41);
}

if (JitConfig.EnableSSE42() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_SSE42);
}

if (JitConfig.EnableAVX() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_AVX);
}

if (JitConfig.EnableAVX2() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_AVX2);
}

if (JitConfig.EnableAES() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_AES);
}

if (JitConfig.EnableBMI1() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_BMI1);
}

if (JitConfig.EnableBMI2() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_BMI2);
}

if (JitConfig.EnableFMA() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_FMA);
}

if (JitConfig.EnableLZCNT() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_LZCNT);
}

if (JitConfig.EnablePCLMULQDQ() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_PCLMULQDQ);
}

if (JitConfig.EnablePOPCNT() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_POPCNT);
}

if (JitConfig.EnableAVXVNNI() != 0)
{
instructionSetFlags.AddInstructionSet(InstructionSet_AVXVNNI);
}
#endif

// These calls are important and explicitly ordered to ensure that the flags are correct in
// the face of missing or removed instruction sets. Without them, we might end up with incorrect
// downstream checks.

instructionSetFlags.Set64BitInstructionSetVariants();
instructionSetFlags = EnsureInstructionSetFlagsAreValid(instructionSetFlags);

compileFlags->SetInstructionSetFlags(instructionSetFlags);
}

compMaxUncheckedOffsetForNullObject = eeGetEEInfo()->maxUncheckedOffsetForNullObject;
Expand Down
37 changes: 37 additions & 0 deletions src/coreclr/jit/jitconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,43 @@ CONFIG_INTEGER(EnableEHWriteThru, W("EnableEHWriteThru"), 1) // Enable the regis
CONFIG_INTEGER(EnableMultiRegLocals, W("EnableMultiRegLocals"), 1) // Enable the enregistration of locals that are
// defined or used in a multireg context.

// clang-format off

//
// Hardware Intrinsic ISAs; keep in sync with clrconfigvalues.h
//
CONFIG_INTEGER(EnableHWIntrinsic, W("EnableHWIntrinsic"), 1) // Allows Base+ hardware intrinsics to be disabled

#if defined(TARGET_AMD64) || defined(TARGET_X86)
CONFIG_INTEGER(EnableAES, W("EnableAES"), 1) // Allows AES+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableAVX, W("EnableAVX"), 1) // Allows AVX+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableAVX2, W("EnableAVX2"), 1) // Allows AVX2+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableAVXVNNI, W("EnableAVXVNNI"), 1) // Allows AVX VNNI+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableBMI1, W("EnableBMI1"), 1) // Allows BMI1+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableBMI2, W("EnableBMI2"), 1) // Allows BMI2+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableFMA, W("EnableFMA"), 1) // Allows FMA+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableLZCNT, W("EnableLZCNT"), 1) // Allows LZCNT+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnablePCLMULQDQ, W("EnablePCLMULQDQ"), 1) // Allows PCLMULQDQ+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnablePOPCNT, W("EnablePOPCNT"), 1) // Allows POPCNT+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableSSE, W("EnableSSE"), 1) // Allows SSE+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableSSE2, W("EnableSSE2"), 1) // Allows SSE2+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableSSE3, W("EnableSSE3"), 1) // Allows SSE3+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableSSE3_4, W("EnableSSE3_4"), 1) // Allows SSE3+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableSSE41, W("EnableSSE41"), 1) // Allows SSE4.1+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableSSE42, W("EnableSSE42"), 1) // Allows SSE4.2+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableSSSE3, W("EnableSSSE3"), 1) // Allows SSSE3+ hardware intrinsics to be disabled
#elif defined(TARGET_ARM64)
CONFIG_INTEGER(EnableArm64AdvSimd, W("EnableArm64AdvSimd"), 1) // Allows Arm64 AdvSimd+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableArm64Aes, W("EnableArm64Aes"), 1) // Allows Arm64 Aes+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableArm64Atomics, W("EnableArm64Atomics"), 1) // Allows Arm64 Atomics+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableArm64Crc32, W("EnableArm64Crc32"), 1) // Allows Arm64 Crc32+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableArm64Dczva, W("EnableArm64Dczva"), 1) // Allows Arm64 Dczva+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableArm64Dp, W("EnableArm64Dp"), 1) // Allows Arm64 Dp+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableArm64Rdm, W("EnableArm64Rdm"), 1) // Allows Arm64 Rdm+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableArm64Sha1, W("EnableArm64Sha1"), 1) // Allows Arm64 Sha1+ hardware intrinsics to be disabled
CONFIG_INTEGER(EnableArm64Sha256, W("EnableArm64Sha256"), 1) // Allows Arm64 Sha256+ hardware intrinsics to be disabled
#endif

// clang-format on

#ifdef FEATURE_SIMD
Expand Down

0 comments on commit a29f51a

Please sign in to comment.