Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Do not eliminate casts from FP types
An optimization in morph was deleting casts
on the RHS of a narrow store if the cast-to-type
was wider than the type being stored. This is only
valid for casts from integral types, as the backend
does not handle "STOREIND(byte*, double)", nor is there
an instruction to go from an XMM register to a narrow
memory location on x86/x64.

The issue is not reproducible right now because
fgMorphCast wraps the casts in question, but it is
an invalid IR transformation nonetheless, and similar
code in fgMorphSmpOpOptional guards against non-integral sources.
  • Loading branch information
SingleAccretion committed Jun 7, 2021
commit 94de26a3d610b5c8499f102205bdc39c67f2d624
9 changes: 5 additions & 4 deletions src/coreclr/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13378,18 +13378,19 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac)
tree->AsOp()->gtOp1 = op1;
}

/* If we are storing a small type, we might be able to omit a cast */
if ((effectiveOp1->gtOper == GT_IND) && varTypeIsSmall(effectiveOp1->TypeGet()))
// If we are storing a small type, we might be able to omit a cast.
if (effectiveOp1->OperIs(GT_IND) && varTypeIsSmall(effectiveOp1))
{
if (!gtIsActiveCSE_Candidate(op2) && (op2->gtOper == GT_CAST) && !op2->gtOverflow())
if (!gtIsActiveCSE_Candidate(op2) && op2->OperIs(GT_CAST) &&
varTypeIsIntegral(op2->AsCast()->CastOp()) && !op2->gtOverflow())
{
var_types castType = op2->CastToType();

// If we are performing a narrowing cast and
// castType is larger or the same as op1's type
// then we can discard the cast.

if (varTypeIsSmall(castType) && (genTypeSize(castType) >= genTypeSize(effectiveOp1->TypeGet())))
if (varTypeIsSmall(castType) && (genTypeSize(castType) >= genTypeSize(effectiveOp1)))
{
tree->AsOp()->gtOp2 = op2 = op2->AsCast()->CastOp();
}
Expand Down