Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intrinsics analyzer and fixes #85481

Merged
merged 21 commits into from
May 16, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e1f2f17
Implement analyzer for platform intrinsics use in System.Private.CoreLib
davidwrighton Apr 25, 2023
b246bd0
Remove BypassReadyToRunAttribute as it should no longer be needed for…
davidwrighton Apr 26, 2023
35105fb
Document new intrinsic handling behavior and enhance crossgen2 to res…
davidwrighton Apr 27, 2023
59a55e4
Fix build break
davidwrighton Apr 27, 2023
768d1a9
Fix condition noted in code review
davidwrighton Apr 28, 2023
5ac974c
Update analyzer to detect more patterns, and attribute much of System…
davidwrighton May 9, 2023
cdc8b3f
Add pragmas and attributes to the packed span helpers
davidwrighton May 9, 2023
a01fd9d
Hah! It works
davidwrighton May 9, 2023
5573738
Rename attribute and fix docs
davidwrighton May 9, 2023
5134b86
Merge branch 'main' of github.com:dotnet/runtime into IntrinsicsAnaly…
davidwrighton May 9, 2023
506f053
Add analyzer tests and fixup issues from merging with main branch
davidwrighton May 9, 2023
2e33ae4
Disable tests on Mono due to Mono runtime bug
davidwrighton May 9, 2023
8a69798
Handle incorrect namespace for the CompExactlyDependsOnAttribute and …
davidwrighton May 10, 2023
919e0c3
Merge branch 'main' of github.com:dotnet/runtime into IntrinsicsAnaly…
davidwrighton May 15, 2023
4e413bd
With the analyzer, negative checks are problematic, so re-order some …
davidwrighton May 15, 2023
994ff3e
Code review feedback
davidwrighton May 15, 2023
8ed51a1
Update src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorIn…
davidwrighton May 15, 2023
9442ebe
Update src/libraries/System.Private.CoreLib/tests/IntrinsicsInSystemP…
davidwrighton May 15, 2023
fba92eb
Update src/libraries/System.Private.CoreLib/gen/IntrinsicsInSystemPri…
davidwrighton May 15, 2023
fcc38ca
Update IntrinsicsInSystemPrivateCoreLibAnalyzer.cs
davidwrighton May 15, 2023
62c5e58
Use auto-implemented get-only property
davidwrighton May 15, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 88 additions & 113 deletions docs/design/coreclr/botr/vectors-and-intrinsics.md

Large diffs are not rendered by default.

365 changes: 365 additions & 0 deletions src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1334,4 +1334,369 @@ public void Set64BitInstructionSetVariantsUnconditionally(TargetArchitecture arc
}
}
}
public static class InstructionSetParser
{
public static InstructionSet LookupPlatformIntrinsicInstructionSet(TargetArchitecture targetArch, TypeDesc intrinsicType)
{
MetadataType metadataType = intrinsicType.GetTypeDefinition() as MetadataType;
if (metadataType == null)
return InstructionSet.ILLEGAL;

string namespaceName;
string typeName = metadataType.Name;
string nestedTypeName = null;
if (metadataType.ContainingType != null)
{
var enclosingType = (MetadataType)metadataType.ContainingType;
namespaceName = enclosingType.Namespace;
nestedTypeName = metadataType.Name;
typeName = enclosingType.Name;
}
else
{
namespaceName = metadataType.Namespace;
}

string platformIntrinsicNamespace;

switch (targetArch)
{
case TargetArchitecture.ARM64:
platformIntrinsicNamespace = "System.Runtime.Intrinsics.Arm";
break;

case TargetArchitecture.X64:
case TargetArchitecture.X86:
platformIntrinsicNamespace = "System.Runtime.Intrinsics.X86";
break;

default:
return InstructionSet.ILLEGAL;
}

if (namespaceName != platformIntrinsicNamespace)
return InstructionSet.ILLEGAL;

switch (targetArch)
{

case TargetArchitecture.ARM64:
switch (typeName)
{

case "ArmBase":
if (nestedTypeName == "Arm64")
{ return InstructionSet.ARM64_ArmBase_Arm64; }
else
{ return InstructionSet.ARM64_ArmBase; }

case "AdvSimd":
if (nestedTypeName == "Arm64")
{ return InstructionSet.ARM64_AdvSimd_Arm64; }
else
{ return InstructionSet.ARM64_AdvSimd; }

case "Aes":
if (nestedTypeName == "Arm64")
{ return InstructionSet.ARM64_Aes_Arm64; }
else
{ return InstructionSet.ARM64_Aes; }

case "Crc32":
if (nestedTypeName == "Arm64")
{ return InstructionSet.ARM64_Crc32_Arm64; }
else
{ return InstructionSet.ARM64_Crc32; }

case "Dp":
if (nestedTypeName == "Arm64")
{ return InstructionSet.ARM64_Dp_Arm64; }
else
{ return InstructionSet.ARM64_Dp; }

case "Rdm":
if (nestedTypeName == "Arm64")
{ return InstructionSet.ARM64_Rdm_Arm64; }
else
{ return InstructionSet.ARM64_Rdm; }

case "Sha1":
if (nestedTypeName == "Arm64")
{ return InstructionSet.ARM64_Sha1_Arm64; }
else
{ return InstructionSet.ARM64_Sha1; }

case "Sha256":
if (nestedTypeName == "Arm64")
{ return InstructionSet.ARM64_Sha256_Arm64; }
else
{ return InstructionSet.ARM64_Sha256; }

}
break;

case TargetArchitecture.X64:
switch (typeName)
{

case "X86Base":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_X86Base_X64; }
else
{ return InstructionSet.X64_X86Base; }

case "Sse":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_SSE_X64; }
else
{ return InstructionSet.X64_SSE; }

case "Sse2":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_SSE2_X64; }
else
{ return InstructionSet.X64_SSE2; }

case "Sse3":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_SSE3_X64; }
else
{ return InstructionSet.X64_SSE3; }

case "Ssse3":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_SSSE3_X64; }
else
{ return InstructionSet.X64_SSSE3; }

case "Sse41":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_SSE41_X64; }
else
{ return InstructionSet.X64_SSE41; }

case "Sse42":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_SSE42_X64; }
else
{ return InstructionSet.X64_SSE42; }

case "Avx":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_AVX_X64; }
else
{ return InstructionSet.X64_AVX; }

case "Avx2":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_AVX2_X64; }
else
{ return InstructionSet.X64_AVX2; }

case "Aes":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_AES_X64; }
else
{ return InstructionSet.X64_AES; }

case "Bmi1":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_BMI1_X64; }
else
{ return InstructionSet.X64_BMI1; }

case "Bmi2":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_BMI2_X64; }
else
{ return InstructionSet.X64_BMI2; }

case "Fma":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_FMA_X64; }
else
{ return InstructionSet.X64_FMA; }

case "Lzcnt":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_LZCNT_X64; }
else
{ return InstructionSet.X64_LZCNT; }

case "Pclmulqdq":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_PCLMULQDQ_X64; }
else
{ return InstructionSet.X64_PCLMULQDQ; }

case "Popcnt":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_POPCNT_X64; }
else
{ return InstructionSet.X64_POPCNT; }

case "AvxVnni":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_AVXVNNI_X64; }
else
{ return InstructionSet.X64_AVXVNNI; }

case "Movbe":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_MOVBE_X64; }
else
{ return InstructionSet.X64_MOVBE; }

case "X86Serialize":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_X86Serialize_X64; }
else
{ return InstructionSet.X64_X86Serialize; }

case "Avx512F":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_AVX512F_X64; }
else
if (nestedTypeName == "VL")
{ return InstructionSet.X64_AVX512F_VL; }
else
{ return InstructionSet.X64_AVX512F; }

case "Avx512BW":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_AVX512BW_X64; }
else
if (nestedTypeName == "VL")
{ return InstructionSet.X64_AVX512BW_VL; }
else
{ return InstructionSet.X64_AVX512BW; }

case "Avx512CD":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_AVX512CD_X64; }
else
if (nestedTypeName == "VL")
{ return InstructionSet.X64_AVX512CD_VL; }
else
{ return InstructionSet.X64_AVX512CD; }

case "Avx512DQ":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_AVX512DQ_X64; }
else
if (nestedTypeName == "VL")
{ return InstructionSet.X64_AVX512DQ_VL; }
else
{ return InstructionSet.X64_AVX512DQ; }

case "Avx512Vbmi":
if (nestedTypeName == "X64")
{ return InstructionSet.X64_AVX512VBMI_X64; }
else
if (nestedTypeName == "VL")
{ return InstructionSet.X64_AVX512VBMI_VL; }
else
{ return InstructionSet.X64_AVX512VBMI; }

}
break;

case TargetArchitecture.X86:
switch (typeName)
{

case "X86Base":
{ return InstructionSet.X86_X86Base; }

case "Sse":
{ return InstructionSet.X86_SSE; }

case "Sse2":
{ return InstructionSet.X86_SSE2; }

case "Sse3":
{ return InstructionSet.X86_SSE3; }

case "Ssse3":
{ return InstructionSet.X86_SSSE3; }

case "Sse41":
{ return InstructionSet.X86_SSE41; }

case "Sse42":
{ return InstructionSet.X86_SSE42; }

case "Avx":
{ return InstructionSet.X86_AVX; }

case "Avx2":
{ return InstructionSet.X86_AVX2; }

case "Aes":
{ return InstructionSet.X86_AES; }

case "Bmi1":
{ return InstructionSet.X86_BMI1; }

case "Bmi2":
{ return InstructionSet.X86_BMI2; }

case "Fma":
{ return InstructionSet.X86_FMA; }

case "Lzcnt":
{ return InstructionSet.X86_LZCNT; }

case "Pclmulqdq":
{ return InstructionSet.X86_PCLMULQDQ; }

case "Popcnt":
{ return InstructionSet.X86_POPCNT; }

case "AvxVnni":
{ return InstructionSet.X86_AVXVNNI; }

case "Movbe":
{ return InstructionSet.X86_MOVBE; }

case "X86Serialize":
{ return InstructionSet.X86_X86Serialize; }

case "Avx512F":
if (nestedTypeName == "VL")
{ return InstructionSet.X86_AVX512F_VL; }
else
{ return InstructionSet.X86_AVX512F; }

case "Avx512BW":
if (nestedTypeName == "VL")
{ return InstructionSet.X86_AVX512BW_VL; }
else
{ return InstructionSet.X86_AVX512BW; }

case "Avx512CD":
if (nestedTypeName == "VL")
{ return InstructionSet.X86_AVX512CD_VL; }
else
{ return InstructionSet.X86_AVX512CD; }

case "Avx512DQ":
if (nestedTypeName == "VL")
{ return InstructionSet.X86_AVX512DQ_VL; }
else
{ return InstructionSet.X86_AVX512DQ; }

case "Avx512Vbmi":
if (nestedTypeName == "VL")
{ return InstructionSet.X86_AVX512VBMI_VL; }
else
{ return InstructionSet.X86_AVX512VBMI; }

}
break;

}
return InstructionSet.ILLEGAL;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
; DO NOT CHANGE R2R NUMERIC VALUES OF THE EXISTING SETS. Changing R2R numeric values definitions would be R2R format breaking change.

; Definition of X86 instruction sets
definearch ,X86 ,32Bit ,X64
definearch ,X86 ,32Bit ,X64, X64

instructionset ,X86 ,X86Base , ,22 ,X86Base ,base
instructionset ,X86 ,Sse , ,1 ,SSE ,sse
Expand Down Expand Up @@ -126,12 +126,12 @@ implication ,X86 ,AVX512VBMI ,AVX512BW
implication ,X86 ,AVX512VBMI_VL ,AVX512BW_VL

; Definition of X64 instruction sets
definearch ,X64 ,64Bit ,X64
definearch ,X64 ,64Bit ,X64, X64

copyinstructionsets,X86 ,X64

; Definition of Arm64 instruction sets
definearch ,ARM64 ,64Bit ,Arm64
definearch ,ARM64 ,64Bit ,Arm64, Arm64

instructionset ,ARM64 ,ArmBase , ,16 ,ArmBase ,base
instructionset ,ARM64 ,AdvSimd , ,17 ,AdvSimd ,neon
Expand Down
Loading