diff options
author | SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> | 2021-07-13 18:10:39 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-13 18:10:39 +0300 |
commit | 53db2ec476e4b3b47168a1bd93f29351b5df23bd (patch) | |
tree | 93b0cdb44cb4c429a1dbcddcae51416055789f9d /src/coreclr | |
parent | c6acf8dbeff5e2c54b055f496cb8dafc5d0b3e20 (diff) |
Do not eliminate casts from FP types (#53667)
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.
Diffstat (limited to 'src/coreclr')
-rw-r--r-- | src/coreclr/jit/morph.cpp | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index b6ee82d3b80..f0bc076f235 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -12071,10 +12071,11 @@ DONE_MORPHING_CHILDREN: 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(); @@ -12082,7 +12083,7 @@ DONE_MORPHING_CHILDREN: // 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(); } |