From 4f38b755fd8953830b58b4bc42943c57feeec419 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid Date: Fri, 24 Jul 2020 18:35:17 +0300 Subject: [PATCH] Convert math intrinsics to named intrinsics (#39730) * Convert math intrinsics to named intrinsics * Annotate Floor and Ceiling with [Intrinsic] --- .../src/System/Math.CoreCLR.cs | 2 + .../src/System/MathF.CoreCLR.cs | 2 + src/coreclr/src/inc/corinfo.h | 32 +-- src/coreclr/src/jit/codegenarmarch.cpp | 12 +- src/coreclr/src/jit/codegenxarch.cpp | 26 +- src/coreclr/src/jit/compiler.h | 10 +- src/coreclr/src/jit/gentree.cpp | 301 ++++++++++++--------- src/coreclr/src/jit/gentree.h | 39 ++- src/coreclr/src/jit/hwintrinsic.cpp | 4 +- src/coreclr/src/jit/importer.cpp | 281 +++++++++++-------- src/coreclr/src/jit/lowerxarch.cpp | 6 +- src/coreclr/src/jit/lsraarm.cpp | 6 +- src/coreclr/src/jit/lsraarm64.cpp | 10 +- src/coreclr/src/jit/lsraxarch.cpp | 16 +- src/coreclr/src/jit/morph.cpp | 4 +- src/coreclr/src/jit/namedintrinsiclist.h | 23 +- src/coreclr/src/jit/rationalize.cpp | 4 +- src/coreclr/src/jit/valuenum.cpp | 92 +++---- src/coreclr/src/jit/valuenum.h | 11 +- .../Common/JitInterface/CorInfoImpl.Intrinsics.cs | 59 +--- .../src/tools/Common/JitInterface/CorInfoImpl.cs | 2 +- .../src/tools/Common/JitInterface/CorInfoTypes.cs | 22 -- .../src/tools/aot/jitinterface/jitwrapper.cpp | 10 +- src/coreclr/src/vm/ecalllist.h | 84 +++--- src/coreclr/src/zap/zapinfo.cpp | 19 +- 25 files changed, 555 insertions(+), 522 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Math.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Math.CoreCLR.cs index 74aca43..beeb322 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Math.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Math.CoreCLR.cs @@ -56,6 +56,7 @@ namespace System [MethodImpl(MethodImplOptions.InternalCall)] public static extern double Cbrt(double d); + [Intrinsic] [MethodImpl(MethodImplOptions.InternalCall)] public static extern double Ceiling(double a); @@ -71,6 +72,7 @@ namespace System [MethodImpl(MethodImplOptions.InternalCall)] public static extern double Exp(double d); + [Intrinsic] [MethodImpl(MethodImplOptions.InternalCall)] public static extern double Floor(double d); diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/MathF.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/MathF.CoreCLR.cs index 371780f..f3dd328 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/MathF.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/MathF.CoreCLR.cs @@ -45,6 +45,7 @@ namespace System [MethodImpl(MethodImplOptions.InternalCall)] public static extern float Cbrt(float x); + [Intrinsic] [MethodImpl(MethodImplOptions.InternalCall)] public static extern float Ceiling(float x); @@ -60,6 +61,7 @@ namespace System [MethodImpl(MethodImplOptions.InternalCall)] public static extern float Exp(float x); + [Intrinsic] [MethodImpl(MethodImplOptions.InternalCall)] public static extern float Floor(float x); diff --git a/src/coreclr/src/inc/corinfo.h b/src/coreclr/src/inc/corinfo.h index 7341e43..7870683 100644 --- a/src/coreclr/src/inc/corinfo.h +++ b/src/coreclr/src/inc/corinfo.h @@ -208,11 +208,11 @@ TODO: Talk about initializing strutures before use // ////////////////////////////////////////////////////////////////////////////////////////////////////////// -constexpr GUID JITEEVersionIdentifier = { /* 164b4e4f-21f6-4d05-b560-3728395404f2 */ - 0x164b4e4f, - 0x21f6, - 0x4d05, - { 0xb5, 0x60, 0x37, 0x28, 0x39, 0x54, 0x04, 0xf2 } +constexpr GUID JITEEVersionIdentifier = { /* a5eec3a4-4176-43a7-8c2b-a05b551d4f49 */ + 0xa5eec3a4, + 0x4176, + 0x43a7, + {0x8c, 0x2b, 0xa0, 0x5b, 0x55, 0x1d, 0x4f, 0x49} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -891,28 +891,6 @@ enum CorInfoException enum CorInfoIntrinsics { - CORINFO_INTRINSIC_Sin, - CORINFO_INTRINSIC_Cos, - CORINFO_INTRINSIC_Cbrt, - CORINFO_INTRINSIC_Sqrt, - CORINFO_INTRINSIC_Abs, - CORINFO_INTRINSIC_Round, - CORINFO_INTRINSIC_Cosh, - CORINFO_INTRINSIC_Sinh, - CORINFO_INTRINSIC_Tan, - CORINFO_INTRINSIC_Tanh, - CORINFO_INTRINSIC_Asin, - CORINFO_INTRINSIC_Asinh, - CORINFO_INTRINSIC_Acos, - CORINFO_INTRINSIC_Acosh, - CORINFO_INTRINSIC_Atan, - CORINFO_INTRINSIC_Atan2, - CORINFO_INTRINSIC_Atanh, - CORINFO_INTRINSIC_Log10, - CORINFO_INTRINSIC_Pow, - CORINFO_INTRINSIC_Exp, - CORINFO_INTRINSIC_Ceiling, - CORINFO_INTRINSIC_Floor, CORINFO_INTRINSIC_GetChar, // fetch character out of string CORINFO_INTRINSIC_Array_GetDimLength, // Get number of elements in a given dimension of an array CORINFO_INTRINSIC_Array_Get, // Get the value of an element in an array diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index a2d8815..4531986 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -616,31 +616,31 @@ void CodeGen::genIntrinsic(GenTree* treeNode) // Right now only Abs/Ceiling/Floor/Round/Sqrt are treated as math intrinsics. // - switch (treeNode->AsIntrinsic()->gtIntrinsicId) + switch (treeNode->AsIntrinsic()->gtIntrinsicName) { - case CORINFO_INTRINSIC_Abs: + case NI_System_Math_Abs: genConsumeOperands(treeNode->AsOp()); GetEmitter()->emitInsBinary(INS_ABS, emitActualTypeSize(treeNode), treeNode, srcNode); break; #ifdef TARGET_ARM64 - case CORINFO_INTRINSIC_Ceiling: + case NI_System_Math_Ceiling: genConsumeOperands(treeNode->AsOp()); GetEmitter()->emitInsBinary(INS_frintp, emitActualTypeSize(treeNode), treeNode, srcNode); break; - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Floor: genConsumeOperands(treeNode->AsOp()); GetEmitter()->emitInsBinary(INS_frintm, emitActualTypeSize(treeNode), treeNode, srcNode); break; - case CORINFO_INTRINSIC_Round: + case NI_System_Math_Round: genConsumeOperands(treeNode->AsOp()); GetEmitter()->emitInsBinary(INS_frintn, emitActualTypeSize(treeNode), treeNode, srcNode); break; #endif // TARGET_ARM64 - case CORINFO_INTRINSIC_Sqrt: + case NI_System_Math_Sqrt: genConsumeOperands(treeNode->AsOp()); GetEmitter()->emitInsBinary(INS_SQRT, emitActualTypeSize(treeNode), treeNode, srcNode); break; diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index e65dda6..ed1a67b 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -6781,7 +6781,7 @@ void CodeGen::genSSE2BitwiseOp(GenTree* treeNode) break; case GT_INTRINSIC: - assert(treeNode->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Abs); + assert(treeNode->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Abs); // Abs(x) = set sign-bit to zero // Abs(f) = f & 0x7fffffff @@ -6859,7 +6859,7 @@ void CodeGen::genSSE2BitwiseOp(GenTree* treeNode) // ii) treeNode oper is a GT_INTRINSIC // iii) treeNode type is a floating point type // iv) treeNode is not used from memory -// v) tree oper is CORINFO_INTRINSIC_Round, _Ceiling, or _Floor +// v) tree oper is NI_System_Math{F}_Round, _Ceiling, or _Floor // vi) caller of this routine needs to call genProduceReg() void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode) { @@ -6887,18 +6887,18 @@ void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode) unsigned ival = 0; - // v) tree oper is CORINFO_INTRINSIC_Round, _Ceiling, or _Floor - switch (treeNode->AsIntrinsic()->gtIntrinsicId) + // v) tree oper is NI_System_Math{F}_Round, _Ceiling, or _Floor + switch (treeNode->AsIntrinsic()->gtIntrinsicName) { - case CORINFO_INTRINSIC_Round: + case NI_System_Math_Round: ival = 4; break; - case CORINFO_INTRINSIC_Ceiling: + case NI_System_Math_Ceiling: ival = 10; break; - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Floor: ival = 9; break; @@ -7020,9 +7020,9 @@ void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode) void CodeGen::genIntrinsic(GenTree* treeNode) { // Right now only Sqrt/Abs are treated as math intrinsics. - switch (treeNode->AsIntrinsic()->gtIntrinsicId) + switch (treeNode->AsIntrinsic()->gtIntrinsicName) { - case CORINFO_INTRINSIC_Sqrt: + case NI_System_Math_Sqrt: { // Both operand and its result must be of the same floating point type. GenTree* srcNode = treeNode->AsOp()->gtOp1; @@ -7034,13 +7034,13 @@ void CodeGen::genIntrinsic(GenTree* treeNode) break; } - case CORINFO_INTRINSIC_Abs: + case NI_System_Math_Abs: genSSE2BitwiseOp(treeNode); break; - case CORINFO_INTRINSIC_Round: - case CORINFO_INTRINSIC_Ceiling: - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Round: + case NI_System_Math_Ceiling: + case NI_System_Math_Floor: genSSE41RoundOp(treeNode->AsOp()); break; diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 37897a6..7c3a347 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -3741,7 +3741,7 @@ protected: GenTree* impMathIntrinsic(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig, var_types callType, - CorInfoIntrinsics intrinsicID, + NamedIntrinsic intrinsicName, bool tailCall); NamedIntrinsic lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method); GenTree* impUnsupportedNamedIntrinsic(unsigned helper, @@ -3937,9 +3937,9 @@ public: bool VarTypeIsMultiByteAndCanEnreg( var_types type, CORINFO_CLASS_HANDLE typeClass, unsigned* typeSize, bool forReturn, bool isVarArg); - bool IsIntrinsicImplementedByUserCall(CorInfoIntrinsics intrinsicId); - bool IsTargetIntrinsic(CorInfoIntrinsics intrinsicId); - bool IsMathIntrinsic(CorInfoIntrinsics intrinsicId); + bool IsIntrinsicImplementedByUserCall(NamedIntrinsic intrinsicName); + bool IsTargetIntrinsic(NamedIntrinsic intrinsicName); + bool IsMathIntrinsic(NamedIntrinsic intrinsicName); bool IsMathIntrinsic(GenTree* tree); private: @@ -9079,7 +9079,7 @@ public: bool compIsVarArgs : 1; // Does the method have varargs parameters? bool compInitMem : 1; // Is the CORINFO_OPT_INIT_LOCALS bit set in the method info options? bool compProfilerCallback : 1; // JIT inserted a profiler Enter callback - bool compPublishStubParam : 1; // EAX captured in prolog will be available through an instrinsic + bool compPublishStubParam : 1; // EAX captured in prolog will be available through an intrinsic bool compRetBuffDefStack : 1; // The ret buff argument definitely points into the stack. bool compHasNextCallRetAddr : 1; // The NextCallReturnAddress intrinsic is used. diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index e39c9c7..ca5c6d4 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -3624,6 +3624,8 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) level = gtSetEvalOrder(op1); + GenTreeIntrinsic* intrinsic; + /* Special handling for some operators */ switch (oper) @@ -3685,54 +3687,82 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) break; case GT_INTRINSIC: - // GT_INTRINSIC intrinsics Sin, Cos, Sqrt, Abs ... have higher costs. - // TODO: tune these costs target specific as some of these are - // target intrinsics and would cost less to generate code. - switch (tree->AsIntrinsic()->gtIntrinsicId) + intrinsic = tree->AsIntrinsic(); + if (intrinsic->gtIntrinsicId == CORINFO_INTRINSIC_Illegal) { - default: - assert(!"missing case for gtIntrinsicId"); - costEx = 12; - costSz = 12; - break; + // named intrinsic + assert(intrinsic->gtIntrinsicName != NI_Illegal); - case CORINFO_INTRINSIC_Sin: - case CORINFO_INTRINSIC_Cos: - case CORINFO_INTRINSIC_Sqrt: - case CORINFO_INTRINSIC_Cbrt: - case CORINFO_INTRINSIC_Cosh: - case CORINFO_INTRINSIC_Sinh: - case CORINFO_INTRINSIC_Tan: - case CORINFO_INTRINSIC_Tanh: - case CORINFO_INTRINSIC_Asin: - case CORINFO_INTRINSIC_Asinh: - case CORINFO_INTRINSIC_Acos: - case CORINFO_INTRINSIC_Acosh: - case CORINFO_INTRINSIC_Atan: - case CORINFO_INTRINSIC_Atanh: - case CORINFO_INTRINSIC_Atan2: - case CORINFO_INTRINSIC_Log10: - case CORINFO_INTRINSIC_Pow: - case CORINFO_INTRINSIC_Exp: - case CORINFO_INTRINSIC_Ceiling: - case CORINFO_INTRINSIC_Floor: - case CORINFO_INTRINSIC_Object_GetType: - // Giving intrinsics a large fixed execution cost is because we'd like to CSE - // them, even if they are implemented by calls. This is different from modeling - // user calls since we never CSE user calls. - costEx = 36; - costSz = 4; - break; + // GT_INTRINSIC intrinsics Sin, Cos, Sqrt, Abs ... have higher costs. + // TODO: tune these costs target specific as some of these are + // target intrinsics and would cost less to generate code. + switch (intrinsic->gtIntrinsicName) + { + default: + assert(!"missing case for gtIntrinsicName"); + costEx = 12; + costSz = 12; + break; - case CORINFO_INTRINSIC_Abs: - costEx = 5; - costSz = 15; - break; + case NI_System_Math_Sin: + case NI_System_Math_Cos: + case NI_System_Math_Sqrt: + case NI_System_Math_Cbrt: + case NI_System_Math_Cosh: + case NI_System_Math_Sinh: + case NI_System_Math_Tan: + case NI_System_Math_Tanh: + case NI_System_Math_Asin: + case NI_System_Math_Asinh: + case NI_System_Math_Acos: + case NI_System_Math_Acosh: + case NI_System_Math_Atan: + case NI_System_Math_Atanh: + case NI_System_Math_Atan2: + case NI_System_Math_Log10: + case NI_System_Math_Pow: + case NI_System_Math_Exp: + case NI_System_Math_Ceiling: + case NI_System_Math_Floor: + // Giving intrinsics a large fixed execution cost is because we'd like to CSE + // them, even if they are implemented by calls. This is different from modeling + // user calls since we never CSE user calls. + costEx = 36; + costSz = 4; + break; - case CORINFO_INTRINSIC_Round: - costEx = 3; - costSz = 4; - break; + case NI_System_Math_Abs: + costEx = 5; + costSz = 15; + break; + + case NI_System_Math_Round: + costEx = 3; + costSz = 4; + break; + } + } + else + { + // old style intrinsic + assert(intrinsic->gtIntrinsicName == NI_Illegal); + + switch (intrinsic->gtIntrinsicId) + { + default: + assert(!"missing case for gtIntrinsicId"); + costEx = 12; + costSz = 12; + break; + + case CORINFO_INTRINSIC_Object_GetType: + // Giving intrinsics a large fixed execution cost is because we'd like to CSE + // them, even if they are implemented by calls. This is different from modeling + // user calls since we never CSE user calls. + costEx = 36; + costSz = 4; + break; + } } level++; break; @@ -4215,10 +4245,10 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) case GT_INTRINSIC: - switch (tree->AsIntrinsic()->gtIntrinsicId) + switch (tree->AsIntrinsic()->gtIntrinsicName) { - case CORINFO_INTRINSIC_Atan2: - case CORINFO_INTRINSIC_Pow: + case NI_System_Math_Atan2: + case NI_System_Math_Pow: // These math intrinsics are actually implemented by user calls. // Increase the Sethi 'complexity' by two to reflect the argument // register requirement. @@ -4275,7 +4305,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) // so if possible it was set above. tryToSwap = false; } - else if ((oper == GT_INTRINSIC) && IsIntrinsicImplementedByUserCall(tree->AsIntrinsic()->gtIntrinsicId)) + else if ((oper == GT_INTRINSIC) && IsIntrinsicImplementedByUserCall(tree->AsIntrinsic()->gtIntrinsicName)) { // We do not swap operand execution order for intrinsics that are implemented by user calls // because of trickiness around ensuring the execution order does not change during rationalization. @@ -5477,7 +5507,7 @@ bool GenTree::OperRequiresCallFlag(Compiler* comp) return true; case GT_INTRINSIC: - return comp->IsIntrinsicImplementedByUserCall(this->AsIntrinsic()->gtIntrinsicId); + return comp->IsIntrinsicImplementedByUserCall(this->AsIntrinsic()->gtIntrinsicName); #if FEATURE_FIXED_OUT_ARGS && !defined(TARGET_64BIT) case GT_LSH: @@ -7699,7 +7729,8 @@ GenTree* Compiler::gtCloneExpr( case GT_INTRINSIC: copy = new (this, GT_INTRINSIC) GenTreeIntrinsic(tree->TypeGet(), tree->AsOp()->gtOp1, tree->AsOp()->gtOp2, - tree->AsIntrinsic()->gtIntrinsicId, tree->AsIntrinsic()->gtMethodHandle); + tree->AsIntrinsic()->gtIntrinsicId, tree->AsIntrinsic()->gtIntrinsicName, + tree->AsIntrinsic()->gtMethodHandle); #ifdef FEATURE_READYTORUN_COMPILER copy->AsIntrinsic()->gtEntryPoint = tree->AsIntrinsic()->gtEntryPoint; #endif @@ -11460,80 +11491,98 @@ void Compiler::gtDispTree(GenTree* tree, if (tree->gtOper == GT_INTRINSIC) { - switch (tree->AsIntrinsic()->gtIntrinsicId) + GenTreeIntrinsic* intrinsic = tree->AsIntrinsic(); + + if (intrinsic->gtIntrinsicId == CORINFO_INTRINSIC_Illegal) { - case CORINFO_INTRINSIC_Sin: - printf(" sin"); - break; - case CORINFO_INTRINSIC_Cos: - printf(" cos"); - break; - case CORINFO_INTRINSIC_Cbrt: - printf(" cbrt"); - break; - case CORINFO_INTRINSIC_Sqrt: - printf(" sqrt"); - break; - case CORINFO_INTRINSIC_Abs: - printf(" abs"); - break; - case CORINFO_INTRINSIC_Round: - printf(" round"); - break; - case CORINFO_INTRINSIC_Cosh: - printf(" cosh"); - break; - case CORINFO_INTRINSIC_Sinh: - printf(" sinh"); - break; - case CORINFO_INTRINSIC_Tan: - printf(" tan"); - break; - case CORINFO_INTRINSIC_Tanh: - printf(" tanh"); - break; - case CORINFO_INTRINSIC_Asin: - printf(" asin"); - break; - case CORINFO_INTRINSIC_Asinh: - printf(" asinh"); - break; - case CORINFO_INTRINSIC_Acos: - printf(" acos"); - break; - case CORINFO_INTRINSIC_Acosh: - printf(" acosh"); - break; - case CORINFO_INTRINSIC_Atan: - printf(" atan"); - break; - case CORINFO_INTRINSIC_Atan2: - printf(" atan2"); - break; - case CORINFO_INTRINSIC_Atanh: - printf(" atanh"); - break; - case CORINFO_INTRINSIC_Log10: - printf(" log10"); - break; - case CORINFO_INTRINSIC_Pow: - printf(" pow"); - break; - case CORINFO_INTRINSIC_Exp: - printf(" exp"); - break; - case CORINFO_INTRINSIC_Ceiling: - printf(" ceiling"); - break; - case CORINFO_INTRINSIC_Floor: - printf(" floor"); - break; - case CORINFO_INTRINSIC_Object_GetType: - printf(" objGetType"); - break; + // named intrinsic + assert(intrinsic->gtIntrinsicName != NI_Illegal); + switch (intrinsic->gtIntrinsicName) + { + case NI_System_Math_Sin: + printf(" sin"); + break; + case NI_System_Math_Cos: + printf(" cos"); + break; + case NI_System_Math_Cbrt: + printf(" cbrt"); + break; + case NI_System_Math_Sqrt: + printf(" sqrt"); + break; + case NI_System_Math_Abs: + printf(" abs"); + break; + case NI_System_Math_Round: + printf(" round"); + break; + case NI_System_Math_Cosh: + printf(" cosh"); + break; + case NI_System_Math_Sinh: + printf(" sinh"); + break; + case NI_System_Math_Tan: + printf(" tan"); + break; + case NI_System_Math_Tanh: + printf(" tanh"); + break; + case NI_System_Math_Asin: + printf(" asin"); + break; + case NI_System_Math_Asinh: + printf(" asinh"); + break; + case NI_System_Math_Acos: + printf(" acos"); + break; + case NI_System_Math_Acosh: + printf(" acosh"); + break; + case NI_System_Math_Atan: + printf(" atan"); + break; + case NI_System_Math_Atan2: + printf(" atan2"); + break; + case NI_System_Math_Atanh: + printf(" atanh"); + break; + case NI_System_Math_Log10: + printf(" log10"); + break; + case NI_System_Math_Pow: + printf(" pow"); + break; + case NI_System_Math_Exp: + printf(" exp"); + break; + case NI_System_Math_Ceiling: + printf(" ceiling"); + break; + case NI_System_Math_Floor: + printf(" floor"); + break; - default: - unreached(); + default: + unreached(); + } + } + else + { + // old style intrinsic + assert(intrinsic->gtIntrinsicName == NI_Illegal); + switch (intrinsic->gtIntrinsicId) + { + case CORINFO_INTRINSIC_Object_GetType: + printf(" objGetType"); + break; + + default: + unreached(); + } } } @@ -18758,7 +18807,7 @@ bool GenTree::isCommutativeSIMDIntrinsic() } } -// Returns true for the SIMD Instrinsic instructions that have MemoryLoad semantics, false otherwise +// Returns true for the SIMD Intrinsic instructions that have MemoryLoad semantics, false otherwise bool GenTreeSIMD::OperIsMemoryLoad() const { if (gtSIMDIntrinsicID == SIMDIntrinsicInitArray) @@ -18980,7 +19029,7 @@ GenTreeHWIntrinsic* Compiler::gtNewScalarHWIntrinsicNode( GenTreeHWIntrinsic(type, gtNewArgList(op1, op2, op3), hwIntrinsicID, TYP_UNKNOWN, 0); } -// Returns true for the HW Instrinsic instructions that have MemoryLoad semantics, false otherwise +// Returns true for the HW Intrinsic instructions that have MemoryLoad semantics, false otherwise bool GenTreeHWIntrinsic::OperIsMemoryLoad() const { #if defined(TARGET_XARCH) || defined(TARGET_ARM64) @@ -19023,7 +19072,7 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad() const return false; } -// Returns true for the HW Instrinsic instructions that have MemoryStore semantics, false otherwise +// Returns true for the HW Intrinsic instructions that have MemoryStore semantics, false otherwise bool GenTreeHWIntrinsic::OperIsMemoryStore() const { #if defined(TARGET_XARCH) || defined(TARGET_ARM64) @@ -19059,7 +19108,7 @@ bool GenTreeHWIntrinsic::OperIsMemoryStore() const return false; } -// Returns true for the HW Instrinsic instructions that have MemoryLoad semantics, false otherwise +// Returns true for the HW Intrinsic instructions that have MemoryLoad semantics, false otherwise bool GenTreeHWIntrinsic::OperIsMemoryLoadOrStore() const { #if defined(TARGET_XARCH) || defined(TARGET_ARM64) diff --git a/src/coreclr/src/jit/gentree.h b/src/coreclr/src/jit/gentree.h index b6a95a1..7e25365 100644 --- a/src/coreclr/src/jit/gentree.h +++ b/src/coreclr/src/jit/gentree.h @@ -4729,6 +4729,7 @@ struct GenTreeQmark : public GenTreeOp struct GenTreeIntrinsic : public GenTreeOp { CorInfoIntrinsics gtIntrinsicId; + NamedIntrinsic gtIntrinsicName; CORINFO_METHOD_HANDLE gtMethodHandle; // Method handle of the method which is treated as an intrinsic. #ifdef FEATURE_READYTORUN_COMPILER @@ -4736,15 +4737,31 @@ struct GenTreeIntrinsic : public GenTreeOp CORINFO_CONST_LOOKUP gtEntryPoint; #endif - GenTreeIntrinsic(var_types type, GenTree* op1, CorInfoIntrinsics intrinsicId, CORINFO_METHOD_HANDLE methodHandle) - : GenTreeOp(GT_INTRINSIC, type, op1, nullptr), gtIntrinsicId(intrinsicId), gtMethodHandle(methodHandle) + GenTreeIntrinsic(var_types type, + GenTree* op1, + CorInfoIntrinsics intrinsicId, + NamedIntrinsic intrinsicName, + CORINFO_METHOD_HANDLE methodHandle) + : GenTreeOp(GT_INTRINSIC, type, op1, nullptr) + , gtIntrinsicId(intrinsicId) + , gtIntrinsicName(intrinsicName) + , gtMethodHandle(methodHandle) { + assert(intrinsicId != CORINFO_INTRINSIC_Illegal || intrinsicName != NI_Illegal); } - GenTreeIntrinsic( - var_types type, GenTree* op1, GenTree* op2, CorInfoIntrinsics intrinsicId, CORINFO_METHOD_HANDLE methodHandle) - : GenTreeOp(GT_INTRINSIC, type, op1, op2), gtIntrinsicId(intrinsicId), gtMethodHandle(methodHandle) + GenTreeIntrinsic(var_types type, + GenTree* op1, + GenTree* op2, + CorInfoIntrinsics intrinsicId, + NamedIntrinsic intrinsicName, + CORINFO_METHOD_HANDLE methodHandle) + : GenTreeOp(GT_INTRINSIC, type, op1, op2) + , gtIntrinsicId(intrinsicId) + , gtIntrinsicName(intrinsicName) + , gtMethodHandle(methodHandle) { + assert(intrinsicId != CORINFO_INTRINSIC_Illegal || intrinsicName != NI_Illegal); } #if DEBUGGABLE_GENTREE @@ -4848,7 +4865,7 @@ struct GenTreeSIMD : public GenTreeJitIntrinsic gtSIMDIntrinsicID = simdIntrinsicID; } - bool OperIsMemoryLoad() const; // Returns true for the SIMD Instrinsic instructions that have MemoryLoad semantics, + bool OperIsMemoryLoad() const; // Returns true for the SIMD Intrinsic instructions that have MemoryLoad semantics, // false otherwise #if DEBUGGABLE_GENTREE @@ -4889,15 +4906,15 @@ struct GenTreeHWIntrinsic : public GenTreeJitIntrinsic } } - // Note that HW Instrinsic instructions are a sub class of GenTreeOp which only supports two operands - // However there are HW Instrinsic instructions that have 3 or even 4 operands and this is + // Note that HW Intrinsic instructions are a sub class of GenTreeOp which only supports two operands + // However there are HW Intrinsic instructions that have 3 or even 4 operands and this is // supported using a single op1 and using an ArgList for it: gtNewArgList(op1, op2, op3) - bool OperIsMemoryLoad() const; // Returns true for the HW Instrinsic instructions that have MemoryLoad semantics, + bool OperIsMemoryLoad() const; // Returns true for the HW Intrinsic instructions that have MemoryLoad semantics, // false otherwise - bool OperIsMemoryStore() const; // Returns true for the HW Instrinsic instructions that have MemoryStore semantics, + bool OperIsMemoryStore() const; // Returns true for the HW Intrinsic instructions that have MemoryStore semantics, // false otherwise - bool OperIsMemoryLoadOrStore() const; // Returns true for the HW Instrinsic instructions that have MemoryLoad or + bool OperIsMemoryLoadOrStore() const; // Returns true for the HW Intrinsic instructions that have MemoryLoad or // MemoryStore semantics, false otherwise #if DEBUGGABLE_GENTREE diff --git a/src/coreclr/src/jit/hwintrinsic.cpp b/src/coreclr/src/jit/hwintrinsic.cpp index 5e7eda6..5723ac8 100644 --- a/src/coreclr/src/jit/hwintrinsic.cpp +++ b/src/coreclr/src/jit/hwintrinsic.cpp @@ -202,7 +202,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleForHWSIMD(var_types simdType, va { int numArgs = HWIntrinsicInfo::lookupNumArgs(hwIntrinsicID); - // HW Instrinsic's with -1 for numArgs have a varying number of args, so we currently + // HW Intrinsic's with -1 for numArgs have a varying number of args, so we currently // give themm a unique value number them, and don't add an extra argument. // if (numArgs == -1) @@ -210,7 +210,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleForHWSIMD(var_types simdType, va return false; } - // We iterate over all of the different baseType's for this instrinsic in the HWIntrinsicInfo table + // We iterate over all of the different baseType's for this intrinsic in the HWIntrinsicInfo table // We set diffInsCount to the number of instructions that can execute differently. // unsigned diffInsCount = 0; diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index e1443b8..6280e1b 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -3623,31 +3623,6 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, GenTree* op1; GenTree* op2; - case CORINFO_INTRINSIC_Sin: - case CORINFO_INTRINSIC_Cbrt: - case CORINFO_INTRINSIC_Sqrt: - case CORINFO_INTRINSIC_Abs: - case CORINFO_INTRINSIC_Cos: - case CORINFO_INTRINSIC_Round: - case CORINFO_INTRINSIC_Cosh: - case CORINFO_INTRINSIC_Sinh: - case CORINFO_INTRINSIC_Tan: - case CORINFO_INTRINSIC_Tanh: - case CORINFO_INTRINSIC_Asin: - case CORINFO_INTRINSIC_Asinh: - case CORINFO_INTRINSIC_Acos: - case CORINFO_INTRINSIC_Acosh: - case CORINFO_INTRINSIC_Atan: - case CORINFO_INTRINSIC_Atan2: - case CORINFO_INTRINSIC_Atanh: - case CORINFO_INTRINSIC_Log10: - case CORINFO_INTRINSIC_Pow: - case CORINFO_INTRINSIC_Exp: - case CORINFO_INTRINSIC_Ceiling: - case CORINFO_INTRINSIC_Floor: - retNode = impMathIntrinsic(method, sig, callType, intrinsicID, tailCall); - break; - #if defined(TARGET_XARCH) || defined(TARGET_ARM64) // TODO-ARM-CQ: reenable treating Interlocked operation as intrinsic @@ -3921,7 +3896,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, { JITDUMP("Expanding as special intrinsic\n"); impPopStack(); - op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, intrinsicID, method); + op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, intrinsicID, ni, method); // Set the CALL flag to indicate that the operator is implemented by a call. // Set also the EXCEPTION flag because the native implementation of @@ -4218,7 +4193,6 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, #ifdef FEATURE_HW_INTRINSICS case NI_System_Math_FusedMultiplyAdd: - case NI_System_MathF_FusedMultiplyAdd: { #ifdef TARGET_XARCH if (compExactlyDependsOn(InstructionSet_FMA) && supportSIMDTypes()) @@ -4248,15 +4222,30 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, } #endif // FEATURE_HW_INTRINSICS + case NI_System_Math_Sin: + case NI_System_Math_Cbrt: + case NI_System_Math_Sqrt: + case NI_System_Math_Abs: + case NI_System_Math_Cos: case NI_System_Math_Round: - case NI_System_MathF_Round: - { - // Math.Round and MathF.Round used to be a traditional JIT intrinsic. In order - // to simplify the transition, we will just treat it as if it was still the - // old intrinsic, CORINFO_INTRINSIC_Round. This should end up flowing properly - // everywhere else. - - retNode = impMathIntrinsic(method, sig, callType, CORINFO_INTRINSIC_Round, tailCall); + case NI_System_Math_Cosh: + case NI_System_Math_Sinh: + case NI_System_Math_Tan: + case NI_System_Math_Tanh: + case NI_System_Math_Asin: + case NI_System_Math_Asinh: + case NI_System_Math_Acos: + case NI_System_Math_Acosh: + case NI_System_Math_Atan: + case NI_System_Math_Atan2: + case NI_System_Math_Atanh: + case NI_System_Math_Log10: + case NI_System_Math_Pow: + case NI_System_Math_Exp: + case NI_System_Math_Ceiling: + case NI_System_Math_Floor: + { + retNode = impMathIntrinsic(method, sig, callType, ni, tailCall); break; } @@ -4345,14 +4334,14 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig, var_types callType, - CorInfoIntrinsics intrinsicID, + NamedIntrinsic intrinsicName, bool tailCall) { GenTree* op1; GenTree* op2; assert(callType != TYP_STRUCT); - assert(IsMathIntrinsic(intrinsicID)); + assert(IsMathIntrinsic(intrinsicName)); op1 = nullptr; @@ -4363,12 +4352,12 @@ GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method, // a) For back compatibility reasons on desktop .NET Framework 4.6 / 4.6.1 // b) It will be non-trivial task or too late to re-materialize a surviving // tail prefixed GT_INTRINSIC as tail call in rationalizer. - if (!IsIntrinsicImplementedByUserCall(intrinsicID) || !tailCall) + if (!IsIntrinsicImplementedByUserCall(intrinsicName) || !tailCall) #else // On x86 RyuJIT, importing intrinsics that are implemented as user calls can cause incorrect calculation // of the depth of the stack if these intrinsics are used as arguments to another call. This causes bad // code generation for certain EH constructs. - if (!IsIntrinsicImplementedByUserCall(intrinsicID)) + if (!IsIntrinsicImplementedByUserCall(intrinsicName)) #endif { switch (sig->numArgs) @@ -4383,7 +4372,8 @@ GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method, op1 = gtNewCastNode(callType, op1, false, callType); } - op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, intrinsicID, method); + op1 = new (this, GT_INTRINSIC) + GenTreeIntrinsic(genActualType(callType), op1, CORINFO_INTRINSIC_Illegal, intrinsicName, method); break; case 2: @@ -4402,14 +4392,15 @@ GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method, op1 = gtNewCastNode(callType, op1, false, callType); } - op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, op2, intrinsicID, method); + op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, op2, + CORINFO_INTRINSIC_Illegal, intrinsicName, method); break; default: - NO_WAY("Unsupported number of args for Math Instrinsic"); + NO_WAY("Unsupported number of args for Math Intrinsic"); } - if (IsIntrinsicImplementedByUserCall(intrinsicID)) + if (IsIntrinsicImplementedByUserCall(intrinsicName)) { op1->gtFlags |= GTF_CALL; } @@ -4474,31 +4465,99 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) { result = NI_System_Enum_HasFlag; } - else if (strncmp(className, "Math", 4) == 0) + else if (strcmp(className, "Math") == 0 || strcmp(className, "MathF") == 0) { - className += 4; - - if (className[0] == '\0') + if (strcmp(methodName, "FusedMultiplyAdd") == 0) { - if (strcmp(methodName, "FusedMultiplyAdd") == 0) - { - result = NI_System_Math_FusedMultiplyAdd; - } - else if (strcmp(methodName, "Round") == 0) - { - result = NI_System_Math_Round; - } + result = NI_System_Math_FusedMultiplyAdd; } - else if (strcmp(className, "F") == 0) + else if (strcmp(methodName, "Round") == 0) { - if (strcmp(methodName, "FusedMultiplyAdd") == 0) - { - result = NI_System_MathF_FusedMultiplyAdd; - } - else if (strcmp(methodName, "Round") == 0) - { - result = NI_System_MathF_Round; - } + result = NI_System_Math_Round; + } + else if (strcmp(methodName, "Sin") == 0) + { + result = NI_System_Math_Sin; + } + else if (strcmp(methodName, "Cos") == 0) + { + result = NI_System_Math_Cos; + } + else if (strcmp(methodName, "Cbrt") == 0) + { + result = NI_System_Math_Cbrt; + } + else if (strcmp(methodName, "Sqrt") == 0) + { + result = NI_System_Math_Sqrt; + } + else if (strcmp(methodName, "Abs") == 0) + { + result = NI_System_Math_Abs; + } + else if (strcmp(methodName, "Cosh") == 0) + { + result = NI_System_Math_Cosh; + } + else if (strcmp(methodName, "Sinh") == 0) + { + result = NI_System_Math_Sinh; + } + else if (strcmp(methodName, "Tan") == 0) + { + result = NI_System_Math_Tan; + } + else if (strcmp(methodName, "Tanh") == 0) + { + result = NI_System_Math_Tanh; + } + else if (strcmp(methodName, "Asin") == 0) + { + result = NI_System_Math_Asin; + } + else if (strcmp(methodName, "Asinh") == 0) + { + result = NI_System_Math_Asinh; + } + else if (strcmp(methodName, "Acos") == 0) + { + result = NI_System_Math_Acos; + } + else if (strcmp(methodName, "Acosh") == 0) + { + result = NI_System_Math_Acosh; + } + else if (strcmp(methodName, "Atan") == 0) + { + result = NI_System_Math_Atan; + } + else if (strcmp(methodName, "Atan2") == 0) + { + result = NI_System_Math_Atan2; + } + else if (strcmp(methodName, "Atanh") == 0) + { + result = NI_System_Math_Atanh; + } + else if (strcmp(methodName, "Log10") == 0) + { + result = NI_System_Math_Log10; + } + else if (strcmp(methodName, "Pow") == 0) + { + result = NI_System_Math_Pow; + } + else if (strcmp(methodName, "Exp") == 0) + { + result = NI_System_Math_Exp; + } + else if (strcmp(methodName, "Ceiling") == 0) + { + result = NI_System_Math_Ceiling; + } + else if (strcmp(methodName, "Floor") == 0) + { + result = NI_System_Math_Floor; } } else if (strcmp(className, "GC") == 0) @@ -7944,9 +8003,9 @@ var_types Compiler::impImportCall(OPCODE opcode, // This is for a non-virtual, non-interface etc. call call = gtNewCallNode(CT_USER_FUNC, callInfo->hMethod, callRetTyp, nullptr, ilOffset); - // We remove the nullcheck for the GetType call instrinsic. + // We remove the nullcheck for the GetType call intrinsic. // TODO-CQ: JIT64 does not introduce the null check for many more helper calls - // and instrinsics. + // and intrinsics. if (callInfo->nullInstanceCheck && !((mflags & CORINFO_FLG_INTRINSIC) != 0 && (intrinsicID == CORINFO_INTRINSIC_Object_GetType))) { @@ -20072,10 +20131,10 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call, // Returns true if the given intrinsic will be implemented by target-specific // instructions -bool Compiler::IsTargetIntrinsic(CorInfoIntrinsics intrinsicId) +bool Compiler::IsTargetIntrinsic(NamedIntrinsic intrinsicName) { #if defined(TARGET_XARCH) - switch (intrinsicId) + switch (intrinsicName) { // AMD64/x86 has SSE2 instructions to directly compute sqrt/abs and SSE4.1 // instructions to directly compute round/ceiling/floor. @@ -20086,37 +20145,37 @@ bool Compiler::IsTargetIntrinsic(CorInfoIntrinsics intrinsicId) // a CQ problem, it may be necessary to change the implementation of // the helper calls to decrease call overhead or switch back to the // x87 instructions. This is tracked by #7097. - case CORINFO_INTRINSIC_Sqrt: - case CORINFO_INTRINSIC_Abs: + case NI_System_Math_Sqrt: + case NI_System_Math_Abs: return true; - case CORINFO_INTRINSIC_Round: - case CORINFO_INTRINSIC_Ceiling: - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Round: + case NI_System_Math_Ceiling: + case NI_System_Math_Floor: return compOpportunisticallyDependsOn(InstructionSet_SSE41); default: return false; } #elif defined(TARGET_ARM64) - switch (intrinsicId) + switch (intrinsicName) { - case CORINFO_INTRINSIC_Sqrt: - case CORINFO_INTRINSIC_Abs: - case CORINFO_INTRINSIC_Round: - case CORINFO_INTRINSIC_Floor: - case CORINFO_INTRINSIC_Ceiling: + case NI_System_Math_Sqrt: + case NI_System_Math_Abs: + case NI_System_Math_Round: + case NI_System_Math_Floor: + case NI_System_Math_Ceiling: return true; default: return false; } #elif defined(TARGET_ARM) - switch (intrinsicId) + switch (intrinsicName) { - case CORINFO_INTRINSIC_Sqrt: - case CORINFO_INTRINSIC_Abs: - case CORINFO_INTRINSIC_Round: + case NI_System_Math_Sqrt: + case NI_System_Math_Abs: + case NI_System_Math_Round: return true; default: @@ -20134,41 +20193,41 @@ bool Compiler::IsTargetIntrinsic(CorInfoIntrinsics intrinsicId) // Returns true if the given intrinsic will be implemented by calling System.Math // methods. -bool Compiler::IsIntrinsicImplementedByUserCall(CorInfoIntrinsics intrinsicId) +bool Compiler::IsIntrinsicImplementedByUserCall(NamedIntrinsic intrinsicName) { // Currently, if a math intrinsic is not implemented by target-specific // instructions, it will be implemented by a System.Math call. In the // future, if we turn to implementing some of them with helper calls, // this predicate needs to be revisited. - return !IsTargetIntrinsic(intrinsicId); + return !IsTargetIntrinsic(intrinsicName); } -bool Compiler::IsMathIntrinsic(CorInfoIntrinsics intrinsicId) +bool Compiler::IsMathIntrinsic(NamedIntrinsic intrinsicName) { - switch (intrinsicId) - { - case CORINFO_INTRINSIC_Sin: - case CORINFO_INTRINSIC_Cbrt: - case CORINFO_INTRINSIC_Sqrt: - case CORINFO_INTRINSIC_Abs: - case CORINFO_INTRINSIC_Cos: - case CORINFO_INTRINSIC_Round: - case CORINFO_INTRINSIC_Cosh: - case CORINFO_INTRINSIC_Sinh: - case CORINFO_INTRINSIC_Tan: - case CORINFO_INTRINSIC_Tanh: - case CORINFO_INTRINSIC_Asin: - case CORINFO_INTRINSIC_Asinh: - case CORINFO_INTRINSIC_Acos: - case CORINFO_INTRINSIC_Acosh: - case CORINFO_INTRINSIC_Atan: - case CORINFO_INTRINSIC_Atan2: - case CORINFO_INTRINSIC_Atanh: - case CORINFO_INTRINSIC_Log10: - case CORINFO_INTRINSIC_Pow: - case CORINFO_INTRINSIC_Exp: - case CORINFO_INTRINSIC_Ceiling: - case CORINFO_INTRINSIC_Floor: + switch (intrinsicName) + { + case NI_System_Math_Sin: + case NI_System_Math_Cbrt: + case NI_System_Math_Sqrt: + case NI_System_Math_Abs: + case NI_System_Math_Cos: + case NI_System_Math_Round: + case NI_System_Math_Cosh: + case NI_System_Math_Sinh: + case NI_System_Math_Tan: + case NI_System_Math_Tanh: + case NI_System_Math_Asin: + case NI_System_Math_Asinh: + case NI_System_Math_Acos: + case NI_System_Math_Acosh: + case NI_System_Math_Atan: + case NI_System_Math_Atan2: + case NI_System_Math_Atanh: + case NI_System_Math_Log10: + case NI_System_Math_Pow: + case NI_System_Math_Exp: + case NI_System_Math_Ceiling: + case NI_System_Math_Floor: return true; default: return false; @@ -20177,7 +20236,7 @@ bool Compiler::IsMathIntrinsic(CorInfoIntrinsics intrinsicId) bool Compiler::IsMathIntrinsic(GenTree* tree) { - return (tree->OperGet() == GT_INTRINSIC) && IsMathIntrinsic(tree->AsIntrinsic()->gtIntrinsicId); + return (tree->OperGet() == GT_INTRINSIC) && IsMathIntrinsic(tree->AsIntrinsic()->gtIntrinsicName); } //------------------------------------------------------------------------ diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp index 331c674..052abaf 100644 --- a/src/coreclr/src/jit/lowerxarch.cpp +++ b/src/coreclr/src/jit/lowerxarch.cpp @@ -4616,10 +4616,10 @@ void Lowering::ContainCheckIntrinsic(GenTreeOp* node) { assert(node->OperIs(GT_INTRINSIC)); - CorInfoIntrinsics intrinsicId = node->AsIntrinsic()->gtIntrinsicId; + NamedIntrinsic intrinsicName = node->AsIntrinsic()->gtIntrinsicName; - if (intrinsicId == CORINFO_INTRINSIC_Sqrt || intrinsicId == CORINFO_INTRINSIC_Round || - intrinsicId == CORINFO_INTRINSIC_Ceiling || intrinsicId == CORINFO_INTRINSIC_Floor) + if (intrinsicName == NI_System_Math_Sqrt || intrinsicName == NI_System_Math_Round || + intrinsicName == NI_System_Math_Ceiling || intrinsicName == NI_System_Math_Floor) { GenTree* op1 = node->gtGetOp1(); if (IsContainableMemoryOp(op1) || op1->IsCnsNonZeroFltOrDbl()) diff --git a/src/coreclr/src/jit/lsraarm.cpp b/src/coreclr/src/jit/lsraarm.cpp index f3b480f..b9b4d0f 100644 --- a/src/coreclr/src/jit/lsraarm.cpp +++ b/src/coreclr/src/jit/lsraarm.cpp @@ -290,10 +290,10 @@ int LinearScan::BuildNode(GenTree* tree) BuildUse(op1); srcCount = 1; - switch (tree->AsIntrinsic()->gtIntrinsicId) + switch (tree->AsIntrinsic()->gtIntrinsicName) { - case CORINFO_INTRINSIC_Abs: - case CORINFO_INTRINSIC_Sqrt: + case NI_System_Math_Abs: + case NI_System_Math_Sqrt: assert(dstCount == 1); BuildDef(tree); break; diff --git a/src/coreclr/src/jit/lsraarm64.cpp b/src/coreclr/src/jit/lsraarm64.cpp index 514ed90..bdb626d 100644 --- a/src/coreclr/src/jit/lsraarm64.cpp +++ b/src/coreclr/src/jit/lsraarm64.cpp @@ -319,11 +319,11 @@ int LinearScan::BuildNode(GenTree* tree) case GT_INTRINSIC: { - noway_assert((tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Abs) || - (tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Ceiling) || - (tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Floor) || - (tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Round) || - (tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Sqrt)); + noway_assert((tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Abs) || + (tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Ceiling) || + (tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Floor) || + (tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Round) || + (tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Sqrt)); // Both operand and its result must be of the same floating point type. GenTree* op1 = tree->gtGetOp1(); diff --git a/src/coreclr/src/jit/lsraxarch.cpp b/src/coreclr/src/jit/lsraxarch.cpp index 8895dc9..e0be880 100644 --- a/src/coreclr/src/jit/lsraxarch.cpp +++ b/src/coreclr/src/jit/lsraxarch.cpp @@ -1779,9 +1779,9 @@ int LinearScan::BuildIntrinsic(GenTree* tree) assert(op1->TypeGet() == tree->TypeGet()); RefPosition* internalFloatDef = nullptr; - switch (tree->AsIntrinsic()->gtIntrinsicId) + switch (tree->AsIntrinsic()->gtIntrinsicName) { - case CORINFO_INTRINSIC_Abs: + case NI_System_Math_Abs: // Abs(float x) = x & 0x7fffffff // Abs(double x) = x & 0x7ffffff ffffffff @@ -1798,16 +1798,16 @@ int LinearScan::BuildIntrinsic(GenTree* tree) break; #ifdef TARGET_X86 - case CORINFO_INTRINSIC_Cos: - case CORINFO_INTRINSIC_Sin: + case NI_System_Math_Cos: + case NI_System_Math_Sin: NYI_X86("Math intrinsics Cos and Sin"); break; #endif // TARGET_X86 - case CORINFO_INTRINSIC_Sqrt: - case CORINFO_INTRINSIC_Round: - case CORINFO_INTRINSIC_Ceiling: - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Sqrt: + case NI_System_Math_Round: + case NI_System_Math_Ceiling: + case NI_System_Math_Floor: break; default: diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index 2979a78..28b15c6 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -5890,7 +5890,7 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac) } #ifdef FEATURE_SIMD - // if this field belongs to simd struct, translate it to simd instrinsic. + // if this field belongs to simd struct, translate it to simd intrinsic. if (mac == nullptr) { GenTree* newTree = fgMorphFieldToSIMDIntrinsicGet(tree); @@ -12166,7 +12166,7 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) #ifdef TARGET_ARM case GT_INTRINSIC: - if (tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Round) + if (tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Round) { switch (tree->TypeGet()) { diff --git a/src/coreclr/src/jit/namedintrinsiclist.h b/src/coreclr/src/jit/namedintrinsiclist.h index 63d79fb..bc84f85 100644 --- a/src/coreclr/src/jit/namedintrinsiclist.h +++ b/src/coreclr/src/jit/namedintrinsiclist.h @@ -12,9 +12,28 @@ enum NamedIntrinsic : unsigned short NI_System_Enum_HasFlag, NI_System_Math_FusedMultiplyAdd, + NI_System_Math_Sin, + NI_System_Math_Cos, + NI_System_Math_Cbrt, + NI_System_Math_Sqrt, + NI_System_Math_Abs, NI_System_Math_Round, - NI_System_MathF_FusedMultiplyAdd, - NI_System_MathF_Round, + NI_System_Math_Cosh, + NI_System_Math_Sinh, + NI_System_Math_Tan, + NI_System_Math_Tanh, + NI_System_Math_Asin, + NI_System_Math_Asinh, + NI_System_Math_Acos, + NI_System_Math_Acosh, + NI_System_Math_Atan, + NI_System_Math_Atan2, + NI_System_Math_Atanh, + NI_System_Math_Log10, + NI_System_Math_Pow, + NI_System_Math_Exp, + NI_System_Math_Ceiling, + NI_System_Math_Floor, NI_System_Collections_Generic_EqualityComparer_get_Default, NI_System_Buffers_Binary_BinaryPrimitives_ReverseEndianness, NI_System_GC_KeepAlive, diff --git a/src/coreclr/src/jit/rationalize.cpp b/src/coreclr/src/jit/rationalize.cpp index b878a30..8054fda 100644 --- a/src/coreclr/src/jit/rationalize.cpp +++ b/src/coreclr/src/jit/rationalize.cpp @@ -726,7 +726,7 @@ Compiler::fgWalkResult Rationalizer::RewriteNode(GenTree** useEdge, Compiler::Ge case GT_INTRINSIC: // Non-target intrinsics should have already been rewritten back into user calls. - assert(comp->IsTargetIntrinsic(node->AsIntrinsic()->gtIntrinsicId)); + assert(comp->IsTargetIntrinsic(node->AsIntrinsic()->gtIntrinsicName)); break; #ifdef FEATURE_SIMD @@ -903,7 +903,7 @@ PhaseStatus Rationalizer::DoPhase() { GenTree* const node = *use; if (node->OperGet() == GT_INTRINSIC && - m_rationalizer.comp->IsIntrinsicImplementedByUserCall(node->AsIntrinsic()->gtIntrinsicId)) + m_rationalizer.comp->IsIntrinsicImplementedByUserCall(node->AsIntrinsic()->gtIntrinsicName)) { m_rationalizer.RewriteIntrinsicAsUserCall(use, this->m_ancestors); } diff --git a/src/coreclr/src/jit/valuenum.cpp b/src/coreclr/src/jit/valuenum.cpp index 1cc0cab..f436216 100644 --- a/src/coreclr/src/jit/valuenum.cpp +++ b/src/coreclr/src/jit/valuenum.cpp @@ -4548,7 +4548,7 @@ void ValueNumStore::SetVNIsCheckedBound(ValueNum vn) m_checkedBoundVNs.AddOrUpdate(vn, true); } -ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMathFN, ValueNum arg0VN) +ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, NamedIntrinsic gtMathFN, ValueNum arg0VN) { assert(arg0VN == VNNormalValue(arg0VN)); @@ -4568,25 +4568,25 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat double res = 0.0; switch (gtMathFN) { - case CORINFO_INTRINSIC_Sin: + case NI_System_Math_Sin: res = sin(arg0Val); break; - case CORINFO_INTRINSIC_Cos: + case NI_System_Math_Cos: res = cos(arg0Val); break; - case CORINFO_INTRINSIC_Sqrt: + case NI_System_Math_Sqrt: res = sqrt(arg0Val); break; - case CORINFO_INTRINSIC_Abs: + case NI_System_Math_Abs: res = fabs(arg0Val); break; - case CORINFO_INTRINSIC_Ceiling: + case NI_System_Math_Ceiling: res = ceil(arg0Val); break; - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Floor: res = floor(arg0Val); break; - case CORINFO_INTRINSIC_Round: + case NI_System_Math_Round: res = FloatingPointUtils::round(arg0Val); break; default: @@ -4604,25 +4604,25 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat float res = 0.0f; switch (gtMathFN) { - case CORINFO_INTRINSIC_Sin: + case NI_System_Math_Sin: res = sinf(arg0Val); break; - case CORINFO_INTRINSIC_Cos: + case NI_System_Math_Cos: res = cosf(arg0Val); break; - case CORINFO_INTRINSIC_Sqrt: + case NI_System_Math_Sqrt: res = sqrtf(arg0Val); break; - case CORINFO_INTRINSIC_Abs: + case NI_System_Math_Abs: res = fabsf(arg0Val); break; - case CORINFO_INTRINSIC_Ceiling: + case NI_System_Math_Ceiling: res = ceilf(arg0Val); break; - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Floor: res = floorf(arg0Val); break; - case CORINFO_INTRINSIC_Round: + case NI_System_Math_Round: res = FloatingPointUtils::round(arg0Val); break; default: @@ -4633,11 +4633,11 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat } else { - // CORINFO_INTRINSIC_Round is currently the only intrinsic that takes floating-point arguments - // and that returns a non floating-point result. + // NI_System_Math{F}_Round are currently the only intrinsic that take floating-point arguments + // and return a non floating-point result. assert(typ == TYP_INT); - assert(gtMathFN == CORINFO_INTRINSIC_Round); + assert(gtMathFN == NI_System_Math_Round); int res = 0; @@ -4664,27 +4664,27 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat } else { - assert(typ == TYP_DOUBLE || typ == TYP_FLOAT || (typ == TYP_INT && gtMathFN == CORINFO_INTRINSIC_Round)); + assert(typ == TYP_DOUBLE || typ == TYP_FLOAT || typ == TYP_INT && gtMathFN == NI_System_Math_Round); VNFunc vnf = VNF_Boundary; switch (gtMathFN) { - case CORINFO_INTRINSIC_Sin: + case NI_System_Math_Sin: vnf = VNF_Sin; break; - case CORINFO_INTRINSIC_Cos: + case NI_System_Math_Cos: vnf = VNF_Cos; break; - case CORINFO_INTRINSIC_Cbrt: + case NI_System_Math_Cbrt: vnf = VNF_Cbrt; break; - case CORINFO_INTRINSIC_Sqrt: + case NI_System_Math_Sqrt: vnf = VNF_Sqrt; break; - case CORINFO_INTRINSIC_Abs: + case NI_System_Math_Abs: vnf = VNF_Abs; break; - case CORINFO_INTRINSIC_Round: + case NI_System_Math_Round: if (typ == TYP_DOUBLE) { vnf = VNF_RoundDouble; @@ -4702,46 +4702,46 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat noway_assert(!"Invalid INTRINSIC_Round"); } break; - case CORINFO_INTRINSIC_Cosh: + case NI_System_Math_Cosh: vnf = VNF_Cosh; break; - case CORINFO_INTRINSIC_Sinh: + case NI_System_Math_Sinh: vnf = VNF_Sinh; break; - case CORINFO_INTRINSIC_Tan: + case NI_System_Math_Tan: vnf = VNF_Tan; break; - case CORINFO_INTRINSIC_Tanh: + case NI_System_Math_Tanh: vnf = VNF_Tanh; break; - case CORINFO_INTRINSIC_Asin: + case NI_System_Math_Asin: vnf = VNF_Asin; break; - case CORINFO_INTRINSIC_Asinh: + case NI_System_Math_Asinh: vnf = VNF_Asinh; break; - case CORINFO_INTRINSIC_Acos: + case NI_System_Math_Acos: vnf = VNF_Acos; break; - case CORINFO_INTRINSIC_Acosh: + case NI_System_Math_Acosh: vnf = VNF_Acosh; break; - case CORINFO_INTRINSIC_Atan: + case NI_System_Math_Atan: vnf = VNF_Atan; break; - case CORINFO_INTRINSIC_Atanh: + case NI_System_Math_Atanh: vnf = VNF_Atanh; break; - case CORINFO_INTRINSIC_Log10: + case NI_System_Math_Log10: vnf = VNF_Log10; break; - case CORINFO_INTRINSIC_Exp: + case NI_System_Math_Exp: vnf = VNF_Exp; break; - case CORINFO_INTRINSIC_Ceiling: + case NI_System_Math_Ceiling: vnf = VNF_Ceiling; break; - case CORINFO_INTRINSIC_Floor: + case NI_System_Math_Floor: vnf = VNF_Floor; break; default: @@ -4752,7 +4752,7 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat } } -ValueNum ValueNumStore::EvalMathFuncBinary(var_types typ, CorInfoIntrinsics gtMathFN, ValueNum arg0VN, ValueNum arg1VN) +ValueNum ValueNumStore::EvalMathFuncBinary(var_types typ, NamedIntrinsic gtMathFN, ValueNum arg0VN, ValueNum arg1VN) { assert(varTypeIsFloating(typ)); assert(arg0VN == VNNormalValue(arg0VN)); @@ -4765,11 +4765,11 @@ ValueNum ValueNumStore::EvalMathFuncBinary(var_types typ, CorInfoIntrinsics gtMa switch (gtMathFN) { - case CORINFO_INTRINSIC_Atan2: + case NI_System_Math_Atan2: vnf = VNF_Atan2; break; - case CORINFO_INTRINSIC_Pow: + case NI_System_Math_Pow: vnf = VNF_Pow; break; @@ -8389,7 +8389,7 @@ void Compiler::fgValueNumberIntrinsic(GenTree* tree) vnStore->VNPUnpackExc(intrinsic->AsOp()->gtOp2->gtVNPair, &arg1VNP, &arg1VNPx); } - if (IsMathIntrinsic(intrinsic->gtIntrinsicId)) + if (IsMathIntrinsic(intrinsic->gtIntrinsicName)) { // GT_INTRINSIC is a currently a subtype of binary operators. But most of // the math intrinsics are actually unary operations. @@ -8397,13 +8397,13 @@ void Compiler::fgValueNumberIntrinsic(GenTree* tree) if (intrinsic->AsOp()->gtOp2 == nullptr) { intrinsic->gtVNPair = - vnStore->VNPWithExc(vnStore->EvalMathFuncUnary(tree->TypeGet(), intrinsic->gtIntrinsicId, arg0VNP), + vnStore->VNPWithExc(vnStore->EvalMathFuncUnary(tree->TypeGet(), intrinsic->gtIntrinsicName, arg0VNP), arg0VNPx); } else { ValueNumPair newVNP = - vnStore->EvalMathFuncBinary(tree->TypeGet(), intrinsic->gtIntrinsicId, arg0VNP, arg1VNP); + vnStore->EvalMathFuncBinary(tree->TypeGet(), intrinsic->gtIntrinsicName, arg0VNP, arg1VNP); ValueNumPair excSet = vnStore->VNPExcSetUnion(arg0VNPx, arg1VNPx); intrinsic->gtVNPair = vnStore->VNPWithExc(newVNP, excSet); } @@ -8615,7 +8615,7 @@ void Compiler::fgValueNumberHWIntrinsic(GenTree* tree) else if (tree->AsOp()->gtOp1->OperIs(GT_LIST) || (lookupNumArgs == -1)) { // We have a HWINTRINSIC node in the GT_LIST form with 3 or more args - // Or the numArgs was specified as -1 in the numArgs column in "hwinstrinsiclistxarch.h" + // Or the numArgs was specified as -1 in the numArgs column in "hwintrinsiclistxarch.h" // For now we will generate a unique value number for this case. // Generate unique VN diff --git a/src/coreclr/src/jit/valuenum.h b/src/coreclr/src/jit/valuenum.h index 9f3cc20..2f57b63 100644 --- a/src/coreclr/src/jit/valuenum.h +++ b/src/coreclr/src/jit/valuenum.h @@ -818,20 +818,17 @@ public: // "arg0VN". For binary ops, return the value number for the application of this function to "arg0VN" and // "arg1VN". - ValueNum EvalMathFuncUnary(var_types typ, CorInfoIntrinsics mthFunc, ValueNum arg0VN); + ValueNum EvalMathFuncUnary(var_types typ, NamedIntrinsic mthFunc, ValueNum arg0VN); - ValueNum EvalMathFuncBinary(var_types typ, CorInfoIntrinsics mthFunc, ValueNum arg0VN, ValueNum arg1VN); + ValueNum EvalMathFuncBinary(var_types typ, NamedIntrinsic mthFunc, ValueNum arg0VN, ValueNum arg1VN); - ValueNumPair EvalMathFuncUnary(var_types typ, CorInfoIntrinsics mthFunc, ValueNumPair arg0VNP) + ValueNumPair EvalMathFuncUnary(var_types typ, NamedIntrinsic mthFunc, ValueNumPair arg0VNP) { return ValueNumPair(EvalMathFuncUnary(typ, mthFunc, arg0VNP.GetLiberal()), EvalMathFuncUnary(typ, mthFunc, arg0VNP.GetConservative())); } - ValueNumPair EvalMathFuncBinary(var_types typ, - CorInfoIntrinsics mthFunc, - ValueNumPair arg0VNP, - ValueNumPair arg1VNP) + ValueNumPair EvalMathFuncBinary(var_types typ, NamedIntrinsic mthFunc, ValueNumPair arg0VNP, ValueNumPair arg1VNP) { return ValueNumPair(EvalMathFuncBinary(typ, mthFunc, arg0VNP.GetLiberal(), arg1VNP.GetLiberal()), EvalMathFuncBinary(typ, mthFunc, arg0VNP.GetConservative(), arg1VNP.GetConservative())); diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs index 3f6c089..46cac9f 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs @@ -76,55 +76,6 @@ namespace Internal.JitInterface { IntrinsicHashtable table = new IntrinsicHashtable(); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sin, "Sin", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sin, "Sin", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cos, "Cos", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cos, "Cos", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cbrt, "Cbrt", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cbrt, "Cbrt", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sqrt, "Sqrt", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sqrt, "Sqrt", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Abs, "Abs", "System", "Math"); - // No System.MathF entry for CORINFO_INTRTINSIC_Abs as System.Math exposes and handles both float and double - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Round, "Round", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Round, "Round", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cosh, "Cosh", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cosh, "Cosh", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sinh, "Sinh", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sinh, "Sinh", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Tan, "Tan", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Tan, "Tan", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Tanh, "Tanh", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Tanh, "Tanh", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Asin, "Asin", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Asin, "Asin", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Asinh, "Asinh", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Asinh, "Asinh", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Acos, "Acos", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Acos, "Acos", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Acosh, "Acosh", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Acosh, "Acosh", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atan, "Atan", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atan, "Atan", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atan2, "Atan2", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atan2, "Atan2", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atanh, "Atanh", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atanh, "Atanh", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Log10, "Log10", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Log10, "Log10", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Pow, "Pow", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Pow, "Pow", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Exp, "Exp", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Exp, "Exp", "System", "MathF"); -#if !READYTORUN - // These are normally handled via the SSE4.1 instructions ROUNDSS/ROUNDSD. - // However, we don't know the ISAs the target machine supports so we should - // fallback to the method call implementation instead. - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Ceiling, "Ceiling", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Ceiling, "Ceiling", "System", "MathF"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Floor, "Floor", "System", "Math"); - table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Floor, "Floor", "System", "MathF"); -#endif // table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_GetChar, null, null, null); // unused // table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Array_GetDimLength, "GetLength", "System", "Array"); // not handled table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Get, "Get", null, null); @@ -163,7 +114,7 @@ namespace Internal.JitInterface table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_GetRawHandle, "AllocatorOf", "System", "Activator"); // If this assert fails, make sure to add the new intrinsics to the table above and update the expected count below. - Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_Count == 56, "Please update intrinsic hash table"); + Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_Count == 34, "Please update intrinsic hash table"); return table; } @@ -201,14 +152,6 @@ namespace Internal.JitInterface CorInfoIntrinsics id = entry.Id; switch (id) { - case CorInfoIntrinsics.CORINFO_INTRINSIC_Abs: - { - // RyuJIT handles floating point overloads only - var returnTypeCategory = method.Signature.ReturnType.Category; - if (returnTypeCategory != TypeFlags.Double && returnTypeCategory != TypeFlags.Single) - return CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal; - } - break; case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Get: case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Address: case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Set: diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs index da5d691..f549637 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs @@ -811,7 +811,7 @@ namespace Internal.JitInterface // do a dynamic check instead. if ( !HardwareIntrinsicHelpers.IsIsSupportedMethod(method) - || !_compilation.IsHardwareInstrinsicWithRuntimeDeterminedSupport(method)) + || !_compilation.IsHardwareIntrinsicWithRuntimeDeterminedSupport(method)) #endif { result |= CorInfoFlag.CORINFO_FLG_JIT_INTRINSIC; diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs index c1a9f87..8f4b1f6 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs @@ -416,28 +416,6 @@ namespace Internal.JitInterface public enum CorInfoIntrinsics { - CORINFO_INTRINSIC_Sin, - CORINFO_INTRINSIC_Cos, - CORINFO_INTRINSIC_Cbrt, - CORINFO_INTRINSIC_Sqrt, - CORINFO_INTRINSIC_Abs, - CORINFO_INTRINSIC_Round, - CORINFO_INTRINSIC_Cosh, - CORINFO_INTRINSIC_Sinh, - CORINFO_INTRINSIC_Tan, - CORINFO_INTRINSIC_Tanh, - CORINFO_INTRINSIC_Asin, - CORINFO_INTRINSIC_Asinh, - CORINFO_INTRINSIC_Acos, - CORINFO_INTRINSIC_Acosh, - CORINFO_INTRINSIC_Atan, - CORINFO_INTRINSIC_Atan2, - CORINFO_INTRINSIC_Atanh, - CORINFO_INTRINSIC_Log10, - CORINFO_INTRINSIC_Pow, - CORINFO_INTRINSIC_Exp, - CORINFO_INTRINSIC_Ceiling, - CORINFO_INTRINSIC_Floor, CORINFO_INTRINSIC_GetChar, // fetch character out of string CORINFO_INTRINSIC_Array_GetDimLength, // Get number of elements in a given dimension of an array CORINFO_INTRINSIC_Array_Get, // Get the value of an element in an array diff --git a/src/coreclr/src/tools/aot/jitinterface/jitwrapper.cpp b/src/coreclr/src/tools/aot/jitinterface/jitwrapper.cpp index c9530e4..1a1ef6f 100644 --- a/src/coreclr/src/tools/aot/jitinterface/jitwrapper.cpp +++ b/src/coreclr/src/tools/aot/jitinterface/jitwrapper.cpp @@ -26,11 +26,11 @@ private: uint64_t corJitFlags; }; -static const GUID JITEEVersionIdentifier = { /* 164b4e4f-21f6-4d05-b560-3728395404f2 */ - 0x164b4e4f, - 0x21f6, - 0x4d05, - { 0xb5, 0x60, 0x37, 0x28, 0x39, 0x54, 0x04, 0xf2 } +static const GUID JITEEVersionIdentifier = { /* a5eec3a4-4176-43a7-8c2b-a05b551d4f49 */ + 0xa5eec3a4, + 0x4176, + 0x43a7, + {0x8c, 0x2b, 0xa0, 0x5b, 0x55, 0x1d, 0x4f, 0x49} }; class Jit diff --git a/src/coreclr/src/vm/ecalllist.h b/src/coreclr/src/vm/ecalllist.h index de55a19..3312004 100644 --- a/src/coreclr/src/vm/ecalllist.h +++ b/src/coreclr/src/vm/ecalllist.h @@ -530,65 +530,65 @@ FCFuncStart(gDelegateFuncs) FCFuncEnd() FCFuncStart(gMathFuncs) - FCIntrinsicSig("Abs", &gsig_SM_Dbl_RetDbl, COMDouble::Abs, CORINFO_INTRINSIC_Abs) - FCIntrinsicSig("Abs", &gsig_SM_Flt_RetFlt, COMSingle::Abs, CORINFO_INTRINSIC_Abs) - FCIntrinsic("Acos", COMDouble::Acos, CORINFO_INTRINSIC_Acos) - FCIntrinsic("Acosh", COMDouble::Acosh, CORINFO_INTRINSIC_Acosh) - FCIntrinsic("Asin", COMDouble::Asin, CORINFO_INTRINSIC_Asin) - FCIntrinsic("Asinh", COMDouble::Asinh, CORINFO_INTRINSIC_Asinh) - FCIntrinsic("Atan", COMDouble::Atan, CORINFO_INTRINSIC_Atan) - FCIntrinsic("Atanh", COMDouble::Atanh, CORINFO_INTRINSIC_Atanh) - FCIntrinsic("Atan2", COMDouble::Atan2, CORINFO_INTRINSIC_Atan2) - FCIntrinsic("Cbrt", COMDouble::Cbrt, CORINFO_INTRINSIC_Cbrt) - FCIntrinsic("Ceiling", COMDouble::Ceil, CORINFO_INTRINSIC_Ceiling) - FCIntrinsic("Cos", COMDouble::Cos, CORINFO_INTRINSIC_Cos) - FCIntrinsic("Cosh", COMDouble::Cosh, CORINFO_INTRINSIC_Cosh) - FCIntrinsic("Exp", COMDouble::Exp, CORINFO_INTRINSIC_Exp) - FCIntrinsic("Floor", COMDouble::Floor, CORINFO_INTRINSIC_Floor) + FCFuncElementSig("Abs", &gsig_SM_Dbl_RetDbl, COMDouble::Abs) + FCFuncElementSig("Abs", &gsig_SM_Flt_RetFlt, COMSingle::Abs) + FCFuncElement("Acos", COMDouble::Acos) + FCFuncElement("Acosh", COMDouble::Acosh) + FCFuncElement("Asin", COMDouble::Asin) + FCFuncElement("Asinh", COMDouble::Asinh) + FCFuncElement("Atan", COMDouble::Atan) + FCFuncElement("Atanh", COMDouble::Atanh) + FCFuncElement("Atan2", COMDouble::Atan2) + FCFuncElement("Cbrt", COMDouble::Cbrt) + FCFuncElement("Ceiling", COMDouble::Ceil) + FCFuncElement("Cos", COMDouble::Cos) + FCFuncElement("Cosh", COMDouble::Cosh) + FCFuncElement("Exp", COMDouble::Exp) + FCFuncElement("Floor", COMDouble::Floor) FCFuncElement("FMod", COMDouble::FMod) FCFuncElement("FusedMultiplyAdd", COMDouble::FusedMultiplyAdd) FCFuncElement("ILogB", COMDouble::ILogB) FCFuncElement("Log", COMDouble::Log) FCFuncElement("Log2", COMDouble::Log2) - FCIntrinsic("Log10", COMDouble::Log10, CORINFO_INTRINSIC_Log10) + FCFuncElement("Log10", COMDouble::Log10) FCFuncElement("ModF", COMDouble::ModF) - FCIntrinsic("Pow", COMDouble::Pow, CORINFO_INTRINSIC_Pow) + FCFuncElement("Pow", COMDouble::Pow) FCFuncElement("ScaleB", COMDouble::ScaleB) - FCIntrinsic("Sin", COMDouble::Sin, CORINFO_INTRINSIC_Sin) - FCIntrinsic("Sinh", COMDouble::Sinh, CORINFO_INTRINSIC_Sinh) - FCIntrinsic("Sqrt", COMDouble::Sqrt, CORINFO_INTRINSIC_Sqrt) - FCIntrinsic("Tan", COMDouble::Tan, CORINFO_INTRINSIC_Tan) - FCIntrinsic("Tanh", COMDouble::Tanh, CORINFO_INTRINSIC_Tanh) + FCFuncElement("Sin", COMDouble::Sin) + FCFuncElement("Sinh", COMDouble::Sinh) + FCFuncElement("Sqrt", COMDouble::Sqrt) + FCFuncElement("Tan", COMDouble::Tan) + FCFuncElement("Tanh", COMDouble::Tanh) FCFuncEnd() FCFuncStart(gMathFFuncs) - FCIntrinsic("Acos", COMSingle::Acos, CORINFO_INTRINSIC_Acos) - FCIntrinsic("Acosh", COMSingle::Acosh, CORINFO_INTRINSIC_Acosh) - FCIntrinsic("Asin", COMSingle::Asin, CORINFO_INTRINSIC_Asin) - FCIntrinsic("Asinh", COMSingle::Asinh, CORINFO_INTRINSIC_Asinh) - FCIntrinsic("Atan", COMSingle::Atan, CORINFO_INTRINSIC_Atan) - FCIntrinsic("Atanh", COMSingle::Atanh, CORINFO_INTRINSIC_Atanh) - FCIntrinsic("Atan2", COMSingle::Atan2, CORINFO_INTRINSIC_Atan2) - FCIntrinsic("Cbrt", COMSingle::Cbrt, CORINFO_INTRINSIC_Cbrt) - FCIntrinsic("Ceiling", COMSingle::Ceil, CORINFO_INTRINSIC_Ceiling) - FCIntrinsic("Cos", COMSingle::Cos, CORINFO_INTRINSIC_Cos) - FCIntrinsic("Cosh", COMSingle::Cosh, CORINFO_INTRINSIC_Cosh) - FCIntrinsic("Exp", COMSingle::Exp, CORINFO_INTRINSIC_Exp) - FCIntrinsic("Floor", COMSingle::Floor, CORINFO_INTRINSIC_Floor) + FCFuncElement("Acos", COMSingle::Acos) + FCFuncElement("Acosh", COMSingle::Acosh) + FCFuncElement("Asin", COMSingle::Asin) + FCFuncElement("Asinh", COMSingle::Asinh) + FCFuncElement("Atan", COMSingle::Atan) + FCFuncElement("Atanh", COMSingle::Atanh) + FCFuncElement("Atan2", COMSingle::Atan2) + FCFuncElement("Cbrt", COMSingle::Cbrt) + FCFuncElement("Ceiling", COMSingle::Ceil) + FCFuncElement("Cos", COMSingle::Cos) + FCFuncElement("Cosh", COMSingle::Cosh) + FCFuncElement("Exp", COMSingle::Exp) + FCFuncElement("Floor", COMSingle::Floor) FCFuncElement("FMod", COMSingle::FMod) FCFuncElement("FusedMultiplyAdd", COMSingle::FusedMultiplyAdd) FCFuncElement("ILogB", COMSingle::ILogB) FCFuncElement("Log", COMSingle::Log) FCFuncElement("Log2", COMSingle::Log2) - FCIntrinsic("Log10", COMSingle::Log10, CORINFO_INTRINSIC_Log10) + FCFuncElement("Log10", COMSingle::Log10) FCFuncElement("ModF", COMSingle::ModF) - FCIntrinsic("Pow", COMSingle::Pow, CORINFO_INTRINSIC_Pow) + FCFuncElement("Pow", COMSingle::Pow) FCFuncElement("ScaleB", COMSingle::ScaleB) - FCIntrinsic("Sin", COMSingle::Sin, CORINFO_INTRINSIC_Sin) - FCIntrinsic("Sinh", COMSingle::Sinh, CORINFO_INTRINSIC_Sinh) - FCIntrinsic("Sqrt", COMSingle::Sqrt, CORINFO_INTRINSIC_Sqrt) - FCIntrinsic("Tan", COMSingle::Tan, CORINFO_INTRINSIC_Tan) - FCIntrinsic("Tanh", COMSingle::Tanh, CORINFO_INTRINSIC_Tanh) + FCFuncElement("Sin", COMSingle::Sin) + FCFuncElement("Sinh", COMSingle::Sinh) + FCFuncElement("Sqrt", COMSingle::Sqrt) + FCFuncElement("Tan", COMSingle::Tan) + FCFuncElement("Tanh", COMSingle::Tanh) FCFuncEnd() FCFuncStart(gThreadFuncs) diff --git a/src/coreclr/src/zap/zapinfo.cpp b/src/coreclr/src/zap/zapinfo.cpp index 2031968..ea45f3e 100644 --- a/src/coreclr/src/zap/zapinfo.cpp +++ b/src/coreclr/src/zap/zapinfo.cpp @@ -2219,12 +2219,13 @@ DWORD FilterNamedIntrinsicMethodAttribs(ZapInfo* pZapInfo, DWORD attribs, CORINF #if defined(TARGET_X86) || defined(TARGET_AMD64) else if (strcmp(namespaceName, "System") == 0) { - if ((strcmp(className, "Math") == 0) || (strcmp(className, "MathF") == 0)) + if (strcmp(className, "Math") == 0 || strcmp(className, "MathF") == 0) { // These are normally handled via the SSE4.1 instructions ROUNDSS/ROUNDSD. // However, we don't know the ISAs the target machine supports so we should // fallback to the method call implementation instead. - fTreatAsRegularMethodCall = strcmp(methodName, "Round") == 0; + fTreatAsRegularMethodCall = strcmp(methodName, "Round") == 0 || strcmp(methodName, "Ceiling") == 0 || + strcmp(methodName, "Floor") == 0; } } else if (strcmp(namespaceName, "System.Numerics") == 0) @@ -3991,19 +3992,7 @@ void ZapInfo::expandRawHandleIntrinsic( CorInfoIntrinsics ZapInfo::getIntrinsicID(CORINFO_METHOD_HANDLE method, bool * pMustExpand) { - CorInfoIntrinsics intrinsicID = m_pEEJitInfo->getIntrinsicID(method, pMustExpand); - -#if defined(TARGET_X86) || defined(TARGET_AMD64) - if ((intrinsicID == CORINFO_INTRINSIC_Ceiling) || (intrinsicID == CORINFO_INTRINSIC_Floor)) - { - // These are normally handled via the SSE4.1 instructions ROUNDSS/ROUNDSD. - // However, we don't know the ISAs the target machine supports so we should - // fallback to the method call implementation instead. - intrinsicID = CORINFO_INTRINSIC_Illegal; - } -#endif // defined(TARGET_X86) || defined(TARGET_AMD64) - - return intrinsicID; + return m_pEEJitInfo->getIntrinsicID(method, pMustExpand); } bool ZapInfo::isIntrinsicType(CORINFO_CLASS_HANDLE classHnd) -- 2.7.4