Skip to content

Commit 2dc5e64

Browse files
committed
Ensure we lie about the type for TYP_SIMD32 bitwise ops when only AVX is supported
1 parent e294559 commit 2dc5e64

File tree

2 files changed

+61
-24
lines changed

2 files changed

+61
-24
lines changed

src/coreclr/jit/gentree.cpp

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19133,14 +19133,22 @@ GenTree* Compiler::gtNewSimdBinOpNode(genTreeOps op,
1913319133
{
1913419134
assert(compIsaSupportedDebugOnly(InstructionSet_AVX));
1913519135

19136-
if (varTypeIsFloating(simdBaseType) || !compOpportunisticallyDependsOn(InstructionSet_AVX2))
19136+
if (varTypeIsFloating(simdBaseType))
1913719137
{
1913819138
intrinsic = NI_AVX_And;
1913919139
}
19140-
else
19140+
else if (compOpportunisticallyDependsOn(InstructionSet_AVX2))
1914119141
{
1914219142
intrinsic = NI_AVX2_And;
1914319143
}
19144+
else
19145+
{
19146+
// Since this is a bitwise operation, we can still support it by lying
19147+
// about the type and doing the operation using a supported instruction
19148+
19149+
intrinsic = NI_AVX_And;
19150+
simdBaseJitType = CORINFO_TYPE_FLOAT;
19151+
}
1914419152
}
1914519153
else if (simdBaseType == TYP_FLOAT)
1914619154
{
@@ -19159,14 +19167,22 @@ GenTree* Compiler::gtNewSimdBinOpNode(genTreeOps op,
1915919167
{
1916019168
assert(compIsaSupportedDebugOnly(InstructionSet_AVX));
1916119169

19162-
if (varTypeIsFloating(simdBaseType) || !compOpportunisticallyDependsOn(InstructionSet_AVX2))
19170+
if (varTypeIsFloating(simdBaseType))
1916319171
{
1916419172
intrinsic = NI_AVX_AndNot;
1916519173
}
19166-
else
19174+
else if (compOpportunisticallyDependsOn(InstructionSet_AVX2))
1916719175
{
1916819176
intrinsic = NI_AVX2_AndNot;
1916919177
}
19178+
else
19179+
{
19180+
// Since this is a bitwise operation, we can still support it by lying
19181+
// about the type and doing the operation using a supported instruction
19182+
19183+
intrinsic = NI_AVX_AndNot;
19184+
simdBaseJitType = CORINFO_TYPE_FLOAT;
19185+
}
1917019186
}
1917119187
else if (simdBaseType == TYP_FLOAT)
1917219188
{
@@ -19337,14 +19353,22 @@ GenTree* Compiler::gtNewSimdBinOpNode(genTreeOps op,
1933719353
{
1933819354
assert(compIsaSupportedDebugOnly(InstructionSet_AVX));
1933919355

19340-
if (varTypeIsFloating(simdBaseType) || !compOpportunisticallyDependsOn(InstructionSet_AVX2))
19356+
if (varTypeIsFloating(simdBaseType))
1934119357
{
1934219358
intrinsic = NI_AVX_Or;
1934319359
}
19344-
else
19360+
else if (compOpportunisticallyDependsOn(InstructionSet_AVX2))
1934519361
{
1934619362
intrinsic = NI_AVX2_Or;
1934719363
}
19364+
else
19365+
{
19366+
// Since this is a bitwise operation, we can still support it by lying
19367+
// about the type and doing the operation using a supported instruction
19368+
19369+
intrinsic = NI_AVX_Or;
19370+
simdBaseJitType = CORINFO_TYPE_FLOAT;
19371+
}
1934819372
}
1934919373
else if (simdBaseType == TYP_FLOAT)
1935019374
{
@@ -19390,14 +19414,22 @@ GenTree* Compiler::gtNewSimdBinOpNode(genTreeOps op,
1939019414
{
1939119415
assert(compIsaSupportedDebugOnly(InstructionSet_AVX));
1939219416

19393-
if (varTypeIsFloating(simdBaseType) || !compOpportunisticallyDependsOn(InstructionSet_AVX2))
19417+
if (varTypeIsFloating(simdBaseType))
1939419418
{
1939519419
intrinsic = NI_AVX_Xor;
1939619420
}
19397-
else
19421+
else if (compOpportunisticallyDependsOn(InstructionSet_AVX2))
1939819422
{
1939919423
intrinsic = NI_AVX2_Xor;
1940019424
}
19425+
else
19426+
{
19427+
// Since this is a bitwise operation, we can still support it by lying
19428+
// about the type and doing the operation using a supported instruction
19429+
19430+
intrinsic = NI_AVX_Xor;
19431+
simdBaseJitType = CORINFO_TYPE_FLOAT;
19432+
}
1940119433
}
1940219434
else if (simdBaseType == TYP_FLOAT)
1940319435
{
@@ -20458,18 +20490,19 @@ GenTree* Compiler::gtNewSimdDotProdNode(var_types type,
2045820490
bool isSimdAsHWIntrinsic)
2045920491
{
2046020492
assert(IsBaselineSimdIsaSupportedDebugOnly());
20493+
assert(varTypeIsArithmetic(type));
2046120494

20462-
assert(varTypeIsSIMD(type));
20463-
assert(getSIMDTypeForSize(simdSize) == type);
20495+
var_types simdType = getSIMDTypeForSize(simdSize);
20496+
assert(varTypeIsSIMD(simdType));
2046420497

2046520498
assert(op1 != nullptr);
20466-
assert(op1->TypeGet() == type);
20499+
assert(op1->TypeGet() == simdType);
2046720500

2046820501
assert(op2 != nullptr);
20469-
assert(op2->TypeGet() == type);
20502+
assert(op2->TypeGet() == simdType);
2047020503

2047120504
var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType);
20472-
assert(varTypeIsArithmetic(simdBaseType));
20505+
assert(genActualType(simdBaseType) == type);
2047320506

2047420507
NamedIntrinsic intrinsic = NI_Illegal;
2047520508

@@ -21061,11 +21094,7 @@ GenTree* Compiler::gtNewSimdUnOpNode(genTreeOps op,
2106121094

2106221095
case GT_NOT:
2106321096
{
21064-
if (simdSize == 32)
21065-
{
21066-
assert(compIsaSupportedDebugOnly(InstructionSet_AVX));
21067-
assert(varTypeIsFloating(simdBaseType) || compIsaSupportedDebugOnly(InstructionSet_AVX2));
21068-
}
21097+
assert((simdSize != 32) || compIsaSupportedDebugOnly(InstructionSet_AVX));
2106921098

2107021099
intrinsic = (simdSize == 32) ? NI_Vector256_get_AllBitsSet : NI_Vector128_get_AllBitsSet;
2107121100
op2 = gtNewSimdHWIntrinsicNode(type, intrinsic, simdBaseJitType, simdSize, isSimdAsHWIntrinsic);

src/coreclr/jit/hwintrinsicxarch.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,10 +1214,14 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
12141214
{
12151215
assert(sig->numArgs == 2);
12161216

1217-
op2 = impSIMDPopStack(retType);
1218-
op1 = impSIMDPopStack(retType);
1217+
if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2))
1218+
{
1219+
op2 = impSIMDPopStack(retType);
1220+
op1 = impSIMDPopStack(retType);
12191221

1220-
retNode = gtNewSimdMaxNode(retType, op1, op2, simdBaseJitType, simdSize, /* isSimdAsHWIntrinsic */ false);
1222+
retNode =
1223+
gtNewSimdMaxNode(retType, op1, op2, simdBaseJitType, simdSize, /* isSimdAsHWIntrinsic */ false);
1224+
}
12211225
break;
12221226
}
12231227

@@ -1226,10 +1230,14 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
12261230
{
12271231
assert(sig->numArgs == 2);
12281232

1229-
op2 = impSIMDPopStack(retType);
1230-
op1 = impSIMDPopStack(retType);
1233+
if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2))
1234+
{
1235+
op2 = impSIMDPopStack(retType);
1236+
op1 = impSIMDPopStack(retType);
12311237

1232-
retNode = gtNewSimdMinNode(retType, op1, op2, simdBaseJitType, simdSize, /* isSimdAsHWIntrinsic */ false);
1238+
retNode =
1239+
gtNewSimdMinNode(retType, op1, op2, simdBaseJitType, simdSize, /* isSimdAsHWIntrinsic */ false);
1240+
}
12331241
break;
12341242
}
12351243

0 commit comments

Comments
 (0)