diff --git a/src/coreclr/src/zap/zapinfo.cpp b/src/coreclr/src/zap/zapinfo.cpp index f65ec7c8aaf1ff..bd1e66e242b06f 100644 --- a/src/coreclr/src/zap/zapinfo.cpp +++ b/src/coreclr/src/zap/zapinfo.cpp @@ -2134,7 +2134,7 @@ DWORD FilterNamedIntrinsicMethodAttribs(ZapInfo* pZapInfo, DWORD attribs, CORINF #if defined(TARGET_X86) || defined(TARGET_AMD64) fIsPlatformHWIntrinsic = strcmp(namespaceName, "System.Runtime.Intrinsics.X86") == 0; -#elif TARGET_ARM64 +#elif defined(TARGET_ARM64) fIsPlatformHWIntrinsic = strcmp(namespaceName, "System.Runtime.Intrinsics.Arm") == 0; #endif @@ -2152,24 +2152,34 @@ DWORD FilterNamedIntrinsicMethodAttribs(ZapInfo* pZapInfo, DWORD attribs, CORINF // answer for the CPU the code is running on. fTreatAsRegularMethodCall = (fIsGetIsSupportedMethod && fIsPlatformHWIntrinsic) || (!fIsPlatformHWIntrinsic && fIsHWIntrinsic); -#if defined(TARGET_X86) || defined(TARGET_AMD64) if (fIsPlatformHWIntrinsic) { // Simplify the comparison logic by grabbing the name of the ISA const char* isaName = (enclosingClassName == nullptr) ? className : enclosingClassName; - if ((strcmp(isaName, "Sse") == 0) || (strcmp(isaName, "Sse2") == 0)) + bool fIsPlatformRequiredISA = false; + bool fIsPlatformSubArchitecture = false; + +#if defined(TARGET_X86) || defined(TARGET_AMD64) + fIsPlatformRequiredISA = (strcmp(isaName, "Sse") == 0) || (strcmp(isaName, "Sse2") == 0); + fIsPlatformSubArchitecture = strcmp(className, "X64") == 0; +#elif defined(TARGET_ARM64) + fIsPlatformRequiredISA = (strcmp(isaName, "ArmBase") == 0) || (strcmp(isaName, "AdvSimd") == 0); + fIsPlatformSubArchitecture = strcmp(className, "Arm64") == 0; +#endif + + if (fIsPlatformRequiredISA) { - if ((enclosingClassName == nullptr) || (strcmp(className, "X64") == 0)) + if ((enclosingClassName == nullptr) || fIsPlatformSubArchitecture) { - // If it's anything related to Sse/Sse2, we can expand unconditionally since this is - // a baseline requirement of CoreCLR. + // If the ISA is required by CoreCLR for the platform, we can expand unconditionally fTreatAsRegularMethodCall = false; } } - else if ((strcmp(className, "Avx") == 0) || (strcmp(className, "Fma") == 0) || (strcmp(className, "Avx2") == 0) || (strcmp(className, "Bmi1") == 0) || (strcmp(className, "Bmi2") == 0)) +#if defined(TARGET_X86) || defined(TARGET_AMD64) + else if ((strcmp(isaName, "Avx") == 0) || (strcmp(isaName, "Fma") == 0) || (strcmp(isaName, "Avx2") == 0) || (strcmp(isaName, "Bmi1") == 0) || (strcmp(isaName, "Bmi2") == 0)) { - if ((enclosingClassName == nullptr) || (strcmp(className, "X64") == 0)) + if ((enclosingClassName == nullptr) || fIsPlatformSubArchitecture) { // If it is the get_IsSupported method for an ISA which requires the VEX // encoding we want to expand unconditionally. This will force those code @@ -2182,7 +2192,20 @@ DWORD FilterNamedIntrinsicMethodAttribs(ZapInfo* pZapInfo, DWORD attribs, CORINF fTreatAsRegularMethodCall = !fIsGetIsSupportedMethod; } } +#endif // defined(TARGET_X86) || defined(TARGET_AMD64) +#ifdef TARGET_X86 + else if (fIsPlatformSubArchitecture) + { + // For ISAs not handled explicitly above, the IsSupported check will always + // be treated as a regular method call. If we are evaulating a method in the X64 + // namespace, we know it will never be supported on x86, so we can allow the code + // to be treated as dead. We treat all non-IsSupported methods as regular method + // calls so they throw PNSE if used withoug the IsSupported check. + fTreatAsRegularMethodCall = !fIsGetIsSupportedMethod; + } +#endif // TARGET_X86 } +#if defined(TARGET_X86) || defined(TARGET_AMD64) else if (strcmp(namespaceName, "System") == 0) { if ((strcmp(className, "Math") == 0) || (strcmp(className, "MathF") == 0)) diff --git a/src/coreclr/src/zap/zapper.cpp b/src/coreclr/src/zap/zapper.cpp index 422775a349257f..61f7dfd41b8e9b 100644 --- a/src/coreclr/src/zap/zapper.cpp +++ b/src/coreclr/src/zap/zapper.cpp @@ -1180,10 +1180,10 @@ void Zapper::InitializeCompilerFlags(CORCOMPILE_VERSION_INFO * pVersionInfo) m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_FCOMI); } - // .NET Core requires SSE2. #endif // TARGET_X86 #if defined(TARGET_X86) || defined(TARGET_AMD64) + // .NET Core requires SSE2. m_pOpt->m_compilerFlags.Set(InstructionSet_SSE); m_pOpt->m_compilerFlags.Set(InstructionSet_SSE2); #endif @@ -1205,8 +1205,6 @@ void Zapper::InitializeCompilerFlags(CORCOMPILE_VERSION_INFO * pVersionInfo) m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_FEATURE_SIMD); #if defined(TARGET_X86) || defined(TARGET_AMD64) - m_pOpt->m_compilerFlags.Set(InstructionSet_SSE); - m_pOpt->m_compilerFlags.Set(InstructionSet_SSE2); m_pOpt->m_compilerFlags.Set(InstructionSet_AES); m_pOpt->m_compilerFlags.Set(InstructionSet_PCLMULQDQ); m_pOpt->m_compilerFlags.Set(InstructionSet_SSE3);