-
Notifications
You must be signed in to change notification settings - Fork 5.1k
ILCompiler: Fix values of IsSupported for HW intrinsics on 32-bit platforms #99753
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,38 +64,32 @@ public bool IsInstructionSetExplicitlyUnsupported(InstructionSet instructionSet) | |
|
||
public InstructionSetSupportFlags Flags => _flags; | ||
|
||
public static string GetHardwareIntrinsicId(TargetArchitecture architecture, TypeDesc potentialTypeDesc) | ||
public static string GetHardwareIntrinsicId(TargetArchitecture architecture, TypeDesc potentialTypeDesc, out bool unsupportedSubset) | ||
{ | ||
unsupportedSubset = false; | ||
|
||
if (!potentialTypeDesc.IsIntrinsic || !(potentialTypeDesc is MetadataType potentialType)) | ||
return ""; | ||
|
||
if (architecture == TargetArchitecture.X64) | ||
{ | ||
if (potentialType.Name == "X64") | ||
potentialType = (MetadataType)potentialType.ContainingType; | ||
if (potentialType.Name == "VL") | ||
potentialType = (MetadataType)potentialType.ContainingType; | ||
if (potentialType.Namespace != "System.Runtime.Intrinsics.X86") | ||
return ""; | ||
} | ||
else if (architecture == TargetArchitecture.X86) | ||
if (architecture is TargetArchitecture.X64 or TargetArchitecture.X86) | ||
{ | ||
if (potentialType.Name == "X64") | ||
{ | ||
potentialType = (MetadataType)potentialType.ContainingType; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why this more complex change rather than just having this line change to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you simply exclude it then we end up with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then it really seems this should be doing some resolution similar to what It looks like you don't need full resolution, rather you mostly just care about:
|
||
unsupportedSubset = architecture == TargetArchitecture.X86; | ||
} | ||
if (potentialType.Name == "VL") | ||
potentialType = (MetadataType)potentialType.ContainingType; | ||
if (potentialType.Namespace != "System.Runtime.Intrinsics.X86") | ||
return ""; | ||
} | ||
else if (architecture == TargetArchitecture.ARM64) | ||
else if (architecture is TargetArchitecture.ARM64 or TargetArchitecture.ARM) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no intrinsic support for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I folded it to follow the same logic as X64/X86. The ARM logic existed there before the change. |
||
{ | ||
if (potentialType.Name == "Arm64") | ||
{ | ||
potentialType = (MetadataType)potentialType.ContainingType; | ||
if (potentialType.Namespace != "System.Runtime.Intrinsics.Arm") | ||
return ""; | ||
} | ||
else if (architecture == TargetArchitecture.ARM) | ||
{ | ||
unsupportedSubset = architecture == TargetArchitecture.ARM; | ||
} | ||
if (potentialType.Namespace != "System.Runtime.Intrinsics.Arm") | ||
return ""; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,14 +37,25 @@ public HardwareIntrinsicILProvider(InstructionSetSupport isaSupport, FieldDesc i | |
public override MethodIL GetMethodIL(MethodDesc method) | ||
{ | ||
TypeDesc owningType = method.OwningType; | ||
string intrinsicId = InstructionSetSupport.GetHardwareIntrinsicId(_context.Target.Architecture, owningType); | ||
string intrinsicId = InstructionSetSupport.GetHardwareIntrinsicId(_context.Target.Architecture, owningType, out bool unsupportedSubset); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this just trying to replace the method body for a couple of the special cases? Can we not just have this logic match what RyuJIT does so we can handle the total set of special "constant" cases:
|
||
if (!string.IsNullOrEmpty(intrinsicId) | ||
&& HardwareIntrinsicHelpers.IsIsSupportedMethod(method)) | ||
{ | ||
InstructionSet instructionSet = _instructionSetMap[intrinsicId]; | ||
|
||
bool isSupported = _isaSupport.IsInstructionSetSupported(instructionSet); | ||
bool isOptimisticallySupported = _isaSupport.OptimisticFlags.HasInstructionSet(instructionSet); | ||
bool isSupported; | ||
bool isOptimisticallySupported; | ||
|
||
if (unsupportedSubset) | ||
{ | ||
isSupported = false; | ||
isOptimisticallySupported = false; | ||
} | ||
else | ||
{ | ||
isSupported = _isaSupport.IsInstructionSetSupported(instructionSet); | ||
isOptimisticallySupported = _isaSupport.OptimisticFlags.HasInstructionSet(instructionSet); | ||
} | ||
|
||
// If this is an instruction set that is optimistically supported, but is not one of the | ||
// intrinsics that are known to be always available, emit IL that checks the support level | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this returning a string, rather than simply some enum entry like is done for RyuJIT?
A string is expensive to compare against and it doesn't even look like this is returning an Intrinsic ID, but rather the type name. A type name by itself may or may not be sufficient for describing an actual
InstructionSet
and whether or not its supported. This is why we have distinctInstructionSet
enum entries for each class we can encounter in RyuJIT.