Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2022-01-25 21:46:38 +0300
committerGitHub <noreply@github.com>2022-01-25 21:46:38 +0300
commitaa731324884707771991eb403eaf249f1eadfdf5 (patch)
tree85ad1ead14847b454aa85465db78ca4255389280
parent0a462a7db1a7f525399df6725e5cfd593e8f51e0 (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.cpp61
-rw-r--r--src/coreclr/jit/hwintrinsiccodegenarm64.cpp3
-rw-r--r--src/coreclr/jit/hwintrinsiccodegenxarch.cpp3
-rw-r--r--src/coreclr/jit/hwintrinsicxarch.cpp25
-rw-r--r--src/coreclr/jit/lowerxarch.cpp2
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;
}