@@ -3987,6 +3987,38 @@ GenTree* Compiler::impSRCSUnsafeIntrinsic(NamedIntrinsic intrinsic,
3987
3987
{
3988
3988
assert ((sig->sigInst .methInstCount == 1 ) || (sig->sigInst .methInstCount == 2 ));
3989
3989
3990
+ if (sig->sigInst .methInstCount == 1 )
3991
+ {
3992
+ const CORINFO_CLASS_HANDLE inst = sig->sigInst .methInst [0 ];
3993
+ assert (inst != nullptr );
3994
+
3995
+ if ((info.compCompHnd ->getClassAttribs (inst) & CORINFO_FLG_SHAREDINST) == 0 )
3996
+ {
3997
+ GenTree* op = impPopStack ().val ;
3998
+ assert (op->TypeIs (TYP_REF));
3999
+
4000
+ JITDUMP (" Expanding Unsafe.As<%s>(...)\n " , eeGetClassName (inst));
4001
+
4002
+ // In order to change the class handle of the object we need to spill it to a temp
4003
+ // and update class info for that temp.
4004
+ unsigned localNum = lvaGrabTemp (true DEBUGARG (" updating class info" ));
4005
+ impAssignTempGen (localNum, op);
4006
+
4007
+ bool isExact, isNonNull;
4008
+ CORINFO_CLASS_HANDLE oldClass = gtGetClassHandle (op, &isExact, &isNonNull);
4009
+ if ((oldClass != NO_CLASS_HANDLE) && info.compCompHnd ->isMoreSpecificType (inst, oldClass))
4010
+ {
4011
+ JITDUMP (" Unsafe.As: Keep using old '%s' type as it is more specific\n " ,
4012
+ eeGetClassName (oldClass));
4013
+ return op;
4014
+ }
4015
+
4016
+ // NOTE: we still can't say for sure that it is the exact type of the argument
4017
+ lvaSetClass (localNum, inst, /* isExact*/ false );
4018
+ return gtNewLclvNode (localNum, TYP_REF);
4019
+ }
4020
+ }
4021
+
3990
4022
// ldarg.0
3991
4023
// ret
3992
4024
0 commit comments