diff --git a/src/coreclr/tools/Common/Compiler/HardwareIntrinsicHelpers.cs b/src/coreclr/tools/Common/Compiler/HardwareIntrinsicHelpers.cs index c30736fcb6019d..642f33a5595525 100644 --- a/src/coreclr/tools/Common/Compiler/HardwareIntrinsicHelpers.cs +++ b/src/coreclr/tools/Common/Compiler/HardwareIntrinsicHelpers.cs @@ -16,7 +16,7 @@ public static partial class HardwareIntrinsicHelpers /// public static bool IsHardwareIntrinsic(MethodDesc method) { - return !string.IsNullOrEmpty(InstructionSetSupport.GetHardwareIntrinsicId(method.Context.Target.Architecture, method.OwningType)); + return !string.IsNullOrEmpty(InstructionSetSupport.GetHardwareIntrinsicId(method.Context.Target.Architecture, method.OwningType, out _)); } public static void AddRuntimeRequiredIsaFlagsToBuilder(InstructionSetSupportBuilder builder, int flags) diff --git a/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs b/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs index f476b972b80460..99b7031dcc0ec7 100644 --- a/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs +++ b/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs @@ -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; + 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) { 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 ""; } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/HardwareIntrinsicILProvider.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/HardwareIntrinsicILProvider.cs index 5e3f9e3f8c0a39..ff8b638bcfa9b6 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/HardwareIntrinsicILProvider.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/HardwareIntrinsicILProvider.cs @@ -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); 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