diff options
author | github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> | 2022-01-25 21:46:38 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-25 21:46:38 +0300 |
commit | aa731324884707771991eb403eaf249f1eadfdf5 (patch) | |
tree | 85ad1ead14847b454aa85465db78ca4255389280 | |
parent | 0a462a7db1a7f525399df6725e5cfd593e8f51e0 (diff) |
[release/7.0-preview1] Ensure that we aren't accidentally generating instructions for unsupported ISAs (#64224)
* Assert that the ISA of the set intrinsic ID is supported
* Ensure gtNewSimdCmpOpAllNode and gtNewSimdCmpOpAnyNode don't generate AVX2 instructions when not supported
* Ensure codegen for Vector128.Dot when SSSE3 is disabled is correct
* Update src/coreclr/jit/hwintrinsiccodegenarm64.cpp
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
* Ensure Vector256.Sum has a check for AVX2
Co-authored-by: Tanner Gooding <tagoo@outlook.com>
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
-rw-r--r-- | src/coreclr/jit/gentree.cpp | 61 | ||||
-rw-r--r-- | src/coreclr/jit/hwintrinsiccodegenarm64.cpp | 3 | ||||
-rw-r--r-- | src/coreclr/jit/hwintrinsiccodegenxarch.cpp | 3 | ||||
-rw-r--r-- | src/coreclr/jit/hwintrinsicxarch.cpp | 25 | ||||
-rw-r--r-- | src/coreclr/jit/lowerxarch.cpp | 2 |
5 files changed, 64 insertions, 30 deletions
diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index ead4be32957..a6a7e73866a 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -19371,20 +19371,22 @@ GenTree* Compiler::gtNewSimdCmpOpAllNode(genTreeOps op, NamedIntrinsic intrinsic = NI_Illegal; -#if defined(TARGET_XARCH) - if (simdSize == 32) - { - assert(compIsaSupportedDebugOnly(InstructionSet_AVX)); - assert(varTypeIsFloating(simdBaseType) || compIsaSupportedDebugOnly(InstructionSet_AVX2)); - } -#endif // TARGET_XARCH - switch (op) { #if defined(TARGET_XARCH) case GT_EQ: { - intrinsic = (simdSize == 32) ? NI_Vector256_op_Equality : NI_Vector128_op_Equality; + if (simdSize == 32) + { + assert(compIsaSupportedDebugOnly(InstructionSet_AVX)); + assert(varTypeIsFloating(simdBaseType) || compIsaSupportedDebugOnly(InstructionSet_AVX2)); + + intrinsic = NI_Vector256_op_Equality; + } + else + { + intrinsic = NI_Vector128_op_Equality; + } break; } @@ -19400,6 +19402,12 @@ GenTree* Compiler::gtNewSimdCmpOpAllNode(genTreeOps op, if (simdSize == 32) { + // TODO-XArch-CQ: It's a non-trivial amount of work to support these + // for floating-point while only utilizing AVX. It would require, among + // other things, inverting the comparison and potentially support for a + // new Avx.TestNotZ intrinsic to ensure the codegen remains efficient. + assert(compIsaSupportedDebugOnly(InstructionSet_AVX2)); + intrinsic = NI_Vector256_op_Equality; getAllBitsSet = NI_Vector256_get_AllBitsSet; } @@ -19510,14 +19518,6 @@ GenTree* Compiler::gtNewSimdCmpOpAnyNode(genTreeOps op, NamedIntrinsic intrinsic = NI_Illegal; -#if defined(TARGET_XARCH) - if (simdSize == 32) - { - assert(compIsaSupportedDebugOnly(InstructionSet_AVX)); - assert(varTypeIsFloating(simdBaseType) || compIsaSupportedDebugOnly(InstructionSet_AVX2)); - } -#endif // TARGET_XARCH - switch (op) { #if defined(TARGET_XARCH) @@ -19530,7 +19530,20 @@ GenTree* Compiler::gtNewSimdCmpOpAnyNode(genTreeOps op, // We want to generate a comparison along the lines of // GT_XX(op1, op2).As<T, TInteger>() != Vector128<TInteger>.Zero - intrinsic = (simdSize == 32) ? NI_Vector256_op_Inequality : NI_Vector128_op_Inequality; + if (simdSize == 32) + { + // TODO-XArch-CQ: It's a non-trivial amount of work to support these + // for floating-point while only utilizing AVX. It would require, among + // other things, inverting the comparison and potentially support for a + // new Avx.TestNotZ intrinsic to ensure the codegen remains efficient. + assert(compIsaSupportedDebugOnly(InstructionSet_AVX2)); + + intrinsic = NI_Vector256_op_Inequality; + } + else + { + intrinsic = NI_Vector128_op_Inequality; + } op1 = gtNewSimdCmpOpNode(op, simdType, op1, op2, simdBaseJitType, simdSize, /* isSimdAsHWIntrinsic */ false); @@ -19552,7 +19565,17 @@ GenTree* Compiler::gtNewSimdCmpOpAnyNode(genTreeOps op, case GT_NE: { - intrinsic = (simdSize == 32) ? NI_Vector256_op_Inequality : NI_Vector128_op_Inequality; + if (simdSize == 32) + { + assert(compIsaSupportedDebugOnly(InstructionSet_AVX)); + assert(varTypeIsFloating(simdBaseType) || compIsaSupportedDebugOnly(InstructionSet_AVX2)); + + intrinsic = NI_Vector256_op_Inequality; + } + else + { + intrinsic = NI_Vector128_op_Inequality; + } break; } #elif defined(TARGET_ARM64) diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index e4b9a132668..6dfe48047c0 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -206,6 +206,9 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) { const HWIntrinsic intrin(node); + // We need to validate that other phases of the compiler haven't introduced unsupported intrinsics + assert(compiler->compIsaSupportedDebugOnly(HWIntrinsicInfo::lookupIsa(intrin.id))); + regNumber targetReg = node->GetRegNum(); regNumber op1Reg = REG_NA; diff --git a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp index d6490c59b2e..10c8dcaedb1 100644 --- a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp @@ -86,6 +86,9 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId); size_t numArgs = node->GetOperandCount(); + // We need to validate that other phases of the compiler haven't introduced unsupported intrinsics + assert(compiler->compIsaSupportedDebugOnly(isa)); + int ival = HWIntrinsicInfo::lookupIval(intrinsicId, compiler->compOpportunisticallyDependsOn(InstructionSet_AVX)); assert(HWIntrinsicInfo::RequiresCodegen(intrinsicId)); diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index f1b84825f21..aec1be705f3 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -1024,7 +1024,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, { assert(sig->numArgs == 2); - if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2)) + if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2)) { var_types simdType = getSIMDTypeForSize(simdSize); @@ -1287,7 +1287,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, { assert(sig->numArgs == 2); - if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2)) + if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2)) { var_types simdType = getSIMDTypeForSize(simdSize); @@ -1305,7 +1305,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, { assert(sig->numArgs == 2); - if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2)) + if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2)) { var_types simdType = getSIMDTypeForSize(simdSize); @@ -1339,7 +1339,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, { assert(sig->numArgs == 2); - if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2)) + if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2)) { var_types simdType = getSIMDTypeForSize(simdSize); @@ -1357,7 +1357,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, { assert(sig->numArgs == 2); - if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2)) + if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2)) { var_types simdType = getSIMDTypeForSize(simdSize); @@ -1391,7 +1391,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, { assert(sig->numArgs == 2); - if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2)) + if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2)) { var_types simdType = getSIMDTypeForSize(simdSize); @@ -1409,7 +1409,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, { assert(sig->numArgs == 2); - if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2)) + if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2)) { var_types simdType = getSIMDTypeForSize(simdSize); @@ -1443,7 +1443,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, { assert(sig->numArgs == 2); - if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2)) + if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2)) { var_types simdType = getSIMDTypeForSize(simdSize); @@ -1461,7 +1461,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, { assert(sig->numArgs == 2); - if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2)) + if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2)) { var_types simdType = getSIMDTypeForSize(simdSize); @@ -2024,7 +2024,12 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, assert(sig->numArgs == 1); var_types simdType = getSIMDTypeForSize(simdSize); - if (varTypeIsFloating(simdBaseType)) + if ((simdSize == 32) && !compOpportunisticallyDependsOn(InstructionSet_AVX2)) + { + // Vector256 for integer types requires AVX2 + break; + } + else if (varTypeIsFloating(simdBaseType)) { if (!compOpportunisticallyDependsOn(InstructionSet_SSE3)) { diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index 413e4ba74a6..316a1c5a546 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -3429,7 +3429,7 @@ void Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node) // e6, e7, e4, e5 | e2, e3, e0, e1 // e7, e6, e5, e4 | e3, e2, e1, e0 - shuffleConst = 0x4D; + shuffleConst = 0x4E; break; } |