// Pops and returns GenTree node from importers type stack.
// Normalizes TYP_STRUCT value in case of GT_CALL, GT_RET_EXPR and arg nodes.
- GenTree* impSIMDPopStack(var_types type, bool expectAddr = false);
+ GenTree* impSIMDPopStack(var_types type, bool expectAddr = false, CORINFO_CLASS_HANDLE structType = nullptr);
// Create a GT_SIMD tree for a Get property of SIMD vector with a fixed index.
GenTreeSIMD* impSIMDGetFixed(var_types simdType, var_types baseType, unsigned simdSize, int index);
// the type system. It is safe to do this here since the retNode type
// and the signature return type are both TYP_SIMD16.
assert(sig->numArgs == 1);
- retNode = impSIMDPopStack(TYP_SIMD16);
+ retNode = impSIMDPopStack(TYP_SIMD16, false, sig->retTypeClass);
SetOpLclRelatedToSIMDIntrinsic(retNode);
assert(retNode->gtType == getSIMDTypeForSize(getSIMDTypeSizeInBytes(sig->retTypeSigClass)));
break;
// the type system. It is safe to do this here since the retNode type
// and the signature return type are both TYP_SIMD32.
assert(sig->numArgs == 1);
- retNode = impSIMDPopStack(TYP_SIMD32);
+ retNode = impSIMDPopStack(TYP_SIMD32, false, sig->retTypeClass);
SetOpLclRelatedToSIMDIntrinsic(retNode);
assert(retNode->gtType == getSIMDTypeForSize(getSIMDTypeSizeInBytes(sig->retTypeSigClass)));
break;
// Arguments:
// type - the type of value that the caller expects to be popped off the stack.
// expectAddr - if true indicates we are expecting type stack entry to be a TYP_BYREF.
+// structType - the class handle to use when normalizing if it is not the same as the stack entry class handle;
+// this can happen for certain scenarios, such as folding away a static cast, where we want the
+// value popped to have the type that would have been returned.
//
// Notes:
// If the popped value is a struct, and the expected type is a simd type, it will be set
// to that type, otherwise it will assert if the type being popped is not the expected type.
-GenTree* Compiler::impSIMDPopStack(var_types type, bool expectAddr)
+GenTree* Compiler::impSIMDPopStack(var_types type, bool expectAddr, CORINFO_CLASS_HANDLE structType)
{
StackEntry se = impPopStack();
typeInfo ti = se.seTypeInfo;
if (varTypeIsStruct(tree) && ((tree->OperGet() == GT_RET_EXPR) || (tree->OperGet() == GT_CALL) || isParam))
{
assert(ti.IsType(TI_STRUCT));
- CORINFO_CLASS_HANDLE structType = ti.GetClassHandleForValueClass();
- tree = impNormStructVal(tree, structType, (unsigned)CHECK_SPILL_ALL);
+
+ if (structType == nullptr)
+ {
+ structType = ti.GetClassHandleForValueClass();
+ }
+
+ tree = impNormStructVal(tree, structType, (unsigned)CHECK_SPILL_ALL);
}
// Now set the type of the tree to the specialized SIMD struct type, if applicable.