From: Egor Bogatov Date: Tue, 17 Aug 2021 15:27:11 +0000 (+0300) Subject: JIT: Don't fold NEG(NEG(X)) to X when NEG(x) is a CSE candidate (#57478) X-Git-Tag: accepted/tizen/unified/20220110.054933~333 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=492a5201fdb26eae5288fd6653945a689a601f3a;p=platform%2Fupstream%2Fdotnet%2Fruntime.git JIT: Don't fold NEG(NEG(X)) to X when NEG(x) is a CSE candidate (#57478) --- diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index a00b4bb..3c2bb44 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -13114,13 +13114,17 @@ DONE_MORPHING_CHILDREN: case GT_NEG: // Remove double negation/not. // Note: this is not a safe tranformation if "tree" is a CSE candidate. - // Consider for example the following expression: NEG(NEG(OP)), where the top-level + // Consider for example the following expression: NEG(NEG(OP)), where any // NEG is a CSE candidate. Were we to morph this to just OP, CSE would fail to find // the original NEG in the statement. - if (op1->OperIs(oper) && opts.OptimizationEnabled() && !gtIsActiveCSE_Candidate(tree)) + if (op1->OperIs(oper) && opts.OptimizationEnabled() && !gtIsActiveCSE_Candidate(tree) && + !gtIsActiveCSE_Candidate(op1)) { - GenTree* child = op1->AsOp()->gtGetOp1(); - return child; + JITDUMP("Remove double negation/not\n") + GenTree* op1op1 = op1->gtGetOp1(); + DEBUG_DESTROY_NODE(tree); + DEBUG_DESTROY_NODE(op1); + return op1op1; } // Distribute negation over simple multiplication/division expressions diff --git a/src/tests/JIT/opt/perf/doublenegate/GitHub_57470.cs b/src/tests/JIT/opt/perf/doublenegate/GitHub_57470.cs new file mode 100644 index 0000000..e0dbc35 --- /dev/null +++ b/src/tests/JIT/opt/perf/doublenegate/GitHub_57470.cs @@ -0,0 +1,50 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// +// This file is auto-generated. +// Seed: -1 +// +using System; +using System.Runtime.CompilerServices; +public class TestClass8505 +{ + static int s_int32_6 = -5; + static sbyte s_sbyte_8 = 2; + static int s_loopInvariant = 3; + public sbyte LeafMethod8() + { + unchecked + { + return s_sbyte_8 <<= s_int32_6 >>= s_int32_6 ^ (-2 - (s_int32_6 &= -5)) / (-1 * s_int32_6 * (2 ^ -2)) + 77; + } + } + public void Method0() + { + unchecked + { + try + { + } + finally + { + { + int __loopvar1 = s_loopInvariant, __loopSecondaryVar1_0 = 15 - 4; + do + { + } + while (15 % 4 > LeafMethod8() / 15 + 4); + } + { + } + } + return; + } + } + public static int Main(string[] args) + { + TestClass8505 objTestClass8505 = new TestClass8505(); + objTestClass8505.Method0(); + return 100; + } +} diff --git a/src/tests/JIT/opt/perf/doublenegate/GitHub_57470.csproj b/src/tests/JIT/opt/perf/doublenegate/GitHub_57470.csproj new file mode 100644 index 0000000..e6cddfa --- /dev/null +++ b/src/tests/JIT/opt/perf/doublenegate/GitHub_57470.csproj @@ -0,0 +1,9 @@ + + + Exe + None + + + + +