@@ -823,7 +823,6 @@ GenTree* Lowering::LowerCast(GenTree* tree)
823
823
var_types castToType = tree->CastToType();
824
824
var_types dstType = castToType;
825
825
var_types srcType = castOp->TypeGet();
826
- var_types tmpType = TYP_UNDEF;
827
826
828
827
// force the srcType to unsigned if GT_UNSIGNED flag is set
829
828
if (tree->IsUnsigned())
@@ -837,11 +836,14 @@ GenTree* Lowering::LowerCast(GenTree* tree)
837
836
// Reason: must be converted to a helper call
838
837
// srcType = float/double, castToType = ulong
839
838
// Reason: must be converted to a helper call
839
+ // srcType = float/double, castToType = byte/sbyte/ushort/short
840
+ // Reason: must have intermediate cast to int
840
841
// srcType = uint castToType = float/double
841
842
// Reason: uint -> float/double = uint -> long -> float/double
842
843
if (varTypeIsFloating(srcType))
843
844
{
844
845
noway_assert(!tree->gtOverflow());
846
+ assert(!varTypeIsSmall(dstType));
845
847
assert(castToType != TYP_ULONG || comp->canUseEvexEncodingDebugOnly());
846
848
}
847
849
else if (srcType == TYP_UINT)
@@ -1164,30 +1166,6 @@ GenTree* Lowering::LowerCast(GenTree* tree)
1164
1166
}
1165
1167
#endif // TARGET_AMD64
1166
1168
1167
- // Case of src is a small type and dst is a floating point type.
1168
- if (varTypeIsSmall(srcType) && varTypeIsFloating(castToType))
1169
- {
1170
- // These conversions can never be overflow detecting ones.
1171
- noway_assert(!tree->gtOverflow());
1172
- tmpType = TYP_INT;
1173
- }
1174
- // case of src is a floating point type and dst is a small type.
1175
- else if (varTypeIsFloating(srcType) && varTypeIsSmall(castToType))
1176
- {
1177
- tmpType = TYP_INT;
1178
- }
1179
-
1180
- if (tmpType != TYP_UNDEF)
1181
- {
1182
- GenTree* tmp = comp->gtNewCastNode(tmpType, castOp, tree->IsUnsigned(), tmpType);
1183
- tmp->gtFlags |= (tree->gtFlags & (GTF_OVERFLOW | GTF_EXCEPT));
1184
-
1185
- tree->gtFlags &= ~GTF_UNSIGNED;
1186
- tree->AsOp()->gtOp1 = tmp;
1187
- BlockRange().InsertAfter(castOp, tmp);
1188
- ContainCheckCast(tmp->AsCast());
1189
- }
1190
-
1191
1169
// Now determine if we have operands that should be contained.
1192
1170
ContainCheckCast(tree->AsCast());
1193
1171
return nullptr;
@@ -8567,26 +8545,14 @@ void Lowering::ContainCheckCast(GenTreeCast* node)
8567
8545
8568
8546
if (varTypeIsFloating(castToType) || varTypeIsFloating(srcType))
8569
8547
{
8570
- #ifdef DEBUG
8571
- // If converting to float/double, the operand must be 4 or 8 byte in size.
8572
- if (varTypeIsFloating(castToType))
8548
+ if (castOp->IsCnsNonZeroFltOrDbl())
8573
8549
{
8574
- unsigned opSize = genTypeSize(srcType);
8575
- assert(opSize == 4 || opSize == 8);
8550
+ MakeSrcContained(node, castOp);
8576
8551
}
8577
- #endif // DEBUG
8578
-
8579
- // U8 -> R8 conversion requires that the operand be in a register.
8580
- if (srcType != TYP_ULONG)
8552
+ else
8581
8553
{
8582
- if (castOp->IsCnsNonZeroFltOrDbl())
8583
- {
8584
- MakeSrcContained(node, castOp);
8585
- }
8586
- else
8587
- {
8588
- srcIsContainable = true;
8589
- }
8554
+ // The ulong->floating SSE2 fallback requires the source to be in register
8555
+ srcIsContainable = !varTypeIsSmall(srcType) && ((srcType != TYP_ULONG) || comp->canUseEvexEncoding());
8590
8556
}
8591
8557
}
8592
8558
else if (comp->opts.OptimizationEnabled() && varTypeIsIntegral(castOp) && varTypeIsIntegral(castToType))
0 commit comments