From: Fei Peng Date: Sun, 24 Sep 2017 17:54:56 +0000 (-0700) Subject: Enable hardware intrinsic in debug and reflection X-Git-Tag: accepted/tizen/base/20180629.140029~1018 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=03c5c252281325e5a7b94cec6a198946f903b359;p=platform%2Fupstream%2Fcoreclr.git Enable hardware intrinsic in debug and reflection --- diff --git a/src/dlls/mscorrc/mscorrc.rc b/src/dlls/mscorrc/mscorrc.rc index 8dd29ae..8bc7ff0 100644 --- a/src/dlls/mscorrc/mscorrc.rc +++ b/src/dlls/mscorrc/mscorrc.rc @@ -853,6 +853,7 @@ BEGIN IDS_EE_SIMD_PARTIAL_TRUST_DISALLOWED "SIMD intrinsics may not be used by partial trust applications." IDS_IBC_MISSING_EXTERNAL_TYPE "The generic type specified by the IBC data is not available to this assembly" IDS_IBC_MISSING_EXTERNAL_METHOD "The generic method specified by the IBC data is not available to this assembly" + IDS_EE_HWINTRINSIC_NGEN_DISALLOWED "Hardware intrinsics may not be used with ngen." IDS_INET_E_CANNOT_CONNECT "Cannot connect to URL for '%1'." IDS_INET_E_RESOURCE_NOT_FOUND "The server or proxy was not found for '%1'." diff --git a/src/dlls/mscorrc/resource.h b/src/dlls/mscorrc/resource.h index 205445a..eb1cb29 100644 --- a/src/dlls/mscorrc/resource.h +++ b/src/dlls/mscorrc/resource.h @@ -613,6 +613,7 @@ #define IDS_EE_SIMD_PARTIAL_TRUST_DISALLOWED 0x1ac4 #define IDS_IBC_MISSING_EXTERNAL_TYPE 0x1ac5 #define IDS_IBC_MISSING_EXTERNAL_METHOD 0x1ac6 +#define IDS_EE_HWINTRINSIC_NGEN_DISALLOWED 0x1ac7 #define BFA_INVALID_FILE_TOKEN 0x2000 #define BFA_INVALID_TOKEN_TYPE 0x2001 diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp index 86179ec..6e1323f 100644 --- a/src/jit/compiler.cpp +++ b/src/jit/compiler.cpp @@ -2561,7 +2561,7 @@ void Compiler::compSetProcessor() #endif // _TARGET_X86_ -// Instruction set flags fo// Instruction set flags for Intel hardware intrinsics +// Instruction set flags for Intel hardware intrinsics #ifdef _TARGET_XARCH_ opts.compSupportsISA = 0; diff --git a/src/jit/compiler.h b/src/jit/compiler.h index dfc50ee..4bdb7ac 100644 --- a/src/jit/compiler.h +++ b/src/jit/compiler.h @@ -3021,22 +3021,22 @@ protected: InstructionSet lookupHWIntrinsicISA(const char* className); NamedIntrinsic lookupHWIntrinsic(const char* methodName, InstructionSet isa); InstructionSet isaOfHWIntrinsic(NamedIntrinsic intrinsic); - GenTree* impX86HWIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); - GenTree* impSSEIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); - GenTree* impSSE2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); - GenTree* impSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); - GenTree* impSSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); - GenTree* impSSE41Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); - GenTree* impSSE42Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); - GenTree* impAVXIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); - GenTree* impAVX2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); - GenTree* impAESIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); - GenTree* impBMI1Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); - GenTree* impBMI2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); - GenTree* impFMAIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); - GenTree* impLZCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); - GenTree* impPCLMULQDQIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); - GenTree* impPOPCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method); + GenTree* impX86HWIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impSSEIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impSSE2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impSSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impSSE41Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impSSE42Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impAVXIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impAVX2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impAESIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impBMI1Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impBMI2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impFMAIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impLZCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impPCLMULQDQIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + GenTree* impPOPCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); #endif GenTreePtr impArrayAccessIntrinsic(CORINFO_CLASS_HANDLE clsHnd, CORINFO_SIG_INFO* sig, @@ -7824,6 +7824,15 @@ private: #endif } + bool compSupports(InstructionSet isa) + { +#ifdef _TARGET_XARCH_ + return (opts.compSupportsISA & (1 << isa)) != 0; +#else + return false; +#endif + } + /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX @@ -7938,16 +7947,11 @@ public: #endif // _TARGET_XARCH_ #ifdef _TARGET_XARCH_ - // only for Intel hardware intrinsics uint64_t compSupportsISA; void setSupportedISA(InstructionSet isa) { compSupportsISA |= 1 << isa; } - bool compSupports(InstructionSet isa) - { - return (compSupportsISA & (1 << isa)) != 0; - } #endif // optimize maximally and/or favor speed over size? diff --git a/src/jit/hwintrinsicxarch.cpp b/src/jit/hwintrinsicxarch.cpp index 4a1ca85..45ee468 100644 --- a/src/jit/hwintrinsicxarch.cpp +++ b/src/jit/hwintrinsicxarch.cpp @@ -154,225 +154,226 @@ InstructionSet Compiler::isaOfHWIntrinsic(NamedIntrinsic intrinsic) // Arguments: // intrinsic -- id of the intrinsic function. // method -- method handle of the intrinsic function. +// sig -- signature of the intrinsic call // // Return Value: // the expanded intrinsic. // -GenTree* Compiler::impX86HWIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impX86HWIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { InstructionSet isa = isaOfHWIntrinsic(intrinsic); switch (isa) { case InstructionSet_SSE: - return impSSEIntrinsic(intrinsic, method); + return impSSEIntrinsic(intrinsic, method, sig); case InstructionSet_SSE2: - return impSSE2Intrinsic(intrinsic, method); + return impSSE2Intrinsic(intrinsic, method, sig); case InstructionSet_SSE3: - return impSSE3Intrinsic(intrinsic, method); + return impSSE3Intrinsic(intrinsic, method, sig); case InstructionSet_SSSE3: - return impSSSE3Intrinsic(intrinsic, method); + return impSSSE3Intrinsic(intrinsic, method, sig); case InstructionSet_SSE41: - return impSSE41Intrinsic(intrinsic, method); + return impSSE41Intrinsic(intrinsic, method, sig); case InstructionSet_SSE42: - return impSSE42Intrinsic(intrinsic, method); + return impSSE42Intrinsic(intrinsic, method, sig); case InstructionSet_AVX: - return impAVXIntrinsic(intrinsic, method); + return impAVXIntrinsic(intrinsic, method, sig); case InstructionSet_AVX2: - return impAVX2Intrinsic(intrinsic, method); + return impAVX2Intrinsic(intrinsic, method, sig); case InstructionSet_AES: - return impAESIntrinsic(intrinsic, method); + return impAESIntrinsic(intrinsic, method, sig); case InstructionSet_BMI1: - return impBMI1Intrinsic(intrinsic, method); + return impBMI1Intrinsic(intrinsic, method, sig); case InstructionSet_BMI2: - return impBMI2Intrinsic(intrinsic, method); + return impBMI2Intrinsic(intrinsic, method, sig); case InstructionSet_FMA: - return impFMAIntrinsic(intrinsic, method); + return impFMAIntrinsic(intrinsic, method, sig); case InstructionSet_LZCNT: - return impLZCNTIntrinsic(intrinsic, method); + return impLZCNTIntrinsic(intrinsic, method, sig); case InstructionSet_PCLMULQDQ: - return impPCLMULQDQIntrinsic(intrinsic, method); + return impPCLMULQDQIntrinsic(intrinsic, method, sig); case InstructionSet_POPCNT: - return impPOPCNTIntrinsic(intrinsic, method); + return impPOPCNTIntrinsic(intrinsic, method, sig); default: return nullptr; } } -GenTree* Compiler::impSSEIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impSSEIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { switch (intrinsic) { case NI_SSE_IsSupported: - return gtNewIconNode(opts.compSupports(InstructionSet_SSE)); + return gtNewIconNode(compSupports(InstructionSet_SSE)); default: return nullptr; } } -GenTree* Compiler::impSSE2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impSSE2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { switch (intrinsic) { case NI_SSE2_IsSupported: - return gtNewIconNode(opts.compSupports(InstructionSet_SSE2)); + return gtNewIconNode(compSupports(InstructionSet_SSE2)); default: return nullptr; } } -GenTree* Compiler::impSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { switch (intrinsic) { case NI_SSE3_IsSupported: - return gtNewIconNode(opts.compSupports(InstructionSet_SSE3)); + return gtNewIconNode(compSupports(InstructionSet_SSE3)); default: return nullptr; } } -GenTree* Compiler::impSSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impSSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { switch (intrinsic) { case NI_SSSE3_IsSupported: - return gtNewIconNode(opts.compSupports(InstructionSet_SSSE3)); + return gtNewIconNode(compSupports(InstructionSet_SSSE3)); default: return nullptr; } } -GenTree* Compiler::impSSE41Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impSSE41Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { switch (intrinsic) { case NI_SSE41_IsSupported: - return gtNewIconNode(opts.compSupports(InstructionSet_SSE41)); + return gtNewIconNode(compSupports(InstructionSet_SSE41)); default: return nullptr; } } -GenTree* Compiler::impSSE42Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impSSE42Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { switch (intrinsic) { case NI_SSE42_IsSupported: - return gtNewIconNode(opts.compSupports(InstructionSet_SSE42)); + return gtNewIconNode(compSupports(InstructionSet_SSE42)); default: return nullptr; } } -GenTree* Compiler::impAVXIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impAVXIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { switch (intrinsic) { case NI_AVX_IsSupported: - return gtNewIconNode(opts.compSupports(InstructionSet_AVX)); + return gtNewIconNode(compSupports(InstructionSet_AVX)); default: return nullptr; } } -GenTree* Compiler::impAVX2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impAVX2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { switch (intrinsic) { case NI_AVX2_IsSupported: - return gtNewIconNode(opts.compSupports(InstructionSet_AVX2)); + return gtNewIconNode(compSupports(InstructionSet_AVX2)); default: return nullptr; } } -GenTree* Compiler::impAESIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impAESIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { switch (intrinsic) { case NI_AES_IsSupported: - return gtNewIconNode(opts.compSupports(InstructionSet_AES)); + return gtNewIconNode(compSupports(InstructionSet_AES)); default: return nullptr; } } -GenTree* Compiler::impBMI1Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impBMI1Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { switch (intrinsic) { case NI_BMI1_IsSupported: - return gtNewIconNode(opts.compSupports(InstructionSet_BMI1)); + return gtNewIconNode(compSupports(InstructionSet_BMI1)); default: return nullptr; } } -GenTree* Compiler::impBMI2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impBMI2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { switch (intrinsic) { case NI_BMI2_IsSupported: - return gtNewIconNode(opts.compSupports(InstructionSet_BMI2)); + return gtNewIconNode(compSupports(InstructionSet_BMI2)); default: return nullptr; } } -GenTree* Compiler::impFMAIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impFMAIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { switch (intrinsic) { case NI_FMA_IsSupported: - return gtNewIconNode(opts.compSupports(InstructionSet_FMA)); + return gtNewIconNode(compSupports(InstructionSet_FMA)); default: return nullptr; } } -GenTree* Compiler::impLZCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impLZCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { switch (intrinsic) { case NI_LZCNT_IsSupported: - return gtNewIconNode(opts.compSupports(InstructionSet_LZCNT)); + return gtNewIconNode(compSupports(InstructionSet_LZCNT)); default: return nullptr; } } -GenTree* Compiler::impPCLMULQDQIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impPCLMULQDQIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { switch (intrinsic) { case NI_PCLMULQDQ_IsSupported: - return gtNewIconNode(opts.compSupports(InstructionSet_PCLMULQDQ)); + return gtNewIconNode(compSupports(InstructionSet_PCLMULQDQ)); default: return nullptr; } } -GenTree* Compiler::impPOPCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method) +GenTree* Compiler::impPOPCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { switch (intrinsic) { case NI_POPCNT_IsSupported: - return gtNewIconNode(opts.compSupports(InstructionSet_POPCNT)); + return gtNewIconNode(compSupports(InstructionSet_POPCNT)); default: return nullptr; diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index d16dfe3..714e6fe 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -3322,9 +3322,11 @@ GenTreePtr Compiler::impIntrinsic(GenTreePtr newobjThis, GenTreePtr retNode = nullptr; // - // We disable the inlining of instrinsics for MinOpts. - // - if (!mustExpand && (opts.compDbgCode || opts.MinOpts())) + // We disable the inlining of intrinsic for MinOpts, + // but we should always expand hardware intrinsics whose managed method body + // is a directly recursive call site. This design makes hardware intrinsic + // be able to work with debugger and reflection. + if (!mustExpand && (opts.compDbgCode || opts.MinOpts()) && !gtIsRecursiveCall(method)) { *pIntrinsicID = CORINFO_INTRINSIC_Illegal; return retNode; @@ -3738,7 +3740,7 @@ GenTreePtr Compiler::impIntrinsic(GenTreePtr newobjThis, #ifdef _TARGET_XARCH_ if (ni > NI_HW_INTRINSIC_START && ni < NI_HW_INTRINSIC_END) { - retNode = impX86HWIntrinsic(ni, method); + retNode = impX86HWIntrinsic(ni, method, sig); } #endif switch (ni) diff --git a/src/jit/instr.h b/src/jit/instr.h index e364fbc..eac4256 100644 --- a/src/jit/instr.h +++ b/src/jit/instr.h @@ -274,9 +274,6 @@ enum emitAttr : unsigned #define EmitSize(x) (EA_ATTR(genTypeSize(TypeGet(x)))) -// Enum specifying the instruction set for generating floating point or SIMD code. -// These enums are ordered such that each one is inclusive of previous instruction sets -// and the VM ensures this as well when setting the CONFIG flags. enum InstructionSet { #ifdef _TARGET_XARCH_ @@ -292,10 +289,12 @@ enum InstructionSet InstructionSet_AVX = 8, InstructionSet_AVX2 = 9, // Linear order end - // Instruction sets have the linear order only in above area. - // Values of InstructionSet not in this area cannot be compared - // (i.e. compiler->getSIMDInstructionSet() >= InstructionSet_SSE3_4). - + // TODO - Instruction sets have the linear order only in above area. + // We should no long compare the return value of getSIMDInstructionSet() + // or getFloatingPointInstructionSet() to the InstructionSet values. + // Should refactor SIMD code only to be aware of SIMD feature levels + // (SSE2, SSE3_4, AVX, and AVX2, etc.) rather than concrete ISA. + InstructionSet_AES = 32, InstructionSet_BMI1 = 33, InstructionSet_BMI2 = 34, diff --git a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Lzcnt.cs b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Lzcnt.cs index 17d7716..6bdc8cc 100644 --- a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Lzcnt.cs +++ b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Lzcnt.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Runtime.Intrinsics; namespace System.Runtime.Intrinsics.X86 { diff --git a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Popcnt.cs b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Popcnt.cs index c9e71b3..21cae31 100644 --- a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Popcnt.cs +++ b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Popcnt.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Runtime.Intrinsics; namespace System.Runtime.Intrinsics.X86 { diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp index 8a96e68..adcf7bb 100644 --- a/src/vm/methodtablebuilder.cpp +++ b/src/vm/methodtablebuilder.cpp @@ -1484,6 +1484,26 @@ MethodTableBuilder::BuildMethodTableThrowing( } } +#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) + // All the funtions in System.Runtime.Intrinsics.X86 are hardware intrinsics. + // We specially treat them here to reduce the disk footprint of mscorlib. + if (GetModule()->IsSystem() && !bmtGenerics->HasInstantiation()) + { + LPCUTF8 x86className; + LPCUTF8 x86nameSpace; + HRESULT hr = GetMDImport()->GetNameOfTypeDef(bmtInternal->pType->GetTypeDefToken(), &x86className, &x86nameSpace); + + if (hr == S_OK && strcmp(x86nameSpace, "System.Runtime.Intrinsics.X86") == 0) + { + if (IsCompilationProcess()) + { + // Disable AOT compiling for managed implementation of hardware intrinsics in mscorlib. + COMPlusThrow(kTypeLoadException, IDS_EE_HWINTRINSIC_NGEN_DISALLOWED); + } + bmtProp->fIsHardwareIntrinsic = true; + } + } +#endif #ifdef FEATURE_COMINTEROP @@ -5090,19 +5110,7 @@ MethodTableBuilder::InitNewMethodDesc( NULL, NULL); - if (hr == S_OK) - { - pNewMD->SetIsJitIntrinsic(); - } - - // All the funtions in System.Runtime.Intrinsics.X86 are hardware intrinsics. - // We specially treat them here to reduce the disk footprint of mscorlib. - LPCUTF8 className; - LPCUTF8 nameSpace; - - HRESULT hrns = GetMDImport()->GetNameOfTypeDef(bmtInternal->pType->GetTypeDefToken(), &className, &nameSpace); - - if (hrns == S_OK && strcmp(nameSpace, "System.Runtime.Intrinsics.X86") == 0) + if (hr == S_OK || bmtProp->fIsHardwareIntrinsic) { pNewMD->SetIsJitIntrinsic(); } @@ -9402,7 +9410,7 @@ void MethodTableBuilder::CheckForSystemTypes() { BuildMethodTableThrowException(IDS_CLASSLOAD_BADFORMAT); } - + if (IsValueClass()) { // diff --git a/src/vm/methodtablebuilder.h b/src/vm/methodtablebuilder.h index a7d7bdd..c5ce09f 100644 --- a/src/vm/methodtablebuilder.h +++ b/src/vm/methodtablebuilder.h @@ -1333,6 +1333,8 @@ private: bool fDynamicStatics; // Set to true if the statics will be allocated in the dynamic bool fGenericsStatics; // Set to true if the there are per-instantiation statics + bool fIsHardwareIntrinsic; // Set to true if the class is a hardware intrinsic + DWORD dwNonGCRegularStaticFieldBytes; DWORD dwNonGCThreadStaticFieldBytes; diff --git a/src/zap/zapimage.cpp b/src/zap/zapimage.cpp index 96fa81f..98b9e92 100644 --- a/src/zap/zapimage.cpp +++ b/src/zap/zapimage.cpp @@ -3560,6 +3560,12 @@ void ZapImage::Error(mdToken token, HRESULT hr, UINT resID, LPCWSTR message) level = CORZAP_LOGLEVEL_INFO; } + if (resID == IDS_EE_HWINTRINSIC_NGEN_DISALLOWED) + { + // Supress printing of "Hardware intrinsics may not be used with ngen." + level = CORZAP_LOGLEVEL_INFO; + } + #ifdef CROSSGEN_COMPILE if ((resID == IDS_IBC_MISSING_EXTERNAL_TYPE) || (resID == IDS_IBC_MISSING_EXTERNAL_METHOD)) diff --git a/tests/src/Common/test_dependencies/test_dependencies.csproj b/tests/src/Common/test_dependencies/test_dependencies.csproj index e9d78ec..1e34f8a 100644 --- a/tests/src/Common/test_dependencies/test_dependencies.csproj +++ b/tests/src/Common/test_dependencies/test_dependencies.csproj @@ -23,7 +23,7 @@ $(CoreFxPackageVersion) - 4.5.0-preview1-25718-03 + $(CoreFxPackageVersion) diff --git a/tests/src/JIT/HardwareIntrinsics/IsSupported.cs b/tests/src/JIT/HardwareIntrinsics/IsSupported.cs index 9f6d924..7e92f18 100644 --- a/tests/src/JIT/HardwareIntrinsics/IsSupported.cs +++ b/tests/src/JIT/HardwareIntrinsics/IsSupported.cs @@ -2,7 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Runtime.Intrinsics.X86; +using System.Numerics; namespace IntelHardwareIntrinsicTest { @@ -50,15 +52,16 @@ namespace IntelHardwareIntrinsicTest result = false; } } - if (Aes.IsSupported && Bmi1.IsSupported && Bmi2.IsSupported && Fma.IsSupported && - Lzcnt.IsSupported && Popcnt.IsSupported && Pclmulqdq.IsSupported) - { - result = result && true; - } - else - { - result = false; - } + } + + if (Vector.Count == 32 && !Avx2.IsSupported) + { + result = false; + } + + if (Vector.Count == 16 && Vector.IsHardwareAccelerated && !Sse2.IsSupported) + { + result = false; } // Non-X86 platforms @@ -82,6 +85,28 @@ namespace IntelHardwareIntrinsicTest result = false; } } + + // Reflection call + var issupported = "get_IsSupported"; + if (Convert.ToBoolean(typeof(Sse).GetMethod(issupported).Invoke(null, null)) != Sse.IsSupported || + Convert.ToBoolean(typeof(Sse2).GetMethod(issupported).Invoke(null, null)) != Sse2.IsSupported || + Convert.ToBoolean(typeof(Sse3).GetMethod(issupported).Invoke(null, null)) != Sse3.IsSupported || + Convert.ToBoolean(typeof(Ssse3).GetMethod(issupported).Invoke(null, null)) != Ssse3.IsSupported || + Convert.ToBoolean(typeof(Sse41).GetMethod(issupported).Invoke(null, null)) != Sse41.IsSupported || + Convert.ToBoolean(typeof(Sse42).GetMethod(issupported).Invoke(null, null)) != Sse42.IsSupported || + Convert.ToBoolean(typeof(Aes).GetMethod(issupported).Invoke(null, null)) != Aes.IsSupported || + Convert.ToBoolean(typeof(Avx).GetMethod(issupported).Invoke(null, null)) != Avx.IsSupported || + Convert.ToBoolean(typeof(Avx2).GetMethod(issupported).Invoke(null, null)) != Avx2.IsSupported || + Convert.ToBoolean(typeof(Fma).GetMethod(issupported).Invoke(null, null)) != Fma.IsSupported || + Convert.ToBoolean(typeof(Lzcnt).GetMethod(issupported).Invoke(null, null)) != Lzcnt.IsSupported || + Convert.ToBoolean(typeof(Bmi1).GetMethod(issupported).Invoke(null, null)) != Bmi1.IsSupported || + Convert.ToBoolean(typeof(Bmi2).GetMethod(issupported).Invoke(null, null)) != Bmi2.IsSupported || + Convert.ToBoolean(typeof(Popcnt).GetMethod(issupported).Invoke(null, null)) != Popcnt.IsSupported || + Convert.ToBoolean(typeof(Pclmulqdq).GetMethod(issupported).Invoke(null, null)) != Pclmulqdq.IsSupported + ) + { + result = false; + } return result ? 100 : 0; } diff --git a/tests/src/JIT/HardwareIntrinsics/IsSupported_r.csproj b/tests/src/JIT/HardwareIntrinsics/IsSupported_r.csproj new file mode 100644 index 0000000..e77c5dc --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/IsSupported_r.csproj @@ -0,0 +1,33 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + + + + + + + False + + + + None + + + + + + + + + + + \ No newline at end of file diff --git a/tests/src/JIT/HardwareIntrinsics/IsSupported.csproj b/tests/src/JIT/HardwareIntrinsics/IsSupported_ro.csproj similarity index 100% rename from tests/src/JIT/HardwareIntrinsics/IsSupported.csproj rename to tests/src/JIT/HardwareIntrinsics/IsSupported_ro.csproj