Skip to content

Commit 57fc9dc

Browse files
Update the JIT to share the xplat vector tables across platforms (#130049)
This massively simplifies and unifies the xplat vector intrinsic support by unifying it to a single table and instruction set. It removes around 3000 lines of code (more simplifications are possible in the future as well) and enables us to add WASM and Arm64 SVE support for the xplat intrinsics without duplicating the import logic two more times. I've generally split it out into two commits. The first is the general refactoring and the second is some of the base support for WASM lightup. There's some pending platform specific work and some more xplat work required before WASM can be fully enabled.
1 parent c538bdd commit 57fc9dc

39 files changed

Lines changed: 6100 additions & 9188 deletions

src/coreclr/inc/corinfoinstructionset.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
enum CORINFO_InstructionSet
1515
{
1616
InstructionSet_ILLEGAL = 0,
17+
InstructionSet_Vector = 126,
1718
InstructionSet_NONE = 127,
1819
#ifdef TARGET_ARM64
1920
InstructionSet_ArmBase=1,

src/coreclr/jit/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ set( JIT_HEADERS
368368
host.h
369369
hostallocator.h
370370
hwintrinsic.h
371+
hwintrinsiclist.h
371372
ICorJitInfo_names_generated.h
372373
ICorJitInfo_wrapper_generated.hpp
373374
inline.h

src/coreclr/jit/assertionprop.cpp

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -340,16 +340,12 @@ static Range GetRange(Compiler* comp, GenTree* tree, BasicBlock* block, ASSERT_V
340340
switch (id)
341341
{
342342
#if defined(TARGET_XARCH)
343-
case NI_Vector256_ExtractMostSignificantBits:
344-
case NI_Vector512_ExtractMostSignificantBits:
345343
case NI_X86Base_MoveMask:
346344
case NI_AVX_MoveMask:
347345
case NI_AVX2_MoveMask:
348346
case NI_AVX512_MoveMask:
349-
#elif defined(TARGET_ARM64)
350-
case NI_Vector64_ExtractMostSignificantBits:
351347
#endif
352-
case NI_Vector128_ExtractMostSignificantBits:
348+
case NI_Vector_ExtractMostSignificantBits:
353349
{
354350
// We have 1 bit per element, remaining upper bits are 0
355351

@@ -1948,23 +1944,10 @@ AssertionInfo Compiler::optAssertionGenJtrue(GenTree* tree)
19481944
GenTreeHWIntrinsic* hwi = op1->AsHWIntrinsic();
19491945
switch (hwi->GetHWIntrinsicId())
19501946
{
1951-
#if defined(TARGET_XARCH)
1952-
case NI_Vector128_op_Equality:
1953-
case NI_Vector256_op_Equality:
1954-
case NI_Vector512_op_Equality:
1955-
#elif defined(TARGET_ARM64)
1956-
case NI_Vector64_op_Equality:
1957-
case NI_Vector128_op_Equality:
1958-
#endif
1947+
case NI_Vector_op_Equality:
19591948
break;
1960-
#if defined(TARGET_XARCH)
1961-
case NI_Vector128_op_Inequality:
1962-
case NI_Vector256_op_Inequality:
1963-
case NI_Vector512_op_Inequality:
1964-
#elif defined(TARGET_ARM64)
1965-
case NI_Vector64_op_Inequality:
1966-
case NI_Vector128_op_Inequality:
1967-
#endif
1949+
1950+
case NI_Vector_op_Inequality:
19681951
equals = !equals;
19691952
break;
19701953

src/coreclr/jit/codegenxarch.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5431,12 +5431,11 @@ void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree)
54315431
GenTreeHWIntrinsic* hwintrinsic = data->AsHWIntrinsic();
54325432
NamedIntrinsic intrinsicId = hwintrinsic->GetHWIntrinsicId();
54335433
var_types baseType = hwintrinsic->GetSimdBaseType();
5434+
unsigned simdSize = hwintrinsic->GetSimdSize();
54345435

54355436
switch (intrinsicId)
54365437
{
5437-
case NI_Vector128_ToScalar:
5438-
case NI_Vector256_ToScalar:
5439-
case NI_Vector512_ToScalar:
5438+
case NI_Vector_ToScalar:
54405439
case NI_X86Base_ConvertToInt32:
54415440
case NI_X86Base_ConvertToUInt32:
54425441
case NI_X86Base_X64_ConvertToInt64:
@@ -5457,9 +5456,10 @@ void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree)
54575456
break;
54585457
}
54595458

5460-
case NI_Vector128_GetElement:
5459+
case NI_Vector_GetElement:
54615460
{
54625461
assert(baseType == TYP_FLOAT);
5462+
assert(simdSize == 16);
54635463
FALLTHROUGH;
54645464
}
54655465

src/coreclr/jit/compiler.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3524,6 +3524,7 @@ class Compiler
35243524

35253525
GenTree* gtNewSimdGetIndicesNode(var_types type, var_types simdBaseType, unsigned simdSize);
35263526

3527+
#if defined(TARGET_XARCH) || defined(TARGET_ARM64)
35273528
GenTree* gtNewSimdGetLowerNode(var_types type,
35283529
GenTree* op1,
35293530
var_types simdBaseType,
@@ -3533,6 +3534,7 @@ class Compiler
35333534
GenTree* op1,
35343535
var_types simdBaseType,
35353536
unsigned simdSize);
3537+
#endif // !TARGET_XARCH && !TARGET_ARM64
35363538

35373539
GenTree* gtNewSimdIsEvenIntegerNode(var_types type,
35383540
GenTree* op1,
@@ -3724,6 +3726,7 @@ class Compiler
37243726
var_types simdBaseType,
37253727
unsigned simdSize);
37263728

3729+
#if defined(TARGET_XARCH) || defined(TARGET_ARM64)
37273730
GenTree* gtNewSimdWithLowerNode(var_types type,
37283731
GenTree* op1,
37293732
GenTree* op2,
@@ -3735,6 +3738,7 @@ class Compiler
37353738
GenTree* op2,
37363739
var_types simdBaseType,
37373740
unsigned simdSize);
3741+
#endif // !TARGET_XARCH && !TARGET_ARM64
37383742

37393743
GenTreeHWIntrinsic* gtNewScalarHWIntrinsicNode(var_types type, NamedIntrinsic hwIntrinsicID);
37403744
GenTreeHWIntrinsic* gtNewScalarHWIntrinsicNode(var_types type, GenTree* op1, NamedIntrinsic hwIntrinsicID);
@@ -5358,6 +5362,16 @@ class Compiler
53585362
unsigned simdSize,
53595363
bool mustExpand);
53605364

5365+
GenTree* impXplatIntrinsic(NamedIntrinsic intrinsic,
5366+
CORINFO_CLASS_HANDLE clsHnd,
5367+
CORINFO_METHOD_HANDLE method,
5368+
CORINFO_SIG_INFO* sig
5369+
R2RARG(CORINFO_CONST_LOOKUP* entryPoint),
5370+
var_types simdBaseType,
5371+
var_types retType,
5372+
unsigned simdSize,
5373+
bool mustExpand);
5374+
53615375
GenTree* getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE argClass);
53625376
GenTree* impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, var_types simdBaseType);
53635377
GenTree* addRangeCheckIfNeeded(

src/coreclr/jit/decomposelongs.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,16 +1909,12 @@ GenTree* DecomposeLongs::DecomposeHWIntrinsic(LIR::Use& use)
19091909

19101910
switch (hwintrinsicTree->GetHWIntrinsicId())
19111911
{
1912-
case NI_Vector128_GetElement:
1913-
case NI_Vector256_GetElement:
1914-
case NI_Vector512_GetElement:
1912+
case NI_Vector_GetElement:
19151913
{
19161914
return DecomposeHWIntrinsicGetElement(use, hwintrinsicTree);
19171915
}
19181916

1919-
case NI_Vector128_ToScalar:
1920-
case NI_Vector256_ToScalar:
1921-
case NI_Vector512_ToScalar:
1917+
case NI_Vector_ToScalar:
19221918
{
19231919
return DecomposeHWIntrinsicToScalar(use, hwintrinsicTree);
19241920
}
@@ -1939,7 +1935,7 @@ GenTree* DecomposeLongs::DecomposeHWIntrinsic(LIR::Use& use)
19391935
}
19401936

19411937
//------------------------------------------------------------------------
1942-
// DecomposeHWIntrinsicGetElement: Decompose GT_HWINTRINSIC -- NI_Vector*_GetElement.
1938+
// DecomposeHWIntrinsicGetElement: Decompose GT_HWINTRINSIC -- NI_Vector_GetElement.
19431939
//
19441940
// Decompose a get[i] node on Vector*<long>. For:
19451941
//
@@ -1953,7 +1949,7 @@ GenTree* DecomposeLongs::DecomposeHWIntrinsic(LIR::Use& use)
19531949
// hi_result = GT_HWINTRINSIC{GetElement}[int](tmp_simd_var, tmp_index_times_two + 1)
19541950
// return: GT_LONG(lo_result, hi_result)
19551951
//
1956-
// This isn't optimal codegen, since NI_Vector*_GetElement sometimes requires
1952+
// This isn't optimal codegen, since NI_Vector_GetElement sometimes requires
19571953
// temps that could be shared, for example.
19581954
//
19591955
// Arguments:
@@ -2048,7 +2044,7 @@ GenTree* DecomposeLongs::DecomposeHWIntrinsicGetElement(LIR::Use& use, GenTreeHW
20482044
}
20492045

20502046
//------------------------------------------------------------------------
2051-
// DecomposeHWIntrinsicToScalar: Decompose GT_HWINTRINSIC -- NI_Vector*_ToScalar.
2047+
// DecomposeHWIntrinsicToScalar: Decompose GT_HWINTRINSIC -- NI_Vector_ToScalar.
20522048
//
20532049
// create:
20542050
//

src/coreclr/jit/fgbasic.cpp

Lines changed: 30 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,26 +1191,17 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
11911191
case NI_ArmBase_Arm64_ReverseElementBits:
11921192
case NI_ArmBase_LeadingZeroCount:
11931193
case NI_ArmBase_ReverseElementBits:
1194-
case NI_Vector64_Create:
1195-
case NI_Vector64_CreateScalar:
1196-
case NI_Vector64_CreateScalarUnsafe:
11971194
#endif // TARGET_ARM64
1198-
case NI_Vector128_Create:
1199-
case NI_Vector128_CreateScalar:
1200-
case NI_Vector128_CreateScalarUnsafe:
1195+
case NI_Vector_Create:
1196+
case NI_Vector_CreateScalar:
1197+
case NI_Vector_CreateScalarUnsafe:
12011198
#if defined(TARGET_XARCH)
12021199
case NI_AVX2_LeadingZeroCount:
12031200
case NI_AVX2_TrailingZeroCount:
12041201
case NI_AVX2_X64_LeadingZeroCount:
12051202
case NI_AVX2_X64_TrailingZeroCount:
12061203
case NI_X86Base_PopCount:
12071204
case NI_X86Base_X64_PopCount:
1208-
case NI_Vector256_Create:
1209-
case NI_Vector512_Create:
1210-
case NI_Vector256_CreateScalar:
1211-
case NI_Vector512_CreateScalar:
1212-
case NI_Vector256_CreateScalarUnsafe:
1213-
case NI_Vector512_CreateScalarUnsafe:
12141205
case NI_X86Base_BitScanForward:
12151206
case NI_X86Base_X64_BitScanForward:
12161207
case NI_X86Base_BitScanReverse:
@@ -1425,67 +1416,21 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
14251416
}
14261417

14271418
#if defined(FEATURE_HW_INTRINSICS)
1428-
#if defined(TARGET_ARM64)
1429-
case NI_Vector64_As:
1430-
case NI_Vector64_AsByte:
1431-
case NI_Vector64_AsDouble:
1432-
case NI_Vector64_AsInt16:
1433-
case NI_Vector64_AsInt32:
1434-
case NI_Vector64_AsInt64:
1435-
case NI_Vector64_AsNInt:
1436-
case NI_Vector64_AsNUInt:
1437-
case NI_Vector64_AsSByte:
1438-
case NI_Vector64_AsSingle:
1439-
case NI_Vector64_AsUInt16:
1440-
case NI_Vector64_AsUInt32:
1441-
case NI_Vector64_AsUInt64:
1442-
case NI_Vector64_op_UnaryPlus:
1443-
#endif // TARGET_ARM64
1444-
case NI_Vector128_As:
1445-
case NI_Vector128_AsByte:
1446-
case NI_Vector128_AsDouble:
1447-
case NI_Vector128_AsInt16:
1448-
case NI_Vector128_AsInt32:
1449-
case NI_Vector128_AsInt64:
1450-
case NI_Vector128_AsNInt:
1451-
case NI_Vector128_AsNUInt:
1452-
case NI_Vector128_AsSByte:
1453-
case NI_Vector128_AsSingle:
1454-
case NI_Vector128_AsUInt16:
1455-
case NI_Vector128_AsUInt32:
1456-
case NI_Vector128_AsUInt64:
1457-
case NI_Vector128_AsVector4:
1458-
case NI_Vector128_op_UnaryPlus:
1459-
#if defined(TARGET_XARCH)
1460-
case NI_Vector256_As:
1461-
case NI_Vector256_AsByte:
1462-
case NI_Vector256_AsDouble:
1463-
case NI_Vector256_AsInt16:
1464-
case NI_Vector256_AsInt32:
1465-
case NI_Vector256_AsInt64:
1466-
case NI_Vector256_AsNInt:
1467-
case NI_Vector256_AsNUInt:
1468-
case NI_Vector256_AsSByte:
1469-
case NI_Vector256_AsSingle:
1470-
case NI_Vector256_AsUInt16:
1471-
case NI_Vector256_AsUInt32:
1472-
case NI_Vector256_AsUInt64:
1473-
case NI_Vector256_op_UnaryPlus:
1474-
case NI_Vector512_As:
1475-
case NI_Vector512_AsByte:
1476-
case NI_Vector512_AsDouble:
1477-
case NI_Vector512_AsInt16:
1478-
case NI_Vector512_AsInt32:
1479-
case NI_Vector512_AsInt64:
1480-
case NI_Vector512_AsNInt:
1481-
case NI_Vector512_AsNUInt:
1482-
case NI_Vector512_AsSByte:
1483-
case NI_Vector512_AsSingle:
1484-
case NI_Vector512_AsUInt16:
1485-
case NI_Vector512_AsUInt32:
1486-
case NI_Vector512_AsUInt64:
1487-
case NI_Vector512_op_UnaryPlus:
1488-
#endif // TARGET_XARCH
1419+
case NI_Vector_As:
1420+
case NI_Vector_AsByte:
1421+
case NI_Vector_AsDouble:
1422+
case NI_Vector_AsInt16:
1423+
case NI_Vector_AsInt32:
1424+
case NI_Vector_AsInt64:
1425+
case NI_Vector_AsNInt:
1426+
case NI_Vector_AsNUInt:
1427+
case NI_Vector_AsSByte:
1428+
case NI_Vector_AsSingle:
1429+
case NI_Vector_AsUInt16:
1430+
case NI_Vector_AsUInt32:
1431+
case NI_Vector_AsUInt64:
1432+
case NI_Vector_AsVector4:
1433+
case NI_Vector_op_UnaryPlus:
14891434
#endif // FEATURE_HW_INTRINSICS
14901435
case NI_SRCS_UNSAFE_As:
14911436
case NI_SRCS_UNSAFE_AsRef:
@@ -1502,58 +1447,18 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
15021447
}
15031448

15041449
#if defined(FEATURE_HW_INTRINSICS)
1505-
#if defined(TARGET_ARM64)
1506-
case NI_Vector64_get_AllBitsSet:
1507-
case NI_Vector64_get_E:
1508-
case NI_Vector64_get_Epsilon:
1509-
case NI_Vector64_get_NaN:
1510-
case NI_Vector64_get_NegativeInfinity:
1511-
case NI_Vector64_get_NegativeOne:
1512-
case NI_Vector64_get_NegativeZero:
1513-
case NI_Vector64_get_One:
1514-
case NI_Vector64_get_Pi:
1515-
case NI_Vector64_get_PositiveInfinity:
1516-
case NI_Vector64_get_Tau:
1517-
case NI_Vector64_get_Zero:
1518-
#endif // TARGET_ARM64
1519-
case NI_Vector128_get_AllBitsSet:
1520-
case NI_Vector128_get_E:
1521-
case NI_Vector128_get_Epsilon:
1522-
case NI_Vector128_get_NaN:
1523-
case NI_Vector128_get_NegativeInfinity:
1524-
case NI_Vector128_get_NegativeOne:
1525-
case NI_Vector128_get_NegativeZero:
1526-
case NI_Vector128_get_One:
1527-
case NI_Vector128_get_Pi:
1528-
case NI_Vector128_get_PositiveInfinity:
1529-
case NI_Vector128_get_Tau:
1530-
case NI_Vector128_get_Zero:
1531-
#if defined(TARGET_XARCH)
1532-
case NI_Vector256_get_AllBitsSet:
1533-
case NI_Vector256_get_E:
1534-
case NI_Vector256_get_Epsilon:
1535-
case NI_Vector256_get_NaN:
1536-
case NI_Vector256_get_NegativeInfinity:
1537-
case NI_Vector256_get_NegativeOne:
1538-
case NI_Vector256_get_NegativeZero:
1539-
case NI_Vector256_get_One:
1540-
case NI_Vector256_get_Pi:
1541-
case NI_Vector256_get_PositiveInfinity:
1542-
case NI_Vector256_get_Tau:
1543-
case NI_Vector256_get_Zero:
1544-
case NI_Vector512_get_AllBitsSet:
1545-
case NI_Vector512_get_E:
1546-
case NI_Vector512_get_Epsilon:
1547-
case NI_Vector512_get_NaN:
1548-
case NI_Vector512_get_NegativeInfinity:
1549-
case NI_Vector512_get_NegativeOne:
1550-
case NI_Vector512_get_NegativeZero:
1551-
case NI_Vector512_get_One:
1552-
case NI_Vector512_get_Pi:
1553-
case NI_Vector512_get_PositiveInfinity:
1554-
case NI_Vector512_get_Tau:
1555-
case NI_Vector512_get_Zero:
1556-
#endif // TARGET_XARCH
1450+
case NI_Vector_get_AllBitsSet:
1451+
case NI_Vector_get_E:
1452+
case NI_Vector_get_Epsilon:
1453+
case NI_Vector_get_NaN:
1454+
case NI_Vector_get_NegativeInfinity:
1455+
case NI_Vector_get_NegativeOne:
1456+
case NI_Vector_get_NegativeZero:
1457+
case NI_Vector_get_One:
1458+
case NI_Vector_get_Pi:
1459+
case NI_Vector_get_PositiveInfinity:
1460+
case NI_Vector_get_Tau:
1461+
case NI_Vector_get_Zero:
15571462
#endif // FEATURE_HW_INTRINSICS
15581463
{
15591464
// These always produce a vector constant

src/coreclr/jit/fgdiagnostic.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3478,6 +3478,7 @@ void Compiler::fgDebugCheckFlags(GenTree* tree, BasicBlock* block)
34783478
{
34793479
GenTreeHWIntrinsic* hwintrinsic = tree->AsHWIntrinsic();
34803480
NamedIntrinsic intrinsicId = hwintrinsic->GetHWIntrinsicId();
3481+
unsigned simdSize = hwintrinsic->GetSimdSize();
34813482

34823483
if (hwintrinsic->OperIsMemoryLoad())
34833484
{
@@ -3516,9 +3517,9 @@ void Compiler::fgDebugCheckFlags(GenTree* tree, BasicBlock* block)
35163517
break;
35173518
}
35183519

3519-
case NI_Vector128_op_Division:
3520-
case NI_Vector256_op_Division:
3520+
case NI_Vector_op_Division:
35213521
{
3522+
assert((simdSize == 16) || (simdSize == 32));
35223523
break;
35233524
}
35243525
#endif // TARGET_XARCH

0 commit comments

Comments
 (0)