From caf36fac2c0f26e4194e99ceb93510d3d1b8029f Mon Sep 17 00:00:00 2001 From: Brian Sullivan Date: Mon, 25 Jan 2021 21:15:03 -0800 Subject: [PATCH] Fix for 46529 - Unexpected behaviour of ulong -> int cast (#47418) * Fix for issue 46529 Move check for side-effect and don't push the cast for shifts of 32 to 63 Added test Runtime_46239.cs * clang format --- src/coreclr/jit/morph.cpp | 24 +++++++++++++++---- .../JitBlue/Runtime_46529/Runtime_46529.cs | 27 ++++++++++++++++++++++ .../JitBlue/Runtime_46529/Runtime_46529.csproj | 14 +++++++++++ 3 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_46529/Runtime_46529.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_46529/Runtime_46529.csproj diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 9816306..639129a 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -466,12 +466,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 { diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_46529/Runtime_46529.cs b/src/tests/JIT/Regression/JitBlue/Runtime_46529/Runtime_46529.cs new file mode 100644 index 0000000..76d13b2 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_46529/Runtime_46529.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; + +public unsafe class Test +{ + [MethodImpl(MethodImplOptions.NoInlining)] + static int Foo(byte* bytes) => (int)(((ulong)bytes[0]) << 56); + + public static int Main() + { + byte p = 0xFF; + int result = Foo(&p); + if (result == 0) + { + Console.WriteLine("Passed"); + return 100; + } + else + { + Console.WriteLine("Failed: {0:x}",result); + return 101; + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_46529/Runtime_46529.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_46529/Runtime_46529.csproj new file mode 100644 index 0000000..de56055 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_46529/Runtime_46529.csproj @@ -0,0 +1,14 @@ + + + Exe + 0 + + + true + None + True + + + + + -- 2.7.4