@@ -1490,7 +1490,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
14901490 {
14911491 spillStack = false ;
14921492 }
1493- else if (( callNode->gtCallMoreFlags & GTF_CALL_M_SPECIAL_INTRINSIC) != 0 )
1493+ else if (callNode->IsSpecialIntrinsic () )
14941494 {
14951495 spillStack = false ;
14961496 }
@@ -4090,7 +4090,7 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
40904090 if (impStackTop ().val ->OperIs (GT_RET_EXPR))
40914091 {
40924092 GenTreeCall* call = impStackTop ().val ->AsRetExpr ()->gtInlineCandidate ->AsCall ();
4093- if (call->gtCallMoreFlags & GTF_CALL_M_SPECIAL_INTRINSIC )
4093+ if (call->IsSpecialIntrinsic () )
40944094 {
40954095 if (lookupNamedIntrinsic (call->gtCallMethHnd ) == NI_System_Threading_Thread_get_CurrentThread)
40964096 {
@@ -4336,7 +4336,7 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
43364336 case NI_System_Math_Log2:
43374337 case NI_System_Math_Log10:
43384338 {
4339- retNode = impMathIntrinsic (method, sig R2RARG (entryPoint), callType, ni, tailCall);
4339+ retNode = impMathIntrinsic (method, sig R2RARG (entryPoint), callType, ni, tailCall, &isSpecial );
43404340 break ;
43414341 }
43424342
@@ -4429,7 +4429,7 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
44294429 case NI_System_Math_Tanh:
44304430 case NI_System_Math_Truncate:
44314431 {
4432- retNode = impMathIntrinsic (method, sig R2RARG (entryPoint), callType, ni, tailCall);
4432+ retNode = impMathIntrinsic (method, sig R2RARG (entryPoint), callType, ni, tailCall, &isSpecial );
44334433 break ;
44344434 }
44354435
@@ -9533,29 +9533,46 @@ GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method,
95339533 CORINFO_SIG_INFO* sig R2RARG (CORINFO_CONST_LOOKUP* entryPoint),
95349534 var_types callType,
95359535 NamedIntrinsic intrinsicName,
9536- bool tailCall)
9536+ bool tailCall,
9537+ bool* isSpecial)
95379538{
95389539 GenTree* op1;
95399540 GenTree* op2;
95409541
95419542 assert (callType != TYP_STRUCT);
95429543 assert (IsMathIntrinsic (intrinsicName));
9544+ assert (isSpecial != nullptr );
95439545
95449546 op1 = nullptr ;
95459547
9548+ bool isIntrinsicImplementedByUserCall = IsIntrinsicImplementedByUserCall (intrinsicName);
9549+
9550+ if (isIntrinsicImplementedByUserCall)
9551+ {
9552+ #if defined(TARGET_XARCH)
9553+ // We want to track math intrinsics implemented as user calls as special
9554+ // to ensure we don't lose track of the fact it will call into native code
9555+ //
9556+ // This is used on xarch to track that it may need vzeroupper inserted to
9557+ // avoid the perf penalty on some hardware.
9558+
9559+ *isSpecial = true ;
9560+ #endif // TARGET_XARCH
9561+ }
9562+
95469563#if !defined(TARGET_X86)
95479564 // Intrinsics that are not implemented directly by target instructions will
95489565 // be re-materialized as users calls in rationalizer. For prefixed tail calls,
95499566 // don't do this optimization, because
95509567 // a) For back compatibility reasons on desktop .NET Framework 4.6 / 4.6.1
95519568 // b) It will be non-trivial task or too late to re-materialize a surviving
95529569 // tail prefixed GT_INTRINSIC as tail call in rationalizer.
9553- if (!IsIntrinsicImplementedByUserCall (intrinsicName) || !tailCall)
9570+ if (!isIntrinsicImplementedByUserCall || !tailCall)
95549571#else
95559572 // On x86 RyuJIT, importing intrinsics that are implemented as user calls can cause incorrect calculation
95569573 // of the depth of the stack if these intrinsics are used as arguments to another call. This causes bad
95579574 // code generation for certain EH constructs.
9558- if (!IsIntrinsicImplementedByUserCall (intrinsicName) )
9575+ if (!isIntrinsicImplementedByUserCall )
95599576#endif
95609577 {
95619578 CORINFO_ARG_LIST_HANDLE arg = sig->args ;
@@ -9588,7 +9605,7 @@ GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method,
95889605 NO_WAY (" Unsupported number of args for Math Intrinsic" );
95899606 }
95909607
9591- if (IsIntrinsicImplementedByUserCall (intrinsicName) )
9608+ if (isIntrinsicImplementedByUserCall )
95929609 {
95939610 op1->gtFlags |= GTF_CALL;
95949611 }
@@ -10073,7 +10090,7 @@ GenTree* Compiler::impMinMaxIntrinsic(CORINFO_METHOD_HANDLE method,
1007310090#endif // FEATURE_HW_INTRINSICS && TARGET_XARCH
1007410091
1007510092 // TODO-CQ: Returning this as an intrinsic blocks inlining and is undesirable
10076- // return impMathIntrinsic(method, sig, callType, intrinsicName, tailCall);
10093+ // return impMathIntrinsic(method, sig, callType, intrinsicName, tailCall, isSpecial );
1007710094
1007810095 return nullptr ;
1007910096}
0 commit comments