Skip to content
Prev Previous commit
Next Next commit
Ensure the Avx512F and related classes can lightup in import
  • Loading branch information
tannergooding committed Mar 16, 2023
commit 7cb6fe3fa3f4bb2e73ee55a69ea20b0ddea42e6e
11 changes: 10 additions & 1 deletion src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2287,7 +2287,16 @@ void Compiler::compSetProcessor()
instructionSetFlags.HasInstructionSet(InstructionSet_AVX512BW) &&
instructionSetFlags.HasInstructionSet(InstructionSet_AVX512DQ))
{
if (!DoJitStressEvexEncoding())
// Using JitStressEVEXEncoding flag will force instructions which would
// otherwise use VEX encoding but can be EVEX encoded to use EVEX encoding
// This requires AVX512VL support. JitForceEVEXEncoding forces this encoding, thus
// causing failure if not running on compatible hardware.

// We can't use !DoJitStressEvexEncoding() yet because opts.compSupportsISA hasn't
// been set yet as that's what we're trying to set here

if (!JitConfig.JitForceEVEXEncoding() && !JitConfig.JitStressEvexEncoding() &&
!instructionSetFlags.HasInstructionSet(InstructionSet_AVX512F_VL))
Copy link
Member Author

@tannergooding tannergooding Mar 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was previously !DoJitStressEvexEncoding() and was preventing just JitStressEvexEncoding from working since the support check for AVX512F_VL would always fail.

{
instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512F);
instructionSetFlags.RemoveInstructionSet(InstructionSet_AVX512F_VL);
Expand Down
8 changes: 8 additions & 0 deletions src/coreclr/jit/emitxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17757,9 +17757,17 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins
case INS_paddusw:
case INS_psubusw:
case INS_pand:
case INS_vpandd:
case INS_vpandq:
case INS_pandn:
case INS_vpandnd:
case INS_vpandnq:
case INS_por:
case INS_vpord:
case INS_vporq:
case INS_pxor:
case INS_vpxord:
case INS_vpxorq:
case INS_andpd:
case INS_andps:
case INS_andnpd:
Expand Down
22 changes: 17 additions & 5 deletions src/coreclr/jit/hwintrinsic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ static bool isSupportedBaseType(NamedIntrinsic intrinsic, CorInfoType baseJitTyp
#ifdef DEBUG
CORINFO_InstructionSet isa = HWIntrinsicInfo::lookupIsa(intrinsic);
#ifdef TARGET_XARCH
assert((isa == InstructionSet_Vector256) || (isa == InstructionSet_Vector128));
assert((isa == InstructionSet_Vector512) || (isa == InstructionSet_Vector256) || (isa == InstructionSet_Vector128));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assert was missing and so we weren't actually testing any InstructionSet_Vector512 paths yet.

#endif // TARGET_XARCH
#ifdef TARGET_ARM64
assert((isa == InstructionSet_Vector64) || (isa == InstructionSet_Vector128));
Expand Down Expand Up @@ -976,11 +976,23 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,

assert(numArgs >= 0);

if (!isScalar && ((HWIntrinsicInfo::lookupIns(intrinsic, simdBaseType) == INS_invalid) ||
((simdSize != 8) && (simdSize != 16) && (simdSize != 32))))
if (!isScalar)
{
assert(!"Unexpected HW Intrinsic");
return nullptr;
if (HWIntrinsicInfo::lookupIns(intrinsic, simdBaseType) == INS_invalid)
{
assert(!"Unexpected HW intrinsic");
return nullptr;
}

#if defined(TARGET_ARM64)
if ((simdSize != 8) && (simdSize != 16))
#elif defined(TARGET_XARCH)
if ((simdSize != 16) && (simdSize != 32) && (simdSize != 64))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for this check against simdSize != 64

#endif // TARGET_*
{
assert(!"Unexpected SIMD size");
return nullptr;
}
}

GenTree* op1 = nullptr;
Expand Down
67 changes: 67 additions & 0 deletions src/coreclr/jit/hwintrinsicxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,22 @@ static CORINFO_InstructionSet X64VersionOfIsa(CORINFO_InstructionSet isa)
return InstructionSet_AVX_X64;
case InstructionSet_AVX2:
return InstructionSet_AVX2_X64;
case InstructionSet_AVX512BW:
return InstructionSet_AVX512BW_X64;
case InstructionSet_AVX512BW_VL:
return InstructionSet_AVX512BW_VL_X64;
case InstructionSet_AVX512CD:
return InstructionSet_AVX512CD_X64;
case InstructionSet_AVX512CD_VL:
return InstructionSet_AVX512CD_VL_X64;
case InstructionSet_AVX512DQ:
return InstructionSet_AVX512DQ_X64;
case InstructionSet_AVX512DQ_VL:
return InstructionSet_AVX512DQ_VL_X64;
case InstructionSet_AVX512F:
return InstructionSet_AVX512F_X64;
case InstructionSet_AVX512F_VL:
return InstructionSet_AVX512F_VL_X64;
case InstructionSet_AVXVNNI:
return InstructionSet_AVXVNNI_X64;
case InstructionSet_AES:
Expand All @@ -59,6 +75,31 @@ static CORINFO_InstructionSet X64VersionOfIsa(CORINFO_InstructionSet isa)
}
}

//------------------------------------------------------------------------
// VLVersionOfIsa: Gets the corresponding AVX512VL only InstructionSet for a given InstructionSet
//
// Arguments:
// isa -- The InstructionSet ID
//
// Return Value:
// The AVX512VL only InstructionSet associated with isa
static CORINFO_InstructionSet VLVersionOfIsa(CORINFO_InstructionSet isa)
{
switch (isa)
{
case InstructionSet_AVX512BW:
return InstructionSet_AVX512BW_VL;
case InstructionSet_AVX512CD:
return InstructionSet_AVX512CD_VL;
case InstructionSet_AVX512DQ:
return InstructionSet_AVX512DQ_VL;
case InstructionSet_AVX512F:
return InstructionSet_AVX512F_VL;
default:
return InstructionSet_NONE;
}
}

//------------------------------------------------------------------------
// lookupInstructionSet: Gets the InstructionSet for a given class name
//
Expand All @@ -84,6 +125,22 @@ static CORINFO_InstructionSet lookupInstructionSet(const char* className)
{
return InstructionSet_AVX2;
}
if (strcmp(className, "Avx512BW") == 0)
{
return InstructionSet_AVX512BW;
}
if (strcmp(className, "Avx512CD") == 0)
{
return InstructionSet_AVX512CD;
}
if (strcmp(className, "Avx512DQ") == 0)
{
return InstructionSet_AVX512DQ;
}
if (strcmp(className, "Avx512F") == 0)
{
return InstructionSet_AVX512F;
}
if (strcmp(className, "AvxVnni") == 0)
{
return InstructionSet_AVXVNNI;
Expand Down Expand Up @@ -152,6 +209,11 @@ static CORINFO_InstructionSet lookupInstructionSet(const char* className)
{
return InstructionSet_Vector512;
}
else if (strcmp(className, "VL") == 0)
{
assert(!"VL.X64 support doesn't exist in the managed libraries and so is not yet implemented");
return InstructionSet_ILLEGAL;
}
}
else if (strcmp(className, "Fma") == 0)
{
Expand Down Expand Up @@ -191,6 +253,11 @@ CORINFO_InstructionSet HWIntrinsicInfo::lookupIsa(const char* className, const c
assert(enclosingClassName != nullptr);
return X64VersionOfIsa(lookupInstructionSet(enclosingClassName));
}
else if (strcmp(className, "VL") == 0)
{
assert(enclosingClassName != nullptr);
return VLVersionOfIsa(lookupInstructionSet(enclosingClassName));
}
else
{
return lookupInstructionSet(className);
Expand Down