diff options
author | Sergey Andreenko <seandree@microsoft.com> | 2018-09-11 20:32:35 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-11 20:32:35 -0700 |
commit | a3443a53b4f6f2f50d666116b0281b65b961197a (patch) | |
tree | 53b0c456b174e00c619f9cf648c7932b1dc2ecc5 /src/jit/morph.cpp | |
parent | 9de98ef09a8998ba8c1f369c0d8067d5ffe1e0e7 (diff) | |
download | coreclr-a3443a53b4f6f2f50d666116b0281b65b961197a.tar.gz coreclr-a3443a53b4f6f2f50d666116b0281b65b961197a.tar.bz2 coreclr-a3443a53b4f6f2f50d666116b0281b65b961197a.zip |
Fix optimization of CAST(int)(LSH(long)<<CNS_INT 32+ with side effects). (#19899)
* add a repro test
* Fix
Diffstat (limited to 'src/jit/morph.cpp')
-rw-r--r-- | src/jit/morph.cpp | 22 |
1 files changed, 8 insertions, 14 deletions
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 4265da2043..4ddd71140c 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -453,29 +453,23 @@ GenTree* Compiler::fgMorphCast(GenTree* tree) { const ssize_t shiftAmountValue = shiftAmount->AsIntCon()->IconValue(); - if (shiftAmountValue >= 64) + if ((shiftAmountValue >= 64) || (shiftAmountValue < 0)) { - // Shift amount is large enough that result is undefined. - // Don't try and optimize. + // Shift amount is large enough or negative so result is undefined. + // Don't try to optimize. assert(!canPushCast); } - else if (shiftAmountValue >= 32) + else if ((shiftAmountValue >= 32) && ((tree->gtFlags & GTF_ALL_EFFECT) == 0)) { // Result of the shift is zero. DEBUG_DESTROY_NODE(tree); GenTree* zero = gtNewZeroConNode(TYP_INT); return fgMorphTree(zero); } - else if (shiftAmountValue >= 0) - { - // Shift amount is small enough that we can push the cast through. - canPushCast = true; - } else { - // Shift amount is negative and so result is undefined. - // Don't try and optimize. - assert(!canPushCast); + // Shift amount is positive and small enough that we can push the cast through. + canPushCast = true; } } else @@ -489,14 +483,14 @@ GenTree* Compiler::fgMorphCast(GenTree* tree) { DEBUG_DESTROY_NODE(tree); - // Insert narrowing casts for op1 and op2 + // Insert narrowing casts for op1 and op2. oper->gtOp.gtOp1 = gtNewCastNode(TYP_INT, oper->gtOp.gtOp1, false, dstType); if (oper->gtOp.gtOp2 != nullptr) { oper->gtOp.gtOp2 = gtNewCastNode(TYP_INT, oper->gtOp.gtOp2, false, dstType); } - // Clear the GT_MUL_64RSLT if it is set + // Clear the GT_MUL_64RSLT if it is set. if (oper->gtOper == GT_MUL && (oper->gtFlags & GTF_MUL_64RSLT)) { oper->gtFlags &= ~GTF_MUL_64RSLT; |