From 38004377f93ec5e253fe0d7eaa54d9a85ed5e8ab Mon Sep 17 00:00:00 2001 From: Brian Sullivan Date: Wed, 10 Mar 2021 04:31:00 -0800 Subject: [PATCH] Backport the fix for dotnet/runtime issue 46529 to dotnet/coreclr 3.1 branch (#28146) Fixes incorrect behavior a 64-bit long with shift of 32 or more combined with a cast to int --- src/jit/morph.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 5d5d471eb7f1..8c883be55a05 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -461,12 +461,26 @@ GenTree* Compiler::fgMorphCast(GenTree* tree) // Don't try to optimize. assert(!canPushCast); } - else if ((shiftAmountValue >= 32) && ((tree->gtFlags & GTF_ALL_EFFECT) == 0)) + else if (shiftAmountValue >= 32) { - // Result of the shift is zero. - DEBUG_DESTROY_NODE(tree); - GenTree* zero = gtNewZeroConNode(TYP_INT); - return fgMorphTree(zero); + // We know that we have a narrowing cast ([u]long -> [u]int) + // and that we are casting to a 32-bit value, which will result in zero. + // + // Check to see if we have any side-effects that we must keep + // + if ((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 // We do have a side-effect + { + // We could create a GT_COMMA node here to keep the side-effect and return a zero + // Instead we just don't try to optimize this case. + canPushCast = false; + } } else {